xref: /netbsd-src/external/gpl3/binutils.old/dist/gprofng/src/ClassFile.cc (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2    Contributed by Oracle.
3 
4    This file is part of GNU Binutils.
5 
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)
9    any later version.
10 
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.
15 
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.  */
20 
21 #include "config.h"
22 #include <fcntl.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 
28 #include "util.h"
29 #include "DbeSession.h"
30 #include "ClassFile.h"
31 #include "Function.h"
32 #include "StringBuilder.h"
33 #include "DbeFile.h"
34 
35 class ByteCodeInfo
36 {
37 public:
38 
ByteCodeInfo(JMethod * _func,int _bci,int _lno)39   ByteCodeInfo (JMethod *_func, int _bci, int _lno)
40   {
41     func = _func;
42     bci = _bci;
43     lno = _lno;
44   };
45 
46   JMethod *func;
47   int bci;
48   int lno;
49 };
50 
51 typedef unsigned char u1;
52 typedef unsigned short u2;
53 typedef unsigned int u4;
54 
55 // Class File Constants
56 #define JAVA_MAGIC        0xcafebabe
57 
58 enum {
59   // First argument in access_flags_to_str()
60   ClassAccess = 1,
61   FieldAccess,
62   MethodAccess,
63   NestedClassAccess,
64 
65   // jdk/src/share/classes/sun/tools/java/RuntimeConstants.java
66   // Type codes
67   T_CLASS             = 0x00000002,
68   T_BOOLEAN           = 0x00000004,
69   T_CHAR              = 0x00000005,
70   T_FLOAT             = 0x00000006,
71   T_DOUBLE            = 0x00000007,
72   T_BYTE              = 0x00000008,
73   T_SHORT             = 0x00000009,
74   T_INT               = 0x0000000a,
75   T_LONG              = 0x0000000b,
76 
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,
93 
94   ACC_SUPER           = 0x00000020,
95   ACC_BRIDGE          = 0x00000040,
96   ACC_VARARGS         = 0x00000080,
97 
98 // Opcodes
99   opc_try             = -3,
100   opc_dead            = -2,
101   opc_label           = -1,
102   opc_nop             = 0,
103   opc_aconst_null     = 1,
104   opc_iconst_m1       = 2,
105   opc_iconst_0        = 3,
106   opc_iconst_1        = 4,
107   opc_iconst_2        = 5,
108   opc_iconst_3        = 6,
109   opc_iconst_4        = 7,
110   opc_iconst_5        = 8,
111   opc_lconst_0        = 9,
112   opc_lconst_1        = 10,
113   opc_fconst_0        = 11,
114   opc_fconst_1        = 12,
115   opc_fconst_2        = 13,
116   opc_dconst_0        = 14,
117   opc_dconst_1        = 15,
118   opc_bipush          = 16,
119   opc_sipush          = 17,
120   opc_ldc             = 18,
121   opc_ldc_w           = 19,
122   opc_ldc2_w          = 20,
123   opc_iload           = 21,
124   opc_lload           = 22,
125   opc_fload           = 23,
126   opc_dload           = 24,
127   opc_aload           = 25,
128   opc_iload_0         = 26,
129   opc_iload_1         = 27,
130   opc_iload_2         = 28,
131   opc_iload_3         = 29,
132   opc_lload_0         = 30,
133   opc_lload_1         = 31,
134   opc_lload_2         = 32,
135   opc_lload_3         = 33,
136   opc_fload_0         = 34,
137   opc_fload_1         = 35,
138   opc_fload_2         = 36,
139   opc_fload_3         = 37,
140   opc_dload_0         = 38,
141   opc_dload_1         = 39,
142   opc_dload_2         = 40,
143   opc_dload_3         = 41,
144   opc_aload_0         = 42,
145   opc_aload_1         = 43,
146   opc_aload_2         = 44,
147   opc_aload_3         = 45,
148   opc_iaload          = 46,
149   opc_laload          = 47,
150   opc_faload          = 48,
151   opc_daload          = 49,
152   opc_aaload          = 50,
153   opc_baload          = 51,
154   opc_caload          = 52,
155   opc_saload          = 53,
156   opc_istore          = 54,
157   opc_lstore          = 55,
158   opc_fstore          = 56,
159   opc_dstore          = 57,
160   opc_astore          = 58,
161   opc_istore_0        = 59,
162   opc_istore_1        = 60,
163   opc_istore_2        = 61,
164   opc_istore_3        = 62,
165   opc_lstore_0        = 63,
166   opc_lstore_1        = 64,
167   opc_lstore_2        = 65,
168   opc_lstore_3        = 66,
169   opc_fstore_0        = 67,
170   opc_fstore_1        = 68,
171   opc_fstore_2        = 69,
172   opc_fstore_3        = 70,
173   opc_dstore_0        = 71,
174   opc_dstore_1        = 72,
175   opc_dstore_2        = 73,
176   opc_dstore_3        = 74,
177   opc_astore_0        = 75,
178   opc_astore_1        = 76,
179   opc_astore_2        = 77,
180   opc_astore_3        = 78,
181   opc_iastore         = 79,
182   opc_lastore         = 80,
183   opc_fastore         = 81,
184   opc_dastore         = 82,
185   opc_aastore         = 83,
186   opc_bastore         = 84,
187   opc_castore         = 85,
188   opc_sastore         = 86,
189   opc_pop             = 87,
190   opc_pop2            = 88,
191   opc_dup             = 89,
192   opc_dup_x1          = 90,
193   opc_dup_x2          = 91,
194   opc_dup2            = 92,
195   opc_dup2_x1         = 93,
196   opc_dup2_x2         = 94,
197   opc_swap            = 95,
198   opc_iadd            = 96,
199   opc_ladd            = 97,
200   opc_fadd            = 98,
201   opc_dadd            = 99,
202   opc_isub            = 100,
203   opc_lsub            = 101,
204   opc_fsub            = 102,
205   opc_dsub            = 103,
206   opc_imul            = 104,
207   opc_lmul            = 105,
208   opc_fmul            = 106,
209   opc_dmul            = 107,
210   opc_idiv            = 108,
211   opc_ldiv            = 109,
212   opc_fdiv            = 110,
213   opc_ddiv            = 111,
214   opc_irem            = 112,
215   opc_lrem            = 113,
216   opc_frem            = 114,
217   opc_drem            = 115,
218   opc_ineg            = 116,
219   opc_lneg            = 117,
220   opc_fneg            = 118,
221   opc_dneg            = 119,
222   opc_ishl            = 120,
223   opc_lshl            = 121,
224   opc_ishr            = 122,
225   opc_lshr            = 123,
226   opc_iushr           = 124,
227   opc_lushr           = 125,
228   opc_iand            = 126,
229   opc_land            = 127,
230   opc_ior             = 128,
231   opc_lor             = 129,
232   opc_ixor            = 130,
233   opc_lxor            = 131,
234   opc_iinc            = 132,
235   opc_i2l             = 133,
236   opc_i2f             = 134,
237   opc_i2d             = 135,
238   opc_l2i             = 136,
239   opc_l2f             = 137,
240   opc_l2d             = 138,
241   opc_f2i             = 139,
242   opc_f2l             = 140,
243   opc_f2d             = 141,
244   opc_d2i             = 142,
245   opc_d2l             = 143,
246   opc_d2f             = 144,
247   opc_i2b             = 145,
248   opc_i2c             = 146,
249   opc_i2s             = 147,
250   opc_lcmp            = 148,
251   opc_fcmpl           = 149,
252   opc_fcmpg           = 150,
253   opc_dcmpl           = 151,
254   opc_dcmpg           = 152,
255   opc_ifeq            = 153,
256   opc_ifne            = 154,
257   opc_iflt            = 155,
258   opc_ifge            = 156,
259   opc_ifgt            = 157,
260   opc_ifle            = 158,
261   opc_if_icmpeq       = 159,
262   opc_if_icmpne       = 160,
263   opc_if_icmplt       = 161,
264   opc_if_icmpge       = 162,
265   opc_if_icmpgt       = 163,
266   opc_if_icmple       = 164,
267   opc_if_acmpeq       = 165,
268   opc_if_acmpne       = 166,
269   opc_goto            = 167,
270   opc_jsr             = 168,
271   opc_ret             = 169,
272   opc_tableswitch     = 170,
273   opc_lookupswitch    = 171,
274   opc_ireturn         = 172,
275   opc_lreturn         = 173,
276   opc_freturn         = 174,
277   opc_dreturn         = 175,
278   opc_areturn         = 176,
279   opc_return          = 177,
280   opc_getstatic       = 178,
281   opc_putstatic       = 179,
282   opc_getfield        = 180,
283   opc_putfield        = 181,
284   opc_invokevirtual   = 182,
285   opc_invokespecial   = 183,
286   opc_invokestatic    = 184,
287   opc_invokeinterface = 185,
288   opc_invokedynamic   = 186,
289   opc_new             = 187,
290   opc_newarray        = 188,
291   opc_anewarray       = 189,
292   opc_arraylength     = 190,
293   opc_athrow          = 191,
294   opc_checkcast       = 192,
295   opc_instanceof      = 193,
296   opc_monitorenter    = 194,
297   opc_monitorexit     = 195,
298   opc_wide            = 196,
299   opc_multianewarray  = 197,
300   opc_ifnull          = 198,
301   opc_ifnonnull       = 199,
302   opc_goto_w          = 200,
303   opc_jsr_w           = 201,
304   opc_breakpoint      = 202,
305 
306 // Constant table
307   CONSTANT_UTF8       = 1,
308   CONSTANT_UNICODE    = 2,
309   CONSTANT_INTEGER    = 3,
310   CONSTANT_FLOAT      = 4,
311   CONSTANT_LONG       = 5,
312   CONSTANT_DOUBLE     = 6,
313   CONSTANT_CLASS      = 7,
314   CONSTANT_STRING     = 8,
315   CONSTANT_FIELD      = 9,
316   CONSTANT_METHOD     = 10,
317   CONSTANT_INTERFACEMETHOD = 11,
318   CONSTANT_NAMEANDTYPE    = 12,
319   CONSTANT_METHODHANDLE   = 15,
320   CONSTANT_METHODTYPE     = 16,
321   CONSTANT_INVOKEDYNAMIC  = 18
322 };
323 
324 static char *opcNames[] = {
325   NTXT ("nop"),
326   NTXT ("aconst_null"),
327   NTXT ("iconst_m1"),
328   NTXT ("iconst_0"),
329   NTXT ("iconst_1"),
330   NTXT ("iconst_2"),
331   NTXT ("iconst_3"),
332   NTXT ("iconst_4"),
333   NTXT ("iconst_5"),
334   NTXT ("lconst_0"),
335   NTXT ("lconst_1"),
336   NTXT ("fconst_0"),
337   NTXT ("fconst_1"),
338   NTXT ("fconst_2"),
339   NTXT ("dconst_0"),
340   NTXT ("dconst_1"),
341   NTXT ("bipush"),
342   NTXT ("sipush"),
343   NTXT ("ldc"),
344   NTXT ("ldc_w"),
345   NTXT ("ldc2_w"),
346   NTXT ("iload"),
347   NTXT ("lload"),
348   NTXT ("fload"),
349   NTXT ("dload"),
350   NTXT ("aload"),
351   NTXT ("iload_0"),
352   NTXT ("iload_1"),
353   NTXT ("iload_2"),
354   NTXT ("iload_3"),
355   NTXT ("lload_0"),
356   NTXT ("lload_1"),
357   NTXT ("lload_2"),
358   NTXT ("lload_3"),
359   NTXT ("fload_0"),
360   NTXT ("fload_1"),
361   NTXT ("fload_2"),
362   NTXT ("fload_3"),
363   NTXT ("dload_0"),
364   NTXT ("dload_1"),
365   NTXT ("dload_2"),
366   NTXT ("dload_3"),
367   NTXT ("aload_0"),
368   NTXT ("aload_1"),
369   NTXT ("aload_2"),
370   NTXT ("aload_3"),
371   NTXT ("iaload"),
372   NTXT ("laload"),
373   NTXT ("faload"),
374   NTXT ("daload"),
375   NTXT ("aaload"),
376   NTXT ("baload"),
377   NTXT ("caload"),
378   NTXT ("saload"),
379   NTXT ("istore"),
380   NTXT ("lstore"),
381   NTXT ("fstore"),
382   NTXT ("dstore"),
383   NTXT ("astore"),
384   NTXT ("istore_0"),
385   NTXT ("istore_1"),
386   NTXT ("istore_2"),
387   NTXT ("istore_3"),
388   NTXT ("lstore_0"),
389   NTXT ("lstore_1"),
390   NTXT ("lstore_2"),
391   NTXT ("lstore_3"),
392   NTXT ("fstore_0"),
393   NTXT ("fstore_1"),
394   NTXT ("fstore_2"),
395   NTXT ("fstore_3"),
396   NTXT ("dstore_0"),
397   NTXT ("dstore_1"),
398   NTXT ("dstore_2"),
399   NTXT ("dstore_3"),
400   NTXT ("astore_0"),
401   NTXT ("astore_1"),
402   NTXT ("astore_2"),
403   NTXT ("astore_3"),
404   NTXT ("iastore"),
405   NTXT ("lastore"),
406   NTXT ("fastore"),
407   NTXT ("dastore"),
408   NTXT ("aastore"),
409   NTXT ("bastore"),
410   NTXT ("castore"),
411   NTXT ("sastore"),
412   NTXT ("pop"),
413   NTXT ("pop2"),
414   NTXT ("dup"),
415   NTXT ("dup_x1"),
416   NTXT ("dup_x2"),
417   NTXT ("dup2"),
418   NTXT ("dup2_x1"),
419   NTXT ("dup2_x2"),
420   NTXT ("swap"),
421   NTXT ("iadd"),
422   NTXT ("ladd"),
423   NTXT ("fadd"),
424   NTXT ("dadd"),
425   NTXT ("isub"),
426   NTXT ("lsub"),
427   NTXT ("fsub"),
428   NTXT ("dsub"),
429   NTXT ("imul"),
430   NTXT ("lmul"),
431   NTXT ("fmul"),
432   NTXT ("dmul"),
433   NTXT ("idiv"),
434   NTXT ("ldiv"),
435   NTXT ("fdiv"),
436   NTXT ("ddiv"),
437   NTXT ("irem"),
438   NTXT ("lrem"),
439   NTXT ("frem"),
440   NTXT ("drem"),
441   NTXT ("ineg"),
442   NTXT ("lneg"),
443   NTXT ("fneg"),
444   NTXT ("dneg"),
445   NTXT ("ishl"),
446   NTXT ("lshl"),
447   NTXT ("ishr"),
448   NTXT ("lshr"),
449   NTXT ("iushr"),
450   NTXT ("lushr"),
451   NTXT ("iand"),
452   NTXT ("land"),
453   NTXT ("ior"),
454   NTXT ("lor"),
455   NTXT ("ixor"),
456   NTXT ("lxor"),
457   NTXT ("iinc"),
458   NTXT ("i2l"),
459   NTXT ("i2f"),
460   NTXT ("i2d"),
461   NTXT ("l2i"),
462   NTXT ("l2f"),
463   NTXT ("l2d"),
464   NTXT ("f2i"),
465   NTXT ("f2l"),
466   NTXT ("f2d"),
467   NTXT ("d2i"),
468   NTXT ("d2l"),
469   NTXT ("d2f"),
470   NTXT ("i2b"),
471   NTXT ("i2c"),
472   NTXT ("i2s"),
473   NTXT ("lcmp"),
474   NTXT ("fcmpl"),
475   NTXT ("fcmpg"),
476   NTXT ("dcmpl"),
477   NTXT ("dcmpg"),
478   NTXT ("ifeq"),
479   NTXT ("ifne"),
480   NTXT ("iflt"),
481   NTXT ("ifge"),
482   NTXT ("ifgt"),
483   NTXT ("ifle"),
484   NTXT ("if_icmpeq"),
485   NTXT ("if_icmpne"),
486   NTXT ("if_icmplt"),
487   NTXT ("if_icmpge"),
488   NTXT ("if_icmpgt"),
489   NTXT ("if_icmple"),
490   NTXT ("if_acmpeq"),
491   NTXT ("if_acmpne"),
492   NTXT ("goto"),
493   NTXT ("jsr"),
494   NTXT ("ret"),
495   NTXT ("tableswitch"),
496   NTXT ("lookupswitch"),
497   NTXT ("ireturn"),
498   NTXT ("lreturn"),
499   NTXT ("freturn"),
500   NTXT ("dreturn"),
501   NTXT ("areturn"),
502   NTXT ("return"),
503   NTXT ("getstatic"),
504   NTXT ("putstatic"),
505   NTXT ("getfield"),
506   NTXT ("putfield"),
507   NTXT ("invokevirtual"),
508   NTXT ("invokespecial"),
509   NTXT ("invokestatic"),
510   NTXT ("invokeinterface"),
511   NTXT ("invokedynamic"),
512   NTXT ("new"),
513   NTXT ("newarray"),
514   NTXT ("anewarray"),
515   NTXT ("arraylength"),
516   NTXT ("athrow"),
517   NTXT ("checkcast"),
518   NTXT ("instanceof"),
519   NTXT ("monitorenter"),
520   NTXT ("monitorexit"),
521   NTXT ("wide"),
522   NTXT ("multianewarray"),
523   NTXT ("ifnull"),
524   NTXT ("ifnonnull"),
525   NTXT ("goto_w"),
526   NTXT ("jsr_w"),
527   NTXT ("breakpoint")
528 };
529 
530 
531 #define APPEND_FLAG(len, buf, flag, x) \
532     if (((x) & (flag)) != 0) \
533       { \
534 	flag &= ~(x); \
535 	AppendString(len, buf, NTXT("%s%s"), delimiter, #x); \
536 	delimiter = NTXT("|"); \
537       }
538 
539 static char *
access_flags_to_str(int kind,int flag)540 access_flags_to_str (int kind, int flag)
541 {
542   static char buf[256];
543   size_t len = 0;
544   buf[0] = 0;
545   if (flag == 0)
546     {
547       AppendString (len, buf, NTXT ("0x%x"), (unsigned int) flag);
548       return buf;
549     }
550   const char *delimiter = "";
551   if (kind == ClassAccess)
552     {
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);
560       if (flag)
561 	AppendString (len, buf, "%s0x%x", delimiter, (unsigned int) (flag));
562     }
563   else if (kind == FieldAccess)
564     {
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);
574       if (flag)
575 	AppendString (len, buf, "%s0x%x", delimiter, (unsigned int) (flag));
576     }
577   else if (kind == MethodAccess)
578     {
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);
591       if (flag)
592 	AppendString (len, buf, "%s0x%x", delimiter, (unsigned int) (flag));
593     }
594   else if (kind == NestedClassAccess)
595     {
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);
606       if (flag)
607 	AppendString (len, buf, "%s0x%x", delimiter, (unsigned int) (flag));
608     }
609   return buf;
610 }
611 
612 class DataReadException
613 {
614 public:
615 
DataReadException(char * s)616   DataReadException (char *s)
617   {
618     str_err = s;
619   }
620 
~DataReadException()621   ~DataReadException ()
622   {
623     free (str_err);
624   }
625 
626   char *
toString()627   toString ()
628   {
629     return str_err;
630   }
631 
632 private:
633   char *str_err;
634 };
635 
636 class DataInputStream
637 {
638 public:
639 
DataInputStream(const unsigned char * bytes,int64_t sz)640   DataInputStream (const unsigned char *bytes, int64_t sz)
641   {
642     bp = bp_orig = bytes;
643     bp_last = bp_orig + sz;
644   }
645 
DataInputStream(DataInputStream * in)646   DataInputStream (DataInputStream *in)
647   {
648     bp = bp_orig = in->bp_orig;
649     bp_last = in->bp_last;
650   }
651 
652   u1
readByte()653   readByte ()
654   {
655     check (1);
656     u1 val = *bp;
657     bp++;
658     return val;
659   }
660 
661   u2
readUnsignedShort()662   readUnsignedShort ()
663   {
664     check (2);
665     u2 val = (bp[0] << 8) | bp[1];
666     bp += 2;
667     return val;
668   }
669 
670   u4
readUnsigned()671   readUnsigned ()
672   {
673     check (4);
674     u4 val = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3];
675     bp += 4;
676     return val;
677   }
678 
679   const u1 *
getptr()680   getptr ()
681   {
682     return bp;
683   }
684 
685   const size_t
get_offset()686   get_offset ()
687   {
688     return bp - bp_orig;
689   }
690 
691   void
skip(int n)692   skip (int n)
693   {
694     check (n);
695     bp += n;
696   }
697 
698   void
reset()699   reset ()
700   {
701     bp = bp_orig;
702   }
703 
704   void
copy_bytes(char * buf,int64_t len)705   copy_bytes (char *buf, int64_t len)
706   {
707     check (len);
708     memcpy (buf, bp, len);
709     buf[len] = '\0';
710   }
711 
712 private:
713 
714   void
check(int64_t sz)715   check (int64_t sz)
716   {
717     if (sz < 0 || bp + sz > bp_last)
718       {
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 ()));
722 	throw (e1);
723       }
724   };
725 
726   const unsigned char *bp_last;
727   const unsigned char *bp_orig;
728   const unsigned char *bp;
729 };
730 
731 class BinaryConstantPool
732 {
733 public:
734   BinaryConstantPool (DataInputStream &in);
735   ~BinaryConstantPool ();
736 
737   u1
getType(int n)738   getType (int n)
739   {
740     return (n < nconst && n > 0) ? types[n] : 0;
741   };
742   char *getString (int index);
743 
744 private:
745   static char *getTypeName (int ty);
746   static char *type_name_to_str (int ty);
747   static char *offset_to_str (long long offset);
748   int nconst;
749   u1 *types;
750   int64_t *offsets;
751   char **strings;
752   DataInputStream *input;
753 };
754 
755 char *
type_name_to_str(int ty)756 BinaryConstantPool::type_name_to_str (int ty)
757 {
758   static char buf[128];
759   char *tyName = getTypeName (ty);
760   snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), tyName, ty);
761   return buf;
762 }
763 
764 char *
offset_to_str(long long offset)765 BinaryConstantPool::offset_to_str (long long offset)
766 {
767   static char buf[128];
768   snprintf (buf, sizeof (buf), NTXT ("offset=0x%06llx (%llu)"), offset, offset);
769   return buf;
770 }
771 
BinaryConstantPool(DataInputStream & in)772 BinaryConstantPool::BinaryConstantPool (DataInputStream &in)
773 {
774   nconst = 0;
775   types = NULL;
776   offsets = NULL;
777   strings = NULL;
778   input = new DataInputStream (in);
779   int cntConst = in.readUnsignedShort ();
780   if (cntConst > 0)
781     {
782       types = new u1[cntConst];
783       types[0] = 0;
784       offsets = new int64_t [cntConst];
785       strings = new char * [cntConst];
786       strings[0] = NULL;
787     }
788   Dprintf (DUMP_JAVA_CLASS, NTXT ("# BinaryConstantPool: %d\n"), (int) nconst);
789   for (int i = 1; i < cntConst; i++)
790     {
791       nconst = i + 1;
792       strings[i] = NULL;
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]));
796       switch (types[i])
797 	{
798 	case CONSTANT_UTF8:
799 	  {
800 	    u2 length = in.readUnsignedShort ();
801 	    in.skip (length);
802 	    Dprintf (DUMP_JAVA_CLASS, " length=%u\n", (unsigned int) length);
803 	    break;
804 	  }
805 	case CONSTANT_INTEGER:
806 	  {
807 	    u4 bytes = in.readUnsigned ();
808 	    Dprintf (DUMP_JAVA_CLASS, " bytes=0x%08x\n", (unsigned int) bytes);
809 	    break;
810 	  }
811 	case CONSTANT_FLOAT:
812 	  {
813 	    u4 bytes = in.readUnsigned ();
814 	    Dprintf (DUMP_JAVA_CLASS, " bytes=0x%08x\n", (unsigned int) bytes);
815 	    break;
816 	  }
817 	case CONSTANT_LONG:
818 	case CONSTANT_DOUBLE:
819 	  {
820 	    // JVM 4.4.5: all 8-byte constants take up
821 	    // two entries in the constant_pool table.
822 	    i++;
823 	    nconst++;
824 	    offsets[i] = 0;
825 	    strings[i] = NULL;
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);
830 	    break;
831 	  }
832 	case CONSTANT_CLASS:
833 	  {
834 	    u2 name_index = in.readUnsignedShort ();
835 	    Dprintf (DUMP_JAVA_CLASS, NTXT (" name_index=%6u\n"), (unsigned int) name_index);
836 	    break;
837 	  }
838 	case CONSTANT_STRING:
839 	  {
840 	    u2 string_index = in.readUnsignedShort ();
841 	    Dprintf (DUMP_JAVA_CLASS, NTXT (" string_index=%4u\n"), (unsigned int) string_index);
842 	    break;
843 	  }
844 	case CONSTANT_FIELD:
845 	case CONSTANT_METHOD:
846 	case CONSTANT_INTERFACEMETHOD:
847 	  {
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);
852 	    break;
853 	  }
854 	case CONSTANT_NAMEANDTYPE:
855 	  {
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);
860 	    break;
861 	  }
862 	case CONSTANT_METHODHANDLE:
863 	  {
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);
868 	    break;
869 	  }
870 	case CONSTANT_METHODTYPE:
871 	  {
872 	    u2 descriptor_index = in.readUnsignedShort ();
873 	    Dprintf (DUMP_JAVA_CLASS, NTXT (" descriptor_index=%u\n"),
874 		     (unsigned int) descriptor_index);
875 	    break;
876 	  }
877 	case CONSTANT_INVOKEDYNAMIC:
878 	  {
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);
884 	    break;
885 	  }
886 	default:
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])));
891 	  throw (e1);
892 	}
893     }
894 }
895 
~BinaryConstantPool()896 BinaryConstantPool::~BinaryConstantPool ()
897 {
898   delete[] types;
899   delete[] offsets;
900   delete input;
901   if (strings)
902     {
903       for (int i = 0; i < nconst; i++)
904 	free (strings[i]);
905       delete[] strings;
906     }
907 }
908 
909 #define CASE_S(x)   case x: return (char *) #x
910 
911 char *
getTypeName(int ty)912 BinaryConstantPool::getTypeName (int ty)
913 {
914   switch (ty)
915     {
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");
931     }
932 }
933 
934 char *
getString(int index)935 BinaryConstantPool::getString (int index)
936 {
937   if (index >= nconst || index <= 0)
938     return NULL;
939   if (strings[index])
940     return strings[index];
941   input->reset ();
942   input->skip (offsets[index]);
943   switch (types[index])
944     {
945     case CONSTANT_CLASS:
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];
954     case CONSTANT_UTF8:
955       break;
956     default:
957       return NULL;
958     }
959   u2 len = input->readUnsignedShort ();
960   strings[index] = (char *) malloc (len + 1);
961   input->copy_bytes (strings[index], len);
962   return strings[index];
963 }
964 
ClassFile()965 ClassFile::ClassFile () : Module ()
966 {
967   input = NULL;
968   bcpool = NULL;
969   cf_buf = NULL;
970   cur_jmthd = NULL;
971   blanksCnt = 0;
972   cf_bufsz = 0;
973   lang_code = Sp_lang_java;
974   class_name = NULL;
975   class_filename = NULL;
976   source_name = NULL;
977   byteCodeInfo = NULL;
978 }
979 
980 char *
get_opc_name(int op)981 ClassFile::get_opc_name (int op)
982 {
983   if (op >= 0 && ((size_t) op) < sizeof (opcNames) / sizeof (char*))
984     return opcNames[op];
985   switch (op)
986     {
987     case opc_try:
988       return NTXT ("try");
989     case opc_dead:
990       return NTXT ("dead");
991     case opc_label:
992       return NTXT ("label");
993     default:
994       return NTXT ("Unknown op code");
995     }
996 }
997 
998 void
openFile(const char * fname)999 ClassFile::openFile (const char *fname)
1000 {
1001   if (fname == NULL)
1002     return;
1003   int fd = open64 (fname, O_RDONLY);
1004   if (fd == -1)
1005     {
1006       append_msg (CMSG_ERROR, GTXT ("Cannot open file %s"), fname);
1007       return;
1008     }
1009   struct stat64 stat_buf;
1010   if ((fstat64 (fd, &stat_buf) == -1) || (stat_buf.st_size == 0))
1011     {
1012       close (fd);
1013       append_msg (CMSG_ERROR, GTXT ("Cannot read file %s"), fname);
1014       return;
1015     }
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))
1019     {
1020       free (cf_buf);
1021       cf_buf = NULL;
1022       close (fd);
1023       append_msg (CMSG_ERROR, GTXT ("Cannot read file %s"), fname);
1024       return;
1025     }
1026   close (fd);
1027 
1028   input = new DataInputStream (cf_buf, cf_bufsz);
1029   u4 c_magic = input->readUnsigned ();
1030   if (c_magic != JAVA_MAGIC)
1031     {
1032       append_msg (CMSG_ERROR, GTXT ("Not a class file: %s"), fname);
1033       return;
1034     }
1035   /* u2 minor = */ input->readUnsignedShort ();
1036   /* u2 major = */ input->readUnsignedShort ();
1037   status = AE_OK;
1038 }
1039 
~ClassFile()1040 ClassFile::~ClassFile ()
1041 {
1042   free (cf_buf);
1043   free (class_name);
1044   free (class_filename);
1045   free (source_name);
1046   delete bcpool;
1047   delete input;
1048 }
1049 
1050 static void
convertName(char * s)1051 convertName (char *s)
1052 {
1053   while (*s)
1054     {
1055       if (*s == '/')
1056 	*s = '.';
1057       s++;
1058     }
1059 }
1060 
1061 void
printConstant(StringBuilder * sb,int index)1062 ClassFile::printConstant (StringBuilder *sb, int index)
1063 {
1064   u1 type = bcpool->getType (index);
1065   switch (type)
1066     {
1067     case CONSTANT_METHOD:
1068       {
1069 	char *str = bcpool->getString (index);
1070 	if (str)
1071 	  {
1072 	    convertName (str);
1073 	    sb->append (str);
1074 	    sb->append (NTXT ("()"));
1075 	  }
1076 	break;
1077       }
1078     case CONSTANT_CLASS:
1079       {
1080 	char *str = bcpool->getString (index);
1081 	if (str)
1082 	  {
1083 	    convertName (str);
1084 	    sb->append (str);
1085 	  }
1086 	break;
1087       }
1088     case CONSTANT_UTF8:
1089       {
1090 	char *str = bcpool->getString (index);
1091 	if (str)
1092 	  sb->append (str);
1093 	break;
1094       }
1095     case CONSTANT_STRING:
1096       {
1097 	char *str = bcpool->getString (index);
1098 	if (str)
1099 	  {
1100 	    sb->append ('"');
1101 	    sb->append (str);
1102 	    sb->append ('"');
1103 	  }
1104 	break;
1105       }
1106     default:
1107       sb->append ('#');
1108       sb->append ((int) index);
1109       break;
1110     }
1111 }
1112 
1113 long long
printCodeSequence(StringBuilder * sb,uint64_t addr,DataInputStream * in)1114 ClassFile::printCodeSequence (StringBuilder *sb, uint64_t addr, DataInputStream *in)
1115 {
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)
1120     {
1121       opcode = in->readByte ();
1122       sb->append (get_opc_name (opcode));
1123       sb->append (NTXT ("_w "));
1124       int arg = in->readUnsignedShort ();
1125       switch (opcode)
1126 	{
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:
1132 	case opc_ret:
1133 	  sb->append (arg);
1134 	  break;
1135 	case opc_iinc:
1136 	  sb->append (arg);
1137 	  sb->append (' ');
1138 	  sb->append (in->readUnsignedShort ());
1139 	  break;
1140 	default:
1141 	  sb->append (GTXT ("Invalid opcode"));
1142 	  break;
1143 	}
1144     }
1145   else
1146     {
1147       sb->append (get_opc_name (opcode));
1148       sb->append (' ');
1149       switch (opcode)
1150 	{
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:
1156 	case opc_ret:
1157 	  sb->append (in->readByte ());
1158 	  break;
1159 	case opc_iinc:
1160 	  sb->append (in->readByte ());
1161 	  sb->append (' ');
1162 	  sb->append (in->readByte ());
1163 	  break;
1164 	case opc_tableswitch:
1165 	  {
1166 	    int align = (addr + 1) % 4; // 1 byte is a length of opc_lookupswitch
1167 	    if (align != 0)
1168 	      {
1169 		in->skip (4 - align); // four byte boundry
1170 	      }
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 ();
1178 	    break;
1179 	  }
1180 	case opc_lookupswitch:
1181 	  {
1182 	    int align = (addr + 1) % 4; // 1 byte is a length of opc_lookupswitch
1183 	    if (align != 0)
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)
1190 	      {
1191 		/* u4 i1 = */ in->readUnsigned ();
1192 		/* u4 i2 = */ in->readUnsigned ();
1193 	      }
1194 	    break;
1195 	  }
1196 	case opc_newarray:
1197 	  switch (in->readByte ())
1198 	    {
1199 	    case T_INT:
1200 	      sb->append (GTXT ("int"));
1201 	      break;
1202 	    case T_LONG:
1203 	      sb->append (GTXT ("long"));
1204 	      break;
1205 	    case T_FLOAT:
1206 	      sb->append (GTXT ("float"));
1207 	      break;
1208 	    case T_DOUBLE:
1209 	      sb->append (GTXT ("double"));
1210 	      break;
1211 	    case T_CHAR:
1212 	      sb->append (GTXT ("char"));
1213 	      break;
1214 	    case T_SHORT:
1215 	      sb->append (GTXT ("short"));
1216 	      break;
1217 	    case T_BYTE:
1218 	      sb->append (GTXT ("byte"));
1219 	      break;
1220 	    case T_BOOLEAN:
1221 	      sb->append (GTXT ("boolean"));
1222 	      break;
1223 	    default:
1224 	      sb->append (GTXT ("BOGUS TYPE"));
1225 	      break;
1226 	    }
1227 	  break;
1228 	case opc_anewarray:
1229 	  sb->append (GTXT ("class "));
1230 	  printConstant (sb, in->readUnsignedShort ());
1231 	  break;
1232 	case opc_sipush:
1233 	  sb->append (in->readUnsignedShort ());
1234 	  break;
1235 	case opc_bipush:
1236 	  sb->append (in->readByte ());
1237 	  break;
1238 	case opc_ldc:
1239 	  printConstant (sb, in->readByte ());
1240 	  break;
1241 	case opc_ldc_w: case opc_ldc2_w:
1242 	case opc_instanceof: case opc_checkcast:
1243 	case opc_new:
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 ());
1250 	  break;
1251 	case opc_invokeinterface:
1252 	  {
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);
1258 	    break;
1259 	  }
1260 	case opc_multianewarray:
1261 	  {
1262 	    u2 index = in->readUnsignedShort ();
1263 	    printConstant (sb, index);
1264 	    sb->appendf (GTXT (" dim #%d "), index);
1265 	    break;
1266 	  }
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 ()));
1275 	  break;
1276 	case opc_jsr_w:
1277 	case opc_goto_w:
1278 	  sb->append (addr + (int) in->readUnsigned ());
1279 	  break;
1280 	default:
1281 	  break;
1282 	}
1283     }
1284   return in->get_offset () - offset;
1285 }
1286 
1287 void
readAttributes(int count)1288 ClassFile::readAttributes (int count)
1289 {
1290   blanksCnt += 4;
1291   for (int ax = 0; ax < count; ax++)
1292     {
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)
1297 	{
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);
1302 	  continue;
1303 	}
1304 
1305       if (strcmp (attribute_name, NTXT ("SourceFile")) == 0)
1306 	{
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));
1313 	}
1314       else if (strcmp (attribute_name, NTXT ("InnerClasses")) == 0)
1315 	{
1316 	  int niclasses = input->readUnsignedShort ();
1317 	  for (int ix = 0; ix < niclasses; ix++)
1318 	    {
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));
1332 	    }
1333 	}
1334       else if (strcmp (attribute_name, NTXT ("Code")) == 0)
1335 	{
1336 	  u2 max_stack = input->readUnsignedShort ();
1337 	  u2 max_locals = input->readUnsignedShort ();
1338 	  u4 code_length = input->readUnsigned ();
1339 	  if (cur_jmthd)
1340 	    {
1341 	      cur_jmthd->size = code_length;
1342 	      cur_jmthd->img_fname = dbeFile->get_location ();
1343 	      cur_jmthd->img_offset = input->get_offset ();
1344 	    }
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 ());
1354 	}
1355       else if (strcmp (attribute_name, NTXT ("LineNumberTable")) == 0)
1356 	{
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,
1361 		   (int) nlines);
1362 	  for (int lx = 0; lx < nlines; lx++)
1363 	    {
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);
1368 	      if (cur_jmthd)
1369 		byteCodeInfo->append (new ByteCodeInfo (cur_jmthd, bci, lno));
1370 	    }
1371 	}
1372       else
1373 	{
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);
1379 	}
1380     }
1381   blanksCnt -= 4;
1382 }
1383 
1384 int
readFile()1385 ClassFile::readFile ()
1386 {
1387   if (status != AE_NOTREAD)
1388     return status;
1389   status = AE_OTHER;
1390 
1391   // The ClassFile Structure http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
1392   try
1393     {
1394       blanksCnt = 4;
1395       cur_jmthd = NULL;
1396       char *fname = dbeFile->get_location ();
1397       openFile (fname);
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)
1401 	return status;
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));
1410       if (class_filename)
1411 	{
1412 	  class_name = strdup (class_filename);
1413 	  convertName (class_name);
1414 	}
1415 
1416       // Get superclass name
1417       u2 superClassInd = input->readUnsignedShort ();
1418       //char *str = bcpool->getString(superClassInd);
1419       //super_name = str ? convertName( str ) : NULL;
1420 
1421       // Read interfaces
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++)
1429 	{
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" : "");
1433 	}
1434 
1435       // Read fields
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++)
1439 	{
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);
1450 	}
1451 
1452       // Read methods
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++)
1457 	{
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);
1462 	  if (mname == NULL)
1463 	    {
1464 	      DataReadException *e1 = new DataReadException (dbe_sprintf (GTXT ("method name[%d] is NULL\n"), i));
1465 	      throw (e1);
1466 	    }
1467 	  char *msign = bcpool->getString (descriptor_index);
1468 	  if (msign == NULL)
1469 	    {
1470 	      DataReadException *e1 = new DataReadException (dbe_sprintf (GTXT ("method signature[%d] is NULL\n"), i));
1471 	      throw (e1);
1472 	    }
1473 	  size_t len = strlen (class_name);
1474 	  cur_jmthd = NULL;
1475 	  for (int idx = 0; idx < func_cnt; idx++)
1476 	    {
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)
1480 		{
1481 		  if (strcmp (jmt_name + len + 1, mname) == 0 &&
1482 		      strcmp (jmthd->get_signature (), msign) == 0)
1483 		    {
1484 		      cur_jmthd = jmthd;
1485 		      break;
1486 		    }
1487 		}
1488 	    }
1489 	  if (cur_jmthd == NULL)
1490 	    {
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);
1496 	      free (nm);
1497 	      functions->append (cur_jmthd);
1498 	    }
1499 	  if ((mthd_access_flags & ACC_NATIVE) != 0)
1500 	    {
1501 	      cur_jmthd->flags |= FUNC_FLAG_NATIVE;
1502 	    }
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 ();
1511 	}
1512 
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);
1517       status = AE_OK;
1518     }
1519   catch (DataReadException *ex)
1520     {
1521       append_msg (CMSG_ERROR, GTXT ("Cannot read class file %s (%s)"), get_name (), ex->toString ());
1522       delete ex;
1523       status = AE_OTHER;
1524     }
1525 
1526   char *fnm = NULL;
1527   if (class_filename)
1528     {
1529       if (strcmp (class_filename, get_name ()) != 0)
1530 	set_name (strdup (class_filename));
1531       if (source_name)
1532 	{
1533 	  char *bname = strrchr (class_filename, '/');
1534 	  if (bname)
1535 	    fnm = dbe_sprintf (NTXT ("%.*s/%s"), (int) (bname - class_filename),
1536 			       class_filename, source_name);
1537 	  else
1538 	    fnm = strdup (source_name);
1539 	}
1540       else
1541 	fnm = get_java_file_name (class_filename, false);
1542     }
1543   else if (source_name)
1544     fnm = strdup (source_name);
1545   if (fnm)
1546     {
1547       set_file_name (fnm);
1548       main_source = findSource (file_name, true);
1549       main_source->dbeFile->filetype |= DbeFile::F_JAVA_SOURCE;
1550     }
1551 
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++)
1556     {
1557       ByteCodeInfo *p = byteCodeInfo->get (i);
1558       if (func != p->func)
1559 	{
1560 	  if (func)
1561 	    func->popSrcFile ();
1562 	  func = p->func;
1563 	  func->line_first = p->lno;
1564 	  func->pushSrcFile (main_source, 0);
1565 	}
1566       func->line_last = p->lno;
1567       func->add_PC_info (p->bci, p->lno, main_source);
1568     }
1569   if (func)
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),
1575 	   STR (get_name ()));
1576   return status;
1577 }
1578 
1579 #define MAX_CLASS_SIZE 65536
1580 
1581 char *
get_disasm(uint64_t inst_address,uint64_t end_address,uint64_t start_address,uint64_t f_offset,int64_t & inst_size)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)
1584 {
1585   int64_t offset = f_offset + (inst_address - start_address);
1586   if ((cf_buf == NULL) || (inst_address >= end_address) || (offset >= cf_bufsz))
1587     {
1588       inst_size = 0;
1589       return NULL;
1590     }
1591 
1592   // Check for an implausibly large size
1593   if ((inst_address - start_address) > MAX_CLASS_SIZE)
1594     {
1595       append_msg (CMSG_ERROR, GTXT ("Cannot disassemble class file %s (%s), implausible size = %lld"),
1596 		  get_name (), dbeFile->get_location (),
1597 		  (end_address - start_address));
1598       inst_size = 0;
1599       return NULL;
1600     }
1601 
1602   StringBuilder sb;
1603   DataInputStream *in = new DataInputStream (input);
1604   try
1605     {
1606       in->skip (offset);
1607       inst_size = printCodeSequence (&sb, inst_address - start_address, in);
1608     }
1609   catch (DataReadException *ex)
1610     {
1611       append_msg (CMSG_ERROR, GTXT ("Cannot disassemble class file %s (%s) %s"),
1612 		  get_name (), dbeFile->get_location (), ex->toString ());
1613       delete ex;
1614       inst_size = 0;
1615     }
1616   delete in;
1617   if (inst_size == 0)
1618     return NULL;
1619   return sb.toString ();
1620 }
1621 
1622 char *
get_java_file_name(char * clname,bool classSuffix)1623 ClassFile::get_java_file_name (char *clname, bool classSuffix)
1624 {
1625   size_t len = strlen (clname);
1626   if (len > 6 && streq (clname + len - 6, NTXT (".class")))
1627     len -= 6;
1628   if (!classSuffix)
1629     { // remove $SubClassName from "ClassName$SubClassName"
1630       char *tmp = strchr (clname, '$');
1631       if (tmp)
1632 	len = tmp - clname;
1633     }
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"));
1638   return clpath;
1639 }
1640