1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_ 18 #define ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_ 19 20 #include <android-base/logging.h> 21 22 #include "base/globals.h" 23 #include "base/macros.h" 24 25 using uint4_t = uint8_t; 26 using int4_t = int8_t; 27 28 namespace art { 29 30 class DexFile; 31 32 enum { 33 kNumPackedOpcodes = 0x100 34 }; 35 36 class Instruction { 37 public: 38 // NOP-encoded switch-statement signatures. 39 enum Signatures { 40 kPackedSwitchSignature = 0x0100, 41 kSparseSwitchSignature = 0x0200, 42 kArrayDataSignature = 0x0300, 43 }; 44 45 struct PACKED(4) PackedSwitchPayload { 46 const uint16_t ident; 47 const uint16_t case_count; 48 const int32_t first_key; 49 const int32_t targets[]; 50 51 private: 52 DISALLOW_COPY_AND_ASSIGN(PackedSwitchPayload); 53 }; 54 55 struct PACKED(4) SparseSwitchPayload { 56 const uint16_t ident; 57 const uint16_t case_count; 58 const int32_t keys_and_targets[]; 59 60 public: GetKeysSparseSwitchPayload61 const int32_t* GetKeys() const { 62 return keys_and_targets; 63 } 64 GetTargetsSparseSwitchPayload65 const int32_t* GetTargets() const { 66 return keys_and_targets + case_count; 67 } 68 69 private: 70 DISALLOW_COPY_AND_ASSIGN(SparseSwitchPayload); 71 }; 72 73 struct PACKED(4) ArrayDataPayload { 74 const uint16_t ident; 75 const uint16_t element_width; 76 const uint32_t element_count; 77 const uint8_t data[]; 78 79 private: 80 DISALLOW_COPY_AND_ASSIGN(ArrayDataPayload); 81 }; 82 83 enum Code { // private marker to avoid generate-operator-out.py from processing. 84 #define INSTRUCTION_ENUM(opcode, cname, p, f, i, a, e, v) cname = (opcode), 85 #include "dex_instruction_list.h" 86 DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM) 87 #undef DEX_INSTRUCTION_LIST 88 #undef INSTRUCTION_ENUM 89 RSUB_INT_LIT16 = RSUB_INT, 90 }; 91 92 enum Format : uint8_t { 93 k10x, // op 94 k12x, // op vA, vB 95 k11n, // op vA, #+B 96 k11x, // op vAA 97 k10t, // op +AA 98 k20t, // op +AAAA 99 k22x, // op vAA, vBBBB 100 k21t, // op vAA, +BBBB 101 k21s, // op vAA, #+BBBB 102 k21h, // op vAA, #+BBBB00000[00000000] 103 k21c, // op vAA, thing@BBBB 104 k23x, // op vAA, vBB, vCC 105 k22b, // op vAA, vBB, #+CC 106 k22t, // op vA, vB, +CCCC 107 k22s, // op vA, vB, #+CCCC 108 k22c, // op vA, vB, thing@CCCC 109 k32x, // op vAAAA, vBBBB 110 k30t, // op +AAAAAAAA 111 k31t, // op vAA, +BBBBBBBB 112 k31i, // op vAA, #+BBBBBBBB 113 k31c, // op vAA, thing@BBBBBBBB 114 k35c, // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG) 115 k3rc, // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB 116 117 // op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH (A: count) 118 // format: AG op BBBB FEDC HHHH 119 k45cc, 120 121 // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count) 122 // format: AA op BBBB CCCC HHHH 123 k4rcc, // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count) 124 125 k51l, // op vAA, #+BBBBBBBBBBBBBBBB 126 kInvalidFormat, 127 }; 128 129 enum IndexType : uint8_t { 130 kIndexUnknown = 0, 131 kIndexNone, // has no index 132 kIndexTypeRef, // type reference index 133 kIndexStringRef, // string reference index 134 kIndexMethodRef, // method reference index 135 kIndexFieldRef, // field reference index 136 kIndexFieldOffset, // field offset (for static linked fields) 137 kIndexVtableOffset, // vtable offset (for static linked methods) 138 kIndexMethodAndProtoRef, // method and a proto reference index (for invoke-polymorphic) 139 kIndexCallSiteRef, // call site reference index 140 kIndexMethodHandleRef, // constant method handle reference index 141 kIndexProtoRef, // prototype reference index 142 }; 143 144 enum Flags : uint8_t { // private marker to avoid generate-operator-out.py from processing. 145 kBranch = 0x01, // conditional or unconditional branch 146 kContinue = 0x02, // flow can continue to next statement 147 kSwitch = 0x04, // switch statement 148 kThrow = 0x08, // could cause an exception to be thrown 149 kReturn = 0x10, // returns, no additional statements 150 kInvoke = 0x20, // a flavor of invoke 151 kUnconditional = 0x40, // unconditional branch 152 kExperimental = 0x80, // is an experimental opcode 153 }; 154 155 // Old flags. Keeping them around in case we might need them again some day. 156 enum ExtendedFlags : uint32_t { 157 kAdd = 0x0000080, // addition 158 kSubtract = 0x0000100, // subtract 159 kMultiply = 0x0000200, // multiply 160 kDivide = 0x0000400, // division 161 kRemainder = 0x0000800, // remainder 162 kAnd = 0x0001000, // and 163 kOr = 0x0002000, // or 164 kXor = 0x0004000, // xor 165 kShl = 0x0008000, // shl 166 kShr = 0x0010000, // shr 167 kUshr = 0x0020000, // ushr 168 kCast = 0x0040000, // cast 169 kStore = 0x0080000, // store opcode 170 kLoad = 0x0100000, // load opcode 171 kClobber = 0x0200000, // clobbers memory in a big way (not just a write) 172 kRegCFieldOrConstant = 0x0400000, // is the third virtual register a field or literal constant (vC) 173 kRegBFieldOrConstant = 0x0800000, // is the second virtual register a field or literal constant (vB) 174 }; 175 176 enum VerifyFlag : uint32_t { // private marker to avoid generate-operator-out.py from processing. 177 kVerifyNothing = 0x0000000, 178 kVerifyRegA = 0x0000001, 179 kVerifyRegAWide = 0x0000002, 180 kVerifyRegB = 0x0000004, 181 kVerifyRegBField = 0x0000008, 182 kVerifyRegBMethod = 0x0000010, 183 kVerifyRegBNewInstance = 0x0000020, 184 kVerifyRegBString = 0x0000040, 185 kVerifyRegBType = 0x0000080, 186 kVerifyRegBWide = 0x0000100, 187 kVerifyRegC = 0x0000200, 188 kVerifyRegCField = 0x0000400, 189 kVerifyRegCNewArray = 0x0000800, 190 kVerifyRegCType = 0x0001000, 191 kVerifyRegCWide = 0x0002000, 192 kVerifyArrayData = 0x0004000, 193 kVerifyBranchTarget = 0x0008000, 194 kVerifySwitchTargets = 0x0010000, 195 kVerifyVarArg = 0x0020000, 196 kVerifyVarArgNonZero = 0x0040000, 197 kVerifyVarArgRange = 0x0080000, 198 kVerifyVarArgRangeNonZero = 0x0100000, 199 kVerifyRuntimeOnly = 0x0200000, 200 kVerifyError = 0x0400000, 201 kVerifyRegHPrototype = 0x0800000, 202 kVerifyRegBCallSite = 0x1000000, 203 kVerifyRegBMethodHandle = 0x2000000, 204 kVerifyRegBPrototype = 0x4000000, 205 }; 206 207 // Collect the enums in a struct for better locality. 208 struct InstructionDescriptor { 209 uint32_t verify_flags; // Set of VerifyFlag. 210 Format format; 211 IndexType index_type; 212 uint8_t flags; // Set of Flags. 213 int8_t size_in_code_units; 214 }; 215 216 static constexpr uint32_t kMaxVarArgRegs = 5; 217 218 static constexpr bool kHaveExperimentalInstructions = false; 219 220 // Returns the size (in 2 byte code units) of this instruction. SizeInCodeUnits()221 size_t SizeInCodeUnits() const { 222 int8_t result = kInstructionDescriptors[Opcode()].size_in_code_units; 223 if (UNLIKELY(result < 0)) { 224 return SizeInCodeUnitsComplexOpcode(); 225 } else { 226 return static_cast<size_t>(result); 227 } 228 } 229 230 // Returns the size (in 2 byte code units) of the given instruction format. 231 ALWAYS_INLINE static constexpr size_t SizeInCodeUnits(Format format); 232 233 // Code units required to calculate the size of the instruction. CodeUnitsRequiredForSizeComputation()234 size_t CodeUnitsRequiredForSizeComputation() const { 235 const int8_t result = kInstructionDescriptors[Opcode()].size_in_code_units; 236 return UNLIKELY(result < 0) ? CodeUnitsRequiredForSizeOfComplexOpcode() : 1; 237 } 238 239 // Reads an instruction out of the stream at the specified address. At(const uint16_t * code)240 static const Instruction* At(const uint16_t* code) { 241 DCHECK(code != nullptr); 242 return reinterpret_cast<const Instruction*>(code); 243 } 244 245 // Reads an instruction out of the stream from the current address plus an offset. RelativeAt(int32_t offset)246 const Instruction* RelativeAt(int32_t offset) const WARN_UNUSED { 247 return At(reinterpret_cast<const uint16_t*>(this) + offset); 248 } 249 250 // Returns a pointer to the next instruction in the stream. Next()251 const Instruction* Next() const { 252 return RelativeAt(SizeInCodeUnits()); 253 } 254 255 // Returns a pointer to the instruction after this 1xx instruction in the stream. Next_1xx()256 const Instruction* Next_1xx() const { 257 DCHECK(FormatOf(Opcode()) >= k10x && FormatOf(Opcode()) <= k10t); 258 return RelativeAt(1); 259 } 260 261 // Returns a pointer to the instruction after this 2xx instruction in the stream. Next_2xx()262 const Instruction* Next_2xx() const { 263 DCHECK(FormatOf(Opcode()) >= k20t && FormatOf(Opcode()) <= k22c); 264 return RelativeAt(2); 265 } 266 267 // Returns a pointer to the instruction after this 3xx instruction in the stream. Next_3xx()268 const Instruction* Next_3xx() const { 269 DCHECK(FormatOf(Opcode()) >= k32x && FormatOf(Opcode()) <= k3rc); 270 return RelativeAt(3); 271 } 272 273 // Returns a pointer to the instruction after this 4xx instruction in the stream. Next_4xx()274 const Instruction* Next_4xx() const { 275 DCHECK(FormatOf(Opcode()) >= k45cc && FormatOf(Opcode()) <= k4rcc); 276 return RelativeAt(4); 277 } 278 279 // Returns a pointer to the instruction after this 51l instruction in the stream. Next_51l()280 const Instruction* Next_51l() const { 281 DCHECK(FormatOf(Opcode()) == k51l); 282 return RelativeAt(5); 283 } 284 285 // Returns the name of this instruction's opcode. Name()286 const char* Name() const { 287 return Instruction::Name(Opcode()); 288 } 289 290 // Returns the name of the given opcode. Name(Code opcode)291 static const char* Name(Code opcode) { 292 return kInstructionNames[opcode]; 293 } 294 295 // VRegA 296 bool HasVRegA() const; 297 ALWAYS_INLINE int32_t VRegA() const; 298 ALWAYS_INLINE int32_t VRegA(Format format, uint16_t inst_data) const; 299 VRegA_10t()300 int8_t VRegA_10t() const { 301 return VRegA_10t(Fetch16(0)); 302 } VRegA_10x()303 uint8_t VRegA_10x() const { 304 return VRegA_10x(Fetch16(0)); 305 } VRegA_11n()306 uint4_t VRegA_11n() const { 307 return VRegA_11n(Fetch16(0)); 308 } VRegA_11x()309 uint8_t VRegA_11x() const { 310 return VRegA_11x(Fetch16(0)); 311 } VRegA_12x()312 uint4_t VRegA_12x() const { 313 return VRegA_12x(Fetch16(0)); 314 } 315 int16_t VRegA_20t() const; VRegA_21c()316 uint8_t VRegA_21c() const { 317 return VRegA_21c(Fetch16(0)); 318 } VRegA_21h()319 uint8_t VRegA_21h() const { 320 return VRegA_21h(Fetch16(0)); 321 } VRegA_21s()322 uint8_t VRegA_21s() const { 323 return VRegA_21s(Fetch16(0)); 324 } VRegA_21t()325 uint8_t VRegA_21t() const { 326 return VRegA_21t(Fetch16(0)); 327 } VRegA_22b()328 uint8_t VRegA_22b() const { 329 return VRegA_22b(Fetch16(0)); 330 } VRegA_22c()331 uint4_t VRegA_22c() const { 332 return VRegA_22c(Fetch16(0)); 333 } VRegA_22s()334 uint4_t VRegA_22s() const { 335 return VRegA_22s(Fetch16(0)); 336 } VRegA_22t()337 uint4_t VRegA_22t() const { 338 return VRegA_22t(Fetch16(0)); 339 } VRegA_22x()340 uint8_t VRegA_22x() const { 341 return VRegA_22x(Fetch16(0)); 342 } VRegA_23x()343 uint8_t VRegA_23x() const { 344 return VRegA_23x(Fetch16(0)); 345 } 346 int32_t VRegA_30t() const; VRegA_31c()347 uint8_t VRegA_31c() const { 348 return VRegA_31c(Fetch16(0)); 349 } VRegA_31i()350 uint8_t VRegA_31i() const { 351 return VRegA_31i(Fetch16(0)); 352 } VRegA_31t()353 uint8_t VRegA_31t() const { 354 return VRegA_31t(Fetch16(0)); 355 } 356 uint16_t VRegA_32x() const; VRegA_35c()357 uint4_t VRegA_35c() const { 358 return VRegA_35c(Fetch16(0)); 359 } VRegA_3rc()360 uint8_t VRegA_3rc() const { 361 return VRegA_3rc(Fetch16(0)); 362 } VRegA_51l()363 uint8_t VRegA_51l() const { 364 return VRegA_51l(Fetch16(0)); 365 } VRegA_45cc()366 uint4_t VRegA_45cc() const { 367 return VRegA_45cc(Fetch16(0)); 368 } VRegA_4rcc()369 uint8_t VRegA_4rcc() const { 370 return VRegA_4rcc(Fetch16(0)); 371 } 372 373 // The following methods return the vA operand for various instruction formats. The "inst_data" 374 // parameter holds the first 16 bits of instruction which the returned value is decoded from. 375 int8_t VRegA_10t(uint16_t inst_data) const; 376 uint8_t VRegA_10x(uint16_t inst_data) const; 377 uint4_t VRegA_11n(uint16_t inst_data) const; 378 uint8_t VRegA_11x(uint16_t inst_data) const; 379 uint4_t VRegA_12x(uint16_t inst_data) const; 380 uint8_t VRegA_21c(uint16_t inst_data) const; 381 uint8_t VRegA_21h(uint16_t inst_data) const; 382 uint8_t VRegA_21s(uint16_t inst_data) const; 383 uint8_t VRegA_21t(uint16_t inst_data) const; 384 uint8_t VRegA_22b(uint16_t inst_data) const; 385 uint4_t VRegA_22c(uint16_t inst_data) const; 386 uint4_t VRegA_22s(uint16_t inst_data) const; 387 uint4_t VRegA_22t(uint16_t inst_data) const; 388 uint8_t VRegA_22x(uint16_t inst_data) const; 389 uint8_t VRegA_23x(uint16_t inst_data) const; 390 uint8_t VRegA_31c(uint16_t inst_data) const; 391 uint8_t VRegA_31i(uint16_t inst_data) const; 392 uint8_t VRegA_31t(uint16_t inst_data) const; 393 uint4_t VRegA_35c(uint16_t inst_data) const; 394 uint8_t VRegA_3rc(uint16_t inst_data) const; 395 uint8_t VRegA_51l(uint16_t inst_data) const; 396 uint4_t VRegA_45cc(uint16_t inst_data) const; 397 uint8_t VRegA_4rcc(uint16_t inst_data) const; 398 399 // VRegB 400 bool HasVRegB() const; 401 ALWAYS_INLINE int32_t VRegB() const; 402 ALWAYS_INLINE int32_t VRegB(Format format, uint16_t inst_data) const; 403 404 bool HasWideVRegB() const; 405 uint64_t WideVRegB() const; 406 VRegB_11n()407 int4_t VRegB_11n() const { 408 return VRegB_11n(Fetch16(0)); 409 } VRegB_12x()410 uint4_t VRegB_12x() const { 411 return VRegB_12x(Fetch16(0)); 412 } 413 uint16_t VRegB_21c() const; 414 uint16_t VRegB_21h() const; 415 int16_t VRegB_21s() const; 416 int16_t VRegB_21t() const; 417 uint8_t VRegB_22b() const; VRegB_22c()418 uint4_t VRegB_22c() const { 419 return VRegB_22c(Fetch16(0)); 420 } VRegB_22s()421 uint4_t VRegB_22s() const { 422 return VRegB_22s(Fetch16(0)); 423 } VRegB_22t()424 uint4_t VRegB_22t() const { 425 return VRegB_22t(Fetch16(0)); 426 } 427 uint16_t VRegB_22x() const; 428 uint8_t VRegB_23x() const; 429 uint32_t VRegB_31c() const; 430 int32_t VRegB_31i() const; 431 int32_t VRegB_31t() const; 432 uint16_t VRegB_32x() const; 433 uint16_t VRegB_35c() const; 434 uint16_t VRegB_3rc() const; 435 uint64_t VRegB_51l() const; // vB_wide 436 uint16_t VRegB_45cc() const; 437 uint16_t VRegB_4rcc() const; 438 439 // The following methods return the vB operand for all instruction formats where it is encoded in 440 // the first 16 bits of instruction. The "inst_data" parameter holds these 16 bits. The returned 441 // value is decoded from it. 442 int4_t VRegB_11n(uint16_t inst_data) const; 443 uint4_t VRegB_12x(uint16_t inst_data) const; 444 uint4_t VRegB_22c(uint16_t inst_data) const; 445 uint4_t VRegB_22s(uint16_t inst_data) const; 446 uint4_t VRegB_22t(uint16_t inst_data) const; 447 448 // VRegC 449 bool HasVRegC() const; 450 ALWAYS_INLINE int32_t VRegC() const; 451 ALWAYS_INLINE int32_t VRegC(Format format) const; 452 453 int8_t VRegC_22b() const; 454 uint16_t VRegC_22c() const; 455 int16_t VRegC_22s() const; 456 int16_t VRegC_22t() const; 457 uint8_t VRegC_23x() const; 458 uint4_t VRegC_35c() const; 459 uint16_t VRegC_3rc() const; 460 uint4_t VRegC_45cc() const; 461 uint16_t VRegC_4rcc() const; 462 463 464 // VRegH 465 bool HasVRegH() const; 466 int32_t VRegH() const; 467 uint16_t VRegH_45cc() const; 468 uint16_t VRegH_4rcc() const; 469 470 // Fills the given array with the 'arg' array of the instruction. 471 bool HasVarArgs() const; 472 uint32_t GetVarArgs(uint32_t args[kMaxVarArgRegs], uint16_t inst_data) const; GetVarArgs(uint32_t args[kMaxVarArgRegs])473 uint32_t GetVarArgs(uint32_t args[kMaxVarArgRegs]) const { 474 return GetVarArgs(args, Fetch16(0)); 475 } 476 477 // Returns the opcode field of the instruction. The given "inst_data" parameter must be the first 478 // 16 bits of instruction. Opcode(uint16_t inst_data)479 Code Opcode(uint16_t inst_data) const { 480 DCHECK_EQ(inst_data, Fetch16(0)); 481 return static_cast<Code>(inst_data & 0xFF); 482 } 483 484 // Returns the opcode field of the instruction from the first 16 bits of instruction. Opcode()485 Code Opcode() const { 486 return Opcode(Fetch16(0)); 487 } 488 SetOpcode(Code opcode)489 void SetOpcode(Code opcode) { 490 DCHECK_LT(static_cast<uint16_t>(opcode), 256u); 491 uint16_t* insns = reinterpret_cast<uint16_t*>(this); 492 insns[0] = (insns[0] & 0xff00) | static_cast<uint16_t>(opcode); 493 } 494 SetVRegA_10x(uint8_t val)495 void SetVRegA_10x(uint8_t val) { 496 DCHECK(FormatOf(Opcode()) == k10x); 497 uint16_t* insns = reinterpret_cast<uint16_t*>(this); 498 insns[0] = (val << 8) | (insns[0] & 0x00ff); 499 } 500 SetVRegB_3rc(uint16_t val)501 void SetVRegB_3rc(uint16_t val) { 502 DCHECK(FormatOf(Opcode()) == k3rc); 503 uint16_t* insns = reinterpret_cast<uint16_t*>(this); 504 insns[1] = val; 505 } 506 SetVRegB_35c(uint16_t val)507 void SetVRegB_35c(uint16_t val) { 508 DCHECK(FormatOf(Opcode()) == k35c); 509 uint16_t* insns = reinterpret_cast<uint16_t*>(this); 510 insns[1] = val; 511 } 512 SetVRegC_22c(uint16_t val)513 void SetVRegC_22c(uint16_t val) { 514 DCHECK(FormatOf(Opcode()) == k22c); 515 uint16_t* insns = reinterpret_cast<uint16_t*>(this); 516 insns[1] = val; 517 } 518 SetVRegA_21c(uint8_t val)519 void SetVRegA_21c(uint8_t val) { 520 DCHECK(FormatOf(Opcode()) == k21c); 521 uint16_t* insns = reinterpret_cast<uint16_t*>(this); 522 insns[0] = (val << 8) | (insns[0] & 0x00ff); 523 } 524 SetVRegB_21c(uint16_t val)525 void SetVRegB_21c(uint16_t val) { 526 DCHECK(FormatOf(Opcode()) == k21c); 527 uint16_t* insns = reinterpret_cast<uint16_t*>(this); 528 insns[1] = val; 529 } 530 531 // Returns the format of the given opcode. FormatOf(Code opcode)532 static Format FormatOf(Code opcode) { 533 return kInstructionDescriptors[opcode].format; 534 } 535 536 // Returns the index type of the given opcode. IndexTypeOf(Code opcode)537 static IndexType IndexTypeOf(Code opcode) { 538 return kInstructionDescriptors[opcode].index_type; 539 } 540 541 // Returns the flags for the given opcode. FlagsOf(Code opcode)542 static uint8_t FlagsOf(Code opcode) { 543 return kInstructionDescriptors[opcode].flags; 544 } 545 546 // Return the verify flags for the given opcode. VerifyFlagsOf(Code opcode)547 static uint32_t VerifyFlagsOf(Code opcode) { 548 return kInstructionDescriptors[opcode].verify_flags; 549 } 550 551 // Returns true if this instruction is a branch. IsBranch()552 bool IsBranch() const { 553 return (kInstructionDescriptors[Opcode()].flags & kBranch) != 0; 554 } 555 556 // Returns true if this instruction is a unconditional branch. IsUnconditional()557 bool IsUnconditional() const { 558 return (kInstructionDescriptors[Opcode()].flags & kUnconditional) != 0; 559 } 560 561 // Returns the branch offset if this instruction is a branch. 562 int32_t GetTargetOffset() const; 563 564 // Returns true if the instruction allows control flow to go to the following instruction. 565 bool CanFlowThrough() const; 566 567 // Returns true if the instruction is a quickened instruction. IsQuickened()568 bool IsQuickened() const { 569 return (kInstructionDescriptors[Opcode()].index_type == kIndexFieldOffset) || 570 (kInstructionDescriptors[Opcode()].index_type == kIndexVtableOffset); 571 } 572 573 // Returns true if this instruction is a switch. IsSwitch()574 bool IsSwitch() const { 575 return (kInstructionDescriptors[Opcode()].flags & kSwitch) != 0; 576 } 577 578 // Returns true if this instruction can throw. IsThrow()579 bool IsThrow() const { 580 return (kInstructionDescriptors[Opcode()].flags & kThrow) != 0; 581 } 582 583 // Determine if the instruction is any of 'return' instructions. IsReturn()584 bool IsReturn() const { 585 return (kInstructionDescriptors[Opcode()].flags & kReturn) != 0; 586 } 587 588 // Determine if this instruction ends execution of its basic block. IsBasicBlockEnd()589 bool IsBasicBlockEnd() const { 590 return IsBranch() || IsReturn() || Opcode() == THROW; 591 } 592 593 // Determine if this instruction is an invoke. IsInvoke()594 bool IsInvoke() const { 595 return (kInstructionDescriptors[Opcode()].flags & kInvoke) != 0; 596 } 597 598 // Determine if this instruction is experimental. IsExperimental()599 bool IsExperimental() const { 600 return (kInstructionDescriptors[Opcode()].flags & kExperimental) != 0; 601 } 602 GetVerifyTypeArgumentA()603 int GetVerifyTypeArgumentA() const { 604 return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegA | kVerifyRegAWide)); 605 } 606 GetVerifyTypeArgumentB()607 int GetVerifyTypeArgumentB() const { 608 return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegB | kVerifyRegBField | 609 kVerifyRegBMethod | kVerifyRegBNewInstance | kVerifyRegBString | kVerifyRegBType | 610 kVerifyRegBWide)); 611 } 612 GetVerifyTypeArgumentC()613 int GetVerifyTypeArgumentC() const { 614 return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegC | kVerifyRegCField | 615 kVerifyRegCNewArray | kVerifyRegCType | kVerifyRegCWide)); 616 } 617 GetVerifyTypeArgumentH()618 int GetVerifyTypeArgumentH() const { 619 return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRegHPrototype); 620 } 621 GetVerifyExtraFlags()622 int GetVerifyExtraFlags() const { 623 return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyArrayData | 624 kVerifyBranchTarget | kVerifySwitchTargets | kVerifyVarArg | kVerifyVarArgNonZero | 625 kVerifyVarArgRange | kVerifyVarArgRangeNonZero | kVerifyError)); 626 } 627 GetVerifyIsRuntimeOnly()628 bool GetVerifyIsRuntimeOnly() const { 629 return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRuntimeOnly) != 0; 630 } 631 632 // Get the dex PC of this instruction as a offset in code units from the beginning of insns. GetDexPc(const uint16_t * insns)633 uint32_t GetDexPc(const uint16_t* insns) const { 634 return (reinterpret_cast<const uint16_t*>(this) - insns); 635 } 636 637 // Dump decoded version of instruction 638 std::string DumpString(const DexFile*) const; 639 640 // Dump code_units worth of this instruction, padding to code_units for shorter instructions 641 std::string DumpHex(size_t code_units) const; 642 643 // Little-endian dump code_units worth of this instruction, padding to code_units for 644 // shorter instructions 645 std::string DumpHexLE(size_t instr_code_units) const; 646 Fetch16(size_t offset)647 uint16_t Fetch16(size_t offset) const { 648 const uint16_t* insns = reinterpret_cast<const uint16_t*>(this); 649 return insns[offset]; 650 } 651 652 private: 653 size_t SizeInCodeUnitsComplexOpcode() const; 654 655 // Return how many code unit words are required to compute the size of the opcode. 656 size_t CodeUnitsRequiredForSizeOfComplexOpcode() const; 657 Fetch32(size_t offset)658 uint32_t Fetch32(size_t offset) const { 659 return (Fetch16(offset) | ((uint32_t) Fetch16(offset + 1) << 16)); 660 } 661 InstA()662 uint4_t InstA() const { 663 return InstA(Fetch16(0)); 664 } 665 InstB()666 uint4_t InstB() const { 667 return InstB(Fetch16(0)); 668 } 669 InstAA()670 uint8_t InstAA() const { 671 return InstAA(Fetch16(0)); 672 } 673 InstA(uint16_t inst_data)674 uint4_t InstA(uint16_t inst_data) const { 675 DCHECK_EQ(inst_data, Fetch16(0)); 676 return static_cast<uint4_t>((inst_data >> 8) & 0x0f); 677 } 678 InstB(uint16_t inst_data)679 uint4_t InstB(uint16_t inst_data) const { 680 DCHECK_EQ(inst_data, Fetch16(0)); 681 return static_cast<uint4_t>(inst_data >> 12); 682 } 683 InstAA(uint16_t inst_data)684 uint8_t InstAA(uint16_t inst_data) const { 685 DCHECK_EQ(inst_data, Fetch16(0)); 686 return static_cast<uint8_t>(inst_data >> 8); 687 } 688 689 static const char* const kInstructionNames[]; 690 691 static const InstructionDescriptor kInstructionDescriptors[]; 692 693 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); 694 }; 695 std::ostream& operator<<(std::ostream& os, Instruction::Code code); 696 std::ostream& operator<<(std::ostream& os, Instruction::Format format); 697 698 // Base class for accessing instruction operands. Unifies operand 699 // access for instructions that have range and varargs forms 700 // (e.g. invoke-polymoprhic/range and invoke-polymorphic). 701 class InstructionOperands { 702 public: InstructionOperands(size_t num_operands)703 explicit InstructionOperands(size_t num_operands) : num_operands_(num_operands) {} ~InstructionOperands()704 virtual ~InstructionOperands() {} 705 virtual uint32_t GetOperand(size_t index) const = 0; GetNumberOfOperands()706 size_t GetNumberOfOperands() const { return num_operands_; } 707 708 private: 709 const size_t num_operands_; 710 711 DISALLOW_IMPLICIT_CONSTRUCTORS(InstructionOperands); 712 }; 713 714 // Class for accessing operands for instructions with a range format 715 // (e.g. 3rc and 4rcc). 716 class RangeInstructionOperands final : public InstructionOperands { 717 public: RangeInstructionOperands(uint32_t first_operand,size_t num_operands)718 RangeInstructionOperands(uint32_t first_operand, size_t num_operands) 719 : InstructionOperands(num_operands), first_operand_(first_operand) {} ~RangeInstructionOperands()720 ~RangeInstructionOperands() {} 721 uint32_t GetOperand(size_t operand_index) const override; 722 723 private: 724 const uint32_t first_operand_; 725 726 DISALLOW_IMPLICIT_CONSTRUCTORS(RangeInstructionOperands); 727 }; 728 729 // Class for accessing operands for instructions with a variable 730 // number of arguments format (e.g. 35c and 45cc). 731 class VarArgsInstructionOperands final : public InstructionOperands { 732 public: VarArgsInstructionOperands(const uint32_t (& operands)[Instruction::kMaxVarArgRegs],size_t num_operands)733 VarArgsInstructionOperands(const uint32_t (&operands)[Instruction::kMaxVarArgRegs], 734 size_t num_operands) 735 : InstructionOperands(num_operands), operands_(operands) {} ~VarArgsInstructionOperands()736 ~VarArgsInstructionOperands() {} 737 uint32_t GetOperand(size_t operand_index) const override; 738 739 private: 740 const uint32_t (&operands_)[Instruction::kMaxVarArgRegs]; 741 742 DISALLOW_IMPLICIT_CONSTRUCTORS(VarArgsInstructionOperands); 743 }; 744 745 // Class for accessing operands without the receiver by wrapping an 746 // existing InstructionOperands instance. 747 class NoReceiverInstructionOperands final : public InstructionOperands { 748 public: NoReceiverInstructionOperands(const InstructionOperands * const inner)749 explicit NoReceiverInstructionOperands(const InstructionOperands* const inner) 750 : InstructionOperands(inner->GetNumberOfOperands() - 1), inner_(inner) {} ~NoReceiverInstructionOperands()751 ~NoReceiverInstructionOperands() {} 752 uint32_t GetOperand(size_t operand_index) const override; 753 754 private: 755 const InstructionOperands* const inner_; 756 757 DISALLOW_IMPLICIT_CONSTRUCTORS(NoReceiverInstructionOperands); 758 }; 759 760 } // namespace art 761 762 #endif // ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_ 763