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
This commit is contained in:
Greg Clayton 2010-06-30 23:03:03 +00:00
parent 56f2e34a6a
commit dda4f7b520
19 changed files with 810 additions and 612 deletions

View File

@ -122,7 +122,8 @@ public:
//Disassemble ();
void
Disassemble (lldb::addr_t file_address_start, lldb::addr_t file_address_end = LLDB_INVALID_ADDRESS,
Disassemble (lldb::addr_t start_address,
lldb::addr_t end_address = LLDB_INVALID_ADDRESS,
const char *module_name = NULL);
void

View File

@ -82,7 +82,12 @@ public:
///< \code
/// // address for printf in libSystem.B.dylib as a load address
/// 0x00007fff8306bcff \endcode
DumpStyleResolvedDescription ///< Display the name that an address resolves to
DumpStyleResolvedDescription, ///< Display the details about what an address resolves to. This can
///< be anything from a symbol context summary (module, function/symbol,
///< and file and line), to information about what the pointer points to
///< if the address is in a section (section of pointers, c strings, etc).
DumpStyleDetailedSymbolContext ///< Detailed symbol context information for an address for all symbol
///< context members.
} DumpStyle;
//------------------------------------------------------------------
@ -221,7 +226,8 @@ public:
Dump (Stream *s,
ExecutionContextScope *exe_scope,
DumpStyle style,
DumpStyle fallback_style = DumpStyleInvalid) const;
DumpStyle fallback_style = DumpStyleInvalid,
uint32_t addr_byte_size = UINT32_MAX) const;
//------------------------------------------------------------------
/// Dump a debug description of this object to a Stream.

View File

@ -42,8 +42,13 @@ public:
GetByteSize() const = 0;
virtual void
Dump (Stream *s, lldb::addr_t base_address, DataExtractor *bytes, uint32_t bytes_offset, const lldb_private::ExecutionContext exe_ctx, bool raw) = 0;
Dump (Stream *s,
Address *address,
const DataExtractor *bytes,
uint32_t bytes_offset,
const ExecutionContext &exe_ctx,
bool raw) = 0;
virtual bool
DoesBranch () const = 0;
@ -89,7 +94,36 @@ public:
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
uint32_t mixed_context_lines,
const AddressRange &range,
uint32_t num_mixed_context_lines,
bool show_bytes,
Stream &strm);
static size_t
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
uint32_t num_mixed_context_lines,
bool show_bytes,
Stream &strm);
static bool
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);
static bool
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
uint32_t num_mixed_context_lines,
bool show_bytes,
Stream &strm);
//------------------------------------------------------------------
@ -102,17 +136,14 @@ public:
size_t
ParseInstructions (const ExecutionContext *exe_ctx,
lldb::AddressType addr_type,
lldb::addr_t addr,
size_t byte_size,
const AddressRange &range,
DataExtractor& data);
virtual size_t
ParseInstructions (const DataExtractor& data,
uint32_t data_offset,
uint32_t num_instructions,
lldb::addr_t base_addr) = 0;
DecodeInstructions (const DataExtractor& data,
uint32_t data_offset,
uint32_t num_instructions) = 0;
InstructionList &
GetInstructionList ();

View File

@ -392,6 +392,9 @@ public:
lldb::DataBufferSP
ReadFileContents (off_t offset = 0, size_t length = SIZE_MAX) const;
size_t
ReadFileContents (off_t file_offset, void *dst, size_t dst_len) const;
//------------------------------------------------------------------
/// Change the file specificed with a new path.
///

View File

@ -217,6 +217,9 @@ public:
size_t
MemoryMapSectionDataFromObjectFile (const ObjectFile* file, DataExtractor& section_data) const;
size_t
ReadSectionDataFromObjectFile (const ObjectFile* objfile, off_t section_offset, void *dst, size_t dst_len) const;
size_t
ReadSectionDataFromObjectFile (const ObjectFile* file, DataExtractor& section_data) const;

View File

@ -264,13 +264,11 @@ public:
GetTargetTriple (ConstString &target_triple);
size_t
ReadMemory (lldb::AddressType addr_type,
lldb::addr_t addr,
void *buf,
size_t size,
Error &error,
ObjectFile* objfile = NULL);
ReadMemory (const Address& addr,
void *dst,
size_t dst_len,
Error &error);
//------------------------------------------------------------------
// lldb::ExecutionContextScope pure virtual functions
//------------------------------------------------------------------

View File

