[Lldb-commits] [lldb] r128063 - in /lldb/trunk: include/lldb/Core/Disassembler.h lldb.xcodeproj/project.pbxproj source/Commands/CommandObjectDisassemble.cpp source/Commands/CommandObjectDisassemble.h source/Core/Disassembler.cpp source/Expression/ClangExpressionParser.cpp source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp source/Plugins/Disassembler/llvm/DisassemblerLLVM.h source/Target/StackFrame.cpp source/Target/ThreadPlanTracer.cpp

Jim Ingham jingham at apple.com
Mon Mar 21 18:48:42 PDT 2011


Author: jingham
Date: Mon Mar 21 20:48:42 2011
New Revision: 128063

URL: http://llvm.org/viewvc/llvm-project?rev=128063&view=rev
Log:
Add the ability to disassemble "n" instructions from the current PC, or the first "n" instructions in a function.
Also added a "-p" flag that disassembles from the current pc.

Modified:
    lldb/trunk/include/lldb/Core/Disassembler.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
    lldb/trunk/source/Commands/CommandObjectDisassemble.h
    lldb/trunk/source/Core/Disassembler.cpp
    lldb/trunk/source/Expression/ClangExpressionParser.cpp
    lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
    lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
    lldb/trunk/source/Target/StackFrame.cpp
    lldb/trunk/source/Target/ThreadPlanTracer.cpp

Modified: lldb/trunk/include/lldb/Core/Disassembler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Disassembler.h?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Disassembler.h (original)
+++ lldb/trunk/include/lldb/Core/Disassembler.h Mon Mar 21 20:48:42 2011
@@ -111,6 +111,18 @@
                  const ArchSpec &arch,
                  const ExecutionContext &exe_ctx,
                  const AddressRange &range,
