diff options
author | Vladimir Marko <vmarko@google.com> | 2020-09-03 09:59:45 +0100 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2020-09-03 11:11:19 +0000 |
commit | 8feddbc07bd1e05ed7aa5cf5fc66f7b2c3c24c31 (patch) | |
tree | 79401419489919a0051cd7e014a1b1ea3137c51f /disassembler/disassembler_arm64.cc | |
parent | d111cd22792c1cda507e343e46762842956a2c9b (diff) |
Improve disasembly of BL to thread entrypoint trampoline.
Test: Manual, search for "\bbl\b" in `m dump-oat` output and
oatdump of an individual oat file for arm and arm64.
Change-Id: Idb6d8d1a21b2aa8c77e5b72f24faf7a4e655294c
Diffstat (limited to 'disassembler/disassembler_arm64.cc')
-rw-r--r-- | disassembler/disassembler_arm64.cc | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/disassembler/disassembler_arm64.cc b/disassembler/disassembler_arm64.cc index 49b9623f4f..0d51cfdc1a 100644 --- a/disassembler/disassembler_arm64.cc +++ b/disassembler/disassembler_arm64.cc @@ -101,13 +101,35 @@ void CustomDisassembler::VisitLoadStoreUnsignedOffset(const Instruction* instr) Disassembler::VisitLoadStoreUnsignedOffset(instr); if (instr->GetRn() == TR) { - int64_t offset = instr->GetImmLSUnsigned() << instr->GetSizeLS(); - std::ostringstream tmp_stream; - options_->thread_offset_name_function_(tmp_stream, static_cast<uint32_t>(offset)); - AppendToOutput(" ; %s", tmp_stream.str().c_str()); + AppendThreadOfsetName(instr); } } +void CustomDisassembler::VisitUnconditionalBranch(const Instruction* instr) { + Disassembler::VisitUnconditionalBranch(instr); + + if (instr->Mask(UnconditionalBranchMask) == BL) { + const Instruction* target = instr->GetImmPCOffsetTarget(); + if (target >= base_address_ && + target < end_address_ && + target->Mask(LoadStoreMask) == LDR_x && + target->GetRn() == TR && + target->GetRt() == IP0 && + target->GetNextInstruction() < end_address_ && + target->GetNextInstruction()->Mask(UnconditionalBranchToRegisterMask) == BR && + target->GetNextInstruction()->GetRn() == IP0) { + AppendThreadOfsetName(target); + } + } +} + +void CustomDisassembler::AppendThreadOfsetName(const vixl::aarch64::Instruction* instr) { + int64_t offset = instr->GetImmLSUnsigned() << instr->GetSizeLS(); + std::ostringstream tmp_stream; + options_->thread_offset_name_function_(tmp_stream, static_cast<uint32_t>(offset)); + AppendToOutput(" ; %s", tmp_stream.str().c_str()); +} + size_t DisassemblerArm64::Dump(std::ostream& os, const uint8_t* begin) { const Instruction* instr = reinterpret_cast<const Instruction*>(begin); decoder.Decode(instr); |