@ -384,9 +384,9 @@ SBTarget::GetBroadcaster () const
}
void
SBTarget::Disassemble (lldb::addr_t file_address_start, lldb::addr_t file_address_end, const char *module_name)
SBTarget::Disassemble (lldb::addr_t start_addr, lldb::addr_t end_addr, const char *module_name)
{
if (file_address_start == LLDB_INVALID_ADDRESS)
if (start_addr == LLDB_INVALID_ADDRESS)
return;
FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
@ -395,61 +395,65 @@ SBTarget::Disassemble (lldb::addr_t file_address_start, lldb::addr_t file_addres
if (m_opaque_sp)
{
SBModule module;
ModuleSP module_sp;
if (module_name != NULL)
{
SBFileSpec file_spec (module_name);
module = FindModule (file_spec);
FileSpec module_file_spec (module_name);
module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
}
AddressRange range;
// Make sure the process object is alive if we have one (it might be
// created but we might not be launched yet).
Process *process = m_opaque_sp->GetProcessSP().get();
if (process && !process->IsAlive())
process = NULL;
// If we are given a module, then "start_addr" is a file address in
// that module.
if (module_sp)
{
if (!module_sp->ResolveFileAddress (start_addr, range.GetBaseAddress()))
range.GetBaseAddress().SetOffset(start_addr);
}
else if (process)
{
// We don't have a module, se we need to figure out if "start_addr"
// resolves to anything in a running process.
if (!process->ResolveLoadAddress(start_addr, range.GetBaseAddress()))
range.GetBaseAddress().SetOffset(start_addr);
}
else
{
if (m_opaque_sp->GetImages().ResolveFileAddress (start_addr, range.GetBaseAddress()))
range.GetBaseAddress().SetOffset(start_addr);
}
ArchSpec arch (m_opaque_sp->GetArchitecture());
if (!arch.IsValid())
return;
Disassembler *disassembler = Disassembler::FindPlugin (arch);
if (disassembler == NULL)
return;
// For now, we need a process; the disassembly functions insist. If we don't have one already,
// make one.
SBProcess process = GetProcess();
if (! process.IsValid())
process = CreateProcess();
ExecutionContext exe_ctx;
ExecutionContext exe_context (process.get());
if (process)
process->Calculate(exe_ctx);
else
m_opaque_sp->Calculate(exe_ctx);
if (file_address_end == LLDB_INVALID_ADDRESS
|| file_address_end < file_address_start)
file_address_end = file_address_start + DEFAULT_DISASM_BYTE_SIZE;
if (end_addr == LLDB_INVALID_ADDRESS || end_addr < start_addr)
range.SetByteSize( DEFAULT_DISASM_BYTE_SIZE);
else
range.SetByteSize(end_addr - start_addr);
// TO BE FIXED: SOMEHOW WE NEED TO SPECIFY/USE THE MODULE, IF THE USER SPECIFIED ONE. I'M NOT
// SURE HOW TO DO THAT AT THE MOMENT. WE ALSO NEED TO FIGURE OUT WHAT TO DO IF THERE ARE MULTIPLE
// MODULES CONTAINING THE SPECIFIED ADDRESSES (E.G. THEY HAVEN'T ALL LOADED & BEEN GIVEN UNIQUE
// ADDRESSES YET).
StreamFile out_stream (out);
DataExtractor data;
size_t bytes_disassembled = disassembler->ParseInstructions (&exe_context, eAddressTypeLoad,
file_address_start,
file_address_end - file_address_start, data);
if (bytes_disassembled > 0)
{
size_t num_instructions = disassembler->GetInstructionList().GetSize();
uint32_t offset = 0;
StreamFile out_stream (out);
for (size_t i = 0; i < num_instructions; ++i)
{
Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i);
if (inst)
{
lldb::addr_t cur_addr = file_address_start + offset;
size_t inst_byte_size = inst->GetByteSize();
inst->Dump (&out_stream, cur_addr, &data, offset, exe_context, false);
out_stream.EOL();
offset += inst_byte_size;
}
}
}
Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
m_opaque_sp->GetArchitecture(),
exe_ctx,
range,
3,
false,
out_stream);
}
}
@ -465,102 +469,40 @@ SBTarget::Disassemble (const char *function_name, const char *module_name)
if (m_opaque_sp)
{
SBModule module;
if (module_name != NULL)
{
SBFileSpec file_spec (module_name);
module = FindModule (file_spec);
}
ArchSpec arch (m_opaque_sp->GetArchitecture());
if (!arch.IsValid())
return;
Disassembler *disassembler = Disassembler::FindPlugin (arch);
Disassembler *disassembler = Disassembler::FindPlugin (m_opaque_sp->GetArchitecture());
if (disassembler == NULL)
return;
// For now, we need a process; the disassembly functions insist. If we don't have one already,
// make one.
SBProcess process = GetProcess();
if (! process.IsValid()
|| process.GetProcessID() == 0)
{
fprintf (out, "Cannot disassemble functions until after process has launched.\n");
return;
}
ExecutionContext exe_context (process.get());
FileSpec *containing_module = NULL;
ModuleSP module_sp;
if (module_name != NULL)
containing_module = new FileSpec (module_name);
SearchFilterSP filter_sp (m_opaque_sp->GetSearchFilterForModule (containing_module));
AddressResolverSP resolver_sp (new AddressResolverName (function_name));
resolver_sp->ResolveAddress (*filter_sp);
size_t num_matches_found = resolver_sp->GetNumberOfAddresses();
if (num_matches_found == 1)
{
DataExtractor data;
AddressRange func_addresses = resolver_sp->GetAddressRangeAtIndex (0);
Address start_addr = func_addresses.GetBaseAddress();
lldb::addr_t num_bytes = func_addresses.GetByteSize();
lldb::addr_t addr = LLDB_INVALID_ADDRESS;
size_t bytes_disassembled = 0;
if (process.GetProcessID() == 0)
{
// Leave this branch in for now, but it should not be reached, since we exit above if the PID is 0.
addr = start_addr.GetFileAddress ();
bytes_disassembled = disassembler->ParseInstructions (&exe_context, eAddressTypeFile, addr,
num_bytes, data);
}
else
{
addr = start_addr.GetLoadAddress (process.get());
bytes_disassembled = disassembler->ParseInstructions (&exe_context, eAddressTypeLoad, addr,
num_bytes, data);
}
if (bytes_disassembled > 0)
{
size_t num_instructions = disassembler->GetInstructionList().GetSize();
uint32_t offset = 0;
StreamFile out_stream (out);
for (size_t i = 0; i < num_instructions; ++i)
{
Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i);
if (inst)
{
lldb::addr_t cur_addr = addr + offset;
size_t inst_byte_size = inst->GetByteSize();
inst->Dump (&out_stream, cur_addr, &data, offset, exe_context, false);
out_stream.EOL();
offset += inst_byte_size;
}
}
}
FileSpec module_file_spec (module_name);
module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
}
else if (num_matches_found > 1)
{
// TO BE FIXED: Eventually we want to list/disassemble all functions found.
fprintf (out, "Function '%s' was found in multiple modules; please specify the desired module name.\n",
function_name);
}
else
fprintf (out, "Function '%s' was not found.\n", function_name);
ExecutionContext exe_ctx;
// Make sure the process object is alive if we have one (it might be
// created but we might not be launched yet).
Process *process = m_opaque_sp->GetProcessSP().get();
if (process && !process->IsAlive())
process = NULL;
if (process)
process->Calculate(exe_ctx);
else
m_opaque_sp->Calculate(exe_ctx);
StreamFile out_stream (out);
Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
m_opaque_sp->GetArchitecture(),
exe_ctx,
ConstString (function_name),
module_sp.get(),
3,
false,
out_stream);
}
}