+                 uint32_t num_instructions,
+                 uint32_t num_mixed_context_lines,
+                 bool show_bytes,
+                 bool raw,
+                 Stream &strm);
+
+    static bool
+    Disassemble (Debugger &debugger,
+                 const ArchSpec &arch,
+                 const ExecutionContext &exe_ctx,
+                 const Address &start,
+                 uint32_t num_instructions,
                  uint32_t num_mixed_context_lines,
                  bool show_bytes,
                  bool raw,
@@ -121,6 +133,7 @@
                  const ArchSpec &arch,
                  const ExecutionContext &exe_ctx,
                  SymbolContextList &sc_list,
+                 uint32_t num_instructions,
                  uint32_t num_mixed_context_lines,
                  bool show_bytes,
                  bool raw,
@@ -132,6 +145,7 @@
                  const ExecutionContext &exe_ctx,
                  const ConstString &name,
                  Module *module,
+                 uint32_t num_instructions,
                  uint32_t num_mixed_context_lines,
                  bool show_bytes,
                  bool raw,
@@ -141,6 +155,7 @@
     Disassemble (Debugger &debugger,
                  const ArchSpec &arch,
                  const ExecutionContext &exe_ctx,
+                 uint32_t num_instructions,
                  uint32_t num_mixed_context_lines,
                  bool show_bytes,
                  bool raw,
@@ -154,16 +169,36 @@
 
     typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
 
+    static bool 
+    PrintInstructions (Disassembler *disasm_ptr,
+                       DataExtractor &data,
+                       Debugger &debugger,
+                       const ArchSpec &arch,
+                       const ExecutionContext &exe_ctx,
+                       const  Address &start_addr,
+                       uint32_t num_instructions,
+                       uint32_t num_mixed_context_lines,
+                       bool show_bytes,
+                       bool raw,
+                       Stream &strm);
+    
     size_t
     ParseInstructions (const ExecutionContext *exe_ctx,
                        const AddressRange &range,
                        DataExtractor& data);
 
+    size_t
+    ParseInstructions (const ExecutionContext *exe_ctx,
+                       const Address &range,
+                       uint32_t num_instructions,
+                       DataExtractor& data);
+
     virtual size_t
     DecodeInstructions (const Address &base_addr,
                         const DataExtractor& data,
                         uint32_t data_offset,
-                        uint32_t num_instructions) = 0;
+                        uint32_t num_instructions,
+                        bool append) = 0;
     
     InstructionList &
     GetInstructionList ();

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Mar 21 20:48:42 2011
@@ -1231,11 +1231,11 @@
 		08FB7794FE84155DC02AAC07 /* lldb */ = {
 			isa = PBXGroup;
 			children = (
-				2689FFCA13353D7A00698AC0 /* liblldb-core.a */,
 				26F5C32810F3DF7D009D5894 /* Libraries */,
 				08FB7795FE84155DC02AAC07 /* Source */,
 				26F5C22410F3D950009D5894 /* Tools */,
 				1AB674ADFE9D54B511CA2CBB /* Products */,
+				2689FFCA13353D7A00698AC0 /* liblldb-core.a */,
 			);
 			name = lldb;
 			sourceTree = "<group>";

Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Mon Mar 21 20:48:42 2011
@@ -27,15 +27,19 @@
 #include "lldb/Target/Target.h"
 
 #define DEFAULT_DISASM_BYTE_SIZE 32
+#define DEFAULT_DISASM_NUM_INS  4
 
 using namespace lldb;
 using namespace lldb_private;
 
 CommandObjectDisassemble::CommandOptions::CommandOptions () :
     Options(),
+    num_lines_context(0),
+    num_instructions (0),
     m_func_name(),
     m_start_addr(),
-    m_end_addr ()
+    m_end_addr (),
+    m_at_pc (false)
 {
     ResetOptionValues();
 }
@@ -51,14 +55,24 @@
 
     char short_option = (char) m_getopt_table[option_idx].val;
 
+    bool success;
+    
     switch (short_option)
     {
     case 'm':
         show_mixed = true;
         break;
 
+    case 'x':
+        num_lines_context = Args::StringToUInt32(option_arg, 0, 0, &success);
+        if (!success)
+            error.SetErrorStringWithFormat ("Invalid num context lines string: \"%s\".\n", option_arg);
+        break;
+
     case 'c':
-        num_lines_context = Args::StringToUInt32(option_arg, 0, 0);
+        num_instructions = Args::StringToUInt32(option_arg, 0, 0, &success);
+        if (!success)
+            error.SetErrorStringWithFormat ("Invalid num of instructions string: \"%s\".\n", option_arg);
         break;
 
     case 'b':
@@ -66,26 +80,30 @@
         break;
 
     case 's':
-        m_start_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
+        m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
         if (m_start_addr == LLDB_INVALID_ADDRESS)
-            m_start_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
+            m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
 
         if (m_start_addr == LLDB_INVALID_ADDRESS)
-            error.SetErrorStringWithFormat ("Invalid start address string '%s'.\n", optarg);
+            error.SetErrorStringWithFormat ("Invalid start address string '%s'.\n", option_arg);
         break;
     case 'e':
-        m_end_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
+        m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
         if (m_end_addr == LLDB_INVALID_ADDRESS)
-            m_end_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
+            m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
 
         if (m_end_addr == LLDB_INVALID_ADDRESS)
-            error.SetErrorStringWithFormat ("Invalid end address string '%s'.\n", optarg);
+            error.SetErrorStringWithFormat ("Invalid end address string '%s'.\n", option_arg);
         break;
 
     case 'n':
         m_func_name = option_arg;
         break;
 
+    case 'p':
+        m_at_pc = true;
+        break;
+
     case 'r':
         raw = true;
         break;
@@ -110,7 +128,9 @@
     show_mixed = false;
     show_bytes = false;
     num_lines_context = 0;
+    num_instructions = 0;
     m_func_name.clear();
+    m_at_pc = false;
     m_start_addr = LLDB_INVALID_ADDRESS;
     m_end_addr = LLDB_INVALID_ADDRESS;
     raw = false;
@@ -126,16 +146,24 @@
 CommandObjectDisassemble::CommandOptions::g_option_table[] =
 {
 { LLDB_OPT_SET_ALL, false, "bytes",    'b', no_argument,       NULL, 0, eArgTypeNone,             "Show opcode bytes when disassembling."},
-{ LLDB_OPT_SET_ALL, false, "context",  'c', required_argument, NULL, 0, eArgTypeNumLines,    "Number of context lines of source to show."},
+{ LLDB_OPT_SET_ALL, false, "context",  'x', required_argument, NULL, 0, eArgTypeNumLines,    "Number of context lines of source to show."},
 { LLDB_OPT_SET_ALL, false, "mixed",    'm', no_argument,       NULL, 0, eArgTypeNone,             "Enable mixed source and assembly display."},
 { LLDB_OPT_SET_ALL, false, "raw",      'r', no_argument,       NULL, 0, eArgTypeNone,             "Print raw disassembly with no symbol information."},
 
 { LLDB_OPT_SET_1, true, "start-address",  's', required_argument, NULL, 0, eArgTypeStartAddress,      "Address at which to start disassembling."},
 { LLDB_OPT_SET_1, false, "end-address",  'e', required_argument, NULL, 0, eArgTypeEndAddress,      "Address at which to end disassembling."},
 
-{ LLDB_OPT_SET_2, true, "name",     'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,             "Disassemble entire contents of the given function name."},
+{ LLDB_OPT_SET_2, true, "start-address",  's', required_argument, NULL, 0, eArgTypeStartAddress,      "Address at which to start disassembling."},
+{ LLDB_OPT_SET_2, false, "instruction-count",  'c', required_argument, NULL, 0, eArgTypeNumLines,      "Number of instructions to display."},
 
-{ LLDB_OPT_SET_3, true, "current-frame", 'f',  no_argument, NULL, 0, eArgTypeNone,             "Disassemble entire contents of the current frame's function."},
+{ LLDB_OPT_SET_3, true, "name",     'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,             "Disassemble entire contents of the given function name."},
+{ LLDB_OPT_SET_3, false, "instruction-count",  'c', required_argument, NULL, 0, eArgTypeNumLines,      "Number of instructions to display."},
+
+{ LLDB_OPT_SET_4, true, "current-frame", 'f',  no_argument, NULL, 0, eArgTypeNone,             "Disassemble from the start of the current frame's function."},
+{ LLDB_OPT_SET_4, false, "instruction-count",  'c', required_argument, NULL, 0, eArgTypeNumLines,      "Number of instructions to display."},
+
+{ LLDB_OPT_SET_5, true, "current-pc", 'p',  no_argument, NULL, 0, eArgTypeNone,             "Disassemble from the current pc."},
+{ LLDB_OPT_SET_5, false, "instruction-count",  'c', required_argument, NULL, 0, eArgTypeNumLines,      "Number of instructions to display."},
 
 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
 };
@@ -202,11 +230,12 @@
         result.SetStatus (eReturnStatusFailed);
         return false;
     }
-    ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
-
+    
     if (m_options.show_mixed && m_options.num_lines_context == 0)
         m_options.num_lines_context = 1;
 
+    ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
+
     if (!m_options.m_func_name.empty())
     {
         ConstString name(m_options.m_func_name.c_str());
@@ -216,6 +245,7 @@
                                        exe_ctx,
                                        name,
                                        NULL,    // Module *
+                                       m_options.num_instructions,
                                        m_options.show_mixed ? m_options.num_lines_context : 0,
                                        m_options.show_bytes,
                                        m_options.raw,
@@ -231,62 +261,133 @@
     } 
     else
     {
-        AddressRange range;
-        if (m_options.m_start_addr != LLDB_INVALID_ADDRESS)
+        Address start_addr;
+        lldb::addr_t range_byte_size = DEFAULT_DISASM_BYTE_SIZE;
+        
+        if (m_options.m_at_pc)
         {
-            range.GetBaseAddress().SetOffset (m_options.m_start_addr);
-            if (m_options.m_end_addr != LLDB_INVALID_ADDRESS)
+            if (exe_ctx.frame == NULL)
+            {
+                result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
+                result.SetStatus (eReturnStatusFailed);
+                return false;
+            }
+            start_addr = exe_ctx.frame->GetFrameCodeAddress();
+            if (m_options.num_instructions == 0)
             {
-                if (m_options.m_end_addr < m_options.m_start_addr)
+                // Disassembling at the PC always disassembles some number of instructions (not the whole function).
+                m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
+            }
+        }
+        else
+        {
+            start_addr.SetOffset (m_options.m_start_addr);
+            if (start_addr.IsValid())
+            {
+                if (m_options.m_end_addr != LLDB_INVALID_ADDRESS)
                 {
-                    result.AppendErrorWithFormat ("End address before start address.\n");
+                    if (m_options.m_end_addr < m_options.m_start_addr)
+                    {
+                        result.AppendErrorWithFormat ("End address before start address.\n");
+                        result.SetStatus (eReturnStatusFailed);
+                        return false;            
+                    }
+                    range_byte_size = m_options.m_end_addr - m_options.m_start_addr;
+                }
+            }
+        }
+        
+        if (m_options.num_instructions != 0)
+        {
+            if (!start_addr.IsValid())
+            {
+                // The default action is to disassemble the current frame function.
+                if (exe_ctx.frame)
+                {
+                    SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
+                    if (sc.function)
+                        start_addr = sc.function->GetAddressRange().GetBaseAddress();
+                    else if (sc.symbol && sc.symbol->GetAddressRangePtr())
+                        start_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
+                    else
+                        start_addr = exe_ctx.frame->GetFrameCodeAddress();
+                }
+                
+                if (!start_addr.IsValid())
+                {
+                    result.AppendError ("invalid frame");
                     result.SetStatus (eReturnStatusFailed);
-                    return false;            
+                    return false;
                 }
-                range.SetByteSize (m_options.m_end_addr - m_options.m_start_addr);
+            }
+
+            if (Disassembler::Disassemble (m_interpreter.GetDebugger(), 
+                                           arch,
+                                           exe_ctx,
+                                           start_addr,
+                                           m_options.num_instructions,
+                                           m_options.show_mixed ? m_options.num_lines_context : 0,
+                                           m_options.show_bytes,
+                                           m_options.raw,
+                                           result.GetOutputStream()))
+            {
+                result.SetStatus (eReturnStatusSuccessFinishResult);
             }
             else
-                range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
-        } 
+            {
+                result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
+                result.SetStatus (eReturnStatusFailed);            
+            }
+        }
         else
         {
-            // The default action is to disassemble the current frame function.
-            if (exe_ctx.frame)
+            AddressRange range;
+            if (start_addr.IsValid())
             {
-                SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
-                if (sc.function)
-                    range = sc.function->GetAddressRange();
-                else if (sc.symbol && sc.symbol->GetAddressRangePtr())
-                    range = *sc.symbol->GetAddressRangePtr();
+                range.GetBaseAddress() = start_addr;
+                range.SetByteSize (range_byte_size);
+            } 
+            else
+            {
+                // The default action is to disassemble the current frame function.
+                if (exe_ctx.frame)
+                {
+                    SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
+                    if (sc.function)
+                        range = sc.function->GetAddressRange();
+                    else if (sc.symbol && sc.symbol->GetAddressRangePtr())
+                        range = *sc.symbol->GetAddressRangePtr();
+                    else
+                        range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
+                }
                 else
-                    range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
+                {
+                    result.AppendError ("invalid frame");
+                    result.SetStatus (eReturnStatusFailed);
+                    return false;
+                }
+            }
+            if (range.GetByteSize() == 0)
+                range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
+
+            if (Disassembler::Disassemble (m_interpreter.GetDebugger(), 
+                                           arch,
+                                           exe_ctx,
+                                           range,
+                                           m_options.num_instructions,
+                                           m_options.show_mixed ? m_options.num_lines_context : 0,
+                                           m_options.show_bytes,
+                                           m_options.raw,
+                                           result.GetOutputStream()))
+            {
+                result.SetStatus (eReturnStatusSuccessFinishResult);
             }
             else
             {
-                result.AppendError ("invalid frame");
-                result.SetStatus (eReturnStatusFailed);
-                return false;
+                result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
+                result.SetStatus (eReturnStatusFailed);            
             }
         }
-        if (range.GetByteSize() == 0)
-            range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
-
-        if (Disassembler::Disassemble (m_interpreter.GetDebugger(), 
-                                       arch,
-                                       exe_ctx,
-                                       range,
-                                       m_options.show_mixed ? m_options.num_lines_context : 0,
-                                       m_options.show_bytes,
-                                       m_options.raw,
-                                       result.GetOutputStream()))
-        {
-            result.SetStatus (eReturnStatusSuccessFinishResult);
-        }
-        else
-        {
-            result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
-            result.SetStatus (eReturnStatusFailed);            
-        }
     }
 
     return result.Succeeded();

Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.h?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectDisassemble.h (original)
+++ lldb/trunk/source/Commands/CommandObjectDisassemble.h Mon Mar 21 20:48:42 2011
@@ -47,10 +47,12 @@
         bool show_mixed; // Show mixed source/assembly
         bool show_bytes;
         uint32_t num_lines_context;
+        uint32_t num_instructions;
         bool raw;
         std::string m_func_name;
         lldb::addr_t m_start_addr;
         lldb::addr_t m_end_addr;
+        bool m_at_pc;
         static lldb::OptionDefinition g_option_table[];
     };
 

Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Mon Mar 21 20:48:42 2011
@@ -61,6 +61,7 @@
     const ArchSpec &arch,
     const ExecutionContext &exe_ctx,
     SymbolContextList &sc_list,
+    uint32_t num_instructions,
     uint32_t num_mixed_context_lines,
     bool show_bytes,
     bool raw,
@@ -71,13 +72,15 @@
     const size_t count = sc_list.GetSize();
     SymbolContext sc;
     AddressRange range;
+    
     for (size_t i=0; i<count; ++i)
     {
         if (sc_list.GetContextAtIndex(i, sc) == false)
             break;
         if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
         {
-            if (Disassemble (debugger, arch, exe_ctx, range, num_mixed_context_lines, show_bytes, raw, strm))
+            if (Disassemble (debugger, arch, exe_ctx, range, num_instructions,
+                             num_mixed_context_lines, show_bytes, raw, strm))
             {
                 ++success_count;
                 strm.EOL();
@@ -95,6 +98,7 @@
     const ExecutionContext &exe_ctx,
     const ConstString &name,
     Module *module,
+    uint32_t num_instructions,
     uint32_t num_mixed_context_lines,
     bool show_bytes,
     bool raw,
@@ -134,7 +138,8 @@
         return Disassemble (debugger, 
                             arch, 
                             exe_ctx, 
-                            sc_list, 
+                            sc_list,
+                            num_instructions, 
                             num_mixed_context_lines, 
                             show_bytes,
                             raw,
@@ -176,6 +181,7 @@
     const ArchSpec &arch,
     const ExecutionContext &exe_ctx,
     const AddressRange &disasm_range,
+    uint32_t num_instructions,
     uint32_t num_mixed_context_lines,
     bool show_bytes,
     bool raw,
@@ -190,8 +196,6 @@
         {
             AddressRange range(disasm_range);
             
-            Process *process = exe_ctx.process;
-
             // If we weren't passed in a section offset address range,
             // try and resolve it to something
             if (range.GetBaseAddress().IsSectionOffset() == false)
@@ -217,116 +221,211 @@
             }
             else
             {
-                // We got some things disassembled...
-                size_t num_instructions = disasm_ap->GetInstructionList().GetSize();
-                uint32_t offset = 0;
-                SymbolContext sc;
-                SymbolContext prev_sc;
-                AddressRange sc_range;
-                if (num_mixed_context_lines)
-                    strm.IndentMore ();
-
-
-                Address addr(range.GetBaseAddress());
-    
-                // We extract the section to make sure we don't transition out
-                // of the current section when disassembling
-                const Section *addr_section = addr.GetSection();
-                Module *range_module = range.GetBaseAddress().GetModule();
+                return PrintInstructions (disasm_ap.get(),
+                                          data,
+                                          debugger,
+                                          arch,
+                                          exe_ctx,
+                                          disasm_range.GetBaseAddress(),
+                                          num_instructions,
+                                          num_mixed_context_lines,
+                                          show_bytes,
+                                          raw,
+                                          strm);
+            }
+        }
+    }
+    return false;
+}
+            
+bool
+Disassembler::Disassemble
+(
+    Debugger &debugger,
+    const ArchSpec &arch,
+    const ExecutionContext &exe_ctx,
+    const Address &start_address,
+    uint32_t num_instructions,
+    uint32_t num_mixed_context_lines,
+    bool show_bytes,
+    bool raw,
+    Stream &strm
+)
+{
+    if (num_instructions > 0)
+    {
+        std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch));
+        Address addr = start_address;
 
-                for (size_t i=0; i<num_instructions; ++i)
+        if (disasm_ap.get())
+        {
+            // If we weren't passed in a section offset address range,
+            // try and resolve it to something
+            if (addr.IsSectionOffset() == false)
+            {
+                if (exe_ctx.target)
                 {
-                    Instruction *inst = disasm_ap->GetInstructionList().GetInstructionAtIndex (i).get();
-                    if (inst)
+                    if (exe_ctx.target->GetSectionLoadList().IsEmpty())
                     {
-                        addr_t file_addr = addr.GetFileAddress();
-                        if (addr_section == NULL || addr_section->ContainsFileAddress (file_addr) == false)
-                        {
-                            if (range_module)
-                                range_module->ResolveFileAddress (file_addr, addr);
-                            else if (exe_ctx.target)
-                                exe_ctx.target->GetImages().ResolveFileAddress (file_addr, addr);
-                                
-                            addr_section = addr.GetSection();
-                        }
+                        exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), addr);
+                    }
+                    else
+                    {
+                        exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), addr);
+                    }
+                }
+            }
+
+            DataExtractor data;
+            size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions, data);
+            if (bytes_disassembled == 0)
+            {
+                return false;
+            }
+            else
+            {
+                return PrintInstructions (disasm_ap.get(),
+                                          data,
+                                          debugger,
+                                          arch,
+                                          exe_ctx,
+                                          addr,
+                                          num_instructions,
+                                          num_mixed_context_lines,
+                                          show_bytes,
+                                          raw,
+                                          strm);
+            }
+        }
+    }
+    return false;
+}
+            
+bool 
+Disassembler::PrintInstructions
+(
+    Disassembler *disasm_ptr,
+    DataExtractor &data,
+    Debugger &debugger,
+    const ArchSpec &arch,
+    const ExecutionContext &exe_ctx,
+    const Address &start_addr,
+    uint32_t num_instructions,
+    uint32_t num_mixed_context_lines,
+    bool show_bytes,
+    bool raw,
+    Stream &strm
+)
+{
+    // We got some things disassembled...
+    size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
+    
+    if (num_instructions > 0 && num_instructions < num_instructions_found)
+        num_instructions_found = num_instructions;
+        
+    uint32_t offset = 0;
+    SymbolContext sc;
+    SymbolContext prev_sc;
+    AddressRange sc_range;
+    Address addr = start_addr;
+    
+    if (num_mixed_context_lines)
+        strm.IndentMore ();
 
-                        prev_sc = sc;
+    // We extract the section to make sure we don't transition out
+    // of the current section when disassembling
+    const Section *addr_section = addr.GetSection();
+    Module *range_module = addr.GetModule();
 
-                        if (addr_section)
+    for (size_t i=0; i<num_instructions_found; ++i)
+    {
+        Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
+        if (inst)
+        {
+            addr_t file_addr = addr.GetFileAddress();
+            if (addr_section == NULL || addr_section->ContainsFileAddress (file_addr) == false)
+            {
+                if (range_module)
+                    range_module->ResolveFileAddress (file_addr, addr);
+                else if (exe_ctx.target)
+                    exe_ctx.target->GetImages().ResolveFileAddress (file_addr, addr);
+                    
+                addr_section = addr.GetSection();
+            }
+
+            prev_sc = sc;
+
+            if (addr_section)
+            {
+                Module *module = addr_section->GetModule();
+                uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
+                if (resolved_mask)
+                {
+                    if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
+                    {
+                        if (prev_sc.function || prev_sc.symbol)
+                            strm.EOL();
+
+                        strm << sc.module_sp->GetFileSpec().GetFilename();
+                        
+                        if (sc.function)
+                            strm << '`' << sc.function->GetMangled().GetName();
+                        else if (sc.symbol)
+                            strm << '`' << sc.symbol->GetMangled().GetName();
+                        strm << ":\n";
+                    }
+
+                    if (num_mixed_context_lines && !sc_range.ContainsFileAddress (addr))
+                    {
+                        sc.GetAddressRange (eSymbolContextEverything, sc_range);
+                            
+                        if (sc != prev_sc)
                         {
-                            Module *module = addr_section->GetModule();
-                            uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
-                            if (resolved_mask)
-                            {
-                                if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
-                                {
-                                    if (prev_sc.function || prev_sc.symbol)
-                                        strm.EOL();
-
-                                    strm << sc.module_sp->GetFileSpec().GetFilename();
-                                    
-                                    if (sc.function)
-                                        strm << '`' << sc.function->GetMangled().GetName();
-                                    else if (sc.symbol)
-                                        strm << '`' << sc.symbol->GetMangled().GetName();
-                                    strm << ":\n";
-                                }
-
-                                if (num_mixed_context_lines && !sc_range.ContainsFileAddress (addr))
-                                {
-                                    sc.GetAddressRange (eSymbolContextEverything, sc_range);
-                                        
-                                    if (sc != prev_sc)
-                                    {
-                                        if (offset != 0)
-                                            strm.EOL();
-
-                                        sc.DumpStopContext(&strm, process, addr, false, true, false);
-                                        strm.EOL();
-
-                                        if (sc.comp_unit && sc.line_entry.IsValid())
-                                        {
-                                            debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
-                                                                                                           sc.line_entry.line,
-                                                                                                           num_mixed_context_lines,
-                                                                                                           num_mixed_context_lines,
-                                                                                                           num_mixed_context_lines ? "->" : "",
-                                                                                                           &strm);
-                                        }
-                                    }
-                                }
-                            }
-                            else
+                            if (offset != 0)
+                                strm.EOL();
+
+                            sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false);
+                            strm.EOL();
+
+                            if (sc.comp_unit && sc.line_entry.IsValid())
                             {
-                                sc.Clear();
+                                debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
+                                                                                               sc.line_entry.line,
+                                                                                               num_mixed_context_lines,
+                                                                                               num_mixed_context_lines,
+                                                                                               num_mixed_context_lines ? "->" : "",
+                                                                                               &strm);
                             }
                         }
-                        if (num_mixed_context_lines)
-                            strm.IndentMore ();
-                        strm.Indent();
-                        size_t inst_byte_size = inst->GetByteSize();
-                        inst->Dump(&strm, true, show_bytes ? &data : NULL, offset, &exe_ctx, raw);
-                        strm.EOL();
-                        offset += inst_byte_size;
-                        
-                        addr.SetOffset (addr.GetOffset() + inst_byte_size);
-
-                        if (num_mixed_context_lines)
-                            strm.IndentLess ();
-                    }
-                    else
-                    {
-                        break;
                     }
                 }
-                if (num_mixed_context_lines)
-                    strm.IndentLess ();
-
+                else
+                {
+                    sc.Clear();
+                }
             }
