[Lldb-commits] [lldb] r128907 - in /lldb/trunk: include/lldb/Core/EmulateInstruction.h source/Core/Disassembler.cpp source/Core/EmulateInstruction.cpp source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp source/Plugins/Instruction/ARM/EmulateInstructionARM.h source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp source/lldb.cpp

Caroline Tice ctice at apple.com
Tue Apr 5 11:46:00 PDT 2011


Author: ctice
Date: Tue Apr  5 13:46:00 2011
New Revision: 128907

URL: http://llvm.org/viewvc/llvm-project?rev=128907&view=rev
Log:

Add the rest of the mechanisms to make ARM instruction emulation usable/possible.


Modified:
    lldb/trunk/include/lldb/Core/EmulateInstruction.h
    lldb/trunk/source/Core/Disassembler.cpp
    lldb/trunk/source/Core/EmulateInstruction.cpp
    lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
    lldb/trunk/source/lldb.cpp

Modified: lldb/trunk/include/lldb/Core/EmulateInstruction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/EmulateInstruction.h?rev=128907&r1=128906&r2=128907&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/EmulateInstruction.h (original)
+++ lldb/trunk/include/lldb/Core/EmulateInstruction.h Tue Apr  5 13:46:00 2011
@@ -10,7 +10,10 @@
 #ifndef lldb_EmulateInstruction_h_
 #define lldb_EmulateInstruction_h_
 
+#include <string>
+
 #include "lldb/lldb-public.h"
+#include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Core/Opcode.h"
 
@@ -354,6 +357,9 @@
         
     };
 
