aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Core/Disassembler.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-31 21:22:58 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-31 21:22:58 +0000
commit5ffd83dbcc34f10e07f6d3e968ae6365869615f4 (patch)
tree0e9f5cf729dde39f949698fddef45a34e2bc7f44 /contrib/llvm-project/lldb/source/Core/Disassembler.cpp
parent1799696096df87b52968b8996d00c91e0a5de8d9 (diff)
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Notes
Diffstat (limited to 'contrib/llvm-project/lldb/source/Core/Disassembler.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/Core/Disassembler.cpp274
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) {