View File

@ -152,135 +152,6 @@ CommandObjectDisassemble::~CommandObjectDisassemble()
{
}
void
CommandObjectDisassemble::Disassemble
(
CommandInterpreter &interpreter,
CommandReturnObject &result,
Disassembler *disassembler,
const SymbolContextList &sc_list
)
{
const size_t count = sc_list.GetSize();
SymbolContext sc;
AddressRange range;
for (size_t i=0; i<count; ++i)
{
if (sc_list.GetContextAtIndex(i, sc) == false)
break;
if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
{
lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(interpreter.GetDebugger().GetExecutionContext().process);
if (addr != LLDB_INVALID_ADDRESS)
{
lldb::addr_t end_addr = addr + range.GetByteSize();
Disassemble (interpreter, result, disassembler, addr, end_addr);
}
}
}
}
void
CommandObjectDisassemble::Disassemble
(
CommandInterpreter &interpreter,
CommandReturnObject &result,
Disassembler *disassembler,
lldb::addr_t addr,
lldb::addr_t end_addr
)
{
if (addr == LLDB_INVALID_ADDRESS)
return;
if (end_addr == LLDB_INVALID_ADDRESS || addr >= end_addr)
end_addr = addr + DEFAULT_DISASM_BYTE_SIZE;
ExecutionContext exe_ctx (interpreter.GetDebugger().GetExecutionContext());
DataExtractor data;
size_t bytes_disassembled = disassembler->ParseInstructions (&exe_ctx, eAddressTypeLoad, addr, end_addr - addr, data);
if (bytes_disassembled == 0)
{
// Nothing got disassembled...
}
else
{
// We got some things disassembled...
size_t num_instructions = disassembler->GetInstructionList().GetSize();
uint32_t offset = 0;
Stream &output_stream = result.GetOutputStream();
SymbolContext sc;
SymbolContext prev_sc;
AddressRange sc_range;
if (m_options.show_mixed)
output_stream.IndentMore ();
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 (m_options.show_mixed)
{
Process *process = interpreter.GetDebugger().GetExecutionContext().process;
if (!sc_range.ContainsLoadAddress (curr_addr, process))
{
prev_sc = sc;
Address curr_so_addr;
if (process && process->ResolveLoadAddress (curr_addr, curr_so_addr))
{
if (curr_so_addr.GetSection())
{
Module *module = curr_so_addr.GetSection()->GetModule();
uint32_t resolved_mask = module->ResolveSymbolContextForAddress(curr_so_addr, eSymbolContextEverything, sc);
if (resolved_mask)
{
sc.GetAddressRange (eSymbolContextEverything, sc_range);
if (sc != prev_sc)
{
if (offset != 0)
output_stream.EOL();
sc.DumpStopContext(&output_stream, process, curr_so_addr);
output_stream.EOL();
if (sc.comp_unit && sc.line_entry.IsValid())
{
interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (
sc.line_entry.file,
sc.line_entry.line,
m_options.num_lines_context,
m_options.num_lines_context,
m_options.num_lines_context ? "->" : "",
&output_stream);
}
}
}
}
}
}
}
if (m_options.show_mixed)
output_stream.IndentMore ();
output_stream.Indent();
size_t inst_byte_size = inst->GetByteSize();
inst->Dump(&output_stream, curr_addr, m_options.show_bytes ? &data : NULL, offset, exe_ctx, m_options.raw);
output_stream.EOL();
offset += inst_byte_size;
if (m_options.show_mixed)
output_stream.IndentLess ();
}
else
{
break;
}
}
if (m_options.show_mixed)
output_stream.IndentLess ();
}
}
bool
CommandObjectDisassemble::Execute
(
@ -316,99 +187,94 @@ CommandObjectDisassemble::Execute
result.SetStatus (eReturnStatusSuccessFinishResult);
lldb::addr_t addr = LLDB_INVALID_ADDRESS;
lldb::addr_t end_addr = LLDB_INVALID_ADDRESS;
ConstString name;
const size_t argc = command.GetArgumentCount();
if (argc != 0)
if (command.GetArgumentCount() != 0)
{
result.AppendErrorWithFormat ("\"disassemble\" doesn't take any arguments.\n");
result.SetStatus (eReturnStatusFailed);
return false;
}
if (m_options.m_start_addr != LLDB_INVALID_ADDRESS)
{
addr = m_options.m_start_addr;
if (m_options.m_end_addr != LLDB_INVALID_ADDRESS)
{
end_addr = m_options.m_end_addr;
if (end_addr < addr)
{
result.AppendErrorWithFormat ("End address before start address.\n");
result.SetStatus (eReturnStatusFailed);
return false;
}
}
else
end_addr = addr + DEFAULT_DISASM_BYTE_SIZE;
}
else if (!m_options.m_func_name.empty())
{
ConstString tmpname(m_options.m_func_name.c_str());
name = tmpname;
}
else
{
ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
if (exe_ctx.frame)
{
SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
if (sc.function)
{
addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(exe_ctx.process);
if (addr != LLDB_INVALID_ADDRESS)
end_addr = addr + sc.function->GetAddressRange().GetByteSize();
}
else if (sc.symbol && sc.symbol->GetAddressRangePtr())
{
addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetLoadAddress(exe_ctx.process);
if (addr != LLDB_INVALID_ADDRESS)
{
end_addr = addr + sc.symbol->GetAddressRangePtr()->GetByteSize();
if (addr == end_addr)
end_addr += DEFAULT_DISASM_BYTE_SIZE;
}
}
else
{
addr = exe_ctx.frame->GetPC().GetLoadAddress(exe_ctx.process);
if (addr != LLDB_INVALID_ADDRESS)
end_addr = addr + DEFAULT_DISASM_BYTE_SIZE;
}
}
else
{
result.AppendError ("invalid frame");
result.SetStatus (eReturnStatusFailed);
return false;
}
}
ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
if (!name.IsEmpty())
{
SymbolContextList sc_list;
if (m_options.show_mixed && m_options.num_lines_context == 0)
m_options.num_lines_context = 3;
if (target->GetImages().FindFunctions(name,
eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
sc_list))
if (!m_options.m_func_name.empty())
{
ConstString name(m_options.m_func_name.c_str());
if (Disassembler::Disassemble (interpreter.GetDebugger(),
arch,
exe_ctx,
name,
NULL, // Module *
m_options.show_mixed ? m_options.num_lines_context : 0,
m_options.show_bytes,
result.GetOutputStream()))
{
Disassemble (interpreter, result, disassembler, sc_list);
}
else if (target->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list))
{
Disassemble (interpreter, result, disassembler, sc_list);
result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
{
result.AppendErrorWithFormat ("Unable to find symbol with name '%s'.\n", name.GetCString());
result.SetStatus (eReturnStatusFailed);
return false;
}
}
}
else
{
Disassemble (interpreter, result, disassembler, addr, end_addr);
AddressRange range;
if (m_options.m_start_addr != LLDB_INVALID_ADDRESS)
{
range.GetBaseAddress().SetOffset (m_options.m_start_addr);
if (m_options.m_end_addr != LLDB_INVALID_ADDRESS)
{
if (m_options.m_end_addr < m_options.m_start_addr)
{
result.AppendErrorWithFormat ("End address before start address.\n");
result.SetStatus (eReturnStatusFailed);
return false;
}
range.SetByteSize (m_options.m_end_addr - m_options.m_start_addr);
}
else
range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
}
else
{
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();
}
else
{
result.AppendError ("invalid frame");
result.SetStatus (eReturnStatusFailed);
return false;
}
}
if (range.GetByteSize() == 0)
range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
if (Disassembler::Disassemble (interpreter.GetDebugger(),
arch,
exe_ctx,
range,
m_options.show_mixed ? m_options.num_lines_context : 0,
m_options.show_bytes,
result.GetOutputStream()))
{
result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
{
result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
result.SetStatus (eReturnStatusFailed);
}
}
return result.Succeeded();

View File

@ -74,18 +74,6 @@ public:
protected:
CommandOptions m_options;
void
Disassemble (CommandInterpreter &interpreter,
CommandReturnObject &result,
Disassembler *disassembler,
lldb::addr_t addr,
lldb::addr_t end_addr);
void
Disassemble (CommandInterpreter &interpreter,
CommandReturnObject &result,
Disassembler *disassembler,
const SymbolContextList &sc_list);
};
} // namespace lldb_private

