• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 
16 #include "instruction_decoder.h"
17 
18 #include "dex/dex_instruction_list.h"
19 
20 #include <android-base/logging.h>
21 
22 namespace titrace {
23 
24 class ClassInstructionDecoder : public InstructionDecoder {
25  public:
GetMaximumOpcode()26   size_t GetMaximumOpcode() override {
27     return 0xff;
28   }
29 
GetName(size_t opcode)30   const char* GetName(size_t opcode) override {
31     Bytecode::Opcode op = static_cast<Bytecode::Opcode>(opcode);
32     return Bytecode::ToString(op);
33   }
34 
LocationToOffset(size_t j_location)35   size_t LocationToOffset(size_t j_location) override {
36     return j_location;
37   }
38 
39  private:
40   class Bytecode {
41    public:
42     enum Opcode {
43       // Java bytecode opcodes from 0x00 to 0xFF.
44       kNop = 0x00,
45       kAconst_null = 0x01,
46       kIconst_m1 = 0x02,
47       kIconst_0 = 0x03,
48       kIconst_1 = 0x04,
49       kIconst_2 = 0x05,
50       kIconst_3 = 0x06,
51       kIconst_4 = 0x07,
52       kIconst_5 = 0x08,
53       kLconst_0 = 0x09,
54       kLconst_1 = 0x0a,
55       kFconst_0 = 0x0b,
56       kFconst_1 = 0x0c,
57       kFconst_2 = 0x0d,
58       kDconst_0 = 0x0e,
59       kDconst_1 = 0x0f,
60       kBipush = 0x10,
61       kSipush = 0x11,
62       kLdc = 0x12,
63       kLdc_w = 0x13,
64       kLdc2_w = 0x14,
65       kIload = 0x15,
66       kLload = 0x16,
67       kFload = 0x17,
68       kDload = 0x18,
69       kAload = 0x19,
70       kIload_0 = 0x1a,
71       kIload_1 = 0x1b,
72       kIload_2 = 0x1c,
73       kIload_3 = 0x1d,
74       kLload_0 = 0x1e,
75       kLload_1 = 0x1f,
76       kLload_2 = 0x20,
77       kLload_3 = 0x21,
78       kFload_0 = 0x22,
79       kFload_1 = 0x23,
80       kFload_2 = 0x24,
81       kFload_3 = 0x25,
82       kDload_0 = 0x26,
83       kDload_1 = 0x27,
84       kDload_2 = 0x28,
85       kDload_3 = 0x29,
86       kAload_0 = 0x2a,
87       kAload_1 = 0x2b,
88       kAload_2 = 0x2c,
89       kAload_3 = 0x2d,
90       kIaload = 0x2e,
91       kLaload = 0x2f,
92       kFaload = 0x30,
93       kDaload = 0x31,
94       kAaload = 0x32,
95       kBaload = 0x33,
96       kCaload = 0x34,
97       kSaload = 0x35,
98       kIstore = 0x36,
99       kLstore = 0x37,
100       kFstore = 0x38,
101       kDstore = 0x39,
102       kAstore = 0x3a,
103       kIstore_0 = 0x3b,
104       kIstore_1 = 0x3c,
105       kIstore_2 = 0x3d,
106       kIstore_3 = 0x3e,
107       kLstore_0 = 0x3f,
108       kLstore_1 = 0x40,
109       kLstore_2 = 0x41,
110       kLstore_3 = 0x42,
111       kFstore_0 = 0x43,
112       kFstore_1 = 0x44,
113       kFstore_2 = 0x45,
114       kFstore_3 = 0x46,
115       kDstore_0 = 0x47,
116       kDstore_1 = 0x48,
117       kDstore_2 = 0x49,
118       kDstore_3 = 0x4a,
119       kAstore_0 = 0x4b,
120       kAstore_1 = 0x4c,
121       kAstore_2 = 0x4d,
122       kAstore_3 = 0x4e,
123       kIastore = 0x4f,
124       kLastore = 0x50,
125       kFastore = 0x51,
126       kDastore = 0x52,
127       kAastore = 0x53,
128       kBastore = 0x54,
129       kCastore = 0x55,
130       kSastore = 0x56,
131       kPop = 0x57,
132       kPop2 = 0x58,
133       kDup = 0x59,
134       kDup_x1 = 0x5a,
135       kDup_x2 = 0x5b,
136       kDup2 = 0x5c,
137       kDup2_x1 = 0x5d,
138       kDup2_x2 = 0x5e,
139       kSwap = 0x5f,
140       kIadd = 0x60,
141       kLadd = 0x61,
142       kFadd = 0x62,
143       kDadd = 0x63,
144       kIsub = 0x64,
145       kLsub = 0x65,
146       kFsub = 0x66,
147       kDsub = 0x67,
148       kImul = 0x68,
149       kLmul = 0x69,
150       kFmul = 0x6a,
151       kDmul = 0x6b,
152       kIdiv = 0x6c,
153       kLdiv = 0x6d,
154       kFdiv = 0x6e,
155       kDdiv = 0x6f,
156       kIrem = 0x70,
157       kLrem = 0x71,
158       kFrem = 0x72,
159       kDrem = 0x73,
160       kIneg = 0x74,
161       kLneg = 0x75,
162       kFneg = 0x76,
163       kDneg = 0x77,
164       kIshl = 0x78,
165       kLshl = 0x79,
166       kIshr = 0x7a,
167       kLshr = 0x7b,
168       kIushr = 0x7c,
169       kLushr = 0x7d,
170       kIand = 0x7e,
171       kLand = 0x7f,
172       kIor = 0x80,
173       kLor = 0x81,
174       kIxor = 0x82,
175       kLxor = 0x83,
176       kIinc = 0x84,
177       kI2l = 0x85,
178       kI2f = 0x86,
179       kI2d = 0x87,
180       kL2i = 0x88,
181       kL2f = 0x89,
182       kL2d = 0x8a,
183       kF2i = 0x8b,
184       kF2l = 0x8c,
185       kF2d = 0x8d,
186       kD2i = 0x8e,
187       kD2l = 0x8f,
188       kD2f = 0x90,
189       kI2b = 0x91,
190       kI2c = 0x92,
191       kI2s = 0x93,
192       kLcmp = 0x94,
193       kFcmpl = 0x95,
194       kFcmpg = 0x96,
195       kDcmpl = 0x97,
196       kDcmpg = 0x98,
197       kIfeq = 0x99,
198       kIfne = 0x9a,
199       kIflt = 0x9b,
200       kIfge = 0x9c,
201       kIfgt = 0x9d,
202       kIfle = 0x9e,
203       kIf_icmpeq = 0x9f,
204       kIf_icmpne = 0xa0,
205       kIf_icmplt = 0xa1,
206       kIf_icmpge = 0xa2,
207       kIf_icmpgt = 0xa3,
208       kIf_icmple = 0xa4,
209       kIf_acmpeq = 0xa5,
210       kIf_acmpne = 0xa6,
211       kGoto = 0xa7,
212       kJsr = 0xa8,
213       kRet = 0xa9,
214       kTableswitch = 0xaa,
215       kLookupswitch = 0xab,
216       kIreturn = 0xac,
217       kLreturn = 0xad,
218       kFreturn = 0xae,
219       kDreturn = 0xaf,
220       kAreturn = 0xb0,
221       kReturn = 0xb1,
222       kGetstatic = 0xb2,
223       kPutstatic = 0xb3,
224       kGetfield = 0xb4,
225       kPutfield = 0xb5,
226       kInvokevirtual = 0xb6,
227       kInvokespecial = 0xb7,
228       kInvokestatic = 0xb8,
229       kInvokeinterface = 0xb9,
230       kInvokedynamic = 0xba,
231       kNew = 0xbb,
232       kNewarray = 0xbc,
233       kAnewarray = 0xbd,
234       kArraylength = 0xbe,
235       kAthrow = 0xbf,
236       kCheckcast = 0xc0,
237       kInstanceof = 0xc1,
238       kMonitorenter = 0xc2,
239       kMonitorexit = 0xc3,
240       kWide = 0xc4,
241       kMultianewarray = 0xc5,
242       kIfnull = 0xc6,
243       kIfnonnull = 0xc7,
244       kGoto_w = 0xc8,
245       kJsr_w = 0xc9,
246       kBreakpoint = 0xca,
247       // Instructions 0xcb-0xfd are undefined.
248           kImpdep1 = 0xfe,
249       kImpdep2 = 0xff,
250     };
251 
ToString(Bytecode::Opcode op)252     static const char* ToString(Bytecode::Opcode op) {
253       switch (op) {
254         case kNop: return "nop";
255         case kAconst_null: return "aconst_null";
256         case kIconst_m1: return "iconst_m1";
257         case kIconst_0: return "iconst_0";
258         case kIconst_1: return "iconst_1";
259         case kIconst_2: return "iconst_2";
260         case kIconst_3: return "iconst_3";
261         case kIconst_4: return "iconst_4";
262         case kIconst_5: return "iconst_5";
263         case kLconst_0: return "lconst_0";
264         case kLconst_1: return "lconst_1";
265         case kFconst_0: return "fconst_0";
266         case kFconst_1: return "fconst_1";
267         case kFconst_2: return "fconst_2";
268         case kDconst_0: return "dconst_0";
269         case kDconst_1: return "dconst_1";
270         case kBipush: return "bipush";
271         case kSipush: return "sipush";
272         case kLdc: return "ldc";
273         case kLdc_w: return "ldc_w";
274         case kLdc2_w: return "ldc2_w";
275         case kIload: return "iload";
276         case kLload: return "lload";
277         case kFload: return "fload";
278         case kDload: return "dload";
279         case kAload: return "aload";
280         case kIload_0: return "iload_0";
281         case kIload_1: return "iload_1";
282         case kIload_2: return "iload_2";
283         case kIload_3: return "iload_3";
284         case kLload_0: return "lload_0";
285         case kLload_1: return "lload_1";
286         case kLload_2: return "lload_2";
287         case kLload_3: return "lload_3";
288         case kFload_0: return "fload_0";
289         case kFload_1: return "fload_1";
290         case kFload_2: return "fload_2";
291         case kFload_3: return "fload_3";
292         case kDload_0: return "dload_0";
293         case kDload_1: return "dload_1";
294         case kDload_2: return "dload_2";
295         case kDload_3: return "dload_3";
296         case kAload_0: return "aload_0";
297         case kAload_1: return "aload_1";
298         case kAload_2: return "aload_2";
299         case kAload_3: return "aload_3";
300         case kIaload: return "iaload";
301         case kLaload: return "laload";
302         case kFaload: return "faload";
303         case kDaload: return "daload";
304         case kAaload: return "aaload";
305         case kBaload: return "baload";
306         case kCaload: return "caload";
307         case kSaload: return "saload";
308         case kIstore: return "istore";
309         case kLstore: return "lstore";
310         case kFstore: return "fstore";
311         case kDstore: return "dstore";
312         case kAstore: return "astore";
313         case kIstore_0: return "istore_0";
314         case kIstore_1: return "istore_1";
315         case kIstore_2: return "istore_2";
316         case kIstore_3: return "istore_3";
317         case kLstore_0: return "lstore_0";
318         case kLstore_1: return "lstore_1";
319         case kLstore_2: return "lstore_2";
320         case kLstore_3: return "lstore_3";
321         case kFstore_0: return "fstore_0";
322         case kFstore_1: return "fstore_1";
323         case kFstore_2: return "fstore_2";
324         case kFstore_3: return "fstore_3";
325         case kDstore_0: return "dstore_0";
326         case kDstore_1: return "dstore_1";
327         case kDstore_2: return "dstore_2";
328         case kDstore_3: return "dstore_3";
329         case kAstore_0: return "astore_0";
330         case kAstore_1: return "astore_1";
331         case kAstore_2: return "astore_2";
332         case kAstore_3: return "astore_3";
333         case kIastore: return "iastore";
334         case kLastore: return "lastore";
335         case kFastore: return "fastore";
336         case kDastore: return "dastore";
337         case kAastore: return "aastore";
338         case kBastore: return "bastore";
339         case kCastore: return "castore";
340         case kSastore: return "sastore";
341         case kPop: return "pop";
342         case kPop2: return "pop2";
343         case kDup: return "dup";
344         case kDup_x1: return "dup_x1";
345         case kDup_x2: return "dup_x2";
346         case kDup2: return "dup2";
347         case kDup2_x1: return "dup2_x1";
348         case kDup2_x2: return "dup2_x2";
349         case kSwap: return "swap";
350         case kIadd: return "iadd";
351         case kLadd: return "ladd";
352         case kFadd: return "fadd";
353         case kDadd: return "dadd";
354         case kIsub: return "isub";
355         case kLsub: return "lsub";
356         case kFsub: return "fsub";
357         case kDsub: return "dsub";
358         case kImul: return "imul";
359         case kLmul: return "lmul";
360         case kFmul: return "fmul";
361         case kDmul: return "dmul";
362         case kIdiv: return "idiv";
363         case kLdiv: return "ldiv";
364         case kFdiv: return "fdiv";
365         case kDdiv: return "ddiv";
366         case kIrem: return "irem";
367         case kLrem: return "lrem";
368         case kFrem: return "frem";
369         case kDrem: return "drem";
370         case kIneg: return "ineg";
371         case kLneg: return "lneg";
372         case kFneg: return "fneg";
373         case kDneg: return "dneg";
374         case kIshl: return "ishl";
375         case kLshl: return "lshl";
376         case kIshr: return "ishr";
377         case kLshr: return "lshr";
378         case kIushr: return "iushr";
379         case kLushr: return "lushr";
380         case kIand: return "iand";
381         case kLand: return "land";
382         case kIor: return "ior";
383         case kLor: return "lor";
384         case kIxor: return "ixor";
385         case kLxor: return "lxor";
386         case kIinc: return "iinc";
387         case kI2l: return "i2l";
388         case kI2f: return "i2f";
389         case kI2d: return "i2d";
390         case kL2i: return "l2i";
391         case kL2f: return "l2f";
392         case kL2d: return "l2d";
393         case kF2i: return "f2i";
394         case kF2l: return "f2l";
395         case kF2d: return "f2d";
396         case kD2i: return "d2i";
397         case kD2l: return "d2l";
398         case kD2f: return "d2f";
399         case kI2b: return "i2b";
400         case kI2c: return "i2c";
401         case kI2s: return "i2s";
402         case kLcmp: return "lcmp";
403         case kFcmpl: return "fcmpl";
404         case kFcmpg: return "fcmpg";
405         case kDcmpl: return "dcmpl";
406         case kDcmpg: return "dcmpg";
407         case kIfeq: return "ifeq";
408         case kIfne: return "ifne";
409         case kIflt: return "iflt";
410         case kIfge: return "ifge";
411         case kIfgt: return "ifgt";
412         case kIfle: return "ifle";
413         case kIf_icmpeq: return "if_icmpeq";
414         case kIf_icmpne: return "if_icmpne";
415         case kIf_icmplt: return "if_icmplt";
416         case kIf_icmpge: return "if_icmpge";
417         case kIf_icmpgt: return "if_icmpgt";
418         case kIf_icmple: return "if_icmple";
419         case kIf_acmpeq: return "if_acmpeq";
420         case kIf_acmpne: return "if_acmpne";
421         case kGoto: return "goto";
422         case kJsr: return "jsr";
423         case kRet: return "ret";
424         case kTableswitch: return "tableswitch";
425         case kLookupswitch: return "lookupswitch";
426         case kIreturn: return "ireturn";
427         case kLreturn: return "lreturn";
428         case kFreturn: return "freturn";
429         case kDreturn: return "dreturn";
430         case kAreturn: return "areturn";
431         case kReturn: return "return";
432         case kGetstatic: return "getstatic";
433         case kPutstatic: return "putstatic";
434         case kGetfield: return "getfield";
435         case kPutfield: return "putfield";
436         case kInvokevirtual: return "invokevirtual";
437         case kInvokespecial: return "invokespecial";
438         case kInvokestatic: return "invokestatic";
439         case kInvokeinterface: return "invokeinterface";
440         case kInvokedynamic: return "invokedynamic";
441         case kNew: return "new";
442         case kNewarray: return "newarray";
443         case kAnewarray: return "anewarray";
444         case kArraylength: return "arraylength";
445         case kAthrow: return "athrow";
446         case kCheckcast: return "checkcast";
447         case kInstanceof: return "instanceof";
448         case kMonitorenter: return "monitorenter";
449         case kMonitorexit: return "monitorexit";
450         case kWide: return "wide";
451         case kMultianewarray: return "multianewarray";
452         case kIfnull: return "ifnull";
453         case kIfnonnull: return "ifnonnull";
454         case kGoto_w: return "goto_w";
455         case kJsr_w: return "jsr_w";
456         case kBreakpoint: return "breakpoint";
457         case kImpdep1: return "impdep1";
458         case kImpdep2: return "impdep2";
459         default:
460           LOG(FATAL) << "Unknown opcode " << op;
461           __builtin_unreachable();
462        }
463      }
464   };
465 };
466 
467 class DexInstructionDecoder : public InstructionDecoder {
468  public:
GetMaximumOpcode()469   size_t GetMaximumOpcode() override {
470     return 0xff;
471   }
472 
GetName(size_t opcode)473   const char* GetName(size_t opcode) override {
474     Bytecode::Opcode op = static_cast<Bytecode::Opcode>(opcode);
475     return Bytecode::ToString(op);
476   }
477 
LocationToOffset(size_t j_location)478   size_t LocationToOffset(size_t j_location) override {
479     // dex pc is uint16_t*, but offset needs to be in bytes.
480     return j_location * (sizeof(uint16_t) / sizeof(uint8_t));
481   }
482 
483  private:
484   class Bytecode {
485    public:
486     enum Opcode {
487 #define MAKE_ENUM_DEFINITION(opcode, instruction_code, name, format, index, flags, extended_flags, verifier_flags) \
488       instruction_code = opcode,  /* NOLINT */
489 DEX_INSTRUCTION_LIST(MAKE_ENUM_DEFINITION)
490 #undef MAKE_ENUM_DEFINITION
491     };
492 
493     static_assert(static_cast<uint32_t>(Bytecode::Opcode::NOP) == 0, "");
494     static_assert(static_cast<uint32_t>(Bytecode::Opcode::MOVE) == 1, "");
495 
ToString(Bytecode::Opcode op)496     static const char* ToString(Bytecode::Opcode op) {
497       switch (op) {
498 #define MAKE_ENUM_DEFINITION(opcode, instruction_code, name, format, index, flags, extended_flags, verifier_flags) \
499         case instruction_code: return (name);
500 DEX_INSTRUCTION_LIST(MAKE_ENUM_DEFINITION)
501 #undef MAKE_ENUM_DEFINITION
502         default: LOG(FATAL) << "Unknown opcode " << op;
503       }
504       __builtin_unreachable();
505     }
506   };
507 };
508 
NewInstance(InstructionFileFormat file_format)509 InstructionDecoder* InstructionDecoder::NewInstance(InstructionFileFormat file_format) {
510   switch (file_format) {
511     case InstructionFileFormat::kClass:
512       return new ClassInstructionDecoder();
513     case InstructionFileFormat::kDex:
514       return new DexInstructionDecoder();
515     default:
516       return nullptr;
517   }
518 }
519 }  // namespace titrace
520