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