[Lldb-commits] [lldb] r176392 - Convert from the C-based LLVM Disassembler shim to the full MC Disassembler API's.
Jim Ingham
jingham at apple.com
Fri Mar 1 16:26:47 PST 2013
Author: jingham
Date: Fri Mar 1 18:26:47 2013
New Revision: 176392
URL: http://llvm.org/viewvc/llvm-project?rev=176392&view=rev
Log:
Convert from the C-based LLVM Disassembler shim to the full MC Disassembler API's.
Calculate "can branch" using the MC API's rather than our hand-rolled regex'es.
As extra credit, allow setting the disassembly flavor for x86 based architectures to intel or att.
<rdar://problem/11319574>
<rdar://problem/9329275>
Modified:
lldb/trunk/include/lldb/API/SBFunction.h
lldb/trunk/include/lldb/API/SBSymbol.h
lldb/trunk/include/lldb/API/SBTarget.h
lldb/trunk/include/lldb/Core/Disassembler.h
lldb/trunk/include/lldb/Target/Target.h
lldb/trunk/include/lldb/lldb-enumerations.h
lldb/trunk/include/lldb/lldb-private-interfaces.h
lldb/trunk/scripts/Python/interface/SBFunction.i
lldb/trunk/scripts/Python/interface/SBSymbol.i
lldb/trunk/scripts/Python/interface/SBTarget.i
lldb/trunk/source/API/SBFunction.cpp
lldb/trunk/source/API/SBSymbol.cpp
lldb/trunk/source/API/SBTarget.cpp
lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
lldb/trunk/source/Commands/CommandObjectDisassemble.h
lldb/trunk/source/Core/DataExtractor.cpp
lldb/trunk/source/Core/Disassembler.cpp
lldb/trunk/source/Expression/ClangExpressionParser.cpp
lldb/trunk/source/Interpreter/CommandObject.cpp
lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
lldb/trunk/source/Target/StackFrame.cpp
lldb/trunk/source/Target/Target.cpp
lldb/trunk/source/Target/ThreadPlanStepRange.cpp
lldb/trunk/source/Target/ThreadPlanTracer.cpp
Modified: lldb/trunk/include/lldb/API/SBFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFunction.h?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBFunction.h (original)
+++ lldb/trunk/include/lldb/API/SBFunction.h Fri Mar 1 18:26:47 2013
@@ -41,6 +41,9 @@ public:
lldb::SBInstructionList
GetInstructions (lldb::SBTarget target);
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor);
+
lldb::SBAddress
GetStartAddress ();
Modified: lldb/trunk/include/lldb/API/SBSymbol.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBSymbol.h?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBSymbol.h (original)
+++ lldb/trunk/include/lldb/API/SBSymbol.h Fri Mar 1 18:26:47 2013
@@ -43,6 +43,9 @@ public:
lldb::SBInstructionList
GetInstructions (lldb::SBTarget target);
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor_string);
+
SBAddress
GetStartAddress ();
Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Fri Mar 1 18:26:47 2013
@@ -744,11 +744,23 @@ public:
ReadInstructions (lldb::SBAddress base_addr, uint32_t count);
lldb::SBInstructionList
+ ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string);
+
+ lldb::SBInstructionList
GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size);
+ // The "WithFlavor" is necessary to keep SWIG from getting confused about overloaded arguments when
+ // using the buf + size -> Python Object magic.
+
+ lldb::SBInstructionList
+ GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size);
+
lldb::SBInstructionList
GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size);
+ lldb::SBInstructionList
+ GetInstructionsWithFlavor (lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size);
+
lldb::SBSymbolContextList
FindSymbols (const char *name,
lldb::SymbolType type = eSymbolTypeAny);
Modified: lldb/trunk/include/lldb/Core/Disassembler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Disassembler.h?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Disassembler.h (original)
+++ lldb/trunk/include/lldb/Core/Disassembler.h Fri Mar 1 18:26:47 2013
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <vector>
+#include <string>
// Other libraries and framework includes
// Project includes
@@ -51,7 +52,7 @@ public:
GetOperands (const ExecutionContext* exe_ctx)
{
CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
- return m_mnemocics.c_str();
+ return m_mnemonics.c_str();
}
const char *
@@ -137,7 +138,7 @@ private:
protected:
Opcode m_opcode; // The opcode for this instruction
std::string m_opcode_name;
- std::string m_mnemocics;
+ std::string m_mnemonics;
std::string m_comment;
bool m_calculated_strings;
@@ -247,18 +248,28 @@ public:
eOptionMarkPCAddress = (1u << 3) // Mark the disassembly line the contains the PC
};
+ // FindPlugin should be lax about the flavor string (it is too annoying to have various internal uses of the
+ // disassembler fail because the global flavor string gets set wrong. Instead, if you get a flavor string you
+ // don't understand, use the default. Folks who care to check can use the FlavorValidForArchSpec method on the
+ // disassembler they got back.
static lldb::DisassemblerSP
- FindPlugin (const ArchSpec &arch, const char *plugin_name);
+ FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name);
+
+ // This version will use the value in the Target settings if flavor is NULL;
+ static lldb::DisassemblerSP
+ FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name);
static lldb::DisassemblerSP
DisassembleRange (const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const AddressRange &disasm_range);
static lldb::DisassemblerSP
DisassembleBytes (const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const Address &start,
const void *bytes,
size_t length,
@@ -268,6 +279,7 @@ public:
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const AddressRange &range,
uint32_t num_instructions,
@@ -279,6 +291,7 @@ public:
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const Address &start,
uint32_t num_instructions,
@@ -290,6 +303,7 @@ public:
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
uint32_t num_instructions,
@@ -301,6 +315,7 @@ public:
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const ConstString &name,
Module *module,
@@ -313,16 +328,17 @@ public:
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
uint32_t num_instructions,
uint32_t num_mixed_context_lines,
uint32_t options,
Stream &strm);
-
+
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- Disassembler(const ArchSpec &arch);
+ Disassembler(const ArchSpec &arch, const char *flavor);
virtual ~Disassembler();
typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
@@ -365,6 +381,15 @@ public:
{
return m_arch;
}
+
+ const char *
+ GetFlavor () const
+ {
+ return m_flavor.c_str();
+ }
+
+ virtual bool
+ FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) = 0;
protected:
//------------------------------------------------------------------
@@ -373,6 +398,7 @@ protected:
const ArchSpec m_arch;
InstructionList m_instruction_list;
lldb::addr_t m_base_addr;
+ std::string m_flavor;
private:
//------------------------------------------------------------------
Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Fri Mar 1 18:26:47 2013
@@ -79,6 +79,12 @@ public:
void
SetDisableSTDIO (bool b);
+ const char *
+ GetDisassemblyFlavor() const;
+
+// void
+// SetDisassemblyFlavor(const char *flavor);
+
InlineStrategy
GetInlineStrategy () const;
Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Fri Mar 1 18:26:47 2013
@@ -381,6 +381,7 @@ namespace lldb {
eArgTypeCommandName,
eArgTypeCount,
eArgTypeDirectoryName,
+ eArgTypeDisassemblyFlavor,
eArgTypeEndAddress,
eArgTypeExpression,
eArgTypeExpressionPath,
Modified: lldb/trunk/include/lldb/lldb-private-interfaces.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-interfaces.h?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-private-interfaces.h (original)
+++ lldb/trunk/include/lldb/lldb-private-interfaces.h Fri Mar 1 18:26:47 2013
@@ -17,7 +17,7 @@
namespace lldb_private
{
typedef lldb::ABISP (*ABICreateInstance) (const ArchSpec &arch);
- typedef Disassembler* (*DisassemblerCreateInstance) (const ArchSpec &arch);
+ typedef Disassembler* (*DisassemblerCreateInstance) (const ArchSpec &arch, const char *flavor);
typedef DynamicLoader* (*DynamicLoaderCreateInstance) (Process* process, bool force);
typedef ObjectContainer* (*ObjectContainerCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t offset, lldb::offset_t length);
typedef ObjectFile* (*ObjectFileCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec* file, lldb::offset_t file_offset, lldb::offset_t length);
Modified: lldb/trunk/scripts/Python/interface/SBFunction.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBFunction.i?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBFunction.i (original)
+++ lldb/trunk/scripts/Python/interface/SBFunction.i Fri Mar 1 18:26:47 2013
@@ -65,6 +65,9 @@ public:
lldb::SBInstructionList
GetInstructions (lldb::SBTarget target);
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor);
+
lldb::SBAddress
GetStartAddress ();
Modified: lldb/trunk/scripts/Python/interface/SBSymbol.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBSymbol.i?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBSymbol.i (original)
+++ lldb/trunk/scripts/Python/interface/SBSymbol.i Fri Mar 1 18:26:47 2013
@@ -38,6 +38,9 @@ public:
lldb::SBInstructionList
GetInstructions (lldb::SBTarget target);
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor_string);
+
SBAddress
GetStartAddress ();
Modified: lldb/trunk/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBTarget.i?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/Python/interface/SBTarget.i Fri Mar 1 18:26:47 2013
@@ -704,8 +704,14 @@ public:
ReadInstructions (lldb::SBAddress base_addr, uint32_t count);
lldb::SBInstructionList
+ ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string);
+
+ lldb::SBInstructionList
GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size);
+ lldb::SBInstructionList
+ GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size);
+
lldb::SBSymbolContextList
FindSymbols (const char *name, lldb::SymbolType type = eSymbolTypeAny);
Modified: lldb/trunk/source/API/SBFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFunction.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/API/SBFunction.cpp (original)
+++ lldb/trunk/source/API/SBFunction.cpp Fri Mar 1 18:26:47 2013
@@ -122,6 +122,12 @@ SBFunction::GetDescription (SBStream &s)
SBInstructionList
SBFunction::GetInstructions (SBTarget target)
{
+ return GetInstructions (target, NULL);
+}
+
+SBInstructionList
+SBFunction::GetInstructions (SBTarget target, const char *flavor)
+{
SBInstructionList sb_instructions;
if (m_opaque_ptr)
{
@@ -139,6 +145,7 @@ SBFunction::GetInstructions (SBTarget ta
{
sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture(),
NULL,
+ flavor,
exe_ctx,
m_opaque_ptr->GetAddressRange()));
}
Modified: lldb/trunk/source/API/SBSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBSymbol.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/API/SBSymbol.cpp (original)
+++ lldb/trunk/source/API/SBSymbol.cpp Fri Mar 1 18:26:47 2013
@@ -113,11 +113,15 @@ SBSymbol::GetDescription (SBStream &desc
return true;
}
-
-
SBInstructionList
SBSymbol::GetInstructions (SBTarget target)
{
+ return GetInstructions (target, NULL);
+}
+
+SBInstructionList
+SBSymbol::GetInstructions (SBTarget target, const char *flavor_string)
+{
SBInstructionList sb_instructions;
if (m_opaque_ptr)
{
@@ -137,6 +141,7 @@ SBSymbol::GetInstructions (SBTarget targ
AddressRange symbol_range (m_opaque_ptr->GetAddress(), m_opaque_ptr->GetByteSize());
sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture (),
NULL,
+ flavor_string,
exe_ctx,
symbol_range));
}
Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Fri Mar 1 18:26:47 2013
@@ -2250,6 +2250,12 @@ SBTarget::GetSourceManager()
lldb::SBInstructionList
SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count)
{
+ return ReadInstructions (base_addr, count, NULL);
+}
+
+lldb::SBInstructionList
+SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string)
+{
SBInstructionList sb_instructions;
TargetSP target_sp(GetSP());
@@ -2265,6 +2271,7 @@ SBTarget::ReadInstructions (lldb::SBAddr
const size_t bytes_read = target_sp->ReadMemory(*addr_ptr, prefer_file_cache, data.GetBytes(), data.GetByteSize(), error);
sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
NULL,
+ flavor_string,
*addr_ptr,
data.GetBytes(),
bytes_read,
@@ -2279,6 +2286,12 @@ SBTarget::ReadInstructions (lldb::SBAddr
lldb::SBInstructionList
SBTarget::GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size)
{
+ return GetInstructionsWithFlavor (base_addr, NULL, buf, size);
+}
+
+lldb::SBInstructionList
+SBTarget::GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size)
+{
SBInstructionList sb_instructions;
TargetSP target_sp(GetSP());
@@ -2291,6 +2304,7 @@ SBTarget::GetInstructions (lldb::SBAddre
sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
NULL,
+ flavor_string,
addr,
buf,
size));
@@ -2302,7 +2316,13 @@ SBTarget::GetInstructions (lldb::SBAddre
lldb::SBInstructionList
SBTarget::GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size)
{
- return GetInstructions (ResolveLoadAddress(base_addr), buf, size);
+ return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), NULL, buf, size);
+}
+
+lldb::SBInstructionList
+SBTarget::GetInstructionsWithFlavor (lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size)
+{
+ return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), flavor_string, buf, size);
}
SBError
Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Fri Mar 1 18:26:47 2013
@@ -46,6 +46,7 @@ CommandObjectDisassemble::CommandOptions
at_pc (false),
frame_line (false),
plugin_name (),
+ flavor_string(),
arch(),
some_location_specified (false)
{
@@ -125,6 +126,18 @@ CommandObjectDisassemble::CommandOptions
plugin_name.assign (option_arg);
break;
+ case 'F':
+ {
+ Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+ if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86
+ || target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)
+ {
+ flavor_string.assign (option_arg);
+ }
+ else
+ error.SetErrorStringWithFormat("Disassembler flavors are currently only supported for x86 and x86_64 targets.");
+ break;
+ }
case 'r':
raw = true;
break;
@@ -162,6 +175,26 @@ CommandObjectDisassemble::CommandOptions
end_addr = LLDB_INVALID_ADDRESS;
raw = false;
plugin_name.clear();
+
+ Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+
+ // This is a hack till we get the ability to specify features based on architecture. For now GetDisassemblyFlavor
+ // is really only valid for x86 (and for the llvm assembler plugin, but I'm papering over that since that is the
+ // only disassembler plugin we have...
+ if (target)
+ {
+ if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86
+ || target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)
+ {
+ flavor_string.assign(target->GetDisassemblyFlavor());
+ }
+ else
+ flavor_string.assign ("default");
+
+ }
+ else
+ flavor_string.assign("default");
+
arch.Clear();
some_location_specified = false;
}
@@ -189,6 +222,9 @@ CommandObjectDisassemble::CommandOptions
{ 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_ALL, false, "flavor" , 'F', required_argument , NULL, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. "
+ "Currently the only valid options are default, and for Intel"
+ " architectures, att and intel."},
{ LLDB_OPT_SET_ALL, false, "arch" , 'a', required_argument , NULL, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."},
{ LLDB_OPT_SET_1 |
LLDB_OPT_SET_2 , true , "start-address", 's', required_argument , NULL, 0, eArgTypeAddressOrExpression,"Address at which to start disassembling."},
@@ -245,20 +281,26 @@ CommandObjectDisassemble::DoExecute (Arg
}
const char *plugin_name = m_options.GetPluginName ();
- DisassemblerSP disassembler = Disassembler::FindPlugin(m_options.arch, plugin_name);
+ const char *flavor_string = m_options.GetFlavorString();
+
+ DisassemblerSP disassembler = Disassembler::FindPlugin(m_options.arch, flavor_string, plugin_name);
if (!disassembler)
{
if (plugin_name)
- result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
+ {
+ result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
plugin_name,
m_options.arch.GetArchitectureName());
+ }
else
result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for the '%s' architecture.\n",
m_options.arch.GetArchitectureName());
result.SetStatus (eReturnStatusFailed);
return false;
}
+ else if (flavor_string != NULL && !disassembler->FlavorValidForArchSpec(m_options.arch, flavor_string))
+ result.AppendWarningWithFormat("invalid disassembler flavor \"%s\", using default.\n", flavor_string);
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -293,6 +335,7 @@ CommandObjectDisassemble::DoExecute (Arg
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
m_options.arch,
plugin_name,
+ flavor_string,
m_exe_ctx,
name,
NULL, // Module *
@@ -413,6 +456,7 @@ CommandObjectDisassemble::DoExecute (Arg
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
m_options.arch,
plugin_name,
+ flavor_string,
m_exe_ctx,
range.GetBaseAddress(),
m_options.num_instructions,
@@ -459,6 +503,7 @@ CommandObjectDisassemble::DoExecute (Arg
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
m_options.arch,
plugin_name,
+ flavor_string,
m_exe_ctx,
range,
m_options.num_instructions,
Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.h?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectDisassemble.h (original)
+++ lldb/trunk/source/Commands/CommandObjectDisassemble.h Fri Mar 1 18:26:47 2013
@@ -53,6 +53,14 @@ public:
return plugin_name.c_str();
}
+ const char *
+ GetFlavorString ()
+ {
+ if (flavor_string.empty() || flavor_string == "default")
+ return NULL;
+ return flavor_string.c_str();
+ }
+
virtual Error
OptionParsingFinished ();
@@ -68,6 +76,7 @@ public:
bool at_pc;
bool frame_line;
std::string plugin_name;
+ std::string flavor_string;
ArchSpec arch;
bool some_location_specified; // If no location was specified, we'll select "at_pc". This should be set
// in SetOptionValue if anything the selects a location is set.
Modified: lldb/trunk/source/Core/DataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataExtractor.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataExtractor.cpp (original)
+++ lldb/trunk/source/Core/DataExtractor.cpp Fri Mar 1 18:26:47 2013
@@ -1332,7 +1332,7 @@ DataExtractor::Dump (Stream *s,
target_sp = exe_scope->CalculateTarget();
if (target_sp)
{
- DisassemblerSP disassembler_sp (Disassembler::FindPlugin(target_sp->GetArchitecture(), NULL));
+ DisassemblerSP disassembler_sp (Disassembler::FindPlugin(target_sp->GetArchitecture(), NULL, NULL));
if (disassembler_sp)
{
lldb::addr_t addr = base_addr + start_offset;
Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Fri Mar 1 18:26:47 2013
@@ -45,7 +45,7 @@ using namespace lldb_private;
DisassemblerSP
-Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
+Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
"Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
@@ -59,7 +59,7 @@ Disassembler::FindPlugin (const ArchSpec
create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
if (create_callback)
{
- DisassemblerSP disassembler_sp(create_callback(arch));
+ DisassemblerSP disassembler_sp(create_callback(arch, flavor));
if (disassembler_sp.get())
return disassembler_sp;
@@ -69,7 +69,7 @@ Disassembler::FindPlugin (const ArchSpec
{
for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- DisassemblerSP disassembler_sp(create_callback(arch));
+ DisassemblerSP disassembler_sp(create_callback(arch, flavor));
if (disassembler_sp.get())
return disassembler_sp;
@@ -78,6 +78,20 @@ Disassembler::FindPlugin (const ArchSpec
return DisassemblerSP();
}
+DisassemblerSP
+Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
+{
+ if (target_sp && flavor == NULL)
+ {
+ // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now
+ // we only support flavors on x86 & x86_64,
+ if (arch.GetTriple().getArch() == llvm::Triple::x86
+ || arch.GetTriple().getArch() == llvm::Triple::x86_64)
+ flavor = target_sp->GetDisassemblyFlavor();
+ }
+ return FindPlugin(arch, flavor, plugin_name);
+}
+
static void
ResolveAddress (const ExecutionContext &exe_ctx,
@@ -114,6 +128,7 @@ Disassembler::Disassemble
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
uint32_t num_instructions,
@@ -137,6 +152,7 @@ Disassembler::Disassemble
if (Disassemble (debugger,
arch,
plugin_name,
+ flavor,
exe_ctx,
range,
num_instructions,
@@ -158,6 +174,7 @@ Disassembler::Disassemble
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const ConstString &name,
Module *module,
@@ -204,6 +221,7 @@ Disassembler::Disassemble
return Disassemble (debugger,
arch,
plugin_name,
+ flavor,
exe_ctx,
sc_list,
num_instructions,
@@ -220,6 +238,7 @@ Disassembler::DisassembleRange
(
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const AddressRange &range
)
@@ -227,7 +246,7 @@ Disassembler::DisassembleRange
lldb::DisassemblerSP disasm_sp;
if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
{
- disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
+ disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
if (disasm_sp)
{
@@ -244,6 +263,7 @@ Disassembler::DisassembleBytes
(
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const Address &start,
const void *bytes,
size_t length,
@@ -254,7 +274,7 @@ Disassembler::DisassembleBytes
if (bytes)
{
- disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
+ disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
if (disasm_sp)
{
@@ -278,6 +298,7 @@ Disassembler::Disassemble
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const AddressRange &disasm_range,
uint32_t num_instructions,
@@ -288,7 +309,7 @@ Disassembler::Disassemble
{
if (disasm_range.GetByteSize())
{
- lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
+ lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
if (disasm_sp.get())
{
@@ -319,6 +340,7 @@ Disassembler::Disassemble
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const Address &start_address,
uint32_t num_instructions,
@@ -329,7 +351,7 @@ Disassembler::Disassemble
{
if (num_instructions > 0)
{
- lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
+ lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
if (disasm_sp.get())
{
Address addr;
@@ -473,6 +495,7 @@ Disassembler::Disassemble
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
uint32_t num_instructions,
uint32_t num_mixed_context_lines,
@@ -506,6 +529,7 @@ Disassembler::Disassemble
return Disassemble (debugger,
arch,
plugin_name,
+ flavor,
exe_ctx,
range,
num_instructions,
@@ -594,7 +618,7 @@ Instruction::Dump (lldb_private::Stream
ss.PutCString (m_opcode_name.c_str());
ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
- ss.PutCString (m_mnemocics.c_str());
+ ss.PutCString (m_mnemonics.c_str());
if (!m_comment.empty())
{
@@ -1121,12 +1145,16 @@ Disassembler::ParseInstructions
//----------------------------------------------------------------------
// Disassembler copy constructor
//----------------------------------------------------------------------
-Disassembler::Disassembler(const ArchSpec& arch) :
+Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
m_arch (arch),
m_instruction_list(),
- m_base_addr(LLDB_INVALID_ADDRESS)
+ m_base_addr(LLDB_INVALID_ADDRESS),
+ m_flavor ()
{
-
+ if (flavor == NULL)
+ m_flavor.assign("default");
+ else
+ m_flavor.assign(flavor);
}
//----------------------------------------------------------------------
Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Fri Mar 1 18:26:47 2013
@@ -798,7 +798,9 @@ ClangExpressionParser::DisassembleFuncti
ArchSpec arch(target->GetArchitecture());
- lldb::DisassemblerSP disassembler = Disassembler::FindPlugin(arch, NULL);
+ const char *plugin_name = NULL;
+ const char *flavor_string = NULL;
+ lldb::DisassemblerSP disassembler = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
if (!disassembler)
{
Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Fri Mar 1 18:26:47 2013
@@ -1029,6 +1029,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { NULL, false }, "A debugger command (may be multiple words), without any options or arguments." },
{ eArgTypeCount, "count", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
{ eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { NULL, false }, "A directory name." },
+ { eArgTypeDisassemblyFlavor, "disassembly-flavor", CommandCompletions::eNoCompletion, { NULL, false }, "A disassembly flavor recognized by your disassembly plugin. Currently the only valid options are \"att\" and \"intel\" for Intel targets" },
{ eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
{ eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
{ eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, NULL },
Modified: lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp Fri Mar 1 18:26:47 2013
@@ -10,7 +10,20 @@
#include "DisassemblerLLVMC.h"
#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/ADT/SmallString.h"
+
#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
@@ -113,19 +126,20 @@ public:
}
if (!got_op)
{
- ::LLVMDisasmContextRef disasm_context = m_disasm.m_disasm_context;
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = m_disasm.m_disasm_ap.get();
bool is_altnernate_isa = false;
- if (m_disasm.m_alternate_disasm_context)
+ if (m_disasm.m_alternate_disasm_ap.get() != NULL)
{
const AddressClass address_class = GetAddressClass ();
if (address_class == eAddressClassCodeAlternateISA)
{
- disasm_context = m_disasm.m_alternate_disasm_context;
+ mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
is_altnernate_isa = true;
}
}
+
const llvm::Triple::ArchType machine = arch.GetMachine();
if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
{
@@ -155,19 +169,16 @@ public:
{
// The opcode isn't evenly sized, so we need to actually use the llvm
// disassembler to parse it and get the size.
- char out_string[512];
m_disasm.Lock(this, NULL);
uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
const size_t opcode_data_len = data.GetByteSize() - data_offset;
const addr_t pc = m_address.GetFileAddress();
- const size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
- opcode_data,
- opcode_data_len,
- pc, // PC value
- out_string,
- sizeof(out_string));
- // The address lookup function could have caused us to fill in our comment
- m_comment.clear();
+ llvm::MCInst inst;
+
+ const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
m_disasm.Unlock();
if (inst_size == 0)
m_opcode.Clear();
@@ -203,12 +214,12 @@ public:
{
char out_string[512];
- ::LLVMDisasmContextRef disasm_context;
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
if (address_class == eAddressClassCodeAlternateISA)
- disasm_context = m_disasm.m_alternate_disasm_context;
+ mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
else
- disasm_context = m_disasm.m_disasm_context;
+ mc_disasm_ptr = m_disasm.m_disasm_ap.get();
lldb::addr_t pc = LLDB_INVALID_ADDRESS;
@@ -223,14 +234,17 @@ public:
pc = m_address.GetFileAddress();
m_disasm.Lock(this, exe_ctx);
+
uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1));
const size_t opcode_data_len = data.GetByteSize();
- size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
- opcode_data,
+ llvm::MCInst inst;
+ size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
opcode_data_len,
pc,
- out_string,
- sizeof(out_string));
+ inst);
+
+ if (inst_size > 0)
+ mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
m_disasm.Unlock();
@@ -290,17 +304,19 @@ public:
}
break;
}
- m_mnemocics.swap(mnemonic_strm.GetString());
+ m_mnemonics.swap(mnemonic_strm.GetString());
return;
}
else
{
if (m_does_branch == eLazyBoolCalculate)
{
- if (StringRepresentsBranch (out_string, strlen(out_string)))
+ bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
m_does_branch = eLazyBoolYes;
else
m_does_branch = eLazyBoolNo;
+
}
}
@@ -317,7 +333,7 @@ public:
if (matches[1].rm_so != -1)
m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
if (matches[2].rm_so != -1)
- m_mnemocics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
+ m_mnemonics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
}
}
}
@@ -335,88 +351,6 @@ public:
}
protected:
- bool StringRepresentsBranch (const char *data, size_t size)
- {
- const char *cursor = data;
-
- bool inWhitespace = true;
-
- while (inWhitespace && cursor < data + size)
- {
- switch (*cursor)
- {
- default:
- inWhitespace = false;
- break;
- case ' ':
- break;
- case '\t':
- break;
- }
-
- if (inWhitespace)
- ++cursor;
- }
-
- if (cursor >= data + size)
- return false;
-
- llvm::Triple::ArchType arch = m_disasm.GetArchitecture().GetMachine();
-
- switch (arch)
- {
- default:
- return false;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (cursor[0])
- {
- default:
- return false;
- case 'j':
- return true;
- case 'c':
- if (cursor[1] == 'a' &&
- cursor[2] == 'l' &&
- cursor[3] == 'l')
- return true;
- else
- return false;
- }
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (cursor[0])
- {
- default:
- return false;
- case 'b':
- {
- switch (cursor[1])
- {
- default:
- return true;
- case 'f':
- case 'i':
- case 'k':
- return false;
- }
- }
- case 'c':
- {
- switch (cursor[1])
- {
- default:
- return false;
- case 'b':
- return true;
- }
- }
- }
- }
-
- return false;
- }
-
bool m_is_valid;
DisassemblerLLVMC &m_disasm;
DisassemblerSP m_disasm_sp; // for ownership
@@ -429,12 +363,159 @@ protected:
bool InstructionLLVMC::s_regex_compiled = false;
::regex_t InstructionLLVMC::s_regex;
+DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner):
+ m_is_valid(true)
+{
+ std::string Error;
+ const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
+ if (!curr_target)
+ {
+ m_is_valid = false;
+ return;
+ }
+
+ m_instr_info_ap.reset(curr_target->createMCInstrInfo());
+ m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));
+
+ std::string features_str;
+
+ m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
+ features_str));
+
+ m_asm_info_ap.reset(curr_target->createMCAsmInfo(triple));
+
+ if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL)
+ {
+ m_is_valid = NULL;
+ return;
+ }
+
+ m_context_ap.reset(new llvm::MCContext(*m_asm_info_ap.get(), *(m_reg_info_ap.get()), 0));
+
+ m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get()));
+ if (m_disasm_ap.get())
+ {
+ m_disasm_ap->setupForSymbolicDisassembly(NULL,
+ DisassemblerLLVMC::SymbolLookupCallback,
+ (void *) &owner,
+ m_context_ap.get());
+
+ unsigned asm_printer_variant;
+ if (flavor == ~0U)
+ asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
+ else
+ {
+ asm_printer_variant = flavor;
+ }
+
+ m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant,
+ *m_asm_info_ap.get(),
+ *m_instr_info_ap.get(),
+ *m_reg_info_ap.get(),
+ *m_subtarget_info_ap.get()));
+ if (m_instr_printer_ap.get() == NULL)
+ {
+ m_disasm_ap.reset();
+ m_is_valid = false;
+ }
+ }
+ else
+ m_is_valid = false;
+}
+
+namespace {
+ // This is the memory object we use in GetInstruction.
+ class LLDBDisasmMemoryObject : public llvm::MemoryObject {
+ uint8_t *m_bytes;
+ uint64_t m_size;
+ uint64_t m_base_PC;
+ public:
+ LLDBDisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) :
+ m_bytes(bytes), m_size(size), m_base_PC(basePC) {}
+
+ uint64_t getBase() const { return m_base_PC; }
+ uint64_t getExtent() const { return m_size; }
+
+ int readByte(uint64_t addr, uint8_t *byte) const {
+ if (addr - m_base_PC >= m_size)
+ return -1;
+ *byte = m_bytes[addr - m_base_PC];
+ return 0;
+ }
+ };
+} // End Anonymous Namespace
+
+uint64_t
+DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (
+ uint8_t *opcode_data,
+ size_t opcode_data_len,
+ lldb::addr_t pc,
+ llvm::MCInst &mc_inst)
+{
+ LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
+ llvm::MCInst inst;
+ llvm::MCDisassembler::DecodeStatus status;
+
+ uint64_t new_inst_size;
+ status = m_disasm_ap->getInstruction(mc_inst,
+ new_inst_size,
+ memory_object,
+ pc,
+ llvm::nulls(),
+ llvm::nulls());
+ if (status == llvm::MCDisassembler::Success)
+ return new_inst_size;
+ else
+ return 0;
+}
+
+uint64_t
+DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len)
+{
+ llvm::StringRef unused_annotations;
+ llvm::SmallString<64> inst_string;
+ llvm::raw_svector_ostream inst_stream(inst_string);
+ m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
+ inst_stream.flush();
+
+ size_t output_size = std::min(out_buffer_len -1, inst_string.size());
+ std::memcpy(output_buffer, inst_string.data(), output_size);
+ output_buffer[output_size] = '\0';
+
+ return output_size;
+}
+
+bool
+DisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
+{
+ return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
+}
+
+bool
+DisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
+{
+ llvm::Triple triple = arch.GetTriple();
+ if (flavor == NULL || strcmp (flavor, "default") == 0)
+ return true;
+
+ if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
+ {
+ if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0)
+ return true;
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
+
Disassembler *
-DisassemblerLLVMC::CreateInstance (const ArchSpec &arch)
+DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
{
if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
{
- std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch));
+ std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));
if (disasm_ap.get() && disasm_ap->IsValid())
return disasm_ap.release();
@@ -442,18 +523,41 @@ DisassemblerLLVMC::CreateInstance (const
return NULL;
}
-DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch) :
- Disassembler(arch),
+DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
+ Disassembler(arch, flavor_string),
m_exe_ctx (NULL),
- m_inst (NULL),
- m_disasm_context (NULL),
- m_alternate_disasm_context (NULL)
+ m_inst (NULL)
{
- m_disasm_context = ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(),
- (void*)this,
- /*TagType=*/1,
- NULL,
- DisassemblerLLVMC::SymbolLookupCallback);
+ if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
+ {
+ m_flavor.assign("default");
+ }
+
+ const char *triple = arch.GetTriple().getTriple().c_str();
+ unsigned flavor = ~0U;
+
+ // So far the only supported flavor is "intel" on x86. The base class will set this
+ // correctly coming in.
+ if (arch.GetTriple().getArch() == llvm::Triple::x86
+ || arch.GetTriple().getArch() == llvm::Triple::x86_64)
+ {
+ if (m_flavor == "intel")
+ {
+ flavor = 1;
+ }
+ else if (m_flavor == "att")
+ {
+ flavor = 0;
+ }
+ }
+
+ m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this));
+ if (!m_disasm_ap->IsValid())
+ {
+ // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
+ // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
+ m_disasm_ap.reset();
+ }
if (arch.GetTriple().getArch() == llvm::Triple::arm)
{
@@ -461,26 +565,17 @@ DisassemblerLLVMC::DisassemblerLLVMC (co
thumb_arch.GetTriple().setArchName(llvm::StringRef("thumbv7"));
std::string thumb_triple(thumb_arch.GetTriple().getTriple());
- m_alternate_disasm_context = ::LLVMCreateDisasm(thumb_triple.c_str(),
- (void*)this,
- /*TagType=*/1,
- NULL,
- DisassemblerLLVMC::SymbolLookupCallback);
+ m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this));
+ if (!m_alternate_disasm_ap->IsValid())
+ {
+ m_disasm_ap.reset();
+ m_alternate_disasm_ap.reset();
+ }
}
}
DisassemblerLLVMC::~DisassemblerLLVMC()
{
- if (m_disasm_context)
- {
- ::LLVMDisasmDispose(m_disasm_context);
- m_disasm_context = NULL;
- }
- if (m_alternate_disasm_context)
- {
- ::LLVMDisasmDispose(m_alternate_disasm_context);
- m_alternate_disasm_context = NULL;
- }
}
size_t
@@ -506,7 +601,7 @@ DisassemblerLLVMC::DecodeInstructions (c
AddressClass address_class = eAddressClassCode;
- if (m_alternate_disasm_context)
+ if (m_alternate_disasm_ap.get() != NULL)
address_class = inst_addr.GetAddressClass ();
InstructionSP inst_sp(new InstructionLLVMC(*this,
Modified: lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h Fri Mar 1 18:26:47 2013
@@ -10,9 +10,23 @@
#ifndef liblldb_DisassemblerLLVMC_h_
#define liblldb_DisassemblerLLVMC_h_
+#include <string>
#include "llvm-c/Disassembler.h"
+// Opaque references to C++ Objects in LLVM's MC.
+namespace llvm
+{
+ class MCContext;
+ class MCInst;
+ class MCInstrInfo;
+ class MCRegisterInfo;
+ class MCDisassembler;
+ class MCInstPrinter;
+ class MCAsmInfo;
+ class MCSubtargetInfo;
+}
+
#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/PluginManager.h"
@@ -22,6 +36,34 @@ class InstructionLLVMC;
class DisassemblerLLVMC : public lldb_private::Disassembler
{
+ // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB), and there's a bit of goo to set up and own
+ // in the MC disassembler world, I added this class to manage the actual disassemblers.
+ class LLVMCDisassembler
+ {
+ public:
+ LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner);
+
+ ~LLVMCDisassembler() {};
+
+ uint64_t GetMCInst (uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst);
+ uint64_t PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len);
+ bool CanBranch (llvm::MCInst &mc_inst);
+ bool IsValid()
+ {
+ return m_is_valid;
+ }
+
+ private:
+ bool m_is_valid;
+ std::auto_ptr<llvm::MCContext> m_context_ap;
+ std::auto_ptr<llvm::MCAsmInfo> m_asm_info_ap;
+ std::auto_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
+ std::auto_ptr<llvm::MCInstrInfo> m_instr_info_ap;
+ std::auto_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
+ std::auto_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
+ std::auto_ptr<llvm::MCDisassembler> m_disasm_ap;
+ };
+
public:
//------------------------------------------------------------------
// Static Functions
@@ -39,10 +81,9 @@ public:
GetPluginDescriptionStatic();
static lldb_private::Disassembler *
- CreateInstance(const lldb_private::ArchSpec &arch);
-
-
- DisassemblerLLVMC(const lldb_private::ArchSpec &arch);
+ CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
+
+ DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor /* = NULL */);
virtual
~DisassemblerLLVMC();
@@ -69,10 +110,13 @@ public:
protected:
friend class InstructionLLVMC;
+ virtual bool
+ FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor);
+
bool
IsValid()
{
- return (m_disasm_context != NULL);
+ return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
}
int OpInfo(uint64_t PC,
@@ -117,8 +161,9 @@ protected:
const lldb_private::ExecutionContext *m_exe_ctx;
InstructionLLVMC *m_inst;
lldb_private::Mutex m_mutex;
- ::LLVMDisasmContextRef m_disasm_context;
- ::LLVMDisasmContextRef m_alternate_disasm_context;
+
+ std::auto_ptr<LLVMCDisassembler> m_disasm_ap;
+ std::auto_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
};
#endif // liblldb_DisassemblerLLVM_h_
Modified: lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp Fri Mar 1 18:26:47 2013
@@ -55,6 +55,7 @@ UnwindAssemblyInstEmulation::GetNonCallS
thread.CalculateExecutionContext(exe_ctx);
DisassemblerSP disasm_sp (Disassembler::DisassembleRange (m_arch,
NULL,
+ NULL,
exe_ctx,
range));
Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Fri Mar 1 18:26:47 2013
@@ -266,9 +266,12 @@ StackFrame::Disassemble ()
Target *target = exe_ctx.GetTargetPtr();
if (target)
{
+ const char *plugin_name = NULL;
+ const char *flavor = NULL;
Disassembler::Disassemble (target->GetDebugger(),
target->GetArchitecture(),
- NULL,
+ plugin_name,
+ flavor,
exe_ctx,
0,
0,
@@ -1426,9 +1429,12 @@ StackFrame::GetStatus (Stream& strm,
AddressRange pc_range;
pc_range.GetBaseAddress() = GetFrameCodeAddress();
pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
+ const char *plugin_name = NULL;
+ const char *flavor = NULL;
Disassembler::Disassemble (target->GetDebugger(),
target_arch,
- NULL,
+ plugin_name,
+ flavor,
exe_ctx,
pc_range,
disasm_lines,
Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Fri Mar 1 18:26:47 2013
@@ -2210,6 +2210,22 @@ g_inline_breakpoint_enums[] =
{ 0, NULL, NULL }
};
+typedef enum x86DisassemblyFlavor
+{
+ eX86DisFlavorDefault,
+ eX86DisFlavorIntel,
+ eX86DisFlavorATT
+} x86DisassemblyFlavor;
+
+static OptionEnumValueElement
+g_x86_dis_flavor_value_types[] =
+{
+ { eX86DisFlavorDefault, "default", "Disassembler default (currently att)."},
+ { eX86DisFlavorIntel, "intel", "Intel disassembler flavor."},
+ { eX86DisFlavorATT, "att", "AT&T disassembler flavor."},
+ { 0, NULL, NULL }
+};
+
static PropertyDefinition
g_properties[] =
{
@@ -2243,6 +2259,8 @@ g_properties[] =
"Always checking for inlined breakpoint locations can be expensive (memory and time), so we try to minimize the "
"times we look for inlined locations. This setting allows you to control exactly which strategy is used when settings "
"file and line breakpoints." },
+ // FIXME: This is the wrong way to do per-architecture settings, but we don't have a general per architecture settings system in place yet.
+ { "x86-disassembly-flavor" , OptionValue::eTypeEnum , false, eX86DisFlavorDefault, NULL, g_x86_dis_flavor_value_types, "The default disassembly flavor to use for x86 or x86-64 targets." },
{ NULL , OptionValue::eTypeInvalid , false, 0 , NULL, NULL, NULL }
};
enum
@@ -2266,7 +2284,8 @@ enum
ePropertyErrorPath,
ePropertyDisableASLR,
ePropertyDisableSTDIO,
- ePropertyInlineStrategy
+ ePropertyInlineStrategy,
+ ePropertyDisassemblyFlavor
};
@@ -2442,6 +2461,17 @@ TargetProperties::SetDisableSTDIO (bool
m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
}
+const char *
+TargetProperties::GetDisassemblyFlavor () const
+{
+ const uint32_t idx = ePropertyDisassemblyFlavor;
+ const char *return_value;
+
+ x86DisassemblyFlavor flavor_value = (x86DisassemblyFlavor) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
+ return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;
+ return return_value;
+}
+
InlineStrategy
TargetProperties::GetInlineStrategy () const
{
Modified: lldb/trunk/source/Target/ThreadPlanStepRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepRange.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepRange.cpp Fri Mar 1 18:26:47 2013
@@ -265,8 +265,11 @@ ThreadPlanStepRange::GetInstructionsForA
{
//Disassemble the address range given:
ExecutionContext exe_ctx (m_thread.GetProcess());
+ const char *plugin_name = NULL;
+ const char *flavor = NULL;
m_instruction_ranges[i] = Disassembler::DisassembleRange(GetTarget().GetArchitecture(),
- NULL,
+ plugin_name,
+ flavor,
exe_ctx,
m_address_ranges[i]);
Modified: lldb/trunk/source/Target/ThreadPlanTracer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanTracer.cpp?rev=176392&r1=176391&r2=176392&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanTracer.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanTracer.cpp Fri Mar 1 18:26:47 2013
@@ -120,7 +120,7 @@ Disassembler *
ThreadPlanAssemblyTracer::GetDisassembler ()
{
if (m_disassembler_sp.get() == NULL)
- m_disassembler_sp = Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL);
+ m_disassembler_sp = Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL, NULL);
return m_disassembler_sp.get();
}
More information about the lldb-commits
mailing list