diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-31 21:22:58 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-31 21:22:58 +0000 |
commit | 5ffd83dbcc34f10e07f6d3e968ae6365869615f4 (patch) | |
tree | 0e9f5cf729dde39f949698fddef45a34e2bc7f44 /contrib/llvm-project/lldb/source/Core/Disassembler.cpp | |
parent | 1799696096df87b52968b8996d00c91e0a5de8d9 (diff) | |
parent | cfca06d7963fa0909f90483b42a6d7d194d01e08 (diff) |
Notes
Diffstat (limited to 'contrib/llvm-project/lldb/source/Core/Disassembler.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Core/Disassembler.cpp | 274 |
1 files changed, 63 insertions, 211 deletions
diff --git a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp index 33172cc8868e..4da823c7a243 100644 --- a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp +++ b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp @@ -1,4 +1,4 @@ -//===-- Disassembler.cpp ----------------------------------------*- C++ -*-===// +//===-- Disassembler.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -89,124 +89,57 @@ DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch, return DisassemblerSP(); } -DisassemblerSP Disassembler::FindPluginForTarget(const TargetSP target_sp, +DisassemblerSP Disassembler::FindPluginForTarget(const Target &target, const ArchSpec &arch, const char *flavor, const char *plugin_name) { - if (target_sp && flavor == nullptr) { + if (flavor == nullptr) { // FIXME - we don't have the mechanism in place to do per-architecture // settings. But since we know that for now we only support flavors on x86 // & x86_64, if (arch.GetTriple().getArch() == llvm::Triple::x86 || arch.GetTriple().getArch() == llvm::Triple::x86_64) - flavor = target_sp->GetDisassemblyFlavor(); + flavor = target.GetDisassemblyFlavor(); } return FindPlugin(arch, flavor, plugin_name); } -static void ResolveAddress(const ExecutionContext &exe_ctx, const Address &addr, - Address &resolved_addr) { +static Address ResolveAddress(Target &target, const Address &addr) { if (!addr.IsSectionOffset()) { + Address resolved_addr; // If we weren't passed in a section offset address range, try and resolve // it to something - Target *target = exe_ctx.GetTargetPtr(); - if (target) { - bool is_resolved = - target->GetSectionLoadList().IsEmpty() ? - target->GetImages().ResolveFileAddress(addr.GetOffset(), - resolved_addr) : - target->GetSectionLoadList().ResolveLoadAddress(addr.GetOffset(), - resolved_addr); - - // We weren't able to resolve the address, just treat it as a raw address - if (is_resolved && resolved_addr.IsValid()) - return; - } - } - resolved_addr = addr; -} - -size_t Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, - const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, - SymbolContextList &sc_list, - uint32_t num_instructions, - bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, - uint32_t options, Stream &strm) { - size_t success_count = 0; - const size_t count = sc_list.GetSize(); - SymbolContext sc; - AddressRange range; - const uint32_t scope = - eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; - const bool use_inline_block_range = true; - for (size_t i = 0; i < count; ++i) { - if (!sc_list.GetContextAtIndex(i, sc)) - break; - for (uint32_t range_idx = 0; - sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); - ++range_idx) { - if (Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm)) { - ++success_count; - strm.EOL(); - } - } - } - return success_count; -} - -bool Disassembler::Disassemble( - Debugger &debugger, const ArchSpec &arch, const char *plugin_name, - const char *flavor, const ExecutionContext &exe_ctx, ConstString name, - Module *module, uint32_t num_instructions, bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) { - // If no name is given there's nothing to disassemble. - if (!name) - return false; - - const bool include_symbols = true; - const bool include_inlines = true; - - // Find functions matching the given name. - SymbolContextList sc_list; - if (module) { - module->FindFunctions(name, nullptr, eFunctionNameTypeAuto, include_symbols, - include_inlines, sc_list); - } else if (exe_ctx.GetTargetPtr()) { - exe_ctx.GetTargetPtr()->GetImages().FindFunctions( - name, eFunctionNameTypeAuto, include_symbols, include_inlines, sc_list); + bool is_resolved = target.GetSectionLoadList().IsEmpty() + ? target.GetImages().ResolveFileAddress( + addr.GetOffset(), resolved_addr) + : target.GetSectionLoadList().ResolveLoadAddress( + addr.GetOffset(), resolved_addr); + + // We weren't able to resolve the address, just treat it as a raw address + if (is_resolved && resolved_addr.IsValid()) + return resolved_addr; } - - // If no functions were found there's nothing to disassemble. - if (sc_list.IsEmpty()) - return false; - - return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, sc_list, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); + return addr; } lldb::DisassemblerSP Disassembler::DisassembleRange( const ArchSpec &arch, const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, const AddressRange &range, - bool prefer_file_cache) { + Target &target, const AddressRange &range, bool prefer_file_cache) { if (range.GetByteSize() <= 0) return {}; if (!range.GetBaseAddress().IsValid()) return {}; - lldb::DisassemblerSP disasm_sp = Disassembler::FindPluginForTarget( - exe_ctx.GetTargetSP(), arch, flavor, plugin_name); + lldb::DisassemblerSP disasm_sp = + Disassembler::FindPluginForTarget(target, arch, flavor, plugin_name); if (!disasm_sp) return {}; - const size_t bytes_disassembled = - disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache); + const size_t bytes_disassembled = disasm_sp->ParseInstructions( + target, range.GetBaseAddress(), {Limit::Bytes, range.GetByteSize()}, + nullptr, prefer_file_cache); if (bytes_disassembled == 0) return {}; @@ -238,63 +171,28 @@ Disassembler::DisassembleBytes(const ArchSpec &arch, const char *plugin_name, bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, const ExecutionContext &exe_ctx, - const AddressRange &disasm_range, - uint32_t num_instructions, + const Address &address, Limit limit, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) { - if (!disasm_range.GetByteSize()) + if (!exe_ctx.GetTargetPtr()) return false; lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget( - exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); - + exe_ctx.GetTargetRef(), arch, flavor, plugin_name)); if (!disasm_sp) return false; - AddressRange range; - ResolveAddress(exe_ctx, disasm_range.GetBaseAddress(), - range.GetBaseAddress()); - range.SetByteSize(disasm_range.GetByteSize()); - const bool prefer_file_cache = false; - size_t bytes_disassembled = - disasm_sp->ParseInstructions(&exe_ctx, range, &strm, prefer_file_cache); - if (bytes_disassembled == 0) - return false; - - return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); -} - -bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, - const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, - const Address &start_address, - uint32_t num_instructions, - bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, - uint32_t options, Stream &strm) { - if (num_instructions == 0) - return false; - - lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget( - exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); - if (!disasm_sp) - return false; - - Address addr; - ResolveAddress(exe_ctx, start_address, addr); - const bool prefer_file_cache = false; size_t bytes_disassembled = disasm_sp->ParseInstructions( - &exe_ctx, addr, num_instructions, prefer_file_cache); + exe_ctx.GetTargetRef(), address, limit, &strm, prefer_file_cache); if (bytes_disassembled == 0) return false; - return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); + disasm_sp->PrintInstructions(debugger, arch, exe_ctx, + mixed_source_and_assembly, + num_mixed_context_lines, options, strm); + return true; } Disassembler::SourceLine @@ -380,21 +278,16 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine( return false; } -bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, - Debugger &debugger, const ArchSpec &arch, +void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch, const ExecutionContext &exe_ctx, - uint32_t num_instructions, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) { // We got some things disassembled... - size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); - - if (num_instructions > 0 && num_instructions < num_instructions_found) - num_instructions_found = num_instructions; + size_t num_instructions_found = GetInstructionList().GetSize(); const uint32_t max_opcode_byte_size = - disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize(); + GetInstructionList().GetMaxOpcocdeByteSize(); SymbolContext sc; SymbolContext prev_sc; AddressRange current_source_line_range; @@ -435,8 +328,7 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, size_t address_text_size = 0; for (size_t i = 0; i < num_instructions_found; ++i) { - Instruction *inst = - disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get(); + Instruction *inst = GetInstructionList().GetInstructionAtIndex(i).get(); if (inst) { const Address &addr = inst->GetAddress(); ModuleSP module_sp(addr.GetModule()); @@ -485,8 +377,7 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, previous_symbol = nullptr; SourceLine previous_line; for (size_t i = 0; i < num_instructions_found; ++i) { - Instruction *inst = - disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get(); + Instruction *inst = GetInstructionList().GetInstructionAtIndex(i).get(); if (inst) { const Address &addr = inst->GetAddress(); @@ -646,8 +537,6 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, break; } } - - return true; } bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, @@ -675,9 +564,10 @@ bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); } - return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); + return Disassemble( + debugger, arch, plugin_name, flavor, exe_ctx, range.GetBaseAddress(), + {Limit::Instructions, num_instructions}, mixed_source_and_assembly, + num_mixed_context_lines, options, strm); } Instruction::Instruction(const Address &address, AddressClass addr_class) @@ -1182,82 +1072,44 @@ InstructionList::GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr, return GetIndexOfInstructionAtAddress(address); } -size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx, - const AddressRange &range, - Stream *error_strm_ptr, - bool prefer_file_cache) { - if (exe_ctx) { - Target *target = exe_ctx->GetTargetPtr(); - const addr_t byte_size = range.GetByteSize(); - if (target == nullptr || byte_size == 0 || - !range.GetBaseAddress().IsValid()) - return 0; - - auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0'); - - Status error; - lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; - const size_t bytes_read = target->ReadMemory( - range.GetBaseAddress(), prefer_file_cache, data_sp->GetBytes(), - data_sp->GetByteSize(), error, &load_addr); - - if (bytes_read > 0) { - if (bytes_read != data_sp->GetByteSize()) - data_sp->SetByteSize(bytes_read); - DataExtractor data(data_sp, m_arch.GetByteOrder(), - m_arch.GetAddressByteSize()); - const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; - return DecodeInstructions(range.GetBaseAddress(), data, 0, UINT32_MAX, - false, data_from_file); - } else if (error_strm_ptr) { - const char *error_cstr = error.AsCString(); - if (error_cstr) { - error_strm_ptr->Printf("error: %s\n", error_cstr); - } - } - } else if (error_strm_ptr) { - error_strm_ptr->PutCString("error: invalid execution context\n"); - } - return 0; -} - -size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx, - const Address &start, - uint32_t num_instructions, +size_t Disassembler::ParseInstructions(Target &target, Address start, + Limit limit, Stream *error_strm_ptr, bool prefer_file_cache) { m_instruction_list.Clear(); - if (exe_ctx == nullptr || num_instructions == 0 || !start.IsValid()) + if (!start.IsValid()) return 0; - Target *target = exe_ctx->GetTargetPtr(); - // Calculate the max buffer size we will need in order to disassemble - const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); - - if (target == nullptr || byte_size == 0) - return 0; + start = ResolveAddress(target, start); - DataBufferHeap *heap_buffer = new DataBufferHeap(byte_size, '\0'); - DataBufferSP data_sp(heap_buffer); + addr_t byte_size = limit.value; + if (limit.kind == Limit::Instructions) + byte_size *= m_arch.GetMaximumOpcodeByteSize(); + auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0'); Status error; lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; const size_t bytes_read = - target->ReadMemory(start, prefer_file_cache, heap_buffer->GetBytes(), - byte_size, error, &load_addr); - + target.ReadMemory(start, prefer_file_cache, data_sp->GetBytes(), + data_sp->GetByteSize(), error, &load_addr); const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; - if (bytes_read == 0) + if (bytes_read == 0) { + if (error_strm_ptr) { + if (const char *error_cstr = error.AsCString()) + error_strm_ptr->Printf("error: %s\n", error_cstr); + } return 0; + } + + if (bytes_read != data_sp->GetByteSize()) + data_sp->SetByteSize(bytes_read); DataExtractor data(data_sp, m_arch.GetByteOrder(), m_arch.GetAddressByteSize()); - - const bool append_instructions = true; - DecodeInstructions(start, data, 0, num_instructions, append_instructions, - data_from_file); - - return m_instruction_list.GetSize(); + return DecodeInstructions(start, data, 0, + limit.kind == Limit::Instructions ? limit.value + : UINT32_MAX, + false, data_from_file); } // Disassembler copy constructor @@ -1346,7 +1198,7 @@ void PseudoInstruction::SetOpcode(size_t opcode_size, void *opcode_data) { } void PseudoInstruction::SetDescription(llvm::StringRef description) { - m_description = description; + m_description = std::string(description); } Instruction::Operand Instruction::Operand::BuildRegister(ConstString &r) { |