View File

@ -231,7 +231,11 @@ LookupAddressInModule (CommandInterpreter &interpreter, Stream &strm, Module *mo
strm.Indent (" Address: ");
so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
strm.EOL();
strm.Indent (" Summary: ");
so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
strm.EOL();
if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext))
strm.EOL();
strm.IndentLess();
return true;
}

View File

@ -17,39 +17,57 @@
using namespace lldb;
using namespace lldb_private;
//static size_t
//ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
//{
// if (exe_scope == NULL)
// return 0;
//
// lldb::AddressType addr_type = eAddressTypeInvalid;
// addr_t addr = LLDB_INVALID_ADDRESS;
//
// Process *process = exe_scope->CalculateProcess();
//
// if (process && process->IsAlive())
// {
// addr = address.GetLoadAddress(process);
// if (addr != LLDB_INVALID_ADDRESS)
// addr_type = eAddressTypeLoad;
// }
//
// if (addr == LLDB_INVALID_ADDRESS)
// {
// addr = address.GetFileAddress();
// if (addr != LLDB_INVALID_ADDRESS)
// addr_type = eAddressTypeFile;
// }
//
// if (addr_type == eAddressTypeInvalid)
// return false;
//
// Target *target = exe_scope->CalculateTarget();
// if (target)
// {
// Error error;
// ObjectFile *objfile = NULL;
// if (address.GetModule())
// objfile = address.GetModule()->GetObjectFile();
// return target->ReadMemory (addr_type, addr, dst, dst_len, error, objfile);
// }
// return 0;
//}
static size_t
ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
{
if (exe_scope == NULL)
return 0;
lldb::AddressType addr_type = eAddressTypeInvalid;
addr_t addr = LLDB_INVALID_ADDRESS;
Process *process = exe_scope->CalculateProcess();
if (process && process->IsAlive())
{
addr = address.GetLoadAddress(process);
if (addr != LLDB_INVALID_ADDRESS)
addr_type = eAddressTypeLoad;
}
if (addr == LLDB_INVALID_ADDRESS)
{
addr = address.GetFileAddress();
if (addr != LLDB_INVALID_ADDRESS)
addr_type = eAddressTypeFile;
}
if (addr_type == eAddressTypeInvalid)
return false;
Target *target = exe_scope->CalculateTarget();
if (target)
{
Error error;
return target->ReadMemory (addr_type, addr, dst, dst_len, error, NULL);
return target->ReadMemory (address, dst, dst_len, error);
}
return 0;
}
@ -386,7 +404,7 @@ Address::Clear()
bool
Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style) const
Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
{
// If the section was NULL, only load address is going to work.
if (m_section == NULL)
@ -395,12 +413,17 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
Process *process = NULL;
if (exe_scope)
process = exe_scope->CalculateProcess();
int addr_size = sizeof (addr_t);
if (process)
addr_size = process->GetAddressByteSize ();
// If addr_byte_size is UINT32_MAX, then determine the correct address
// byte size for the process or default to the size of addr_t
if (addr_size == UINT32_MAX)
{
if (process)
addr_size = process->GetAddressByteSize ();
else
addr_size = sizeof(addr_t);
}
lldb_private::Address so_addr;
switch (style)
{
case DumpStyleSectionNameOffset:
@ -411,12 +434,13 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
}
else
{
s->Printf("0x%16.16llx", m_offset);
s->Address(m_offset, addr_size);
}
break;
case DumpStyleSectionPointerOffset:
s->Printf("(Section *)%.*p + 0x%16.16llx", (int)sizeof(void*) * 2, m_section, m_offset);
s->Printf("(Section *)%.*p + ", (int)sizeof(void*) * 2, m_section);
s->Address(m_offset, addr_size);
break;
case DumpStyleModuleWithFileAddress:
@ -428,7 +452,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
if (file_addr == LLDB_INVALID_ADDRESS)
{
if (fallback_style != DumpStyleInvalid)
return Dump (s, exe_scope, fallback_style);
return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
return false;
}
s->Address (file_addr, addr_size);
@ -443,7 +467,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
if (load_addr == LLDB_INVALID_ADDRESS)
{
if (fallback_style != DumpStyleInvalid)
return Dump (s, exe_scope, fallback_style);
return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
return false;
}
s->Address (load_addr, addr_size);
@ -592,13 +616,17 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
if (so_addr.IsSectionOffset())
{
lldb_private::SymbolContext pointer_sc;
process->GetTarget().GetImages().ResolveSymbolContextForAddress (so_addr,
eSymbolContextEverything,
pointer_sc);
if (pointer_sc.function || pointer_sc.symbol)
Target *target = exe_scope->CalculateTarget();
if (target)
{
s->PutCString(": ");
pointer_sc.DumpStopContext(s, process, so_addr, false);
target->GetImages().ResolveSymbolContextForAddress (so_addr,
eSymbolContextEverything,
pointer_sc);
if (pointer_sc.function || pointer_sc.symbol)
{
s->PutCString(": ");
pointer_sc.DumpStopContext(s, process, so_addr, false);
}
}
}
}
@ -629,10 +657,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
{
// We have a function or a symbol from the same
// sections as this address.
s->Indent(" Summary: ");
sc.DumpStopContext(s, process, *this, false);
s->EOL();
sc.GetDescription(s, eDescriptionLevelBrief, process);
sc.DumpStopContext(s, process, *this, true);
}
else
{
@ -648,10 +673,45 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
else
{
if (fallback_style != DumpStyleInvalid)
return Dump (s, exe_scope, fallback_style);
return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
return false;
}
break;
case DumpStyleDetailedSymbolContext:
if (IsSectionOffset())
{
lldb::AddressType addr_type = eAddressTypeLoad;
addr_t addr = GetLoadAddress (process);
if (addr == LLDB_INVALID_ADDRESS)
{
addr = GetFileAddress();
addr_type = eAddressTypeFile;
}
lldb_private::Module *module = GetModule();
if (module)
{
lldb_private::SymbolContext sc;
module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
if (sc.function || sc.symbol)
{
if (sc.function == NULL && sc.symbol != NULL)
{
// If we have just a symbol make sure it is in the right section
if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() == GetSection())
{
sc.GetDescription(s, eDescriptionLevelBrief, process);
break;
}
}
}
}
}
if (fallback_style != DumpStyleInvalid)
return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
return false;
break;
}
return true;

