From 372f3a374681ef11f003460e14249adb7bc8313d Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Fri, 19 Aug 2016 10:49:06 -0700 Subject: [PATCH] ART: Add thread offset printing hook to disassembler To prepare separation of disassembler from libart, add a function hook to the disassembler options for thread offset name printing. Bug: 15436106 Change-Id: I9e9b7e565ae923952c64026f675ac527b560f51b --- compiler/cfi_test.h | 10 +++++++++- compiler/optimizing/graph_visualizer.cc | 5 ++++- disassembler/disassembler.cc | 6 ++---- disassembler/disassembler.h | 14 ++++++++++---- disassembler/disassembler_arm.cc | 5 ++--- disassembler/disassembler_arm64.cc | 3 +-- disassembler/disassembler_arm64.h | 5 ++++- disassembler/disassembler_mips.cc | 7 +------ disassembler/disassembler_mips.h | 5 +---- disassembler/disassembler_x86.cc | 5 ++--- oatdump/oatdump.cc | 14 +++++++++----- 11 files changed, 45 insertions(+), 34 deletions(-) diff --git a/compiler/cfi_test.h b/compiler/cfi_test.h index f8b746093..c754e5588 100644 --- a/compiler/cfi_test.h +++ b/compiler/cfi_test.h @@ -22,11 +22,13 @@ #include #include "arch/instruction_set.h" +#include "base/enums.h" #include "debug/dwarf/dwarf_constants.h" #include "debug/dwarf/dwarf_test.h" #include "debug/dwarf/headers.h" #include "disassembler/disassembler.h" #include "gtest/gtest.h" +#include "thread.h" namespace art { @@ -57,7 +59,13 @@ class CFITest : public dwarf::DwarfTest { // Pretty-print assembly. const uint8_t* asm_base = actual_asm.data(); const uint8_t* asm_end = asm_base + actual_asm.size(); - auto* opts = new DisassemblerOptions(false, asm_base, asm_end, true); + auto* opts = new DisassemblerOptions(false, + asm_base, + asm_end, + true, + is64bit + ? &Thread::DumpThreadOffset + : &Thread::DumpThreadOffset); std::unique_ptr disasm(Disassembler::Create(isa, opts)); std::stringstream stream; const uint8_t* base = actual_asm.data() + (isa == kThumb2 ? 1 : 0); diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index 89d80cc28..b3d5341de 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -122,7 +122,10 @@ class HGraphVisualizerDisassembler { new DisassemblerOptions(/* absolute_addresses */ false, base_address, end_address, - /* can_read_literals */ true))); + /* can_read_literals */ true, + Is64BitInstructionSet(instruction_set) + ? &Thread::DumpThreadOffset + : &Thread::DumpThreadOffset))); } ~HGraphVisualizerDisassembler() { diff --git a/disassembler/disassembler.cc b/disassembler/disassembler.cc index e604c1f62..bcd0d1630 100644 --- a/disassembler/disassembler.cc +++ b/disassembler/disassembler.cc @@ -32,10 +32,8 @@ Disassembler* Disassembler::Create(InstructionSet instruction_set, DisassemblerO return new arm::DisassemblerArm(options); } else if (instruction_set == kArm64) { return new arm64::DisassemblerArm64(options); - } else if (instruction_set == kMips) { - return new mips::DisassemblerMips(options, false); - } else if (instruction_set == kMips64) { - return new mips::DisassemblerMips(options, true); + } else if (instruction_set == kMips || instruction_set == kMips64) { + return new mips::DisassemblerMips(options); } else if (instruction_set == kX86) { return new x86::DisassemblerX86(options, false); } else if (instruction_set == kX86_64) { diff --git a/disassembler/disassembler.h b/disassembler/disassembler.h index b08031587..86793ccb1 100644 --- a/disassembler/disassembler.h +++ b/disassembler/disassembler.h @@ -28,8 +28,9 @@ namespace art { class DisassemblerOptions { public: - // Should the disassembler print absolute or relative addresses. - const bool absolute_addresses_; + using ThreadOffsetNameFunction = void (*)(std::ostream& os, uint32_t offset); + + ThreadOffsetNameFunction thread_offset_name_function_; // Base address for calculating relative code offsets when absolute_addresses_ is false. const uint8_t* const base_address_; @@ -37,6 +38,9 @@ class DisassemblerOptions { // End address (exclusive); const uint8_t* const end_address_; + // Should the disassembler print absolute or relative addresses. + const bool absolute_addresses_; + // If set, the disassembler is allowed to look at load targets in literal // pools. const bool can_read_literals_; @@ -44,10 +48,12 @@ class DisassemblerOptions { DisassemblerOptions(bool absolute_addresses, const uint8_t* base_address, const uint8_t* end_address, - bool can_read_literals) - : absolute_addresses_(absolute_addresses), + bool can_read_literals, + ThreadOffsetNameFunction fn) + : thread_offset_name_function_(fn), base_address_(base_address), end_address_(end_address), + absolute_addresses_(absolute_addresses), can_read_literals_(can_read_literals) {} private: diff --git a/disassembler/disassembler_arm.cc b/disassembler/disassembler_arm.cc index 4f0e144aa..a47b6adcc 100644 --- a/disassembler/disassembler_arm.cc +++ b/disassembler/disassembler_arm.cc @@ -25,7 +25,6 @@ #include "base/bit_utils.h" #include "base/logging.h" #include "base/stringprintf.h" -#include "thread.h" namespace art { namespace arm { @@ -329,7 +328,7 @@ void DisassemblerArm::DumpArm(std::ostream& os, const uint8_t* instr_ptr) { } if (rn.r == 9) { args << " ; "; - Thread::DumpThreadOffset(args, offset); + GetDisassemblerOptions()->thread_offset_name_function_(args, offset); } } } @@ -1401,7 +1400,7 @@ size_t DisassemblerArm::DumpThumb32(std::ostream& os, const uint8_t* instr_ptr) args << Rt << ", [" << Rn << ", #" << (U != 0u ? "" : "-") << imm12 << "]"; if (Rn.r == TR && is_load) { args << " ; "; - Thread::DumpThreadOffset(args, imm12); + GetDisassemblerOptions()->thread_offset_name_function_(args, imm12); } else if (Rn.r == PC) { T2LitType lit_type[] = { kT2LitUByte, kT2LitUHalf, kT2LitHexWord, kT2LitInvalid, diff --git a/disassembler/disassembler_arm64.cc b/disassembler/disassembler_arm64.cc index 0ef9025cd..80bacb2be 100644 --- a/disassembler/disassembler_arm64.cc +++ b/disassembler/disassembler_arm64.cc @@ -22,7 +22,6 @@ #include "base/logging.h" #include "base/stringprintf.h" -#include "thread.h" using namespace vixl::aarch64; // NOLINT(build/namespaces) @@ -102,7 +101,7 @@ void CustomDisassembler::VisitLoadStoreUnsignedOffset(const Instruction* instr) if (instr->GetRn() == TR) { int64_t offset = instr->GetImmLSUnsigned() << instr->GetSizeLS(); std::ostringstream tmp_stream; - Thread::DumpThreadOffset(tmp_stream, static_cast(offset)); + options_->thread_offset_name_function_(tmp_stream, static_cast(offset)); AppendToOutput(" ; %s", tmp_stream.str().c_str()); } } diff --git a/disassembler/disassembler_arm64.h b/disassembler/disassembler_arm64.h index 7c64792b1..19e4dfb48 100644 --- a/disassembler/disassembler_arm64.h +++ b/disassembler/disassembler_arm64.h @@ -35,7 +35,8 @@ class CustomDisassembler FINAL : public vixl::aarch64::Disassembler { : vixl::aarch64::Disassembler(), read_literals_(options->can_read_literals_), base_address_(options->base_address_), - end_address_(options->end_address_) { + end_address_(options->end_address_), + options_(options) { if (!options->absolute_addresses_) { MapCodeAddress(0, reinterpret_cast(options->base_address_)); @@ -64,6 +65,8 @@ class CustomDisassembler FINAL : public vixl::aarch64::Disassembler { // Valid address range: [base_address_, end_address_) const void* const base_address_; const void* const end_address_; + + DisassemblerOptions* options_; }; class DisassemblerArm64 FINAL : public Disassembler { diff --git a/disassembler/disassembler_mips.cc b/disassembler/disassembler_mips.cc index 344887839..02c6d7151 100644 --- a/disassembler/disassembler_mips.cc +++ b/disassembler/disassembler_mips.cc @@ -21,7 +21,6 @@ #include "base/logging.h" #include "base/stringprintf.h" -#include "thread.h" namespace art { namespace mips { @@ -503,11 +502,7 @@ size_t DisassemblerMips::Dump(std::ostream& os, const uint8_t* instr_ptr) { args << StringPrintf("%+d(r%d)", offset, rs); if (rs == 17) { args << " ; "; - if (is64bit_) { - Thread::DumpThreadOffset(args, offset); - } else { - Thread::DumpThreadOffset(args, offset); - } + GetDisassemblerOptions()->thread_offset_name_function_(args, offset); } } break; diff --git a/disassembler/disassembler_mips.h b/disassembler/disassembler_mips.h index b0e49b397..6342f2296 100644 --- a/disassembler/disassembler_mips.h +++ b/disassembler/disassembler_mips.h @@ -26,9 +26,8 @@ namespace mips { class DisassemblerMips FINAL : public Disassembler { public: - DisassemblerMips(DisassemblerOptions* options, bool is64bit) + explicit DisassemblerMips(DisassemblerOptions* options) : Disassembler(options), - is64bit_(is64bit), last_ptr_(nullptr), last_instr_(0) {} @@ -36,8 +35,6 @@ class DisassemblerMips FINAL : public Disassembler { void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) OVERRIDE; private: - const bool is64bit_; - // Address and encoding of the last disassembled instruction. // Needed to produce more readable disassembly of certain 2-instruction sequences. const uint8_t* last_ptr_; diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 147e0b142..2ca84e5e5 100644 --- a/disassembler/disassembler_x86.cc +++ b/disassembler/disassembler_x86.cc @@ -23,7 +23,6 @@ #include "base/logging.h" #include "base/stringprintf.h" -#include "thread.h" namespace art { namespace x86 { @@ -1409,11 +1408,11 @@ DISASSEMBLER_ENTRY(cmp, } if (prefix[1] == kFs && !supports_rex_) { args << " ; "; - Thread::DumpThreadOffset(args, address_bits); + GetDisassemblerOptions()->thread_offset_name_function_(args, address_bits); } if (prefix[1] == kGs && supports_rex_) { args << " ; "; - Thread::DumpThreadOffset(args, address_bits); + GetDisassemblerOptions()->thread_offset_name_function_(args, address_bits); } const char* prefix_str; switch (prefix[0]) { diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 77730b925..96c8e94d9 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -335,10 +335,14 @@ class OatDumper { resolved_addr2instr_(0), instruction_set_(oat_file_.GetOatHeader().GetInstructionSet()), disassembler_(Disassembler::Create(instruction_set_, - new DisassemblerOptions(options_.absolute_addresses_, - oat_file.Begin(), - oat_file.End(), - true /* can_read_literals_ */))) { + new DisassemblerOptions( + options_.absolute_addresses_, + oat_file.Begin(), + oat_file.End(), + true /* can_read_literals_ */, + Is64BitInstructionSet(instruction_set_) + ? &Thread::DumpThreadOffset + : &Thread::DumpThreadOffset))) { CHECK(options_.class_loader_ != nullptr); CHECK(options_.class_filter_ != nullptr); CHECK(options_.method_filter_ != nullptr); @@ -1402,7 +1406,7 @@ class OatDumper { const std::vector oat_dex_files_; const OatDumperOptions& options_; uint32_t resolved_addr2instr_; - InstructionSet instruction_set_; + const InstructionSet instruction_set_; std::set offsets_; Disassembler* disassembler_; }; -- 2.11.0