Cleaned up the Disassembler code a bit more. You can now request a disassembler

plugin by name on the command line for when there is more than one disassembler
plugin.

Taught the Opcode class to dump itself so that "disassembler -b" will dump
the bytes correctly for each opcode type. Modified all places that were passing
the opcode bytes buffer in so that the bytes could be displayed to just pass
in a bool that indicates if we should dump the opcode bytes since the opcode
now lives inside llvm_private::Instruction.

llvm-svn: 128290
This commit is contained in:
Greg Clayton 2011-03-25 18:03:16 +00:00
parent 6f4c9425eb
commit 1080edbcdd
17 changed files with 237 additions and 137 deletions

View File

@ -27,8 +27,7 @@ namespace lldb_private {
class Instruction
{
public:
Instruction (const Address &addr);
Instruction (const Address &addr, const Opcode &opcode);
Instruction (const Address &address);
virtual
~Instruction();
@ -36,24 +35,19 @@ public:
const Address &
GetAddress () const
{
return m_addr;
return m_address;
}
void
SetAddress (const Address &addr)
{
m_addr = addr;
m_address = addr;
}
virtual size_t
GetByteSize() const = 0;
virtual void
Dump (Stream *s,
bool show_address,
const DataExtractor *bytes,
uint32_t bytes_offset,
bool show_bytes,
const ExecutionContext *exe_ctx,
bool raw) = 0;
@ -72,7 +66,7 @@ public:
}
protected:
Address m_addr; // The section offset address of this instruction
Address m_address; // The section offset address of this instruction
Opcode m_opcode; // The opcode for this instruction
};
@ -110,16 +104,18 @@ public:
static Disassembler*
FindPlugin (const ArchSpec &arch);
FindPlugin (const ArchSpec &arch, const char *plugin_name);
static lldb::DisassemblerSP
DisassembleRange (const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
const AddressRange &disasm_range);
static bool
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
const AddressRange &range,
uint32_t num_instructions,
@ -131,6 +127,7 @@ public:
static bool
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
const Address &start,
uint32_t num_instructions,
@ -142,6 +139,7 @@ public:
static size_t
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
uint32_t num_instructions,
@ -153,6 +151,7 @@ public:
static bool
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
const ConstString &name,
Module *module,
@ -165,6 +164,7 @@ public:
static bool
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
uint32_t num_instructions,
uint32_t num_mixed_context_lines,
@ -182,7 +182,6 @@ public:
static bool
PrintInstructions (Disassembler *disasm_ptr,
DataExtractor &data,
Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,

View File

@ -171,6 +171,9 @@ namespace lldb_private {
}
}
int
Dump (Stream *s, uint32_t min_byte_width);
const void *
GetOpcodeBytes () const
{

View File

@ -3371,6 +3371,10 @@
CURRENT_PROJECT_VERSION = 46;
DYLIB_CURRENT_VERSION = 46;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
);
GCC_ENABLE_OBJC_GC = supported;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -3395,7 +3399,6 @@
);
OTHER_LDFLAGS = "-lllvmclang";
PRODUCT_NAME = "lib$(TARGET_NAME)";
SDKROOT = macosx;
STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static;
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/source $(SRCROOT)/source/Plugins/Process/Utility $(SRCROOT)/include $(SRCROOT)/source/Host/macosx/cfcpp $(SRCROOT)/llvm/include $(SRCROOT)/llvm/tools/clang/include $(LLVM_BUILD_DIR)/llvm/include $(LLVM_BUILD_DIR)/llvm/tools/clang/include";
VERSIONING_SYSTEM = "apple-generic";
@ -3411,6 +3414,10 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_CURRENT_VERSION = 46;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
);
GCC_ENABLE_OBJC_GC = supported;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -3435,7 +3442,6 @@
);
OTHER_LDFLAGS = "-lllvmclang";
PRODUCT_NAME = "lib$(TARGET_NAME)";
SDKROOT = macosx;
STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static;
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/source $(SRCROOT)/source/Plugins/Process/Utility $(SRCROOT)/include $(SRCROOT)/source/Host/macosx/cfcpp $(SRCROOT)/llvm/include $(SRCROOT)/llvm/tools/clang/include $(LLVM_BUILD_DIR)/llvm/include $(LLVM_BUILD_DIR)/llvm/tools/clang/include";
VERSIONING_SYSTEM = "apple-generic";
@ -3451,6 +3457,10 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_CURRENT_VERSION = 46;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
);
GCC_ENABLE_OBJC_GC = supported;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -3475,7 +3485,6 @@
);
OTHER_LDFLAGS = "-lllvmclang";
PRODUCT_NAME = "lib$(TARGET_NAME)";
SDKROOT = macosx;
STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static;
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/source $(SRCROOT)/source/Plugins/Process/Utility $(SRCROOT)/include $(SRCROOT)/source/Host/macosx/cfcpp $(SRCROOT)/llvm/include $(SRCROOT)/llvm/tools/clang/include $(LLVM_BUILD_DIR)/llvm/include $(LLVM_BUILD_DIR)/llvm/tools/clang/include";
VERSIONING_SYSTEM = "apple-generic";

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
version = "1.3">
version = "1.5">
<BuildAction
parallelizeBuildables = "NO"
buildImplicitDependencies = "YES">
@ -76,7 +76,7 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
displayScaleIsEnabled = "NO"
displayScale = "1.00"
launchStyle = "1"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug">
<BuildableProductRunnable>
@ -189,4 +189,7 @@
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
<InstallAction
buildConfiguration = "Debug">
</InstallAction>
</Scheme>

