diff options
author | Brian Carlstrom <bdc@google.com> | 2014-09-14 20:34:17 -0700 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2014-09-16 12:50:08 -0700 |
commit | 2cbaccb67e22c0b313a9785bfc65bcb4b25d0676 (patch) | |
tree | daeb766e19880b651fd9c4a719c9a07dd7d4bd0e /disassembler | |
parent | bace0378d720a1d2938ec7f6be17e2814671d20a (diff) | |
download | art-2cbaccb67e22c0b313a9785bfc65bcb4b25d0676.zip art-2cbaccb67e22c0b313a9785bfc65bcb4b25d0676.tar.gz art-2cbaccb67e22c0b313a9785bfc65bcb4b25d0676.tar.bz2 |
Avoid printing absolute addresses in oatdump
- Added printing of OatClass offsets.
- Added printing of OatMethod offsets.
- Added bounds checks for code size size, code size, mapping table, gc map, vmap table.
- Added sanity check of 100k for code size.
- Added partial disassembly of questionable code.
- Added --no-disassemble to disable disassembly.
- Added --no-dump:vmap to disable vmap dumping.
- Reordered OatMethod info to be in file order.
Bug: 15567083
(cherry picked from commit 34fa79ece5b3a1940d412cd94dbdcc4225aae72f)
Change-Id: I2c368f3b81af53b735149a866f3e491c9ac33fb8
Diffstat (limited to 'disassembler')
-rw-r--r-- | disassembler/disassembler.cc | 22 | ||||
-rw-r--r-- | disassembler/disassembler.h | 33 | ||||
-rw-r--r-- | disassembler/disassembler_arm.cc | 14 | ||||
-rw-r--r-- | disassembler/disassembler_arm.h | 3 | ||||
-rw-r--r-- | disassembler/disassembler_arm64.cc | 3 | ||||
-rw-r--r-- | disassembler/disassembler_arm64.h | 2 | ||||
-rw-r--r-- | disassembler/disassembler_mips.cc | 15 | ||||
-rw-r--r-- | disassembler/disassembler_mips.h | 3 | ||||
-rw-r--r-- | disassembler/disassembler_x86.cc | 8 | ||||
-rw-r--r-- | disassembler/disassembler_x86.h | 4 |
10 files changed, 75 insertions, 32 deletions
diff --git a/disassembler/disassembler.cc b/disassembler/disassembler.cc index 41ee213..c97bf64 100644 --- a/disassembler/disassembler.cc +++ b/disassembler/disassembler.cc @@ -19,6 +19,7 @@ #include <iostream> #include "base/logging.h" +#include "base/stringprintf.h" #include "disassembler_arm.h" #include "disassembler_arm64.h" #include "disassembler_mips.h" @@ -26,21 +27,30 @@ namespace art { -Disassembler* Disassembler::Create(InstructionSet instruction_set) { +Disassembler* Disassembler::Create(InstructionSet instruction_set, DisassemblerOptions* options) { if (instruction_set == kArm || instruction_set == kThumb2) { - return new arm::DisassemblerArm(); + return new arm::DisassemblerArm(options); } else if (instruction_set == kArm64) { - return new arm64::DisassemblerArm64(); + return new arm64::DisassemblerArm64(options); } else if (instruction_set == kMips) { - return new mips::DisassemblerMips(); + return new mips::DisassemblerMips(options); } else if (instruction_set == kX86) { - return new x86::DisassemblerX86(false); + return new x86::DisassemblerX86(options, false); } else if (instruction_set == kX86_64) { - return new x86::DisassemblerX86(true); + return new x86::DisassemblerX86(options, true); } else { UNIMPLEMENTED(FATAL) << "no disassembler for " << instruction_set; return NULL; } } +std::string Disassembler::FormatInstructionPointer(const uint8_t* begin) { + if (disassembler_options_->absolute_addresses_) { + return StringPrintf("%p", begin); + } else { + size_t offset = begin - disassembler_options_->base_address_; + return StringPrintf("0x%08zx", offset); + } +} + } // namespace art diff --git a/disassembler/disassembler.h b/disassembler/disassembler.h index 183e692..487f433 100644 --- a/disassembler/disassembler.h +++ b/disassembler/disassembler.h @@ -26,10 +26,31 @@ namespace art { +class DisassemblerOptions { + public: + // Should the disassembler print absolute or relative addresses. + const bool absolute_addresses_; + + // Base addess for calculating relative code offsets when absolute_addresses_ is false. + const uint8_t* const base_address_; + + DisassemblerOptions(bool absolute_addresses, const uint8_t* base_address) + : absolute_addresses_(absolute_addresses), base_address_(base_address) {} + + private: + DISALLOW_COPY_AND_ASSIGN(DisassemblerOptions); +}; + class Disassembler { public: - static Disassembler* Create(InstructionSet instruction_set); - virtual ~Disassembler() {} + // Creates a Disassembler for the given InstructionSet with the + // non-null DisassemblerOptions which become owned by the + // Disassembler. + static Disassembler* Create(InstructionSet instruction_set, DisassemblerOptions* options); + + virtual ~Disassembler() { + delete disassembler_options_; + } // Dump a single instruction returning the length of that instruction. virtual size_t Dump(std::ostream& os, const uint8_t* begin) = 0; @@ -37,9 +58,15 @@ class Disassembler { virtual void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) = 0; protected: - Disassembler() {} + explicit Disassembler(DisassemblerOptions* disassembler_options) + : disassembler_options_(disassembler_options) { + CHECK(disassembler_options_ != nullptr); + } + + std::string FormatInstructionPointer(const uint8_t* begin); private: + DisassemblerOptions* disassembler_options_; DISALLOW_COPY_AND_ASSIGN(Disassembler); }; diff --git a/disassembler/disassembler_arm.cc b/disassembler/disassembler_arm.cc index 56023c1..54e7761 100644 --- a/disassembler/disassembler_arm.cc +++ b/disassembler/disassembler_arm.cc @@ -94,7 +94,7 @@ void DisassemblerArm::DumpMemoryDomain(std::ostream& os, uint32_t domain) { } void DisassemblerArm::DumpBranchTarget(std::ostream& os, const uint8_t* instr_ptr, int32_t imm32) { - os << StringPrintf("%+d (%p)", imm32, instr_ptr + imm32); + os << StringPrintf("%+d (", imm32) << FormatInstructionPointer(instr_ptr + imm32) << ")"; } static uint32_t ReadU16(const uint8_t* ptr) { @@ -356,7 +356,9 @@ void DisassemblerArm::DumpArm(std::ostream& os, const uint8_t* instr_ptr) { opcode += kConditionCodeNames[cond]; opcode += suffixes; // TODO: a more complete ARM disassembler could generate wider opcodes. - os << StringPrintf("%p: %08x\t%-7s ", instr_ptr, instruction, opcode.c_str()) << args.str() << '\n'; + os << FormatInstructionPointer(instr_ptr) + << StringPrintf(": %08x\t%-7s ", instruction, opcode.c_str()) + << args.str() << '\n'; } int32_t ThumbExpand(int32_t imm12) { @@ -1608,7 +1610,9 @@ size_t DisassemblerArm::DumpThumb32(std::ostream& os, const uint8_t* instr_ptr) opcode << "UNKNOWN " << op2; } - os << StringPrintf("%p: %08x\t%-7s ", instr_ptr, instr, opcode.str().c_str()) << args.str() << '\n'; + os << FormatInstructionPointer(instr_ptr) + << StringPrintf(": %08x\t%-7s ", instr, opcode.str().c_str()) + << args.str() << '\n'; return 4; } // NOLINT(readability/fn_size) @@ -1936,7 +1940,9 @@ size_t DisassemblerArm::DumpThumb16(std::ostream& os, const uint8_t* instr_ptr) it_conditions_.pop_back(); } - os << StringPrintf("%p: %04x \t%-7s ", instr_ptr, instr, opcode.str().c_str()) << args.str() << '\n'; + os << FormatInstructionPointer(instr_ptr) + << StringPrintf(": %04x \t%-7s ", instr, opcode.str().c_str()) + << args.str() << '\n'; } return 2; } diff --git a/disassembler/disassembler_arm.h b/disassembler/disassembler_arm.h index f6d7fda..f870e8e 100644 --- a/disassembler/disassembler_arm.h +++ b/disassembler/disassembler_arm.h @@ -26,8 +26,7 @@ namespace arm { class DisassemblerArm FINAL : public Disassembler { public: - DisassemblerArm() { - } + explicit DisassemblerArm(DisassemblerOptions* options) : Disassembler(options) {} size_t Dump(std::ostream& os, const uint8_t* begin) OVERRIDE; void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) OVERRIDE; diff --git a/disassembler/disassembler_arm64.cc b/disassembler/disassembler_arm64.cc index 864d22d..5d0c218 100644 --- a/disassembler/disassembler_arm64.cc +++ b/disassembler/disassembler_arm64.cc @@ -34,7 +34,8 @@ static uint32_t ReadU32(const uint8_t* ptr) { size_t DisassemblerArm64::Dump(std::ostream& os, const uint8_t* begin) { uint32_t instruction = ReadU32(begin); decoder.Decode(reinterpret_cast<vixl::Instruction*>(&instruction)); - os << StringPrintf("%p: %08x\t%s\n", begin, instruction, disasm.GetOutput()); + os << FormatInstructionPointer(begin) + << StringPrintf(": %08x\t%s\n", instruction, disasm.GetOutput()); return vixl::kInstructionSize; } diff --git a/disassembler/disassembler_arm64.h b/disassembler/disassembler_arm64.h index 28c0fa7..ad20c70 100644 --- a/disassembler/disassembler_arm64.h +++ b/disassembler/disassembler_arm64.h @@ -27,7 +27,7 @@ namespace arm64 { class DisassemblerArm64 FINAL : public Disassembler { public: - DisassemblerArm64() { + explicit DisassemblerArm64(DisassemblerOptions* options) : Disassembler(options) { decoder.AppendVisitor(&disasm); } diff --git a/disassembler/disassembler_mips.cc b/disassembler/disassembler_mips.cc index 5e89f6f..bd5fac7 100644 --- a/disassembler/disassembler_mips.cc +++ b/disassembler/disassembler_mips.cc @@ -168,7 +168,7 @@ static uint32_t ReadU32(const uint8_t* ptr) { return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); } -static void DumpMips(std::ostream& os, const uint8_t* instr_ptr) { +size_t DisassemblerMips::Dump(std::ostream& os, const uint8_t* instr_ptr) { uint32_t instruction = ReadU32(instr_ptr); uint32_t rs = (instruction >> 21) & 0x1f; // I-type, R-type. @@ -197,7 +197,8 @@ static void DumpMips(std::ostream& os, const uint8_t* instr_ptr) { int32_t offset = static_cast<int16_t>(instruction & 0xffff); offset <<= 2; offset += 4; // Delay slot. - args << StringPrintf("%p ; %+d", instr_ptr + offset, offset); + args << FormatInstructionPointer(instr_ptr + offset) + << StringPrintf(" ; %+d", offset); } break; case 'D': args << 'r' << rd; break; @@ -254,17 +255,15 @@ static void DumpMips(std::ostream& os, const uint8_t* instr_ptr) { } } - os << StringPrintf("%p: %08x\t%-7s ", instr_ptr, instruction, opcode.c_str()) << args.str() << '\n'; -} - -size_t DisassemblerMips::Dump(std::ostream& os, const uint8_t* begin) { - DumpMips(os, begin); + os << FormatInstructionPointer(instr_ptr) + << StringPrintf(": %08x\t%-7s ", instruction, opcode.c_str()) + << args.str() << '\n'; return 4; } void DisassemblerMips::Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) { for (const uint8_t* cur = begin; cur < end; cur += 4) { - DumpMips(os, cur); + Dump(os, cur); } } diff --git a/disassembler/disassembler_mips.h b/disassembler/disassembler_mips.h index e1fb034..00b2f8d 100644 --- a/disassembler/disassembler_mips.h +++ b/disassembler/disassembler_mips.h @@ -26,8 +26,7 @@ namespace mips { class DisassemblerMips FINAL : public Disassembler { public: - DisassemblerMips() { - } + explicit DisassemblerMips(DisassemblerOptions* options) : Disassembler(options) {} size_t Dump(std::ostream& os, const uint8_t* begin) OVERRIDE; void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) OVERRIDE; diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 1848abe..1d29765 100644 --- a/disassembler/disassembler_x86.cc +++ b/disassembler/disassembler_x86.cc @@ -1215,7 +1215,9 @@ DISASSEMBLER_ENTRY(cmp, displacement = *reinterpret_cast<const int32_t*>(instr); instr += 4; } - args << StringPrintf("%+d (%p)", displacement, instr + displacement); + args << StringPrintf("%+d (", displacement) + << FormatInstructionPointer(instr + displacement) + << ")"; } if (prefix[1] == kFs && !supports_rex_) { args << " ; "; @@ -1238,8 +1240,8 @@ DISASSEMBLER_ENTRY(cmp, default: LOG(FATAL) << "Unreachable"; } prefixed_opcode << opcode.str(); - os << StringPrintf("%p: %22s \t%-7s ", begin_instr, hex.str().c_str(), - prefixed_opcode.str().c_str()) + os << FormatInstructionPointer(begin_instr) + << StringPrintf(": %22s \t%-7s ", hex.str().c_str(), prefixed_opcode.str().c_str()) << args.str() << '\n'; return instr - begin_instr; } // NOLINT(readability/fn_size) diff --git a/disassembler/disassembler_x86.h b/disassembler/disassembler_x86.h index 2565bb1..f448662 100644 --- a/disassembler/disassembler_x86.h +++ b/disassembler/disassembler_x86.h @@ -24,8 +24,8 @@ namespace x86 { class DisassemblerX86 FINAL : public Disassembler { public: - explicit DisassemblerX86(bool supports_rex) : supports_rex_(supports_rex) { - } + DisassemblerX86(DisassemblerOptions* options, bool supports_rex) + : Disassembler(options), supports_rex_(supports_rex) {} size_t Dump(std::ostream& os, const uint8_t* begin) OVERRIDE; void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) OVERRIDE; |