+            if (num_mixed_context_lines)
+                strm.IndentMore ();
+            strm.Indent();
+            size_t inst_byte_size = inst->GetByteSize();
+            inst->Dump(&strm, true, show_bytes ? &data : NULL, offset, &exe_ctx, raw);
+            strm.EOL();
+            offset += inst_byte_size;
+            
+            addr.SetOffset (addr.GetOffset() + inst_byte_size);
+
+            if (num_mixed_context_lines)
+                strm.IndentLess ();
+        }
+        else
+        {
+            break;
         }
-        return true;
     }
-    return false;
+    if (num_mixed_context_lines)
+        strm.IndentLess ();
+        
+    return true;
 }
 
 
@@ -336,6 +435,7 @@
     Debugger &debugger,
     const ArchSpec &arch,
     const ExecutionContext &exe_ctx,
+    uint32_t num_instructions,
     uint32_t num_mixed_context_lines,
     bool show_bytes,
     bool raw,
@@ -363,7 +463,7 @@
             range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
     }
 
-    return Disassemble(debugger, arch, exe_ctx, range, num_mixed_context_lines, show_bytes, raw, strm);
+    return Disassemble(debugger, arch, exe_ctx, range, num_instructions, num_mixed_context_lines, show_bytes, raw, strm);
 }
 
 Instruction::Instruction(const Address &addr) :
