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 virtual size_t LocationToOffset(size_t j_location) {
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: LOG(FATAL) << "Unknown opcode " << op;
460 }
461 return "";
462 }
463 };
464 };
465
466 class DexInstructionDecoder : public InstructionDecoder {
467 public:
GetMaximumOpcode()468 size_t GetMaximumOpcode() override {
469 return 0xff;
470 }
471
GetName(size_t opcode)472 const char* GetName(size_t opcode) override {
473 Bytecode::Opcode op = static_cast<Bytecode::Opcode>(opcode);
474 return Bytecode::ToString(op);
475 }
476
LocationToOffset(size_t j_location)477 virtual size_t LocationToOffset(size_t j_location) {
478 // dex pc is uint16_t*, but offset needs to be in bytes.
479 return j_location * (sizeof(uint16_t) / sizeof(uint8_t));
480 }
481
482 private:
483 class Bytecode {
484 public:
485 enum Opcode {
486 #define MAKE_ENUM_DEFINITION(opcode, instruction_code, name, format, index, flags, extended_flags, verifier_flags) \
487 instruction_code = opcode,
488 DEX_INSTRUCTION_LIST(MAKE_ENUM_DEFINITION)
489 #undef MAKE_ENUM_DEFINITION
490 };
491
492 static_assert(static_cast<uint32_t>(Bytecode::Opcode::NOP) == 0, "");
493 static_assert(static_cast<uint32_t>(Bytecode::Opcode::MOVE) == 1, "");
494
ToString(Bytecode::Opcode op)495 static const char* ToString(Bytecode::Opcode op) {
496 switch (op) {
497 #define MAKE_ENUM_DEFINITION(opcode, instruction_code, name, format, index, flags, extended_flags, verifier_flags) \
498 case instruction_code: return (name);
499 DEX_INSTRUCTION_LIST(MAKE_ENUM_DEFINITION)
500 #undef MAKE_ENUM_DEFINITION
501 default: LOG(FATAL) << "Unknown opcode " << op;
502 }
503 return "";
504 }
505 };
506 };
507
NewInstance(InstructionFileFormat file_format)508 InstructionDecoder* InstructionDecoder::NewInstance(InstructionFileFormat file_format) {
509 switch (file_format) {
510 case InstructionFileFormat::kClass:
511 return new ClassInstructionDecoder();
512 case InstructionFileFormat::kDex:
513 return new DexInstructionDecoder();
514 default:
515 return nullptr;
516 }
517 }
518 } // namespace titrace
519