summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/Disassembler.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2010-06-30 23:03:03 +0000
committerGreg Clayton <gclayton@apple.com>2010-06-30 23:03:03 +0000
commitdda4f7b520827fb1cce38dbef9a00758067df99a (patch)
tree622c1e19dfdda4764cb606030d83e030c22a92e0 /lldb/source/Core/Disassembler.cpp
parent56f2e34a6a0810f28fa4d7ab171a9e12415e29a3 (diff)
downloadbcm5719-llvm-dda4f7b520827fb1cce38dbef9a00758067df99a.tar.gz
bcm5719-llvm-dda4f7b520827fb1cce38dbef9a00758067df99a.zip
Centralized all disassembly into static functions in source/Core/Disassembler.cpp.
Added the ability to read memory from the target's object files when we aren't running, so disassembling works before you run! Cleaned up the API to lldb_private::Target::ReadMemory(). Cleaned up the API to the Disassembler to use actual "lldb_private::Address" objects instead of just an "addr_t". This is nice because the Address objects when resolved carry along their section and module which can get us the object file. This allows Target::ReadMemory to be used when we are not running. Added a new lldb_private::Address dump style: DumpStyleDetailedSymbolContext This will show a full breakdown of what an address points to. To see some sample output, execute a "image lookup --address <addr>". Fixed SymbolContext::DumpStopContext(...) to not require a live process in order to be able to print function and symbol offsets. llvm-svn: 107350
Diffstat (limited to 'lldb/source/Core/Disassembler.cpp')
-rw-r--r--lldb/source/Core/Disassembler.cpp298
1 files changed, 223 insertions, 75 deletions
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index 9cdf618c087..a8eceb74ff9 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -52,53 +52,121 @@ Disassembler::FindPlugin (const ArchSpec &arch)
return NULL;
}
-bool
+
+
+size_t
Disassembler::Disassemble
(
Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
- uint32_t mixed_context_lines,
+ SymbolContextList &sc_list,
+ uint32_t num_mixed_context_lines,
+ bool show_bytes,
Stream &strm
)
{
- Disassembler *disassembler = Disassembler::FindPlugin(arch);
-
- if (disassembler)
+ size_t success_count = 0;
+ const size_t count = sc_list.GetSize();
+ SymbolContext sc;
+ AddressRange range;
+ for (size_t i=0; i<count; ++i)
{
- lldb::addr_t addr = LLDB_INVALID_ADDRESS;
- size_t byte_size = 0;
- if (exe_ctx.frame)
+ if (sc_list.GetContextAtIndex(i, sc) == false)
+ break;
+ if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
{
- SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
- if (sc.function)
+ if (Disassemble (debugger, arch, exe_ctx, range, num_mixed_context_lines, show_bytes, strm))
{
- addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(exe_ctx.process);
- if (addr != LLDB_INVALID_ADDRESS)
- byte_size = sc.function->GetAddressRange().GetByteSize();
+ ++success_count;
+ strm.EOL();
}
- else if (sc.symbol && sc.symbol->GetAddressRangePtr())
+ }
+ }
+ return success_count;
+}
+
+bool
+Disassembler::Disassemble
+(
+ Debugger &debugger,
+ const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ const ConstString &name,
+ Module *module,
+ uint32_t num_mixed_context_lines,
+ bool show_bytes,
+ Stream &strm
+)
+{
+ if (exe_ctx.target == NULL && name)
+ return false;
+
+ SymbolContextList sc_list;
+
+ if (module)
+ {
+ if (!module->FindFunctions (name,
+ eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
+ true,
+ sc_list))
+ return false;
+ }
+ else
+ {
+ if (exe_ctx.target->GetImages().FindFunctions (name,
+ eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
+ sc_list))
+ {
+ return Disassemble (debugger, arch, exe_ctx, sc_list, num_mixed_context_lines, show_bytes, strm);
+ }
+ else if (exe_ctx.target->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list))
+ {
+ return Disassemble (debugger, arch, exe_ctx, sc_list, num_mixed_context_lines, show_bytes, strm);
+ }
+ }
+ return false;
+}
+
+bool
+Disassembler::Disassemble
+(
+ Debugger &debugger,
+ const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ const AddressRange &disasm_range,
+ uint32_t num_mixed_context_lines,
+ bool show_bytes,
+ Stream &strm
+)
+{
+ if (disasm_range.GetByteSize())
+ {
+ Disassembler *disassembler = Disassembler::FindPlugin(arch);
+
+ if (disassembler)
+ {
+ AddressRange range(disasm_range);
+
+ Process *process = exe_ctx.process;
+
+ // If we weren't passed in a section offset address range,
+ // try and resolve it to something
+ if (range.GetBaseAddress().IsSectionOffset() == false)
{
- addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetLoadAddress(exe_ctx.process);
- if (addr != LLDB_INVALID_ADDRESS)
+ if (process && process->IsAlive())
{
- byte_size = sc.symbol->GetAddressRangePtr()->GetByteSize();
- if (byte_size == 0)
- byte_size = DEFAULT_DISASM_BYTE_SIZE;
+ process->ResolveLoadAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
+ }
+ else if (exe_ctx.target)
+ {
+ exe_ctx.target->GetImages().ResolveFileAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
}
}
- else
- {
- addr = exe_ctx.frame->GetPC().GetLoadAddress(exe_ctx.process);
- if (addr != LLDB_INVALID_ADDRESS)
- byte_size = DEFAULT_DISASM_BYTE_SIZE;
- }
- }
- if (byte_size)
- {
+
DataExtractor data;
- size_t bytes_disassembled = disassembler->ParseInstructions (&exe_ctx, eAddressTypeLoad, addr, byte_size, data);
+ size_t bytes_disassembled = disassembler->ParseInstructions (&exe_ctx, range, data);
if (bytes_disassembled == 0)
{
return false;
@@ -111,63 +179,94 @@ Disassembler::Disassemble
SymbolContext sc;
SymbolContext prev_sc;
AddressRange sc_range;
- if (mixed_context_lines)
+ if (num_mixed_context_lines)
strm.IndentMore ();
+
+ Address addr(range.GetBaseAddress());
+
+ // We extract the section to make sure we don't transition out
+ // of the current section when disassembling
+ const Section *addr_section = addr.GetSection();
+ Module *range_module = range.GetBaseAddress().GetModule();
+
for (size_t i=0; i<num_instructions; ++i)
{
Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i);
if (inst)
{
- lldb::addr_t curr_addr = addr + offset;
- if (mixed_context_lines)
+ addr_t file_addr = addr.GetFileAddress();
+ if (addr_section == NULL || addr_section->ContainsFileAddress (file_addr) == false)
+ {
+ if (range_module)
+ range_module->ResolveFileAddress (file_addr, addr);
+ else if (exe_ctx.target)
+ exe_ctx.target->GetImages().ResolveFileAddress (file_addr, addr);
+
+ addr_section = addr.GetSection();
+ }
+
+ prev_sc = sc;
+
+ if (addr_section)
{
- if (!sc_range.ContainsLoadAddress (curr_addr, exe_ctx.process))
+ Module *module = addr_section->GetModule();
+ uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
+ if (resolved_mask)
{
- prev_sc = sc;
- Address curr_so_addr;
- Process *process = exe_ctx.process;
- if (process && process->ResolveLoadAddress (curr_addr, curr_so_addr))
+ if (prev_sc.function != sc.function || prev_sc.symbol != sc.symbol)
{
- if (curr_so_addr.GetSection())
+ if (prev_sc.function || prev_sc.symbol)
+ strm.EOL();
+
+ strm << sc.module_sp->GetFileSpec().GetFilename();
+
+ if (sc.function)
+ strm << '`' << sc.function->GetMangled().GetName();
+ else if (sc.symbol)
+ strm << '`' << sc.symbol->GetMangled().GetName();
+ strm << ":\n";
+ }
+
+ if (num_mixed_context_lines && !sc_range.ContainsFileAddress (addr))
+ {
+ sc.GetAddressRange (eSymbolContextEverything, sc_range);
+
+ if (sc != prev_sc)
{
- Module *module = curr_so_addr.GetSection()->GetModule();
- uint32_t resolved_mask = module->ResolveSymbolContextForAddress(curr_so_addr, eSymbolContextEverything, sc);
- if (resolved_mask)
+ if (offset != 0)
+ strm.EOL();
+
+ sc.DumpStopContext(&strm, process, addr);
+
+ if (sc.comp_unit && sc.line_entry.IsValid())
{
- sc.GetAddressRange (eSymbolContextEverything, sc_range);
- if (sc != prev_sc)
- {
- if (offset != 0)
- strm.EOL();
-
- sc.DumpStopContext(&strm, process, curr_so_addr);
-
- if (sc.comp_unit && sc.line_entry.IsValid())
- {
- debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (
- sc.line_entry.file,
- sc.line_entry.line,
- mixed_context_lines,
- mixed_context_lines,
- mixed_context_lines ? "->" : "",
- &strm);
- }
- }
+ debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
+ sc.line_entry.line,
+ num_mixed_context_lines,
+ num_mixed_context_lines,
+ num_mixed_context_lines ? "->" : "",
+ &strm);
}
}
}
}
+ else
+ {
+ sc.Clear();
+ }
}
- if (mixed_context_lines)
+ if (num_mixed_context_lines)
strm.IndentMore ();
strm.Indent();
size_t inst_byte_size = inst->GetByteSize();
- //inst->Dump(&strm, curr_addr, &data, offset); // Do dump opcode bytes
- inst->Dump(&strm, curr_addr, NULL, offset, exe_ctx, false); // Don't dump opcode bytes
+ inst->Dump(&strm, &addr, show_bytes ? &data : NULL, offset, exe_ctx, show_bytes);
strm.EOL();
offset += inst_byte_size;
- if (mixed_context_lines)
+
+ addr.SetOffset (addr.GetOffset() + inst_byte_size);
+
+ if (num_mixed_context_lines)
strm.IndentLess ();
}
else
@@ -175,7 +274,7 @@ Disassembler::Disassemble
break;
}
}
- if (mixed_context_lines)
+ if (num_mixed_context_lines)
strm.IndentLess ();
}
@@ -185,6 +284,42 @@ Disassembler::Disassemble
return false;
}
+
+bool
+Disassembler::Disassemble
+(
+ Debugger &debugger,
+ const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ uint32_t num_mixed_context_lines,
+ bool show_bytes,
+ Stream &strm
+)
+{
+ AddressRange range;
+ if (exe_ctx.frame)
+ {
+ SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
+ if (sc.function)
+ {
+ range = sc.function->GetAddressRange();
+ }
+ else if (sc.symbol && sc.symbol->GetAddressRangePtr())
+ {
+ range = *sc.symbol->GetAddressRangePtr();
+ }
+ else
+ {
+ range.GetBaseAddress() = exe_ctx.frame->GetPC();
+ }
+
+ if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
+ range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
+ }
+
+ return Disassemble(debugger, arch, exe_ctx, range, num_mixed_context_lines, show_bytes, strm);
+}
+
Disassembler::Instruction::Instruction()
{
}
@@ -244,26 +379,39 @@ size_t
Disassembler::ParseInstructions
(
const ExecutionContext *exe_ctx,
- lldb::AddressType addr_type,
- lldb::addr_t addr,
- size_t byte_size,
+ const AddressRange &range,
DataExtractor& data
)
{
- Process *process = exe_ctx->process;
+ Target *target = exe_ctx->target;
- if (process == NULL)
+ const addr_t byte_size = range.GetByteSize();
+ if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
return 0;
- DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
+ DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
+ DataBufferSP data_sp(heap_buffer);
Error error;
- if (process->GetTarget().ReadMemory (addr_type, addr, data_sp->GetBytes(), data_sp->GetByteSize(), error, NULL))
+ const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), heap_buffer->GetBytes(), heap_buffer->GetByteSize(), error);
+
+ if (bytes_read > 0)
{
+ if (bytes_read != heap_buffer->GetByteSize())
+ heap_buffer->SetByteSize (bytes_read);
+
data.SetData(data_sp);
- data.SetByteOrder(process->GetByteOrder());
- data.SetAddressByteSize(process->GetAddressByteSize());
- return ParseInstructions (data, 0, UINT32_MAX, addr);
+ if (exe_ctx->process)
+ {
+ data.SetByteOrder(exe_ctx->process->GetByteOrder());
+ data.SetAddressByteSize(exe_ctx->process->GetAddressByteSize());
+ }
+ else
+ {
+ data.SetByteOrder(target->GetArchitecture().GetDefaultEndian());
+ data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ }
+ return DecodeInstructions (data, 0, UINT32_MAX);
}
return 0;
OpenPOWER on IntegriCloud