View File

@ -52,53 +52,121 @@ Disassembler::FindPlugin (const ArchSpec &arch)
return NULL;
}
size_t
Disassembler::Disassemble
(
Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
uint32_t num_mixed_context_lines,
bool show_bytes,
Stream &strm
)
{
size_t success_count = 0;
const size_t count = sc_list.GetSize();
SymbolContext sc;
AddressRange range;
for (size_t i=0; i<count; ++i)
{
if (sc_list.GetContextAtIndex(i, sc) == false)
break;
if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
{
if (Disassemble (debugger, arch, exe_ctx, range, num_mixed_context_lines, show_bytes, strm))
{
++success_count;
strm.EOL();
}
}
}
return success_count;
}
bool
Disassembler::Disassemble
(
Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
uint32_t mixed_context_lines,
const ConstString &name,
Module *module,
uint32_t num_mixed_context_lines,
bool show_bytes,
Stream &strm
)
{
Disassembler *disassembler = Disassembler::FindPlugin(arch);
if (exe_ctx.target == NULL && name)
return false;
if (disassembler)
SymbolContextList sc_list;
if (module)
{
lldb::addr_t addr = LLDB_INVALID_ADDRESS;
size_t byte_size = 0;
if (exe_ctx.frame)
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))
{
SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
if (sc.function)
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.function->GetAddressRange().GetBaseAddress().GetLoadAddress(exe_ctx.process);
if (addr != LLDB_INVALID_ADDRESS)
byte_size = sc.function->GetAddressRange().GetByteSize();
}
else if (sc.symbol && sc.symbol->GetAddressRangePtr())
{
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 (!sc_range.ContainsLoadAddress (curr_addr, exe_ctx.process))
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)
{
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;

View File

@ -496,21 +496,11 @@ FileSpec::MemorySize() const
return m_filename.MemorySize() + m_directory.MemorySize();
}
//------------------------------------------------------------------
// Returns a shared pointer to a data buffer that contains all or
// part of the contents of a file. The data copies into a heap based
// buffer that lives in the DataBuffer shared pointer object returned.
// The data that is cached will start "file_offset" bytes into the
// file, and "file_size" bytes will be mapped. If "file_size" is
// greater than the number of bytes available in the file starting
// at "file_offset", the number of bytes will be appropriately
// truncated. The final number of bytes that get mapped can be
// verified using the DataBuffer::GetByteSize() function.
//------------------------------------------------------------------
DataBufferSP
FileSpec::ReadFileContents(off_t file_offset, size_t file_size) const
size_t
FileSpec::ReadFileContents (off_t file_offset, void *dst, size_t dst_len) const
{
DataBufferSP data_sp;
size_t bytes_read = 0;
char resolved_path[PATH_MAX];
if (GetPath(resolved_path, sizeof(resolved_path)))
{
@ -521,6 +511,50 @@ FileSpec::ReadFileContents(off_t file_offset, size_t file_size) const
if (::fstat (fd, &file_stats) == 0)
{
// Read bytes directly into our basic_string buffer
if (file_stats.st_size > 0)
{
off_t lseek_result = 0;
if (file_offset > 0)
lseek_result = ::lseek (fd, file_offset, SEEK_SET);
if (lseek_result == file_offset)
{
ssize_t n = ::read (fd, dst, dst_len);
if (n >= 0)
bytes_read = n;
}
}
}
}
close(fd);
}
return bytes_read;
}
//------------------------------------------------------------------
// Returns a shared pointer to a data buffer that contains all or
// part of the contents of a file. The data copies into a heap based
// buffer that lives in the DataBuffer shared pointer object returned.
// The data that is cached will start "file_offset" bytes into the
// file, and "file_size" bytes will be mapped. If "file_size" is
// greater than the number of bytes available in the file starting
// at "file_offset", the number of bytes will be appropriately
// truncated. The final number of bytes that get mapped can be
// verified using the DataBuffer::GetByteSize() function.
//------------------------------------------------------------------
DataBufferSP
FileSpec::ReadFileContents (off_t file_offset, size_t file_size) const
{
DataBufferSP data_sp;
char resolved_path[PATH_MAX];
if (GetPath(resolved_path, sizeof(resolved_path)))
{
int fd = ::open (resolved_path, O_RDONLY, 0);
if (fd != -1)
{
struct stat file_stats;
if (::fstat (fd, &file_stats) == 0)
{
if (file_stats.st_size > 0)
{
off_t lseek_result = 0;
@ -533,11 +567,13 @@ FileSpec::ReadFileContents(off_t file_offset, size_t file_size) const
}
else if (lseek_result == file_offset)
{
const size_t bytes_left = file_stats.st_size - file_offset;
size_t num_bytes_to_read = file_size;
if (num_bytes_to_read > bytes_left)
num_bytes_to_read = bytes_left;
std::auto_ptr<DataBufferHeap> data_heap_ap;
if (file_stats.st_size < file_size)
data_heap_ap.reset(new DataBufferHeap(file_stats.st_size, '\0'));
else
data_heap_ap.reset(new DataBufferHeap(file_size, '\0'));
data_heap_ap.reset(new DataBufferHeap(num_bytes_to_read, '\0'));
if (data_heap_ap.get())
{

View File

@ -323,6 +323,22 @@ Section::GetSectionDataFromImage (const DataExtractor& image_data, DataExtractor
return false;
}
size_t
Section::ReadSectionDataFromObjectFile (const ObjectFile* objfile, off_t section_offset, void *dst, size_t dst_len) const
{
if (objfile && dst && dst_len)
{
const FileSpec& file = objfile->GetFileSpec();
if (file)
{
off_t section_file_offset = GetFileOffset() + objfile->GetOffset() + section_offset;
return file.ReadFileContents (section_file_offset, dst, dst_len);
}
}
return 0;
}
//----------------------------------------------------------------------
// Get the section data the file on disk
//----------------------------------------------------------------------
@ -340,11 +356,11 @@ Section::ReadSectionDataFromObjectFile(const ObjectFile* objfile, DataExtractor&
if (section_file_size > 0)
{
off_t section_file_offset = GetFileOffset() + objfile->GetOffset();
DataBufferSP sectionDataSP(file.ReadFileContents(section_file_offset, section_file_size));
DataBufferSP section_data_sp(file.ReadFileContents(section_file_offset, section_file_size));
section_data.SetByteOrder(objfile->GetByteOrder());
section_data.SetAddressByteSize(objfile->GetAddressByteSize());
return section_data.SetData (sectionDataSP);
return section_data.SetData (section_data_sp);
}
}
return 0;
@ -364,10 +380,10 @@ Section::MemoryMapSectionDataFromObjectFile(const ObjectFile* objfile, DataExtra
if (section_file_size > 0)
{
off_t section_file_offset = GetFileOffset() + objfile->GetOffset();
DataBufferSP sectionDataSP(file.MemoryMapFileContents(section_file_offset, section_file_size));
DataBufferSP section_data_sp(file.MemoryMapFileContents(section_file_offset, section_file_size));
section_data.SetByteOrder(objfile->GetByteOrder());
section_data.SetAddressByteSize(objfile->GetAddressByteSize());
return section_data.SetData (sectionDataSP);
return section_data.SetData (section_data_sp);
}
}
return 0;

View File

@ -100,19 +100,27 @@ void
DisassemblerLLVM::Instruction::Dump
(
Stream *s,
lldb::addr_t base_address,
DataExtractor *bytes,
lldb_private::Address *inst_addr_ptr,
const DataExtractor *bytes,
uint32_t bytes_offset,
const lldb_private::ExecutionContext exe_ctx,
const lldb_private::ExecutionContext& exe_ctx,
bool raw
)
{
const size_t opcodeColumnWidth = 7;
const size_t operandColumnWidth = 25;
ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
// If we have an address, print it out
if (base_address != LLDB_INVALID_ADDRESS)
s->Printf("0x%llx: ", base_address);
if (inst_addr_ptr)
{
if (inst_addr_ptr->Dump (s,
exe_scope,
Address::DumpStyleLoadAddress,
Address::DumpStyleModuleWithFileAddress,
0))
s->PutCString(": ");
}
// If we are supposed to show bytes, "bytes" will be non-NULL.
if (bytes)
@ -131,9 +139,15 @@ DisassemblerLLVM::Instruction::Dump
int currentOpIndex = -1;
RegisterReaderArg rra(base_address + EDInstByteSize(m_inst), m_disassembler);
lldb_private::Process *process = exe_ctx.process;
addr_t base_addr = LLDB_INVALID_ADDRESS;
if (process && process->IsAlive())
base_addr = inst_addr_ptr->GetLoadAddress (process);
if (base_addr == LLDB_INVALID_ADDRESS)
base_addr = inst_addr_ptr->GetFileAddress ();
RegisterReaderArg rra(base_addr + EDInstByteSize(m_inst), m_disassembler);
bool printTokenized = false;
@ -228,13 +242,21 @@ DisassemblerLLVM::Instruction::Dump
}
lldb_private::Address so_addr;
if (process)
if (process && process->IsAlive())
{
if (process->ResolveLoadAddress(operand_value, so_addr))
if (process->ResolveLoadAddress (operand_value, so_addr))
so_addr.Dump(&comment, exe_scope, Address::DumpStyleResolvedDescription, Address::DumpStyleSectionNameOffset);
}
else if (inst_addr_ptr)
{
Module *module = inst_addr_ptr->GetModule();
if (module)
{
so_addr.Dump(&comment, process, Address::DumpStyleResolvedDescription, Address::DumpStyleSectionNameOffset);
if (module->ResolveFileAddress (operand_value, so_addr))
so_addr.Dump(&comment, exe_scope, Address::DumpStyleResolvedDescription, Address::DumpStyleSectionNameOffset);
}
}
} // EDEvaluateOperand
} // EDOperandIsMemory
} // EDGetOperand
@ -364,12 +386,11 @@ DisassemblerLLVM::~DisassemblerLLVM()
}
size_t
DisassemblerLLVM::ParseInstructions
DisassemblerLLVM::DecodeInstructions
(
const DataExtractor& data,
uint32_t data_offset,
uint32_t num_instructions,
lldb::addr_t base_addr
uint32_t num_instructions
)
{
size_t total_inst_byte_size = 0;

View File

@ -32,10 +32,10 @@ public:
void
Dump (lldb_private::Stream *s,
lldb::addr_t base_address,
lldb_private::DataExtractor *bytes,
lldb_private::Address *instr_addr_ptr,
const lldb_private::DataExtractor *bytes,
uint32_t bytes_offset,
const lldb_private::ExecutionContext exe_ctx,
const lldb_private::ExecutionContext& exe_ctx,
bool raw);
bool
@ -78,11 +78,10 @@ public:
~DisassemblerLLVM();
size_t
ParseInstructions (const lldb_private::DataExtractor& data,
uint32_t data_offset,
uint32_t num_instructions,
lldb::addr_t base_addr);
DecodeInstructions (const lldb_private::DataExtractor& data,
uint32_t data_offset,
uint32_t num_instructions);
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------

View File

@ -117,11 +117,6 @@ SymbolContext::DumpStopContext
bool show_module
) const
{
Process *process = NULL;
if (exe_scope)
process = exe_scope->CalculateProcess();
addr_t load_addr = addr.GetLoadAddress (process);
if (show_module && module_sp)
{
*s << module_sp->GetFileSpec().GetFilename() << '`';
@ -132,9 +127,9 @@ SymbolContext::DumpStopContext
if (function->GetMangled().GetName())
function->GetMangled().GetName().Dump(s);
const addr_t func_load_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(process);
if (load_addr > func_load_addr)
s->Printf(" + %llu", load_addr - func_load_addr);
const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
if (function_offset)
s->Printf(" + %llu", function_offset);
if (block != NULL)
{
@ -158,9 +153,9 @@ SymbolContext::DumpStopContext
if (symbol->GetAddressRangePtr())
{
const addr_t sym_load_addr = symbol->GetAddressRangePtr()->GetBaseAddress().GetLoadAddress(process);
if (load_addr > sym_load_addr)
s->Printf(" + %llu", load_addr - sym_load_addr);
const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
if (symbol_offset)
s->Printf(" + %llu", symbol_offset);
}
}
else

View File

@ -181,6 +181,7 @@ StackFrame::Disassemble ()
target.GetArchitecture(),
exe_ctx,
0,
false,
m_disassembly);
if (m_disassembly.GetSize() == 0)
return NULL;

View File

@ -507,90 +507,170 @@ Target::ModulesDidUnload (ModuleList &module_list)
BroadcastEvent (eBroadcastBitModulesUnloaded, NULL);
}
//size_t
//Target::ReadMemory
//(
// lldb::AddressType addr_type,
// lldb::addr_t addr,
// void *dst,
// size_t dst_len,
// Error &error,
// ObjectFile* objfile
//)
//{
// size_t bytes_read = 0;
// error.Clear();
// switch (addr_type)
// {
// case eAddressTypeFile:
// if (objfile)
// {
// Address so_addr(addr, objfile->GetSectionList());
// if (m_process_sp.get())
// {
// // If we have an execution context with a process, lets try and
// // resolve the file address in "objfile" and read it from the
// // process
// lldb::addr_t load_addr = so_addr.GetLoadAddress(m_process_sp.get());
// if (load_addr == LLDB_INVALID_ADDRESS)
// {
// if (objfile->GetFileSpec())
// error.SetErrorStringWithFormat("0x%llx can't be resolved, %s in not currently loaded.\n", addr, objfile->GetFileSpec().GetFilename().AsCString());
// else
// error.SetErrorStringWithFormat("0x%llx can't be resolved.\n", addr, objfile->GetFileSpec().GetFilename().AsCString());
// }
// else
// {
// bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
// if (bytes_read != dst_len)
// {
// if (error.Success())
// {
// if (bytes_read == 0)
// error.SetErrorStringWithFormat("Read memory from 0x%llx failed.\n", load_addr);
// else
// error.SetErrorStringWithFormat("Only %zu of %zu bytes were read from memory at 0x%llx.\n", bytes_read, dst_len, load_addr);
// }
// }
// }
// }
// else
// {
// // Try and read the file based address from the object file's
// // section data.
// const Section *section = so_addr.GetSection();
// if (section)
// return section->ReadSectionDataFromObjectFile(objfile, so_addr.GetOffset(), dst, dst_len);
// }
// }
// break;
//
// case eAddressTypeLoad:
// if (m_process_sp.get())
// {
// bytes_read = m_process_sp->ReadMemory(addr, dst, dst_len, error);
// if (bytes_read != dst_len)
// {
// if (error.Success())
// {
// if (bytes_read == 0)
// error.SetErrorStringWithFormat("Read memory from 0x%llx failed.\n", addr);
// else
// error.SetErrorStringWithFormat("Only %zu of %zu bytes were read from memory at 0x%llx.\n", bytes_read, dst_len, addr);
// }
// }
// }
// else
// error.SetErrorStringWithFormat("Need valid process to read load address.\n");
// break;
//
// case eAddressTypeHost:
// // The address is an address in this process, so just copy it
// ::memcpy (dst, (uint8_t*)NULL + addr, dst_len);
// break;
//
// default:
// error.SetErrorStringWithFormat ("Unsupported lldb::AddressType value (%i).\n", addr_type);
// break;
// }
// return bytes_read;
//}
size_t
Target::ReadMemory
(
lldb::AddressType addr_type,
lldb::addr_t addr,
const Address& addr,
void *dst,
size_t dst_len,
Error &error,
ObjectFile* objfile
Error &error
)
{
size_t bytes_read = 0;
error.Clear();
switch (addr_type)
{
case eAddressTypeFile:
if (objfile)
{
if (m_process_sp.get())
{
// If we have an execution context with a process, lets try and
// resolve the file address in "objfile" and read it from the
// process
Address so_addr(addr, objfile->GetSectionList());
lldb::addr_t load_addr = so_addr.GetLoadAddress(m_process_sp.get());
if (load_addr == LLDB_INVALID_ADDRESS)
{
if (objfile->GetFileSpec())
error.SetErrorStringWithFormat("0x%llx can't be resolved, %s in not currently loaded.\n", addr, objfile->GetFileSpec().GetFilename().AsCString());
else
error.SetErrorStringWithFormat("0x%llx can't be resolved.\n", addr, objfile->GetFileSpec().GetFilename().AsCString());
}
else
{
bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
if (bytes_read != dst_len)
{
if (error.Success())
{
if (bytes_read == 0)
error.SetErrorStringWithFormat("Read memory from 0x%llx failed.\n", load_addr);
else
error.SetErrorStringWithFormat("Only %zu of %zu bytes were read from memory at 0x%llx.\n", bytes_read, dst_len, load_addr);
}
}
}
}
else
{
// Try and read the file based address from the object file's
// section data.
}
}
break;
case eAddressTypeLoad:
if (m_process_sp.get())
bool process_is_valid = m_process_sp && m_process_sp->IsAlive();
Address resolved_addr(addr);
if (!resolved_addr.IsSectionOffset())
{
if (process_is_valid)
{
bytes_read = m_process_sp->ReadMemory(addr, dst, dst_len, error);
m_process_sp->ResolveLoadAddress (addr.GetOffset(), resolved_addr);
}
else
{
m_images.ResolveFileAddress(addr.GetOffset(), resolved_addr);
}
}
if (process_is_valid)
{
lldb::addr_t load_addr = resolved_addr.GetLoadAddress(m_process_sp.get());
if (load_addr == LLDB_INVALID_ADDRESS)
{
if (resolved_addr.GetModule() && resolved_addr.GetModule()->GetFileSpec())
error.SetErrorStringWithFormat("%s[0x%llx] can't be resolved, %s in not currently loaded.\n",
resolved_addr.GetModule()->GetFileSpec().GetFilename().AsCString(),
resolved_addr.GetFileAddress());
else
error.SetErrorStringWithFormat("0x%llx can't be resolved.\n", resolved_addr.GetFileAddress());
}
else
{
size_t bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
if (bytes_read != dst_len)
{
if (error.Success())
{
if (bytes_read == 0)
error.SetErrorStringWithFormat("Read memory from 0x%llx failed.\n", addr);
error.SetErrorStringWithFormat("Read memory from 0x%llx failed.\n", load_addr);
else
error.SetErrorStringWithFormat("Only %zu of %zu bytes were read from memory at 0x%llx.\n", bytes_read, dst_len, addr);
error.SetErrorStringWithFormat("Only %zu of %zu bytes were read from memory at 0x%llx.\n", bytes_read, dst_len, load_addr);
}
}
if (bytes_read)
return bytes_read;
// If the address is not section offset we have an address that
// doesn't resolve to any address in any currently loaded shared
// libaries and we failed to read memory so there isn't anything
// more we can do. If it is section offset, we might be able to
// read cached memory from the object file.
if (!resolved_addr.IsSectionOffset())
return 0;
}
else
error.SetErrorStringWithFormat("Need valid process to read load address.\n");
break;
case eAddressTypeHost:
// The address is an address in this process, so just copy it
::memcpy (dst, (uint8_t*)NULL + addr, dst_len);
break;
default:
error.SetErrorStringWithFormat ("Unsupported lldb::AddressType value (%i).\n", addr_type);
break;
}
return bytes_read;
const Section *section = resolved_addr.GetSection();
if (section && section->GetModule())
{
ObjectFile *objfile = section->GetModule()->GetObjectFile();
return section->ReadSectionDataFromObjectFile (objfile,
resolved_addr.GetOffset(),
dst,
dst_len);
}
return 0;
}