+    static void
+    PrintContext (const char *context_type, const Context &context);
+    
     typedef size_t (*ReadMemory) (void *baton,
                                   const Context &context, 
                                   lldb::addr_t addr, 
@@ -379,11 +385,16 @@
 
     EmulateInstruction (lldb::ByteOrder byte_order,
                         uint32_t addr_byte_size,
+                        const ArchSpec &arch,
                         void *baton,
                         ReadMemory read_mem_callback,
                         WriteMemory write_mem_callback,
                         ReadRegister read_reg_callback,
                         WriteRegister write_reg_callback);
+                        
+    EmulateInstruction (lldb::ByteOrder byte_order,
+                        uint32_t addr_byte_size,
+                        const ArchSpec &arch);
 
     virtual ~EmulateInstruction()
     {
@@ -396,8 +407,14 @@
     ReadInstruction () = 0;
 
     virtual bool
+    SetInstruction (const Opcode &insn_opcode, const Address &inst_addr) = 0;
+
+    virtual bool
     EvaluateInstruction () = 0;
     
+    static void
+    TranslateRegister (uint32_t reg_kind, uint32_t reg_num, std::string &reg_name);
+    
     uint64_t
     ReadRegisterUnsigned (uint32_t reg_kind, 
                           uint32_t reg_num, 
@@ -441,9 +458,89 @@
         return m_opcode;
     }
 
+
+    static size_t 
+    ReadMemoryProcess (void *baton,
+                       const Context &context, 
+                       lldb::addr_t addr, 
+                       void *dst,
+                       size_t length);
+    
+    static size_t 
+    WriteMemoryProcess (void *baton,
+                        const Context &context, 
+                        lldb::addr_t addr, 
+                        const void *dst,
+                        size_t length);
+    
+    static bool   
+    ReadRegisterProcess  (void *baton,
+                          uint32_t reg_kind, 
+                          uint32_t reg_num,
+                          uint64_t &reg_value);
+    
+    
+    static bool   
+    WriteRegisterProcess (void *baton,
+                          const Context &context, 
+                          uint32_t reg_kind, 
+                          uint32_t reg_num,
+                          uint64_t reg_value);
+                          
+    static size_t 
+    ReadMemoryDefault (void *baton,
+                       const Context &context, 
+                       lldb::addr_t addr, 
+                       void *dst,
+                       size_t length);
+    
+    static size_t 
+    WriteMemoryDefault (void *baton,
+                        const Context &context, 
+                        lldb::addr_t addr, 
+                        const void *dst,
+                        size_t length);
+    
+    static bool   
+    ReadRegisterDefault  (void *baton,
+                          uint32_t reg_kind, 
+                          uint32_t reg_num,
+                          uint64_t &reg_value);
+    
+    
+    static bool   
+    WriteRegisterDefault (void *baton,
+                          const Context &context, 
+                          uint32_t reg_kind, 
+                          uint32_t reg_num,
+                          uint64_t reg_value);
+   
+    void
+    SetBaton (void *baton);
+    
+    void
+    SetCallbacks (ReadMemory read_mem_callback,
+                  WriteMemory write_mem_callback,
+                  ReadRegister read_reg_callback,
+                  WriteRegister write_reg_callback);
+                  
+    void
+    SetReadMemCallback (ReadMemory read_mem_callback);
+    
+    void
+    SetWriteMemCallback (WriteMemory write_mem_callback);
+    
+    void
+    SetReadRegCallback (ReadRegister read_reg_callback);
+    
+    void
+    SetWriteRegCallback (WriteRegister write_reg_callback);
+    
+
 protected:
     lldb::ByteOrder     m_byte_order;
     uint32_t            m_addr_byte_size;
+    ArchSpec            m_arch;
     void *              m_baton;
     ReadMemory          m_read_mem_callback;
     WriteMemory         m_write_mem_callback;

Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=128907&r1=128906&r2=128907&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Tue Apr  5 13:46:00 2011
@@ -18,6 +18,7 @@
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Core/EmulateInstruction.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Timer.h"

Modified: lldb/trunk/source/Core/EmulateInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/EmulateInstruction.cpp?rev=128907&r1=128906&r2=128907&view=diff
==============================================================================
--- lldb/trunk/source/Core/EmulateInstruction.cpp (original)
+++ lldb/trunk/source/Core/EmulateInstruction.cpp Tue Apr  5 13:46:00 2011
@@ -9,10 +9,18 @@
 
 #include "lldb/Core/EmulateInstruction.h"
 
+#include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Error.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Host/Endian.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+
+#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -25,18 +33,18 @@
         create_callback  = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
         if (create_callback)
         {
-            std::auto_ptr<EmulateInstruction> instance_ap(create_callback(arch));
-            if (instance_ap.get())
-                return instance_ap.release();
+           	EmulateInstruction *emulate_insn_ptr = create_callback(arch);
+            if (emulate_insn_ptr)
+                return emulate_insn_ptr;
         }
     }
     else
     {
         for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
         {
-            std::auto_ptr<EmulateInstruction> instance_ap(create_callback(arch));
-            if (instance_ap.get())
-                return instance_ap.release();
+            EmulateInstruction *emulate_insn_ptr = create_callback(arch);
+            if (emulate_insn_ptr)
+                return emulate_insn_ptr;
         }
     }
     return NULL;
@@ -46,6 +54,7 @@
 (
     lldb::ByteOrder byte_order,
     uint32_t addr_byte_size,
+    const ArchSpec &arch,
     void *baton,
     ReadMemory read_mem_callback,
     WriteMemory write_mem_callback,
@@ -53,7 +62,8 @@
     WriteRegister write_reg_callback
 ) :
     m_byte_order (endian::InlHostByteOrder()),
-    m_addr_byte_size (sizeof (void *)),
+    m_addr_byte_size (addr_byte_size),
+    m_arch (arch),
     m_baton (baton),
     m_read_mem_callback (read_mem_callback),
     m_write_mem_callback (write_mem_callback),
@@ -64,6 +74,25 @@
 {
 }
 
+EmulateInstruction::EmulateInstruction 
+(
+    lldb::ByteOrder byte_order,
+    uint32_t addr_byte_size,
+    const ArchSpec &arch
+) :
+    m_byte_order (endian::InlHostByteOrder()),
+    m_addr_byte_size (addr_byte_size),
+    m_arch (arch),
+    m_baton (NULL),
+    m_read_mem_callback (&ReadMemoryDefault),
+    m_write_mem_callback (&WriteMemoryDefault),
+    m_read_reg_callback (&ReadRegisterDefault),
+    m_write_reg_callback (&WriteRegisterDefault),
+    m_opcode_pc (LLDB_INVALID_ADDRESS)
+{
+    ::memset (&m_opcode, 0, sizeof (m_opcode));
+}
+
 uint64_t
 EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr)
 {
@@ -123,3 +152,489 @@
         return true;
     return false;
 }
