dex_instruction.cc revision e3c845cdb5884e770287a5c0c65c8bb64733c388
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 1612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro 17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction.h" 1812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro 19d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers#include "dex_file.h" 20d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers#include <iomanip> 21d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers 2212eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapironamespace art { 2312eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro 24e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroconst char* const Instruction::kInstructionNames[] = { 25ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_NAME(o, c, pname, f, r, i, a, v) pname, 26578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h" 27e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro DEX_INSTRUCTION_LIST(INSTRUCTION_NAME) 28e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST 29e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_NAME 30e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro}; 31e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro 32e4c1ce498f7933b91696caa4a527e6556128a8e2Carl ShapiroInstruction::InstructionFormat const Instruction::kInstructionFormats[] = { 33ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FORMAT(o, c, p, format, r, i, a, v) format, 34578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h" 35e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro DEX_INSTRUCTION_LIST(INSTRUCTION_FORMAT) 36e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST 37e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FORMAT 38e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro}; 39e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro 40e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroint const Instruction::kInstructionFlags[] = { 41ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FLAGS(o, c, p, f, r, i, flags, v) flags, 42578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h" 43e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro DEX_INSTRUCTION_LIST(INSTRUCTION_FLAGS) 44e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST 45e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FLAGS 46e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro}; 47e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro 48ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaoint const Instruction::kInstructionVerifyFlags[] = { 49ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_VERIFY_FLAGS(o, c, p, f, r, i, a, vflags) vflags, 50ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#include "dex_instruction_list.h" 51ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao DEX_INSTRUCTION_LIST(INSTRUCTION_VERIFY_FLAGS) 52ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef DEX_INSTRUCTION_LIST 53ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef INSTRUCTION_VERIFY_FLAGS 54ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao}; 55ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 56ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao/* 57ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Handy macros for helping decode instructions. 58ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */ 59ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define FETCH(_offset) (insns[(_offset)]) 60ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define FETCH_u4(_offset) (fetch_u4_impl((_offset), insns)) 61ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_A(_insn) (((uint16_t)(_insn) >> 8) & 0x0f) 62ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_B(_insn) ((uint16_t)(_insn) >> 12) 63ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_AA(_insn) ((_insn) >> 8) 64ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 65ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao/* Helper for FETCH_u4, above. */ 66ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaostatic inline uint32_t fetch_u4_impl(uint32_t offset, const uint16_t* insns) { 67ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return insns[offset] | ((uint32_t) insns[offset+1] << 16); 68ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao} 69ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 70ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaovoid Instruction::Decode(uint32_t &vA, uint32_t &vB, uint64_t &vB_wide, uint32_t &vC, uint32_t arg[]) const { 71ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao const uint16_t* insns = reinterpret_cast<const uint16_t*>(this); 72ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao uint16_t insn = *insns; 73ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao int opcode = insn & 0xFF; 74ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 75ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao switch (Format()) { 76ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k10x: // op 77ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao /* nothing to do; copy the AA bits out for the verifier */ 78ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 79ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 80ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k12x: // op vA, vB 81ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_A(insn); 82ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = INST_B(insn); 83ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 84ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k11n: // op vA, #+B 85ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_A(insn); 86ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = (int32_t) (INST_B(insn) << 28) >> 28; // sign extend 4-bit value 87ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 88ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k11x: // op vAA 89ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 90ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 91ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k10t: // op +AA 92ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = (int8_t) INST_AA(insn); // sign-extend 8-bit value 93ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 94e0cfb6fef149e4b001d580809b2815eb6e181a09jeffhao case k20bc: // op AA, kind@BBBB 95e0cfb6fef149e4b001d580809b2815eb6e181a09jeffhao break; 96ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k20t: // op +AAAA 97ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = (int16_t) FETCH(1); // sign-extend 16-bit value 98ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 99ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k21c: // op vAA, thing@BBBB 100ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22x: // op vAA, vBBBB 101ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 102ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1); 103ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 104ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k21s: // op vAA, #+BBBB 105ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k21t: // op vAA, +BBBB 106ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 107ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = (int16_t) FETCH(1); // sign-extend 16-bit value 108ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 109ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k21h: // op vAA, #+BBBB0000[00000000] 110ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 111ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao /* 112ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * The value should be treated as right-zero-extended, but we don't 113ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * actually do that here. Among other things, we don't know if it's 114ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * the top bits of a 32- or 64-bit value. 115ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */ 116ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1); 117ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 118ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k23x: // op vAA, vBB, vCC 119ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 120ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1) & 0xff; 121ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = FETCH(1) >> 8; 122ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 123ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22b: // op vAA, vBB, #+CC 124ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 125ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1) & 0xff; 126ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = (int8_t) (FETCH(1) >> 8); // sign-extend 8-bit value 127ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 128ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22s: // op vA, vB, #+CCCC 129ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22t: // op vA, vB, +CCCC 130ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_A(insn); 131ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = INST_B(insn); 132ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = (int16_t) FETCH(1); // sign-extend 16-bit value 133ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 134ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22c: // op vA, vB, thing@CCCC 135ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_A(insn); 136ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = INST_B(insn); 137ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = FETCH(1); 138ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 139ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k30t: // op +AAAAAAAA 140ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = FETCH_u4(1); // signed 32-bit value 141ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 142ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k31t: // op vAA, +BBBBBBBB 143ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k31c: // op vAA, string@BBBBBBBB 144ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 145ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH_u4(1); // 32-bit value 146ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 147ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k32x: // op vAAAA, vBBBB 148ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = FETCH(1); 149ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(2); 150ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 151ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k31i: // op vAA, #+BBBBBBBB 152ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 153ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH_u4(1); // signed 32-bit value 154ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 155ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k35c: // op {vC, vD, vE, vF, vG}, thing@BBBB 156ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao { 157ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao /* 158ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Note that the fields mentioned in the spec don't appear in 159ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * their "usual" positions here compared to most formats. This 160ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * was done so that the field names for the argument count and 161ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * reference index match between this format and the corresponding 162ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * range formats (3rc and friends). 163ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * 164ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Bottom line: The argument count is always in vA, and the 165ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * method constant (or equivalent) is always in vB. 166ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */ 167ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao uint16_t regList; 168ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao int count; 169ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 170ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_B(insn); // This is labeled A in the spec. 171ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1); 172ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao regList = FETCH(2); 173ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 174ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao count = vA; 175ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 176ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao /* 177ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Copy the argument registers into the arg[] array, and 178ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * also copy the first argument (if any) into vC. (The 179ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * DecodedInstruction structure doesn't have separate 180ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * fields for {vD, vE, vF, vG}, so there's no need to make 181ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * copies of those.) Note that cases 5..2 fall through. 182ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */ 183ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao switch (count) { 184ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 5: arg[4] = INST_A(insn); 185ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 4: arg[3] = (regList >> 12) & 0x0f; 186ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 3: arg[2] = (regList >> 8) & 0x0f; 187ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 2: arg[1] = (regList >> 4) & 0x0f; 188ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 1: vC = arg[0] = regList & 0x0f; break; 189ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 0: break; // Valid, but no need to do anything. 190ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao default: 191ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao LOG(ERROR) << "Invalid arg count in 35c (" << count << ")"; 192ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return; 193ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao } 194ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao } 195ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 196ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k3rc: // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB 197ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 198ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1); 199ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = FETCH(2); 200ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 201ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k51l: // op vAA, #+BBBBBBBBBBBBBBBB 202ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 203ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB_wide = FETCH_u4(1) | ((uint64_t) FETCH_u4(3) << 32); 204ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 205ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao default: 206ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes LOG(ERROR) << "Can't decode unexpected format " << static_cast<int>(Format()) << " (op=" << opcode << ")"; 207ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return; 208ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao } 209ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao} 210ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 211d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogerssize_t Instruction::SizeInCodeUnits() const { 21212eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro const uint16_t* insns = reinterpret_cast<const uint16_t*>(this); 213e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro if (*insns == kPackedSwitchSignature) { 214ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return (4 + insns[1] * 2); 215e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro } else if (*insns == kSparseSwitchSignature) { 216ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return (2 + insns[1] * 4); 217e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro } else if (*insns == kArrayDataSignature) { 218e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro uint16_t element_size = insns[1]; 219e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro uint32_t length = insns[2] | (((uint32_t)insns[3]) << 16); 220e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro // The plus 1 is to round up for odd size and width. 221ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return (4 + (element_size * length + 1) / 2); 222e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro } else { 223e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro switch (Format()) { 224e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k10x: 225e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k12x: 226e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k11n: 227e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k11x: 228e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k10t: 229ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return 1; 2309fdfc1808f2a3845ee7e890a4e5d22a10f2ee93dIan Rogers case k20bc: 231e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k20t: 232e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k22x: 233e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k21t: 234e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k21s: 235e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k21h: 236e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k21c: 237e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k23x: 238e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k22b: 239e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k22t: 240e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k22s: 241e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k22c: 242ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return 2; 243e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k32x: 244e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k30t: 245e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k31t: 246e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k31i: 247e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k31c: 248e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k35c: 249e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k3rc: 250ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return 3; 251e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro case k51l: 252ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return 5; 253e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro default: 254e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro LOG(FATAL) << "Unreachable"; 255e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro } 256e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro } 257ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return 0; 25812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro} 25912eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro 260e4c1ce498f7933b91696caa4a527e6556128a8e2Carl ShapiroInstruction::Code Instruction::Opcode() const { 26112eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro const uint16_t* insns = reinterpret_cast<const uint16_t*>(this); 262e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro int opcode = *insns & 0xFF; 263e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro return static_cast<Code>(opcode); 26412eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro} 26512eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro 266e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroconst Instruction* Instruction::Next() const { 267d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers size_t current_size_in_bytes = SizeInCodeUnits() * sizeof(uint16_t); 26812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this); 269d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers return reinterpret_cast<const Instruction*>(ptr + current_size_in_bytes); 270d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers} 271d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers 2722c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpHex(size_t code_units) const { 273d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers size_t inst_length = SizeInCodeUnits(); 274d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers if (inst_length > code_units) { 275d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers inst_length = code_units; 276d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 2772c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers std::ostringstream os; 278d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers const uint16_t* insn = reinterpret_cast<const uint16_t*>(this); 279d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers for (size_t i = 0; i < inst_length; i++) { 2802c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers os << StringPrintf("0x%04x", insn[i]) << " "; 281d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 282d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers for (size_t i = inst_length; i < code_units; i++) { 283d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers os << " "; 284d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 2852c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers return os.str(); 286d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers} 287d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers 2882c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpString(const DexFile* file) const { 289d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers DecodedInstruction insn(this); 2902c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers std::ostringstream os; 291d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers const char* opcode = kInstructionNames[insn.opcode_]; 292d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers switch (Format()) { 293e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k10x: os << opcode; break; 294e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k12x: os << StringPrintf("%s v%d, v%d", opcode, insn.vA_, insn.vB_); break; 295e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k11n: os << StringPrintf("%s v%d, #%+d", opcode, insn.vA_, insn.vB_); break; 296e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k11x: os << StringPrintf("%s v%d", opcode, insn.vA_); break; 297e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k10t: os << StringPrintf("%s %+d", opcode, insn.vA_); break; 298e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k20bc: os << StringPrintf("%s %d, kind@%d", opcode, insn.vA_, insn.vB_); break; 299e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k20t: os << StringPrintf("%s %+d", opcode, insn.vA_); break; 300e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k22x: os << StringPrintf("%s v%d, v%d", opcode, insn.vA_, insn.vB_); break; 301e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k21t: os << StringPrintf("%s v%d, %+d", opcode, insn.vA_, insn.vB_); break; 302e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k21s: os << StringPrintf("%s v%d, #%+d", opcode, insn.vA_, insn.vB_); break; 303e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k21h: os << StringPrintf("%s v%d, #%+d00000[00000000]", opcode, insn.vA_, insn.vB_); break; 304e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k21c: os << StringPrintf("%s v%d, thing@%d", opcode, insn.vA_, insn.vB_); break; 305e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k23x: os << StringPrintf("%s v%d, v%d, v%d", opcode, insn.vA_, insn.vB_, insn.vC_); break; 306e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k22b: os << StringPrintf("%s v%d, v%d, #%+d", opcode, insn.vA_, insn.vB_, insn.vC_); break; 307e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k22t: os << StringPrintf("%s v%d, v%d, %+d", opcode, insn.vA_, insn.vB_, insn.vC_); break; 308e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k22s: os << StringPrintf("%s v%d, v%d, #%+d", opcode, insn.vA_, insn.vB_, insn.vC_); break; 309e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k22c: os << StringPrintf("%s v%d, v%d, thing@%d", opcode, insn.vA_, insn.vB_, insn.vC_); break; 310e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k32x: os << StringPrintf("%s v%d, v%d", opcode, insn.vA_, insn.vB_); break; 311e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k30t: os << StringPrintf("%s %+d", opcode, insn.vA_); break; 312e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k31t: os << StringPrintf("%s v%d, %+d", opcode, insn.vA_, insn.vB_); break; 313e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k31i: os << StringPrintf("%s v%d, #%+d", opcode, insn.vA_, insn.vB_); break; 314e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k31c: os << StringPrintf("%s v%d, thing@%d", opcode, insn.vA_, insn.vB_); break; 315d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case k35c: { 316d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers switch (insn.opcode_) { 317d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_VIRTUAL: 318d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_SUPER: 319d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_DIRECT: 320d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_STATIC: 321d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_INTERFACE: 322d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers if (file != NULL) { 323d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers const DexFile::MethodId& meth_id = file->GetMethodId(insn.vB_); 324e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes os << opcode << " {"; 325e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes for (size_t i = 0; i < insn.vA_; ++i) { 326e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes if (i != 0) { 327e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes os << ", "; 328e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes } 329e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes os << "v" << insn.arg_[i]; 330e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes } 331e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes os << "}, " 332e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes << file->GetMethodDeclaringClassDescriptor(meth_id) << "." 333e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes << file->GetMethodName(meth_id) << file->GetMethodSignature(meth_id) 334e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes << " // method@" << insn.vB_; 335d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers break; 336d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } // else fall-through 337d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers default: 338d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers os << opcode << " {v" << insn.arg_[0] << ", v" << insn.arg_[1] << ", v" << insn.arg_[2] 339d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers << ", v" << insn.arg_[3] << ", v" << insn.arg_[4] << "}, thing@" << insn.vB_; 340d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers break; 341d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 342d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers break; 343d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 344e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k3rc: os << StringPrintf("%s, {v%d .. v%d}, method@%d", opcode, insn.vC_, (insn.vC_+ insn.vA_ - 1), insn.vB_); break; 345e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k51l: os << StringPrintf("%s v%d, #%+d", opcode, insn.vA_, insn.vB_); break; 3462c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers default: os << " unknown format (" << DumpHex(5) << ")"; break; 347d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 3482c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers return os.str(); 34912eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro} 35012eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro 35112eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro} // namespace art 352