]> Git Repo - binutils.git/blob - gprofng/src/ClassFile.cc
Automatic date update in version.in
[binutils.git] / gprofng / src / ClassFile.cc
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
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 *
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
616   DataReadException (char *s)
617   {
618     str_err = s;
619   }
620
621   ~DataReadException ()
622   {
623     free (str_err);
624   }
625
626   char *
627   toString ()
628   {
629     return str_err;
630   }
631
632 private:
633   char *str_err;
634 };
635
636 class DataInputStream
637 {
638 public:
639
640   DataInputStream (const unsigned char *bytes, int64_t sz)
641   {
642     bp = bp_orig = bytes;
643     bp_last = bp_orig + sz;
644   }
645
646   DataInputStream (DataInputStream *in)
647   {
648     bp = bp_orig = in->bp_orig;
649     bp_last = in->bp_last;
650   }
651
652   u1
653   readByte ()
654   {
655     check (1);
656     u1 val = *bp;
657     bp++;
658     return val;
659   }
660
661   u2
662   readUnsignedShort ()
663   {
664     check (2);
665     u2 val = (bp[0] << 8) | bp[1];
666     bp += 2;
667     return val;
668   }
669
670   u4
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 *
680   getptr ()
681   {
682     return bp;
683   }
684
685   const size_t
686   get_offset ()
687   {
688     return bp - bp_orig;
689   }
690
691   void
692   skip (int n)
693   {
694     check (n);
695     bp += n;
696   }
697
698   void
699   reset ()
700   {
701     bp = bp_orig;
702   }
703
704   void
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
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
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 *
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 *
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
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
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 *
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 *
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
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 *
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
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
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
1051 convertName (char *s)
1052 {
1053   while (*s)
1054     {
1055       if (*s == '/')
1056         *s = '.';
1057       s++;
1058     }
1059 }
1060
1061 void
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
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
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
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 *
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 *
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 }
This page took 0.115488 seconds and 4 git commands to generate.