+
+
+void
+EmulateInstruction::SetBaton (void *baton)
+{
+    m_baton = baton;
+}
+
+void
+EmulateInstruction::SetCallbacks (ReadMemory read_mem_callback,
+                                  WriteMemory write_mem_callback,
+                                  ReadRegister read_reg_callback,
+                                  WriteRegister write_reg_callback)
+{
+    m_read_mem_callback = read_mem_callback;
+    m_write_mem_callback = write_mem_callback;
+    m_read_reg_callback = read_reg_callback;
+    m_write_reg_callback = write_reg_callback;
+}
+
+void
+EmulateInstruction::SetReadMemCallback (ReadMemory read_mem_callback)
+{
+    m_read_mem_callback = read_mem_callback;
+}
+
+                                  
+void
+EmulateInstruction::SetWriteMemCallback (WriteMemory write_mem_callback)
+{
+    m_write_mem_callback = write_mem_callback;
+}
+
+                                  
+void
+EmulateInstruction::SetReadRegCallback (ReadRegister read_reg_callback)
+{
+    m_read_reg_callback = read_reg_callback;
+}
+
+                                  
+void
+EmulateInstruction::SetWriteRegCallback (WriteRegister write_reg_callback)
+{
+    m_write_reg_callback = write_reg_callback;
+}
+
+                                  
+                            
+//
+//  Read & Write Memory and Registers callback functions.
+//
+
+size_t 
+EmulateInstruction::ReadMemoryProcess (void *baton,
+                                       const Context &context, 
+                                       lldb::addr_t addr, 
+                                       void *dst,
+                                       size_t length)
+{
+    Process *process = (Process *) baton;
+    
+    if (!process)
+        return 0;
+    
+    DataBufferSP data_sp (new DataBufferHeap (length, '\0'));
+    Error error;
+    
+    size_t bytes_read = process->ReadMemory (addr, data_sp->GetBytes(), data_sp->GetByteSize(), error);
+    
+    if (bytes_read > 0)
+        ((DataBufferHeap *) data_sp.get())->CopyData (dst, length);
+        
+    return bytes_read;
+}
+
+size_t 
+EmulateInstruction::WriteMemoryProcess (void *baton,
+                                        const Context &context, 
+                                        lldb::addr_t addr, 
+                                        const void *dst,
+                                        size_t length)
+{
+    Process *process = (Process *) baton;
+    
+    if (!process)
+        return 0;
+    
+    lldb::DataBufferSP data_sp (new DataBufferHeap (dst, length));
+    if (data_sp)
+    {
+        length = data_sp->GetByteSize();
+        if (length > 0)
+        {
+            Error error;
+            size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error);
+            
+            return bytes_written;
+        }
+    }
+    
+    return 0;
+}
+
+bool   
+EmulateInstruction::ReadRegisterProcess  (void *baton,
+                                          uint32_t reg_kind, 
+                                          uint32_t reg_num,
+                                          uint64_t &reg_value)
+{
+    Process *process = (Process *) baton;
+    if (!process)
+        return false;
+        
+    Thread *thread = process->CalculateThread ();
+    RegisterContext *reg_context = thread->GetRegisterContext().get();
+    Scalar value;
+    
+    
+    if (reg_context->ReadRegisterValue (reg_num, value))
+    {
+        reg_value = value.GetRawBits64 (0);
+        return true;
+    }
+    
+    return false;
+}
+
+bool   
+EmulateInstruction::WriteRegisterProcess (void *baton,
+                                          const Context &context, 
+                                          uint32_t reg_kind, 
+                                          uint32_t reg_num,
+                                          uint64_t reg_value)
+{
+    Process *process = (Process *) baton;
+    Thread *thread = process->CalculateThread ();
+    RegisterContext *reg_context = thread->GetRegisterContext().get();
+    Scalar value (reg_value);
+    
+    return reg_context->WriteRegisterValue (reg_num, value);
+}
+
+size_t 
+EmulateInstruction::ReadMemoryDefault (void *baton,
+                                       const Context &context, 
+                                       lldb::addr_t addr, 
+                                       void *dst,
+                                       size_t length)
+{
+    PrintContext ("Read from memory", context);
+    fprintf (stdout, "    Read from Memory (address = %p, length = %d)\n",(void *) addr, (uint) length);
+    
+    *((uint64_t *) dst) = 0xdeadbeef;
+    return length;
+}
+
+size_t 
+EmulateInstruction::WriteMemoryDefault (void *baton,
+                                        const Context &context, 
+                                        lldb::addr_t addr, 
+                                        const void *dst,
+                                        size_t length)
+{
+    PrintContext ("Write to memory", context);
+    fprintf (stdout, "    Write to Memory (address = %p, length = %d)\n",  (void *) addr, (uint) length);
+    return length;
+}
+
+bool   
+EmulateInstruction::ReadRegisterDefault  (void *baton,
+                                          uint32_t reg_kind, 
+                                          uint32_t reg_num,
+                                          uint64_t &reg_value)
+{
+    std::string reg_name;
+    TranslateRegister (reg_kind, reg_num, reg_name);
+    fprintf (stdout, "  Read Register (%s)\n", reg_name.c_str());
+    
+    reg_value = 24;
+    return true;
+}
+
+bool   
+EmulateInstruction::WriteRegisterDefault (void *baton,
+                                          const Context &context, 
+                                          uint32_t reg_kind, 
+                                          uint32_t reg_num,
+                                          uint64_t reg_value)
+{
+    PrintContext ("Write to register", context);
+    std::string reg_name;
+    TranslateRegister (reg_kind, reg_num, reg_name);
+    fprintf (stdout, "    Write to Register (%s),  value = 0x%llx\n", reg_name.c_str(), reg_value);
+    return true;
+}
+
+void
+EmulateInstruction::PrintContext (const char *context_type, const Context &context)
+{
+    switch (context.type)
+    {
+        case eContextReadOpcode:
+            fprintf (stdout, "  %s context: Reading an Opcode\n", context_type);
+            break;
+            
+        case eContextImmediate:
+            fprintf (stdout, "  %s context:  Immediate\n", context_type);
+            break;
+            
+        case eContextPushRegisterOnStack:
+            fprintf (stdout, "  %s context:  Pushing a register onto the stack.\n", context_type);
+            break;
+            
+        case eContextPopRegisterOffStack:
+            fprintf (stdout, "  %s context: Popping a register off the stack.\n", context_type);
+            break;
+            
+        case eContextAdjustStackPointer:
+            fprintf (stdout, "  %s context:  Adjusting the stack pointer.\n", context_type);
+            break;
+            
+        case eContextAdjustBaseRegister:
+            fprintf (stdout, "  %s context:  Adjusting (writing value back to) a base register.\n", context_type);
+            break;
+            
+        case eContextRegisterPlusOffset:
+            fprintf (stdout, "  %s context: Register plus offset\n", context_type);
+            break;
+            
+        case eContextRegisterStore:
+            fprintf (stdout, "  %s context:  Storing a register.\n", context_type);
+            break;
+            
+        case eContextRegisterLoad:
+            fprintf (stdout, "  %s context:  Loading a register.\n", context_type);
+            break;
+            
+        case eContextRelativeBranchImmediate:
+            fprintf (stdout, "  %s context: Relative branch immediate\n", context_type);
+            break;
+            
+        case eContextAbsoluteBranchRegister:
+            fprintf (stdout, "  %s context:  Absolute branch register\n", context_type);
+            break;
+            
+        case eContextSupervisorCall:
+            fprintf (stdout, "  %s context:  Performing a supervisor call.\n", context_type);
+            break;
+            
+        case eContextTableBranchReadMemory:
+            fprintf (stdout, "  %s context:  Table branch read memory\n", context_type);
+            break;
+            
+        case eContextWriteRegisterRandomBits:
+            fprintf (stdout, "  %s context:  Write random bits to a register\n", context_type);
+            break;
+            
+        case eContextWriteMemoryRandomBits:
+            fprintf (stdout, "  %s context:  Write random bits to a memory address\n", context_type);
+            break;
+            
+        case eContextMultiplication:
+            fprintf (stdout, "  %s context:  Performing a multiplication\n", context_type);
+            break;
+            
+        case eContextAddition:
+            fprintf (stdout, "  %s context:  Performing an addition\n", context_type);
+            break;
+            
+        case eContextReturnFromException:
+            fprintf (stdout, "  %s context:  Returning from an exception\n", context_type);
+            break;
+            
+        default:
+            fprintf (stdout, "  %s context:  Unrecognized context.\n", context_type);
+            break;
+    }
+    
+    switch (context.info_type)
+    {
+        case eInfoTypeRegisterPlusOffset:
+        {
+            std::string reg_name;
+            TranslateRegister (context.info.RegisterPlusOffset.reg.kind, 
+                               context.info.RegisterPlusOffset.reg.num,
+                               reg_name);
+            fprintf (stdout, "    Info type:  Register plus offset (%s  +/- %lld)\n", reg_name.c_str(),
+                    context.info.RegisterPlusOffset.signed_offset);
+        }
+            break;
+        case eInfoTypeRegisterPlusIndirectOffset:
+        {
+            std::string base_reg_name;
+            std::string offset_reg_name;
+            TranslateRegister (context.info.RegisterPlusIndirectOffset.base_reg.kind, 
+                                context.info.RegisterPlusIndirectOffset.base_reg.num,
+                                base_reg_name);
+            TranslateRegister (context.info.RegisterPlusIndirectOffset.offset_reg.kind, 
+                                context.info.RegisterPlusIndirectOffset.offset_reg.num,
+                                offset_reg_name);
+            fprintf (stdout, "    Info type:  Register plus indirect offset (%s  +/- %s)\n", 
+                     base_reg_name.c_str(),
+                     offset_reg_name.c_str());
+        }
+            break;
+        case eInfoTypeRegisterToRegisterPlusOffset:
+        {
+            std::string base_reg_name;
+            std::string data_reg_name;
+            TranslateRegister (context.info.RegisterToRegisterPlusOffset.base_reg.kind, 
+                                context.info.RegisterToRegisterPlusOffset.base_reg.num,
+                                base_reg_name);
+            TranslateRegister (context.info.RegisterToRegisterPlusOffset.data_reg.kind, 
+                                context.info.RegisterToRegisterPlusOffset.data_reg.num,
+                                data_reg_name);
+            fprintf (stdout, "    Info type:  Register plus offset (%s  +/- %lld) and data register (%s)\n", 
+                     base_reg_name.c_str(), context.info.RegisterToRegisterPlusOffset.offset,
+                     data_reg_name.c_str());
+        }
+            break;
+        case eInfoTypeRegisterToRegisterPlusIndirectOffset:
+        {
+            std::string base_reg_name;
+            std::string offset_reg_name;
+            std::string data_reg_name;
+            TranslateRegister (context.info.RegisterToRegisterPlusIndirectOffset.base_reg.kind, 
+                                context.info.RegisterToRegisterPlusIndirectOffset.base_reg.num,
+                                base_reg_name);
+            TranslateRegister (context.info.RegisterToRegisterPlusIndirectOffset.offset_reg.kind, 
+                                context.info.RegisterToRegisterPlusIndirectOffset.offset_reg.num,
+                                offset_reg_name);
+            TranslateRegister (context.info.RegisterToRegisterPlusIndirectOffset.data_reg.kind, 
+                                context.info.RegisterToRegisterPlusIndirectOffset.data_reg.num,
+                                data_reg_name);
+            fprintf (stdout, "    Info type:  Register plus indirect offset (%s +/- %s) and data register (%s)\n",
+                     base_reg_name.c_str(), offset_reg_name.c_str(), data_reg_name.c_str());
+        }
+            break;
+        
+        case eInfoTypeRegisterRegisterOperands:
+        {
+            std::string op1_reg_name;
+            std::string op2_reg_name;
+            TranslateRegister (context.info.RegisterRegisterOperands.operand1.kind, 
+                                context.info.RegisterRegisterOperands.operand1.num,
+                                op1_reg_name);
+            TranslateRegister (context.info.RegisterRegisterOperands.operand2.kind, 
+                                context.info.RegisterRegisterOperands.operand2.num,
+                                op2_reg_name);
+            fprintf (stdout, "    Info type:  Register operands for binary op (%s, %s)\n", 
+                     op1_reg_name.c_str(),
+                     op2_reg_name.c_str());
+        }
+            break;
+        case eInfoTypeOffset:
+            fprintf (stdout, "    Info type: signed offset (%lld)\n", context.info.signed_offset);
+            break;
+            
+        case eInfoTypeRegister:
+        {
+            std::string reg_name;
+            TranslateRegister (context.info.reg.kind, context.info.reg.num, reg_name);
+            fprintf (stdout, "    Info type:  Register (%s)\n", reg_name.c_str());
+        }
+            break;
+            
+        case eInfoTypeImmediate:
+            fprintf (stdout, "    Info type:  Immediate (%lld)\n", context.info.immediate);
+            break;
+
+        case eInfoTypeImmediateSigned:
+            fprintf (stdout, "    Info type:  Signed immediate (%lld)\n", context.info.signed_immediate);
+            break;
+            
+        case eInfoTypeAddress:
+            fprintf (stdout, "    Info type:  Address (%p)\n", (void *) context.info.address);
+            break;
+            
+        case eInfoTypeModeAndImmediate:
+        {
+            std::string mode_name;
+            
+            if (context.info.ModeAndImmediate.mode == EmulateInstructionARM::eModeARM)
+                mode_name = "ARM";
+            else if (context.info.ModeAndImmediate.mode == EmulateInstructionARM::eModeThumb)
+                mode_name = "Thumb";
+            else
+                mode_name = "Unknown mode";
+
+            fprintf (stdout, "    Info type:  Mode (%s) and immediate (%d)\n", mode_name.c_str(),
+                     context.info.ModeAndImmediate.data_value);
+        }
+            break;
+            
+        case eInfoTypeModeAndImmediateSigned:
+        {
+            std::string mode_name;
+            
+            if (context.info.ModeAndImmediateSigned.mode == EmulateInstructionARM::eModeARM)
+                mode_name = "ARM";
+            else if (context.info.ModeAndImmediateSigned.mode == EmulateInstructionARM::eModeThumb)
+                mode_name = "Thumb";
+            else
+                mode_name = "Unknown mode";
+
+            fprintf (stdout, "    Info type:  Mode (%s) and signed immediate (%d)\n", mode_name.c_str(),
+                     context.info.ModeAndImmediateSigned.signed_data_value);
+        }
+            break;
+            
+        case eInfoTypeMode:
+        {
+            std::string mode_name;
+            
+            if (context.info.mode == EmulateInstructionARM::eModeARM)
+                mode_name = "ARM";
+            else if (context.info.mode == EmulateInstructionARM::eModeThumb)
+                mode_name = "Thumb";
+            else
+                mode_name = "Unknown mode";
+
+            fprintf (stdout, "    Info type:  Mode (%s)\n", mode_name.c_str());
+        }
+            break;
+            
+        case eInfoTypeNoArgs:
+            fprintf (stdout, "    Info type:  no arguments\n");
+            break;
+
+        default:
+            break;
+    }
+}
+
+void
+EmulateInstruction::TranslateRegister (uint32_t kind, uint32_t num, std::string &name)
+{
+    if (kind == eRegisterKindDWARF)
+    {
+        if (num == 13) //dwarf_sp  NOTE:  This is ARM-SPECIFIC
+            name = "sp";
+        else if (num == 14) //dwarf_lr  NOTE:  This is ARM-SPECIFIC
+            name = "lr";
+        else if (num == 15) //dwarf_pc  NOTE:  This is ARM-SPECIFIC
+            name = "pc";
+        else if (num == 16) //dwarf_cpsr  NOTE:  This is ARM-SPECIFIC
+            name = "cpsr";
+        else
+        {
+            StreamString sstr;
+            
+            sstr.Printf ("r%d", num);
+            name = sstr.GetData();
+        }
+            
+    }
+    else if (kind == eRegisterKindGeneric)
+    {
+        if (num == LLDB_REGNUM_GENERIC_SP)
+            name = "sp";
+        else if (num == LLDB_REGNUM_GENERIC_FLAGS)
+            name = "cpsr";
+        else if (num == LLDB_REGNUM_GENERIC_PC)
+            name = "pc";
+        else if (num == LLDB_REGNUM_GENERIC_RA)
+            name = "lr";
+        else
+        {
+            StreamString sstr;
+            
+            sstr.Printf ("r%d", num);
+            name = sstr.GetData();
+        }
+    }
+    else
+    {
+        StreamString sstr;
+            
+        sstr.Printf ("r%d", num);
+        name = sstr.GetData();
+    }
+}
+
+
+

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=128907&r1=128906&r2=128907&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp Tue Apr  5 13:46:00 2011
@@ -404,7 +404,7 @@
 {
     std::auto_ptr<DisassemblerLLVM> disasm_ap (new DisassemblerLLVM(arch));
  
-    if (disasm_ap->IsValid())
+    if (disasm_ap.get() && disasm_ap->IsValid())
         return disasm_ap.release();
 
     return NULL;

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=128907&r1=128906&r2=128907&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Tue Apr  5 13:46:00 2011
@@ -11,7 +11,9 @@
 
 #include "EmulateInstructionARM.h"
 #include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Address.h"
 #include "lldb/Core/ConstString.h"
+#include "lldb/Core/PluginManager.h"
 
 #include "Plugins/Process/Utility/ARMDefines.h"
 #include "Plugins/Process/Utility/ARMUtils.h"
@@ -153,13 +155,61 @@
 void
 EmulateInstructionARM::Initialize ()
 {
+    PluginManager::RegisterPlugin (GetPluginNameStatic (),
+                                   GetPluginDescriptionStatic (),
+                                   CreateInstance);
 }
 
 void
 EmulateInstructionARM::Terminate ()
 {
+    PluginManager::UnregisterPlugin (CreateInstance);
 }
 
+const char *
+EmulateInstructionARM::GetPluginNameStatic ()
+{
+    return "lldb.emulate-instruction.arm";
+}
+
+const char *
+EmulateInstructionARM::GetPluginDescriptionStatic ()
+{
+    return "Emulate instructions for the ARM architecture.";
+}
+
+EmulateInstruction *
+EmulateInstructionARM::CreateInstance (const ArchSpec &arch)
+{
+    if (arch.GetTriple().getArch() == llvm::Triple::arm)
+    {
+        std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
+        
+        if (emulate_insn_ap.get())
+            return emulate_insn_ap.release();
+    }
+    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
+    {
+        std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
+        
+        if (emulate_insn_ap.get())
+            return emulate_insn_ap.release();
+    }
+    
+    return NULL;
+}
+
+bool
+EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
+{
+    if (arch.GetTriple().getArch () == llvm::Triple::arm)
+        return true;
+    else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
+        return true;
+       
+    return false;
+}
+    
 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
 bool
 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
@@ -503,7 +553,7 @@
         addr_t addr = sp + sp_offset; // a pointer to the stack area
         
         EmulateInstruction::Context context;
-        context.type = EmulateInstruction::eContextRegisterPlusOffset;
+        context.type = EmulateInstruction::eContextAdjustStackPointer;
         Register sp_reg;
         sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
         context.SetRegisterPlusOffset (sp_reg, sp_offset);
@@ -1191,7 +1241,9 @@
         
         EmulateInstruction::Context context;
         context.type = EmulateInstruction::eContextAdjustStackPointer;
-        context.SetImmediateSigned (sp_offset);
+        Register sp_reg;
+        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
+        context.SetRegisterPlusOffset (sp_reg, sp_offset);
     
         if (d == 15)
         {
@@ -1253,8 +1305,12 @@
         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
         
         EmulateInstruction::Context context;
-        context.type = EmulateInstruction::eContextAdjustStackPointer;
-        context.SetImmediateSigned (reg_value);
+        context.type = EmulateInstruction::eContextAddition;
+        Register sp_reg;
+        sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
+        Register other_reg;
+        other_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
+        context.SetRegisterRegisterOperands (sp_reg, other_reg);
     
         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
             return false;
@@ -2431,8 +2487,10 @@
         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
 
         EmulateInstruction::Context context;
-        context.type = EmulateInstruction::eContextImmediate;
-        context.SetNoArgs ();
+        context.type = EmulateInstruction::eContextAddition;
+        Register dwarf_reg;
+        dwarf_reg.SetRegister (eRegisterKindDWARF, Rn);
+        context.SetRegisterPlusOffset (dwarf_reg, imm32);
 
         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
             return false;
@@ -12247,7 +12305,16 @@
         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
         // mul
         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
+                   
+
+        //----------------------------------------------------------------------
+        // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 
+        // otherwise the wrong instructions will be selected.
+        //----------------------------------------------------------------------
  
+        { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
+        { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
+
         //----------------------------------------------------------------------
         // Load instructions
         //----------------------------------------------------------------------
@@ -12330,9 +12397,6 @@
         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
-        { 0xffd00000, 0xe8100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
-        { 0xffd00000, 0xe9900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }
-                  
     };
 
     const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
@@ -12347,6 +12411,7 @@
 bool
 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
 {
+    m_arch = arch;
     m_arm_isa = 0;
     const char *arch_cstr = arch.GetArchitectureName ();
     if (arch_cstr)
@@ -12365,6 +12430,26 @@
     return m_arm_isa != 0;
 }
 
+bool
+EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr)
+{
+    m_opcode = insn_opcode;
+
+    if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
+        m_opcode_mode = eModeThumb;
+	else
+	{
+		AddressClass addr_class = inst_addr.GetAddressClass();
+
+    	if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
+        	m_opcode_mode = eModeARM;
+    	else if (addr_class == eAddressClassCodeAlternateISA)
+        	m_opcode_mode = eModeThumb;
+    	else
+        	return false;
+	}    
+    return true;
+}
 
 bool 
 EmulateInstructionARM::ReadInstruction ()
@@ -12421,8 +12506,6 @@
 bool
 EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
 {
-    if (m_opcode_cpsr == 0)
-        return false;
 
     const uint32_t cond = CurrentCond (opcode);
     
@@ -12432,20 +12515,46 @@
     bool result = false;
     switch (UnsignedBits(cond, 3, 1))
     {
-    case 0: result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; break;
-    case 1: result = (m_opcode_cpsr & MASK_CPSR_C) != 0; break;
-    case 2: result = (m_opcode_cpsr & MASK_CPSR_N) != 0; break;
-    case 3: result = (m_opcode_cpsr & MASK_CPSR_V) != 0; break;
-    case 4: result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); break;
+    case 0: 
+		if (m_opcode_cpsr == 0)
+			return true;
+		result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 
+		break;
+    case 1:
+ 		if (m_opcode_cpsr == 0)
+			return true;
+		result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 
+		break;
+    case 2:
+ 		if (m_opcode_cpsr == 0)
+			return true;
+		result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 
+		break;
+    case 3:
+ 		if (m_opcode_cpsr == 0)
+			return true;
+		result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 
+		break;
+    case 4:
+ 		if (m_opcode_cpsr == 0)
+			return true;
+		result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 
+		break;
     case 5: 
-        {
+  		if (m_opcode_cpsr == 0)
+			return true;
+       	else
+		{
             bool n = (m_opcode_cpsr & MASK_CPSR_N);
             bool v = (m_opcode_cpsr & MASK_CPSR_V);
             result = n == v;
         }
         break;
     case 6: 
-        {
+  		if (m_opcode_cpsr == 0)
+			return true;
+       	else
+		{
             bool n = (m_opcode_cpsr & MASK_CPSR_N);
             bool v = (m_opcode_cpsr & MASK_CPSR_V);
             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
@@ -12875,5 +12984,79 @@
     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
         m_it_session.ITAdvance();
 
-    return false;
+        
+    ARMOpcode *opcode_data;
+   
+    if (m_opcode_mode == eModeThumb)
+        opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32());
+    else if (m_opcode_mode == eModeARM)
+        opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32());
+    else    
+        return false;
+        
+    if (!opcode_data)
+        return false;
+    // Verify that we're the right arch for this opcode
+    
+    switch (m_arm_isa)
+    {
+    case ARMv4:
+        if (opcode_data->variants != ARMvAll)
+            return false;
+        break;
+        
+    case ARMv4T:
+        if ((opcode_data->variants!= ARMvAll) 
+            && (opcode_data->variants != ARMV4T_ABOVE))
+            return false;
+        break;
+                  
+    case ARMv5T:
+    case ARMv5TE:
+        if ((opcode_data->variants != ARMvAll) 
+            && (opcode_data->variants != ARMV4T_ABOVE)
+            && (opcode_data->variants != ARMV5_ABOVE))
+            return false;
+        break;
+                  
+    case ARMv5TEJ:
+        if ((opcode_data->variants != ARMvAll) 
+            && (opcode_data->variants != ARMV4T_ABOVE)
+            && (opcode_data->variants != ARMV5_ABOVE)
+            && (opcode_data->variants != ARMV5J_ABOVE))
+            return false;
+        break;
+        
+    case ARMv6:
+    case ARMv6K:
+        if ((opcode_data->variants != ARMvAll) 
+            && (opcode_data->variants != ARMV4T_ABOVE)
+            && (opcode_data->variants != ARMV5_ABOVE)
+            && (opcode_data->variants != ARMV5J_ABOVE)
+            && (opcode_data->variants != ARMV6_ABOVE))
+            return false;
+        break;
+        
+    case ARMv6T2:
+    case ARMv7:
+    case ARMv8:
+        if ((opcode_data->variants != ARMvAll) 
+            && (opcode_data->variants != ARMV4T_ABOVE)
+            && (opcode_data->variants != ARMV5_ABOVE)
+            && (opcode_data->variants != ARMV5J_ABOVE)
+            && (opcode_data->variants != ARMV6_ABOVE)
+            && (opcode_data->variants != ARMV6T2_ABOVE))
+            return false;
+        break;
+        
+    default:
+//            if (opcode_data->variants != ARMvAll)
+//                return false;
+        break;
+    }
+    
+    // Just for now, for testing purposes.
+    //fprintf (stdout, "\nEvaluateInstruction, opcode (0x%x), found = '%s'\n", m_opcode.GetOpcode32(), opcode_data->name);
+    
+    return (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);  // Call the Emulate... function.
 }

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h?rev=128907&r1=128906&r2=128907&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h Tue Apr  5 13:46:00 2011
@@ -67,6 +67,15 @@
     static void
     Terminate ();
 
+    static const char *
+    GetPluginNameStatic ();
+    
+    static const char *
+    GetPluginDescriptionStatic ();
+    
+    static lldb_private::EmulateInstruction *
+    CreateInstance (const lldb_private::ArchSpec &arch);
+    
     virtual const char *
     GetPluginName()
     {
@@ -76,7 +85,7 @@
     virtual const char *
     GetShortPluginName()
     {
-        return "lldb.emulate-instruction.arm";
+        return GetPluginNameStatic();
     }
 
     virtual uint32_t
@@ -85,20 +94,36 @@
         return 1;
     }
 
+    bool
+    SetTargetTriple (const ArchSpec &arch);
+    
     enum Mode
     {
         eModeInvalid,
         eModeARM,
         eModeThumb
     };
+    
+    EmulateInstructionARM (const ArchSpec &arch) :
+        EmulateInstruction (lldb::eByteOrderLittle,
+                            4,
+                            arch),
+        m_arm_isa (0),
+        m_opcode_mode (eModeInvalid),
+        m_opcode_cpsr (0),
+        m_it_session ()
+    {
+    }
 
-    EmulateInstructionARM (void *baton,
+    EmulateInstructionARM (const ArchSpec &arch,
+                           void *baton,
                            ReadMemory read_mem_callback,
                            WriteMemory write_mem_callback,
                            ReadRegister read_reg_callback,
                            WriteRegister write_reg_callback) :
         EmulateInstruction (lldb::eByteOrderLittle, // Byte order for ARM
                             4,                      // Address size in byte
+                            arch,
                             baton,
                             read_mem_callback,
                             write_mem_callback,
@@ -117,6 +142,9 @@
 
     virtual bool 
     ReadInstruction ();
+    
+    virtual bool
+    SetInstruction (const Opcode &insn_opcode, const Address &inst_addr);
 
     virtual bool
     EvaluateInstruction ();

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp?rev=128907&r1=128906&r2=128907&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp Tue Apr  5 13:46:00 2011
@@ -70,6 +70,8 @@
                                 break;
                             }
                         }
+                        parent_arg_die = parent_arg_die->GetParent();
+                        parend_pos_die = parend_pos_die->GetParent();
                     }
 
                     if (match)

Modified: lldb/trunk/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=128907&r1=128906&r2=128907&view=diff
==============================================================================
--- lldb/trunk/source/lldb.cpp (original)
+++ lldb/trunk/source/lldb.cpp Tue Apr  5 13:46:00 2011
@@ -23,6 +23,7 @@
 #include "llvm/ADT/StringRef.h"
 
 #include "Plugins/Disassembler/llvm/DisassemblerLLVM.h"
+#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
 #include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
 #include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
@@ -85,6 +86,7 @@
         ArchDefaultUnwindPlan_x86_64::Initialize();
         ArchDefaultUnwindPlan_i386::Initialize();
         ArchVolatileRegs_x86::Initialize();
+        EmulateInstructionARM::Initialize ();
 
 #if defined (__APPLE__)
         //----------------------------------------------------------------------
@@ -152,6 +154,7 @@
     ArchDefaultUnwindPlan_i386::Terminate();
     ArchDefaultUnwindPlan_x86_64::Terminate();
     ArchVolatileRegs_x86::Terminate();
+    EmulateInstructionARM::Terminate ();
 
 #if defined (__APPLE__)
     DynamicLoaderMacOSXDYLD::Terminate();





More information about the lldb-commits mailing list