diff options
Diffstat (limited to 'lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp')
-rw-r--r-- | lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | 200 |
1 files changed, 99 insertions, 101 deletions
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index e358a1b..9eb22fdf 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -47,11 +47,11 @@ public: InstructionLLVMC (DisassemblerLLVMC &disasm, const lldb_private::Address &address, AddressClass addr_class) : - Instruction(address, addr_class), - m_is_valid(false), - m_disasm(disasm), - m_disasm_sp(disasm.shared_from_this()), - m_does_branch(eLazyBoolCalculate) + Instruction (address, addr_class), + m_disasm_sp (disasm.shared_from_this()), + m_does_branch (eLazyBoolCalculate), + m_is_valid (false), + m_using_file_addr (false) { } @@ -60,24 +60,12 @@ public: { } - static void - PadToWidth (lldb_private::StreamString &ss, - int new_width) - { - int old_width = ss.GetSize(); - - if (old_width < new_width) - { - ss.Printf("%*s", new_width - old_width, ""); - } - } - virtual bool DoesBranch () { if (m_does_branch == eLazyBoolCalculate) { - m_disasm.Lock(this, NULL); + GetDisassemblerLLVMC().Lock(this, NULL); DataExtractor data; if (m_opcode.GetData(data)) { @@ -85,26 +73,26 @@ public: lldb::addr_t pc = m_address.GetFileAddress(); DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa); - uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1)); + const uint8_t *opcode_data = data.GetDataStart(); const size_t opcode_data_len = data.GetByteSize(); llvm::MCInst inst; - size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data, - opcode_data_len, - pc, - inst); + const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data, + opcode_data_len, + pc, + inst); // Be conservative, if we didn't understand the instruction, say it might branch... if (inst_size == 0) m_does_branch = eLazyBoolYes; else { - bool can_branch = mc_disasm_ptr->CanBranch(inst); + const bool can_branch = mc_disasm_ptr->CanBranch(inst); if (can_branch) m_does_branch = eLazyBoolYes; else m_does_branch = eLazyBoolNo; } } - m_disasm.Unlock(); + GetDisassemblerLLVMC().Unlock(); } return m_does_branch == eLazyBoolYes; } @@ -112,20 +100,19 @@ public: DisassemblerLLVMC::LLVMCDisassembler * GetDisasmToUse (bool &is_alternate_isa) { - DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = m_disasm.m_disasm_ap.get(); - is_alternate_isa = false; - if (m_disasm.m_alternate_disasm_ap.get() != NULL) + DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC(); + if (llvm_disasm.m_alternate_disasm_ap.get() != NULL) { const AddressClass address_class = GetAddressClass (); if (address_class == eAddressClassCodeAlternateISA) { - mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get(); is_alternate_isa = true; + return llvm_disasm.m_alternate_disasm_ap.get(); } } - return mc_disasm_ptr; + return llvm_disasm.m_disasm_ap.get(); } virtual size_t @@ -136,7 +123,8 @@ public: // All we have to do is read the opcode which can be easy for some // architetures bool got_op = false; - const ArchSpec &arch = m_disasm.GetArchitecture(); + DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC(); + const ArchSpec &arch = llvm_disasm.GetArchitecture(); const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize(); const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize(); @@ -179,17 +167,6 @@ public: bool is_alternate_isa = false; DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa); - if (m_disasm.m_alternate_disasm_ap.get() != NULL) - { - const AddressClass address_class = GetAddressClass (); - - if (address_class == eAddressClassCodeAlternateISA) - { - mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get(); - is_alternate_isa = true; - } - } - const llvm::Triple::ArchType machine = arch.GetMachine(); if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) { @@ -219,17 +196,17 @@ public: { // The opcode isn't evenly sized, so we need to actually use the llvm // disassembler to parse it and get the size. - m_disasm.Lock(this, NULL); uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1)); - const size_t opcode_data_len = data.GetByteSize() - data_offset; + const size_t opcode_data_len = data.BytesLeft(data_offset); const addr_t pc = m_address.GetFileAddress(); llvm::MCInst inst; + llvm_disasm.Lock(this, NULL); const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data, - opcode_data_len, - pc, - inst); - m_disasm.Unlock(); + opcode_data_len, + pc, + inst); + llvm_disasm.Unlock(); if (inst_size == 0) m_opcode.Clear(); else @@ -264,39 +241,50 @@ public: { char out_string[512]; + DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC(); + DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr; if (address_class == eAddressClassCodeAlternateISA) - mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get(); + mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get(); else - mc_disasm_ptr = m_disasm.m_disasm_ap.get(); + mc_disasm_ptr = llvm_disasm.m_disasm_ap.get(); - lldb::addr_t pc = LLDB_INVALID_ADDRESS; + lldb::addr_t pc = m_address.GetFileAddress(); + m_using_file_addr = true; - if (exe_ctx) + const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file; + if (!data_from_file) { - Target *target = exe_ctx->GetTargetPtr(); - if (target) - pc = m_address.GetLoadAddress(target); + if (exe_ctx) + { + Target *target = exe_ctx->GetTargetPtr(); + if (target) + { + const lldb::addr_t load_addr = m_address.GetLoadAddress(target); + if (load_addr != LLDB_INVALID_ADDRESS) + { + pc = load_addr; + m_using_file_addr = false; + } + } + } } - if (pc == LLDB_INVALID_ADDRESS) - pc = m_address.GetFileAddress(); - - m_disasm.Lock(this, exe_ctx); + llvm_disasm.Lock(this, exe_ctx); - uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1)); + const uint8_t *opcode_data = data.GetDataStart(); const size_t opcode_data_len = data.GetByteSize(); llvm::MCInst inst; - size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data, - opcode_data_len, - pc, - inst); + size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data, + opcode_data_len, + pc, + inst); if (inst_size > 0) mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string)); - m_disasm.Unlock(); + llvm_disasm.Unlock(); if (inst_size == 0) { @@ -361,7 +349,7 @@ public: { if (m_does_branch == eLazyBoolCalculate) { - bool can_branch = mc_disasm_ptr->CanBranch(inst); + const bool can_branch = mc_disasm_ptr->CanBranch(inst); if (can_branch) m_does_branch = eLazyBoolYes; else @@ -389,22 +377,33 @@ public: } bool - IsValid () + IsValid () const { return m_is_valid; } + bool + UsingFileAddress() const + { + return m_using_file_addr; + } size_t - GetByteSize () + GetByteSize () const { return m_opcode.GetByteSize(); } + + DisassemblerLLVMC & + GetDisassemblerLLVMC () + { + return *(DisassemblerLLVMC *)m_disasm_sp.get(); + } protected: - bool m_is_valid; - DisassemblerLLVMC &m_disasm; DisassemblerSP m_disasm_sp; // for ownership LazyBool m_does_branch; + bool m_is_valid; + bool m_using_file_addr; static bool s_regex_compiled; static ::regex_t s_regex; @@ -476,11 +475,11 @@ DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, uns namespace { // This is the memory object we use in GetInstruction. class LLDBDisasmMemoryObject : public llvm::MemoryObject { - uint8_t *m_bytes; + const uint8_t *m_bytes; uint64_t m_size; uint64_t m_base_PC; public: - LLDBDisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) : + LLDBDisasmMemoryObject(const uint8_t *bytes, uint64_t size, uint64_t basePC) : m_bytes(bytes), m_size(size), m_base_PC(basePC) {} uint64_t getBase() const { return m_base_PC; } @@ -496,14 +495,12 @@ namespace { } // End Anonymous Namespace uint64_t -DisassemblerLLVMC::LLVMCDisassembler::GetMCInst ( - uint8_t *opcode_data, - size_t opcode_data_len, - lldb::addr_t pc, - llvm::MCInst &mc_inst) +DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data, + size_t opcode_data_len, + lldb::addr_t pc, + llvm::MCInst &mc_inst) { LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc); - llvm::MCInst inst; llvm::MCDisassembler::DecodeStatus status; uint64_t new_inst_size; @@ -520,17 +517,18 @@ DisassemblerLLVMC::LLVMCDisassembler::GetMCInst ( } uint64_t -DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len) +DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst, + char *dst, + size_t dst_len) { llvm::StringRef unused_annotations; llvm::SmallString<64> inst_string; llvm::raw_svector_ostream inst_stream(inst_string); m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations); inst_stream.flush(); - - size_t output_size = std::min(out_buffer_len -1, inst_string.size()); - std::memcpy(output_buffer, inst_string.data(), output_size); - output_buffer[output_size] = '\0'; + const size_t output_size = std::min(dst_len - 1, inst_string.size()); + std::memcpy(dst, inst_string.data(), output_size); + dst[output_size] = '\0'; return output_size; } @@ -576,7 +574,8 @@ DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor) DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) : Disassembler(arch, flavor_string), m_exe_ctx (NULL), - m_inst (NULL) + m_inst (NULL), + m_data_from_file (false) { if (!FlavorValidForArchSpec (arch, m_flavor.c_str())) { @@ -633,7 +632,8 @@ DisassemblerLLVMC::DecodeInstructions (const Address &base_addr, const DataExtractor& data, lldb::offset_t data_offset, size_t num_instructions, - bool append) + bool append, + bool data_from_file) { if (!append) m_instruction_list.Clear(); @@ -641,6 +641,7 @@ DisassemblerLLVMC::DecodeInstructions (const Address &base_addr, if (!IsValid()) return 0; + m_data_from_file = data_from_file; uint32_t data_cursor = data_offset; const size_t data_byte_size = data.GetByteSize(); uint32_t instructions_parsed = 0; @@ -760,36 +761,33 @@ const char *DisassemblerLLVMC::SymbolLookup (uint64_t value, if (m_exe_ctx && m_inst) { //std::string remove_this_prior_to_checkin; - Address reference_address; - Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL; - - if (target && !target->GetSectionLoadList().IsEmpty()) - target->GetSectionLoadList().ResolveLoadAddress(value, reference_address); - else + Address value_so_addr; + if (m_inst->UsingFileAddress()) { ModuleSP module_sp(m_inst->GetAddress().GetModule()); if (module_sp) - module_sp->ResolveFileAddress(value, reference_address); + module_sp->ResolveFileAddress(value, value_so_addr); } - - if (reference_address.IsValid() && reference_address.GetSection()) + else if (target && !target->GetSectionLoadList().IsEmpty()) + { + target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr); + } + + if (value_so_addr.IsValid() && value_so_addr.GetSection()) { StreamString ss; - reference_address.Dump (&ss, - target, - Address::DumpStyleResolvedDescriptionNoModule, - Address::DumpStyleSectionNameOffset); + value_so_addr.Dump (&ss, + target, + Address::DumpStyleResolvedDescriptionNoModule, + Address::DumpStyleSectionNameOffset); if (!ss.GetString().empty()) { - //remove_this_prior_to_checkin = ss.GetString(); - //if (*type_ptr) m_inst->AppendComment(ss.GetString()); } } - //printf ("DisassemblerLLVMC::SymbolLookup (value=0x%16.16" PRIx64 ", type=%" PRIu64 ", pc=0x%16.16" PRIx64 ", name=\"%s\") m_exe_ctx=%p, m_inst=%p\n", value, *type_ptr, pc, remove_this_prior_to_checkin.c_str(), m_exe_ctx, m_inst); } } |