View File

@ -137,6 +137,7 @@ SBFunction::GetInstructions (SBTarget target)
if (module)
{
sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module->GetArchitecture(),
NULL,
exe_ctx,
m_opaque_ptr->GetAddressRange()));
}

View File

@ -64,7 +64,7 @@ size_t
SBInstruction::GetByteSize ()
{
if (m_opaque_sp)
return m_opaque_sp->GetByteSize();
return m_opaque_sp->GetOpcode().GetByteSize();
return 0;
}
@ -89,7 +89,7 @@ SBInstruction::GetDescription (lldb::SBStream &s)
{
// Use the "ref()" instead of the "get()" accessor in case the SBStream
// didn't have a stream already created, one will get created...
m_opaque_sp->Dump (&s.ref(), true, NULL, 0, NULL, false);
m_opaque_sp->Dump (&s.ref(), true, false, NULL, false);
return true;
}
return false;
@ -104,6 +104,6 @@ SBInstruction::Print (FILE *out)
if (m_opaque_sp)
{
StreamFile out_stream (out, false);
m_opaque_sp->Dump (&out_stream, true, NULL, 0, NULL, false);
m_opaque_sp->Dump (&out_stream, true, false, NULL, false);
}
}

View File

@ -98,7 +98,7 @@ SBInstructionList::GetDescription (lldb::SBStream &description)
Instruction *inst = m_opaque_sp->GetInstructionList().GetInstructionAtIndex (i).get();
if (inst == NULL)
break;
inst->Dump (&sref, true, NULL, 0, NULL, false);
inst->Dump (&sref, true, false, NULL, false);
sref.EOL();
}
return true;

View File

@ -134,6 +134,7 @@ SBSymbol::GetInstructions (SBTarget target)
if (module)
{
sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module->GetArchitecture (),
NULL,
exe_ctx,
*symbol_range));
}

View File

@ -39,7 +39,8 @@ CommandObjectDisassemble::CommandOptions::CommandOptions () :
m_func_name(),
m_start_addr(),
m_end_addr (),
m_at_pc (false)
m_at_pc (false),
m_plugin_name ()
{
ResetOptionValues();
}
@ -97,13 +98,17 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const
break;
case 'n':
m_func_name = option_arg;
m_func_name.assign (option_arg);
break;
case 'p':
m_at_pc = true;
break;
case 'P':
m_plugin_name.assign (option_arg);
break;
case 'r':
raw = true;
break;
@ -134,6 +139,7 @@ CommandObjectDisassemble::CommandOptions::ResetOptionValues ()
m_start_addr = LLDB_INVALID_ADDRESS;
m_end_addr = LLDB_INVALID_ADDRESS;
raw = false;
m_plugin_name.clear();
}
const OptionDefinition*
@ -145,10 +151,11 @@ CommandObjectDisassemble::CommandOptions::GetDefinitions ()
OptionDefinition
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", '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_ALL, false, "bytes", 'b', no_argument, NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."},
{ 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_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."},
{ 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."},
@ -209,11 +216,18 @@ CommandObjectDisassemble::Execute
return false;
}
Disassembler *disassembler = Disassembler::FindPlugin(arch);
const char *plugin_name = m_options.GetPluginName ();
Disassembler *disassembler = Disassembler::FindPlugin(arch, plugin_name);
if (disassembler == NULL)
{
result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture.\n", arch.GetArchitectureName());
if (plugin_name)
result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture named '%s'.\n",
arch.GetArchitectureName(),
plugin_name);
else
result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture.\n",
arch.GetArchitectureName());
result.SetStatus (eReturnStatusFailed);
return false;
}
@ -242,6 +256,7 @@ CommandObjectDisassemble::Execute
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
arch,
plugin_name,
exe_ctx,
name,
NULL, // Module *
@ -323,6 +338,7 @@ CommandObjectDisassemble::Execute
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
arch,
plugin_name,
exe_ctx,
start_addr,
m_options.num_instructions,
@ -372,6 +388,7 @@ CommandObjectDisassemble::Execute
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
arch,
plugin_name,
exe_ctx,
range,
m_options.num_instructions,

