[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