@@ -443,12 +543,78 @@
         data.SetData(data_sp);
         data.SetByteOrder(target->GetArchitecture().GetByteOrder());
         data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
-        return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX);
+        return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
     }
 
     return 0;
 }
 
+size_t
+Disassembler::ParseInstructions
+(
+    const ExecutionContext *exe_ctx,
+    const Address &start,
+    uint32_t num_instructions,
+    DataExtractor& data
+)
+{
+    Address addr = start;
+    
+    if (num_instructions == 0)
+        return 0;
+        
+    Target *target = exe_ctx->target;
+    // We'll guess at a size for the buffer, if we don't get all the instructions we want we can just re-fill & reuse it.
+    const addr_t byte_size = num_instructions * 2;
+    addr_t data_offset = 0;
+    addr_t next_instruction_offset = 0;
+    size_t buffer_size = byte_size;
+    
+    uint32_t num_instructions_found = 0;
+    
+    if (target == NULL || byte_size == 0 || !start.IsValid())
+        return 0;
+
+    DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
+    DataBufferSP data_sp(heap_buffer);
+    
+    data.SetData(data_sp);
+    data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+    data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+
+    Error error;
+    bool prefer_file_cache = true;
+    
+    m_instruction_list.Clear();
+    
+    while (num_instructions_found < num_instructions)
+    {
+        if (buffer_size < data_offset + byte_size)
+        {
+            buffer_size = data_offset + byte_size;
+            heap_buffer->SetByteSize (buffer_size);
+            data.SetData(data_sp);  // Resizing might have changed the backing store location, so we have to reset
+                                    // the DataBufferSP in the extractor so it changes to pointing at the right thing.
+        }
+        const size_t bytes_read = target->ReadMemory (addr, prefer_file_cache, heap_buffer->GetBytes() + data_offset, byte_size, error);
+        size_t num_bytes_read = 0;
+        if (bytes_read == 0)
+            break;
+            
+        num_bytes_read = DecodeInstructions (start, data, next_instruction_offset, num_instructions - num_instructions_found, true);
+        if (num_bytes_read == 0)
+            break;
+        num_instructions_found = m_instruction_list.GetSize();
+        
+        // Prepare for the next round.
+        data_offset += bytes_read;
+        addr.Slide (bytes_read);
+        next_instruction_offset += num_bytes_read;
+    }
+    
+    return m_instruction_list.GetSize();
+}
+
 //----------------------------------------------------------------------
 // Disassembler copy constructor
 //----------------------------------------------------------------------

Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Mon Mar 21 20:48:42 2011
@@ -739,7 +739,7 @@
                             DataExtractor::TypeUInt8);
     }
     
