Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/cfdumper/main.c
5985 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2022 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include <stdlib.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include "j9.h"
27
#include "j9port.h"
28
#include "cfreader.h"
29
#include "bcnames.h"
30
#include "j9protos.h"
31
#include "jimage.h"
32
#include "jimagereader.h"
33
#include "zip_api.h"
34
#include "rommeth.h"
35
#include "exelib_api.h"
36
#include "j9cp.h"
37
#include "bcutil_api.h"
38
#include "cfdumper_internal.h"
39
#include "vendor_version.h"
40
41
#if defined(J9ZOS390)
42
#include "atoe.h"
43
#endif
44
45
#define CFDUMP_CLASSFILE_EXTENSION ".class"
46
#define CFDUMP_CLASSFILE_EXTENSION_WITHOUT_DOT "class"
47
48
/* Return values. */
49
#define RET_SUCCESS 0
50
#define RET_ALLOCATE_FAILED -1
51
#define RET_TRANSLATE_FAILED -2
52
#define RET_COMMANDLINE_INCORRECT -3
53
#define RET_UNSUPPORTED_ACTION -4
54
#define RET_UNSUPPORTED_SOURCE -5
55
#define RET_FILE_OPEN_FAILED -11
56
#define RET_FILE_SEEK_FAILED -12
57
#define RET_FILE_READ_FAILED -13
58
#define RET_FILE_WRITE_FAILED -14
59
#define RET_FILE_LOAD_FAILED -15
60
#define RET_ZIP_OPEN_FAILED -16
61
#define RET_ZIP_GETENTRY_FAILED -17
62
#define RET_ZIP_GETNEXTZIPENTRY_FAILED -18
63
#define RET_ZIP_GETZIPENTRYFILENAME_FAILED -19
64
#define RET_ZIP_GETENTRYDATA_FAILED -20
65
#define RET_JIMAGE_LOADJIMAGE_FAILED -21
66
#define RET_JIMAGE_CREATEJIMAGELOCATION_FAILED -22
67
#define RET_JIMAGE_GETJIMAGERESOURCE_FAILED -23
68
#define RET_JIMAGE_INVALIDLOCATION_OFFSET -24
69
#define RET_LOADROMCLASSFROMBYTES_FAILED -25
70
#define RET_LOADCLASSFROMBYTES_FAILED -26
71
#define RET_CREATE_DIR_FAILED -27
72
#define RET_PARSE_CLASS_NAME_FAILED -28
73
74
typedef enum
75
{
76
ACTION_definition = 0,
77
ACTION_structure,
78
ACTION_bytecodes,
79
ACTION_formatClass,
80
ACTION_formatFields,
81
ACTION_formatMethods,
82
ACTION_formatBytecodes,
83
ACTION_transformRomClass,
84
ACTION_writeRomClassFile,
85
ACTION_writeRomClassFileHierarchy,
86
ACTION_dumpMaps,
87
ACTION_dumpRomClass,
88
ACTION_dumpRomClassXML,
89
ACTION_queryRomClass,
90
ACTION_dumpJImageInfo,
91
ACTION_writeJImageResource,
92
ACTION_findModuleForPackage
93
} actionType;
94
95
typedef enum
96
{
97
SOURCE_files = 0,
98
SOURCE_zip,
99
SOURCE_jimage,
100
SOURCE_rom
101
} sourceType;
102
103
typedef enum
104
{
105
OPTION_none = 0x0,
106
OPTION_check = 0x1,
107
OPTION_stripDebugAttributes = 0x2,
108
OPTION_quiet = 0x4,
109
OPTION_verbose = 0x8,
110
OPTION_multi = 0x10,
111
OPTION_recursive = 0x20,
112
OPTION_translate = 0x40,
113
OPTION_littleEndian = 0x80,
114
OPTION_bigEndian = 0x100,
115
OPTION_dumpPreverifyData = 0x200,
116
OPTION_leaveJSRs = 0x400,
117
OPTION_stripDebugLines = 0x800,
118
OPTION_stripDebugSource = 0x1000,
119
OPTION_stripDebugVars = 0x2000,
120
OPTION_pedantic = 0x4000,
121
OPTION_dumpMaps = 0x8000,
122
} optionType;
123
124
typedef struct
125
{
126
const char *module;
127
char *parentString;
128
char *baseString;
129
} JImageMatchInfo;
130
131
132
static void j9_formatMethod (J9ROMClass* romClass, J9ROMMethod* method, char *formatString, IDATA length, U_32 flags);
133
static void dumpAnnotations (J9CfrClassFile* classfile, J9CfrAnnotation *annotations, U_32 annotationCount, U_32 tabLevel);
134
static void dumpTypeAnnotations (J9CfrClassFile* classfile, J9CfrTypeAnnotation *annotations, U_32 annotationCount, U_32 tabLevel);
135
static void printClassFile (J9CfrClassFile* classfile);
136
static void tty_output_char (J9PortLibrary *portLib, const char c);
137
static U_32 buildFlags (void);
138
static void sun_formatBytecode (J9CfrClassFile* classfile, J9CfrMethod* method, BOOLEAN bigEndian, U_8* bcStart, U_8* bytes, U_8 bc, U_32 bytesLength, U_32 decode, char *formatString, IDATA length);
139
static void sun_formatBytecodes (J9CfrClassFile* classfile, J9CfrMethod* method, BOOLEAN bigEndian, U_8* bytecodes, U_32 bytecodesLength, char *formatString, IDATA stringLength);
140
static I_32 processSingleFile (char* requestedFile, U_32 flags);
141
static void j9_formatField (J9ROMClass* romClass, J9ROMFieldShape* field, char *formatString, IDATA length, U_32 flags);
142
static I_32 processAllFiles (char** files, U_32 flags);
143
static void dumpStackMap (J9CfrAttributeStackMap * stackMap, J9CfrClassFile* classfile, U_32 tabLevel);
144
static int parseCommandLine (int argc, char** argv, char** envp);
145
static void dumpAnnotationElement (J9CfrClassFile* classfile, J9CfrAnnotationElement *element, U_32 tabLevel);
146
static void sun_formatMethod (J9CfrClassFile* classfile, J9CfrMethod* method, char *formatString, IDATA length);
147
static I_32 processROMFile (char* requestedFile, U_32 flags);
148
static BOOLEAN validateROMClassAddressRange (J9ROMClass *romClass, void *address, UDATA length, void *userData);
149
static I_32 processROMClass (J9ROMClass* romClass, char* requestedFile, U_32 flags);
150
static void dumpMethod (J9CfrClassFile* classfile, J9CfrMethod* method);
151
static void sun_formatField (J9CfrClassFile* classfile, J9CfrField* field, char *formatString, IDATA length);
152
static void printMethod (J9CfrClassFile* classfile, J9CfrMethod* method);
153
static I_32 processFilesInZIP (char* zipFilename, char** files, U_32 flags);
154
static I_32 processDirectory (char* dir, BOOLEAN recursive, U_32 flags);
155
static void dumpField (J9CfrClassFile* classfile, J9CfrField* field);
156
static void j9_formatBytecode (J9ROMClass* romClass, J9ROMMethod* method, U_8* bcStart, U_8* bytes, U_8 bc, U_32 bytesLength, U_32 decode, char *formatString, IDATA length, U_32 flags);
157
static void j9_formatBytecodes (J9ROMClass* romClass, J9ROMMethod* method, U_8* bytecodes, U_32 bytecodesLength, char *formatString, IDATA stringLength, U_32 flags);
158
static void dumpHelpText ( J9PortLibrary *portLib, int argc, char **argv);
159
static I_32 processAllInZIP (char* zipFilename, U_32 flags);
160
static J9CfrClassFile* loadClassFile (char* requestedFile, U_32* lengthReturn, U_32 flags);
161
static void j9_formatClass (J9ROMClass* romClass, char *formatString, IDATA length, U_32 flags);
162
static J9ROMClass *translateClassBytes (U_8 * data, U_32 dataLength, char *requestedFile, U_32 flags);
163
static void printDisassembledMethod (J9CfrClassFile* classfile, J9CfrMethod* method, BOOLEAN bigEndian, U_8* bytecodes, U_32 bytecodesLength);
164
static void printDisassembledMethods (J9CfrClassFile *classfile);
165
static void dumpClassFile (J9CfrClassFile* classfile);
166
static U_8 * dumpStackMapSlots (J9CfrClassFile* classfile, U_8 * slotData, U_16 slotCount);
167
static I_32 processClassFile (J9CfrClassFile* classfile, U_32 dataLength, char* requestedFile, U_32 flags);
168
static I_32 getBytes (const char* filename, U_8** dataHandle);
169
static void reportClassLoadError (J9CfrError* error, char* requestedFile);
170
static void printField (J9CfrClassFile* classfile, J9CfrField* field);
171
static J9CfrClassFile* loadClassFromBytes (U_8* data, U_32 dataLength, char* requestedFile, U_32 flags);
172
static U_8* loadBytes (char* requestedFile, U_32* lengthReturn, U_32 flags);
173
static void sun_formatClass (J9CfrClassFile* classfile, char *formatString, IDATA length);
174
static I_32 writeOutputFile (U_8 *fileData, U_32 length, char* filename, char *extension);
175
static void dumpAttribute (J9CfrClassFile* classfile, J9CfrAttribute* attrib, U_32 tabLevel);
176
static I_32 convertToClassFilename(const char **files, char ***classFiles, I_32 *fileCount);
177
static I_32 processFilesInJImage(J9JImage *jimage, char* jimageFileName, char** files, U_32 flags);
178
static I_32 convertToJImageLocations(J9JImage *jimage, char **files, JImageMatchInfo ** output, I_32 *fileCount);
179
static I_32 processAllInJImage(J9JImage *jimage, char* jimageFileName, U_32 flags);
180
static void dumpRawData(char *message, U_32 rawDataLength, U_8 *rawData);
181
182
UDATA signalProtectedMain(struct J9PortLibrary *portLibrary, void *arg);
183
184
185
typedef struct
186
{
187
actionType action;
188
sourceType source;
189
I_32 options;
190
I_32 filesStart;
191
char *sourceString;
192
char *actionString;
193
} CFDumpOptions;
194
195
#define j9tty_output_char(c) tty_output_char(PORTLIB, (c))
196
197
#if defined(WIN32) || defined(OS2)
198
#define PATH_SEP_CHAR '\\'
199
#else /* defined(WIN32) || defined(OS2) */
200
#define PATH_SEP_CHAR '/'
201
#endif /* defined(WIN32) || defined(OS2) */
202
203
static J9TranslationBufferSet *translationBuffers;
204
static J9BytecodeVerificationData *verifyBuffers;
205
J9PortLibrary* portLib;
206
CFDumpOptions options;
207
208
static I_32 getBytes(const char* filename, U_8** dataHandle)
209
{
210
U_8* data;
211
U_32 fileSize;
212
I_64 actualFileSize;
213
IDATA fd;
214
215
PORT_ACCESS_FROM_PORT(portLib);
216
217
fd = j9file_open((char*)filename, EsOpenRead, 0);
218
if(fd == -1) {
219
return RET_FILE_OPEN_FAILED;
220
}
221
222
actualFileSize = j9file_seek(fd, 0, EsSeekEnd);
223
/* Restrict file size to < 2G */
224
if ((actualFileSize == -1) || (actualFileSize > J9CONST64(0x7FFFFFFF))) {
225
j9file_close(fd);
226
return RET_FILE_SEEK_FAILED;
227
}
228
fileSize = (U_32) actualFileSize;
229
230
if (j9file_seek(fd, 0, EsSeekSet) == -1) {
231
j9file_close(fd);
232
return RET_FILE_SEEK_FAILED;
233
}
234
235
data = (U_8*)j9mem_allocate_memory(fileSize, J9MEM_CATEGORY_CLASSES);
236
if(data == NULL) {
237
j9file_close(fd);
238
return RET_ALLOCATE_FAILED;
239
}
240
241
if(j9file_read(fd, data, (IDATA)fileSize) != (IDATA)fileSize) {
242
j9file_close(fd);
243
return RET_FILE_READ_FAILED;
244
}
245
246
j9file_close(fd);
247
*dataHandle = data;
248
return (I_32)fileSize;
249
}
250
251
/**
252
* Converts list of class names to file names by converting '.' to '/' and
253
* by appending ".class" extension if not already present.
254
*
255
* @param [in] files list of class names
256
* @param [out] classFiles if not NULL then on exit points to list of converted class file names
257
* @param [out] fileCount size of the list pointed by classFiles
258
*
259
* @return RET_SUCCESS on success, negative error code on failure
260
*/
261
static I_32
262
convertToClassFilename(const char **files, char ***classFiles, I_32 *fileCount) {
263
char **convertedFiles = NULL;
264
char *currentFile = NULL;
265
I_32 count = 0;
266
UDATA size = 0;
267
I_32 i = 0;
268
I_32 result = RET_SUCCESS;
269
UDATA classExtLen = sizeof(CFDUMP_CLASSFILE_EXTENSION) - 1;
270
271
PORT_ACCESS_FROM_PORT(portLib);
272
273
/* Convert the various file specifiers to the expected one -- java/lang/Object.class */
274
currentFile = (char *)files[count];
275
while (NULL != currentFile) {
276
count += 1;
277
size += strlen(currentFile) + classExtLen + 1; /* NULL and potentially the ".class" */
278
currentFile = (char *)files[count];
279
}
280
/*
281
* convertedFiles is an array of pointers with each element pointing to the converted file name.
282
* Just after the array we store the strings for converted file names. So the memory layout is:
283
*
284
* pointer to 1st file name string
285
* pointer to 2nd file name string
286
* ...
287
* pointer to nth file name string
288
* 1st file name string
289
* 2nd file name string
290
* ...
291
* nth file name string
292
*/
293
convertedFiles = j9mem_allocate_memory((count * sizeof(char*)) + size, J9MEM_CATEGORY_CLASSES);
294
if (NULL == convertedFiles) {
295
result = RET_ALLOCATE_FAILED;
296
goto _end;
297
}
298
currentFile = (char *)((U_8 *)convertedFiles + (count * sizeof(char*)));
299
for (i = 0; i < count; i++) {
300
const char *file = files[i];
301
UDATA length = strlen(file);
302
UDATA j = 0;
303
304
if ((length > classExtLen) && !strncmp(&file[length - classExtLen], CFDUMP_CLASSFILE_EXTENSION, classExtLen)) {
305
length -= classExtLen;
306
}
307
for (j = 0; j < length; j++) {
308
if ((file[j] == '.') || (file[j] == '\\')) {
309
currentFile[j] = '/';
310
} else {
311
currentFile[j] = file[j];
312
}
313
}
314
strcpy(&currentFile[length], CFDUMP_CLASSFILE_EXTENSION);
315
currentFile[length + classExtLen] = '\0';
316
convertedFiles[i] = currentFile;
317
currentFile += length + classExtLen + 1; /* ".class" */
318
}
319
320
_end:
321
if (NULL != classFiles) {
322
*classFiles = convertedFiles;
323
}
324
if (NULL != fileCount) {
325
*fileCount = count;
326
}
327
return result;
328
}
329
330
331
/**
332
* Takes a list of class names in the form of package.name.ClassName[.class]
333
* and converts to a list of JImageMatchInfo structs.
334
*
335
* @param [in] jimage The jimage file in which the class is going to be looked up
336
* @param [in] files list of class names to process
337
* @param [out] output if not NULL then on exit points to list of converted class file names. Caller responsible for cleanup
338
* @param [out] fileCount If non-null, number of names processed is written here
339
*
340
* @return RET_SUCCESS on success, negative error code on failure
341
*/
342
static I_32
343
convertToJImageLocations(J9JImage *jimage, char **files, JImageMatchInfo ** output, I_32 *fileCount) {
344
char *currentFile = (char *)files[0];
345
JImageMatchInfo *matchData = NULL;
346
I_32 count = 0;
347
UDATA size = 0;
348
I_32 result = RET_SUCCESS;
349
char * buffer = NULL;
350
I_32 i = 0;
351
352
PORT_ACCESS_FROM_PORT(portLib);
353
354
355
while (NULL != currentFile){
356
count += 1;
357
/* add room for null char */
358
size += strlen(currentFile) + 1;
359
currentFile = (char *)files[count];
360
}
361
362
/* if caller just wants the class count, then we are done */
363
if (NULL == output) {
364
goto _end;
365
}
366
367
matchData = (JImageMatchInfo*) j9mem_allocate_memory((count * sizeof(JImageMatchInfo) + size), J9MEM_CATEGORY_CLASSES);
368
if (NULL == matchData) {
369
result = RET_ALLOCATE_FAILED;
370
j9tty_printf( PORTLIB, "Insufficient memory to complete operation\n");
371
goto _end;
372
}
373
/* We begin putting strings after Match info structs */
374
buffer = (char*) (matchData + count);
375
for (i = 0; i < count; ++i) {
376
char *lastDot = NULL;
377
char * const file = buffer;
378
UDATA length = strlen(files[i]);
379
I_32 charIdx= 0;
380
char currentChar = 0;
381
382
memcpy(file, files[i], length + 1);
383
384
/* Check if input ends with '.class' */
385
if (
386
(length > sizeof(CFDUMP_CLASSFILE_EXTENSION)) &&
387
(0 == strcmp(file + length - sizeof(CFDUMP_CLASSFILE_EXTENSION) + 1, CFDUMP_CLASSFILE_EXTENSION))) {
388
/* ignore the .class extension */
389
file[length - sizeof(CFDUMP_CLASSFILE_EXTENSION)+1] = '\0';
390
}
391
/* Split into package & class */
392
lastDot = strrchr(file, '.');
393
if (NULL == lastDot) {
394
j9tty_printf( PORTLIB, "Failed parsing class %s\n", files[i]);
395
result = RET_PARSE_CLASS_NAME_FAILED;
396
goto _end;
397
}
398
399
*lastDot = '\0';
400
matchData[i].baseString = lastDot + 1;
401
matchData[i].module = j9bcutil_findModuleForPackage(portLib, jimage, file);
402
403
/* replace dots with slashes */
404
while (0 != (currentChar = file[charIdx])) {
405
406
if ('.' == currentChar) {
407
file[charIdx] = '/';
408
}
409
++charIdx;
410
}
411
matchData[i].parentString = file;
412
buffer += length + 1;
413
}
414
415
_end:
416
if (RET_SUCCESS == result){
417
if (NULL != output) {
418
*output = matchData;
419
}
420
if (NULL != fileCount) {
421
*fileCount = count;
422
}
423
} else {
424
/* free copied strings */
425
if (matchData != NULL) {
426
j9mem_free_memory(matchData);
427
}
428
}
429
return result;
430
}
431
432
static void dumpClassFile(J9CfrClassFile* classfile)
433
{
434
U_32 i;
435
U_32 index;
436
437
PORT_ACCESS_FROM_PORT(portLib);
438
439
j9tty_printf( PORTLIB, "Magic: %X\n", classfile->magic);
440
j9tty_printf( PORTLIB, "Version: %i.%i\n", classfile->majorVersion, classfile->minorVersion);
441
j9tty_printf( PORTLIB, "Constant Pool Size: %i\n", classfile->constantPoolCount);
442
j9tty_printf( PORTLIB, "Access Flags: 0x%X ( ", classfile->accessFlags);
443
printModifiers(PORTLIB, classfile->accessFlags, INCLUDE_INTERNAL_MODIFIERS, MODIFIERSOURCE_CLASS);
444
j9tty_printf( PORTLIB, " )\n");
445
index = classfile->constantPool[classfile->thisClass].slot1;
446
j9tty_printf( PORTLIB, "ThisClass: %i -> %s\n", classfile->thisClass, classfile->constantPool[index].bytes);
447
index = classfile->constantPool[classfile->superClass].slot1;
448
j9tty_printf( PORTLIB, "SuperClass: %i -> %s\n", classfile->superClass, classfile->constantPool[index].bytes);
449
j9tty_printf( PORTLIB, "Interfaces (%i):\n", classfile->interfacesCount);
450
for(i = 0; i < classfile->interfacesCount; i++)
451
{
452
index = classfile->constantPool[classfile->interfaces[i]].slot1;
453
j9tty_printf( PORTLIB, " %i -> %s ", classfile->interfaces[i], classfile->constantPool[index].bytes);
454
}
455
j9tty_printf( PORTLIB, "\n");
456
j9tty_printf( PORTLIB, "Fields (%i):\n", classfile->fieldsCount);
457
for(i = 0; i < classfile->fieldsCount; i++)
458
{
459
dumpField(classfile, &(classfile->fields[i]));
460
j9tty_printf( PORTLIB, "\n");
461
}
462
j9tty_printf( PORTLIB, "Methods (%i):\n", classfile->methodsCount);
463
for(i = 0; i < classfile->methodsCount; i++)
464
{
465
dumpMethod(classfile, &(classfile->methods[i]));
466
j9tty_printf( PORTLIB, "\n");
467
}
468
j9tty_printf( PORTLIB, "Attributes (%i):\n", classfile->attributesCount);
469
for(i = 0; i < classfile->attributesCount; i++)
470
{
471
dumpAttribute(classfile, classfile->attributes[i], 1);
472
}
473
j9tty_printf( PORTLIB, "\n");
474
return;
475
}
476
477
478
static void dumpField(J9CfrClassFile* classfile, J9CfrField* field)
479
{
480
U_32 i;
481
482
PORT_ACCESS_FROM_PORT(portLib);
483
484
j9tty_printf( PORTLIB, " Name: %i -> %s\n", field->nameIndex, classfile->constantPool[field->nameIndex].bytes);
485
j9tty_printf( PORTLIB, " Signature: %i -> %s\n", field->descriptorIndex, classfile->constantPool[field->descriptorIndex].bytes);
486
j9tty_printf( PORTLIB, " Access Flags: 0x%X ( ", field->accessFlags);
487
printModifiers(PORTLIB, field->accessFlags, INCLUDE_INTERNAL_MODIFIERS, MODIFIERSOURCE_FIELD);
488
j9tty_printf( PORTLIB, " )\n");
489
j9tty_printf( PORTLIB, " Attributes (%i):\n", field->attributesCount);
490
for(i = 0; i < field->attributesCount; i++)
491
{
492
dumpAttribute(classfile, field->attributes[i], 2);
493
}
494
return;
495
}
496
497
static void dumpRawData(char *message, U_32 rawDataLength, U_8 *rawData) {
498
PORT_ACCESS_FROM_PORT(portLib);
499
U_32 i;
500
j9tty_printf(PORTLIB, "%s:\n", message);
501
for (i = 0; i < rawDataLength; ++i) {
502
j9tty_printf(PORTLIB, "%0x ", rawData[i]);
503
}
504
j9tty_printf(PORTLIB, "\n");
505
506
}
507
508
509
static void dumpMethod(J9CfrClassFile* classfile, J9CfrMethod* method)
510
{
511
U_32 i;
512
513
PORT_ACCESS_FROM_PORT(portLib);
514
515
j9tty_printf( PORTLIB, " Name: %i -> %s\n", method->nameIndex, classfile->constantPool[method->nameIndex].bytes);
516
j9tty_printf( PORTLIB, " Signature: %i -> %s\n", method->descriptorIndex, classfile->constantPool[method->descriptorIndex].bytes);
517
j9tty_printf( PORTLIB, " Access Flags: 0x%X ( ", method->accessFlags);
518
printModifiers(PORTLIB, method->accessFlags, INCLUDE_INTERNAL_MODIFIERS, MODIFIERSOURCE_METHOD);
519
j9tty_printf( PORTLIB, " )\n");
520
j9tty_printf( PORTLIB, " Attributes (%i):\n", method->attributesCount);
521
for(i = 0; i < method->attributesCount; i++)
522
{
523
dumpAttribute(classfile, method->attributes[i], 2);
524
}
525
return;
526
}
527
528
529
static void dumpAttribute(J9CfrClassFile* classfile, J9CfrAttribute* attrib, U_32 tabLevel)
530
{
531
U_16 index, index2;
532
J9CfrAttributeCode* code;
533
J9CfrAttributeInnerClasses* classes;
534
#if JAVA_SPEC_VERSION >= 11
535
J9CfrAttributeNestMembers* nestMembers;
536
U_16 nestMemberCount;
537
#endif /* JAVA_SPEC_VERSION >= 11 */
538
J9CfrAttributeExceptions* exceptions;
539
U_32 i;
540
U_32 j;
541
U_32 maxLength;
542
543
PORT_ACCESS_FROM_PORT(portLib);
544
545
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
546
j9tty_printf( PORTLIB, "%s:\n", classfile->constantPool[attrib->nameIndex].bytes);
547
switch(attrib->tag)
548
{
549
case CFR_ATTRIBUTE_SourceFile:
550
index = ((J9CfrAttributeSourceFile*)attrib)->sourceFileIndex;
551
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
552
j9tty_printf( PORTLIB, "Source File: %i -> %s\n", index, classfile->constantPool[index].bytes);
553
break;
554
555
case CFR_ATTRIBUTE_Signature:
556
index = ((J9CfrAttributeSignature*)attrib)->signatureIndex;
557
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
558
j9tty_printf( PORTLIB, "Signature: %i -> %s\n", index, classfile->constantPool[index].bytes);
559
break;
560
561
case CFR_ATTRIBUTE_ConstantValue:
562
index = ((J9CfrAttributeConstantValue*)attrib)->constantValueIndex;
563
switch(classfile->constantPool[index].tag)
564
{
565
case CFR_CONSTANT_Integer:
566
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
567
j9tty_printf( PORTLIB, "(int) %i\n", classfile->constantPool[index].slot1);
568
break;
569
570
case CFR_CONSTANT_Float:
571
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
572
j9tty_printf( PORTLIB, "(float) 0x%08X\n", classfile->constantPool[index].slot1);
573
break;
574
575
case CFR_CONSTANT_Long:
576
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
577
j9tty_printf( PORTLIB, "(long) 0x%08X%08X\n", classfile->constantPool[index].slot1, classfile->constantPool[index].slot2);
578
break;
579
580
case CFR_CONSTANT_Double:
581
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
582
j9tty_printf( PORTLIB, "(double) 0x%08X%08X\n", classfile->constantPool[index].slot1, classfile->constantPool[index].slot2);
583
break;
584
585
case CFR_CONSTANT_String:
586
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
587
index = classfile->constantPool[index].slot1;
588
j9tty_printf( PORTLIB, "(java.lang.String) %s\n", classfile->constantPool[index].bytes);
589
break;
590
}
591
break;
592
593
case CFR_ATTRIBUTE_Code:
594
code = (J9CfrAttributeCode*)attrib;
595
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
596
j9tty_printf( PORTLIB, "Max stack: %i\n", code->maxStack);
597
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
598
j9tty_printf( PORTLIB, "Max Locals: %i\n", code->maxLocals);
599
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
600
j9tty_printf( PORTLIB, "Code Length: %i\n", code->codeLength);
601
602
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
603
j9tty_printf( PORTLIB, "Caught Exceptions (%i):\n", code->exceptionTableLength);
604
for(j = 0; j < code->exceptionTableLength; j++)
605
{
606
for(i = 0; i < tabLevel + 2; i++) j9tty_printf( PORTLIB, " ");
607
index = code->exceptionTable[j].catchType;
608
if(index == 0)
609
j9tty_printf( PORTLIB, "from %i to %i goto %i when (any) \n", code->exceptionTable[j].startPC, code->exceptionTable[j].endPC, code->exceptionTable[j].handlerPC);
610
else
611
{
612
index = classfile->constantPool[code->exceptionTable[j].catchType].slot1;
613
j9tty_printf( PORTLIB, "from %i to %i goto %i when %i -> %s\n", code->exceptionTable[j].startPC, code->exceptionTable[j].endPC, code->exceptionTable[j].handlerPC, index, classfile->constantPool[index].bytes);
614
}
615
}
616
617
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
618
j9tty_printf( PORTLIB, "Attributes (%i):\n", code->attributesCount);
619
for(j = 0; j < code->attributesCount; j++)
620
dumpAttribute(classfile, code->attributes[j], tabLevel + 2);
621
break;
622
623
case CFR_ATTRIBUTE_Exceptions:
624
exceptions = (J9CfrAttributeExceptions*)attrib;
625
for(i = 0; i < exceptions->numberOfExceptions; i++)
626
{
627
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
628
index = classfile->constantPool[exceptions->exceptionIndexTable[i]].slot1;
629
j9tty_printf( PORTLIB, "%i -> %s\n", exceptions->exceptionIndexTable[i], classfile->constantPool[index].bytes);
630
}
631
break;
632
633
case CFR_ATTRIBUTE_InnerClasses:
634
classes = (J9CfrAttributeInnerClasses*)attrib;
635
for(i = 0; i < classes->numberOfClasses; i++)
636
{
637
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
638
index = classfile->constantPool[classes->classes[i].innerClassInfoIndex].slot1;
639
j9tty_printf( PORTLIB, "Inner Class: %i -> %s\n", classes->classes[i].innerClassInfoIndex, classfile->constantPool[index].bytes);
640
641
for(j = 0; j < tabLevel + 2; j++) j9tty_printf( PORTLIB, " ");
642
if(classes->classes[i].outerClassInfoIndex == 0)
643
{
644
j9tty_printf( PORTLIB, "Outer Class: (not a member)\n");
645
}
646
else
647
{
648
index = classfile->constantPool[classes->classes[i].outerClassInfoIndex].slot1;
649
j9tty_printf( PORTLIB, "Outer Class: %i -> %s\n", classes->classes[i].outerClassInfoIndex, classfile->constantPool[index].bytes);
650
}
651
652
for(j = 0; j < tabLevel + 2; j++) j9tty_printf( PORTLIB, " ");
653
index = classes->classes[i].innerNameIndex;
654
if(index == 0)
655
{
656
j9tty_printf( PORTLIB, "Inner Name: (anonymous)\n");
657
}
658
else
659
{
660
j9tty_printf( PORTLIB, "Inner Name: %i -> %s\n", index, classfile->constantPool[index].bytes);
661
}
662
663
for(j = 0; j < tabLevel + 2; j++) j9tty_printf( PORTLIB, " ");
664
j9tty_printf( PORTLIB, "Inner Class Access Flags: 0x%X ( ", classes->classes[i].innerClassAccessFlags);
665
printModifiers(PORTLIB, classes->classes[i].innerClassAccessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_CLASS);
666
j9tty_printf( PORTLIB, " )\n");
667
}
668
break;
669
670
#if JAVA_SPEC_VERSION >= 11
671
case CFR_ATTRIBUTE_NestMembers: {
672
nestMembers = (J9CfrAttributeNestMembers*)attrib;
673
nestMemberCount = nestMembers->numberOfClasses;
674
675
for (j = 0; j < nestMemberCount; j++) {
676
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
677
index = nestMembers->classes[j];
678
j9tty_printf( PORTLIB, "%i -> %s\n", index, classfile->constantPool[classfile->constantPool[index].slot1].bytes);
679
}
680
break;
681
}
682
683
case CFR_ATTRIBUTE_NestHost: {
684
index = ((J9CfrAttributeNestHost*)attrib)->hostClassIndex;
685
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
686
j9tty_printf( PORTLIB, "%i -> %s\n", index, classfile->constantPool[classfile->constantPool[index].slot1].bytes);
687
break;
688
}
689
#endif /* JAVA_SPEC_VERSION >= 11 */
690
691
case CFR_ATTRIBUTE_LineNumberTable:
692
for(i = 0; i < ((J9CfrAttributeLineNumberTable*)attrib)->lineNumberTableLength; i++)
693
{
694
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
695
j9tty_printf( PORTLIB, "pc: %i line number: %i\n", ((J9CfrAttributeLineNumberTable*)attrib)->lineNumberTable[i].startPC, ((J9CfrAttributeLineNumberTable*)attrib)->lineNumberTable[i].lineNumber);
696
}
697
break;
698
699
case CFR_ATTRIBUTE_LocalVariableTable:
700
for(i = 0; i < ((J9CfrAttributeLocalVariableTable*)attrib)->localVariableTableLength; i++)
701
{
702
index = ((J9CfrAttributeLocalVariableTable*)attrib)->localVariableTable[i].nameIndex;
703
index2 = ((J9CfrAttributeLocalVariableTable*)attrib)->localVariableTable[i].descriptorIndex;
704
705
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
706
j9tty_printf( PORTLIB, "from %i to %i slot %i is %i -> %s type %i -> %s\n",
707
((J9CfrAttributeLocalVariableTable*)attrib)->localVariableTable[i].startPC,
708
((J9CfrAttributeLocalVariableTable*)attrib)->localVariableTable[i].startPC + ((J9CfrAttributeLocalVariableTable*)attrib)->localVariableTable[i].length,
709
((J9CfrAttributeLocalVariableTable*)attrib)->localVariableTable[i].index,
710
index,
711
classfile->constantPool[index].bytes,
712
index2,
713
classfile->constantPool[index2].bytes,
714
0);
715
}
716
break;
717
718
case CFR_ATTRIBUTE_LocalVariableTypeTable:
719
for(i = 0; i < ((J9CfrAttributeLocalVariableTypeTable*)attrib)->localVariableTypeTableLength; i++)
720
{
721
index = ((J9CfrAttributeLocalVariableTypeTable*)attrib)->localVariableTypeTable[i].nameIndex;
722
index2 = ((J9CfrAttributeLocalVariableTypeTable*)attrib)->localVariableTypeTable[i].signatureIndex;
723
724
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
725
j9tty_printf( PORTLIB, "from %i to %i slot %i is %i -> %s type %i -> %s\n",
726
((J9CfrAttributeLocalVariableTypeTable*)attrib)->localVariableTypeTable[i].startPC,
727
((J9CfrAttributeLocalVariableTypeTable*)attrib)->localVariableTypeTable[i].startPC
728
+ ((J9CfrAttributeLocalVariableTypeTable*)attrib)->localVariableTypeTable[i].length,
729
((J9CfrAttributeLocalVariableTypeTable*)attrib)->localVariableTypeTable[i].index,
730
index,
731
classfile->constantPool[index].bytes,
732
index2,
733
classfile->constantPool[index2].bytes,
734
0);
735
}
736
break;
737
738
case CFR_ATTRIBUTE_AnnotationDefault:
739
dumpAnnotationElement(classfile, ((J9CfrAttributeAnnotationDefault *)attrib)->defaultValue, tabLevel + 1);
740
break;
741
742
case CFR_ATTRIBUTE_RuntimeVisibleAnnotations:
743
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
744
j9tty_printf( PORTLIB, "Annotations (%i):\n", ((J9CfrAttributeRuntimeVisibleAnnotations *)attrib)->numberOfAnnotations);
745
746
dumpAnnotations(classfile, ((J9CfrAttributeRuntimeVisibleAnnotations *)attrib)->annotations,
747
((J9CfrAttributeRuntimeVisibleAnnotations *)attrib)->numberOfAnnotations, tabLevel + 2);
748
break;
749
750
case CFR_ATTRIBUTE_RuntimeInvisibleAnnotations:
751
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
752
j9tty_printf( PORTLIB, "Annotations (%i):\n", ((J9CfrAttributeRuntimeInvisibleAnnotations *)attrib)->numberOfAnnotations);
753
754
dumpAnnotations(classfile, ((J9CfrAttributeRuntimeInvisibleAnnotations *)attrib)->annotations,
755
((J9CfrAttributeRuntimeInvisibleAnnotations *)attrib)->numberOfAnnotations, tabLevel + 1);
756
break;
757
758
case CFR_ATTRIBUTE_RuntimeVisibleTypeAnnotations: {
759
J9CfrAttributeRuntimeVisibleTypeAnnotations *annotations = (J9CfrAttributeRuntimeVisibleTypeAnnotations *)attrib;
760
if (0 == annotations->rawDataLength) { /* the attribute was well-formed */
761
dumpTypeAnnotations(classfile, annotations->typeAnnotations,
762
annotations->numberOfAnnotations, tabLevel + 1);
763
} else {
764
dumpRawData("Malformed RuntimeVisibleTypeAnnotations attribute", annotations->rawDataLength,annotations->rawAttributeData);
765
}
766
}
767
768
break;
769
770
case CFR_ATTRIBUTE_RuntimeInvisibleTypeAnnotations: {
771
J9CfrAttributeRuntimeInvisibleTypeAnnotations *annotations = (J9CfrAttributeRuntimeInvisibleTypeAnnotations *)attrib;
772
if (0 == annotations->rawDataLength) { /* the attribute was well-formed */
773
dumpTypeAnnotations(classfile, annotations->typeAnnotations,
774
annotations->numberOfAnnotations, tabLevel + 1);
775
} else {
776
dumpRawData("Malformed RuntimeInvisibleTypeAnnotations attribute", annotations->rawDataLength,annotations->rawAttributeData);
777
}
778
}
779
break;
780
781
case CFR_ATTRIBUTE_MethodParameters: {
782
const char *noName = "<no name>";
783
784
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
785
786
maxLength = 0;
787
for (i = 0; i < ((J9CfrAttributeMethodParameters *)attrib)->numberOfMethodParameters; i++) {
788
U_8 *bytes = (U_8*)noName;
789
U_16 index = ((J9CfrAttributeMethodParameters *)attrib)->methodParametersIndexTable[i];
790
U_32 bytesLen = 0;
791
if (0 != index) {
792
bytes = classfile->constantPool[((J9CfrAttributeMethodParameters *)attrib)->methodParametersIndexTable[i]].bytes;
793
}
794
bytesLen = (U_32)strlen((const char*)bytes);
795
if (maxLength < bytesLen) {
796
maxLength = bytesLen;
797
}
798
}
799
j9tty_printf( PORTLIB, "Name");
800
/* Flags start point is (maxLength + Name.length) from the start point of Name string
801
* Name<------------Space1-->Flags
802
* ParameterName<---Space2-->FlagValue
803
*
804
* Space1 == maxLength
805
* Name.length + Space1 == ParameterName.length + Space2
806
*
807
*/
808
for(j = 0; j < maxLength; j++) j9tty_printf( PORTLIB, " ");
809
j9tty_printf( PORTLIB, " Flags\n");
810
for (i = 0; i < ((J9CfrAttributeMethodParameters *)attrib)->numberOfMethodParameters; i++) {
811
U_8 *bytes = (U_8*)noName;
812
U_16 index = ((J9CfrAttributeMethodParameters *)attrib)->methodParametersIndexTable[i];
813
if (0 != index) {
814
bytes = classfile->constantPool[((J9CfrAttributeMethodParameters *)attrib)->methodParametersIndexTable[i]].bytes;
815
}
816
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
817
j9tty_printf( PORTLIB, "%i -> %s", ((J9CfrAttributeMethodParameters *)attrib)->methodParametersIndexTable[i], bytes);
818
if (0 != ((J9CfrAttributeMethodParameters *)attrib)->flags[i]) {
819
for(j = 0; j < maxLength - ((U_32)strlen((const char*)bytes)) + ((U_32)strlen("Name")); j++) j9tty_printf( PORTLIB, " ");
820
j9tty_printf( PORTLIB, "0x%x ( ", ((J9CfrAttributeMethodParameters *)attrib)->flags[i]);
821
printModifiers(PORTLIB, ((J9CfrAttributeMethodParameters *)attrib)->flags[i], ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_METHODPARAMETER);
822
j9tty_printf( PORTLIB, " )\n");
823
} else {
824
j9tty_printf( PORTLIB, "\n");
825
}
826
}
827
break;
828
}
829
830
case CFR_ATTRIBUTE_RuntimeVisibleParameterAnnotations: {
831
J9CfrAttributeRuntimeVisibleParameterAnnotations *annotations = (J9CfrAttributeRuntimeVisibleParameterAnnotations *)attrib;
832
if (0 == annotations->rawDataLength) { /* the attribute was well-formed */
833
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
834
j9tty_printf( PORTLIB, "Parameter Count (%i):\n", annotations->numberOfParameters);
835
836
for (i = 0; i < annotations->numberOfParameters; i++) {
837
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
838
j9tty_printf( PORTLIB, "Annotations (%i):\n", annotations->parameterAnnotations->numberOfAnnotations);
839
dumpAnnotations(classfile, annotations->parameterAnnotations->annotations,
840
annotations->parameterAnnotations->numberOfAnnotations, tabLevel + 1);
841
}
842
} else {
843
dumpRawData("Malformed RuntimeVisibleParameterAnnotations attribute", annotations->rawDataLength,annotations->rawAttributeData);
844
}
845
}
846
847
break;
848
849
case CFR_ATTRIBUTE_RuntimeInvisibleParameterAnnotations: {
850
J9CfrAttributeRuntimeInvisibleParameterAnnotations *annotations = (J9CfrAttributeRuntimeInvisibleParameterAnnotations *)attrib;
851
if (0 == annotations->rawDataLength) { /* the attribute was well-formed */
852
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
853
j9tty_printf( PORTLIB, "Parameter Count (%i):\n", annotations->numberOfParameters);
854
855
for (i = 0; i < annotations->numberOfParameters; i++) {
856
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
857
j9tty_printf( PORTLIB, "Annotations (%i):\n", annotations->parameterAnnotations->numberOfAnnotations);
858
dumpAnnotations(classfile, annotations->parameterAnnotations->annotations,
859
annotations->parameterAnnotations->numberOfAnnotations, tabLevel + 1);
860
}
861
} else {
862
dumpRawData("Malformed RuntimeInvisibleParameterAnnotations attribute", annotations->rawDataLength,annotations->rawAttributeData);
863
}
864
}
865
866
break;
867
868
case CFR_ATTRIBUTE_EnclosingMethod:
869
index = ((J9CfrAttributeEnclosingMethod *)attrib)->classIndex;
870
index2 = classfile->constantPool[index].slot1;
871
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
872
j9tty_printf( PORTLIB, "Class: %i -> %s\n", index, classfile->constantPool[index2].bytes);
873
874
index = ((J9CfrAttributeEnclosingMethod *)attrib)->methodIndex;
875
index2 = classfile->constantPool[index].slot1;
876
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
877
878
/* If EnclosingMethod is a static initializer or clinit it will not have a method index */
879
if (index2 != 0) {
880
j9tty_printf( PORTLIB, "Method: %i -> %s\n", index, classfile->constantPool[index2].bytes);
881
} else {
882
j9tty_printf( PORTLIB, "Method: (none)\n");
883
}
884
break;
885
886
case CFR_ATTRIBUTE_StackMap:
887
case CFR_ATTRIBUTE_StackMapTable:
888
for(i = 0; i < tabLevel + 1; i++) j9tty_printf( PORTLIB, " ");
889
index = ((J9CfrAttributeStackMap *)attrib)->numberOfEntries;
890
j9tty_printf( PORTLIB, "Stackmaps (%i):\n", index);
891
dumpStackMap((J9CfrAttributeStackMap *)attrib, classfile, tabLevel + 2);
892
break;
893
894
case CFR_ATTRIBUTE_Record:
895
for(i = 0; i < ((J9CfrAttributeRecord*)attrib)->numberOfRecordComponents; i++) {
896
J9CfrRecordComponent* recordComponent = &(((J9CfrAttributeRecord*)attrib)->recordComponents[i]);
897
898
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
899
j9tty_printf( PORTLIB, "Record Component Name: %i -> %s\n", recordComponent->nameIndex, classfile->constantPool[recordComponent->nameIndex].bytes);
900
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
901
j9tty_printf( PORTLIB, "Record Component Signature: %i -> %s\n", recordComponent->descriptorIndex, classfile->constantPool[recordComponent->descriptorIndex].bytes);
902
903
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
904
j9tty_printf( PORTLIB, "Attributes (%i):\n", recordComponent->attributesCount);
905
for(j = 0; j < recordComponent->attributesCount; j++)
906
dumpAttribute(classfile, recordComponent->attributes[j], tabLevel + 2);
907
}
908
break;
909
910
case CFR_ATTRIBUTE_PermittedSubclasses:
911
for(i = 0; i < ((J9CfrAttributePermittedSubclasses*)attrib)->numberOfClasses; i++) {
912
U_16 classIndex = ((J9CfrAttributePermittedSubclasses*)attrib)->classes[i];
913
U_16 nameIndex = classfile->constantPool[classIndex].slot1;
914
915
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
916
j9tty_printf( PORTLIB, "PermittedSubclass class index, name: %i, %i -> %s\n", classIndex, nameIndex, classfile->constantPool[nameIndex].bytes);
917
}
918
break;
919
920
case CFR_ATTRIBUTE_StrippedLineNumberTable:
921
case CFR_ATTRIBUTE_StrippedLocalVariableTable:
922
case CFR_ATTRIBUTE_StrippedLocalVariableTypeTable:
923
case CFR_ATTRIBUTE_StrippedInnerClasses:
924
case CFR_ATTRIBUTE_StrippedUnknown:
925
for(j = 0; j < tabLevel + 1; j++) j9tty_printf( PORTLIB, " ");
926
j9tty_printf( PORTLIB, "Attribute data stripped\n");
927
break;
928
929
case CFR_ATTRIBUTE_Unknown:
930
case CFR_ATTRIBUTE_Synthetic:
931
case CFR_ATTRIBUTE_Deprecated:
932
default:
933
break;
934
}
935
return;
936
}
937
938
939
static void printClassFile(J9CfrClassFile* classfile)
940
{
941
U_16 index;
942
U_8* string;
943
I_32 i, j, k;
944
945
PORT_ACCESS_FROM_PORT(portLib);
946
947
if(classfile->accessFlags & CFR_ACC_PUBLIC) j9tty_printf( PORTLIB, "public ");
948
if(classfile->accessFlags & CFR_ACC_PRIVATE) j9tty_printf( PORTLIB, "protected ");
949
if(classfile->accessFlags & CFR_ACC_PROTECTED) j9tty_printf( PORTLIB, "private ");
950
/* JEP 360: note: non-sealed will not be indicated for subclasses. There's no way of knowing until classes are linked. */
951
if(classfile->j9Flags & CFR_J9FLAG_IS_SEALED) j9tty_printf( PORTLIB, "sealed ");
952
if(classfile->accessFlags & CFR_ACC_INTERFACE)
953
j9tty_printf( PORTLIB, "interface ");
954
else if (classfile->j9Flags & CFR_J9FLAG_IS_RECORD)
955
{
956
j9tty_printf( PORTLIB, "record ");
957
}
958
else
959
{
960
if(classfile->accessFlags & CFR_ACC_ABSTRACT) j9tty_printf( PORTLIB, "abstract ");
961
j9tty_printf( PORTLIB, "class ");
962
}
963
964
index = classfile->constantPool[classfile->thisClass].slot1;
965
string = classfile->constantPool[index].bytes;
966
i = 0;
967
while(string[i])
968
{
969
j9tty_printf( PORTLIB, "%c", (string[i] == '/')?'.':string[i]);
970
i++;
971
}
972
973
if(classfile->superClass != 0)
974
{
975
index = classfile->constantPool[classfile->superClass].slot1;
976
string = classfile->constantPool[index].bytes;
977
j9tty_printf( PORTLIB, " extends ");
978
i = 0;
979
while(string[i])
980
{
981
j9tty_printf( PORTLIB, "%c", (string[i] == '/')?'.':string[i]);
982
i++;
983
}
984
}
985
986
if(classfile->interfacesCount > 0)
987
{
988
j9tty_printf( PORTLIB, " implements ");
989
for(i = 0; i < classfile->interfacesCount - 1; i++)
990
{
991
index = classfile->constantPool[classfile->interfaces[i]].slot1;
992
string = classfile->constantPool[index].bytes;
993
j = 0;
994
while(string[j])
995
{
996
j9tty_printf( PORTLIB, "%c", (string[j] == '/')?'.':string[j]);
997
j++;
998
}
999
j9tty_printf( PORTLIB, ", ");
1000
}
1001
index = classfile->constantPool[classfile->interfaces[i]].slot1;
1002
string = classfile->constantPool[index].bytes;
1003
j = 0;
1004
while(string[j])
1005
{
1006
j9tty_printf( PORTLIB, "%c", (string[j] == '/')?'.':string[j]);
1007
j++;
1008
}
1009
}
1010
1011
/* JEP 360: sealed class permits list */
1012
if(classfile->j9Flags & CFR_J9FLAG_IS_SEALED) {
1013
/* find PermittedSubclasses attribute */
1014
for (i = 0; i < classfile->attributesCount; i++) {
1015
if (CFR_ATTRIBUTE_PermittedSubclasses == classfile->attributes[i]->tag) {
1016
/* found attribute, print permitted subclasses */
1017
j9tty_printf( PORTLIB, " permits ");
1018
1019
for (j = 0; j < ((J9CfrAttributePermittedSubclasses*)classfile->attributes[i])->numberOfClasses; j++) {
1020
/* class index */
1021
index = ((J9CfrAttributePermittedSubclasses*)classfile->attributes[i])->classes[j];
1022
/* class name index */
1023
index = classfile->constantPool[index].slot1;
1024
string = classfile->constantPool[index].bytes;
1025
1026
k = 0;
1027
while('\0' != string[k]) {
1028
j9tty_printf( PORTLIB, "%c", (string[k] == '/') ? '.' : string[k]);
1029
k++;
1030
}
1031
if ((j + 1) != ((J9CfrAttributePermittedSubclasses*)classfile->attributes[i])->numberOfClasses) j9tty_printf( PORTLIB, ", ");
1032
}
1033
break;
1034
}
1035
}
1036
}
1037
1038
1039
j9tty_printf( PORTLIB, "\n{\n");
1040
1041
for(i = 0; i < classfile->fieldsCount; i++)
1042
printField(classfile, &(classfile->fields[i]));
1043
1044
if((classfile->fieldsCount > 0)&&(classfile->methodsCount > 0))
1045
j9tty_printf( PORTLIB, "\n");
1046
1047
for(i = 0; i < classfile->methodsCount; i++)
1048
printMethod(classfile, &(classfile->methods[i]));
1049
1050
j9tty_printf( PORTLIB, "}\n");
1051
return;
1052
}
1053
1054
1055
static void printMethod(J9CfrClassFile* classfile, J9CfrMethod* method)
1056
{
1057
U_8* string;
1058
J9CfrAttributeExceptions* exceptions;
1059
U_16 index;
1060
I_32 arity, i, j;
1061
1062
PORT_ACCESS_FROM_PORT(portLib);
1063
1064
j9tty_printf( PORTLIB, " ");
1065
1066
/* Access flags. */
1067
if(method->accessFlags & CFR_ACC_PUBLIC) j9tty_printf( PORTLIB, "public ");
1068
if(method->accessFlags & CFR_ACC_PRIVATE) j9tty_printf( PORTLIB, "private ");
1069
if(method->accessFlags & CFR_ACC_PROTECTED) j9tty_printf( PORTLIB, "protected ");
1070
if(method->accessFlags & CFR_ACC_STATIC) j9tty_printf( PORTLIB, "static ");
1071
if(method->accessFlags & CFR_ACC_FINAL) j9tty_printf( PORTLIB, "final ");
1072
if(method->accessFlags & CFR_ACC_SYNCHRONIZED) j9tty_printf( PORTLIB, "synchronized ");
1073
if(method->accessFlags & CFR_ACC_NATIVE) j9tty_printf( PORTLIB, "native ");
1074
if(method->accessFlags & CFR_ACC_ABSTRACT) j9tty_printf( PORTLIB, "abstract ");
1075
if(method->accessFlags & CFR_ACC_STRICT) j9tty_printf( PORTLIB, "strict ");
1076
1077
/* Return type. */
1078
string = classfile->constantPool[method->descriptorIndex].bytes;
1079
i = 0;
1080
while(string[i++] != ')');
1081
arity = 0;
1082
while(string[i] == '[') arity++, i++;
1083
switch(string[i])
1084
{
1085
case 'B':
1086
j9tty_printf( PORTLIB, "byte");
1087
break;
1088
1089
case 'C':
1090
j9tty_printf( PORTLIB, "char");
1091
break;
1092
1093
case 'D':
1094
j9tty_printf( PORTLIB, "double");
1095
break;
1096
1097
case 'F':
1098
j9tty_printf( PORTLIB, "float");
1099
break;
1100
1101
case 'I':
1102
j9tty_printf( PORTLIB, "int");
1103
break;
1104
1105
case 'J':
1106
j9tty_printf( PORTLIB, "long");
1107
break;
1108
1109
case 'L':
1110
i++;
1111
while(string[i] != ';')
1112
{
1113
j9tty_printf( PORTLIB, "%c", (string[i] == '/')?'.':string[i]);
1114
i++;
1115
}
1116
break;
1117
1118
case 'S':
1119
j9tty_printf( PORTLIB, "short");
1120
break;
1121
1122
case 'V':
1123
j9tty_printf( PORTLIB, "void");
1124
break;
1125
1126
case 'Z':
1127
j9tty_printf( PORTLIB, "boolean");
1128
break;
1129
}
1130
for(i = 0; i < arity; i++)
1131
j9tty_printf( PORTLIB, "[]");
1132
1133
j9tty_printf( PORTLIB, " %s(", classfile->constantPool[method->nameIndex].bytes);
1134
1135
for(i = 1; string[i] != ')'; i++)
1136
{
1137
arity = 0;
1138
while(string[i] == '[') arity++, i++;
1139
switch(string[i])
1140
{
1141
case 'B':
1142
j9tty_printf( PORTLIB, "byte");
1143
break;
1144
1145
case 'C':
1146
j9tty_printf( PORTLIB, "char");
1147
break;
1148
1149
case 'D':
1150
j9tty_printf( PORTLIB, "double");
1151
break;
1152
1153
case 'F':
1154
j9tty_printf( PORTLIB, "float");
1155
break;
1156
1157
case 'I':
1158
j9tty_printf( PORTLIB, "int");
1159
break;
1160
1161
case 'J':
1162
j9tty_printf( PORTLIB, "long");
1163
break;
1164
1165
case 'L':
1166
i++;
1167
while(string[i] != ';')
1168
{
1169
j9tty_printf( PORTLIB, "%c", (string[i] == '/')?'.':string[i]);
1170
i++;
1171
}
1172
break;
1173
1174
case 'S':
1175
j9tty_printf( PORTLIB, "short");
1176
break;
1177
1178
case 'V':
1179
j9tty_printf( PORTLIB, "void");
1180
break;
1181
1182
case 'Z':
1183
j9tty_printf( PORTLIB, "boolean");
1184
break;
1185
}
1186
for(j = 0; j < arity; j++)
1187
j9tty_printf( PORTLIB, "[]");
1188
1189
if(string[i + 1] != ')')
1190
j9tty_printf( PORTLIB, ", ");
1191
}
1192
1193
j9tty_printf( PORTLIB, ")");
1194
1195
for(i = 0; i < method->attributesCount; i++)
1196
{
1197
if(method->attributes[i]->tag == CFR_ATTRIBUTE_Exceptions)
1198
{
1199
exceptions = (J9CfrAttributeExceptions*)method->attributes[i];
1200
1201
if (exceptions && exceptions->numberOfExceptions)
1202
{
1203
j9tty_printf( PORTLIB, " throws ");
1204
for(j = 0; j < exceptions->numberOfExceptions;)
1205
{
1206
if(exceptions->exceptionIndexTable[j] != 0)
1207
{
1208
index = classfile->constantPool[exceptions->exceptionIndexTable[j]].slot1;
1209
string = classfile->constantPool[index].bytes;
1210
while(*string)
1211
{
1212
j9tty_printf( PORTLIB, "%c", (*string == '/')?'.':*string);
1213
string++;
1214
}
1215
if (++j != exceptions->numberOfExceptions)
1216
{
1217
j9tty_printf( PORTLIB, ", ");
1218
}
1219
}
1220
}
1221
}
1222
1223
i = method->attributesCount;
1224
}
1225
}
1226
1227
j9tty_printf( PORTLIB, ";\n");
1228
return;
1229
}
1230
1231
1232
static void printField(J9CfrClassFile* classfile, J9CfrField* field)
1233
{
1234
U_8* string;
1235
U_32 arity, i;
1236
1237
PORT_ACCESS_FROM_PORT(portLib);
1238
1239
j9tty_printf( PORTLIB, " ");
1240
1241
/* Access flags. */
1242
if(field->accessFlags & CFR_ACC_PUBLIC) j9tty_printf( PORTLIB, "public ");
1243
if(field->accessFlags & CFR_ACC_PRIVATE) j9tty_printf( PORTLIB, "private ");
1244
if(field->accessFlags & CFR_ACC_PROTECTED) j9tty_printf( PORTLIB, "protected ");
1245
if(field->accessFlags & CFR_ACC_STATIC) j9tty_printf( PORTLIB, "static ");
1246
if(field->accessFlags & CFR_ACC_FINAL) j9tty_printf( PORTLIB, "final ");
1247
if(field->accessFlags & CFR_ACC_VOLATILE) j9tty_printf( PORTLIB, "volatile ");
1248
if(field->accessFlags & CFR_ACC_TRANSIENT) j9tty_printf( PORTLIB, "transient ");
1249
1250
/* Return type. */
1251
string = classfile->constantPool[field->descriptorIndex].bytes;
1252
i = 0;
1253
arity = 0;
1254
while(string[i] == '[') arity++, i++;
1255
switch(string[i])
1256
{
1257
case 'B':
1258
j9tty_printf( PORTLIB, "byte");
1259
break;
1260
1261
case 'C':
1262
j9tty_printf( PORTLIB, "char");
1263
break;
1264
1265
case 'D':
1266
j9tty_printf( PORTLIB, "double");
1267
break;
1268
1269
case 'F':
1270
j9tty_printf( PORTLIB, "float");
1271
break;
1272
1273
case 'I':
1274
j9tty_printf( PORTLIB, "int");
1275
break;
1276
1277
case 'J':
1278
j9tty_printf( PORTLIB, "long");
1279
break;
1280
1281
case 'L':
1282
i++;
1283
while(string[i] != ';')
1284
{
1285
j9tty_printf( PORTLIB, "%c", (string[i] == '/')?'.':string[i]);
1286
i++;
1287
}
1288
break;
1289
1290
case 'S':
1291
j9tty_printf( PORTLIB, "short");
1292
break;
1293
1294
case 'V':
1295
j9tty_printf( PORTLIB, "void");
1296
break;
1297
1298
case 'Z':
1299
j9tty_printf( PORTLIB, "boolean");
1300
break;
1301
}
1302
for(i = 0; i < arity; i++)
1303
j9tty_printf( PORTLIB, "[]");
1304
1305
j9tty_printf( PORTLIB, " %s;\n", classfile->constantPool[field->nameIndex].bytes);
1306
1307
return;
1308
}
1309
1310
1311
static void printDisassembledMethod(J9CfrClassFile* classfile, J9CfrMethod* method, BOOLEAN bigEndian, U_8* bytecodes, U_32 bytecodesLength)
1312
{
1313
U_8* string;
1314
J9CfrAttributeExceptions* exceptions;
1315
J9CfrAttributeCode* code;
1316
J9CfrConstantPoolInfo info;
1317
I_32 arity, i, j;
1318
U_8* bcIndex;
1319
I_32 pc, index, target, start;
1320
I_32 low, high;
1321
U_32 length, npairs;
1322
U_8 bc;
1323
BOOLEAN fieldFlag;
1324
BOOLEAN wide;
1325
1326
PORT_ACCESS_FROM_PORT(portLib);
1327
1328
if(!(code = method->codeAttribute))
1329
{
1330
return;
1331
}
1332
1333
/* Access flags. */
1334
if(method->accessFlags & CFR_ACC_PUBLIC) j9tty_printf( PORTLIB, "public ");
1335
if(method->accessFlags & CFR_ACC_PRIVATE) j9tty_printf( PORTLIB, "private ");
1336
if(method->accessFlags & CFR_ACC_PROTECTED) j9tty_printf( PORTLIB, "protected ");
1337
if(method->accessFlags & CFR_ACC_STATIC) j9tty_printf( PORTLIB, "static ");
1338
if(method->accessFlags & CFR_ACC_FINAL) j9tty_printf( PORTLIB, "final ");
1339
if(method->accessFlags & CFR_ACC_SYNCHRONIZED) j9tty_printf( PORTLIB, "synchronized ");
1340
if(method->accessFlags & CFR_ACC_NATIVE) j9tty_printf( PORTLIB, "native ");
1341
if(method->accessFlags & CFR_ACC_ABSTRACT) j9tty_printf( PORTLIB, "abstract ");
1342
1343
/* Return type. */
1344
string = classfile->constantPool[method->descriptorIndex].bytes;
1345
i = 0;
1346
while(string[i++] != ')');
1347
arity = 0;
1348
while(string[i] == '[') arity++, i++;
1349
switch(string[i])
1350
{
1351
case 'B':
1352
j9tty_printf( PORTLIB, "byte");
1353
break;
1354
1355
case 'C':
1356
j9tty_printf( PORTLIB, "char");
1357
break;
1358
1359
case 'D':
1360
j9tty_printf( PORTLIB, "double");
1361
break;
1362
1363
case 'F':
1364
j9tty_printf( PORTLIB, "float");
1365
break;
1366
1367
case 'I':
1368
j9tty_printf( PORTLIB, "int");
1369
break;
1370
1371
case 'J':
1372
j9tty_printf( PORTLIB, "long");
1373
break;
1374
1375
case 'L':
1376
i++;
1377
while(string[i] != ';')
1378
{
1379
j9tty_printf( PORTLIB, "%c", (string[i] == '/')?'.':string[i]);
1380
i++;
1381
}
1382
break;
1383
1384
case 'S':
1385
j9tty_printf( PORTLIB, "short");
1386
break;
1387
1388
case 'V':
1389
j9tty_printf( PORTLIB, "void");
1390
break;
1391
1392
case 'Z':
1393
j9tty_printf( PORTLIB, "boolean");
1394
break;
1395
}
1396
for(i = 0; i < arity; i++)
1397
j9tty_printf( PORTLIB, "[]");
1398
1399
j9tty_printf( PORTLIB, " %s(", classfile->constantPool[method->nameIndex].bytes);
1400
1401
for(i = 1; string[i] != ')'; i++)
1402
{
1403
arity = 0;
1404
while(string[i] == '[') arity++, i++;
1405
switch(string[i])
1406
{
1407
case 'B':
1408
j9tty_printf( PORTLIB, "byte");
1409
break;
1410
1411
case 'C':
1412
j9tty_printf( PORTLIB, "char");
1413
break;
1414
1415
case 'D':
1416
j9tty_printf( PORTLIB, "double");
1417
break;
1418
1419
case 'F':
1420
j9tty_printf( PORTLIB, "float");
1421
break;
1422
1423
case 'I':
1424
j9tty_printf( PORTLIB, "int");
1425
break;
1426
1427
case 'J':
1428
j9tty_printf( PORTLIB, "long");
1429
break;
1430
1431
case 'L':
1432
i++;
1433
while(string[i] != ';')
1434
{
1435
j9tty_printf( PORTLIB, "%c", (string[i] == '/')?'.':string[i]);
1436
i++;
1437
}
1438
break;
1439
1440
case 'S':
1441
j9tty_printf( PORTLIB, "short");
1442
break;
1443
1444
case 'V':
1445
j9tty_printf( PORTLIB, "void");
1446
break;
1447
1448
case 'Z':
1449
j9tty_printf( PORTLIB, "boolean");
1450
break;
1451
}
1452
for(j = 0; j < arity; j++)
1453
j9tty_printf( PORTLIB, "[]");
1454
1455
if(string[i + 1] != ')')
1456
j9tty_printf( PORTLIB, ", ");
1457
}
1458
1459
j9tty_printf( PORTLIB, ")");
1460
1461
exceptions = method->exceptionsAttribute;
1462
if(exceptions && exceptions->numberOfExceptions)
1463
{
1464
j9tty_printf( PORTLIB, " throws ");
1465
for(j = 0; j < exceptions->numberOfExceptions;)
1466
{
1467
if(exceptions->exceptionIndexTable[j] != 0)
1468
{
1469
index = classfile->constantPool[exceptions->exceptionIndexTable[j]].slot1;
1470
string = classfile->constantPool[index].bytes;
1471
while(*string)
1472
{
1473
j9tty_printf( PORTLIB, "%c", (*string == '/')?'.':*string);
1474
string++;
1475
}
1476
if (++j != exceptions->numberOfExceptions)
1477
{
1478
j9tty_printf( PORTLIB, ", ");
1479
}
1480
}
1481
}
1482
}
1483
1484
j9tty_printf( PORTLIB, "\n");
1485
1486
if(bytecodes)
1487
{
1488
bcIndex = bytecodes;
1489
length = bytecodesLength;
1490
}
1491
else
1492
{
1493
bcIndex = code->code;
1494
length = code->codeLength;
1495
}
1496
pc = 0;
1497
wide = FALSE;
1498
fieldFlag = FALSE;
1499
while((U_32)pc < length)
1500
{
1501
NEXT_U8_ENDIAN(bigEndian, bc, bcIndex);
1502
if(wide)
1503
{
1504
j9tty_printf( PORTLIB, "%s", sunJavaBCNames[bc]);
1505
}
1506
else
1507
{
1508
j9tty_printf( PORTLIB, "%5i %s", pc, sunJavaBCNames[bc]);
1509
}
1510
1511
if(0 == strcmp(sunJavaBCNames[bc], "JBunimplemented"))
1512
{
1513
j9tty_printf( PORTLIB, "_%d ", bc);
1514
}
1515
else
1516
{
1517
j9tty_printf( PORTLIB, " ", bc);
1518
}
1519
1520
start = pc;
1521
pc++;
1522
switch(bc)
1523
{
1524
case CFR_BC_bipush:
1525
NEXT_U8_ENDIAN(bigEndian, index, bcIndex);
1526
j9tty_printf( PORTLIB, "%i\n", (I_8)index);
1527
pc++;
1528
break;
1529
1530
case CFR_BC_sipush:
1531
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1532
j9tty_printf( PORTLIB, "%i\n", (I_16)index);
1533
pc += 2;
1534
break;
1535
1536
case CFR_BC_ldc:
1537
case CFR_BC_ldc_w:
1538
case CFR_BC_ldc2_w:
1539
if (bc == CFR_BC_ldc) {
1540
NEXT_U8_ENDIAN(bigEndian, index, bcIndex);
1541
} else {
1542
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1543
}
1544
j9tty_printf( PORTLIB, "%i ", index);
1545
info = classfile->constantPool[index];
1546
switch(info.tag)
1547
{
1548
case CFR_CONSTANT_Integer:
1549
j9tty_printf( PORTLIB, "(int) 0x%08X\n", info.slot1);
1550
break;
1551
case CFR_CONSTANT_Float:
1552
j9tty_printf( PORTLIB, "(float) 0x%08X\n", info.slot1);
1553
break;
1554
case CFR_CONSTANT_Long:
1555
#ifdef J9VM_ENV_LITTLE_ENDIAN
1556
j9tty_printf( PORTLIB, "(long) 0x%08X%08X\n", info.slot2, info.slot1);
1557
#else
1558
j9tty_printf( PORTLIB, "(long) 0x%08X%08X\n", info.slot1, info.slot2);
1559
#endif
1560
break;
1561
case CFR_CONSTANT_Double:
1562
#ifdef J9VM_ENV_LITTLE_ENDIAN
1563
j9tty_printf( PORTLIB, "(double) 0x%08X%08X\n", info.slot2, info.slot1);
1564
#else
1565
j9tty_printf( PORTLIB, "(double) 0x%08X%08X\n", info.slot1, info.slot2);
1566
#endif
1567
j9tty_printf( PORTLIB, "(double) 0x%08X%08X\n", info.slot1, info.slot2);
1568
break;
1569
case CFR_CONSTANT_String:
1570
j9tty_printf( PORTLIB, "(java.lang.String) \"%s\"\n", classfile->constantPool[info.slot1].bytes);
1571
break;
1572
case CFR_CONSTANT_Class:
1573
j9tty_printf( PORTLIB, "(java.lang.Class) ");
1574
info = classfile->constantPool[info.slot1];
1575
for(i = 0; i < (I_32)info.slot1; i++)
1576
{
1577
j9tty_printf( PORTLIB, "%c", info.bytes[i] == '/' ? '.' : info.bytes[i]);
1578
}
1579
j9tty_printf( PORTLIB, "\n");
1580
break;
1581
case CFR_CONSTANT_MethodType:
1582
j9tty_printf( PORTLIB, "(java.dyn.MethodType) \"%s\"\n", classfile->constantPool[info.slot1].bytes);
1583
break;
1584
case CFR_CONSTANT_MethodHandle:
1585
/* TODO - print pretty: kind + field/method ref */
1586
j9tty_printf( PORTLIB, "(java.dyn.MethodHandle) kind=%x methodOrFieldRef=%x\n", info.slot1, info.slot2);
1587
break;
1588
default:
1589
j9tty_printf( PORTLIB, "<unknown constant type %i>\n", info.tag);
1590
break;
1591
}
1592
pc++;
1593
if (bc != CFR_BC_ldc) {
1594
pc++;
1595
}
1596
break;
1597
1598
case CFR_BC_iload:
1599
case CFR_BC_lload:
1600
case CFR_BC_fload:
1601
case CFR_BC_dload:
1602
case CFR_BC_aload:
1603
case CFR_BC_istore:
1604
case CFR_BC_lstore:
1605
case CFR_BC_fstore:
1606
case CFR_BC_dstore:
1607
case CFR_BC_astore:
1608
case CFR_BC_ret:
1609
if(wide)
1610
{
1611
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1612
pc += 2;
1613
wide = FALSE;
1614
}
1615
else
1616
{
1617
NEXT_U8_ENDIAN(bigEndian, index, bcIndex);
1618
pc++;
1619
}
1620
j9tty_printf( PORTLIB, "%i\n", index);
1621
break;
1622
1623
case CFR_BC_iinc:
1624
if(wide)
1625
{
1626
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1627
j9tty_printf( PORTLIB, "%i ", index);
1628
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1629
j9tty_printf( PORTLIB, "%i\n", (I_16)index);
1630
pc += 4;
1631
wide = FALSE;
1632
}
1633
else
1634
{
1635
NEXT_U8_ENDIAN(bigEndian, index, bcIndex);
1636
j9tty_printf( PORTLIB, "%i ", index);
1637
NEXT_U8_ENDIAN(bigEndian, target, bcIndex);
1638
j9tty_printf( PORTLIB, "%i\n", (I_8)target);
1639
pc += 2;
1640
}
1641
break;
1642
1643
case CFR_BC_ifeq:
1644
case CFR_BC_ifne:
1645
case CFR_BC_iflt:
1646
case CFR_BC_ifge:
1647
case CFR_BC_ifgt:
1648
case CFR_BC_ifle:
1649
case CFR_BC_if_icmpeq:
1650
case CFR_BC_if_icmpne:
1651
case CFR_BC_if_icmplt:
1652
case CFR_BC_if_icmpge:
1653
case CFR_BC_if_icmpgt:
1654
case CFR_BC_if_icmple:
1655
case CFR_BC_if_acmpeq:
1656
case CFR_BC_if_acmpne:
1657
case CFR_BC_goto:
1658
case CFR_BC_jsr:
1659
case CFR_BC_ifnull:
1660
case CFR_BC_ifnonnull:
1661
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1662
target = start + (I_16)index;
1663
j9tty_printf( PORTLIB, "%i\n", target);
1664
pc += 2;
1665
break;
1666
1667
case CFR_BC_tableswitch:
1668
switch(start % 4)
1669
{
1670
case 0:
1671
bcIndex++;
1672
pc++;
1673
case 1:
1674
bcIndex++;
1675
pc++;
1676
case 2:
1677
bcIndex++;
1678
pc++;
1679
case 3:
1680
break;
1681
}
1682
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
1683
target = start + index;
1684
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
1685
low = (I_32)index;
1686
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
1687
high = (I_32)index;
1688
pc += 12;
1689
j9tty_printf( PORTLIB, "low %i high %i\n", low, high);
1690
j9tty_printf( PORTLIB, " default %10i\n", target);
1691
j = high - low + 1;
1692
for(i = 0; i < j; i++)
1693
{
1694
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
1695
target = start + index;
1696
j9tty_printf( PORTLIB, " %10i %10i\n", low + i, target);
1697
pc += 4;
1698
}
1699
break;
1700
1701
case CFR_BC_lookupswitch:
1702
switch(start % 4)
1703
{
1704
case 0:
1705
bcIndex++;
1706
pc++;
1707
case 1:
1708
bcIndex++;
1709
pc++;
1710
case 2:
1711
bcIndex++;
1712
pc++;
1713
case 3:
1714
break;
1715
}
1716
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
1717
target = start + index;
1718
NEXT_U32_ENDIAN(bigEndian, npairs, bcIndex);
1719
j9tty_printf( PORTLIB, "pairs %i\n", npairs);
1720
j9tty_printf( PORTLIB, " default %10i\n", target);
1721
pc += 8;
1722
for(i = 0; i < (I_32)npairs; i++)
1723
{
1724
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
1725
j9tty_printf( PORTLIB, " %10i", index);
1726
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
1727
target = start + index;
1728
j9tty_printf( PORTLIB, " %10i\n", target);
1729
pc += 8;
1730
}
1731
break;
1732
1733
case CFR_BC_getstatic:
1734
case CFR_BC_putstatic:
1735
case CFR_BC_getfield:
1736
case CFR_BC_putfield:
1737
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
1738
case CFR_BC_withfield:
1739
#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */
1740
fieldFlag = TRUE;
1741
1742
case CFR_BC_invokevirtual:
1743
case CFR_BC_invokespecial:
1744
case CFR_BC_invokestatic:
1745
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1746
info = classfile->constantPool[index];
1747
j9tty_printf( PORTLIB, "%i ", index);
1748
info = classfile->constantPool[classfile->constantPool[info.slot1].slot1];
1749
for(i = 0; i < (I_32)info.slot1; i++)
1750
{
1751
j9tty_printf( PORTLIB, "%c", info.bytes[i] == '/' ? '.' : info.bytes[i]);
1752
}
1753
j9tty_printf( PORTLIB, ".");
1754
index = classfile->constantPool[index].slot2;
1755
info = classfile->constantPool[classfile->constantPool[index].slot1];
1756
for(i = 0; i < (I_32)info.slot1; i++)
1757
{
1758
j9tty_printf( PORTLIB, "%c", info.bytes[i] == '/' ? '.' : info.bytes[i]);
1759
}
1760
if(fieldFlag) j9tty_printf( PORTLIB, " ");
1761
info = classfile->constantPool[classfile->constantPool[index].slot2];
1762
for(i = 0; i < (I_32)info.slot1; i++)
1763
{
1764
j9tty_printf( PORTLIB, "%c", info.bytes[i] == '/' ? '.' : info.bytes[i]);
1765
}
1766
j9tty_printf( PORTLIB, "\n");
1767
pc += 2;
1768
fieldFlag = FALSE;
1769
break;
1770
1771
case CFR_BC_invokeinterface:
1772
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1773
info = classfile->constantPool[index];
1774
j9tty_printf( PORTLIB, "%i ", index);
1775
info = classfile->constantPool[classfile->constantPool[info.slot1].slot1];
1776
for(i = 0; i < (I_32)info.slot1; i++)
1777
{
1778
j9tty_printf( PORTLIB, "%c", info.bytes[i] == '/' ? '.' : info.bytes[i]);
1779
}
1780
j9tty_printf( PORTLIB, ".");
1781
index = classfile->constantPool[index].slot2;
1782
info = classfile->constantPool[classfile->constantPool[index].slot1];
1783
for(i = 0; i < (I_32)info.slot1; i++)
1784
{
1785
j9tty_printf( PORTLIB, "%c", info.bytes[i] == '/' ? '.' : info.bytes[i]);
1786
}
1787
info = classfile->constantPool[classfile->constantPool[index].slot2];
1788
for(i = 0; i < (I_32)info.slot1; i++)
1789
{
1790
j9tty_printf( PORTLIB, "%c", info.bytes[i] == '/' ? '.' : info.bytes[i]);
1791
}
1792
j9tty_printf( PORTLIB, "\n");
1793
bcIndex += 2;
1794
pc += 4;
1795
break;
1796
1797
case CFR_BC_new:
1798
case CFR_BC_anewarray:
1799
case CFR_BC_checkcast:
1800
case CFR_BC_instanceof:
1801
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
1802
case CFR_BC_aconst_init:
1803
#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */
1804
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1805
info = classfile->constantPool[index];
1806
j9tty_printf( PORTLIB, "%i ", index);
1807
info = classfile->constantPool[info.slot1];
1808
for(i = 0; i < (I_32)info.slot1; i++)
1809
{
1810
j9tty_printf( PORTLIB, "%c", info.bytes[i] == '/' ? '.' : info.bytes[i]);
1811
}
1812
j9tty_printf( PORTLIB, "\n");
1813
pc += 2;
1814
break;
1815
1816
case CFR_BC_newarray:
1817
NEXT_U8_ENDIAN(bigEndian, index, bcIndex);
1818
switch(index)
1819
{
1820
case /*T_BOOLEAN*/ 4 :
1821
j9tty_printf( PORTLIB, "boolean\n");
1822
break;
1823
case /*T_CHAR*/ 5:
1824
j9tty_printf( PORTLIB, "char\n");
1825
break;
1826
case /*T_FLOAT*/ 6:
1827
j9tty_printf( PORTLIB, "float\n");
1828
break;
1829
case /*T_DOUBLE*/ 7:
1830
j9tty_printf( PORTLIB, "double\n");
1831
break;
1832
case /*T_BYTE*/ 8:
1833
j9tty_printf( PORTLIB, "byte\n");
1834
break;
1835
case /*T_SHORT*/ 9:
1836
j9tty_printf( PORTLIB, "short\n");
1837
break;
1838
case /*T_INT*/ 10:
1839
j9tty_printf( PORTLIB, "int\n");
1840
break;
1841
case /*T_LONG*/ 11:
1842
j9tty_printf( PORTLIB, "long\n");
1843
break;
1844
default:
1845
j9tty_printf( PORTLIB, "(unknown type %i)\n", index);
1846
break;
1847
}
1848
pc++;
1849
break;
1850
1851
case CFR_BC_wide:
1852
wide = TRUE;
1853
break;
1854
1855
case CFR_BC_multianewarray:
1856
NEXT_U16_ENDIAN(bigEndian, index, bcIndex);
1857
info = classfile->constantPool[index];
1858
j9tty_printf( PORTLIB, "%i ", index);
1859
NEXT_U8_ENDIAN(bigEndian, index, bcIndex);
1860
j9tty_printf( PORTLIB, "dims %i ", index);
1861
info = classfile->constantPool[info.slot1];
1862
for(i = 0; i < (I_32)info.slot1; i++)
1863
{
1864
j9tty_printf( PORTLIB, "%c", info.bytes[i] == '/' ? '.' : info.bytes[i]);
1865
}
1866
j9tty_printf( PORTLIB, "\n");
1867
pc += 3;
1868
break;
1869
1870
case CFR_BC_goto_w:
1871
case CFR_BC_jsr_w:
1872
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
1873
target = start + index;
1874
j9tty_printf( PORTLIB, "%i\n", target);
1875
pc += 4;
1876
break;
1877
1878
default:
1879
j9tty_printf( PORTLIB, "\n");
1880
break;
1881
}
1882
}
1883
1884
if(code->exceptionTableLength)
1885
{
1886
j9tty_printf( PORTLIB, "\nException Table");
1887
if(bytecodes)
1888
{
1889
j9tty_printf( PORTLIB, " - PCs may be wrong\n");
1890
}
1891
else
1892
{
1893
j9tty_printf( PORTLIB, "\n");
1894
}
1895
j9tty_printf( PORTLIB, "start end handler catch type\n");
1896
j9tty_printf( PORTLIB, "----- --- ------- ----------\n");
1897
for(i = 0; i < code->exceptionTableLength; i++)
1898
{
1899
j9tty_printf( PORTLIB, "%5i%6i%10i ",
1900
code->exceptionTable[i].startPC,
1901
code->exceptionTable[i].endPC,
1902
code->exceptionTable[i].handlerPC,
1903
0);
1904
if(code->exceptionTable[i].catchType)
1905
{
1906
int k;
1907
info = classfile->constantPool[code->exceptionTable[i].catchType];
1908
info = classfile->constantPool[info.slot1];
1909
for(k = 0; k < (I_32)info.slot1; k++)
1910
{
1911
j9tty_printf( PORTLIB, "%c", info.bytes[k] == '/' ? '.' : info.bytes[k]);
1912
}
1913
j9tty_printf( PORTLIB, "\n");
1914
}
1915
else
1916
{
1917
j9tty_printf( PORTLIB, "(any)\n");
1918
}
1919
}
1920
}
1921
1922
j9tty_printf( PORTLIB, "\n");
1923
return;
1924
}
1925
1926
1927
1928
1929
1930
static void dumpHelpText( J9PortLibrary *portLib, int argc, char **argv)
1931
{
1932
char detailString[1024];
1933
PORT_ACCESS_FROM_PORT(portLib);
1934
1935
vmDetailString(portLib, detailString, 1024);
1936
j9file_printf( PORTLIB, J9PORT_TTY_OUT, "\nOpenJ9 Java(TM) Class File Reader, Version " J9JVM_VERSION_STRING);
1937
j9file_printf( PORTLIB, J9PORT_TTY_OUT, "\n" J9_COPYRIGHT_STRING);
1938
j9file_printf( PORTLIB, J9PORT_TTY_OUT, "\nTarget: %s\n", detailString);
1939
j9file_printf( PORTLIB, J9PORT_TTY_OUT, "\nJava and all Java-based marks and logos are trademarks or registered");
1940
j9file_printf( PORTLIB, J9PORT_TTY_OUT, "\ntrademarks of Oracle, Inc.\n\n");
1941
j9file_printf( PORTLIB, J9PORT_TTY_OUT, "Usage:\t%s [options] classfile\n\n", argv[0] );
1942
j9file_printf( PORTLIB, J9PORT_TTY_OUT, "[options]\n" );
1943
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -b show bytecodes\n");
1944
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -bi show bytecodes with jsrs inlined\n");
1945
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -c check classfile structure\n");
1946
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -d dump structure details\n");
1947
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -di dump structure details with jsrs inlined\n");
1948
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -dr dump J9 ROM Class physical memory layout\n");
1949
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -dr:<depth> dump J9 ROM Class physical memory layout with specified nesting depth\n");
1950
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -drx dump J9 ROM Class physical memory layout (XML)\n");
1951
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -drq:q1[,q2,...] query J9 ROM Class physical memory layout\n");
1952
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " Query examples:\n");
1953
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -drq:/romHeader\n");
1954
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -drq:/romHeader,/methods\n");
1955
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -drq:/romHeader/className,/romHeader/romSize\n");
1956
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -drq:/methods/method[3]/name,/methods/method[3]/methodBytecodes\n");
1957
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -h or -? print usage\n");
1958
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -j:<jimagefile> load from JImage file\n");
1959
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -jh:<jimagefile> load JImage file and display header and resources metadata\n");
1960
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -jp:<jimagefile> display the module containing the given package in the JImage file\n");
1961
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -jx:<jimagefile> extract resources from JImage file\n");
1962
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -m dump multiple classes\n");
1963
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -o:<filename> write out J9 ROM Class to file (use with -x)\n");
1964
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -oh write out J9 ROM Class to file under the package hierarchy\n");
1965
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -p pedantic mode (-Xfuture)\n");
1966
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -q quiet mode (don't print standard class description)\n");
1967
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -r recurse subdirectories\n");
1968
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -r:<filename> read in J9 ROM Class from file\n");
1969
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -sd strip debug attributes\n");
1970
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -t:<filename> write out recreated .class data to file\n");
1971
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -x translate to J9 ROM format\n");
1972
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -xm translate to J9 ROM format with local, debug and stack maps (print only)\n");
1973
j9file_printf( PORTLIB, J9PORT_TTY_OUT, " -z:<zipfile> load from ZIP or JAR\n\n");
1974
}
1975
1976
static I_32
1977
writeOutputFile(U_8 *fileData, U_32 length, char* filename, char *extension)
1978
{
1979
char* newFilename;
1980
I_32 extnLen = 0;
1981
IDATA i;
1982
IDATA fd;
1983
BOOLEAN appendExtension = FALSE;
1984
1985
PORT_ACCESS_FROM_PORT(portLib);
1986
1987
i = strlen(filename);
1988
1989
if (NULL != extension) {
1990
extnLen = (I_32) strlen(extension);
1991
/* Append extension if the filename doesn't have it already. */
1992
if ((i < (extnLen + 1)) || (0 != strcmp(filename + i - extnLen, extension))) {
1993
newFilename = j9mem_allocate_memory(i + extnLen + 1, J9MEM_CATEGORY_CLASSES); /* filename + extension + null */
1994
appendExtension = TRUE;
1995
}
1996
}
1997
if (TRUE == appendExtension) {
1998
newFilename = j9mem_allocate_memory(i + extnLen + 1, J9MEM_CATEGORY_CLASSES); /* filename + extension + null */
1999
} else {
2000
newFilename = j9mem_allocate_memory(i + 1, J9MEM_CATEGORY_CLASSES); /* filename + null */
2001
}
2002
if (!newFilename) {
2003
return -3;
2004
}
2005
2006
memcpy(newFilename, filename, i);
2007
if (TRUE == appendExtension) {
2008
memcpy(newFilename + i, extension, extnLen);
2009
i += extnLen;
2010
}
2011
newFilename[i] = '\0';
2012
2013
fd = j9file_open(newFilename, EsOpenWrite | EsOpenCreate | EsOpenTruncate , 0666);
2014
if (-1 == fd) {
2015
return RET_FILE_OPEN_FAILED;
2016
}
2017
2018
if ((U_32)j9file_write(fd, fileData, length) != length) {
2019
j9file_close(fd);
2020
return RET_FILE_WRITE_FAILED;
2021
}
2022
2023
if(!(options.options & OPTION_quiet))
2024
j9tty_printf( PORTLIB, "Wrote %i bytes to output file %s\n", length, newFilename);
2025
2026
j9file_close(fd);
2027
2028
j9mem_free_memory(newFilename);
2029
return length;
2030
}
2031
2032
static int parseCommandLine(int argc, char** argv, char** envp)
2033
{
2034
int i;
2035
2036
PORT_ACCESS_FROM_PORT(portLib);
2037
memset(&options, 0, sizeof(CFDumpOptions));
2038
if(argc == 1) goto help;
2039
for(i = 1; i < argc; i++)
2040
{
2041
IDATA optionLen = strlen(argv[i]);
2042
2043
if(argv[i][0] != '-')
2044
{
2045
options.filesStart = i;
2046
break;
2047
}
2048
if (optionLen < 2) {
2049
goto incomplete;
2050
}
2051
2052
switch(argv[i][1])
2053
{
2054
case 'b':
2055
if(options.action) goto incompatible;
2056
options.action = ACTION_bytecodes;
2057
if (argv[i][2] != 'i') {
2058
options.options = OPTION_leaveJSRs;
2059
}
2060
break;
2061
2062
case 'c':
2063
options.options |= OPTION_check;
2064
options.options |= OPTION_dumpPreverifyData;
2065
break;
2066
2067
case 'd':
2068
if(options.action) goto incompatible;
2069
if (argv[i][2] == 'r') {
2070
options.actionString = "1";
2071
if (argv[i][3] == 'x') {
2072
options.action = ACTION_dumpRomClassXML;
2073
if (argv[i][4] == ':') {
2074
options.actionString = &argv[i][5];
2075
}
2076
} else if (argv[i][3] == 'q') {
2077
options.action = ACTION_queryRomClass;
2078
if (argv[i][4] == ':') {
2079
options.actionString = &argv[i][5];
2080
} else {
2081
options.actionString = "";
2082
}
2083
} else {
2084
options.action = ACTION_dumpRomClass;
2085
if (argv[i][3] == ':') {
2086
options.actionString = &argv[i][4];
2087
}
2088
}
2089
options.options |= OPTION_translate;
2090
} else {
2091
options.action = ACTION_structure;
2092
if (argv[i][2] != 'i') {
2093
options.options = OPTION_leaveJSRs;
2094
}
2095
}
2096
break;
2097
2098
case 'f':
2099
if(argv[i][3] != ':') goto incomplete;
2100
switch(argv[i][2])
2101
{
2102
case 'c':
2103
if(options.action) goto incompatible;
2104
options.action = ACTION_formatClass;
2105
options.actionString = &argv[i][4];
2106
break;
2107
2108
case 'f':
2109
if(options.action) goto incompatible;
2110
options.action = ACTION_formatFields;
2111
options.actionString = &argv[i][4];
2112
break;
2113
2114
case 'm':
2115
if(options.action) goto incompatible;
2116
options.action = ACTION_formatMethods;
2117
options.actionString = &argv[i][4];
2118
break;
2119
2120
case 'b':
2121
if(options.action) goto incompatible;
2122
options.action = ACTION_formatBytecodes;
2123
options.actionString = &argv[i][4];
2124
break;
2125
2126
default:
2127
goto unknown;
2128
}
2129
break;
2130
2131
case 'h':
2132
case '?':
2133
goto help;
2134
2135
case 'i':
2136
options.options |= OPTION_verbose;
2137
break;
2138
2139
case 'j':
2140
{
2141
/* similar to -z option, but for jimage files */
2142
if (options.source) {
2143
goto incompatible;
2144
}
2145
if (optionLen < 4) {
2146
/* Minimum size option is -j:[a-z] */
2147
goto incomplete;
2148
}
2149
options.source = SOURCE_jimage;
2150
if (argv[i][2] != ':') {
2151
if (optionLen < 5) {
2152
goto incomplete;
2153
}
2154
if (argv[i][3] == ':') {
2155
if (argv[i][2] == 'x') {
2156
/* found '-jx:' option */
2157
options.action = ACTION_writeJImageResource;
2158
options.sourceString = &argv[i][4];
2159
} else if (argv[i][2] == 'p') {
2160
/* found '-jp:' option */
2161
options.action = ACTION_findModuleForPackage;
2162
options.sourceString = &argv[i][4];
2163
} else if (argv[i][2] == 'h') {
2164
/* found '-jh:' option */
2165
options.action = ACTION_dumpJImageInfo;
2166
options.sourceString = &argv[i][4];
2167
} else {
2168
goto unknown;
2169
}
2170
} else {
2171
IDATA jimageOptLen = strlen("-jimage:");
2172
if ((optionLen < jimageOptLen) || strncmp(argv[i], "-jimage:", jimageOptLen)) {
2173
goto incomplete;
2174
}
2175
options.action = ACTION_dumpJImageInfo;
2176
options.sourceString = &argv[i][jimageOptLen];
2177
}
2178
} else {
2179
options.sourceString = &argv[i][3];
2180
}
2181
break;
2182
}
2183
case 'm':
2184
options.options |= OPTION_multi;
2185
break;
2186
2187
case 'o':
2188
if (options.action) {
2189
goto incompatible;
2190
}
2191
options.action = ACTION_writeRomClassFile;
2192
if (argv[i][2] == 'h') {
2193
options.action = ACTION_writeRomClassFileHierarchy;
2194
} else if(argv[i][2] == ':') {
2195
options.actionString = &argv[i][3];
2196
}
2197
options.options |= OPTION_translate;
2198
break;
2199
2200
case 'p':
2201
options.options |= OPTION_pedantic;
2202
break;
2203
2204
case 'q':
2205
options.options |= OPTION_quiet;
2206
break;
2207
2208
case 'r':
2209
case 'R':
2210
if(argv[i][2] == ':')
2211
{
2212
if(options.source) goto incompatible;
2213
options.source = SOURCE_rom;
2214
options.options |= OPTION_translate;
2215
options.sourceString = &argv[i][3];
2216
}
2217
else
2218
{
2219
options.options |= OPTION_recursive;
2220
}
2221
break;
2222
2223
case 's':
2224
switch(argv[i][2])
2225
{
2226
case 'd':
2227
options.options |= OPTION_stripDebugAttributes;
2228
break;
2229
case 'l':
2230
options.options |= OPTION_stripDebugLines;
2231
break;
2232
case 's':
2233
options.options |= OPTION_stripDebugSource;
2234
break;
2235
case 'v':
2236
options.options |= OPTION_stripDebugVars;
2237
break;
2238
2239
default:
2240
goto unknown;
2241
break;
2242
}
2243
break;
2244
2245
case 't':
2246
if(options.action) {
2247
goto incompatible;
2248
}
2249
options.action = ACTION_transformRomClass;
2250
if(argv[i][2] == ':') {
2251
options.actionString = &argv[i][3];
2252
}
2253
/* Enable translate by default */
2254
options.options |= OPTION_translate;
2255
break;
2256
2257
case 'v':
2258
if((strlen(argv[i]) == 8) && !strcmp(argv[i], "-verbose"))
2259
{
2260
options.options |= OPTION_verbose;
2261
break;
2262
}
2263
options.options |= OPTION_dumpPreverifyData;
2264
break;
2265
2266
case 'x':
2267
options.options |= OPTION_translate;
2268
if ((argv[i][2]) == 'm') {
2269
options.options |= OPTION_dumpMaps;
2270
if(options.action) {
2271
goto incompatible;
2272
}
2273
options.action = ACTION_dumpMaps;
2274
}
2275
#ifdef J9VM_ENV_LITTLE_ENDIAN
2276
options.options |= OPTION_littleEndian;
2277
options.options &= ~OPTION_bigEndian;
2278
#else
2279
options.options |= OPTION_bigEndian;
2280
options.options &= ~OPTION_littleEndian;
2281
#endif
2282
break;
2283
2284
case 'z':
2285
if(options.source) goto incompatible;
2286
options.source = SOURCE_zip;
2287
if(argv[i][2] != ':')
2288
{
2289
if((strlen(argv[i]) < 5) || strncmp(argv[i], "-zip:", 5)) goto incomplete;
2290
options.sourceString = &argv[i][5];
2291
}
2292
else
2293
{
2294
options.sourceString = &argv[i][3];
2295
}
2296
break;
2297
2298
default:
2299
goto unknown;
2300
break;
2301
}
2302
}
2303
2304
if (!options.filesStart) {
2305
options.filesStart = argc;
2306
2307
/* If no files specified but zip source, go into multi mode. */
2308
if ((SOURCE_zip == options.source) || (SOURCE_jimage == options.source)) {
2309
options.options |= OPTION_multi;
2310
} else if(options.source == SOURCE_rom) {
2311
if (options.action) {
2312
options.options |= OPTION_multi;
2313
}
2314
} else {
2315
/* Must be file mode -- where's the file? */
2316
j9tty_printf( PORTLIB, "No filename specified\n");
2317
return 1;
2318
}
2319
} else if(options.filesStart < argc - 1) {
2320
/* If multiple files specified, go into multi mode. */
2321
options.options |= OPTION_multi;
2322
}
2323
2324
/* If doing a multi operation, don't use specified names for output files. */
2325
if(((options.options & OPTION_multi)
2326
&& ((options.action == ACTION_writeRomClassFile) || (options.action == ACTION_transformRomClass)))
2327
|| (ACTION_writeRomClassFileHierarchy == options.action)
2328
) {
2329
options.actionString = NULL;
2330
}
2331
2332
return 0;
2333
2334
unknown:
2335
j9tty_printf( PORTLIB, "Unrecognized option(s) on command line. First was: %s\n", argv[i]);
2336
return RET_COMMANDLINE_INCORRECT;
2337
2338
incomplete:
2339
j9tty_printf( PORTLIB, "Incomplete option(s) on command line. First was: %s\n", argv[i]);
2340
return RET_COMMANDLINE_INCORRECT;
2341
2342
incompatible:
2343
j9tty_printf( PORTLIB, "Incompatible options on command line. First was: %s\n", argv[i]);
2344
return RET_COMMANDLINE_INCORRECT;
2345
2346
help:
2347
dumpHelpText(PORTLIB, argc, argv);
2348
return RET_COMMANDLINE_INCORRECT;
2349
}
2350
2351
2352
static void printDisassembledMethods(J9CfrClassFile *classfile)
2353
{
2354
I_32 i;
2355
2356
for(i = 0; i < classfile->methodsCount; i++)
2357
printDisassembledMethod(classfile, &(classfile->methods[i]), TRUE, NULL, 0);
2358
}
2359
2360
2361
2362
static J9CfrClassFile* loadClassFile(char* requestedFile, U_32* lengthReturn, U_32 flags)
2363
{
2364
J9CfrClassFile* classfile;
2365
U_8* data;
2366
U_32 dataLength;
2367
2368
PORT_ACCESS_FROM_PORT(portLib);
2369
2370
data = loadBytes(requestedFile, &dataLength, flags);
2371
if(data == NULL) return NULL;
2372
classfile = loadClassFromBytes(data, dataLength, requestedFile, flags);
2373
j9mem_free_memory(data);
2374
*lengthReturn = dataLength;
2375
return classfile;
2376
}
2377
2378
static U_32 buildFlags(void)
2379
{
2380
U_32 flags;
2381
2382
flags = BCT_RetainRuntimeInvisibleAttributes;
2383
2384
/* Set vm flags to the latest version to pass version validation
2385
* check in j9bcutil_readClassFileBytes.
2386
*/
2387
flags |= BCT_JavaMaxMajorVersionShifted;
2388
flags |= BCT_AnyPreviewVersion;
2389
2390
if(options.options & OPTION_stripDebugAttributes) flags |= CFR_StripDebugAttributes;
2391
if(options.options & OPTION_stripDebugLines) flags |= BCT_StripDebugLines;
2392
if(options.options & OPTION_stripDebugSource) flags |= BCT_StripDebugSource;
2393
if(options.options & OPTION_stripDebugVars) flags |= BCT_StripDebugVars;
2394
if(options.options & OPTION_check) flags |= CFR_StaticVerification;
2395
if(options.options & OPTION_littleEndian) flags |= BCT_LittleEndianOutput;
2396
if(options.options & OPTION_bigEndian) flags |= BCT_BigEndianOutput;
2397
if(options.options & OPTION_leaveJSRs) flags |= CFR_LeaveJSRs;
2398
if(options.options & OPTION_pedantic) flags |= BCT_Xfuture;
2399
if(options.options & OPTION_dumpMaps) flags |= BCT_DumpMaps;
2400
return flags;
2401
}
2402
2403
2404
static I_32 processClassFile(J9CfrClassFile* classfile, U_32 dataLength, char* requestedFile, U_32 flags)
2405
{
2406
U_32 i;
2407
2408
PORT_ACCESS_FROM_PORT(portLib);
2409
2410
switch(options.action)
2411
{
2412
case ACTION_definition:
2413
if(!((options.options & OPTION_check) && (options.options & OPTION_quiet)))
2414
printClassFile(classfile);
2415
break;
2416
2417
case ACTION_structure:
2418
dumpClassFile(classfile);
2419
break;
2420
2421
case ACTION_bytecodes:
2422
if(!(options.options & OPTION_quiet)) printClassFile(classfile);
2423
printDisassembledMethods(classfile);
2424
break;
2425
2426
case ACTION_formatClass:
2427
sun_formatClass(classfile, options.actionString, strlen(options.actionString));
2428
j9tty_printf(PORTLIB, "\n");
2429
break;
2430
2431
case ACTION_formatFields:
2432
for(i = 0; i < classfile->fieldsCount; i++)
2433
{
2434
sun_formatField(classfile, &(classfile->fields[i]), options.actionString, strlen(options.actionString));
2435
j9tty_printf(PORTLIB, "\n");
2436
}
2437
break;
2438
2439
case ACTION_formatMethods:
2440
for(i = 0; i < classfile->methodsCount; i++)
2441
{
2442
sun_formatMethod(classfile, &(classfile->methods[i]), options.actionString, strlen(options.actionString));
2443
j9tty_printf(PORTLIB, "\n");
2444
}
2445
break;
2446
2447
case ACTION_formatBytecodes:
2448
for(i = 0; i < classfile->methodsCount; i++)
2449
{
2450
sun_formatBytecodes(classfile, &(classfile->methods[i]), TRUE, NULL, 0, options.actionString, strlen(options.actionString));
2451
}
2452
break;
2453
2454
case ACTION_dumpMaps:
2455
/* Case reserves mapping output to only dump to screen mode for ROM classes */
2456
break;
2457
2458
default:
2459
return RET_UNSUPPORTED_ACTION;
2460
}
2461
return 0;
2462
}
2463
2464
2465
static I_32
2466
processAllFiles(char **files, U_32 flags)
2467
{
2468
I_32 i = 0;
2469
2470
PORT_ACCESS_FROM_PORT(portLib);
2471
2472
for (i = 0; ; ++i) {
2473
char *currentFile = files[i];
2474
if (NULL == currentFile) {
2475
break;
2476
}
2477
if (j9file_attr(currentFile) != EsIsDir) {
2478
processSingleFile(currentFile, flags);
2479
} else {
2480
IDATA length = strlen(currentFile);
2481
if ((length > 0) && (PATH_SEP_CHAR == currentFile[length - 1])) {
2482
processDirectory(currentFile, (BOOLEAN) ((options.options & OPTION_recursive) != 0), flags);
2483
} else {
2484
char *dirCopy = j9mem_allocate_memory(length + 2, J9MEM_CATEGORY_CLASSES);
2485
if (NULL == dirCopy) {
2486
return RET_ALLOCATE_FAILED;
2487
}
2488
memcpy(dirCopy, currentFile, length);
2489
dirCopy[length] = PATH_SEP_CHAR;
2490
dirCopy[length + 1] = '\0';
2491
processDirectory(dirCopy, (BOOLEAN) ((options.options & OPTION_recursive) != 0), flags);
2492
j9mem_free_memory(dirCopy);
2493
}
2494
}
2495
}
2496
return 0;
2497
}
2498
2499
2500
static I_32
2501
processAllInZIP(char* zipFilename, U_32 flags)
2502
{
2503
J9ROMClass* romClass = NULL;
2504
J9CfrClassFile* classfile = NULL;
2505
J9ZipFile zipFile;
2506
J9ZipEntry entry;
2507
U_8* dataBuffer = NULL;
2508
U_32 dataBufferSize = 1024;
2509
I_32 result;
2510
IDATA nextEntry;
2511
2512
PORT_ACCESS_FROM_PORT(portLib);
2513
2514
/* Open the zip file (in non-cached mode) */
2515
result = zip_openZipFile(PORTLIB, zipFilename, &zipFile, NULL, J9ZIP_OPEN_NO_FLAGS);
2516
if(result)
2517
{
2518
j9tty_printf(PORTLIB, "Could not open or read %s\n", zipFilename);
2519
return RET_ZIP_OPEN_FAILED;
2520
}
2521
2522
dataBuffer = j9mem_allocate_memory(dataBufferSize, J9MEM_CATEGORY_CLASSES);
2523
if(dataBuffer == NULL)
2524
{
2525
j9tty_printf( PORTLIB, "Insufficient memory to complete operation\n");
2526
result = RET_ALLOCATE_FAILED;
2527
goto cleanExit;
2528
}
2529
2530
zip_resetZipFile(PORTLIB, &zipFile, &nextEntry);
2531
2532
while(1)
2533
{
2534
/* Read the next entry. */
2535
result = zip_getNextZipEntry(PORTLIB, &zipFile, &entry, &nextEntry, TRUE);
2536
if(result == ZIP_ERR_NO_MORE_ENTRIES)
2537
{
2538
result = 0;
2539
goto cleanExit;
2540
}
2541
if(result)
2542
{
2543
result = RET_ZIP_GETNEXTZIPENTRY_FAILED;
2544
j9tty_printf( PORTLIB, "Error reading %s\n", zipFilename);
2545
goto cleanExit;
2546
}
2547
2548
/* Don't bother with files that can't possibly have a ".class" extension. */
2549
if(entry.filenameLength > 6)
2550
{
2551
/* Check for the ".class" extension. */
2552
if(!strcmp((const char*)&entry.filename[entry.filenameLength - 6], ".class"))
2553
{
2554
/* Looks like a class file. Ensure buffer space. Read the data. */
2555
if(entry.uncompressedSize > dataBufferSize)
2556
{
2557
j9mem_free_memory(dataBuffer);
2558
dataBufferSize = ((entry.uncompressedSize / 1024) + 1) * 1024;
2559
dataBuffer = j9mem_allocate_memory(dataBufferSize, J9MEM_CATEGORY_CLASSES);
2560
if(dataBuffer == NULL)
2561
{
2562
j9tty_printf( PORTLIB, "Insufficient memory to complete operation\n");
2563
result = RET_ALLOCATE_FAILED;
2564
goto cleanExit;
2565
}
2566
}
2567
2568
result = zip_getZipEntryData(PORTLIB, &zipFile, &entry, dataBuffer, dataBufferSize);
2569
if(result)
2570
{
2571
j9tty_printf( PORTLIB, "Error reading %s from %s\n", entry.filename, zipFilename);
2572
continue;
2573
}
2574
2575
if(options.options & OPTION_translate)
2576
{
2577
romClass = translateClassBytes(dataBuffer, entry.uncompressedSize, (char*)entry.filename, flags);
2578
if(!romClass) {
2579
continue;
2580
}
2581
result = processROMClass(romClass, (char*)entry.filename, flags);
2582
if(result) {
2583
goto cleanExit;
2584
}
2585
j9mem_free_memory((U_8*)romClass);
2586
romClass = NULL;
2587
}
2588
else
2589
{
2590
classfile = loadClassFromBytes(dataBuffer, entry.uncompressedSize, (char*)entry.filename, flags);
2591
if(!classfile) continue;
2592
result = processClassFile(classfile, entry.uncompressedSize, (char*)entry.filename, flags);
2593
j9mem_free_memory((U_8*)classfile);
2594
classfile = NULL;
2595
}
2596
}
2597
}
2598
}
2599
result = 0;
2600
2601
cleanExit:
2602
zip_releaseZipFile(PORTLIB, &zipFile);
2603
if(dataBuffer) j9mem_free_memory(dataBuffer);
2604
if(classfile) j9mem_free_memory((U_8*)classfile);
2605
if(romClass) j9mem_free_memory((U_8*)romClass);
2606
return result;
2607
}
2608
2609
static I_32 processFilesInZIP(char* zipFilename, char** files, U_32 flags)
2610
{
2611
J9ROMClass* romClass = NULL;
2612
J9CfrClassFile* classfile = NULL;
2613
J9ZipFile zipFile;
2614
J9ZipEntry entry;
2615
J9ZipCachePool* cachePool = NULL;
2616
char* requestedFile;
2617
char** convertedFiles = NULL;
2618
U_8* dataBuffer = NULL;
2619
U_32 dataBufferSize = 1024;
2620
I_32 result, i;
2621
I_32 fileCount;
2622
2623
PORT_ACCESS_FROM_PORT(portLib);
2624
2625
result = convertToClassFilename((const char **)files, &convertedFiles, &fileCount);
2626
if (RET_SUCCESS != result) {
2627
j9tty_printf(PORTLIB, "Error in converting file name to .class file name\n");
2628
goto cleanExit;
2629
}
2630
2631
/* make ourselves a pool and just let zipsup manage the cache */
2632
cachePool = zipCachePool_new(PORTLIB, NULL);
2633
/* Open the zip file. */
2634
result = zip_openZipFile(PORTLIB, (char*)zipFilename, &zipFile, cachePool, J9ZIP_OPEN_READ_CACHE_DATA);
2635
if (0 != result) {
2636
j9tty_printf(PORTLIB, "Could not open or read %s\n", zipFilename);
2637
return RET_ZIP_OPEN_FAILED;
2638
}
2639
2640
zip_initZipEntry(PORTLIB, &entry);
2641
2642
dataBuffer = j9mem_allocate_memory(dataBufferSize, J9MEM_CATEGORY_CLASSES);
2643
if(dataBuffer == NULL)
2644
{
2645
j9tty_printf( PORTLIB, "Insufficient memory to complete operation\n");
2646
result = RET_ALLOCATE_FAILED;
2647
goto cleanExit;
2648
}
2649
2650
for(i = 0; i < fileCount; i++)
2651
{
2652
IDATA filenameLength;
2653
2654
zip_freeZipEntry(PORTLIB, &entry);
2655
zip_initZipEntry(PORTLIB, &entry);
2656
2657
requestedFile = convertedFiles[i];
2658
/* Search for the entry. */
2659
filenameLength = strlen(requestedFile);
2660
result = zip_getZipEntry(PORTLIB, &zipFile, &entry, requestedFile, filenameLength, J9ZIP_GETENTRY_READ_DATA_POINTER);
2661
if(result)
2662
{
2663
j9tty_printf(PORTLIB, "File %s not found in %s\n", requestedFile, zipFilename);
2664
continue;
2665
}
2666
2667
/* Ensure buffer space. Read the data. */
2668
if(entry.uncompressedSize > dataBufferSize)
2669
{
2670
j9mem_free_memory(dataBuffer);
2671
dataBufferSize = ((entry.uncompressedSize / 1024) + 1) * 1024;
2672
dataBuffer = j9mem_allocate_memory(dataBufferSize, J9MEM_CATEGORY_CLASSES);
2673
if(dataBuffer == NULL)
2674
{
2675
j9tty_printf( PORTLIB, "Insufficient memory to complete operation\n");
2676
result = RET_ALLOCATE_FAILED;
2677
goto cleanExit;
2678
}
2679
}
2680
2681
result = zip_getZipEntryData(PORTLIB, &zipFile, &entry, dataBuffer, dataBufferSize);
2682
if (result) {
2683
j9tty_printf( PORTLIB, "Error reading %s from %s\n", requestedFile, zipFilename);
2684
continue;
2685
}
2686
2687
if (options.options & OPTION_translate) {
2688
romClass = translateClassBytes(dataBuffer, entry.uncompressedSize, requestedFile, flags);
2689
if(!romClass) continue;
2690
result = processROMClass(romClass, requestedFile, flags);
2691
if(result) goto cleanExit;
2692
j9mem_free_memory((U_8*)romClass);
2693
romClass = NULL;
2694
} else {
2695
classfile = loadClassFromBytes(dataBuffer, entry.uncompressedSize, requestedFile, flags);
2696
if(!classfile) continue;
2697
processClassFile(classfile, entry.uncompressedSize, requestedFile, flags);
2698
j9mem_free_memory((U_8*)classfile);
2699
classfile = NULL;
2700
}
2701
}
2702
result = 0;
2703
2704
cleanExit:
2705
zip_freeZipEntry(PORTLIB, &entry);
2706
j9mem_free_memory(convertedFiles);
2707
zip_releaseZipFile(PORTLIB, &zipFile);
2708
if (cachePool) zipCachePool_kill(cachePool);
2709
if(dataBuffer) j9mem_free_memory(dataBuffer);
2710
if(classfile) j9mem_free_memory((U_8*)classfile);
2711
if(romClass) j9mem_free_memory((U_8*)romClass);
2712
return result;
2713
}
2714
2715
2716
2717
/**
2718
* Process jimage resource specified by "j9jimageLocation".
2719
*
2720
* @param [in] jimageFileName name of the jimage file
2721
* @param [in] jimage pointer to J9JImage
2722
* @param [in] j9jimageLocation pointer to J9JImageLocation storing metadata about the resource
2723
* @param [in] name of the resource represented by j9jimageLocation
2724
* @param [in/out] pointer to a buffer for storing resource data; if the buffer is not large enough, it is freed and reallocated to desired amount
2725
* @param [in/out] pointer to integer specifying input buffer size; if the buffer is reallocated, then it is updated with the new size
2726
* @param [in] flags build flags used during processing of class files
2727
*
2728
* @return RET_SUCCESS on success, negative error code on failure
2729
*/
2730
static I_32
2731
processJImageResource(const char *jimageFileName, J9JImage *jimage, J9JImageLocation *j9jimageLocation, const char *resourceName, U_8 **dataBuffer, UDATA *dataBufferSize, U_32 flags)
2732
{
2733
U_8 *buffer = *dataBuffer;
2734
UDATA bufferSize = *dataBufferSize;
2735
U_64 size = 0;
2736
I_32 result = RET_SUCCESS;
2737
2738
PORT_ACCESS_FROM_PORT(portLib);
2739
2740
size = j9jimageLocation->uncompressedSize;
2741
if (size > bufferSize) {
2742
j9mem_free_memory(buffer);
2743
bufferSize = (UDATA)(((size / 1024) + 1) * 1024);
2744
buffer = j9mem_allocate_memory(bufferSize, J9MEM_CATEGORY_CLASSES);
2745
if (NULL == buffer) {
2746
j9tty_printf(PORTLIB, "Insufficient memory to complete operation\n");
2747
result = RET_ALLOCATE_FAILED;
2748
goto _exit;
2749
}
2750
*dataBuffer = buffer;
2751
*dataBufferSize = bufferSize;
2752
}
2753
2754
result = j9bcutil_getJImageResource(PORTLIB, jimage, j9jimageLocation, buffer, bufferSize);
2755
if (J9JIMAGE_NO_ERROR != result) {
2756
j9tty_printf(PORTLIB, "Error in getting data of the resource %s in jimage file %s. Error code=%d\n", resourceName, jimageFileName, result);
2757
result = RET_JIMAGE_GETJIMAGERESOURCE_FAILED;
2758
goto _exit;
2759
}
2760
2761
if (0 != (options.options & OPTION_translate)) {
2762
J9ROMClass *romClass = translateClassBytes(buffer, (U_32)size, (char *)resourceName, flags);
2763
if (NULL != romClass) {
2764
result = processROMClass(romClass, (char *)resourceName, flags);
2765
if (NULL != romClass) {
2766
j9mem_free_memory((U_8*)romClass);
2767
romClass = NULL;
2768
}
2769
if (RET_SUCCESS != result) {
2770
goto _exit;
2771
}
2772
} else {
2773
result = RET_LOADROMCLASSFROMBYTES_FAILED;
2774
}
2775
} else if (ACTION_writeJImageResource == options.action) {
2776
char tempPath[EsMaxPath];
2777
char *current = NULL;
2778
char jimageFileSeparator = '/';
2779
2780
/* skip leading '/' if present */
2781
if ('/' == resourceName[0]) {
2782
j9str_printf(PORTLIB, tempPath, EsMaxPath, "%s", resourceName + 1);
2783
} else {
2784
j9str_printf(PORTLIB, tempPath, EsMaxPath, "%s", resourceName);
2785
}
2786
current = strchr(tempPath, jimageFileSeparator);
2787
while (NULL != current) {
2788
I_32 rc = 0;
2789
2790
*current = '\0';
2791
rc = j9file_mkdir(tempPath);
2792
if (0 != rc) {
2793
I_32 errorCode = j9error_last_error_number();
2794
2795
if (J9PORT_ERROR_FILE_EXIST != errorCode) {
2796
j9tty_printf(PORTLIB, "Error in creating path %s. Portable error code: %d\n", tempPath, errorCode);
2797
return RET_CREATE_DIR_FAILED;
2798
}
2799
}
2800
*current = DIR_SEPARATOR;
2801
current = strchr(current + 1, jimageFileSeparator);
2802
}
2803
writeOutputFile(buffer, (U_32)size, tempPath, NULL);
2804
} else {
2805
J9CfrClassFile* classfile = loadClassFromBytes(buffer, (U_32)size, (char *)resourceName, flags);
2806
if (NULL != classfile) {
2807
result = processClassFile(classfile, (U_32)size, (char *)resourceName, flags);
2808
if (NULL != classfile) {
2809
j9mem_free_memory((U_8*)classfile);
2810
classfile = NULL;
2811
}
2812
if (RET_SUCCESS != result) {
2813
goto _exit;
2814
}
2815
} else {
2816
result = RET_LOADCLASSFROMBYTES_FAILED;
2817
}
2818
}
2819
2820
_exit:
2821
return result;
2822
}
2823
2824
/**
2825
* Process all ".class" files in the given jimage file.
2826
*
2827
* @param [in] jimage pointer to J9JImage representing the jimage file
2828
* @param [in] jimageFileName name of the jimage file to be used
2829
* @param [in] flags build flags used during processing of class files
2830
*
2831
* @return RET_SUCCESS on success, negative error code on failure
2832
*/
2833
static I_32
2834
processAllInJImage(J9JImage *jimage, char *jimageFileName, U_32 flags)
2835
{
2836
J9JImageHeader *j9jimageHeader = jimage->j9jimageHeader;
2837
JImageHeader *jimageHeader = j9jimageHeader->jimageHeader;
2838
U_32 lotIndex = 0;
2839
U_8 *dataBuffer = NULL;
2840
UDATA dataBufferSize = 1024;
2841
I_32 result = RET_SUCCESS;
2842
2843
PORT_ACCESS_FROM_PORT(portLib);
2844
2845
dataBuffer = j9mem_allocate_memory(dataBufferSize, J9MEM_CATEGORY_CLASSES);
2846
if (NULL == dataBuffer) {
2847
j9tty_printf( PORTLIB, "Insufficient memory to complete operation\n");
2848
result = RET_ALLOCATE_FAILED;
2849
goto cleanExit;
2850
}
2851
2852
for (lotIndex = 0; lotIndex < jimageHeader->tableLength; lotIndex++) {
2853
void *imageLocation = NULL;
2854
J9JImageLocation j9jimageLocation = {0};
2855
U_32 locationOffset = 0;
2856
char *resourceName = NULL;
2857
2858
locationOffset = j9jimageHeader->locationsOffsetTable[lotIndex];
2859
if (locationOffset >= JIMAGE_LOCATION_DATA_SIZE(*jimageHeader)) {
2860
j9tty_printf(PORTLIB, "Invalid location offset found at index %u in Locations Offset Table of jimage file %s\n", lotIndex, jimageFileName);
2861
result = RET_JIMAGE_INVALIDLOCATION_OFFSET;
2862
goto cleanExit;
2863
}
2864
2865
imageLocation = j9jimageHeader->locationsData + j9jimageHeader->locationsOffsetTable[lotIndex];
2866
result = j9bcutil_createAndVerifyJImageLocation(PORTLIB, jimage, NULL /* resourceName */, imageLocation, &j9jimageLocation);
2867
if (J9JIMAGE_NO_ERROR != result) {
2868
j9tty_printf(PORTLIB, "Error in creating JImageLocation. Error code=%d\n", result);
2869
result = RET_JIMAGE_CREATEJIMAGELOCATION_FAILED;
2870
goto cleanExit;
2871
}
2872
2873
/* Don't bother with files that don't have a ".class" extension. */
2874
if ((NULL == j9jimageLocation.extensionString)
2875
|| (strncmp(j9jimageLocation.extensionString, CFDUMP_CLASSFILE_EXTENSION_WITHOUT_DOT, sizeof(CFDUMP_CLASSFILE_EXTENSION_WITHOUT_DOT)))
2876
) {
2877
continue;
2878
}
2879
2880
result = j9bcutil_getJImageResourceName(PORTLIB, jimage, j9jimageLocation.moduleString, j9jimageLocation.parentString, j9jimageLocation.baseString, j9jimageLocation.extensionString, &resourceName);
2881
if (J9JIMAGE_NO_ERROR == result) {
2882
result = processJImageResource(jimageFileName, jimage, &j9jimageLocation, resourceName, &dataBuffer, &dataBufferSize, flags);
2883
j9mem_free_memory(resourceName);
2884
if (RET_SUCCESS != result) {
2885
goto cleanExit;
2886
}
2887
} else {
2888
j9tty_printf(PORTLIB, "Insufficient memory to complete operation\n");
2889
}
2890
}
2891
2892
result = RET_SUCCESS;
2893
2894
cleanExit:
2895
if (NULL != dataBuffer) {
2896
j9mem_free_memory(dataBuffer);
2897
}
2898
return result;
2899
}
2900
2901
/**
2902
* Search list of resources in the given jimage file.
2903
* If the resource is found, then process it as requested by the user.
2904
*
2905
* @param [in] jimage pointer to J9JImage representing the jimage file
2906
* @param [in] jimageFileName name of the jimage file to be used
2907
* @param [in] resources list of resources to be searched in the jimage file
2908
* @param [in] flags build flags used during processing of class files
2909
*
2910
* @return RET_SUCCESS on success, negative error code on failure
2911
*/
2912
static I_32
2913
processFilesInJImage(J9JImage *jimage, char *jimageFileName, char **resources, U_32 flags)
2914
{
2915
J9JImageHeader *j9jimageHeader = jimage->j9jimageHeader;
2916
JImageHeader *jimageHeader = j9jimageHeader->jimageHeader;
2917
I_32 resourceCount = 0;
2918
U_8* dataBuffer = NULL;
2919
UDATA dataBufferSize = 1024;
2920
I_32 i = 0;
2921
I_32 result = RET_SUCCESS;
2922
JImageMatchInfo *matchInfo = NULL;
2923
2924
PORT_ACCESS_FROM_PORT(portLib);
2925
2926
if (ACTION_writeJImageResource == options.action) {
2927
/* Use same resource name(s) as specified by the user */
2928
char *currentFile = resources[0];
2929
while (NULL != currentFile) {
2930
resourceCount += 1;
2931
currentFile = resources[resourceCount];
2932
}
2933
} else {
2934
result = convertToJImageLocations(jimage, resources, &matchInfo, &resourceCount);
2935
}
2936
2937
dataBuffer = j9mem_allocate_memory(dataBufferSize, J9MEM_CATEGORY_CLASSES);
2938
if (NULL == dataBuffer) {
2939
j9tty_printf( PORTLIB, "Insufficient memory to complete operation\n");
2940
result = RET_ALLOCATE_FAILED;
2941
goto cleanExit;
2942
}
2943
2944
for (i = 0; i < resourceCount; i++) {
2945
J9JImageLocation j9jimageLocation = {0};
2946
char *resourceName = NULL;
2947
if (ACTION_writeJImageResource == options.action) {
2948
resourceName = resources[i];
2949
} else {
2950
result = j9bcutil_getJImageResourceName(PORTLIB, jimage, matchInfo[i].module, matchInfo[i].parentString, matchInfo[i].baseString, CFDUMP_CLASSFILE_EXTENSION_WITHOUT_DOT, &resourceName);
2951
if (result != J9JIMAGE_NO_ERROR ){
2952
j9tty_printf(PORTLIB, "Insufficient memory to complete operation\n");
2953
goto cleanExit;
2954
}
2955
}
2956
2957
2958
result = j9bcutil_lookupJImageResource(PORTLIB, jimage, &j9jimageLocation, resourceName);
2959
if (J9JIMAGE_RESOURCE_NOT_FOUND == result) {
2960
j9tty_printf(PORTLIB, "File %s not found in %s\n", resourceName, jimageFileName);
2961
goto cleanExit;
2962
}
2963
2964
result = processJImageResource(jimageFileName, jimage, &j9jimageLocation, resourceName, &dataBuffer, &dataBufferSize, flags);
2965
if (RET_SUCCESS != result) {
2966
goto cleanExit;
2967
}
2968
if (ACTION_writeJImageResource != options.action) {
2969
j9mem_free_memory(resourceName);
2970
}
2971
}
2972
2973
result = RET_SUCCESS;
2974
2975
cleanExit:
2976
if (NULL != dataBuffer) {
2977
j9mem_free_memory(dataBuffer);
2978
}
2979
if (NULL != matchInfo) {
2980
j9mem_free_memory(matchInfo);
2981
}
2982
return result;
2983
}
2984
2985
static J9CfrClassFile* loadClassFromBytes(U_8* data, U_32 dataLength, char* requestedFile, U_32 flags)
2986
{
2987
J9CfrError* error;
2988
U_8* segment;
2989
U_32 segmentLength;
2990
I_32 result;
2991
BOOLEAN verbose;
2992
2993
PORT_ACCESS_FROM_PORT(portLib);
2994
verbose = (options.options & OPTION_verbose)?TRUE:FALSE;
2995
2996
segmentLength = ESTIMATE_SIZE(dataLength);
2997
2998
if(verbose) j9tty_printf( PORTLIB, "<file size: %i bytes>\n", dataLength);
2999
if(verbose) j9tty_printf( PORTLIB, "<estimated memory size: %i bytes>\n", segmentLength);
3000
3001
do
3002
{
3003
segment = (U_8*)j9mem_allocate_memory(segmentLength, J9MEM_CATEGORY_CLASSES);
3004
if(segment == NULL) goto outOfMemory;
3005
3006
result = j9bcutil_readClassFileBytes(PORTLIB, verifyBuffers ? j9bcv_verifyClassStructure : NULL,
3007
data, dataLength, segment, segmentLength, flags, NULL, NULL, 0, UDATA_MAX);
3008
3009
if(result == -2)
3010
{
3011
/* Not enough space. Retry. */
3012
if(verbose) j9tty_printf( PORTLIB, "<increasing space to: %i bytes>\n", segmentLength*2);
3013
segmentLength = segmentLength * 2;
3014
j9mem_free_memory(segment);
3015
}
3016
} while (result == -2);
3017
3018
if(result == -1)
3019
{
3020
error = (J9CfrError*)segment;
3021
reportClassLoadError(error, requestedFile);
3022
return NULL;
3023
}
3024
else if(result == -2)
3025
{
3026
outOfMemory:
3027
j9tty_printf( PORTLIB, "Insufficient memory to complete operation\n");
3028
return NULL;
3029
}
3030
3031
return (J9CfrClassFile*) segment;
3032
}
3033
3034
3035
static J9ROMClass *translateClassBytes(U_8 * data, U_32 dataLength, char *requestedFile, U_32 flags)
3036
{
3037
U_8 *segment;
3038
U_64 xl8_startTime;
3039
U_64 xl8_endTime;
3040
IDATA result;
3041
UDATA bufferSize = 4 * dataLength;
3042
U_8 *classFileBuffer;
3043
3044
PORT_ACCESS_FROM_PORT(portLib);
3045
3046
retry:
3047
segment = j9mem_allocate_memory(bufferSize, J9MEM_CATEGORY_CLASSES);
3048
if (!segment) {
3049
j9tty_printf(PORTLIB, "Insufficient memory to complete operation\n");
3050
return NULL;
3051
}
3052
3053
classFileBuffer = NULL;
3054
3055
xl8_startTime = j9time_hires_clock();
3056
result = j9bcutil_buildRomClassIntoBuffer(data, dataLength, PORTLIB, verifyBuffers, flags,
3057
translationBuffers->flags, 0, segment, bufferSize, NULL, 0, NULL, 0, &classFileBuffer);
3058
xl8_endTime = j9time_hires_clock();
3059
3060
if (0 != (options.options & OPTION_verbose)) {
3061
j9tty_printf(PORTLIB, "<dynamic load time: %llu us.>\n", j9time_hires_delta(xl8_startTime, xl8_endTime, J9PORT_TIME_DELTA_IN_MICROSECONDS));
3062
}
3063
3064
switch (result) {
3065
case BCT_ERR_NO_ERROR:
3066
j9mem_free_memory(classFileBuffer);
3067
return (J9ROMClass *) segment;
3068
3069
case BCT_ERR_OUT_OF_ROM:
3070
j9mem_free_memory(classFileBuffer);
3071
j9mem_free_memory(segment);
3072
bufferSize *= 2;
3073
goto retry;
3074
3075
case BCT_ERR_CLASS_READ:
3076
reportClassLoadError((J9CfrError *) classFileBuffer, requestedFile);
3077
break;
3078
3079
default:
3080
j9tty_printf(PORTLIB, "<unknown error during translation: %d>\n", result);
3081
break;
3082
}
3083
3084
j9mem_free_memory(classFileBuffer);
3085
j9mem_free_memory(segment);
3086
return NULL;
3087
}
3088
3089
static BOOLEAN validateROMClassAddressRange(J9ROMClass *romClass, void *address, UDATA length, void *userData)
3090
{
3091
return ((UDATA)address >= (UDATA)romClass) && ((UDATA)address + length <= (UDATA)romClass + romClass->romSize);
3092
}
3093
3094
static I_32 processROMClass(J9ROMClass* romClass, char* requestedFile, U_32 flags)
3095
{
3096
char* filename;
3097
int i, length;
3098
U_32 newFlags, j;
3099
char ch;
3100
J9ROMFieldWalkState state;
3101
J9ROMFieldShape * currentField;
3102
U_8 *data = (U_8 *) romClass;
3103
U_32 size = romClass->romSize;
3104
char *extension = ".rom";
3105
3106
PORT_ACCESS_FROM_PORT(portLib);
3107
3108
switch(options.action)
3109
{
3110
case ACTION_definition:
3111
case ACTION_structure:
3112
case ACTION_bytecodes:
3113
case ACTION_dumpMaps:
3114
newFlags = flags;
3115
if (options.options & OPTION_dumpPreverifyData) {
3116
newFlags |= BCT_DumpPreverifyData;
3117
}
3118
j9bcutil_dumpRomClass(romClass, PORTLIB, (J9TranslationBufferSet *)translationBuffers, newFlags);
3119
break;
3120
3121
case ACTION_transformRomClass:
3122
{
3123
I_32 rc;
3124
/* we don't have J9JavaVM pointer here */
3125
rc = (I_32) j9bcutil_transformROMClass(NULL, PORTLIB, romClass, &data, &size);
3126
if (BCT_ERR_NO_ERROR != rc) {
3127
j9tty_printf(PORTLIB, "Error in recreating .class data: %d\n", rc);
3128
return rc;
3129
}
3130
extension = ".j9class";
3131
}
3132
/* fall through to write recreated .class data to file */
3133
case ACTION_writeRomClassFile:
3134
if(options.actionString) {
3135
writeOutputFile(data, size, options.actionString, extension);
3136
} else {
3137
length = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
3138
if(SWAPPING_ENDIAN(flags))
3139
{
3140
length =
3141
((((length) & 0xFF00) >> 8) |
3142
((length) & 0x00FF) << 8);
3143
}
3144
filename = j9mem_allocate_memory(length + 1, J9MEM_CATEGORY_CLASSES);
3145
for(i = 0; i < length; i++)
3146
{
3147
ch = ((U_8*) J9ROMCLASS_CLASSNAME(romClass))[i + 2];
3148
if(ch == '/') filename[i] = '_';
3149
else filename[i] = ch;
3150
}
3151
filename[i] = '\0';
3152
writeOutputFile(data, size, filename, extension);
3153
j9mem_free_memory(filename);
3154
}
3155
break;
3156
3157
case ACTION_writeRomClassFileHierarchy:
3158
{
3159
char tempPath[EsMaxPath];
3160
char *current = NULL;
3161
U_8 *romClassName = J9UTF8_DATA(J9ROMCLASS_CLASSNAME(romClass));
3162
I_32 rc = 0;
3163
3164
length = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
3165
if (SWAPPING_ENDIAN(flags)) {
3166
length = (((length & 0xFF00) >> 8) | (length & 0x00FF) << 8);
3167
}
3168
3169
j9str_printf(PORTLIB, tempPath, EsMaxPath, "%.*s", length, romClassName);
3170
current = strchr(tempPath, DIR_SEPARATOR);
3171
while (NULL != current) {
3172
*current = '\0';
3173
rc = j9file_mkdir(tempPath);
3174
if ((0 != rc) && (j9error_last_error_number() != J9PORT_ERROR_FILE_EXIST)) {
3175
j9tty_printf(PORTLIB, "Error in creating path %s\n", tempPath);
3176
return RET_CREATE_DIR_FAILED;
3177
}
3178
*current = DIR_SEPARATOR;
3179
current = strchr(current + 1, DIR_SEPARATOR);
3180
}
3181
writeOutputFile(data, size, tempPath, extension);
3182
}
3183
break;
3184
case ACTION_formatClass:
3185
j9_formatClass(romClass, options.actionString, strlen(options.actionString), flags);
3186
j9tty_printf(PORTLIB, "\n");
3187
break;
3188
3189
case ACTION_formatFields:
3190
currentField = romFieldsStartDo(romClass, &state);
3191
while (currentField != NULL) {
3192
j9_formatField(romClass, currentField, options.actionString, strlen(options.actionString), flags);
3193
j9tty_printf(PORTLIB, "\n");
3194
currentField = romFieldsNextDo(&state);
3195
}
3196
break;
3197
3198
case ACTION_formatMethods:
3199
{
3200
J9ROMMethod * currentMethod = (J9ROMMethod *) J9ROMCLASS_ROMMETHODS(romClass);
3201
3202
for(j = 0; j < romClass->romMethodCount; j++)
3203
{
3204
j9_formatMethod(romClass, currentMethod, options.actionString, strlen(options.actionString), flags);
3205
j9tty_printf(PORTLIB, "\n");
3206
currentMethod = nextROMMethod(currentMethod);
3207
}
3208
}
3209
break;
3210
3211
case ACTION_formatBytecodes:
3212
{
3213
J9ROMMethod * currentMethod = (J9ROMMethod *) J9ROMCLASS_ROMMETHODS(romClass);
3214
3215
for(j = 0; j < romClass->romMethodCount; j++)
3216
{
3217
j9_formatBytecodes(romClass, currentMethod, NULL, 0, options.actionString, strlen(options.actionString), flags);
3218
currentMethod = nextROMMethod(currentMethod);
3219
}
3220
}
3221
break;
3222
3223
case ACTION_dumpRomClass:
3224
{
3225
UDATA nestingThreshold = (UDATA)atoi(options.actionString);
3226
j9bcutil_linearDumpROMClass(portLib, romClass, NULL, nestingThreshold, validateROMClassAddressRange);
3227
}
3228
break;
3229
3230
case ACTION_dumpRomClassXML:
3231
j9bcutil_linearDumpROMClassXML(portLib, romClass, validateROMClassAddressRange);
3232
break;
3233
3234
case ACTION_queryRomClass:
3235
j9bcutil_queryROMClassCommaSeparated(portLib, romClass, NULL, options.actionString, validateROMClassAddressRange);
3236
break;
3237
3238
default:
3239
return RET_UNSUPPORTED_ACTION;
3240
}
3241
return 0;
3242
}
3243
3244
3245
/* Print information about the bytecode formatted as per @formatString.
3246
Format string:
3247
%<modifiers><specifier>
3248
Supported specifiers:
3249
c short class name
3250
C qualified class name
3251
n method name
3252
s method signature
3253
i instruction pointer
3254
b bytecode
3255
B complete bytecode
3256
p parameters
3257
Supported modifiers:
3258
%i
3259
d decimal (default)
3260
x hex, lowercase
3261
X hex, uppercase
3262
%B
3263
d decimal
3264
x hex, lowercase
3265
X hex, uppercase (default)
3266
%b
3267
a ascii (default)
3268
d decimal
3269
x hex, lowercase
3270
X hex, uppercase
3271
%p
3272
a ascii (default)
3273
d decimal
3274
x hex, lowercase
3275
X hex, uppercase
3276
*/
3277
static void sun_formatBytecode(J9CfrClassFile* classfile, J9CfrMethod* method, BOOLEAN bigEndian, U_8* bcStart, U_8* bytes, U_8 bc, U_32 bytesLength, U_32 decode, char *formatString, IDATA length)
3278
{
3279
J9CfrConstantPoolInfo* info;
3280
U_8* string;
3281
U_8* bcIndex;
3282
U_16 cpIndex;
3283
UDATA pc, branch;
3284
U_8 u8, u8_2;
3285
U_16 u16, u16_2;
3286
U_32 u32;
3287
U_32 index, npairs;
3288
U_32 j;
3289
I_32 low, high, key;
3290
I_32 i, k;
3291
char modifier;
3292
char pcModifier;
3293
char ch, ch2;
3294
3295
PORT_ACCESS_FROM_PORT(portLib);
3296
3297
pcModifier = 'd';
3298
pc = bytes - bcStart;
3299
3300
i = 0;
3301
modifier = '\0';
3302
while(i < length)
3303
{
3304
ch = formatString[i++];
3305
if(modifier || ch == '%')
3306
{
3307
if(ch == '%')
3308
{
3309
modifier = '\0';
3310
ch = formatString[i++];
3311
}
3312
if(ch == '\0' || ch == '%')
3313
{
3314
if(modifier) j9tty_printf(PORTLIB, "%%%c", modifier);
3315
j9tty_output_char(ch);
3316
}
3317
else
3318
{
3319
switch(ch)
3320
{
3321
case 'c':
3322
/* short class name */
3323
cpIndex = classfile->constantPool[classfile->thisClass].slot1;
3324
string = classfile->constantPool[cpIndex].bytes;
3325
j = 0;
3326
index = 0;
3327
while('\0' != (ch2 = string[j++])) if(ch2 == '/') index = j;
3328
j = index;
3329
while('\0' != (ch2 = string[j++])) j9tty_output_char(ch2);
3330
break;
3331
3332
case 'C':
3333
/* qualified class name */
3334
cpIndex = classfile->constantPool[classfile->thisClass].slot1;
3335
string = classfile->constantPool[cpIndex].bytes;
3336
j = 0;
3337
while('\0' != (ch2 = string[j++]))
3338
{
3339
if(ch2 == '/') j9tty_output_char('.');
3340
else j9tty_output_char(ch2);
3341
}
3342
break;
3343
3344
case 'n':
3345
/* method name */
3346
string = classfile->constantPool[method->nameIndex].bytes;
3347
j9tty_printf(PORTLIB, "%s", string);
3348
break;
3349
3350
case 's':
3351
/* method signature */
3352
string = classfile->constantPool[method->descriptorIndex].bytes;
3353
j = 0;
3354
while('\0' != (ch2 = string[j++]))
3355
{
3356
if(ch2 == '/') j9tty_output_char('.');
3357
else j9tty_output_char(ch2);
3358
}
3359
break;
3360
3361
case 'i':
3362
/* instruction pointer */
3363
pcModifier = modifier;
3364
switch(modifier)
3365
{
3366
case 'x':
3367
j9tty_printf(PORTLIB, "%08x", pc);
3368
break;
3369
3370
case 'X':
3371
j9tty_printf(PORTLIB, "%08X", pc);
3372
break;
3373
3374
case 'd':
3375
default:
3376
j9tty_printf(PORTLIB, "%i", pc);
3377
break;
3378
}
3379
modifier = '\0';
3380
break;
3381
3382
case 'b':
3383
/* bytecode */
3384
switch(modifier)
3385
{
3386
case 'x':
3387
j9tty_printf(PORTLIB, "%02x", bc);
3388
break;
3389
3390
case 'X':
3391
j9tty_printf(PORTLIB, "%02X", bc);
3392
break;
3393
3394
case 'd':
3395
j9tty_printf(PORTLIB, "%i", bc);
3396
break;
3397
3398
default:
3399
j9tty_printf(PORTLIB, "%s", sunJavaBCNames[bc]);
3400
break;
3401
}
3402
modifier = '\0';
3403
break;
3404
3405
case 'B':
3406
/* bytecode bytes */
3407
switch(modifier)
3408
{
3409
case 'd':
3410
for(j = 0; j < bytesLength; )
3411
{
3412
j9tty_printf(PORTLIB, "%i", bytes[j]);
3413
if(++j < bytesLength) j9tty_output_char(' ');
3414
}
3415
break;
3416
3417
case 'x':
3418
for(j = 0; j < bytesLength; j++) j9tty_printf(PORTLIB, "%02x", bytes[j]);
3419
break;
3420
3421
default:
3422
case 'X':
3423
for(j = 0; j < bytesLength; j++) j9tty_printf(PORTLIB, "%02X", bytes[j]);
3424
break;
3425
}
3426
modifier = '\0';
3427
break;
3428
3429
case 'p':
3430
/* parameters */
3431
bcIndex = bytes + 1;
3432
if(bc != *bytes) bcIndex++;
3433
switch(decode)
3434
{
3435
case CFR_DECODE_SIMPLE:
3436
break;
3437
3438
case CFR_DECODE_I8:
3439
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
3440
switch(modifier)
3441
{
3442
case 'x':
3443
j9tty_printf(PORTLIB, "%02x", (I_8)u8);
3444
break;
3445
3446
case 'X':
3447
j9tty_printf(PORTLIB, "%02X", (I_8)u8);
3448
break;
3449
3450
case 'd':
3451
case 'a':
3452
default:
3453
j9tty_printf(PORTLIB, "%i", (I_8)u8);
3454
break;
3455
}
3456
break;
3457
3458
case CFR_DECODE_U8:
3459
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
3460
switch(modifier)
3461
{
3462
case 'x':
3463
j9tty_printf(PORTLIB, "%02x", u8);
3464
break;
3465
3466
case 'X':
3467
j9tty_printf(PORTLIB, "%02X", u8);
3468
break;
3469
3470
case 'd':
3471
case 'a':
3472
default:
3473
j9tty_printf(PORTLIB, "%i", u8);
3474
break;
3475
}
3476
break;
3477
3478
case CFR_DECODE_I16:
3479
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
3480
switch(modifier)
3481
{
3482
case 'x':
3483
j9tty_printf(PORTLIB, "%04x", (I_16)u16);
3484
break;
3485
3486
case 'X':
3487
j9tty_printf(PORTLIB, "%04X", (I_16)u16);
3488
break;
3489
3490
case 'd':
3491
case 'a':
3492
default:
3493
j9tty_printf(PORTLIB, "%i", (I_16)u16);
3494
break;
3495
}
3496
break;
3497
3498
case CFR_DECODE_U16:
3499
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
3500
switch(modifier)
3501
{
3502
case 'x':
3503
j9tty_printf(PORTLIB, "%04x", (I_16)u16);
3504
break;
3505
3506
case 'X':
3507
j9tty_printf(PORTLIB, "%04X", (I_16)u16);
3508
break;
3509
3510
case 'd':
3511
case 'a':
3512
default:
3513
j9tty_printf(PORTLIB, "%i", (I_16)u16);
3514
break;
3515
}
3516
break;
3517
3518
case CFR_DECODE_U8_I8:
3519
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
3520
NEXT_U8_ENDIAN(bigEndian, u8_2, bcIndex);
3521
switch(modifier)
3522
{
3523
case 'x':
3524
j9tty_printf(PORTLIB, "%02x %02x", u8, (I_8)u8_2);
3525
break;
3526
3527
case 'X':
3528
j9tty_printf(PORTLIB, "%02X %02X", u8, (I_8)u8_2);
3529
break;
3530
3531
case 'd':
3532
case 'a':
3533
default:
3534
j9tty_printf(PORTLIB, "%i %i", u8, (I_8)u8_2);
3535
break;
3536
}
3537
break;
3538
3539
case CFR_DECODE_U16_I16:
3540
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
3541
NEXT_U16_ENDIAN(bigEndian, u16_2, bcIndex);
3542
switch(modifier)
3543
{
3544
case 'x':
3545
j9tty_printf(PORTLIB, "%04x %04x", u16, (I_16)u16_2);
3546
break;
3547
3548
case 'X':
3549
j9tty_printf(PORTLIB, "%04X %04X", u16, (I_16)u16_2);
3550
break;
3551
3552
case 'd':
3553
case 'a':
3554
default:
3555
j9tty_printf(PORTLIB, "%i %i", u16, (I_16)u16_2);
3556
break;
3557
}
3558
break;
3559
3560
case CFR_DECODE_CP8:
3561
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
3562
switch(modifier)
3563
{
3564
case 'x':
3565
j9tty_printf(PORTLIB, "%02x", u8);
3566
break;
3567
3568
case 'X':
3569
j9tty_printf(PORTLIB, "%02X", u8);
3570
break;
3571
3572
case 'd':
3573
j9tty_printf(PORTLIB, "%i", u8);
3574
break;
3575
3576
case 'a':
3577
default:
3578
info = &(classfile->constantPool[u8]);
3579
cpAscii:
3580
switch(info->tag)
3581
{
3582
case CFR_CONSTANT_Integer:
3583
j9tty_printf( PORTLIB, "(int) 0x%08X", info->slot1);
3584
break;
3585
3586
case CFR_CONSTANT_Float:
3587
j9tty_printf( PORTLIB, "(float) 0x%08X", info->slot1);
3588
break;
3589
3590
case CFR_CONSTANT_Long:
3591
#ifdef J9VM_ENV_LITTLE_ENDIAN
3592
j9tty_printf( PORTLIB, "(long) 0x%08X%08X", info->slot2, info->slot1);
3593
#else
3594
j9tty_printf( PORTLIB, "(long) 0x%08X%08X", info->slot1, info->slot2);
3595
#endif
3596
break;
3597
3598
case CFR_CONSTANT_Double:
3599
#ifdef J9VM_ENV_LITTLE_ENDIAN
3600
j9tty_printf( PORTLIB, "(double) 0x%08X%08X", info->slot2, info->slot1);
3601
#else
3602
j9tty_printf( PORTLIB, "(double) 0x%08X%08X", info->slot1, info->slot2);
3603
#endif
3604
break;
3605
3606
case CFR_CONSTANT_String:
3607
string = classfile->constantPool[info->slot1].bytes;
3608
j9tty_printf(PORTLIB, "(java.lang.String) \"%s\"", string);
3609
break;
3610
case CFR_CONSTANT_MethodType:
3611
string = classfile->constantPool[info->slot1].bytes;
3612
j9tty_printf(PORTLIB, "(java.dyn.MethodType) \"%s\"", string);
3613
break;
3614
3615
case CFR_CONSTANT_Class:
3616
string = classfile->constantPool[info->slot1].bytes;
3617
j = 0;
3618
while('\0' != (ch2 = string[j++]))
3619
{
3620
if(ch2 == '/') j9tty_output_char('.');
3621
else j9tty_output_char(ch2);
3622
}
3623
break;
3624
3625
case CFR_CONSTANT_Fieldref:
3626
case CFR_CONSTANT_Methodref:
3627
case CFR_CONSTANT_InterfaceMethodref:
3628
cpIndex = classfile->constantPool[info->slot1].slot1;
3629
string = classfile->constantPool[cpIndex].bytes;
3630
j = 0;
3631
while('\0' != (ch2 = string[j++]))
3632
{
3633
if(ch2 == '/') j9tty_output_char('.');
3634
else j9tty_output_char(ch2);
3635
}
3636
cpIndex = classfile->constantPool[info->slot2].slot1;
3637
string = classfile->constantPool[cpIndex].bytes;
3638
j9tty_printf(PORTLIB, ".%s ", string);
3639
cpIndex = classfile->constantPool[info->slot2].slot2;
3640
string = classfile->constantPool[cpIndex].bytes;
3641
j = 0;
3642
while('\0' != (ch2 = string[j++]))
3643
{
3644
if(ch2 == '/') j9tty_output_char('.');
3645
else j9tty_output_char(ch2);
3646
}
3647
break;
3648
3649
case CFR_CONSTANT_MethodHandle:
3650
/* TODO - print pretty: kind + field/method ref */
3651
j9tty_printf(PORTLIB, "<java.dyn.MethodHandle %i>", info->tag);
3652
break;
3653
3654
case CFR_CONSTANT_Null:
3655
case CFR_CONSTANT_Utf8:
3656
case CFR_CONSTANT_NameAndType:
3657
j9tty_printf(PORTLIB, "<unexpected constant type %i>", info->tag);
3658
break;
3659
3660
default:
3661
j9tty_printf(PORTLIB, "<unknown constant type %i>", info->tag);
3662
break;
3663
}
3664
}
3665
break;
3666
3667
case CFR_DECODE_CP16:
3668
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
3669
switch(modifier)
3670
{
3671
case 'x':
3672
j9tty_printf(PORTLIB, "%04x", u16);
3673
break;
3674
3675
case 'X':
3676
j9tty_printf(PORTLIB, "%04X", u16);
3677
break;
3678
3679
case 'd':
3680
j9tty_printf(PORTLIB, "%i", u16);
3681
break;
3682
3683
case 'a':
3684
default:
3685
info = &(classfile->constantPool[u16]);
3686
goto cpAscii;
3687
}
3688
break;
3689
3690
case CFR_DECODE_MULTIANEWARRAY:
3691
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
3692
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
3693
switch(modifier)
3694
{
3695
case 'x':
3696
j9tty_printf(PORTLIB, "%02x %04x", u8, u16);
3697
break;
3698
3699
case 'X':
3700
j9tty_printf(PORTLIB, "%02X %04X", u8, u16);
3701
break;
3702
3703
case 'd':
3704
j9tty_printf(PORTLIB, "%i %i", u8, u16);
3705
break;
3706
3707
case 'a':
3708
default:
3709
j9tty_printf(PORTLIB, "%i ", u8);
3710
info = &(classfile->constantPool[u16]);
3711
goto cpAscii;
3712
}
3713
break;
3714
3715
case CFR_DECODE_L16:
3716
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
3717
switch(modifier)
3718
{
3719
case 'x':
3720
j9tty_printf(PORTLIB, "%04x", (I_16)u16);
3721
break;
3722
3723
case 'X':
3724
j9tty_printf(PORTLIB, "%04X", (I_16)u16);
3725
break;
3726
3727
case 'd':
3728
j9tty_printf(PORTLIB, "%i", (I_16)u16);
3729
break;
3730
3731
case 'a':
3732
default:
3733
branch = pc + (I_16)u16;
3734
switch(pcModifier)
3735
{
3736
case 'x':
3737
j9tty_printf(PORTLIB, "%08x", branch);
3738
break;
3739
3740
case 'X':
3741
j9tty_printf(PORTLIB, "%08X", branch);
3742
break;
3743
3744
case 'd':
3745
j9tty_printf(PORTLIB, "%i", branch);
3746
break;
3747
}
3748
break;
3749
}
3750
break;
3751
3752
case CFR_DECODE_L32:
3753
NEXT_U32_ENDIAN(bigEndian, u32, bcIndex);
3754
switch(modifier)
3755
{
3756
case 'x':
3757
j9tty_printf(PORTLIB, "%08x", (I_32)u32);
3758
break;
3759
3760
case 'X':
3761
j9tty_printf(PORTLIB, "%08X", (I_32)u32);
3762
break;
3763
3764
case 'd':
3765
j9tty_printf(PORTLIB, "%i", (I_32)u32);
3766
break;
3767
3768
case 'a':
3769
default:
3770
branch = pc + (I_32)u32;
3771
switch(pcModifier)
3772
{
3773
case 'x':
3774
j9tty_printf(PORTLIB, "%08x", branch);
3775
break;
3776
3777
case 'X':
3778
j9tty_printf(PORTLIB, "%08X", branch);
3779
break;
3780
3781
case 'd':
3782
j9tty_printf(PORTLIB, "%i", branch);
3783
break;
3784
}
3785
break;
3786
}
3787
break;
3788
3789
case CFR_DECODE_NEWARRAY:
3790
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
3791
switch(modifier)
3792
{
3793
case 'x':
3794
j9tty_printf(PORTLIB, "%02x", u8);
3795
break;
3796
3797
case 'X':
3798
j9tty_printf(PORTLIB, "%02X", u8);
3799
break;
3800
3801
case 'd':
3802
j9tty_printf(PORTLIB, "%i", u8);
3803
break;
3804
3805
case 'a':
3806
default:
3807
switch(u8)
3808
{
3809
case /*T_BOOLEAN*/ 4 :
3810
j9tty_printf( PORTLIB, "boolean");
3811
break;
3812
case /*T_CHAR*/ 5:
3813
j9tty_printf( PORTLIB, "char");
3814
break;
3815
case /*T_FLOAT*/ 6:
3816
j9tty_printf( PORTLIB, "float");
3817
break;
3818
case /*T_DOUBLE*/ 7:
3819
j9tty_printf( PORTLIB, "double");
3820
break;
3821
case /*T_BYTE*/ 8:
3822
j9tty_printf( PORTLIB, "byte");
3823
break;
3824
case /*T_SHORT*/ 9:
3825
j9tty_printf( PORTLIB, "short");
3826
break;
3827
case /*T_INT*/ 10:
3828
j9tty_printf( PORTLIB, "int");
3829
break;
3830
case /*T_LONG*/ 11:
3831
j9tty_printf( PORTLIB, "long");
3832
break;
3833
default:
3834
j9tty_printf( PORTLIB, "???");
3835
break;
3836
}
3837
break;
3838
}
3839
break;
3840
3841
case CFR_DECODE_TABLESWITCH:
3842
bcIndex = bytes + 4 - (pc % 4);
3843
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
3844
branch = pc + index;
3845
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
3846
low = (I_32)index;
3847
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
3848
high = (I_32)index;
3849
j9tty_printf( PORTLIB, "default->%i", branch);
3850
j = high - low + 1;
3851
for(k = 0; k <= (I_32) j; k++)
3852
{
3853
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
3854
branch = pc + index;
3855
j9tty_printf( PORTLIB, " %i->%i", k + low, branch);
3856
}
3857
break;
3858
3859
case CFR_DECODE_LOOKUPSWITCH:
3860
bcIndex = bytes + 4 - (pc % 4);
3861
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
3862
branch = pc + index;
3863
NEXT_U32_ENDIAN(bigEndian, npairs, bcIndex);
3864
j9tty_printf( PORTLIB, "default->%i", branch);
3865
for(j = 0; j < npairs; j++)
3866
{
3867
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
3868
key = (I_32)index;
3869
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
3870
branch = pc + index;
3871
j9tty_printf( PORTLIB, " %i->%i", key, branch);
3872
}
3873
break;
3874
}
3875
modifier = '\0';
3876
break;
3877
3878
case 'a':
3879
/* ascii */
3880
if(formatString[i] == 'b' || formatString[i] == 'p')
3881
{
3882
modifier = ch;
3883
}
3884
else
3885
{
3886
j9tty_output_char('%');
3887
j9tty_output_char(ch);
3888
}
3889
break;
3890
3891
case 'd':
3892
/* decimal */
3893
case 'x':
3894
/* hex, lowercase */
3895
case 'X':
3896
/* hex, uppercase */
3897
3898
if(formatString[i] == 'i' || formatString[i] == 'B' || formatString[i] == 'b' || formatString[i] == 'p')
3899
{
3900
modifier = ch;
3901
break;
3902
}
3903
3904
default:
3905
j9tty_output_char('%');
3906
j9tty_output_char(ch);
3907
}
3908
}
3909
}
3910
else
3911
{
3912
j9tty_output_char(ch);
3913
}
3914
}
3915
return;
3916
}
3917
3918
3919
static void sun_formatBytecodes(J9CfrClassFile* classfile, J9CfrMethod* method, BOOLEAN bigEndian, U_8* bytecodes, U_32 bytecodesLength, char *formatString, IDATA stringLength)
3920
{
3921
J9CfrAttributeCode* code;
3922
U_8 *bcIndex, *tempIndex;
3923
I_32 pc, index;
3924
I_32 low, high;
3925
U_32 length, npairs, bcLength;
3926
U_8 bc;
3927
BOOLEAN wide;
3928
3929
PORT_ACCESS_FROM_PORT(portLib);
3930
3931
if(!(code = method->codeAttribute)) return;
3932
3933
if(bytecodes)
3934
{
3935
bcIndex = bytecodes;
3936
length = bytecodesLength;
3937
}
3938
else
3939
{
3940
bytecodes = code->code;
3941
bcIndex = code->code;
3942
length = code->codeLength;
3943
}
3944
pc = 0;
3945
wide = FALSE;
3946
3947
while((U_32)pc < length)
3948
{
3949
bc = *bcIndex;
3950
pc++;
3951
switch(bc)
3952
{
3953
case CFR_BC_bipush:
3954
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 2, CFR_DECODE_I8, formatString, stringLength);
3955
pc++;
3956
bcIndex += 2;
3957
break;
3958
3959
case CFR_BC_sipush:
3960
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 3, CFR_DECODE_I16, formatString, stringLength);
3961
pc += 2;
3962
bcIndex += 3;
3963
break;
3964
3965
case CFR_BC_ldc:
3966
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 2, CFR_DECODE_CP8, formatString, stringLength);
3967
pc++;
3968
bcIndex += 2;
3969
break;
3970
3971
case CFR_BC_ldc_w:
3972
case CFR_BC_ldc2_w:
3973
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 3, CFR_DECODE_CP16, formatString, stringLength);
3974
pc += 2;
3975
bcIndex += 3;
3976
break;
3977
3978
case CFR_BC_iload:
3979
case CFR_BC_lload:
3980
case CFR_BC_fload:
3981
case CFR_BC_dload:
3982
case CFR_BC_aload:
3983
case CFR_BC_istore:
3984
case CFR_BC_lstore:
3985
case CFR_BC_fstore:
3986
case CFR_BC_dstore:
3987
case CFR_BC_astore:
3988
case CFR_BC_ret:
3989
if(wide)
3990
{
3991
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 4, CFR_DECODE_U16, formatString, stringLength);
3992
pc += 2;
3993
bcIndex += 3;
3994
wide = FALSE;
3995
}
3996
else
3997
{
3998
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 2, CFR_DECODE_U8, formatString, stringLength);
3999
pc++;
4000
bcIndex += 2;
4001
}
4002
break;
4003
4004
case CFR_BC_iinc:
4005
if(wide)
4006
{
4007
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 6, CFR_DECODE_U16_I16, formatString, stringLength);
4008
pc += 4;
4009
bcIndex += 5;
4010
wide = FALSE;
4011
}
4012
else
4013
{
4014
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 3, CFR_DECODE_U8_I8, formatString, stringLength);
4015
pc += 2;
4016
bcIndex += 3;
4017
}
4018
break;
4019
4020
case CFR_BC_ifeq:
4021
case CFR_BC_ifne:
4022
case CFR_BC_iflt:
4023
case CFR_BC_ifge:
4024
case CFR_BC_ifgt:
4025
case CFR_BC_ifle:
4026
case CFR_BC_if_icmpeq:
4027
case CFR_BC_if_icmpne:
4028
case CFR_BC_if_icmplt:
4029
case CFR_BC_if_icmpge:
4030
case CFR_BC_if_icmpgt:
4031
case CFR_BC_if_icmple:
4032
case CFR_BC_if_acmpeq:
4033
case CFR_BC_if_acmpne:
4034
case CFR_BC_goto:
4035
case CFR_BC_jsr:
4036
case CFR_BC_ifnull:
4037
case CFR_BC_ifnonnull:
4038
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 3, CFR_DECODE_L16, formatString, stringLength);
4039
pc += 2;
4040
bcIndex += 3;
4041
break;
4042
4043
case CFR_BC_tableswitch:
4044
tempIndex = bcIndex + 1;
4045
switch((pc - 1) % 4)
4046
{
4047
case 0:
4048
tempIndex++;
4049
case 1:
4050
tempIndex++;
4051
case 2:
4052
tempIndex++;
4053
case 3:
4054
break;
4055
}
4056
NEXT_U32_ENDIAN(bigEndian, index, tempIndex);
4057
NEXT_U32_ENDIAN(bigEndian, index, tempIndex);
4058
low = (I_32)index;
4059
NEXT_U32_ENDIAN(bigEndian, index, tempIndex);
4060
high = (I_32)index;
4061
bcLength = (U_32) (tempIndex - bcIndex) + ((high - low + 1) * 4);
4062
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, bcLength, CFR_DECODE_TABLESWITCH, formatString, stringLength);
4063
bcIndex += bcLength;
4064
pc += bcLength - 1;
4065
break;
4066
4067
case CFR_BC_lookupswitch:
4068
tempIndex = bcIndex + 1;
4069
switch((pc - 1) % 4)
4070
{
4071
case 0:
4072
tempIndex++;
4073
case 1:
4074
tempIndex++;
4075
case 2:
4076
tempIndex++;
4077
case 3:
4078
break;
4079
}
4080
NEXT_U32_ENDIAN(bigEndian, index, tempIndex);
4081
NEXT_U32_ENDIAN(bigEndian, npairs, tempIndex);
4082
bcLength = (U_32)(tempIndex - bcIndex) + (npairs * 8);
4083
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, bcLength, CFR_DECODE_LOOKUPSWITCH, formatString, stringLength);
4084
bcIndex += bcLength;
4085
pc += bcLength - 1;
4086
break;
4087
4088
case CFR_BC_getstatic:
4089
case CFR_BC_putstatic:
4090
case CFR_BC_getfield:
4091
case CFR_BC_putfield:
4092
case CFR_BC_invokevirtual:
4093
case CFR_BC_invokespecial:
4094
case CFR_BC_invokestatic:
4095
case CFR_BC_new:
4096
case CFR_BC_anewarray:
4097
case CFR_BC_checkcast:
4098
case CFR_BC_instanceof:
4099
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 3, CFR_DECODE_CP16, formatString, stringLength);
4100
pc += 2;
4101
bcIndex += 3;
4102
break;
4103
4104
case CFR_BC_invokeinterface:
4105
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 3, CFR_DECODE_CP16, formatString, stringLength);
4106
pc += 4;
4107
bcIndex += 5;
4108
break;
4109
4110
case CFR_BC_newarray:
4111
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 2, CFR_DECODE_NEWARRAY, formatString, stringLength);
4112
pc++;
4113
bcIndex += 2;
4114
break;
4115
4116
case CFR_BC_wide:
4117
wide = TRUE;
4118
break;
4119
4120
case CFR_BC_multianewarray:
4121
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 4, CFR_DECODE_MULTIANEWARRAY, formatString, stringLength);
4122
pc += 3;
4123
bcIndex += 4;
4124
break;
4125
4126
case CFR_BC_goto_w:
4127
case CFR_BC_jsr_w:
4128
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 5, CFR_DECODE_L32, formatString, stringLength);
4129
pc += 4;
4130
bcIndex += 5;
4131
break;
4132
4133
default:
4134
sun_formatBytecode(classfile, method, bigEndian, bytecodes, bcIndex, bc, 1, CFR_DECODE_SIMPLE, formatString, stringLength);
4135
bcIndex++;
4136
break;
4137
}
4138
j9tty_printf(PORTLIB, "\n");
4139
}
4140
4141
return;
4142
}
4143
4144
4145
/* Print information about the class formatted as per @formatString.
4146
Format string:
4147
%<modifiers><specifier>
4148
Supported specifiers:
4149
p package
4150
c short class name
4151
C qualified class name
4152
s superclass name
4153
i interfaces names
4154
m modifiers
4155
Supported modifiers:
4156
%m
4157
a ascii (default)
4158
d decimal
4159
x hex, lowercase
4160
X hex, uppercase
4161
*/
4162
static void sun_formatClass(J9CfrClassFile* classfile, char *formatString, IDATA length)
4163
{
4164
U_16 cpIndex;
4165
U_8* string;
4166
U_32 j, k;
4167
U_32 index;
4168
int i;
4169
char ch, ch2;
4170
char modifier;
4171
4172
PORT_ACCESS_FROM_PORT(portLib);
4173
i = 0;
4174
modifier = '\0';
4175
while(i < length)
4176
{
4177
ch = formatString[i++];
4178
if(modifier || ch == '%')
4179
{
4180
if(ch == '%')
4181
{
4182
modifier = '\0';
4183
ch = formatString[i++];
4184
}
4185
if(ch == '\0' || ch == '%')
4186
{
4187
if(modifier) j9tty_printf(PORTLIB, "%%%c", modifier);
4188
j9tty_output_char(ch);
4189
}
4190
else
4191
{
4192
switch(ch)
4193
{
4194
case 'p':
4195
/* package */
4196
cpIndex = classfile->constantPool[classfile->thisClass].slot1;
4197
string = classfile->constantPool[cpIndex].bytes;
4198
j = 0;
4199
index = 0;
4200
while('\0' != (ch2 = string[j++])) if(ch2 == '/') index = j - 1;
4201
j = 0;
4202
while(j < index)
4203
{
4204
ch2 = string[j++];
4205
if(ch2 == '/') j9tty_output_char('.');
4206
else j9tty_output_char(ch2);
4207
}
4208
break;
4209
4210
case 'c':
4211
/* short class name */
4212
cpIndex = classfile->constantPool[classfile->thisClass].slot1;
4213
string = classfile->constantPool[cpIndex].bytes;
4214
j = 0;
4215
index = 0;
4216
while('\0' != (ch2 = string[j++])) if(ch2 == '/') index = j;
4217
j = index;
4218
while('\0' != (ch2 = string[j++])) j9tty_output_char(ch2);
4219
break;
4220
4221
case 'C':
4222
/* qualified class name */
4223
cpIndex = classfile->constantPool[classfile->thisClass].slot1;
4224
string = classfile->constantPool[cpIndex].bytes;
4225
j = 0;
4226
while('\0' != (ch2 = string[j++]))
4227
{
4228
if(ch2 == '/') j9tty_output_char('.');
4229
else j9tty_output_char(ch2);
4230
}
4231
break;
4232
4233
case 's':
4234
/* superclass name */
4235
if(classfile->superClass)
4236
{
4237
cpIndex = classfile->constantPool[classfile->superClass].slot1;
4238
string = classfile->constantPool[cpIndex].bytes;
4239
j = 0;
4240
while('\0' != (ch2 = string[j++]))
4241
{
4242
if(ch2 == '/') j9tty_output_char('.');
4243
else j9tty_output_char(ch2);
4244
}
4245
}
4246
break;
4247
4248
case 'i':
4249
/* interfaces names */
4250
for(j = 0; j < classfile->interfacesCount;)
4251
{
4252
cpIndex = classfile->interfaces[j];
4253
cpIndex = classfile->constantPool[cpIndex].slot1;
4254
string = classfile->constantPool[cpIndex].bytes;
4255
k = 0;
4256
while('\0' != (ch2 = string[k++]))
4257
{
4258
if(ch2 == '/') j9tty_output_char('.');
4259
else j9tty_output_char(ch2);
4260
}
4261
if(++j != classfile->interfacesCount) j9tty_output_char(',');
4262
}
4263
break;
4264
4265
case 'm':
4266
/* modifiers */
4267
switch(modifier)
4268
{
4269
case 'd':
4270
j9tty_printf(PORTLIB, "%i ( ", classfile->accessFlags);
4271
printModifiers(PORTLIB, classfile->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_CLASS);
4272
j9tty_printf( PORTLIB, " )");
4273
break;
4274
4275
case 'x':
4276
j9tty_printf(PORTLIB, "%08x ( ", classfile->accessFlags);
4277
printModifiers(PORTLIB, classfile->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_CLASS);
4278
j9tty_printf( PORTLIB, " )");
4279
break;
4280
4281
case 'X':
4282
j9tty_printf(PORTLIB, "%08X ( ", classfile->accessFlags);
4283
printModifiers(PORTLIB, classfile->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_CLASS);
4284
j9tty_printf( PORTLIB, " )");
4285
break;
4286
4287
case '\0':
4288
case 'a':
4289
default:
4290
printModifiers(PORTLIB, classfile->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_CLASS);
4291
break;
4292
}
4293
modifier = '\0';
4294
break;
4295
4296
case 'a':
4297
/* ascii */
4298
case 'd':
4299
/* decimal */
4300
case 'x':
4301
/* hex, lowercase */
4302
case 'X':
4303
/* hex, uppercase */
4304
4305
if(formatString[i] == 'm')
4306
{
4307
modifier = ch;
4308
break;
4309
}
4310
4311
default:
4312
j9tty_output_char('%');
4313
j9tty_output_char(ch);
4314
}
4315
}
4316
}
4317
else
4318
{
4319
j9tty_output_char(ch);
4320
}
4321
}
4322
return;
4323
}
4324
4325
4326
/* Print information about the field formatted as per @formatString.
4327
Format string:
4328
%<modifiers><specifier>
4329
Supported specifiers:
4330
c short class name
4331
C qualified class name
4332
n name
4333
t type
4334
s signature
4335
i inlined value
4336
m modifiers
4337
Supported modifiers:
4338
%m
4339
a ascii (default)
4340
d decimal
4341
x hex, lowercase
4342
X hex, uppercase
4343
*/
4344
static void sun_formatField(J9CfrClassFile* classfile, J9CfrField* field, char *formatString, IDATA length)
4345
{
4346
J9CfrConstantPoolInfo info;
4347
U_16 cpIndex;
4348
U_8* string;
4349
U_32 j;
4350
U_32 index;
4351
U_32 arity;
4352
int i;
4353
char ch, ch2;
4354
char modifier;
4355
4356
PORT_ACCESS_FROM_PORT(portLib);
4357
i = 0;
4358
modifier = '\0';
4359
while(i < length)
4360
{
4361
ch = formatString[i++];
4362
if(modifier || ch == '%')
4363
{
4364
if(ch == '%')
4365
{
4366
modifier = '\0';
4367
ch = formatString[i++];
4368
}
4369
if(ch == '\0' || ch == '%')
4370
{
4371
if(modifier) j9tty_printf(PORTLIB, "%%%c", modifier);
4372
j9tty_output_char(ch);
4373
}
4374
else
4375
{
4376
switch(ch)
4377
{
4378
case 'c':
4379
/* short class name */
4380
cpIndex = classfile->constantPool[classfile->thisClass].slot1;
4381
string = classfile->constantPool[cpIndex].bytes;
4382
j = 0;
4383
index = 0;
4384
while('\0' != (ch2 = string[j++])) if(ch2 == '/') index = j;
4385
j = index;
4386
while('\0' != (ch2 = string[j++])) j9tty_output_char(ch2);
4387
break;
4388
4389
case 'C':
4390
/* qualified class name */
4391
cpIndex = classfile->constantPool[classfile->thisClass].slot1;
4392
string = classfile->constantPool[cpIndex].bytes;
4393
j = 0;
4394
while('\0' != (ch2 = string[j++]))
4395
{
4396
if(ch2 == '/') j9tty_output_char('.');
4397
else j9tty_output_char(ch2);
4398
}
4399
break;
4400
4401
case 'n':
4402
/* field name */
4403
string = classfile->constantPool[field->nameIndex].bytes;
4404
j9tty_printf(PORTLIB, "%s", string);
4405
break;
4406
4407
case 's':
4408
/* type signature */
4409
string = classfile->constantPool[field->descriptorIndex].bytes;
4410
j = 0;
4411
while('\0' != (ch2 = string[j++]))
4412
{
4413
if(ch2 == '/') j9tty_output_char('.');
4414
else j9tty_output_char(ch2);
4415
}
4416
break;
4417
4418
case 't':
4419
/* qualified type name */
4420
string = classfile->constantPool[field->descriptorIndex].bytes;
4421
j = 0;
4422
arity = 0;
4423
while(string[j] == '[')
4424
{
4425
j++;
4426
arity++;
4427
}
4428
switch(string[j++])
4429
{
4430
case 'L':
4431
while((ch2 = string[j++]) != ';')
4432
{
4433
if(ch2 == '/') j9tty_output_char('.');
4434
else j9tty_output_char(ch2);
4435
}
4436
break;
4437
4438
case 'B':
4439
j9tty_printf(PORTLIB, "byte");
4440
break;
4441
4442
case 'C':
4443
j9tty_printf(PORTLIB, "char");
4444
break;
4445
4446
case 'D':
4447
j9tty_printf(PORTLIB, "double");
4448
break;
4449
4450
case 'F':
4451
j9tty_printf(PORTLIB, "float");
4452
break;
4453
4454
case 'I':
4455
j9tty_printf(PORTLIB, "int");
4456
break;
4457
4458
case 'J':
4459
j9tty_printf(PORTLIB, "long");
4460
break;
4461
4462
case 'S':
4463
j9tty_printf(PORTLIB, "short");
4464
break;
4465
4466
case 'Z':
4467
j9tty_printf(PORTLIB, "boolean");
4468
break;
4469
4470
default:
4471
j9tty_printf(PORTLIB, "???");
4472
break;
4473
}
4474
for(j = 0; j < arity; j++) j9tty_printf(PORTLIB, "[]");
4475
break;
4476
4477
case 'i':
4478
if(field->constantValueAttribute)
4479
{
4480
info = classfile->constantPool[field->constantValueAttribute->constantValueIndex];
4481
switch(info.tag)
4482
{
4483
case CFR_CONSTANT_Integer:
4484
j9tty_printf(PORTLIB, "=(int)0x%08X", info.slot1);
4485
break;
4486
case CFR_CONSTANT_Float:
4487
j9tty_printf(PORTLIB, "=(float)0x%08X", info.slot1);
4488
break;
4489
case CFR_CONSTANT_Long:
4490
#ifdef J9VM_ENV_LITTLE_ENDIAN
4491
j9tty_printf(PORTLIB, "=(long)0x%08X%08X", info.slot2, info.slot1);
4492
#else
4493
j9tty_printf(PORTLIB, "=(long)0x%08X%08X", info.slot1, info.slot2);
4494
#endif
4495
break;
4496
case CFR_CONSTANT_Double:
4497
#ifdef J9VM_ENV_LITTLE_ENDIAN
4498
j9tty_printf(PORTLIB, "=(double)0x%08X%08X", info.slot2, info.slot1);
4499
#else
4500
j9tty_printf(PORTLIB, "=(double)0x%08X%08X", info.slot1, info.slot2);
4501
#endif
4502
break;
4503
case CFR_CONSTANT_String:
4504
j9tty_printf(PORTLIB, "=\"%s\"", classfile->constantPool[info.slot1].bytes);
4505
break;
4506
}
4507
}
4508
break;
4509
4510
case 'm':
4511
/* modifiers */
4512
switch(modifier)
4513
{
4514
case 'd':
4515
j9tty_printf(PORTLIB, "%i ( ", field->accessFlags);
4516
printModifiers(PORTLIB, field->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_FIELD);
4517
j9tty_printf( PORTLIB, " )");
4518
break;
4519
4520
case 'x':
4521
j9tty_printf(PORTLIB, "%08x ( ", field->accessFlags);
4522
printModifiers(PORTLIB, field->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_FIELD);
4523
j9tty_printf( PORTLIB, " )");
4524
break;
4525
4526
case 'X':
4527
j9tty_printf(PORTLIB, "%08X ( ", field->accessFlags);
4528
printModifiers(PORTLIB, field->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_FIELD);
4529
j9tty_printf( PORTLIB, " )");
4530
break;
4531
4532
case '\0':
4533
case 'a':
4534
default:
4535
printModifiers(PORTLIB, field->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_FIELD);
4536
break;
4537
}
4538
modifier = '\0';
4539
break;
4540
4541
case 'a':
4542
/* ascii */
4543
case 'd':
4544
/* decimal */
4545
case 'x':
4546
/* hex, lowercase */
4547
case 'X':
4548
/* hex, uppercase */
4549
4550
if(formatString[i] == 'm')
4551
{
4552
modifier = ch;
4553
break;
4554
}
4555
4556
default:
4557
j9tty_output_char('%');
4558
j9tty_output_char(ch);
4559
}
4560
}
4561
}
4562
else
4563
{
4564
j9tty_output_char(ch);
4565
}
4566
}
4567
return;
4568
}
4569
4570
4571
/* Print information about the method formatted as per @formatString.
4572
Format string:
4573
%<modifiers><specifier>
4574
Supported specifiers:
4575
c short class name
4576
C qualified class name
4577
n name
4578
r return type
4579
p parameter types
4580
s signature
4581
e thrown exception types
4582
m modifiers
4583
Supported modifiers:
4584
%m
4585
a ascii (default)
4586
d decimal
4587
x hex, lowercase
4588
X hex, uppercase
4589
*/
4590
static void sun_formatMethod(J9CfrClassFile* classfile, J9CfrMethod* method, char *formatString, IDATA length)
4591
{
4592
J9CfrAttributeExceptions* exceptions;
4593
U_8* string;
4594
U_16 cpIndex;
4595
U_32 j, k;
4596
U_32 index;
4597
U_32 arity;
4598
int i;
4599
char ch, ch2;
4600
char modifier;
4601
4602
PORT_ACCESS_FROM_PORT(portLib);
4603
i = 0;
4604
modifier = '\0';
4605
while(i < length)
4606
{
4607
ch = formatString[i++];
4608
if(modifier || ch == '%')
4609
{
4610
if(ch == '%')
4611
{
4612
modifier = '\0';
4613
ch = formatString[i++];
4614
}
4615
if(ch == '\0' || ch == '%')
4616
{
4617
if(modifier) j9tty_printf(PORTLIB, "%%%c", modifier);
4618
j9tty_output_char(ch);
4619
}
4620
else
4621
{
4622
switch(ch)
4623
{
4624
case 'c':
4625
/* short class name */
4626
cpIndex = classfile->constantPool[classfile->thisClass].slot1;
4627
string = classfile->constantPool[cpIndex].bytes;
4628
j = 0;
4629
index = 0;
4630
while('\0' != (ch2 = string[j++])) if(ch2 == '/') index = j;
4631
j = index;
4632
while('\0' != (ch2 = string[j++])) j9tty_output_char(ch2);
4633
break;
4634
4635
case 'C':
4636
/* qualified class name */
4637
cpIndex = classfile->constantPool[classfile->thisClass].slot1;
4638
string = classfile->constantPool[cpIndex].bytes;
4639
j = 0;
4640
while('\0' != (ch2 = string[j++]))
4641
{
4642
if(ch2 == '/') j9tty_output_char('.');
4643
else j9tty_output_char(ch2);
4644
}
4645
break;
4646
4647
case 'n':
4648
/* method name */
4649
string = classfile->constantPool[method->nameIndex].bytes;
4650
j9tty_printf(PORTLIB, "%s", string);
4651
break;
4652
4653
case 's':
4654
/* method signature */
4655
string = classfile->constantPool[method->descriptorIndex].bytes;
4656
j = 0;
4657
while('\0' != (ch2 = string[j++]))
4658
{
4659
if(ch2 == '/') j9tty_output_char('.');
4660
else j9tty_output_char(ch2);
4661
}
4662
break;
4663
4664
case 'r':
4665
/* qualified return type name */
4666
string = classfile->constantPool[method->descriptorIndex].bytes;
4667
j = 0;
4668
arity = 0;
4669
while(string[j++] != ')');
4670
while(string[j] == '[')
4671
{
4672
j++;
4673
arity++;
4674
}
4675
switch(string[j++])
4676
{
4677
case 'L':
4678
while((ch2 = string[j++]) != ';')
4679
{
4680
if(ch2 == '/') j9tty_output_char('.');
4681
else j9tty_output_char(ch2);
4682
}
4683
break;
4684
4685
case 'B':
4686
j9tty_printf(PORTLIB, "byte");
4687
break;
4688
4689
case 'C':
4690
j9tty_printf(PORTLIB, "char");
4691
break;
4692
4693
case 'D':
4694
j9tty_printf(PORTLIB, "double");
4695
break;
4696
4697
case 'F':
4698
j9tty_printf(PORTLIB, "float");
4699
break;
4700
4701
case 'I':
4702
j9tty_printf(PORTLIB, "int");
4703
break;
4704
4705
case 'J':
4706
j9tty_printf(PORTLIB, "long");
4707
break;
4708
4709
case 'S':
4710
j9tty_printf(PORTLIB, "short");
4711
break;
4712
4713
case 'V':
4714
j9tty_printf(PORTLIB, "void");
4715
break;
4716
4717
case 'Z':
4718
j9tty_printf(PORTLIB, "boolean");
4719
break;
4720
4721
default:
4722
j9tty_printf(PORTLIB, "???");
4723
break;
4724
}
4725
for(j = 0; j < arity; j++) j9tty_printf(PORTLIB, "[]");
4726
break;
4727
4728
case 'p':
4729
/* qualified parameter type names */
4730
string = classfile->constantPool[method->descriptorIndex].bytes;
4731
j = 1;
4732
while(string[j] != ')')
4733
{
4734
arity = 0;
4735
while(string[j] == '[')
4736
{
4737
j++;
4738
arity++;
4739
}
4740
switch(string[j++])
4741
{
4742
case 'L':
4743
while((ch2 = string[j++]) != ';')
4744
{
4745
if(ch2 == '/') j9tty_output_char('.');
4746
else j9tty_output_char(ch2);
4747
}
4748
break;
4749
4750
case 'B':
4751
j9tty_printf(PORTLIB, "byte");
4752
break;
4753
4754
case 'C':
4755
j9tty_printf(PORTLIB, "char");
4756
break;
4757
4758
case 'D':
4759
j9tty_printf(PORTLIB, "double");
4760
break;
4761
4762
case 'F':
4763
j9tty_printf(PORTLIB, "float");
4764
break;
4765
4766
case 'I':
4767
j9tty_printf(PORTLIB, "int");
4768
break;
4769
4770
case 'J':
4771
j9tty_printf(PORTLIB, "long");
4772
break;
4773
4774
case 'S':
4775
j9tty_printf(PORTLIB, "short");
4776
break;
4777
4778
case 'Z':
4779
j9tty_printf(PORTLIB, "boolean");
4780
break;
4781
4782
default:
4783
j9tty_printf(PORTLIB, "???");
4784
break;
4785
}
4786
for(k = 0; k < arity; k++) j9tty_printf(PORTLIB, "[]");
4787
if(string[j] != ')') j9tty_output_char(',');
4788
}
4789
break;
4790
4791
case 'e':
4792
/* qualified thrown exception type names */
4793
exceptions = method->exceptionsAttribute;
4794
if(exceptions == NULL) break;
4795
for(j = 0; j < exceptions->numberOfExceptions;)
4796
{
4797
index = classfile->constantPool[exceptions->exceptionIndexTable[j]].slot1;
4798
string = classfile->constantPool[index].bytes;
4799
k = 0;
4800
while('\0' != (ch2 = string[k++]))
4801
{
4802
if(ch2 == '/') j9tty_output_char('.');
4803
else j9tty_output_char(ch2);
4804
}
4805
if(++j != exceptions->numberOfExceptions) j9tty_output_char(',');
4806
}
4807
break;
4808
4809
case 'm':
4810
/* modifiers */
4811
switch(modifier)
4812
{
4813
case 'd':
4814
j9tty_printf(PORTLIB, "%i ( ", method->accessFlags);
4815
printModifiers(PORTLIB, method->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_METHOD);
4816
j9tty_printf( PORTLIB, " )");
4817
break;
4818
4819
case 'x':
4820
j9tty_printf(PORTLIB, "%08x ( ", method->accessFlags);
4821
printModifiers(PORTLIB, method->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_METHOD);
4822
j9tty_printf( PORTLIB, " )");
4823
break;
4824
4825
case 'X':
4826
j9tty_printf(PORTLIB, "%08X ( ", method->accessFlags);
4827
printModifiers(PORTLIB, method->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_METHOD);
4828
j9tty_printf( PORTLIB, " )");
4829
break;
4830
4831
case '\0':
4832
case 'a':
4833
default:
4834
printModifiers(PORTLIB, method->accessFlags, ONLY_SPEC_MODIFIERS, MODIFIERSOURCE_METHOD);
4835
break;
4836
}
4837
modifier = '\0';
4838
break;
4839
4840
case 'a':
4841
/* ascii */
4842
case 'd':
4843
/* decimal */
4844
case 'x':
4845
/* hex, lowercase */
4846
case 'X':
4847
/* hex, uppercase */
4848
4849
if(formatString[i] == 'm')
4850
{
4851
modifier = ch;
4852
break;
4853
}
4854
4855
default:
4856
j9tty_output_char('%');
4857
j9tty_output_char(ch);
4858
}
4859
}
4860
}
4861
else
4862
{
4863
j9tty_output_char(ch);
4864
}
4865
}
4866
return;
4867
}
4868
4869
4870
/* Print information about the class formatted as per @formatString.
4871
Format string:
4872
%<modifiers><specifier>
4873
Supported specifiers:
4874
p package
4875
c short class name
4876
C qualified class name
4877
s superclass name
4878
i interfaces names
4879
m sun modifiers
4880
M j9 modifiers
4881
Supported modifiers:
4882
%m
4883
a ascii (default)
4884
d decimal
4885
x hex, lowercase
4886
X hex, uppercase
4887
*/
4888
static void j9_formatClass(J9ROMClass* romClass, char *formatString, IDATA length, U_32 flags)
4889
{
4890
U_8* string;
4891
U_32 j, k;
4892
U_32 index;
4893
U_32 utfLength;
4894
int i;
4895
char ch, ch2;
4896
char modifier;
4897
4898
PORT_ACCESS_FROM_PORT(portLib);
4899
i = 0;
4900
modifier = '\0';
4901
while(i < length)
4902
{
4903
ch = formatString[i++];
4904
if(modifier || ch == '%')
4905
{
4906
if(ch == '%')
4907
{
4908
modifier = '\0';
4909
ch = formatString[i++];
4910
}
4911
if(ch == '\0' || ch == '%')
4912
{
4913
if(modifier) j9tty_printf(PORTLIB, "%%%c", modifier);
4914
j9tty_output_char(ch);
4915
}
4916
else
4917
{
4918
switch(ch)
4919
{
4920
case 'p':
4921
/* package */
4922
utfLength = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
4923
string = ((U_8*) J9ROMCLASS_CLASSNAME(romClass)) + 2;
4924
index = 0;
4925
for(j = 0; j < utfLength; j++)
4926
{
4927
if(string[j] == '/') index = j;
4928
}
4929
for(j = 0; j < index; j++)
4930
{
4931
ch2 = string[j];
4932
if(ch2 == '/') j9tty_output_char('.');
4933
else j9tty_output_char(ch2);
4934
}
4935
break;
4936
4937
case 'c':
4938
/* short class name */
4939
utfLength = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
4940
string = ((U_8*) J9ROMCLASS_CLASSNAME(romClass)) + 2;
4941
index = 0;
4942
for(j = 0; j < utfLength; j++)
4943
{
4944
if(string[j] == '/') index = j + 1;
4945
}
4946
for(j = index; j < utfLength; j++)
4947
{
4948
ch2 = string[j];
4949
if(ch2 == '/') j9tty_output_char('.');
4950
else j9tty_output_char(ch2);
4951
}
4952
break;
4953
4954
case 'C':
4955
/* qualified class name */
4956
utfLength = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
4957
string = ((U_8*) J9ROMCLASS_CLASSNAME(romClass)) + 2;
4958
for(j = 0; j < utfLength; j++)
4959
{
4960
ch2 = string[j];
4961
if(ch2 == '/') j9tty_output_char('.');
4962
else j9tty_output_char(ch2);
4963
}
4964
break;
4965
4966
case 's':
4967
/* superclass name */
4968
utfLength = J9UTF8_LENGTH(J9ROMCLASS_SUPERCLASSNAME(romClass));
4969
string = ((U_8*) J9ROMCLASS_SUPERCLASSNAME(romClass)) + 2;
4970
for(j = 0; j < utfLength; j++)
4971
{
4972
ch2 = string[j];
4973
if(ch2 == '/') j9tty_output_char('.');
4974
else j9tty_output_char(ch2);
4975
}
4976
break;
4977
4978
case 'i': {
4979
J9SRP * interfaces = J9ROMCLASS_INTERFACES(romClass);
4980
4981
/* interfaces names */
4982
for(j = 0; j < romClass->interfaceCount;)
4983
{
4984
J9UTF8 * interfaceName = NNSRP_PTR_GET(interfaces, J9UTF8 *);
4985
4986
utfLength = J9UTF8_LENGTH(interfaceName);
4987
string = ((U_8*)interfaceName) + 2;
4988
for(k = 0; k < utfLength; k++)
4989
{
4990
ch2 = string[k];
4991
if(ch2 == '/') j9tty_output_char('.');
4992
else j9tty_output_char(ch2);
4993
}
4994
if(++j != romClass->interfaceCount) j9tty_output_char(',');
4995
interfaces++;
4996
}
4997
break;
4998
}
4999
5000
case 'm':
5001
/* modifiers */
5002
switch(modifier)
5003
{
5004
case 'd':
5005
j9tty_printf(PORTLIB, "%i", romClass->modifiers);
5006
break;
5007
5008
case 'x':
5009
j9tty_printf(PORTLIB, "%08x", romClass->modifiers);
5010
break;
5011
5012
case 'X':
5013
j9tty_printf(PORTLIB, "%08X", romClass->modifiers);
5014
break;
5015
5016
case '\0':
5017
case 'a':
5018
default:
5019
printModifiers(PORTLIB, romClass->modifiers, INCLUDE_INTERNAL_MODIFIERS, MODIFIERSOURCE_CLASS);
5020
break;
5021
}
5022
modifier = '\0';
5023
break;
5024
5025
case 'M':
5026
/* modifiers */
5027
switch(modifier)
5028
{
5029
case 'd':
5030
j9tty_printf(PORTLIB, "%i", romClass->extraModifiers);
5031
break;
5032
5033
case 'x':
5034
j9tty_printf(PORTLIB, "%08x", romClass->extraModifiers);
5035
break;
5036
5037
case 'X':
5038
j9tty_printf(PORTLIB, "%08X", romClass->extraModifiers);
5039
break;
5040
5041
case '\0':
5042
case 'a':
5043
default:
5044
j9_printClassExtraModifiers(portLib, romClass->extraModifiers);
5045
break;
5046
}
5047
modifier = '\0';
5048
break;
5049
5050
case 'a':
5051
/* ascii */
5052
case 'd':
5053
/* decimal */
5054
case 'x':
5055
/* hex, lowercase */
5056
case 'X':
5057
/* hex, uppercase */
5058
5059
if(formatString[i] == 'm')
5060
{
5061
modifier = ch;
5062
break;
5063
}
5064
5065
default:
5066
j9tty_output_char('%');
5067
j9tty_output_char(ch);
5068
}
5069
}
5070
}
5071
else
5072
{
5073
j9tty_output_char(ch);
5074
}
5075
}
5076
return;
5077
}
5078
5079
5080
/* Print information about the field formatted as per @formatString.
5081
Format string:
5082
%<modifiers><specifier>
5083
Supported specifiers:
5084
c short class name
5085
C qualified class name
5086
n name
5087
t type
5088
s signature
5089
i inlined value
5090
m modifiers
5091
Supported modifiers:
5092
%m
5093
a ascii (default)
5094
d decimal
5095
x hex, lowercase
5096
X hex, uppercase
5097
*/
5098
static void j9_formatField(J9ROMClass* romClass, J9ROMFieldShape* field, char *formatString, IDATA length, U_32 flags)
5099
{
5100
J9ROMConstantPoolItem* info;
5101
U_8* string;
5102
U_16 utfLength;
5103
U_32 fieldType;
5104
U_32 j;
5105
U_32 index;
5106
U_32 arity;
5107
int i;
5108
char ch, ch2;
5109
char modifier;
5110
U_32 * initialValue = NULL;
5111
5112
PORT_ACCESS_FROM_PORT(portLib);
5113
i = 0;
5114
modifier = '\0';
5115
while(i < length)
5116
{
5117
ch = formatString[i++];
5118
if(modifier || ch == '%')
5119
{
5120
if(ch == '%')
5121
{
5122
modifier = '\0';
5123
ch = formatString[i++];
5124
}
5125
if(ch == '\0' || ch == '%')
5126
{
5127
if(modifier) j9tty_printf(PORTLIB, "%%%c", modifier);
5128
j9tty_output_char(ch);
5129
}
5130
else
5131
{
5132
switch(ch)
5133
{
5134
case 'c':
5135
/* short class name */
5136
utfLength = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
5137
string = ((U_8*) J9ROMCLASS_CLASSNAME(romClass)) + 2;
5138
index = 0;
5139
for(j = 0; j < utfLength; j++)
5140
{
5141
if(string[j] == '/') index = j + 1;
5142
}
5143
for(j = index; j < utfLength; j++)
5144
{
5145
ch2 = string[j];
5146
if(ch2 == '/') j9tty_output_char('.');
5147
else j9tty_output_char(ch2);
5148
}
5149
break;
5150
5151
case 'C':
5152
/* qualified class name */
5153
utfLength = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
5154
string = ((U_8*) J9ROMCLASS_CLASSNAME(romClass)) + 2;
5155
for(j = 0; j < utfLength; j++)
5156
{
5157
ch2 = string[j];
5158
if(ch2 == '/') j9tty_output_char('.');
5159
else j9tty_output_char(ch2);
5160
}
5161
break;
5162
5163
case 'n':
5164
/* field name */
5165
utfLength = J9UTF8_LENGTH(J9ROMFIELDSHAPE_NAME(field));
5166
string = ((U_8*) J9ROMFIELDSHAPE_NAME(field)) + 2;
5167
for(j = 0; j < utfLength; j++) j9tty_output_char(string[j]);
5168
break;
5169
5170
case 's':
5171
/* type signature */
5172
utfLength = J9UTF8_LENGTH(J9ROMFIELDSHAPE_SIGNATURE(field));
5173
string = ((U_8*) J9ROMFIELDSHAPE_SIGNATURE(field)) + 2;
5174
for(j = 0; j < utfLength; j++)
5175
{
5176
ch2 = string[j];
5177
if(ch2 == '/') j9tty_output_char('.');
5178
else j9tty_output_char(ch2);
5179
}
5180
break;
5181
5182
case 't':
5183
/* qualified type name */
5184
utfLength = J9UTF8_LENGTH(J9ROMFIELDSHAPE_SIGNATURE(field));
5185
string = ((U_8*) J9ROMFIELDSHAPE_SIGNATURE(field)) + 2;
5186
j = 0;
5187
arity = 0;
5188
while(string[j] == '[')
5189
{
5190
j++;
5191
arity++;
5192
}
5193
switch(string[j++])
5194
{
5195
case 'L':
5196
while((ch2 = string[j++]) != ';')
5197
{
5198
if(ch2 == '/') j9tty_output_char('.');
5199
else j9tty_output_char(ch2);
5200
}
5201
break;
5202
5203
case 'B':
5204
j9tty_printf(PORTLIB, "byte");
5205
break;
5206
5207
case 'C':
5208
j9tty_printf(PORTLIB, "char");
5209
break;
5210
5211
case 'D':
5212
j9tty_printf(PORTLIB, "double");
5213
break;
5214
5215
case 'F':
5216
j9tty_printf(PORTLIB, "float");
5217
break;
5218
5219
case 'I':
5220
j9tty_printf(PORTLIB, "int");
5221
break;
5222
5223
case 'J':
5224
j9tty_printf(PORTLIB, "long");
5225
break;
5226
5227
case 'S':
5228
j9tty_printf(PORTLIB, "short");
5229
break;
5230
5231
case 'Z':
5232
j9tty_printf(PORTLIB, "boolean");
5233
break;
5234
5235
default:
5236
j9tty_printf(PORTLIB, "???");
5237
break;
5238
}
5239
for(j = 0; j < arity; j++) j9tty_printf(PORTLIB, "[]");
5240
break;
5241
5242
case 'i':
5243
if(initialValue != NULL)
5244
{
5245
fieldType = field->modifiers & 0x3A0000; /* FieldTypeMask */
5246
switch(fieldType)
5247
{
5248
case 0: /* char */
5249
j9tty_printf(PORTLIB, "=(char) 0x%08X", *initialValue);
5250
break;
5251
5252
case 0x020000: /* Object, therefore java.lang.String */
5253
info = &((J9ROMConstantPoolItem *) (romClass + 1))[*initialValue];
5254
utfLength = J9UTF8_LENGTH(J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef*) info));
5255
string = ((U_8*) J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef*) info)) + 2;
5256
j9tty_printf(PORTLIB, "=(java.lang.String) \"%.*s\"", utfLength, string);
5257
break;
5258
5259
case 0x080000: /* boolean */
5260
j9tty_printf(PORTLIB, "=(boolean) 0x%08X", *initialValue);
5261
break;
5262
5263
case 0x100000: /* float */
5264
j9tty_printf(PORTLIB, "=(float) 0x%08X", *initialValue);
5265
break;
5266
5267
case 0x180000: /* double */
5268
#ifdef J9VM_ENV_LITTLE_ENDIAN
5269
j9tty_printf(PORTLIB, "=(double) 0x%08X%08X", initialValue[1], initialValue[0]);
5270
#else
5271
j9tty_printf(PORTLIB, "=(double) 0x%08X%08X", initialValue[0], initialValue[1]);
5272
#endif
5273
break;
5274
5275
case 0x200000: /* byte */
5276
j9tty_printf(PORTLIB, "=(byte) 0x%08X", *initialValue);
5277
break;
5278
5279
case 0x280000: /* short */
5280
j9tty_printf(PORTLIB, "=(short) 0x%08X", *initialValue);
5281
break;
5282
5283
case 0x300000: /* int */
5284
j9tty_printf(PORTLIB, "=(int) 0x%08X", *initialValue);
5285
break;
5286
5287
case 0x380000: /* long */
5288
#ifdef J9VM_ENV_LITTLE_ENDIAN
5289
j9tty_printf(PORTLIB, "=(long) 0x%08X%08X", initialValue[1], initialValue[0]);
5290
#else
5291
j9tty_printf(PORTLIB, "=(long) 0x%08X%08X", initialValue[0], initialValue[1]);
5292
#endif
5293
break;
5294
}
5295
}
5296
break;
5297
5298
case 'm':
5299
/* modifiers */
5300
switch(modifier)
5301
{
5302
case 'd':
5303
j9tty_printf(PORTLIB, "%i", field->modifiers);
5304
break;
5305
5306
case 'x':
5307
j9tty_printf(PORTLIB, "%08x", field->modifiers);
5308
break;
5309
5310
case 'X':
5311
j9tty_printf(PORTLIB, "%08X", field->modifiers);
5312
break;
5313
5314
case '\0':
5315
case 'a':
5316
default:
5317
printModifiers(PORTLIB, field->modifiers, INCLUDE_INTERNAL_MODIFIERS, MODIFIERSOURCE_FIELD);
5318
break;
5319
}
5320
modifier = '\0';
5321
break;
5322
5323
case 'a':
5324
/* ascii */
5325
case 'd':
5326
/* decimal */
5327
case 'x':
5328
/* hex, lowercase */
5329
case 'X':
5330
/* hex, uppercase */
5331
5332
if(formatString[i] == 'm')
5333
{
5334
modifier = ch;
5335
break;
5336
}
5337
5338
default:
5339
j9tty_output_char('%');
5340
j9tty_output_char(ch);
5341
}
5342
}
5343
}
5344
else
5345
{
5346
j9tty_output_char(ch);
5347
}
5348
}
5349
return;
5350
}
5351
5352
5353
/* Print information about the method formatted as per @formatString.
5354
Format string:
5355
%<modifiers><specifier>
5356
Supported specifiers:
5357
c short class name
5358
C qualified class name
5359
n name
5360
r return type
5361
p parameter types
5362
s signature
5363
m modifiers
5364
Supported modifiers:
5365
%m
5366
a ascii (default)
5367
d decimal
5368
x hex, lowercase
5369
X hex, uppercase
5370
*/
5371
static void j9_formatMethod(J9ROMClass* romClass, J9ROMMethod* method, char *formatString, IDATA length, U_32 flags)
5372
{
5373
J9SRP * currentThrowName;
5374
U_8* string;
5375
U_16 utfLength;
5376
U_32 j, k;
5377
U_32 index;
5378
U_32 arity;
5379
int i;
5380
char ch, ch2;
5381
char modifier;
5382
5383
PORT_ACCESS_FROM_PORT(portLib);
5384
i = 0;
5385
modifier = '\0';
5386
while(i < length)
5387
{
5388
ch = formatString[i++];
5389
if(modifier || ch == '%')
5390
{
5391
if(ch == '%')
5392
{
5393
modifier = '\0';
5394
ch = formatString[i++];
5395
}
5396
if(ch == '\0' || ch == '%')
5397
{
5398
if(modifier) j9tty_printf(PORTLIB, "%%%c", modifier);
5399
j9tty_output_char(ch);
5400
}
5401
else
5402
{
5403
switch(ch)
5404
{
5405
case 'c':
5406
/* short class name */
5407
utfLength = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
5408
string = ((U_8*) J9ROMCLASS_CLASSNAME(romClass)) + 2;
5409
index = 0;
5410
for(j = 0; j < utfLength; j++)
5411
{
5412
if(string[j] == '/') index = j + 1;
5413
}
5414
for(j = index; j < utfLength; j++)
5415
{
5416
ch2 = string[j];
5417
if(ch2 == '/') j9tty_output_char('.');
5418
else j9tty_output_char(ch2);
5419
}
5420
break;
5421
5422
case 'C':
5423
/* qualified class name */
5424
utfLength = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
5425
string = ((U_8*) J9ROMCLASS_CLASSNAME(romClass)) + 2;
5426
for(j = 0; j < utfLength; j++)
5427
{
5428
ch2 = string[j];
5429
if(ch2 == '/') j9tty_output_char('.');
5430
else j9tty_output_char(ch2);
5431
}
5432
break;
5433
5434
case 'n':
5435
/* method name */
5436
utfLength = J9UTF8_LENGTH(J9ROMMETHOD_NAME(method));
5437
string = ((U_8*) J9ROMMETHOD_NAME(method)) + 2;
5438
for(j = 0; j < utfLength; j++) j9tty_output_char(string[j]);
5439
break;
5440
5441
case 's':
5442
/* type signature */
5443
utfLength = J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(method));
5444
string = ((U_8*) J9ROMMETHOD_SIGNATURE(method)) + 2;
5445
for(j = 0; j < utfLength; j++)
5446
{
5447
ch2 = string[j];
5448
if(ch2 == '/') j9tty_output_char('.');
5449
else j9tty_output_char(ch2);
5450
}
5451
break;
5452
5453
case 'r':
5454
/* qualified return type name */
5455
utfLength = J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(method));
5456
string = ((U_8*) J9ROMMETHOD_SIGNATURE(method)) + 2;
5457
j = 0;
5458
arity = 0;
5459
while(string[j++] != ')');
5460
while(string[j] == '[')
5461
{
5462
j++;
5463
arity++;
5464
}
5465
switch(string[j++])
5466
{
5467
case 'L':
5468
while((ch2 = string[j++]) != ';')
5469
{
5470
if(ch2 == '/') j9tty_output_char('.');
5471
else j9tty_output_char(ch2);
5472
}
5473
break;
5474
5475
case 'B':
5476
j9tty_printf(PORTLIB, "byte");
5477
break;
5478
5479
case 'C':
5480
j9tty_printf(PORTLIB, "char");
5481
break;
5482
5483
case 'D':
5484
j9tty_printf(PORTLIB, "double");
5485
break;
5486
5487
case 'F':
5488
j9tty_printf(PORTLIB, "float");
5489
break;
5490
5491
case 'I':
5492
j9tty_printf(PORTLIB, "int");
5493
break;
5494
5495
case 'J':
5496
j9tty_printf(PORTLIB, "long");
5497
break;
5498
5499
case 'S':
5500
j9tty_printf(PORTLIB, "short");
5501
break;
5502
5503
case 'V':
5504
j9tty_printf(PORTLIB, "void");
5505
break;
5506
5507
case 'Z':
5508
j9tty_printf(PORTLIB, "boolean");
5509
break;
5510
5511
default:
5512
j9tty_printf(PORTLIB, "???");
5513
break;
5514
}
5515
for(j = 0; j < arity; j++) j9tty_printf(PORTLIB, "[]");
5516
break;
5517
5518
case 'p':
5519
/* qualified parameter type names */
5520
utfLength = J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(method));
5521
string = ((U_8*) J9ROMMETHOD_SIGNATURE(method)) + 2;
5522
j = 1;
5523
while(string[j] != ')')
5524
{
5525
arity = 0;
5526
while(string[j] == '[')
5527
{
5528
j++;
5529
arity++;
5530
}
5531
switch(string[j++])
5532
{
5533
case 'L':
5534
while((ch2 = string[j++]) != ';')
5535
{
5536
if(ch2 == '/') j9tty_output_char('.');
5537
else j9tty_output_char(ch2);
5538
}
5539
break;
5540
5541
case 'B':
5542
j9tty_printf(PORTLIB, "byte");
5543
break;
5544
5545
case 'C':
5546
j9tty_printf(PORTLIB, "char");
5547
break;
5548
5549
case 'D':
5550
j9tty_printf(PORTLIB, "double");
5551
break;
5552
5553
case 'F':
5554
j9tty_printf(PORTLIB, "float");
5555
break;
5556
5557
case 'I':
5558
j9tty_printf(PORTLIB, "int");
5559
break;
5560
5561
case 'J':
5562
j9tty_printf(PORTLIB, "long");
5563
break;
5564
5565
case 'S':
5566
j9tty_printf(PORTLIB, "short");
5567
break;
5568
5569
case 'Z':
5570
j9tty_printf(PORTLIB, "boolean");
5571
break;
5572
5573
default:
5574
j9tty_printf(PORTLIB, "???");
5575
break;
5576
}
5577
for(k = 0; k < arity; k++) j9tty_printf(PORTLIB, "[]");
5578
if(string[j] != ')') j9tty_output_char(',');
5579
}
5580
break;
5581
5582
case 'e': {
5583
J9ExceptionInfo * exceptionData = J9_EXCEPTION_DATA_FROM_ROM_METHOD(method);
5584
/* qualified thrown exception type names */
5585
if(J9ROMMETHOD_HAS_EXCEPTION_INFO(method) && (exceptionData->throwCount))
5586
{
5587
currentThrowName = J9EXCEPTIONINFO_THROWNAMES(exceptionData);
5588
for (k=0; k < exceptionData->throwCount; )
5589
{
5590
J9UTF8 * currentName = NNSRP_PTR_GET(currentThrowName, J9UTF8 *);
5591
currentThrowName++;
5592
5593
utfLength = J9UTF8_LENGTH(currentName);
5594
string = ((U_8*)currentName) + 2;
5595
for(j = 0; j < utfLength; j++)
5596
{
5597
ch2 = string[j];
5598
if(ch2 == '/') j9tty_output_char('.');
5599
else j9tty_output_char(ch2);
5600
}
5601
if(++k != exceptionData->throwCount) j9tty_output_char(',');
5602
}
5603
}
5604
break;
5605
}
5606
5607
case 'm':
5608
/* modifiers */
5609
switch(modifier)
5610
{
5611
case 'd':
5612
j9tty_printf(PORTLIB, "%i", method->modifiers);
5613
break;
5614
5615
case 'x':
5616
j9tty_printf(PORTLIB, "%08x", method->modifiers);
5617
break;
5618
5619
case 'X':
5620
j9tty_printf(PORTLIB, "%08X", method->modifiers);
5621
break;
5622
5623
case '\0':
5624
case 'a':
5625
default:
5626
printModifiers(PORTLIB, method->modifiers, INCLUDE_INTERNAL_MODIFIERS, MODIFIERSOURCE_METHOD);
5627
break;
5628
}
5629
modifier = '\0';
5630
break;
5631
5632
case 'a':
5633
/* ascii */
5634
case 'd':
5635
/* decimal */
5636
case 'x':
5637
/* hex, lowercase */
5638
case 'X':
5639
/* hex, uppercase */
5640
5641
if(formatString[i] == 'm')
5642
{
5643
modifier = ch;
5644
break;
5645
}
5646
5647
default:
5648
j9tty_output_char('%');
5649
j9tty_output_char(ch);
5650
}
5651
}
5652
}
5653
else
5654
{
5655
j9tty_output_char(ch);
5656
}
5657
}
5658
return;
5659
}
5660
5661
5662
/* Print information about the bytecode formatted as per @formatString.
5663
Format string:
5664
%<modifiers><specifier>
5665
Supported specifiers:
5666
c short class name
5667
C qualified class name
5668
n method name
5669
s method signature
5670
i instruction pointer
5671
b bytecode
5672
B complete bytecode
5673
p parameters
5674
Supported modifiers:
5675
%i
5676
d decimal (default)
5677
x hex, lowercase
5678
X hex, uppercase
5679
%B
5680
d decimal
5681
x hex, lowercase
5682
X hex, uppercase (default)
5683
%b
5684
a ascii (default)
5685
d decimal
5686
x hex, lowercase
5687
X hex, uppercase
5688
%p
5689
a ascii (default)
5690
d decimal
5691
x hex, lowercase
5692
X hex, uppercase
5693
*/
5694
static void j9_formatBytecode(J9ROMClass* romClass, J9ROMMethod* method, U_8* bcStart, U_8* bytes, U_8 bc, U_32 bytesLength, U_32 decode, char *formatString, IDATA length, U_32 flags)
5695
{
5696
J9ROMConstantPoolItem* constantPool;
5697
J9ROMConstantPoolItem *info, *info2;
5698
J9ROMNameAndSignature *nameAndSig;
5699
U_8* string;
5700
U_16 utfLength;
5701
U_8* bcIndex;
5702
UDATA pc, branch;
5703
U_8 u8, u8_2;
5704
U_16 u16, u16_2;
5705
U_32 u32;
5706
U_32 index = 0;
5707
U_32 npairs;
5708
U_32 j;
5709
I_32 low, high, key;
5710
I_32 i, k;
5711
BOOLEAN bigEndian;
5712
char modifier;
5713
char pcModifier;
5714
char ch, ch2;
5715
5716
PORT_ACCESS_FROM_PORT( portLib );
5717
5718
pcModifier = 'd';
5719
pc = bytes - bcStart;
5720
bigEndian = flags & BCT_BigEndianOutput;
5721
constantPool = (J9ROMConstantPoolItem*)((U_8*)romClass + sizeof(J9ROMClass));
5722
5723
i = 0;
5724
modifier = '\0';
5725
while(i < length)
5726
{
5727
ch = formatString[i++];
5728
if(modifier || ch == '%')
5729
{
5730
if(ch == '%')
5731
{
5732
modifier = '\0';
5733
ch = formatString[i++];
5734
}
5735
if(ch == '\0' || ch == '%')
5736
{
5737
if(modifier) j9tty_printf(PORTLIB, "%%%c", modifier);
5738
j9tty_output_char(ch);
5739
}
5740
else
5741
{
5742
switch(ch)
5743
{
5744
case 'c':
5745
/* short class name */
5746
utfLength = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
5747
string = ((U_8*) J9ROMCLASS_CLASSNAME(romClass)) + 2;
5748
index = 0;
5749
for(j = 0; j < utfLength; j++)
5750
{
5751
if(string[j] == '/') index = j + 1;
5752
}
5753
for(j = index; j < utfLength; j++)
5754
{
5755
ch2 = string[j];
5756
if(ch2 == '/') j9tty_output_char('.');
5757
else j9tty_output_char(ch2);
5758
}
5759
break;
5760
5761
case 'C':
5762
/* qualified class name */
5763
utfLength = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass));
5764
string = ((U_8*) J9ROMCLASS_CLASSNAME(romClass)) + 2;
5765
for(j = 0; j < utfLength; j++)
5766
{
5767
ch2 = string[j];
5768
if(ch2 == '/') j9tty_output_char('.');
5769
else j9tty_output_char(ch2);
5770
}
5771
break;
5772
5773
case 'n':
5774
/* method name */
5775
utfLength = J9UTF8_LENGTH(J9ROMMETHOD_NAME(method));
5776
string = ((U_8*) J9ROMMETHOD_NAME(method)) + 2;
5777
for(j = 0; j < utfLength; j++) j9tty_output_char(string[j]);
5778
break;
5779
5780
case 's':
5781
/* type signature */
5782
utfLength = J9UTF8_LENGTH(J9ROMMETHOD_SIGNATURE(method));
5783
string = ((U_8*) J9ROMMETHOD_SIGNATURE(method)) + 2;
5784
for(j = 0; j < utfLength; j++)
5785
{
5786
ch2 = string[j];
5787
if(ch2 == '/') j9tty_output_char('.');
5788
else j9tty_output_char(ch2);
5789
}
5790
break;
5791
5792
case 'i':
5793
/* instruction pointer */
5794
pcModifier = modifier;
5795
switch(modifier)
5796
{
5797
case 'x':
5798
j9tty_printf(PORTLIB, "%08x", pc);
5799
break;
5800
5801
case 'X':
5802
j9tty_printf(PORTLIB, "%08X", pc);
5803
break;
5804
5805
case 'd':
5806
default:
5807
j9tty_printf(PORTLIB, "%i", pc);
5808
break;
5809
}
5810
modifier = '\0';
5811
break;
5812
5813
case 'b':
5814
/* bytecode */
5815
switch(modifier)
5816
{
5817
case 'x':
5818
j9tty_printf(PORTLIB, "%02x", bc);
5819
break;
5820
5821
case 'X':
5822
j9tty_printf(PORTLIB, "%02X", bc);
5823
break;
5824
5825
case 'd':
5826
j9tty_printf(PORTLIB, "%i", bc);
5827
break;
5828
5829
default:
5830
j9tty_printf(PORTLIB, "%s", JavaBCNames[bc]);
5831
break;
5832
}
5833
modifier = '\0';
5834
break;
5835
5836
case 'B':
5837
/* bytecode bytes */
5838
switch(modifier)
5839
{
5840
case 'd':
5841
for(j = 0; j < bytesLength; )
5842
{
5843
j9tty_printf(PORTLIB, "%i", bytes[j]);
5844
if(++j < bytesLength) j9tty_output_char(' ');
5845
}
5846
break;
5847
5848
case 'x':
5849
for(j = 0; j < bytesLength; j++) j9tty_printf(PORTLIB, "%02x", bytes[j]);
5850
break;
5851
5852
default:
5853
case 'X':
5854
for(j = 0; j < bytesLength; j++) j9tty_printf(PORTLIB, "%02X", bytes[j]);
5855
break;
5856
}
5857
modifier = '\0';
5858
break;
5859
5860
case 'p':
5861
/* parameters */
5862
bcIndex = bytes + 1;
5863
if(bc != *bytes) bcIndex++;
5864
switch(decode)
5865
{
5866
case CFR_DECODE_SIMPLE:
5867
break;
5868
5869
case CFR_DECODE_I8:
5870
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
5871
switch(modifier)
5872
{
5873
case 'x':
5874
j9tty_printf(PORTLIB, "%02x", (I_8)u8);
5875
break;
5876
5877
case 'X':
5878
j9tty_printf(PORTLIB, "%02X", (I_8)u8);
5879
break;
5880
5881
case 'd':
5882
case 'a':
5883
default:
5884
j9tty_printf(PORTLIB, "%i", (I_8)u8);
5885
break;
5886
}
5887
break;
5888
5889
case CFR_DECODE_U8:
5890
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
5891
switch(modifier)
5892
{
5893
case 'x':
5894
j9tty_printf(PORTLIB, "%02x", u8);
5895
break;
5896
5897
case 'X':
5898
j9tty_printf(PORTLIB, "%02X", u8);
5899
break;
5900
5901
case 'd':
5902
case 'a':
5903
default:
5904
j9tty_printf(PORTLIB, "%i", u8);
5905
break;
5906
}
5907
break;
5908
5909
case CFR_DECODE_I16:
5910
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
5911
switch(modifier)
5912
{
5913
case 'x':
5914
j9tty_printf(PORTLIB, "%04x", (I_16)u16);
5915
break;
5916
5917
case 'X':
5918
j9tty_printf(PORTLIB, "%04X", (I_16)u16);
5919
break;
5920
5921
case 'd':
5922
case 'a':
5923
default:
5924
j9tty_printf(PORTLIB, "%i", (I_16)u16);
5925
break;
5926
}
5927
break;
5928
5929
case CFR_DECODE_U16:
5930
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
5931
switch(modifier)
5932
{
5933
case 'x':
5934
j9tty_printf(PORTLIB, "%04x", (I_16)u16);
5935
break;
5936
5937
case 'X':
5938
j9tty_printf(PORTLIB, "%04X", (I_16)u16);
5939
break;
5940
5941
case 'd':
5942
case 'a':
5943
default:
5944
j9tty_printf(PORTLIB, "%i", (I_16)u16);
5945
break;
5946
}
5947
break;
5948
5949
case CFR_DECODE_U8_I8:
5950
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
5951
NEXT_U8_ENDIAN(bigEndian, u8_2, bcIndex);
5952
switch(modifier)
5953
{
5954
case 'x':
5955
j9tty_printf(PORTLIB, "%02x %02x", u8, (I_8)u8_2);
5956
break;
5957
5958
case 'X':
5959
j9tty_printf(PORTLIB, "%02X %02X", u8, (I_8)u8_2);
5960
break;
5961
5962
case 'd':
5963
case 'a':
5964
default:
5965
j9tty_printf(PORTLIB, "%i %i", u8, (I_8)u8_2);
5966
break;
5967
}
5968
break;
5969
5970
case CFR_DECODE_U16_I16:
5971
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
5972
NEXT_U16_ENDIAN(bigEndian, u16_2, bcIndex);
5973
switch(modifier)
5974
{
5975
case 'x':
5976
j9tty_printf(PORTLIB, "%04x %04x", u16, (I_16)u16_2);
5977
break;
5978
5979
case 'X':
5980
j9tty_printf(PORTLIB, "%04X %04X", u16, (I_16)u16_2);
5981
break;
5982
5983
case 'd':
5984
case 'a':
5985
default:
5986
j9tty_printf(PORTLIB, "%i %i", u16, (I_16)u16_2);
5987
break;
5988
}
5989
break;
5990
5991
case CFR_DECODE_J9_CLASSREF:
5992
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
5993
switch(modifier)
5994
{
5995
case 'x':
5996
j9tty_printf(PORTLIB, "%04x", u16);
5997
break;
5998
5999
case 'X':
6000
j9tty_printf(PORTLIB, "%04X", u16);
6001
break;
6002
6003
case 'd':
6004
j9tty_printf(PORTLIB, "%i", u16);
6005
break;
6006
6007
case 'a':
6008
default:
6009
info = &constantPool[u16];
6010
classrefAscii:
6011
utfLength = J9UTF8_LENGTH(J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info));
6012
string = ((U_8*) (J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info))) + 2;
6013
for(j = 0; j < utfLength; j++)
6014
{
6015
ch2 = string[j];
6016
if(ch2 == '/') j9tty_output_char('.');
6017
else j9tty_output_char(ch2);
6018
}
6019
break;
6020
}
6021
break;
6022
6023
case CFR_DECODE_J9_FIELDREF:
6024
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
6025
switch(modifier)
6026
{
6027
case 'x':
6028
j9tty_printf(PORTLIB, "%04x", u16);
6029
break;
6030
6031
case 'X':
6032
j9tty_printf(PORTLIB, "%04X", u16);
6033
break;
6034
6035
case 'd':
6036
j9tty_printf(PORTLIB, "%i", u16);
6037
break;
6038
6039
case 'a':
6040
default:
6041
info = &constantPool[u16];
6042
utfLength = J9UTF8_LENGTH(J9ROMCLASSREF_NAME((J9ROMClassRef *) &constantPool[((J9ROMFieldRef *) info)->classRefCPIndex]));
6043
string = ((U_8*) J9ROMCLASSREF_NAME((J9ROMClassRef *) &constantPool[((J9ROMFieldRef *) info)->classRefCPIndex])) + 2;
6044
for(j = 0; j < utfLength; j++)
6045
{
6046
ch2 = string[j];
6047
if(ch2 == '/') j9tty_output_char('.');
6048
else j9tty_output_char(ch2);
6049
}
6050
j9tty_output_char('.');
6051
nameAndSig = J9ROMFIELDREF_NAMEANDSIGNATURE((J9ROMFieldRef *) info);
6052
utfLength = J9UTF8_LENGTH(J9ROMNAMEANDSIGNATURE_NAME(nameAndSig));
6053
string = ((U_8*) J9ROMNAMEANDSIGNATURE_NAME(nameAndSig)) + 2;
6054
for(j = 0; j < utfLength; j++) j9tty_output_char(string[j]);
6055
j9tty_output_char(' ');
6056
utfLength = J9UTF8_LENGTH(J9ROMNAMEANDSIGNATURE_SIGNATURE(nameAndSig));
6057
string = ((U_8*) J9ROMNAMEANDSIGNATURE_SIGNATURE(nameAndSig)) + 2;
6058
for(j = 0; j < utfLength; j++) j9tty_output_char(string[j]);
6059
break;
6060
}
6061
break;
6062
6063
case CFR_DECODE_J9_METHODTYPEREF:
6064
/* fall through: A J9RAMMethodTypeRef has a J9ROMMethodRef
6065
* as its ROM Constant pool equivalent
6066
*/
6067
case CFR_DECODE_J9_METHODREF:
6068
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
6069
switch(modifier)
6070
{
6071
case 'x':
6072
j9tty_printf(PORTLIB, "%04x", u16);
6073
break;
6074
6075
case 'X':
6076
j9tty_printf(PORTLIB, "%04X", u16);
6077
break;
6078
6079
case 'd':
6080
j9tty_printf(PORTLIB, "%i", u16);
6081
break;
6082
6083
case 'a':
6084
default:
6085
info = &constantPool[u16];
6086
if (JBinvokestaticsplit == bc) {
6087
U_16 cpIndex = *(J9ROMCLASS_STATICSPLITMETHODREFINDEXES(romClass) + u16);
6088
info = &constantPool[cpIndex];
6089
} else if (JBinvokespecialsplit == bc) {
6090
U_16 cpIndex = *(J9ROMCLASS_SPECIALSPLITMETHODREFINDEXES(romClass) + u16);
6091
info = &constantPool[cpIndex];
6092
}
6093
info2 = &constantPool[((J9ROMMethodRef *) info)->classRefCPIndex];
6094
utfLength = J9UTF8_LENGTH(J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info2));
6095
string = ((U_8*) J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info2)) + 2;
6096
for(j = 0; j < utfLength; j++)
6097
{
6098
ch2 = string[j];
6099
if(ch2 == '/') j9tty_output_char('.');
6100
else j9tty_output_char(ch2);
6101
}
6102
j9tty_output_char('.');
6103
nameAndSig = J9ROMMETHODREF_NAMEANDSIGNATURE((J9ROMMethodRef *) info);
6104
utfLength = J9UTF8_LENGTH(J9ROMNAMEANDSIGNATURE_NAME(nameAndSig));
6105
string = ((U_8*) J9ROMNAMEANDSIGNATURE_NAME(nameAndSig)) + 2;
6106
for(j = 0; j < utfLength; j++) j9tty_output_char(string[j]);
6107
utfLength = J9UTF8_LENGTH(J9ROMNAMEANDSIGNATURE_SIGNATURE(nameAndSig));
6108
string = ((U_8*) J9ROMNAMEANDSIGNATURE_SIGNATURE(nameAndSig)) + 2;
6109
for(j = 0; j < utfLength; j++) j9tty_output_char(string[j]);
6110
break;
6111
}
6112
break;
6113
6114
case CFR_DECODE_J9_LDC:
6115
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
6116
switch(modifier)
6117
{
6118
case 'x':
6119
j9tty_printf(PORTLIB, "%02x", u8);
6120
break;
6121
6122
case 'X':
6123
j9tty_printf(PORTLIB, "%02X", u8);
6124
break;
6125
6126
case 'd':
6127
j9tty_printf(PORTLIB, "%i", u8);
6128
break;
6129
6130
case 'a':
6131
default:
6132
info = &constantPool[u8];
6133
ldcAscii:
6134
switch (J9_CP_TYPE(J9ROMCLASS_CPSHAPEDESCRIPTION(romClass), index)) {
6135
case J9CPTYPE_CLASS:
6136
utfLength = J9UTF8_LENGTH(J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info));
6137
string = ((U_8*) (J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info))) + 2;
6138
for(j = 0; j < utfLength; j++)
6139
{
6140
ch2 = string[j];
6141
if(ch2 == '/') j9tty_output_char('.');
6142
else j9tty_output_char(ch2);
6143
}
6144
break;
6145
6146
case J9CPTYPE_STRING:
6147
case J9CPTYPE_ANNOTATION_UTF8:
6148
utfLength = J9UTF8_LENGTH(J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info));
6149
string = ((U_8*) J9ROMSTRINGREF_UTF8DATA((J9ROMStringRef *) info)) + 2;
6150
j9tty_printf(PORTLIB, "(java.lang.String) \"%.*s\"", utfLength, string);
6151
break;
6152
6153
case J9CPTYPE_INT:
6154
j9tty_printf(PORTLIB, "(int) 0x%08X", ((J9ROMSingleSlotConstantRef *) info)->data);
6155
break;
6156
6157
case J9CPTYPE_FLOAT:
6158
j9tty_printf(PORTLIB, "(float) 0x%08X", ((J9ROMSingleSlotConstantRef *) info)->data);
6159
break;
6160
6161
default:
6162
j9tty_printf(PORTLIB, "unknown");
6163
break;
6164
}
6165
break;
6166
}
6167
break;
6168
6169
case CFR_DECODE_J9_LDCW:
6170
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
6171
switch(modifier)
6172
{
6173
case 'x':
6174
j9tty_printf(PORTLIB, "%04x", u16);
6175
break;
6176
6177
case 'X':
6178
j9tty_printf(PORTLIB, "%04X", u16);
6179
break;
6180
6181
case 'd':
6182
j9tty_printf(PORTLIB, "%i", u16);
6183
break;
6184
6185
case 'a':
6186
default:
6187
info = &constantPool[u16];
6188
goto ldcAscii;
6189
break;
6190
}
6191
break;
6192
6193
case CFR_DECODE_J9_LDC2DW:
6194
case CFR_DECODE_J9_LDC2LW:
6195
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
6196
switch(modifier)
6197
{
6198
case 'x':
6199
j9tty_printf(PORTLIB, "%04x", u16);
6200
break;
6201
6202
case 'X':
6203
j9tty_printf(PORTLIB, "%04X", u16);
6204
break;
6205
6206
case 'd':
6207
j9tty_printf(PORTLIB, "%i", u16);
6208
break;
6209
6210
case 'a':
6211
default:
6212
info = &constantPool[u16];
6213
if(decode == CFR_DECODE_J9_LDC2DW)
6214
{
6215
/* double */
6216
#ifdef J9VM_ENV_LITTLE_ENDIAN
6217
j9tty_printf(PORTLIB, "(double) 0x%08X%08X", info->slot2, info->slot1);
6218
#else
6219
j9tty_printf(PORTLIB, "(double) 0x%08X%08X", info->slot1, info->slot2);
6220
#endif
6221
}
6222
else
6223
{
6224
#ifdef J9VM_ENV_LITTLE_ENDIAN
6225
j9tty_printf(PORTLIB, "(long) 0x%08X%08X", info->slot2, info->slot1);
6226
#else
6227
j9tty_printf(PORTLIB, "(long) 0x%08X%08X", info->slot1, info->slot2);
6228
#endif
6229
}
6230
break;
6231
}
6232
break;
6233
6234
case CFR_DECODE_MULTIANEWARRAY:
6235
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
6236
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
6237
switch(modifier)
6238
{
6239
case 'x':
6240
j9tty_printf(PORTLIB, "%02x %04x", u8, u16);
6241
break;
6242
6243
case 'X':
6244
j9tty_printf(PORTLIB, "%02X %04X", u8, u16);
6245
break;
6246
6247
case 'd':
6248
j9tty_printf(PORTLIB, "%i %i", u8, u16);
6249
break;
6250
6251
case 'a':
6252
default:
6253
j9tty_printf(PORTLIB, "%i ", u8);
6254
info = &constantPool[u16];
6255
goto classrefAscii;
6256
break;
6257
}
6258
break;
6259
6260
case CFR_DECODE_L16:
6261
NEXT_U16_ENDIAN(bigEndian, u16, bcIndex);
6262
switch(modifier)
6263
{
6264
case 'x':
6265
j9tty_printf(PORTLIB, "%04x", (I_16)u16);
6266
break;
6267
6268
case 'X':
6269
j9tty_printf(PORTLIB, "%04X", (I_16)u16);
6270
break;
6271
6272
case 'd':
6273
j9tty_printf(PORTLIB, "%i", (I_16)u16);
6274
break;
6275
6276
case 'a':
6277
default:
6278
branch = pc + (I_16)u16;
6279
switch(pcModifier)
6280
{
6281
case 'x':
6282
j9tty_printf(PORTLIB, "%08x", branch);
6283
break;
6284
6285
case 'X':
6286
j9tty_printf(PORTLIB, "%08X", branch);
6287
break;
6288
6289
case 'd':
6290
j9tty_printf(PORTLIB, "%i", branch);
6291
break;
6292
}
6293
break;
6294
}
6295
break;
6296
6297
case CFR_DECODE_L32:
6298
NEXT_U32_ENDIAN(bigEndian, u32, bcIndex);
6299
switch(modifier)
6300
{
6301
case 'x':
6302
j9tty_printf(PORTLIB, "%08x", (I_32)u32);
6303
break;
6304
6305
case 'X':
6306
j9tty_printf(PORTLIB, "%08X", (I_32)u32);
6307
break;
6308
6309
case 'd':
6310
j9tty_printf(PORTLIB, "%i", (I_32)u32);
6311
break;
6312
6313
case 'a':
6314
default:
6315
branch = pc + (I_32)u32;
6316
switch(pcModifier)
6317
{
6318
case 'x':
6319
j9tty_printf(PORTLIB, "%08x", branch);
6320
break;
6321
6322
case 'X':
6323
j9tty_printf(PORTLIB, "%08X", branch);
6324
break;
6325
6326
case 'd':
6327
j9tty_printf(PORTLIB, "%i", branch);
6328
break;
6329
}
6330
break;
6331
}
6332
break;
6333
6334
case CFR_DECODE_NEWARRAY:
6335
NEXT_U8_ENDIAN(bigEndian, u8, bcIndex);
6336
switch(modifier)
6337
{
6338
case 'x':
6339
j9tty_printf(PORTLIB, "%02x", u8);
6340
break;
6341
6342
case 'X':
6343
j9tty_printf(PORTLIB, "%02X", u8);
6344
break;
6345
6346
case 'd':
6347
j9tty_printf(PORTLIB, "%i", u8);
6348
break;
6349
6350
case 'a':
6351
default:
6352
switch(u8)
6353
{
6354
case /*T_BOOLEAN*/ 4 :
6355
j9tty_printf( PORTLIB, "boolean");
6356
break;
6357
case /*T_CHAR*/ 5:
6358
j9tty_printf( PORTLIB, "char");
6359
break;
6360
case /*T_FLOAT*/ 6:
6361
j9tty_printf( PORTLIB, "float");
6362
break;
6363
case /*T_DOUBLE*/ 7:
6364
j9tty_printf( PORTLIB, "double");
6365
break;
6366
case /*T_BYTE*/ 8:
6367
j9tty_printf( PORTLIB, "byte");
6368
break;
6369
case /*T_SHORT*/ 9:
6370
j9tty_printf( PORTLIB, "short");
6371
break;
6372
case /*T_INT*/ 10:
6373
j9tty_printf( PORTLIB, "int");
6374
break;
6375
case /*T_LONG*/ 11:
6376
j9tty_printf( PORTLIB, "long");
6377
break;
6378
default:
6379
j9tty_printf( PORTLIB, "???");
6380
break;
6381
}
6382
break;
6383
}
6384
break;
6385
6386
case CFR_DECODE_TABLESWITCH:
6387
bcIndex = bytes + 4 - (pc % 4);
6388
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
6389
branch = pc + index;
6390
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
6391
low = (I_32)index;
6392
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
6393
high = (I_32)index;
6394
j9tty_printf( PORTLIB, "default->%i", branch);
6395
j = high - low + 1;
6396
for(k = 0; k <= (I_32) j; k++)
6397
{
6398
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
6399
branch = pc + index;
6400
j9tty_printf( PORTLIB, " %i->%i", k + low, branch);
6401
}
6402
break;
6403
6404
case CFR_DECODE_LOOKUPSWITCH:
6405
bcIndex = bytes + 4 - (pc % 4);
6406
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
6407
branch = pc + index;
6408
NEXT_U32_ENDIAN(bigEndian, npairs, bcIndex);
6409
j9tty_printf( PORTLIB, "default->%i", branch);
6410
for(j = 0; j < npairs; j++)
6411
{
6412
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
6413
key = (I_32)index;
6414
NEXT_U32_ENDIAN(bigEndian, index, bcIndex);
6415
branch = pc + index;
6416
j9tty_printf( PORTLIB, " %i->%i", key, branch);
6417
}
6418
break;
6419
}
6420
modifier = '\0';
6421
break;
6422
6423
case 'a':
6424
/* ascii */
6425
if(formatString[i] == 'b' || formatString[i] == 'p')
6426
{
6427
modifier = ch;
6428
}
6429
else
6430
{
6431
j9tty_output_char('%');
6432
j9tty_output_char(ch);
6433
}
6434
break;
6435
6436
case 'd':
6437
/* decimal */
6438
case 'x':
6439
/* hex, lowercase */
6440
case 'X':
6441
/* hex, uppercase */
6442
6443
if(formatString[i] == 'i' || formatString[i] == 'B' || formatString[i] == 'b' || formatString[i] == 'p')
6444
{
6445
modifier = ch;
6446
break;
6447
}
6448
6449
default:
6450
j9tty_output_char('%');
6451
j9tty_output_char(ch);
6452
}
6453
}
6454
}
6455
else
6456
{
6457
j9tty_output_char(ch);
6458
}
6459
}
6460
return;
6461
}
6462
6463
6464
static void j9_formatBytecodes(J9ROMClass* romClass, J9ROMMethod* method, U_8* bytecodes, U_32 bytecodesLength, char *formatString, IDATA stringLength, U_32 flags)
6465
{
6466
U_8 *bcIndex, *tempIndex;
6467
I_32 pc, index;
6468
I_32 low, high;
6469
UDATA length;
6470
U_32 npairs, bcLength;
6471
U_8 bc;
6472
BOOLEAN bigEndian;
6473
6474
PORT_ACCESS_FROM_PORT(portLib);
6475
6476
bigEndian = flags & BCT_BigEndianOutput;
6477
6478
if((method->modifiers & CFR_ACC_NATIVE) || (method->modifiers & CFR_ACC_ABSTRACT)) return;
6479
if(bytecodes)
6480
{
6481
length = bytecodesLength;
6482
if(length == 0) return;
6483
bcIndex = bytecodes;
6484
pc = 0;
6485
}
6486
else
6487
{
6488
length = J9_BYTECODE_SIZE_FROM_ROM_METHOD(method);
6489
if(length == 0) return;
6490
bytecodes = J9_BYTECODE_START_FROM_ROM_METHOD(method);
6491
bcIndex = bytecodes;
6492
pc = 0;
6493
}
6494
6495
while((U_32)pc < length)
6496
{
6497
bc = *bcIndex;
6498
pc++;
6499
switch(bc)
6500
{
6501
case JBbipush:
6502
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 2, CFR_DECODE_I8, formatString, stringLength, flags);
6503
pc++;
6504
bcIndex += 2;
6505
break;
6506
6507
case JBsipush:
6508
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 3, CFR_DECODE_I16, formatString, stringLength, flags);
6509
pc += 2;
6510
bcIndex += 3;
6511
break;
6512
6513
case JBldc:
6514
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 2, CFR_DECODE_J9_LDC, formatString, stringLength, flags);
6515
pc++;
6516
bcIndex += 2;
6517
break;
6518
6519
case JBldcw:
6520
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 3, CFR_DECODE_J9_LDCW, formatString, stringLength, flags);
6521
pc += 2;
6522
bcIndex += 3;
6523
break;
6524
6525
case JBldc2dw:
6526
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 3, CFR_DECODE_J9_LDC2DW, formatString, stringLength, flags);
6527
pc += 2;
6528
bcIndex += 3;
6529
break;
6530
6531
case JBldc2lw:
6532
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 3, CFR_DECODE_J9_LDC2LW, formatString, stringLength, flags);
6533
pc += 2;
6534
bcIndex += 3;
6535
break;
6536
6537
case JBiload:
6538
case JBlload:
6539
case JBfload:
6540
case JBdload:
6541
case JBaload:
6542
case JBistore:
6543
case JBlstore:
6544
case JBfstore:
6545
case JBdstore:
6546
case JBastore:
6547
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 2, CFR_DECODE_U8, formatString, stringLength, flags);
6548
pc++;
6549
bcIndex += 2;
6550
break;
6551
6552
case JBiloadw:
6553
case JBlloadw:
6554
case JBfloadw:
6555
case JBdloadw:
6556
case JBaloadw:
6557
case JBistorew:
6558
case JBlstorew:
6559
case JBfstorew:
6560
case JBdstorew:
6561
case JBastorew:
6562
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 4, CFR_DECODE_U16, formatString, stringLength, flags);
6563
pc += 2;
6564
bcIndex += 3;
6565
break;
6566
6567
case JBiinc:
6568
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 3, CFR_DECODE_U8_I8, formatString, stringLength, flags);
6569
pc += 2;
6570
bcIndex += 3;
6571
break;
6572
6573
case JBiincw:
6574
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 6, CFR_DECODE_U16_I16, formatString, stringLength, flags);
6575
pc += 4;
6576
bcIndex += 5;
6577
break;
6578
6579
case JBifeq:
6580
case JBifne:
6581
case JBiflt:
6582
case JBifge:
6583
case JBifgt:
6584
case JBifle:
6585
case JBificmpeq:
6586
case JBificmpne:
6587
case JBificmplt:
6588
case JBificmpge:
6589
case JBificmpgt:
6590
case JBificmple:
6591
case JBifacmpeq:
6592
case JBifacmpne:
6593
case JBgoto:
6594
case JBifnull:
6595
case JBifnonnull:
6596
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 3, CFR_DECODE_L16, formatString, stringLength, flags);
6597
pc += 2;
6598
bcIndex += 3;
6599
break;
6600
6601
case JBtableswitch:
6602
tempIndex = bcIndex + 1;
6603
switch((pc - 1) % 4)
6604
{
6605
case 0:
6606
tempIndex++;
6607
case 1:
6608
tempIndex++;
6609
case 2:
6610
tempIndex++;
6611
case 3:
6612
break;
6613
}
6614
NEXT_U32_ENDIAN(bigEndian, index, tempIndex);
6615
NEXT_U32_ENDIAN(bigEndian, index, tempIndex);
6616
low = (I_32)index;
6617
NEXT_U32_ENDIAN(bigEndian, index, tempIndex);
6618
high = (I_32)index;
6619
bcLength = (U_32) (tempIndex - bcIndex) + ((high - low + 1) * 4);
6620
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, bcLength, CFR_DECODE_TABLESWITCH, formatString, stringLength, flags);
6621
bcIndex += bcLength;
6622
pc += bcLength - 1;
6623
break;
6624
6625
case JBlookupswitch:
6626
tempIndex = bcIndex + 1;
6627
switch((pc - 1) % 4)
6628
{
6629
case 0:
6630
tempIndex++;
6631
case 1:
6632
tempIndex++;
6633
case 2:
6634
tempIndex++;
6635
case 3:
6636
break;
6637
}
6638
NEXT_U32_ENDIAN(bigEndian, index, tempIndex);
6639
NEXT_U32_ENDIAN(bigEndian, npairs, tempIndex);
6640
bcLength = (U_32)(tempIndex - bcIndex) + (npairs * 8);
6641
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, bcLength, CFR_DECODE_LOOKUPSWITCH, formatString, stringLength, flags);
6642
bcIndex += bcLength;
6643
pc += bcLength - 1;
6644
break;
6645
6646
case JBgetstatic:
6647
case JBputstatic:
6648
case JBgetfield:
6649
case JBputfield:
6650
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
6651
case JBwithfield:
6652
#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */
6653
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 3, CFR_DECODE_J9_FIELDREF, formatString, stringLength, flags);
6654
pc += 2;
6655
bcIndex += 3;
6656
break;
6657
6658
case JBinvokevirtual:
6659
case JBinvokespecial:
6660
case JBinvokestatic:
6661
case JBinvokeinterface:
6662
case JBinvokehandle:
6663
case JBinvokehandlegeneric:
6664
case JBinvokestaticsplit:
6665
case JBinvokespecialsplit:
6666
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 3, CFR_DECODE_J9_METHODREF, formatString, stringLength, flags);
6667
pc += 2;
6668
bcIndex += 3;
6669
break;
6670
6671
case JBnew:
6672
case JBanewarray:
6673
case JBcheckcast:
6674
case JBinstanceof:
6675
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
6676
case JBaconst_init:
6677
#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */
6678
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 3, CFR_DECODE_J9_CLASSREF, formatString, stringLength, flags);
6679
pc += 2;
6680
bcIndex += 3;
6681
break;
6682
6683
case JBnewarray:
6684
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 2, CFR_DECODE_NEWARRAY, formatString, stringLength, flags);
6685
pc++;
6686
bcIndex += 2;
6687
break;
6688
6689
case JBmultianewarray:
6690
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 4, CFR_DECODE_MULTIANEWARRAY, formatString, stringLength, flags);
6691
pc += 3;
6692
bcIndex += 4;
6693
break;
6694
6695
case JBgotow:
6696
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 5, CFR_DECODE_L32, formatString, stringLength, flags);
6697
pc += 4;
6698
bcIndex += 5;
6699
break;
6700
6701
default:
6702
j9_formatBytecode(romClass, method, bytecodes, bcIndex, bc, 1, CFR_DECODE_SIMPLE, formatString, stringLength, flags);
6703
bcIndex++;
6704
break;
6705
}
6706
j9tty_printf(PORTLIB, "\n");
6707
}
6708
6709
return;
6710
}
6711
6712
6713
static I_32
6714
processDirectory(char *dir, BOOLEAN recursive, U_32 flags)
6715
{
6716
char *pathBuffer = NULL;
6717
char *resultBuffer = NULL;
6718
UDATA handle = 0;
6719
IDATA result = 0;
6720
IDATA length = 0;
6721
6722
PORT_ACCESS_FROM_PORT(portLib);
6723
6724
pathBuffer = j9mem_allocate_memory(EsMaxPath, J9MEM_CATEGORY_CLASSES);
6725
if (NULL == pathBuffer) {
6726
return RET_ALLOCATE_FAILED;
6727
}
6728
6729
resultBuffer = j9mem_allocate_memory(EsMaxPath, J9MEM_CATEGORY_CLASSES);
6730
if (NULL == resultBuffer) {
6731
j9mem_free_memory(pathBuffer);
6732
return RET_ALLOCATE_FAILED;
6733
}
6734
6735
length = strlen(dir);
6736
if (length >= EsMaxPath) {
6737
j9tty_printf(PORTLIB, "Could not open directory %s (path too long)\n", dir);
6738
goto cleanup;
6739
}
6740
memcpy(resultBuffer, dir, length + 1);
6741
6742
handle = j9file_findfirst(dir, pathBuffer);
6743
if (~(UDATA)0 == handle) {
6744
j9tty_printf(PORTLIB, "Could not open directory %s\n", dir);
6745
goto cleanup;
6746
}
6747
6748
result = handle;
6749
while (-1 != result) {
6750
/* ignore "." and ".." */
6751
if ((0 != strcmp(pathBuffer, ".")) && (0 != strcmp(pathBuffer, ".."))) {
6752
IDATA length2 = length + strlen(pathBuffer);
6753
if (length2 + 1 >= EsMaxPath) {
6754
j9tty_printf(PORTLIB, "Could not open %s%s (path too long)\n", dir, pathBuffer);
6755
break;
6756
}
6757
strcpy(resultBuffer + length, pathBuffer);
6758
6759
if (recursive && (j9file_attr(resultBuffer) == EsIsDir)) {
6760
resultBuffer[length2] = PATH_SEP_CHAR;
6761
resultBuffer[length2 + 1] = '\0';
6762
processDirectory(resultBuffer, TRUE, flags);
6763
} else {
6764
if ((length2 > 6) && (0 == strcmp(resultBuffer + length2 - 6, ".class"))) {
6765
processSingleFile(resultBuffer, flags);
6766
}
6767
}
6768
}
6769
result = j9file_findnext(handle, pathBuffer);
6770
}
6771
j9file_findclose(handle);
6772
cleanup:
6773
j9mem_free_memory(pathBuffer);
6774
j9mem_free_memory(resultBuffer);
6775
return 0;
6776
}
6777
6778
6779
static I_32 processSingleFile(char* requestedFile, U_32 flags)
6780
{
6781
J9CfrClassFile* classfile;
6782
J9ROMClass* romClass;
6783
U_8* data;
6784
U_32 dataLength;
6785
int result;
6786
6787
PORT_ACCESS_FROM_PORT(portLib);
6788
6789
if(options.options & OPTION_translate)
6790
{
6791
data = loadBytes(requestedFile, &dataLength, flags);
6792
if(data == NULL) return RET_FILE_LOAD_FAILED;
6793
romClass = translateClassBytes(data, dataLength, requestedFile, flags);
6794
if(romClass == NULL)
6795
{
6796
j9mem_free_memory(data);
6797
return RET_TRANSLATE_FAILED;
6798
}
6799
result = processROMClass(romClass, requestedFile, flags);
6800
j9mem_free_memory(data);
6801
j9mem_free_memory(romClass);
6802
if(result) return result;
6803
}
6804
else
6805
{
6806
classfile = loadClassFile(requestedFile, &dataLength, flags);
6807
if(classfile == NULL) return RET_FILE_LOAD_FAILED;
6808
result = processClassFile(classfile, dataLength, requestedFile, flags);
6809
j9mem_free_memory((U_8*)classfile);
6810
if(result) return result;
6811
}
6812
return 0;
6813
}
6814
6815
static void
6816
reportClassLoadError(J9CfrError* error, char* requestedFile)
6817
{
6818
J9CfrConstantPoolInfo *name, *sig;
6819
PORT_ACCESS_FROM_PORT(portLib);
6820
const char* errorDescription;
6821
6822
errorDescription = getJ9CfrErrorDescription(PORTLIB, error);
6823
6824
if(requestedFile) {
6825
j9tty_printf( PORTLIB, "\nInvalid class file: %s\n", requestedFile);
6826
} else {
6827
j9tty_printf( PORTLIB, "\nInvalid class file\n");
6828
}
6829
6830
j9tty_printf( PORTLIB, "Recommended action: ");
6831
switch(error->errorAction) {
6832
case CFR_NoAction:
6833
j9tty_printf( PORTLIB, "no action\n");
6834
break;
6835
6836
case CFR_ThrowNoClassDefFoundError:
6837
j9tty_printf( PORTLIB, "throw java.lang.NoClassDefFoundError\n");
6838
break;
6839
6840
case CFR_ThrowClassFormatError:
6841
j9tty_printf( PORTLIB, "throw java.lang.ClassFormatError\n");
6842
break;
6843
6844
case CFR_ThrowVerifyError:
6845
j9tty_printf( PORTLIB, "throw java.lang.VerifyError\n");
6846
break;
6847
6848
case CFR_ThrowUnsupportedClassVersionError:
6849
j9tty_printf( PORTLIB, "throw java.lang.UnsupportedClassVersionError\n");
6850
break;
6851
6852
case CFR_ThrowOutOfMemoryError:
6853
j9tty_printf( PORTLIB, "throw java.lang.OutOfMemoryError\n");
6854
break;
6855
6856
default:
6857
j9tty_printf( PORTLIB, "<unknown action>\n");
6858
}
6859
6860
if(error->errorMethod == -1) {
6861
j9tty_printf( PORTLIB, "Error: %s at %i\n", errorDescription, error->errorOffset);
6862
} else {
6863
name = &(error->constantPool)[error->errorMember->nameIndex];
6864
sig = &(error->constantPool)[error->errorMember->descriptorIndex];
6865
j9tty_printf( PORTLIB, "Verification error in method %i (%.*s%.*s) at PC %i\n", error->errorMethod, name->slot1, name->bytes, sig->slot1, sig->bytes, error->errorPC);
6866
j9tty_printf( PORTLIB, "Error: %s\n", errorDescription);
6867
}
6868
return;
6869
}
6870
6871
/* when we removed j9tty_output_char, most of the senders were here in cfdump.
6872
* This function replaces the portLibrary one
6873
*/
6874
static void tty_output_char(J9PortLibrary *portLib, const char c) {
6875
PORT_ACCESS_FROM_PORT(portLib);
6876
6877
j9tty_printf(PORTLIB, "%c", c);
6878
}
6879
6880
6881
UDATA signalProtectedMain(struct J9PortLibrary *portLibrary, void *arg)
6882
{
6883
struct j9cmdlineOptions *startupOptions = (struct j9cmdlineOptions *) arg;
6884
int argc = startupOptions->argc;
6885
char **argv = startupOptions->argv;
6886
char **envp = startupOptions->envp;
6887
U_32 flags;
6888
I_32 result;
6889
6890
PORT_ACCESS_FROM_PORT(startupOptions->portLibrary);
6891
portLib = startupOptions->portLibrary;
6892
6893
main_setNLSCatalog(PORTLIB, argv);
6894
6895
/* Initialize the thread library -- Zip code now uses monitors. */
6896
omrthread_attach_ex(NULL, J9THREAD_ATTR_DEFAULT);
6897
6898
result = initZipLibrary(portLib, NULL);
6899
if(result) return result;
6900
6901
result = parseCommandLine(argc, argv, envp);
6902
if(result) return result;
6903
flags = buildFlags();
6904
6905
translationBuffers = j9bcutil_allocTranslationBuffers(PORTLIB);
6906
if(!translationBuffers)
6907
{
6908
j9tty_printf( PORTLIB, "Failed to allocate buffers\n");
6909
return RET_ALLOCATE_FAILED;
6910
}
6911
if(options.options & OPTION_check)
6912
{
6913
verifyBuffers = j9mem_allocate_memory( sizeof( J9BytecodeVerificationData ) , J9MEM_CATEGORY_CLASSES);
6914
if( !verifyBuffers ) {
6915
j9tty_printf( PORTLIB, "Failed to allocate verify buffers\n");
6916
return RET_ALLOCATE_FAILED;
6917
}
6918
}
6919
6920
result = 0;
6921
switch(options.source)
6922
{
6923
case SOURCE_files:
6924
/* Recursive? Directories? */
6925
result = processAllFiles(&argv[options.filesStart], flags);
6926
break;
6927
6928
case SOURCE_zip:
6929
if ((options.filesStart == argc) && (options.options & OPTION_multi)) {
6930
result = processAllInZIP(options.sourceString, flags);
6931
} else {
6932
result = processFilesInZIP(options.sourceString, &argv[options.filesStart], flags);
6933
}
6934
break;
6935
6936
case SOURCE_jimage:
6937
{
6938
J9JImage *jimage = NULL;
6939
result = j9bcutil_loadJImage(PORTLIB, options.sourceString, &jimage);
6940
if (J9JIMAGE_NO_ERROR != result) {
6941
j9tty_printf(PORTLIB, "Error in loading jimage file %s. Error code=%d\n", options.sourceString, result);
6942
result = RET_JIMAGE_LOADJIMAGE_FAILED;
6943
} else {
6944
if (ACTION_findModuleForPackage == options.action) {
6945
char *module = NULL;
6946
char **packageName = &argv[options.filesStart];
6947
6948
while (NULL != *packageName) {
6949
module = (char *)j9bcutil_findModuleForPackage(PORTLIB, jimage, *packageName);
6950
if (NULL != module) {
6951
j9tty_printf(PORTLIB, "Package %s is present in module %s\n", *packageName, module);
6952
} else {
6953
j9tty_printf(PORTLIB, "Package %s is not present in any module\n");
6954
}
6955
packageName += 1;
6956
}
6957
} else if (ACTION_dumpJImageInfo == options.action) {
6958
j9bcutil_dumpJImageInfo(PORTLIB, jimage);
6959
} else {
6960
if ((options.filesStart == argc) && (options.options & OPTION_multi)) {
6961
result = processAllInJImage(jimage, options.sourceString, flags);
6962
} else {
6963
result = processFilesInJImage(jimage, options.sourceString, &argv[options.filesStart], flags);
6964
}
6965
}
6966
if (NULL != jimage) {
6967
j9bcutil_unloadJImage(PORTLIB, jimage);
6968
jimage = NULL;
6969
}
6970
}
6971
break;
6972
}
6973
case SOURCE_rom:
6974
result = processROMFile(options.sourceString, flags);
6975
break;
6976
6977
default:
6978
result = RET_UNSUPPORTED_SOURCE;
6979
}
6980
return result;
6981
}
6982
6983
6984
static I_32 processROMFile(char* requestedFile, U_32 flags)
6985
{
6986
U_8* data;
6987
U_32 dataLength;
6988
int result;
6989
6990
PORT_ACCESS_FROM_PORT(portLib);
6991
6992
data = loadBytes(requestedFile, &dataLength, flags);
6993
if(data == NULL) return RET_FILE_LOAD_FAILED;
6994
6995
result = processROMClass((J9ROMClass*)data, requestedFile, flags);
6996
j9mem_free_memory(data);
6997
return result;
6998
}
6999
7000
7001
static U_8* loadBytes(char* requestedFile, U_32* lengthReturn, U_32 flags)
7002
{
7003
U_8* data;
7004
U_32 dataLength;
7005
UDATA startTime;
7006
UDATA endTime;
7007
BOOLEAN verbose;
7008
7009
PORT_ACCESS_FROM_PORT(portLib);
7010
verbose = (options.options & OPTION_verbose)?TRUE:FALSE;
7011
7012
startTime = j9time_usec_clock( );
7013
dataLength = getBytes(requestedFile, &data);
7014
endTime = j9time_usec_clock( );
7015
translationBuffers->dynamicLoadStats->readStartTime = startTime;
7016
translationBuffers->dynamicLoadStats->readEndTime = endTime;
7017
switch(dataLength)
7018
{
7019
case RET_FILE_OPEN_FAILED:
7020
j9tty_printf(PORTLIB, "Could not open %s\n", requestedFile);
7021
return NULL;
7022
7023
case RET_FILE_SEEK_FAILED:
7024
case RET_FILE_READ_FAILED:
7025
j9tty_printf(PORTLIB, "Could not read %s\n", options.sourceString);
7026
return NULL;
7027
7028
case RET_ALLOCATE_FAILED:
7029
j9tty_printf(PORTLIB, "Insufficient memory to complete operation\n");
7030
return NULL;
7031
}
7032
if(verbose) j9tty_printf( PORTLIB, "<file read time: %d us.>\n", endTime - startTime);
7033
7034
*lengthReturn = dataLength;
7035
return data;
7036
}
7037
7038
7039
static void dumpAnnotationElement(J9CfrClassFile* classfile, J9CfrAnnotationElement *element, U_32 tabLevel)
7040
{
7041
J9CfrAnnotationElementArray *array;
7042
U_16 index, index2;
7043
U_32 i;
7044
7045
PORT_ACCESS_FROM_PORT(portLib);
7046
7047
switch (element->tag) {
7048
case 'B':
7049
index = ((J9CfrAnnotationElementPrimitive *)element)->constValueIndex;
7050
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7051
j9tty_printf(PORTLIB, "Byte value: %i -> %x\n", index, classfile->constantPool[index].slot1);
7052
break;
7053
7054
case 'C':
7055
index = ((J9CfrAnnotationElementPrimitive *)element)->constValueIndex;
7056
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7057
j9tty_printf(PORTLIB, "Char value: %i -> %c\n", index, classfile->constantPool[index].slot1);
7058
break;
7059
7060
case 'D':
7061
index = ((J9CfrAnnotationElementPrimitive *)element)->constValueIndex;
7062
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7063
j9tty_printf(PORTLIB, "Double value: %i -> 0x%08X%08X\n", index, classfile->constantPool[index].slot1, classfile->constantPool[index].slot2);
7064
break;
7065
7066
case 'F':
7067
index = ((J9CfrAnnotationElementPrimitive *)element)->constValueIndex;
7068
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7069
j9tty_printf(PORTLIB, "Float value: %i -> 0x%08X\n", index, classfile->constantPool[index].slot1);
7070
break;
7071
7072
case 'I':
7073
index = ((J9CfrAnnotationElementPrimitive *)element)->constValueIndex;
7074
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7075
j9tty_printf(PORTLIB, "Int value: %i -> %i\n", index, classfile->constantPool[index].slot1);
7076
break;
7077
7078
case 'J':
7079
index = ((J9CfrAnnotationElementPrimitive *)element)->constValueIndex;
7080
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7081
j9tty_printf(PORTLIB, "Long value: %i -> 0x%08X%08X\n", index, classfile->constantPool[index].slot1, classfile->constantPool[index].slot2);
7082
break;
7083
7084
case 'S':
7085
index = ((J9CfrAnnotationElementPrimitive *)element)->constValueIndex;
7086
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7087
j9tty_printf(PORTLIB, "Short value: %i -> %i\n", index, classfile->constantPool[index].slot1);
7088
break;
7089
7090
case 'Z':
7091
index = ((J9CfrAnnotationElementPrimitive *)element)->constValueIndex;
7092
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7093
j9tty_printf(PORTLIB, "Boolean value: %i -> %i\n", index, classfile->constantPool[index].slot1);
7094
break;
7095
7096
case 's':
7097
index = ((J9CfrAnnotationElementPrimitive *)element)->constValueIndex;
7098
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7099
j9tty_printf(PORTLIB, "String value: %i -> %s\n", index, classfile->constantPool[index].bytes);
7100
break;
7101
7102
case 'e':
7103
index = ((J9CfrAnnotationElementEnum *)element)->typeNameIndex;
7104
index2 = ((J9CfrAnnotationElementEnum *)element)->constNameIndex;
7105
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7106
j9tty_printf(PORTLIB, "Enum Type: %i -> %s\n", index, classfile->constantPool[index].bytes);
7107
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7108
j9tty_printf(PORTLIB, "Enum Constant: %i -> %s\n", index, classfile->constantPool[index2].bytes);
7109
break;
7110
7111
case '@':
7112
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7113
j9tty_printf(PORTLIB, "Nested Annotation\n");
7114
7115
dumpAnnotations(classfile, &((J9CfrAnnotationElementAnnotation *)element)->annotationValue, 1, tabLevel);
7116
break;
7117
7118
case '[':
7119
array = (J9CfrAnnotationElementArray *)element;
7120
7121
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7122
j9tty_printf(PORTLIB, "Array Count: %i\n", array->numberOfValues);
7123
7124
for (i = 0; i < array->numberOfValues; i++) {
7125
dumpAnnotationElement(classfile, array->values[i], tabLevel + 1);
7126
}
7127
break;
7128
7129
case 'c':
7130
index = ((J9CfrAnnotationElementClass *)element)->classInfoIndex;
7131
j9tty_printf( PORTLIB, "Class: %i %s\n", index, classfile->constantPool[index].bytes);
7132
break;
7133
7134
default:
7135
for(i = 0; i < tabLevel; i++) j9tty_printf( PORTLIB, " ");
7136
j9tty_printf(PORTLIB, "???");
7137
break;
7138
}
7139
}
7140
7141
7142
static void dumpAnnotations(J9CfrClassFile* classfile, J9CfrAnnotation *annotations, U_32 annotationCount, U_32 tabLevel)
7143
{
7144
J9CfrAnnotation *annotation;
7145
J9CfrAnnotationElementPair *elementPair;
7146
U_16 index;
7147
U_32 i, j, k;
7148
7149
PORT_ACCESS_FROM_PORT(portLib);
7150
7151
annotation = annotations;
7152
for (i = 0; i < annotationCount; i++, annotation++) {
7153
index = annotation->typeIndex;
7154
for(j = 0; j < tabLevel; j++) j9tty_printf( PORTLIB, " ");
7155
j9tty_printf(PORTLIB, "Type: %i -> %s\n", index, classfile->constantPool[index].bytes);
7156
7157
for(j = 0; j < tabLevel; j++) j9tty_printf( PORTLIB, " ");
7158
j9tty_printf(PORTLIB, "Element Value Pairs (%i):\n", annotation->numberOfElementValuePairs);
7159
7160
elementPair = annotation->elementValuePairs;
7161
for (j = 0; j < annotation->numberOfElementValuePairs; j++, elementPair++) {
7162
index = elementPair->elementNameIndex;
7163
for(k = 0; k < tabLevel + 1; k++) j9tty_printf( PORTLIB, " ");
7164
j9tty_printf(PORTLIB, "Name: %i -> %s\n", index, classfile->constantPool[index].bytes);
7165
7166
dumpAnnotationElement(classfile, elementPair->value, tabLevel + 1);
7167
j9tty_printf(PORTLIB, "\n");
7168
}
7169
}
7170
}
7171
7172
#define INDENT(indentation) \
7173
do { \
7174
U_32 tl; \
7175
for (tl = 0; tl < tabLevel; tl++) { \
7176
j9tty_printf( PORTLIB, " "); \
7177
} \
7178
} while(FALSE)
7179
7180
static void dumpTypeAnnotations (J9CfrClassFile* classfile, J9CfrTypeAnnotation *annotations, U_32 annotationCount, U_32 tabLevel) {
7181
char *targetTypeName = "unknown target_type";
7182
U_32 annotationIndex = 0;
7183
7184
PORT_ACCESS_FROM_PORT(portLib);
7185
7186
for (annotationIndex = 0; annotationIndex < annotationCount; ++annotationIndex) {
7187
J9CfrTypeAnnotation *currentAnnotation = &annotations[annotationIndex];
7188
U_32 pi = 0;
7189
7190
switch (currentAnnotation->targetType) {
7191
case CFR_TARGET_TYPE_TypeParameterGenericClass:
7192
targetTypeName = "TypeParameterGenericClass";
7193
break;
7194
7195
case CFR_TARGET_TYPE_TypeParameterGenericMethod:
7196
targetTypeName = "TypeParameterGenericMethod";
7197
break;
7198
7199
case CFR_TARGET_TYPE_TypeInExtends:
7200
targetTypeName = "TypeInExtends";
7201
break;
7202
7203
case CFR_TARGET_TYPE_TypeInBoundOfGenericClass:
7204
targetTypeName = "TypeInBoundOfGenericClass";
7205
break;
7206
7207
case CFR_TARGET_TYPE_TypeInBoundOfGenericMethod:
7208
targetTypeName = "TypeInBoundOfGenericMethod";
7209
break;
7210
7211
case CFR_TARGET_TYPE_TypeInFieldDecl:
7212
targetTypeName = "TypeInFieldDecl";
7213
break;
7214
7215
case CFR_TARGET_TYPE_ReturnType:
7216
targetTypeName = "ReturnType";
7217
break;
7218
7219
case CFR_TARGET_TYPE_ReceiverType:
7220
targetTypeName = "ReceiverType";
7221
break;
7222
7223
case CFR_TARGET_TYPE_TypeInFormalParam:
7224
targetTypeName = "TypeInFormalParam";
7225
break;
7226
7227
case CFR_TARGET_TYPE_TypeInThrows:
7228
targetTypeName = "TypeInThrows";
7229
break;
7230
7231
case CFR_TARGET_TYPE_TypeInLocalVar:
7232
targetTypeName = "TypeInLocalVar";
7233
break;
7234
7235
case CFR_TARGET_TYPE_TypeInResourceVar:
7236
targetTypeName = "TypeInResourceVar";
7237
break;
7238
7239
case CFR_TARGET_TYPE_TypeInExceptionParam:
7240
targetTypeName = "TypeInExceptionParam";
7241
break;
7242
7243
case CFR_TARGET_TYPE_TypeInInstanceof:
7244
targetTypeName = "TypeInInstanceof";
7245
break;
7246
7247
case CFR_TARGET_TYPE_TypeInNew:
7248
targetTypeName = "TypeInNew";
7249
break;
7250
7251
case CFR_TARGET_TYPE_TypeInMethodrefNew:
7252
targetTypeName = "TypeInMethodrefNew";
7253
break;
7254
7255
case CFR_TARGET_TYPE_TypeInMethodrefIdentifier:
7256
targetTypeName = "TypeInMethodrefIdentifier";
7257
break;
7258
7259
case CFR_TARGET_TYPE_TypeInCast:
7260
targetTypeName = "TypeInCast";
7261
break;
7262
7263
case CFR_TARGET_TYPE_TypeForGenericConstructorInNew:
7264
targetTypeName = "TypeForGenericConstructorInNew";
7265
break;
7266
7267
case CFR_TARGET_TYPE_TypeForGenericMethodInvocation:
7268
targetTypeName = "TypeForGenericMethodInvocation";
7269
break;
7270
7271
case CFR_TARGET_TYPE_TypeForGenericConstructorInMethodRef:
7272
targetTypeName = "TypeForGenericConstructorInMethodRef";
7273
break;
7274
7275
case CFR_TARGET_TYPE_TypeForGenericMethodInvocationInMethodRef:
7276
targetTypeName = "TypeForGenericMethodInvocationInMethodRef";
7277
break;
7278
7279
default:
7280
targetTypeName = "unknown target_type";
7281
break;
7282
}
7283
INDENT(tabLevel);
7284
j9tty_printf(PORTLIB, "target_type=0x%0x (%s) ", currentAnnotation->targetType, targetTypeName);
7285
7286
switch (currentAnnotation->targetType) {
7287
7288
case CFR_TARGET_TYPE_TypeParameterGenericClass:
7289
case CFR_TARGET_TYPE_TypeParameterGenericMethod:
7290
j9tty_printf(PORTLIB, "type_parameter_index=%d", currentAnnotation->targetInfo.typeParameterTarget.typeParameterIndex);
7291
break;
7292
7293
case CFR_TARGET_TYPE_TypeInExtends:
7294
j9tty_printf(PORTLIB, "supertype_index=%d", currentAnnotation->targetInfo.supertypeTarget.supertypeIndex);
7295
break;
7296
7297
case CFR_TARGET_TYPE_TypeInBoundOfGenericClass:
7298
case CFR_TARGET_TYPE_TypeInBoundOfGenericMethod:
7299
j9tty_printf(PORTLIB, "type_parameter_index=%d bound_index=%d",
7300
currentAnnotation->targetInfo.typeParameterBoundTarget.typeParameterIndex, currentAnnotation->targetInfo.typeParameterBoundTarget.boundIndex);
7301
break;
7302
7303
case CFR_TARGET_TYPE_TypeInFormalParam:
7304
j9tty_printf(PORTLIB, "formal_parameter_index=%d", currentAnnotation->targetInfo.methodFormalParameterTarget.formalParameterIndex);
7305
break;
7306
7307
case CFR_TARGET_TYPE_TypeInThrows:
7308
j9tty_printf(PORTLIB, "throws_type_index=%d", currentAnnotation->targetInfo.throwsTarget.throwsTypeIndex);
7309
break;
7310
7311
case CFR_TARGET_TYPE_TypeInLocalVar:
7312
case CFR_TARGET_TYPE_TypeInResourceVar: {
7313
U_32 ti;
7314
7315
J9CfrLocalvarTarget *t = &(currentAnnotation->targetInfo.localvarTarget);
7316
for (ti=0; ti < t->tableLength; ++ti) {
7317
J9CfrLocalvarTargetEntry *te = &(t->table[ti]);
7318
j9tty_printf(PORTLIB, "\n");
7319
INDENT(tabLevel);
7320
j9tty_printf(PORTLIB, "start_pc=%d length=%d index=%d", te->startPC, te->length, te->index);
7321
}
7322
}
7323
break;
7324
7325
case CFR_TARGET_TYPE_TypeInExceptionParam:
7326
j9tty_printf(PORTLIB, "exception_table_index=%d", currentAnnotation->targetInfo.catchTarget.exceptiontableIndex);
7327
break;
7328
7329
case CFR_TARGET_TYPE_TypeInInstanceof:
7330
case CFR_TARGET_TYPE_TypeInNew:
7331
case CFR_TARGET_TYPE_TypeInMethodrefNew:
7332
case CFR_TARGET_TYPE_TypeInMethodrefIdentifier:
7333
j9tty_printf(PORTLIB, "offset=%d", currentAnnotation->targetInfo.offsetTarget.offset);
7334
break;
7335
7336
case CFR_TARGET_TYPE_TypeInCast:
7337
case CFR_TARGET_TYPE_TypeForGenericConstructorInNew:
7338
case CFR_TARGET_TYPE_TypeForGenericMethodInvocation:
7339
case CFR_TARGET_TYPE_TypeForGenericConstructorInMethodRef:
7340
case CFR_TARGET_TYPE_TypeForGenericMethodInvocationInMethodRef:
7341
j9tty_printf(PORTLIB, "offset=%d type_argument_index=%d",
7342
currentAnnotation->targetInfo.typeArgumentTarget.offset, currentAnnotation->targetInfo.typeArgumentTarget.typeArgumentIndex);
7343
break;
7344
7345
default:
7346
break;
7347
}
7348
j9tty_printf(PORTLIB, "\n");
7349
7350
for (pi=0; pi < currentAnnotation->typePath.pathLength; ++pi) {
7351
J9CfrTypePathEntry *entry = &currentAnnotation->typePath.path[pi];
7352
INDENT(tabLevel);
7353
j9tty_printf(PORTLIB, "type_path_kind=%d type_argument_index=%d\n", entry->typePathKind, entry->typeArgumentIndex);
7354
}
7355
7356
dumpAnnotations(classfile, &currentAnnotation->annotation, 1, tabLevel+1);
7357
}
7358
return;
7359
}
7360
7361
static void dumpStackMap(J9CfrAttributeStackMap * stackMap, J9CfrClassFile* classfile, U_32 tabLevel)
7362
{
7363
U_32 i, j;
7364
U_32 framePC = (U_32) -1;
7365
U_8 frameType;
7366
U_8 *framePointer = stackMap->entries;
7367
U_8 *frameEnd = framePointer+stackMap->mapLength;
7368
U_16 offset;
7369
7370
PORT_ACCESS_FROM_PORT(portLib);
7371
7372
for(j = 0; j < stackMap->numberOfEntries; j++) {
7373
if (framePointer >= frameEnd) {
7374
j9tty_printf( PORTLIB, "End of StackMapTable attribute reached before last field\n");
7375
return;
7376
}
7377
for(i = 0; i < tabLevel; i++) {
7378
j9tty_printf( PORTLIB, " ");
7379
}
7380
7381
if (stackMap->tag == CFR_ATTRIBUTE_StackMap) {
7382
frameType = 255;
7383
} else {
7384
frameType = *framePointer++;
7385
framePC += 1;
7386
}
7387
7388
if (frameType < 64) {
7389
framePC += (U_32) frameType;
7390
j9tty_printf( PORTLIB, "pc: %i same\n", framePC);
7391
7392
} else if (frameType < 128) {
7393
framePC += (U_32) (frameType - 64);
7394
j9tty_printf( PORTLIB, "pc: %i same_locals_1_stack_item: ", framePC);
7395
framePointer = dumpStackMapSlots(classfile, framePointer, 1);
7396
j9tty_printf( PORTLIB, "\n");
7397
7398
} else if (frameType < 247) {
7399
j9tty_printf( PORTLIB, "UNKNOWN FRAME TAG %02x\n", frameType);
7400
7401
} else if (frameType == 247) {
7402
offset = (framePointer[0] << 8) + framePointer[1];
7403
framePointer +=2;
7404
framePC += (U_32) (offset);
7405
j9tty_printf( PORTLIB, "pc: %i same_locals_1_stack_item_extended: ", framePC);
7406
framePointer = dumpStackMapSlots(classfile, framePointer, 1);
7407
j9tty_printf( PORTLIB, "\n");
7408
7409
} else if (frameType < 251) {
7410
offset = (framePointer[0] << 8) + framePointer[1];
7411
framePointer +=2;
7412
framePC += (U_32) (offset);
7413
j9tty_printf( PORTLIB, "pc: %i chop %i\n", framePC, 251 - frameType);
7414
7415
} else if (frameType == 251) {
7416
offset = (framePointer[0] << 8) + framePointer[1];
7417
framePointer +=2;
7418
framePC += (U_32) (offset);
7419
j9tty_printf( PORTLIB, "pc: %i same_extended\n", framePC);
7420
7421
} else if (frameType < 255) {
7422
offset = (framePointer[0] << 8) + framePointer[1];
7423
framePointer +=2;
7424
framePC += (U_32) (offset);
7425
j9tty_printf( PORTLIB, "pc: %i append: ", framePC);
7426
framePointer = dumpStackMapSlots(classfile, framePointer, (U_16) (frameType - 251));
7427
j9tty_printf( PORTLIB, "\n");
7428
7429
} else if (frameType == 255) {
7430
offset = (framePointer[0] << 8) + framePointer[1];
7431
framePointer +=2;
7432
if (stackMap->tag == CFR_ATTRIBUTE_StackMap) {
7433
framePC = offset;
7434
} else {
7435
framePC += (U_32) (offset);
7436
}
7437
j9tty_printf( PORTLIB, "pc: %i full, local(s): ", framePC);
7438
offset = (framePointer[0] << 8) + framePointer[1];
7439
framePointer +=2;
7440
framePointer = dumpStackMapSlots(classfile, framePointer, offset);
7441
j9tty_printf( PORTLIB, ", stack: ");
7442
offset = (framePointer[0] << 8) + framePointer[1];
7443
framePointer +=2;
7444
framePointer = dumpStackMapSlots(classfile, framePointer, offset);
7445
j9tty_printf( PORTLIB, "\n");
7446
}
7447
}
7448
7449
return;
7450
}
7451
7452
7453
static U_8 * dumpStackMapSlots(J9CfrClassFile* classfile, U_8 * slotData, U_16 slotCount)
7454
{
7455
U_16 i;
7456
U_8 slotType;
7457
U_16 index;
7458
7459
PORT_ACCESS_FROM_PORT(portLib);
7460
7461
const char * slotTypes [] = {
7462
"top",
7463
"int",
7464
"float",
7465
"double",
7466
"long",
7467
"null",
7468
"uninitialized_this" };
7469
7470
j9tty_printf( PORTLIB, "(");
7471
7472
for(i = 0; i < slotCount; i++) {
7473
slotType = *slotData++;
7474
7475
if (slotType <= CFR_STACKMAP_TYPE_INIT_OBJECT) {
7476
j9tty_printf( PORTLIB, "%s", slotTypes[slotType]);
7477
7478
} else if (slotType == CFR_STACKMAP_TYPE_OBJECT) {
7479
index = (slotData[0] << 8) + slotData[1];
7480
index = classfile->constantPool[index].slot1;
7481
if (classfile->constantPool[index].bytes[0] != '[') {
7482
j9tty_printf( PORTLIB, "L");
7483
}
7484
j9tty_printf( PORTLIB, "%s;", classfile->constantPool[index].bytes);
7485
slotData += 2;
7486
7487
} else if (slotType == CFR_STACKMAP_TYPE_NEW_OBJECT) {
7488
index = (slotData[0] << 8) + slotData[1];
7489
j9tty_printf( PORTLIB, "this pc:%i", index);
7490
slotData += 2;
7491
7492
} else {
7493
j9tty_printf( PORTLIB, "UNKNOWN SLOT TYPE %x", slotType);
7494
}
7495
7496
if (i != (slotCount - 1)) {
7497
j9tty_printf( PORTLIB, ", ");
7498
}
7499
}
7500
7501
j9tty_printf( PORTLIB, ")");
7502
7503
return slotData;
7504
}
7505
7506