| 173 | } |
| 174 | |
| 175 | std::string Instruction::DumpString(const DexFile* file) const { |
| 176 | std::ostringstream os; |
| 177 | const char* opcode = kInstructionNames[Opcode()]; |
| 178 | switch (FormatOf(Opcode())) { |
| 179 | case k10x: os << opcode; break; |
| 180 | case k12x: os << StringPrintf("%s v%d, v%d", opcode, VRegA_12x(), VRegB_12x()); break; |
| 181 | case k11n: os << StringPrintf("%s v%d, #%+d", opcode, VRegA_11n(), VRegB_11n()); break; |
| 182 | case k11x: os << StringPrintf("%s v%d", opcode, VRegA_11x()); break; |
| 183 | case k10t: os << StringPrintf("%s %+d", opcode, VRegA_10t()); break; |
| 184 | case k20t: os << StringPrintf("%s %+d", opcode, VRegA_20t()); break; |
| 185 | case k22x: os << StringPrintf("%s v%d, v%d", opcode, VRegA_22x(), VRegB_22x()); break; |
| 186 | case k21t: os << StringPrintf("%s v%d, %+d", opcode, VRegA_21t(), VRegB_21t()); break; |
| 187 | case k21s: os << StringPrintf("%s v%d, #%+d", opcode, VRegA_21s(), VRegB_21s()); break; |
| 188 | case k21h: { |
| 189 | // op vAA, #+BBBB0000[00000000] |
| 190 | if (Opcode() == CONST_HIGH16) { |
| 191 | uint32_t value = VRegB_21h() << 16; |
| 192 | os << StringPrintf("%s v%d, #int %+d // 0x%x", opcode, VRegA_21h(), value, value); |
| 193 | } else { |
| 194 | uint64_t value = static_cast<uint64_t>(VRegB_21h()) << 48; |
| 195 | os << StringPrintf("%s v%d, #long %+" PRId64 " // 0x%" PRIx64, opcode, VRegA_21h(), |
| 196 | value, value); |
| 197 | } |
| 198 | } |
| 199 | break; |
| 200 | case k21c: { |
| 201 | switch (Opcode()) { |
| 202 | case CONST_STRING: |
| 203 | if (file != nullptr) { |
| 204 | uint32_t string_idx = VRegB_21c(); |
| 205 | if (string_idx < file->NumStringIds()) { |
| 206 | os << StringPrintf( |
| 207 | "const-string v%d, %s // string@%d", |
| 208 | VRegA_21c(), |
| 209 | PrintableString(file->StringDataByIdx(dex::StringIndex(string_idx))).c_str(), |
| 210 | string_idx); |
| 211 | } else { |
| 212 | os << StringPrintf("const-string v%d, <<invalid-string-idx-%d>> // string@%d", |
| 213 | VRegA_21c(), |
| 214 | string_idx, |
| 215 | string_idx); |
| 216 | } |
| 217 | break; |
| 218 | } |
| 219 | FALLTHROUGH_INTENDED; |
| 220 | case CHECK_CAST: |
| 221 | case CONST_CLASS: |
| 222 | case NEW_INSTANCE: |
| 223 | if (file != nullptr) { |
| 224 | dex::TypeIndex type_idx(VRegB_21c()); |
| 225 | os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " |
| 226 | << file->PrettyType(type_idx) << " // type@" << type_idx; |
| 227 | break; |
| 228 | } |
| 229 | FALLTHROUGH_INTENDED; |
| 230 | case SGET: |
| 231 | case SGET_WIDE: |
| 232 | case SGET_OBJECT: |
nothing calls this directly
no test coverage detected