-    disassembler->DecodeInstructions (Address (NULL, func_remote_addr), extractor, 0, UINT32_MAX);
+    disassembler->DecodeInstructions (Address (NULL, func_remote_addr), extractor, 0, UINT32_MAX, false);
     
     InstructionList &instruction_list = disassembler->GetInstructionList();
     

Modified: lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp Mon Mar 21 20:48:42 2011
@@ -404,7 +404,8 @@
     const Address &base_addr,
     const DataExtractor& data,
     uint32_t data_offset,
-    uint32_t num_instructions
+    uint32_t num_instructions,
+    bool append
 )
 {
     if (m_disassembler == NULL)
@@ -412,7 +413,8 @@
 
     size_t total_inst_byte_size = 0;
 
-    m_instruction_list.Clear();
+    if (!append)
+        m_instruction_list.Clear();
 
     while (data.ValidOffset(data_offset) && num_instructions)
     {

Modified: lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h Mon Mar 21 20:48:42 2011
@@ -78,7 +78,8 @@
     DecodeInstructions (const lldb_private::Address &base_addr,
                         const lldb_private::DataExtractor& data,
                         uint32_t data_offset,
-                        uint32_t num_instructions);
+                        uint32_t num_instructions,
+                        bool append);
     
     //------------------------------------------------------------------
     // PluginInterface protocol

Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Mon Mar 21 20:48:42 2011
@@ -260,6 +260,7 @@
                                    target.GetArchitecture(),
                                    exe_ctx,
                                    0,
+                                   0,
                                    false,
                                    false,
                                    m_disassembly);

Modified: lldb/trunk/source/Target/ThreadPlanTracer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanTracer.cpp?rev=128063&r1=128062&r2=128063&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanTracer.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanTracer.cpp Mon Mar 21 20:48:42 2011
@@ -204,9 +204,9 @@
                                     m_process.GetAddressByteSize());
             
             if (addr_valid)
-                m_disassembler->DecodeInstructions (pc_addr, extractor, 0, 1);
+                m_disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false);
             else
-                m_disassembler->DecodeInstructions (Address (NULL, pc), extractor, 0, 1);
+                m_disassembler->DecodeInstructions (Address (NULL, pc), extractor, 0, 1, false);
             
             InstructionList &instruction_list = m_disassembler->GetInstructionList();
             





More information about the lldb-commits mailing list