1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
29 #include "DbeSession.h"
30 #include "ClassFile.h"
32 #include "StringBuilder.h"
39 ByteCodeInfo (JMethod
*_func
, int _bci
, int _lno
)
51 typedef unsigned char u1
;
52 typedef unsigned short u2
;
53 typedef unsigned int u4
;
55 // Class File Constants
56 #define JAVA_MAGIC 0xcafebabe
59 // First argument in access_flags_to_str()
65 // jdk/src/share/classes/sun/tools/java/RuntimeConstants.java
68 T_BOOLEAN
= 0x00000004,
71 T_DOUBLE
= 0x00000007,
77 // Access and modifier flags
78 ACC_PUBLIC
= 0x00000001,
79 ACC_PRIVATE
= 0x00000002,
80 ACC_PROTECTED
= 0x00000004,
81 ACC_STATIC
= 0x00000008,
82 ACC_FINAL
= 0x00000010,
83 ACC_SYNCHRONIZED
= 0x00000020,
84 ACC_VOLATILE
= 0x00000040,
85 ACC_TRANSIENT
= 0x00000080,
86 ACC_NATIVE
= 0x00000100,
87 ACC_INTERFACE
= 0x00000200,
88 ACC_ABSTRACT
= 0x00000400,
89 ACC_STRICT
= 0x00000800,
90 ACC_SYNTHETIC
= 0x00001000,
91 ACC_ANNOTATION
= 0x00002000,
92 ACC_ENUM
= 0x00004000,
94 ACC_SUPER
= 0x00000020,
95 ACC_BRIDGE
= 0x00000040,
96 ACC_VARARGS
= 0x00000080,
272 opc_tableswitch
= 170,
273 opc_lookupswitch
= 171,
284 opc_invokevirtual
= 182,
285 opc_invokespecial
= 183,
286 opc_invokestatic
= 184,
287 opc_invokeinterface
= 185,
288 opc_invokedynamic
= 186,
292 opc_arraylength
= 190,
295 opc_instanceof
= 193,
296 opc_monitorenter
= 194,
297 opc_monitorexit
= 195,
299 opc_multianewarray
= 197,
304 opc_breakpoint
= 202,
308 CONSTANT_UNICODE
= 2,
309 CONSTANT_INTEGER
= 3,
316 CONSTANT_METHOD
= 10,
317 CONSTANT_INTERFACEMETHOD
= 11,
318 CONSTANT_NAMEANDTYPE
= 12,
319 CONSTANT_METHODHANDLE
= 15,
320 CONSTANT_METHODTYPE
= 16,
321 CONSTANT_INVOKEDYNAMIC
= 18
324 static char *opcNames
[] = {
326 NTXT ("aconst_null"),
495 NTXT ("tableswitch"),
496 NTXT ("lookupswitch"),
507 NTXT ("invokevirtual"),
508 NTXT ("invokespecial"),
509 NTXT ("invokestatic"),
510 NTXT ("invokeinterface"),
511 NTXT ("invokedynamic"),
515 NTXT ("arraylength"),
519 NTXT ("monitorenter"),
520 NTXT ("monitorexit"),
522 NTXT ("multianewarray"),
531 #define APPEND_FLAG(len, buf, flag, x) \
532 if (((x) & (flag)) != 0) \
535 AppendString(len, buf, NTXT("%s%s"), delimiter, #x); \
536 delimiter = NTXT("|"); \
540 access_flags_to_str (int kind
, int flag
)
542 static char buf
[256];
547 AppendString (len
, buf
, NTXT ("0x%x"), (unsigned int) flag
);
550 const char *delimiter
= "";
551 if (kind
== ClassAccess
)
553 APPEND_FLAG (len
, buf
, flag
, ACC_FINAL
);
554 APPEND_FLAG (len
, buf
, flag
, ACC_SUPER
);
555 APPEND_FLAG (len
, buf
, flag
, ACC_INTERFACE
);
556 APPEND_FLAG (len
, buf
, flag
, ACC_ABSTRACT
);
557 APPEND_FLAG (len
, buf
, flag
, ACC_SYNTHETIC
);
558 APPEND_FLAG (len
, buf
, flag
, ACC_ANNOTATION
);
559 APPEND_FLAG (len
, buf
, flag
, ACC_ENUM
);
561 AppendString (len
, buf
, "%s0x%x", delimiter
, (unsigned int) (flag
));
563 else if (kind
== FieldAccess
)
565 APPEND_FLAG (len
, buf
, flag
, ACC_PUBLIC
);
566 APPEND_FLAG (len
, buf
, flag
, ACC_PRIVATE
);
567 APPEND_FLAG (len
, buf
, flag
, ACC_PROTECTED
);
568 APPEND_FLAG (len
, buf
, flag
, ACC_STATIC
);
569 APPEND_FLAG (len
, buf
, flag
, ACC_FINAL
);
570 APPEND_FLAG (len
, buf
, flag
, ACC_VOLATILE
);
571 APPEND_FLAG (len
, buf
, flag
, ACC_TRANSIENT
);
572 APPEND_FLAG (len
, buf
, flag
, ACC_SYNTHETIC
);
573 APPEND_FLAG (len
, buf
, flag
, ACC_ENUM
);
575 AppendString (len
, buf
, "%s0x%x", delimiter
, (unsigned int) (flag
));
577 else if (kind
== MethodAccess
)
579 APPEND_FLAG (len
, buf
, flag
, ACC_PUBLIC
);
580 APPEND_FLAG (len
, buf
, flag
, ACC_PRIVATE
);
581 APPEND_FLAG (len
, buf
, flag
, ACC_PROTECTED
);
582 APPEND_FLAG (len
, buf
, flag
, ACC_STATIC
);
583 APPEND_FLAG (len
, buf
, flag
, ACC_FINAL
);
584 APPEND_FLAG (len
, buf
, flag
, ACC_SYNCHRONIZED
);
585 APPEND_FLAG (len
, buf
, flag
, ACC_BRIDGE
);
586 APPEND_FLAG (len
, buf
, flag
, ACC_VARARGS
);
587 APPEND_FLAG (len
, buf
, flag
, ACC_NATIVE
);
588 APPEND_FLAG (len
, buf
, flag
, ACC_ABSTRACT
);
589 APPEND_FLAG (len
, buf
, flag
, ACC_STRICT
);
590 APPEND_FLAG (len
, buf
, flag
, ACC_SYNTHETIC
);
592 AppendString (len
, buf
, "%s0x%x", delimiter
, (unsigned int) (flag
));
594 else if (kind
== NestedClassAccess
)
596 APPEND_FLAG (len
, buf
, flag
, ACC_PUBLIC
);
597 APPEND_FLAG (len
, buf
, flag
, ACC_PRIVATE
);
598 APPEND_FLAG (len
, buf
, flag
, ACC_PROTECTED
);
599 APPEND_FLAG (len
, buf
, flag
, ACC_STATIC
);
600 APPEND_FLAG (len
, buf
, flag
, ACC_FINAL
);
601 APPEND_FLAG (len
, buf
, flag
, ACC_INTERFACE
);
602 APPEND_FLAG (len
, buf
, flag
, ACC_ABSTRACT
);
603 APPEND_FLAG (len
, buf
, flag
, ACC_SYNTHETIC
);
604 APPEND_FLAG (len
, buf
, flag
, ACC_ANNOTATION
);
605 APPEND_FLAG (len
, buf
, flag
, ACC_ENUM
);
607 AppendString (len
, buf
, "%s0x%x", delimiter
, (unsigned int) (flag
));
612 class DataReadException
616 DataReadException (char *s
)
621 ~DataReadException ()
636 class DataInputStream
640 DataInputStream (const unsigned char *bytes
, int64_t sz
)
642 bp
= bp_orig
= bytes
;
643 bp_last
= bp_orig
+ sz
;
646 DataInputStream (DataInputStream
*in
)
648 bp
= bp_orig
= in
->bp_orig
;
649 bp_last
= in
->bp_last
;
665 u2 val
= (bp
[0] << 8) | bp
[1];
674 u4 val
= (bp
[0] << 24) | (bp
[1] << 16) | (bp
[2] << 8) | bp
[3];
705 copy_bytes (char *buf
, int64_t len
)
708 memcpy (buf
, bp
, len
);
717 if (sz
< 0 || bp
+ sz
> bp_last
)
719 DataReadException
*e1
= new DataReadException (
720 dbe_sprintf (GTXT ("(Cannot read %lld byte(s) offset=0x%llx)\n"),
721 (long long) sz
, (long long) get_offset ()));
726 const unsigned char *bp_last
;
727 const unsigned char *bp_orig
;
728 const unsigned char *bp
;
731 class BinaryConstantPool
734 BinaryConstantPool (DataInputStream
&in
);
735 ~BinaryConstantPool ();
740 return (n
< nconst
&& n
> 0) ? types
[n
] : 0;
742 char *getString (int index
);
745 static char *getTypeName (int ty
);
746 static char *type_name_to_str (int ty
);
747 static char *offset_to_str (long long offset
);
752 DataInputStream
*input
;
756 BinaryConstantPool::type_name_to_str (int ty
)
758 static char buf
[128];
759 char *tyName
= getTypeName (ty
);
760 snprintf (buf
, sizeof (buf
), NTXT ("%s(%d)"), tyName
, ty
);
765 BinaryConstantPool::offset_to_str (long long offset
)
767 static char buf
[128];
768 snprintf (buf
, sizeof (buf
), NTXT ("offset=0x%06llx (%llu)"), offset
, offset
);
772 BinaryConstantPool::BinaryConstantPool (DataInputStream
&in
)
778 input
= new DataInputStream (in
);
779 int cntConst
= in
.readUnsignedShort ();
782 types
= new u1
[cntConst
];
784 offsets
= new int64_t [cntConst
];
785 strings
= new char * [cntConst
];
788 Dprintf (DUMP_JAVA_CLASS
, NTXT ("# BinaryConstantPool: %d\n"), (int) nconst
);
789 for (int i
= 1; i
< cntConst
; i
++)
793 types
[i
] = in
.readByte ();
794 offsets
[i
] = in
.get_offset ();
795 Dprintf (DUMP_JAVA_CLASS
, NTXT (" %3d %-25s %-25s"), i
, offset_to_str (offsets
[i
]), type_name_to_str (types
[i
]));
800 u2 length
= in
.readUnsignedShort ();
802 Dprintf (DUMP_JAVA_CLASS
, " length=%u\n", (unsigned int) length
);
805 case CONSTANT_INTEGER
:
807 u4 bytes
= in
.readUnsigned ();
808 Dprintf (DUMP_JAVA_CLASS
, " bytes=0x%08x\n", (unsigned int) bytes
);
813 u4 bytes
= in
.readUnsigned ();
814 Dprintf (DUMP_JAVA_CLASS
, " bytes=0x%08x\n", (unsigned int) bytes
);
818 case CONSTANT_DOUBLE
:
820 // JVM 4.4.5: all 8-byte constants take up
821 // two entries in the constant_pool table.
826 u4 high_bytes
= in
.readUnsigned ();
827 u4 low_bytes
= in
.readUnsigned ();
828 Dprintf (DUMP_JAVA_CLASS
, NTXT (" high_bytes=0x%08x low_bytes=0x%08x\n"),
829 (unsigned int) high_bytes
, (unsigned int) low_bytes
);
834 u2 name_index
= in
.readUnsignedShort ();
835 Dprintf (DUMP_JAVA_CLASS
, NTXT (" name_index=%6u\n"), (unsigned int) name_index
);
838 case CONSTANT_STRING
:
840 u2 string_index
= in
.readUnsignedShort ();
841 Dprintf (DUMP_JAVA_CLASS
, NTXT (" string_index=%4u\n"), (unsigned int) string_index
);
845 case CONSTANT_METHOD
:
846 case CONSTANT_INTERFACEMETHOD
:
848 u2 class_index
= in
.readUnsignedShort ();
849 u2 name_and_type_index
= in
.readUnsignedShort ();
850 Dprintf (DUMP_JAVA_CLASS
, NTXT (" class_index=%5u name_and_type_index=%u\n"),
851 (unsigned int) class_index
, (unsigned int) name_and_type_index
);
854 case CONSTANT_NAMEANDTYPE
:
856 u2 name_index
= in
.readUnsignedShort ();
857 u2 descriptor_index
= in
.readUnsignedShort ();
858 Dprintf (DUMP_JAVA_CLASS
, " name_index=%6u descriptor_index=%u\n",
859 (unsigned int) name_index
, (unsigned int) descriptor_index
);
862 case CONSTANT_METHODHANDLE
:
864 u1 reference_kind
= in
.readByte ();
865 u2 reference_index
= in
.readUnsignedShort ();
866 Dprintf (DUMP_JAVA_CLASS
, " reference_kind=%u reference_index=%u\n",
867 (unsigned int) reference_kind
, (unsigned int) reference_index
);
870 case CONSTANT_METHODTYPE
:
872 u2 descriptor_index
= in
.readUnsignedShort ();
873 Dprintf (DUMP_JAVA_CLASS
, NTXT (" descriptor_index=%u\n"),
874 (unsigned int) descriptor_index
);
877 case CONSTANT_INVOKEDYNAMIC
:
879 u2 bootstrap_method_attr_index
= in
.readUnsignedShort ();
880 u2 name_and_type_index
= in
.readUnsignedShort ();
881 Dprintf (DUMP_JAVA_CLASS
, NTXT (" bootstrap_method_attr_index=%5u name_and_type_index=%u\n"),
882 (unsigned int) bootstrap_method_attr_index
,
883 (unsigned int) name_and_type_index
);
887 Dprintf (DUMP_JAVA_CLASS
, NTXT ("\n"));
888 DataReadException
*e1
= new DataReadException (
889 dbe_sprintf (GTXT ("BinaryConstantPool[%d]: bad tag %d %s\n"),
890 i
, types
[i
], offset_to_str (offsets
[i
])));
896 BinaryConstantPool::~BinaryConstantPool ()
903 for (int i
= 0; i
< nconst
; i
++)
909 #define CASE_S(x) case x: return (char *) #x
912 BinaryConstantPool::getTypeName (int ty
)
916 CASE_S (CONSTANT_UTF8
);
917 CASE_S (CONSTANT_INTEGER
);
918 CASE_S (CONSTANT_FLOAT
);
919 CASE_S (CONSTANT_LONG
);
920 CASE_S (CONSTANT_DOUBLE
);
921 CASE_S (CONSTANT_CLASS
);
922 CASE_S (CONSTANT_STRING
);
923 CASE_S (CONSTANT_FIELD
);
924 CASE_S (CONSTANT_METHOD
);
925 CASE_S (CONSTANT_INTERFACEMETHOD
);
926 CASE_S (CONSTANT_NAMEANDTYPE
);
927 CASE_S (CONSTANT_METHODHANDLE
);
928 CASE_S (CONSTANT_METHODTYPE
);
929 CASE_S (CONSTANT_INVOKEDYNAMIC
);
930 default: return NTXT ("UNKNOWN_TYPE");
935 BinaryConstantPool::getString (int index
)
937 if (index
>= nconst
|| index
<= 0)
940 return strings
[index
];
942 input
->skip (offsets
[index
]);
943 switch (types
[index
])
946 case CONSTANT_STRING
:
947 case CONSTANT_NAMEANDTYPE
:
948 strings
[index
] = dbe_strdup (getString (input
->readUnsignedShort ()));
949 return strings
[index
];
950 case CONSTANT_METHOD
:
951 input
->readUnsignedShort (); // cl_inx
952 strings
[index
] = dbe_strdup (getString (input
->readUnsignedShort ()));
953 return strings
[index
];
959 u2 len
= input
->readUnsignedShort ();
960 strings
[index
] = (char *) malloc (len
+ 1);
961 input
->copy_bytes (strings
[index
], len
);
962 return strings
[index
];
965 ClassFile::ClassFile () : Module ()
973 lang_code
= Sp_lang_java
;
975 class_filename
= NULL
;
981 ClassFile::get_opc_name (int op
)
983 if (op
>= 0 && ((size_t) op
) < sizeof (opcNames
) / sizeof (char*))
990 return NTXT ("dead");
992 return NTXT ("label");
994 return NTXT ("Unknown op code");
999 ClassFile::openFile (const char *fname
)
1003 int fd
= open64 (fname
, O_RDONLY
);
1006 append_msg (CMSG_ERROR
, GTXT ("Cannot open file %s"), fname
);
1009 dbe_stat_t stat_buf
;
1010 if ((fstat64 (fd
, &stat_buf
) == -1) || (stat_buf
.st_size
== 0))
1013 append_msg (CMSG_ERROR
, GTXT ("Cannot read file %s"), fname
);
1016 cf_bufsz
= stat_buf
.st_size
;
1017 cf_buf
= (unsigned char *) malloc (cf_bufsz
);
1018 if (cf_bufsz
!= read_from_file (fd
, cf_buf
, cf_bufsz
))
1023 append_msg (CMSG_ERROR
, GTXT ("Cannot read file %s"), fname
);
1028 input
= new DataInputStream (cf_buf
, cf_bufsz
);
1029 u4 c_magic
= input
->readUnsigned ();
1030 if (c_magic
!= JAVA_MAGIC
)
1032 append_msg (CMSG_ERROR
, GTXT ("Not a class file: %s"), fname
);
1035 /* u2 minor = */ input
->readUnsignedShort ();
1036 /* u2 major = */ input
->readUnsignedShort ();
1040 ClassFile::~ClassFile ()
1044 free (class_filename
);
1051 convertName (char *s
)
1062 ClassFile::printConstant (StringBuilder
*sb
, int index
)
1064 u1 type
= bcpool
->getType (index
);
1067 case CONSTANT_METHOD
:
1069 char *str
= bcpool
->getString (index
);
1074 sb
->append (NTXT ("()"));
1078 case CONSTANT_CLASS
:
1080 char *str
= bcpool
->getString (index
);
1090 char *str
= bcpool
->getString (index
);
1095 case CONSTANT_STRING
:
1097 char *str
= bcpool
->getString (index
);
1108 sb
->append ((int) index
);
1114 ClassFile::printCodeSequence (StringBuilder
*sb
, uint64_t addr
, DataInputStream
*in
)
1116 int64_t offset
= in
->get_offset ();
1117 sb
->appendf (NTXT ("%08llx: "), (long long) addr
);
1118 int opcode
= in
->readByte ();
1119 if (opcode
== opc_wide
)
1121 opcode
= in
->readByte ();
1122 sb
->append (get_opc_name (opcode
));
1123 sb
->append (NTXT ("_w "));
1124 int arg
= in
->readUnsignedShort ();
1127 case opc_aload
: case opc_astore
:
1128 case opc_fload
: case opc_fstore
:
1129 case opc_iload
: case opc_istore
:
1130 case opc_lload
: case opc_lstore
:
1131 case opc_dload
: case opc_dstore
:
1138 sb
->append (in
->readUnsignedShort ());
1141 sb
->append (GTXT ("Invalid opcode"));
1147 sb
->append (get_opc_name (opcode
));
1151 case opc_aload
: case opc_astore
:
1152 case opc_fload
: case opc_fstore
:
1153 case opc_iload
: case opc_istore
:
1154 case opc_lload
: case opc_lstore
:
1155 case opc_dload
: case opc_dstore
:
1157 sb
->append (in
->readByte ());
1160 sb
->append (in
->readByte ());
1162 sb
->append (in
->readByte ());
1164 case opc_tableswitch
:
1166 int align
= (addr
+ 1) % 4; // 1 byte is a length of opc_lookupswitch
1169 in
->skip (4 - align
); // four byte boundry
1171 long default_skip
= in
->readUnsigned ();
1172 long low
= in
->readUnsigned ();
1173 long high
= in
->readUnsigned ();
1174 sb
->appendf (GTXT ("%ld to %ld: default=0x%llx"),
1175 (long) low
, (long) high
, (long long) (addr
+ default_skip
));
1176 for (long i
= low
; i
<= high
; ++i
)
1177 /* u4 i1 = */ in
->readUnsigned ();
1180 case opc_lookupswitch
:
1182 int align
= (addr
+ 1) % 4; // 1 byte is a length of opc_lookupswitch
1184 in
->skip (4 - align
); // four byte boundry
1185 u4 default_skip
= in
->readUnsigned ();
1186 u4 npairs
= in
->readUnsigned ();
1187 sb
->appendf (GTXT ("%d: default=0x%llx"), npairs
,
1188 (long long) (addr
+ default_skip
));
1189 for (int i
= 0, nints
= npairs
* 2; i
< nints
; i
+= 2)
1191 /* u4 i1 = */ in
->readUnsigned ();
1192 /* u4 i2 = */ in
->readUnsigned ();
1197 switch (in
->readByte ())
1200 sb
->append (GTXT ("int"));
1203 sb
->append (GTXT ("long"));
1206 sb
->append (GTXT ("float"));
1209 sb
->append (GTXT ("double"));
1212 sb
->append (GTXT ("char"));
1215 sb
->append (GTXT ("short"));
1218 sb
->append (GTXT ("byte"));
1221 sb
->append (GTXT ("boolean"));
1224 sb
->append (GTXT ("BOGUS TYPE"));
1229 sb
->append (GTXT ("class "));
1230 printConstant (sb
, in
->readUnsignedShort ());
1233 sb
->append (in
->readUnsignedShort ());
1236 sb
->append (in
->readByte ());
1239 printConstant (sb
, in
->readByte ());
1241 case opc_ldc_w
: case opc_ldc2_w
:
1242 case opc_instanceof
: case opc_checkcast
:
1244 case opc_putstatic
: case opc_getstatic
:
1245 case opc_putfield
: case opc_getfield
:
1246 case opc_invokevirtual
:
1247 case opc_invokespecial
:
1248 case opc_invokestatic
:
1249 printConstant (sb
, in
->readUnsignedShort ());
1251 case opc_invokeinterface
:
1253 u2 index
= in
->readUnsignedShort ();
1254 u1 count
= in
->readByte ();
1255 /* u1 zero = */ in
->readByte ();
1256 sb
->appendf (" #%u, %u) ", (unsigned int) index
, (unsigned int) count
);
1257 printConstant (sb
, index
);
1260 case opc_multianewarray
:
1262 u2 index
= in
->readUnsignedShort ();
1263 printConstant (sb
, index
);
1264 sb
->appendf (GTXT (" dim #%d "), index
);
1267 case opc_jsr
: case opc_goto
:
1268 case opc_ifeq
: case opc_ifge
: case opc_ifgt
:
1269 case opc_ifle
: case opc_iflt
: case opc_ifne
:
1270 case opc_if_icmpeq
: case opc_if_icmpne
: case opc_if_icmpge
:
1271 case opc_if_icmpgt
: case opc_if_icmple
: case opc_if_icmplt
:
1272 case opc_if_acmpeq
: case opc_if_acmpne
:
1273 case opc_ifnull
: case opc_ifnonnull
:
1274 sb
->appendf (NTXT ("0x%llx"), (long long) (addr
+ (short) in
->readUnsignedShort ()));
1278 sb
->append (addr
+ (int) in
->readUnsigned ());
1284 return in
->get_offset () - offset
;
1288 ClassFile::readAttributes (int count
)
1291 for (int ax
= 0; ax
< count
; ax
++)
1293 u2 attribute_name_index
= input
->readUnsignedShort ();
1294 u4 attribute_length
= input
->readUnsigned ();
1295 char *attribute_name
= bcpool
->getString (attribute_name_index
);
1296 if (!attribute_name
)
1298 Dprintf (DUMP_JAVA_CLASS
, NTXT ("%*c %2d: attr_name=%3d %-15s len=%4d\n"),
1299 (int) blanksCnt
, ' ', (int) (ax
+ 1),
1300 (int) attribute_name_index
, STR (attribute_name
), (int) attribute_length
);
1301 input
->skip (attribute_length
);
1305 if (strcmp (attribute_name
, NTXT ("SourceFile")) == 0)
1307 u2 sourcefile_index
= input
->readUnsignedShort ();
1308 source_name
= dbe_strdup (bcpool
->getString (sourcefile_index
));
1309 Dprintf (DUMP_JAVA_CLASS
, NTXT ("%*c %2d: attr_name=%3d %-15s len=%4d file_name=%d %s\n"),
1310 (int) blanksCnt
, ' ', (int) (ax
+ 1),
1311 (int) attribute_name_index
, STR (attribute_name
), (int) attribute_length
,
1312 (int) sourcefile_index
, STR (source_name
));
1314 else if (strcmp (attribute_name
, NTXT ("InnerClasses")) == 0)
1316 int niclasses
= input
->readUnsignedShort ();
1317 for (int ix
= 0; ix
< niclasses
; ix
++)
1319 u2 inner_class_info_index
= input
->readUnsignedShort ();
1320 u2 outer_class_info_index
= input
->readUnsignedShort ();
1321 u2 inner_name_index
= input
->readUnsignedShort ();
1322 u2 inner_class_access_flags
= input
->readUnsignedShort ();
1323 Dprintf (DUMP_JAVA_CLASS
,
1324 NTXT ("%*c %2d: attr_name=%3d %-15s len=%4d name=%d '%s'\n"
1325 "%*cinner_class_info_index=%d outer_class_info_index=%d flags=%s\n"),
1326 (int) blanksCnt
, ' ', (int) (ax
+ 1),
1327 (int) attribute_name_index
, STR (attribute_name
), (int) attribute_length
,
1328 (int) inner_name_index
, STR (bcpool
->getString (inner_name_index
)),
1329 (int) (blanksCnt
+ 10), ' ',
1330 (int) inner_class_info_index
, (int) outer_class_info_index
,
1331 access_flags_to_str (NestedClassAccess
, inner_class_access_flags
));
1334 else if (strcmp (attribute_name
, NTXT ("Code")) == 0)
1336 u2 max_stack
= input
->readUnsignedShort ();
1337 u2 max_locals
= input
->readUnsignedShort ();
1338 u4 code_length
= input
->readUnsigned ();
1341 cur_jmthd
->size
= code_length
;
1342 cur_jmthd
->img_fname
= dbeFile
->get_location ();
1343 cur_jmthd
->img_offset
= input
->get_offset ();
1345 input
->skip (code_length
);
1346 u2 exception_table_length
= input
->readUnsignedShort ();
1347 input
->skip (exception_table_length
* (2 + 2 + 2 + 2));
1348 Dprintf (DUMP_JAVA_CLASS
,
1349 NTXT ("%*c %2d: attr_name=%3d %-15s len=%4d max_stack=%d max_locals=%d code_length=%d exception_table_length=%d\n"),
1350 (int) blanksCnt
, ' ', (int) (ax
+ 1),
1351 (int) attribute_name_index
, STR (attribute_name
), (int) attribute_length
,
1352 (int) max_stack
, (int) max_locals
, (int) code_length
, (int) exception_table_length
);
1353 readAttributes (input
->readUnsignedShort ());
1355 else if (strcmp (attribute_name
, NTXT ("LineNumberTable")) == 0)
1357 int nlines
= input
->readUnsignedShort ();
1358 Dprintf (DUMP_JAVA_CLASS
, NTXT ("%*c %2d: attr_name=%3d %-15s len=%4d nlines=%d\n"),
1359 (int) blanksCnt
, ' ', (int) (ax
+ 1),
1360 (int) attribute_name_index
, STR (attribute_name
), (int) attribute_length
,
1362 for (int lx
= 0; lx
< nlines
; lx
++)
1364 int bci
= input
->readUnsignedShort ();
1365 int lno
= input
->readUnsignedShort ();
1366 Dprintf (DUMP_JAVA_CLASS
, NTXT ("%*c %3d: pc=%4d (0x%04x) line=%d\n"),
1367 (int) (blanksCnt
+ 5), ' ', (int) (lx
+ 1), (int) bci
, (int) bci
, (int) lno
);
1369 byteCodeInfo
->append (new ByteCodeInfo (cur_jmthd
, bci
, lno
));
1374 Dprintf (DUMP_JAVA_CLASS
, NTXT ("%*c %2d: attr_name=%3d %-15s len=%4d\n"),
1375 (int) blanksCnt
, ' ', (int) (ax
+ 1),
1376 (int) attribute_name_index
, STR (attribute_name
),
1377 (int) attribute_length
);
1378 input
->skip (attribute_length
);
1385 ClassFile::readFile ()
1387 if (status
!= AE_NOTREAD
)
1391 // The ClassFile Structure http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
1396 char *fname
= dbeFile
->get_location ();
1398 Dprintf (DUMP_JAVA_CLASS
, NTXT ("\nClassFile::readFile status=%d %s location=%s\n"),
1399 (unsigned int) status
, STR (get_name ()), STR (fname
));
1400 if (status
!= AE_OK
)
1402 byteCodeInfo
= new Vector
<ByteCodeInfo
*>(512);
1403 bcpool
= new BinaryConstantPool (*input
);
1404 u2 access_flags
= input
->readUnsignedShort ();
1405 Dprintf (DUMP_JAVA_CLASS
, NTXT ("\naccess_flags=%s; %s\n"),
1406 access_flags_to_str (ClassAccess
, access_flags
),
1407 STR (dbeFile
->get_name ()));
1408 u2 classNameInd
= input
->readUnsignedShort ();
1409 class_filename
= dbe_strdup (bcpool
->getString (classNameInd
));
1412 class_name
= strdup (class_filename
);
1413 convertName (class_name
);
1416 // Get superclass name
1417 u2 superClassInd
= input
->readUnsignedShort ();
1418 //char *str = bcpool->getString(superClassInd);
1419 //super_name = str ? convertName( str ) : NULL;
1422 int interfaces_count
= input
->readUnsignedShort ();
1423 Dprintf (DUMP_JAVA_CLASS
,
1424 NTXT (" class_name=%3d %-20s superClass=%3d %s interfaces_count=%d\n"),
1425 (int) classNameInd
, STR (class_name
),
1426 (int) superClassInd
, STR (bcpool
->getString (superClassInd
)),
1427 (int) interfaces_count
);
1428 for (int i
= 0; i
< interfaces_count
; i
++)
1430 u2 index
= input
->readUnsignedShort ();
1431 Dprintf (DUMP_JAVA_CLASS
, NTXT (" %6lld%s"), (long long) index
,
1432 (i
% 8 == 7) || (i
+ 1 == interfaces_count
) ? "\n" : "");
1436 int fields_count
= input
->readUnsignedShort ();
1437 Dprintf (DUMP_JAVA_CLASS
, NTXT (" fields_count=%d\n"), fields_count
);
1438 for (int i
= 0; i
< fields_count
; i
++)
1440 u2 fld_access_flags
= input
->readUnsignedShort ();
1441 u2 name_index
= input
->readUnsignedShort ();
1442 u2 descriptor_index
= input
->readUnsignedShort ();
1443 u2 attributes_count
= input
->readUnsignedShort ();
1444 Dprintf (DUMP_JAVA_CLASS
,
1445 NTXT (" %2d: name=%3d %-20s flags=%s; desc_ind=%d attr_count=%d\n"),
1446 i
, (int) name_index
, STR (bcpool
->getString (name_index
)),
1447 access_flags_to_str (FieldAccess
, fld_access_flags
),
1448 (int) descriptor_index
, (int) attributes_count
);
1449 readAttributes (attributes_count
);
1453 int methods_count
= input
->readUnsignedShort ();
1454 Dprintf (DUMP_JAVA_CLASS
, NTXT ("\n methods_count=%d\n"), (int) methods_count
);
1455 int func_cnt
= functions
->size ();
1456 for (int i
= 0; i
< methods_count
; i
++)
1458 u2 mthd_access_flags
= input
->readUnsignedShort ();
1459 u2 name_index
= input
->readUnsignedShort ();
1460 u2 descriptor_index
= input
->readUnsignedShort ();
1461 char *mname
= bcpool
->getString (name_index
);
1464 DataReadException
*e1
= new DataReadException (dbe_sprintf (GTXT ("method name[%d] is NULL\n"), i
));
1467 char *msign
= bcpool
->getString (descriptor_index
);
1470 DataReadException
*e1
= new DataReadException (dbe_sprintf (GTXT ("method signature[%d] is NULL\n"), i
));
1473 size_t len
= strlen (class_name
);
1475 for (int idx
= 0; idx
< func_cnt
; idx
++)
1477 JMethod
*jmthd
= (JMethod
*) functions
->fetch (idx
);
1478 char *jmt_name
= jmthd
->get_name (Histable::SHORT
);
1479 if (strncmp (jmt_name
, class_name
, len
) == 0)
1481 if (strcmp (jmt_name
+ len
+ 1, mname
) == 0 &&
1482 strcmp (jmthd
->get_signature (), msign
) == 0)
1489 if (cur_jmthd
== NULL
)
1491 cur_jmthd
= dbeSession
->createJMethod ();
1492 cur_jmthd
->module
= this;
1493 cur_jmthd
->set_signature (dbe_strdup (msign
));
1494 char *nm
= dbe_sprintf (NTXT ("%s.%s"), class_name
, mname
);
1495 cur_jmthd
->set_name (nm
);
1497 functions
->append (cur_jmthd
);
1499 if ((mthd_access_flags
& ACC_NATIVE
) != 0)
1501 cur_jmthd
->flags
|= FUNC_FLAG_NATIVE
;
1503 u2 attributes_count
= input
->readUnsignedShort ();
1504 Dprintf (DUMP_JAVA_CLASS
,
1505 NTXT (" %2d: name=%d %-20s flags=%s desc_ind=%d attr_count=%d\n"),
1506 (int) (i
+ 1), (int) name_index
, STR (bcpool
->getString (name_index
)),
1507 access_flags_to_str (MethodAccess
, mthd_access_flags
),
1508 (int) descriptor_index
, (int) attributes_count
);
1509 readAttributes (attributes_count
);
1510 cur_jmthd
->popSrcFile ();
1513 // Read global attributes
1514 u2 global_attributes_count
= input
->readUnsignedShort ();
1515 Dprintf (DUMP_JAVA_CLASS
, NTXT (" global_attributes_count=%d\n"), global_attributes_count
);
1516 readAttributes (global_attributes_count
);
1519 catch (DataReadException
*ex
)
1521 append_msg (CMSG_ERROR
, GTXT ("Cannot read class file %s (%s)"), get_name (), ex
->toString ());
1529 if (strcmp (class_filename
, get_name ()) != 0)
1530 set_name (strdup (class_filename
));
1533 char *bname
= strrchr (class_filename
, '/');
1535 fnm
= dbe_sprintf (NTXT ("%.*s/%s"), (int) (bname
- class_filename
),
1536 class_filename
, source_name
);
1538 fnm
= strdup (source_name
);
1541 fnm
= get_java_file_name (class_filename
, false);
1543 else if (source_name
)
1544 fnm
= strdup (source_name
);
1547 set_file_name (fnm
);
1548 main_source
= findSource (file_name
, true);
1549 main_source
->dbeFile
->filetype
|= DbeFile::F_JAVA_SOURCE
;
1552 for (long i
= 0, sz
= VecSize (functions
); i
< sz
; i
++)
1553 functions
->get (i
)->def_source
= main_source
;
1554 JMethod
*func
= NULL
;
1555 for (long i
= 0, sz
= VecSize (byteCodeInfo
); i
< sz
; i
++)
1557 ByteCodeInfo
*p
= byteCodeInfo
->get (i
);
1558 if (func
!= p
->func
)
1561 func
->popSrcFile ();
1563 func
->line_first
= p
->lno
;
1564 func
->pushSrcFile (main_source
, 0);
1566 func
->line_last
= p
->lno
;
1567 func
->add_PC_info (p
->bci
, p
->lno
, main_source
);
1570 func
->popSrcFile ();
1571 Destroy (byteCodeInfo
);
1572 Dprintf (DUMP_JAVA_CLASS
, NTXT ("\n status=%d class_filename=%s class_name=%s source_name=%s file_name=%s %s\n"),
1573 (unsigned int) status
, STR (class_filename
), STR (class_name
),
1574 STR (source_name
), STR (file_name
),
1579 #define MAX_CLASS_SIZE 65536
1582 ClassFile::get_disasm (uint64_t inst_address
, uint64_t end_address
,
1583 uint64_t start_address
, uint64_t f_offset
, int64_t &inst_size
)
1585 int64_t offset
= f_offset
+ (inst_address
- start_address
);
1586 if ((cf_buf
== NULL
) || (inst_address
>= end_address
) || (offset
>= cf_bufsz
))
1592 // Check for an implausibly large size
1593 if ((inst_address
- start_address
) > MAX_CLASS_SIZE
)
1595 append_msg (CMSG_ERROR
, GTXT ("Cannot disassemble class file %s (%s), implausible size = %lld"),
1596 get_name (), dbeFile
->get_location (),
1597 (long long) (end_address
- start_address
));
1603 DataInputStream
*in
= new DataInputStream (input
);
1607 inst_size
= printCodeSequence (&sb
, inst_address
- start_address
, in
);
1609 catch (DataReadException
*ex
)
1611 append_msg (CMSG_ERROR
, GTXT ("Cannot disassemble class file %s (%s) %s"),
1612 get_name (), dbeFile
->get_location (), ex
->toString ());
1619 return sb
.toString ();
1623 ClassFile::get_java_file_name (char *clname
, bool classSuffix
)
1625 size_t len
= strlen (clname
);
1626 if (len
> 6 && streq (clname
+ len
- 6, NTXT (".class")))
1629 { // remove $SubClassName from "ClassName$SubClassName"
1630 char *tmp
= strchr (clname
, '$');
1634 char *clpath
= (char *) malloc (len
+ 10);
1635 for (size_t i
= 0; i
< len
; i
++)
1636 clpath
[i
] = (clname
[i
] == '.') ? '/' : clname
[i
];
1637 snprintf (clpath
+ len
, 10, classSuffix
? NTXT (".class") : NTXT (".java"));