View File

@ -44,6 +44,15 @@ public:
const OptionDefinition*
GetDefinitions ();
const char *
GetPluginName ()
{
if (m_plugin_name.empty())
return NULL;
return m_plugin_name.c_str();
}
bool show_mixed; // Show mixed source/assembly
bool show_bytes;
uint32_t num_lines_context;
@ -53,6 +62,7 @@ public:
lldb::addr_t m_start_addr;
lldb::addr_t m_end_addr;
bool m_at_pc;
std::string m_plugin_name;
static OptionDefinition g_option_table[];
};

View File

@ -34,20 +34,36 @@ using namespace lldb_private;
Disassembler*
Disassembler::FindPlugin (const ArchSpec &arch)
Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
"Disassembler::FindPlugin (arch = %s)",
arch.GetArchitectureName());
"Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
arch.GetArchitectureName(),
plugin_name);
std::auto_ptr<Disassembler> disassembler_ap;
DisassemblerCreateInstance create_callback;
for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
DisassemblerCreateInstance create_callback = NULL;
if (plugin_name)
{
disassembler_ap.reset (create_callback(arch));
create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
if (create_callback)
{
disassembler_ap.reset (create_callback(arch));
if (disassembler_ap.get())
return disassembler_ap.release();
}
}
else
{
for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
disassembler_ap.reset (create_callback(arch));
if (disassembler_ap.get())
return disassembler_ap.release();
if (disassembler_ap.get())
return disassembler_ap.release();
}
}
return NULL;
}
@ -59,6 +75,7 @@ Disassembler::Disassemble
(
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
uint32_t num_instructions,
@ -79,8 +96,16 @@ Disassembler::Disassemble
break;
if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
{
if (Disassemble (debugger, arch, exe_ctx, range, num_instructions,
num_mixed_context_lines, show_bytes, raw, strm))
if (Disassemble (debugger,
arch,
plugin_name,
exe_ctx,
range,
num_instructions,
num_mixed_context_lines,
show_bytes,
raw,
strm))
{
++success_count;
strm.EOL();
@ -95,6 +120,7 @@ Disassembler::Disassemble
(
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
const ConstString &name,
Module *module,
@ -137,6 +163,7 @@ Disassembler::Disassemble
{
return Disassemble (debugger,
arch,
plugin_name,
exe_ctx,
sc_list,
num_instructions,
@ -153,6 +180,7 @@ lldb::DisassemblerSP
Disassembler::DisassembleRange
(
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
const AddressRange &range
)
@ -160,7 +188,7 @@ Disassembler::DisassembleRange
lldb::DisassemblerSP disasm_sp;
if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
{
disasm_sp.reset (Disassembler::FindPlugin(arch));
disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name));
if (disasm_sp)
{
@ -179,6 +207,7 @@ Disassembler::Disassemble
(
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
const AddressRange &disasm_range,
uint32_t num_instructions,
@ -190,7 +219,7 @@ Disassembler::Disassemble
{
if (disasm_range.GetByteSize())
{
std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch));
std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
if (disasm_ap.get())
{
@ -216,23 +245,18 @@ Disassembler::Disassemble
DataExtractor data;
size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range, data);
if (bytes_disassembled == 0)
{
return false;
}
else
{
return PrintInstructions (disasm_ap.get(),
data,
debugger,
arch,
exe_ctx,
disasm_range.GetBaseAddress(),
num_instructions,
num_mixed_context_lines,
show_bytes,
raw,
strm);
}
return PrintInstructions (disasm_ap.get(),
debugger,
arch,
exe_ctx,
disasm_range.GetBaseAddress(),
num_instructions,
num_mixed_context_lines,
show_bytes,
raw,
strm);
}
}
return false;
@ -243,6 +267,7 @@ Disassembler::Disassemble
(
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
const Address &start_address,
uint32_t num_instructions,
@ -254,7 +279,7 @@ Disassembler::Disassemble
{
if (num_instructions > 0)
{
std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch));
std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Address addr = start_address;
if (disasm_ap.get())
@ -279,23 +304,17 @@ Disassembler::Disassemble
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 PrintInstructions (disasm_ap.get(),
debugger,
arch,
exe_ctx,
addr,
num_instructions,
num_mixed_context_lines,
show_bytes,
raw,
strm);
}
}
return false;
@ -305,7 +324,6 @@ bool
Disassembler::PrintInstructions
(
Disassembler *disasm_ptr,
DataExtractor &data,
Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
@ -407,12 +425,10 @@ Disassembler::PrintInstructions
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);
inst->Dump(&strm, true, show_bytes, &exe_ctx, raw);
strm.EOL();
offset += inst_byte_size;
addr.SetOffset (addr.GetOffset() + inst_byte_size);
addr.Slide(inst->GetOpcode().GetByteSize());
if (num_mixed_context_lines)
strm.IndentLess ();
@ -434,6 +450,7 @@ Disassembler::Disassemble
(
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
const ExecutionContext &exe_ctx,
uint32_t num_instructions,
uint32_t num_mixed_context_lines,
@ -463,19 +480,21 @@ Disassembler::Disassemble
range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
}
return Disassemble(debugger, arch, exe_ctx, range, num_instructions, num_mixed_context_lines, show_bytes, raw, strm);
return Disassemble (debugger,
arch,
plugin_name,
exe_ctx,
range,
num_instructions,
num_mixed_context_lines,
show_bytes,
raw,
strm);
}
Instruction::Instruction(const Address &addr) :
m_addr (addr)
{
::memset (&m_opcode, 0, sizeof (m_opcode));
}
Instruction::Instruction(const Address &addr, const Opcode &opcode) :
m_addr (addr),
m_opcode (opcode)
Instruction::Instruction(const Address &address) :
m_address (address),
m_opcode()
{
}

View File

@ -13,6 +13,52 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Stream.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private;
int
Opcode::Dump (Stream *s, uint32_t min_byte_width)
{
int bytes_written = 0;
switch (m_type)
{
case Opcode::eTypeInvalid:
bytes_written = s->PutCString ("<invalid>");
break;
case Opcode::eType8:
bytes_written = s->Printf ("0x%2.2x", m_data.inst8);
break;
case Opcode::eType16:
bytes_written = s->Printf ("0x%4.4x", m_data.inst16);
break;
case Opcode::eType32:
bytes_written = s->Printf ("0x%8.8x", m_data.inst32);
break;
case Opcode::eType64:
bytes_written = s->Printf ("0x%16.16llx", m_data.inst64);
break;
case Opcode::eTypeBytes:
{
for (uint32_t i=0; i<m_data.inst.length; ++i)
{
if (i > 0)
s->PutChar (' ');
bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]);
}
}
break;
}
// Add spaces to make sure bytes dispay comes out even in case opcodes
// aren't all the same size
if (bytes_written < min_byte_width)
bytes_written = s->Printf ("%*s", min_byte_width - bytes_written, "");
return bytes_written;
}

View File

@ -708,7 +708,7 @@ ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &ex
ArchSpec arch(exe_ctx.target->GetArchitecture());
Disassembler *disassembler = Disassembler::FindPlugin(arch);
Disassembler *disassembler = Disassembler::FindPlugin(arch, NULL);
if (disassembler == NULL)
{
@ -743,8 +743,6 @@ ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &ex
InstructionList &instruction_list = disassembler->GetInstructionList();
uint32_t bytes_offset = 0;
for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize();
instruction_index < num_instructions;
++instruction_index)
@ -752,12 +750,10 @@ ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &ex
Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
instruction->Dump (&stream,
true,
&extractor,
bytes_offset,
true,
&exe_ctx,
true);
stream.PutChar('\n');
bytes_offset += instruction->GetByteSize();
}
return ret;

