[Lldb-commits] [lldb] r128063 - in /lldb/trunk: include/lldb/Core/Disassembler.h lldb.xcodeproj/project.pbxproj source/Commands/CommandObjectDisassemble.cpp source/Commands/CommandObjectDisassemble.h source/Core/Disassembler.cpp source/Expression/ClangExpressionParser.cpp source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp source/Plugins/Disassembler/llvm/DisassemblerLLVM.h source/Target/StackFrame.cpp source/Target/ThreadPlanTracer.cpp
Jim Ingham
jingham at apple.com
Mon Mar 21 18:48:42 PDT 2011
Author: jingham
Date: Mon Mar 21 20:48:42 2011
New Revision: 128063
URL: http://llvm.org/viewvc/llvm-project?rev=128063&view=rev
Log:
Add the ability to disassemble "n" instructions from the current PC, or the first "n" instructions in a function.
Also added a "-p" flag that disassembles from the current pc.
Modified:
lldb/trunk/include/lldb/Core/Disassembler.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
lldb/trunk/source/Commands/CommandObjectDisassemble.h
lldb/trunk/source/Core/Disassembler.cpp
lldb/trunk/source/Expression/ClangExpressionParser.cpp
lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
lldb/trunk/source/Target/StackFrame.cpp
lldb/trunk/source/Target/ThreadPlanTracer.cpp
Modified: lldb/trunk/include/lldb/Core/Disassembler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Disassembler.h?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Disassembler.h (original)
+++ lldb/trunk/include/lldb/Core/Disassembler.h Mon Mar 21 20:48:42 2011
@@ -111,6 +111,18 @@
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
const AddressRange &range,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ bool show_bytes,
+ bool raw,
+ Stream &strm);
+
+ static bool
+ Disassemble (Debugger &debugger,
+ const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ const Address &start,
+ uint32_t num_instructions,
uint32_t num_mixed_context_lines,
bool show_bytes,
bool raw,
@@ -121,6 +133,7 @@
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
+ uint32_t num_instructions,
uint32_t num_mixed_context_lines,
bool show_bytes,
bool raw,
@@ -132,6 +145,7 @@
const ExecutionContext &exe_ctx,
const ConstString &name,
Module *module,
+ uint32_t num_instructions,
uint32_t num_mixed_context_lines,
bool show_bytes,
bool raw,
@@ -141,6 +155,7 @@
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
+ uint32_t num_instructions,
uint32_t num_mixed_context_lines,
bool show_bytes,
bool raw,
@@ -154,16 +169,36 @@
typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
+ static bool
+ PrintInstructions (Disassembler *disasm_ptr,
+ DataExtractor &data,
+ Debugger &debugger,
+ const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ const Address &start_addr,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ bool show_bytes,
+ bool raw,
+ Stream &strm);
+
size_t
ParseInstructions (const ExecutionContext *exe_ctx,
const AddressRange &range,
DataExtractor& data);
+ size_t
+ ParseInstructions (const ExecutionContext *exe_ctx,
+ const Address &range,
+ uint32_t num_instructions,
+ DataExtractor& data);
+
virtual size_t
DecodeInstructions (const Address &base_addr,
const DataExtractor& data,
uint32_t data_offset,
- uint32_t num_instructions) = 0;
+ uint32_t num_instructions,
+ bool append) = 0;
InstructionList &
GetInstructionList ();
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Mar 21 20:48:42 2011
@@ -1231,11 +1231,11 @@
08FB7794FE84155DC02AAC07 /* lldb */ = {
isa = PBXGroup;
children = (
- 2689FFCA13353D7A00698AC0 /* liblldb-core.a */,
26F5C32810F3DF7D009D5894 /* Libraries */,
08FB7795FE84155DC02AAC07 /* Source */,
26F5C22410F3D950009D5894 /* Tools */,
1AB674ADFE9D54B511CA2CBB /* Products */,
+ 2689FFCA13353D7A00698AC0 /* liblldb-core.a */,
);
name = lldb;
sourceTree = "<group>";
Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Mon Mar 21 20:48:42 2011
@@ -27,15 +27,19 @@
#include "lldb/Target/Target.h"
#define DEFAULT_DISASM_BYTE_SIZE 32
+#define DEFAULT_DISASM_NUM_INS 4
using namespace lldb;
using namespace lldb_private;
CommandObjectDisassemble::CommandOptions::CommandOptions () :
Options(),
+ num_lines_context(0),
+ num_instructions (0),
m_func_name(),
m_start_addr(),
- m_end_addr ()
+ m_end_addr (),
+ m_at_pc (false)
{
ResetOptionValues();
}
@@ -51,14 +55,24 @@
char short_option = (char) m_getopt_table[option_idx].val;
+ bool success;
+
switch (short_option)
{
case 'm':
show_mixed = true;
break;
+ case 'x':
+ num_lines_context = Args::StringToUInt32(option_arg, 0, 0, &success);
+ if (!success)
+ error.SetErrorStringWithFormat ("Invalid num context lines string: \"%s\".\n", option_arg);
+ break;
+
case 'c':
- num_lines_context = Args::StringToUInt32(option_arg, 0, 0);
+ num_instructions = Args::StringToUInt32(option_arg, 0, 0, &success);
+ if (!success)
+ error.SetErrorStringWithFormat ("Invalid num of instructions string: \"%s\".\n", option_arg);
break;
case 'b':
@@ -66,26 +80,30 @@
break;
case 's':
- m_start_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
+ m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
if (m_start_addr == LLDB_INVALID_ADDRESS)
- m_start_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
+ m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
if (m_start_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat ("Invalid start address string '%s'.\n", optarg);
+ error.SetErrorStringWithFormat ("Invalid start address string '%s'.\n", option_arg);
break;
case 'e':
- m_end_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
+ m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
if (m_end_addr == LLDB_INVALID_ADDRESS)
- m_end_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
+ m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
if (m_end_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat ("Invalid end address string '%s'.\n", optarg);
+ error.SetErrorStringWithFormat ("Invalid end address string '%s'.\n", option_arg);
break;
case 'n':
m_func_name = option_arg;
break;
+ case 'p':
+ m_at_pc = true;
+ break;
+
case 'r':
raw = true;
break;
@@ -110,7 +128,9 @@
show_mixed = false;
show_bytes = false;
num_lines_context = 0;
+ num_instructions = 0;
m_func_name.clear();
+ m_at_pc = false;
m_start_addr = LLDB_INVALID_ADDRESS;
m_end_addr = LLDB_INVALID_ADDRESS;
raw = false;
@@ -126,16 +146,24 @@
CommandObjectDisassemble::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_ALL, false, "bytes", 'b', no_argument, NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."},
-{ LLDB_OPT_SET_ALL, false, "context", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of context lines of source to show."},
+{ LLDB_OPT_SET_ALL, false, "context", 'x', required_argument, NULL, 0, eArgTypeNumLines, "Number of context lines of source to show."},
{ LLDB_OPT_SET_ALL, false, "mixed", 'm', no_argument, NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."},
{ LLDB_OPT_SET_ALL, false, "raw", 'r', no_argument, NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."},
{ LLDB_OPT_SET_1, true, "start-address", 's', required_argument, NULL, 0, eArgTypeStartAddress, "Address at which to start disassembling."},
{ LLDB_OPT_SET_1, false, "end-address", 'e', required_argument, NULL, 0, eArgTypeEndAddress, "Address at which to end disassembling."},
-{ LLDB_OPT_SET_2, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name."},
+{ LLDB_OPT_SET_2, true, "start-address", 's', required_argument, NULL, 0, eArgTypeStartAddress, "Address at which to start disassembling."},
+{ LLDB_OPT_SET_2, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
-{ LLDB_OPT_SET_3, true, "current-frame", 'f', no_argument, NULL, 0, eArgTypeNone, "Disassemble entire contents of the current frame's function."},
+{ LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name."},
+{ LLDB_OPT_SET_3, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
+
+{ LLDB_OPT_SET_4, true, "current-frame", 'f', no_argument, NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
+{ LLDB_OPT_SET_4, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
+
+{ LLDB_OPT_SET_5, true, "current-pc", 'p', no_argument, NULL, 0, eArgTypeNone, "Disassemble from the current pc."},
+{ LLDB_OPT_SET_5, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -202,11 +230,12 @@
result.SetStatus (eReturnStatusFailed);
return false;
}
- ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
-
+
if (m_options.show_mixed && m_options.num_lines_context == 0)
m_options.num_lines_context = 1;
+ ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+
if (!m_options.m_func_name.empty())
{
ConstString name(m_options.m_func_name.c_str());
@@ -216,6 +245,7 @@
exe_ctx,
name,
NULL, // Module *
+ m_options.num_instructions,
m_options.show_mixed ? m_options.num_lines_context : 0,
m_options.show_bytes,
m_options.raw,
@@ -231,62 +261,133 @@
}
else
{
- AddressRange range;
- if (m_options.m_start_addr != LLDB_INVALID_ADDRESS)
+ Address start_addr;
+ lldb::addr_t range_byte_size = DEFAULT_DISASM_BYTE_SIZE;
+
+ if (m_options.m_at_pc)
{
- range.GetBaseAddress().SetOffset (m_options.m_start_addr);
- if (m_options.m_end_addr != LLDB_INVALID_ADDRESS)
+ if (exe_ctx.frame == NULL)
+ {
+ result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ start_addr = exe_ctx.frame->GetFrameCodeAddress();
+ if (m_options.num_instructions == 0)
{
- if (m_options.m_end_addr < m_options.m_start_addr)
+ // Disassembling at the PC always disassembles some number of instructions (not the whole function).
+ m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
+ }
+ }
+ else
+ {
+ start_addr.SetOffset (m_options.m_start_addr);
+ if (start_addr.IsValid())
+ {
+ if (m_options.m_end_addr != LLDB_INVALID_ADDRESS)
{
- result.AppendErrorWithFormat ("End address before start address.\n");
+ 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_byte_size = m_options.m_end_addr - m_options.m_start_addr;
+ }
+ }
+ }
+
+ if (m_options.num_instructions != 0)
+ {
+ if (!start_addr.IsValid())
+ {
+ // The default action is to disassemble the current frame function.
+ if (exe_ctx.frame)
+ {
+ SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
+ if (sc.function)
+ start_addr = sc.function->GetAddressRange().GetBaseAddress();
+ else if (sc.symbol && sc.symbol->GetAddressRangePtr())
+ start_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
+ else
+ start_addr = exe_ctx.frame->GetFrameCodeAddress();
+ }
+
+ if (!start_addr.IsValid())
+ {
+ result.AppendError ("invalid frame");
result.SetStatus (eReturnStatusFailed);
- return false;
+ return false;
}
- range.SetByteSize (m_options.m_end_addr - m_options.m_start_addr);
+ }
+
+ if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
+ arch,
+ exe_ctx,
+ start_addr,
+ m_options.num_instructions,
+ m_options.show_mixed ? m_options.num_lines_context : 0,
+ m_options.show_bytes,
+ m_options.raw,
+ result.GetOutputStream()))
+ {
+ result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
- range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
- }
+ {
+ result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
else
{
- // The default action is to disassemble the current frame function.
- if (exe_ctx.frame)
+ AddressRange range;
+ if (start_addr.IsValid())
{
- 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();
+ range.GetBaseAddress() = start_addr;
+ range.SetByteSize (range_byte_size);
+ }
+ else
+ {
+ // The default action is to disassemble the current frame function.
+ 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->GetFrameCodeAddress();
+ }
else
- range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
+ {
+ result.AppendError ("invalid frame");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+ if (range.GetByteSize() == 0)
+ range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
+
+ if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
+ arch,
+ exe_ctx,
+ range,
+ m_options.num_instructions,
+ m_options.show_mixed ? m_options.num_lines_context : 0,
+ m_options.show_bytes,
+ m_options.raw,
+ result.GetOutputStream()))
+ {
+ result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
{
- result.AppendError ("invalid frame");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
+ result.SetStatus (eReturnStatusFailed);
}
}
- if (range.GetByteSize() == 0)
- range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
-
- if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- arch,
- exe_ctx,
- range,
- m_options.show_mixed ? m_options.num_lines_context : 0,
- m_options.show_bytes,
- m_options.raw,
- 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();
Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.h?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectDisassemble.h (original)
+++ lldb/trunk/source/Commands/CommandObjectDisassemble.h Mon Mar 21 20:48:42 2011
@@ -47,10 +47,12 @@
bool show_mixed; // Show mixed source/assembly
bool show_bytes;
uint32_t num_lines_context;
+ uint32_t num_instructions;
bool raw;
std::string m_func_name;
lldb::addr_t m_start_addr;
lldb::addr_t m_end_addr;
+ bool m_at_pc;
static lldb::OptionDefinition g_option_table[];
};
Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Mon Mar 21 20:48:42 2011
@@ -61,6 +61,7 @@
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
+ uint32_t num_instructions,
uint32_t num_mixed_context_lines,
bool show_bytes,
bool raw,
@@ -71,13 +72,15 @@
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, raw, strm))
+ if (Disassemble (debugger, arch, exe_ctx, range, num_instructions,
+ num_mixed_context_lines, show_bytes, raw, strm))
{
++success_count;
strm.EOL();
@@ -95,6 +98,7 @@
const ExecutionContext &exe_ctx,
const ConstString &name,
Module *module,
+ uint32_t num_instructions,
uint32_t num_mixed_context_lines,
bool show_bytes,
bool raw,
@@ -134,7 +138,8 @@
return Disassemble (debugger,
arch,
exe_ctx,
- sc_list,
+ sc_list,
+ num_instructions,
num_mixed_context_lines,
show_bytes,
raw,
@@ -176,6 +181,7 @@
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
const AddressRange &disasm_range,
+ uint32_t num_instructions,
uint32_t num_mixed_context_lines,
bool show_bytes,
bool raw,
@@ -190,8 +196,6 @@
{
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)
@@ -217,116 +221,211 @@
}
else
{
- // We got some things disassembled...
- size_t num_instructions = disasm_ap->GetInstructionList().GetSize();
- uint32_t offset = 0;
- SymbolContext sc;
- SymbolContext prev_sc;
- AddressRange sc_range;
- 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();
+ return PrintInstructions (disasm_ap.get(),
+ data,
+ debugger,
+ arch,
+ exe_ctx,
+ disasm_range.GetBaseAddress(),
+ num_instructions,
+ num_mixed_context_lines,
+ show_bytes,
+ raw,
+ strm);
+ }
+ }
+ }
+ return false;
+}
+
+bool
+Disassembler::Disassemble
+(
+ Debugger &debugger,
+ const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ const Address &start_address,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ bool show_bytes,
+ bool raw,
+ Stream &strm
+)
+{
+ if (num_instructions > 0)
+ {
+ std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch));
+ Address addr = start_address;
- for (size_t i=0; i<num_instructions; ++i)
+ if (disasm_ap.get())
+ {
+ // If we weren't passed in a section offset address range,
+ // try and resolve it to something
+ if (addr.IsSectionOffset() == false)
+ {
+ if (exe_ctx.target)
{
- Instruction *inst = disasm_ap->GetInstructionList().GetInstructionAtIndex (i).get();
- if (inst)
+ if (exe_ctx.target->GetSectionLoadList().IsEmpty())
{
- 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();
- }
+ exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), addr);
+ }
+ else
+ {
+ exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), addr);
+ }
+ }
+ }
+
+ DataExtractor data;
+ size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions, data);
+ if (bytes_disassembled == 0)
+ {
+ return false;
+ }
+ else
+ {
+ return PrintInstructions (disasm_ap.get(),
+ data,
+ debugger,
+ arch,
+ exe_ctx,
+ addr,
+ num_instructions,
+ num_mixed_context_lines,
+ show_bytes,
+ raw,
+ strm);
+ }
+ }
+ }
+ return false;
+}
+
+bool
+Disassembler::PrintInstructions
+(
+ Disassembler *disasm_ptr,
+ DataExtractor &data,
+ Debugger &debugger,
+ const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ const Address &start_addr,
+ uint32_t num_instructions,
+ uint32_t num_mixed_context_lines,
+ bool show_bytes,
+ bool raw,
+ 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;
+
+ uint32_t offset = 0;
+ SymbolContext sc;
+ SymbolContext prev_sc;
+ AddressRange sc_range;
+ Address addr = start_addr;
+
+ if (num_mixed_context_lines)
+ strm.IndentMore ();
- prev_sc = sc;
+ // 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 = addr.GetModule();
- if (addr_section)
+ for (size_t i=0; i<num_instructions_found; ++i)
+ {
+ Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
+ if (inst)
+ {
+ 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)
+ {
+ Module *module = addr_section->GetModule();
+ uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
+ if (resolved_mask)
+ {
+ if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
+ {
+ 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 = addr_section->GetModule();
- uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
- if (resolved_mask)
- {
- if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
- {
- 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)
- {
- if (offset != 0)
- strm.EOL();
-
- sc.DumpStopContext(&strm, process, addr, false, true, false);
- strm.EOL();
-
- if (sc.comp_unit && sc.line_entry.IsValid())
- {
- 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
+ if (offset != 0)
+ strm.EOL();
+
+ sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false);
+ strm.EOL();
+
+ if (sc.comp_unit && sc.line_entry.IsValid())
{
- sc.Clear();
+ debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
+ sc.line_entry.line,
+ num_mixed_context_lines,
+ num_mixed_context_lines,
+ num_mixed_context_lines ? "->" : "",
+ &strm);
}
}
- if (num_mixed_context_lines)
- strm.IndentMore ();
- strm.Indent();
- size_t inst_byte_size = inst->GetByteSize();
- inst->Dump(&strm, true, show_bytes ? &data : NULL, offset, &exe_ctx, raw);
- strm.EOL();
- offset += inst_byte_size;
-
- addr.SetOffset (addr.GetOffset() + inst_byte_size);
-
- if (num_mixed_context_lines)
- strm.IndentLess ();
- }
- else
- {
- break;
}
}
- if (num_mixed_context_lines)
- strm.IndentLess ();
-
+ else
+ {
+ sc.Clear();
+ }
}
+ if (num_mixed_context_lines)
+ strm.IndentMore ();
+ strm.Indent();
+ size_t inst_byte_size = inst->GetByteSize();
+ inst->Dump(&strm, true, show_bytes ? &data : NULL, offset, &exe_ctx, raw);
+ strm.EOL();
+ offset += inst_byte_size;
+
+ addr.SetOffset (addr.GetOffset() + inst_byte_size);
+
+ if (num_mixed_context_lines)
+ strm.IndentLess ();
+ }
+ else
+ {
+ break;
}
- return true;
}
- return false;
+ if (num_mixed_context_lines)
+ strm.IndentLess ();
+
+ return true;
}
@@ -336,6 +435,7 @@
Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
+ uint32_t num_instructions,
uint32_t num_mixed_context_lines,
bool show_bytes,
bool raw,
@@ -363,7 +463,7 @@
range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
}
- return Disassemble(debugger, arch, exe_ctx, range, num_mixed_context_lines, show_bytes, raw, strm);
+ return Disassemble(debugger, arch, exe_ctx, range, num_instructions, num_mixed_context_lines, show_bytes, raw, strm);
}
Instruction::Instruction(const Address &addr) :
@@ -443,12 +543,78 @@
data.SetData(data_sp);
data.SetByteOrder(target->GetArchitecture().GetByteOrder());
data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
- return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX);
+ return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
}
return 0;
}
+size_t
+Disassembler::ParseInstructions
+(
+ const ExecutionContext *exe_ctx,
+ const Address &start,
+ uint32_t num_instructions,
+ DataExtractor& data
+)
+{
+ Address addr = start;
+
+ if (num_instructions == 0)
+ return 0;
+
+ Target *target = exe_ctx->target;
+ // We'll guess at a size for the buffer, if we don't get all the instructions we want we can just re-fill & reuse it.
+ const addr_t byte_size = num_instructions * 2;
+ addr_t data_offset = 0;
+ addr_t next_instruction_offset = 0;
+ size_t buffer_size = byte_size;
+
+ uint32_t num_instructions_found = 0;
+
+ if (target == NULL || byte_size == 0 || !start.IsValid())
+ return 0;
+
+ DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
+ DataBufferSP data_sp(heap_buffer);
+
+ data.SetData(data_sp);
+ data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+
+ Error error;
+ bool prefer_file_cache = true;
+
+ m_instruction_list.Clear();
+
+ while (num_instructions_found < num_instructions)
+ {
+ if (buffer_size < data_offset + byte_size)
+ {
+ buffer_size = data_offset + byte_size;
+ heap_buffer->SetByteSize (buffer_size);
+ data.SetData(data_sp); // Resizing might have changed the backing store location, so we have to reset
+ // the DataBufferSP in the extractor so it changes to pointing at the right thing.
+ }
+ const size_t bytes_read = target->ReadMemory (addr, prefer_file_cache, heap_buffer->GetBytes() + data_offset, byte_size, error);
+ size_t num_bytes_read = 0;
+ if (bytes_read == 0)
+ break;
+
+ num_bytes_read = DecodeInstructions (start, data, next_instruction_offset, num_instructions - num_instructions_found, true);
+ if (num_bytes_read == 0)
+ break;
+ num_instructions_found = m_instruction_list.GetSize();
+
+ // Prepare for the next round.
+ data_offset += bytes_read;
+ addr.Slide (bytes_read);
+ next_instruction_offset += num_bytes_read;
+ }
+
+ return m_instruction_list.GetSize();
+}
+
//----------------------------------------------------------------------
// Disassembler copy constructor
//----------------------------------------------------------------------
Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Mon Mar 21 20:48:42 2011
@@ -739,7 +739,7 @@
DataExtractor::TypeUInt8);
}
- disassembler->DecodeInstructions (Address (NULL, func_remote_addr), extractor, 0, UINT32_MAX);
+ disassembler->DecodeInstructions (Address (NULL, func_remote_addr), extractor, 0, UINT32_MAX, false);
InstructionList &instruction_list = disassembler->GetInstructionList();
Modified: lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp Mon Mar 21 20:48:42 2011
@@ -404,7 +404,8 @@
const Address &base_addr,
const DataExtractor& data,
uint32_t data_offset,
- uint32_t num_instructions
+ uint32_t num_instructions,
+ bool append
)
{
if (m_disassembler == NULL)
@@ -412,7 +413,8 @@
size_t total_inst_byte_size = 0;
- m_instruction_list.Clear();
+ if (!append)
+ m_instruction_list.Clear();
while (data.ValidOffset(data_offset) && num_instructions)
{
Modified: lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h Mon Mar 21 20:48:42 2011
@@ -78,7 +78,8 @@
DecodeInstructions (const lldb_private::Address &base_addr,
const lldb_private::DataExtractor& data,
uint32_t data_offset,
- uint32_t num_instructions);
+ uint32_t num_instructions,
+ bool append);
//------------------------------------------------------------------
// PluginInterface protocol
Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Mon Mar 21 20:48:42 2011
@@ -260,6 +260,7 @@
target.GetArchitecture(),
exe_ctx,
0,
+ 0,
false,
false,
m_disassembly);
Modified: lldb/trunk/source/Target/ThreadPlanTracer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanTracer.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanTracer.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanTracer.cpp Mon Mar 21 20:48:42 2011
@@ -204,9 +204,9 @@
m_process.GetAddressByteSize());
if (addr_valid)
- m_disassembler->DecodeInstructions (pc_addr, extractor, 0, 1);
+ m_disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false);
else
- m_disassembler->DecodeInstructions (Address (NULL, pc), extractor, 0, 1);
+ m_disassembler->DecodeInstructions (Address (NULL, pc), extractor, 0, 1, false);
InstructionList &instruction_list = m_disassembler->GetInstructionList();
More information about the lldb-commits
mailing list