summaryrefslogtreecommitdiffstats
path: root/disassembler
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2014-09-14 20:34:17 -0700
committerBrian Carlstrom <bdc@google.com>2014-09-16 12:50:08 -0700
commit2cbaccb67e22c0b313a9785bfc65bcb4b25d0676 (patch)
treedaeb766e19880b651fd9c4a719c9a07dd7d4bd0e /disassembler
parentbace0378d720a1d2938ec7f6be17e2814671d20a (diff)
downloadart-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.cc22
-rw-r--r--disassembler/disassembler.h33
-rw-r--r--disassembler/disassembler_arm.cc14
-rw-r--r--disassembler/disassembler_arm.h3
-rw-r--r--disassembler/disassembler_arm64.cc3
-rw-r--r--disassembler/disassembler_arm64.h2
-rw-r--r--disassembler/disassembler_mips.cc15
-rw-r--r--disassembler/disassembler_mips.h3
-rw-r--r--disassembler/disassembler_x86.cc8
-rw-r--r--disassembler/disassembler_x86.h4
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;