View File

@ -100,8 +100,7 @@ DisassemblerLLVM::InstructionLLVM::Dump
(
Stream *s,
bool show_address,
const DataExtractor *bytes,
uint32_t bytes_offset,
bool show_bytes,
const lldb_private::ExecutionContext* exe_ctx,
bool raw
)
@ -125,18 +124,20 @@ DisassemblerLLVM::InstructionLLVM::Dump
}
// If we are supposed to show bytes, "bytes" will be non-NULL.
if (bytes)
if (show_bytes)
{
uint32_t bytes_dumped = bytes->Dump(s, bytes_offset, eFormatBytes, 1, EDInstByteSize(m_inst), UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0) - bytes_offset;
// Allow for 15 bytes of opcodes since this is the max for x86_64.
// TOOD: We need to taylor this better for different architectures. For
// ARM we would want to show 16 bit opcodes for Thumb as properly byte
// swapped uint16_t values, or 32 bit values swapped values for ARM.
const uint32_t default_num_opcode_bytes = 15;
if (bytes_dumped * 3 < (default_num_opcode_bytes*3))
if (m_opcode.GetType() == Opcode::eTypeBytes)
{
uint32_t indent_level = (default_num_opcode_bytes*3) - (bytes_dumped * 3) + 1;
s->Printf("%*.*s", indent_level, indent_level, "");
// x86_64 and i386 are the only ones that use bytes right now so
// pad out the byte dump to be able to always show 15 bytes (3 chars each)
// plus a space
m_opcode.Dump (s, 15 * 3 + 1);
}
else
{
// Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
// plus two for padding...
m_opcode.Dump (s, 12);
}
}
@ -327,12 +328,6 @@ DisassemblerLLVM::InstructionLLVM::DoesBranch() const
return EDInstIsBranch(m_inst);
}
size_t
DisassemblerLLVM::InstructionLLVM::GetByteSize() const
{
return EDInstByteSize(m_inst);
}
size_t
DisassemblerLLVM::InstructionLLVM::Extract (const Disassembler &disassembler,
const lldb_private::DataExtractor &data,
@ -351,16 +346,21 @@ DisassemblerLLVM::InstructionLLVM::Extract (const Disassembler &disassembler,
break;
case llvm::Triple::arm:
assert (byte_size == 4);
m_opcode.SetOpcode32 (data.GetU32 (&offset));
break;
case llvm::Triple::thumb:
assert ((byte_size == 2) || (byte_size == 4));
if (byte_size == 2)
m_opcode.SetOpcode16 (data.GetU16 (&offset));
else
switch (byte_size)
{
case 2:
m_opcode.SetOpcode16 (data.GetU16 (&offset));
break;
case 4:
m_opcode.SetOpcode32 (data.GetU32 (&offset));
break;
default:
assert (!"Invalid ARM opcode size");
break;
}
break;
default:
@ -497,13 +497,13 @@ DisassemblerLLVM::Terminate()
const char *
DisassemblerLLVM::GetPluginNameStatic()
{
return "disassembler.llvm";
return "llvm";
}
const char *
DisassemblerLLVM::GetPluginDescriptionStatic()
{
return "Disassembler that uses LLVM opcode tables to disassemble i386 and x86_64.";
return "Disassembler that uses LLVM opcode tables to disassemble i386, x86_64 and ARM.";
}
//------------------------------------------------------------------

View File

@ -28,21 +28,17 @@ public:
virtual
~InstructionLLVM();
void
virtual void
Dump (lldb_private::Stream *s,
bool show_address,
const lldb_private::DataExtractor *bytes,
uint32_t bytes_offset,
bool show_bytes,
const lldb_private::ExecutionContext* exe_ctx,
bool raw);
bool
virtual bool
DoesBranch () const;
size_t
GetByteSize() const;
size_t
virtual size_t
Extract (const Disassembler &disassembler,
const lldb_private::DataExtractor &data,
uint32_t data_offset);

View File

@ -258,6 +258,7 @@ StackFrame::Disassemble ()
Target &target = m_thread.GetProcess().GetTarget();
Disassembler::Disassemble (target.GetDebugger(),
target.GetArchitecture(),
NULL,
exe_ctx,
0,
0,

View File

@ -110,7 +110,7 @@ ThreadPlanAssemblyTracer::InitializeTracer()
ArchSpec arch(target.GetArchitecture());
m_disassembler = Disassembler::FindPlugin(arch);
m_disassembler = Disassembler::FindPlugin(arch, NULL);
m_abi = process.GetABI();
@ -215,8 +215,7 @@ ThreadPlanAssemblyTracer::Log ()
Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
instruction->Dump (&desc,
false,
NULL,
0,
false,
NULL,
true);
}