[Lldb-commits] [lldb] r232619 - Initial Assembly profiler for mips64

Bhushan D. Attarde Bhushan.Attarde at imgtec.com
Wed Mar 18 02:21:30 PDT 2015


Author: bhushan.attarde
Date: Wed Mar 18 04:21:29 2015
New Revision: 232619

URL: http://llvm.org/viewvc/llvm-project?rev=232619&view=rev
Log:
Initial Assembly profiler for mips64

Summary:
This is initial implementation of assembly profiler which only scans prologue/epilogue assembly instructions to create CFI instructions.

Reviewers: clayborg, jasonmolenda

Differential Revision: http://reviews.llvm.org/D7696

Added:
    lldb/trunk/source/Plugins/Instruction/MIPS64/
    lldb/trunk/source/Plugins/Instruction/MIPS64/CMakeLists.txt
    lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
    lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
    lldb/trunk/source/Plugins/Instruction/MIPS64/Makefile
Modified:
    lldb/trunk/cmake/LLDBDependencies.cmake
    lldb/trunk/lib/Makefile
    lldb/trunk/source/Plugins/Instruction/CMakeLists.txt
    lldb/trunk/source/Plugins/Makefile
    lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
    lldb/trunk/source/lldb.cpp

Modified: lldb/trunk/cmake/LLDBDependencies.cmake
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/cmake/LLDBDependencies.cmake?rev=232619&r1=232618&r2=232619&view=diff
==============================================================================
--- lldb/trunk/cmake/LLDBDependencies.cmake (original)
+++ lldb/trunk/cmake/LLDBDependencies.cmake Wed Mar 18 04:21:29 2015
@@ -49,6 +49,7 @@ set( LLDB_USED_LIBS
   lldbPluginABISysV_ppc64
   lldbPluginInstructionARM
   lldbPluginInstructionARM64
+  lldbPluginInstructionMIPS64
   lldbPluginObjectFilePECOFF
   lldbPluginOSPython
   lldbPluginMemoryHistoryASan

Modified: lldb/trunk/lib/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lib/Makefile?rev=232619&r1=232618&r2=232619&view=diff
==============================================================================
--- lldb/trunk/lib/Makefile (original)
+++ lldb/trunk/lib/Makefile Wed Mar 18 04:21:29 2015
@@ -45,6 +45,7 @@ USEDLIBS = lldbAPI.a \
 	lldbPluginDynamicLoaderMacOSX.a \
 	lldbPluginEmulateInstructionARM.a \
 	lldbPluginEmulateInstructionARM64.a \
+        lldbPluginEmulateInstructionMIPS64.a \
 	lldbPluginInstrumentationRuntimeAddressSanitizer.a \
 	lldbPluginLanguageRuntimeCPlusPlusItaniumABI.a \
 	lldbPluginLanguageRuntimeObjCAppleObjCRuntime.a \

Modified: lldb/trunk/source/Plugins/Instruction/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/CMakeLists.txt?rev=232619&r1=232618&r2=232619&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Instruction/CMakeLists.txt Wed Mar 18 04:21:29 2015
@@ -1,2 +1,3 @@
 add_subdirectory(ARM)
 add_subdirectory(ARM64)
+add_subdirectory(MIPS64)

Added: lldb/trunk/source/Plugins/Instruction/MIPS64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/MIPS64/CMakeLists.txt?rev=232619&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS64/CMakeLists.txt (added)
+++ lldb/trunk/source/Plugins/Instruction/MIPS64/CMakeLists.txt Wed Mar 18 04:21:29 2015
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginInstructionMIPS64
+  EmulateInstructionMIPS64.cpp
+  )

Added: lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp?rev=232619&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp (added)
+++ lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp Wed Mar 18 04:21:29 2015
@@ -0,0 +1,444 @@
+//===-- EmulateInstructionMIPS64.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EmulateInstructionMIPS64.h"
+
+#include <stdlib.h>
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Symbol/UnwindPlan.h"
+
+#include "llvm/ADT/STLExtras.h"
+//#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
+
+#include "Plugins/Process/Utility/InstructionUtils.h"
+#include "Plugins/Process/Utility/RegisterContext_mips64.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+#define UInt(x) ((uint64_t)x)
+#define integer int64_t
+
+
+//----------------------------------------------------------------------
+//
+// EmulateInstructionMIPS64 implementation
+//
+//----------------------------------------------------------------------
+
+void
+EmulateInstructionMIPS64::Initialize ()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic (),
+                                   GetPluginDescriptionStatic (),
+                                   CreateInstance);
+}
+
+void
+EmulateInstructionMIPS64::Terminate ()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+ConstString
+EmulateInstructionMIPS64::GetPluginNameStatic ()
+{
+    ConstString g_plugin_name ("lldb.emulate-instruction.mips64");
+    return g_plugin_name;
+}
+
+lldb_private::ConstString
+EmulateInstructionMIPS64::GetPluginName()
+{
+    static ConstString g_plugin_name ("EmulateInstructionMIPS64");
+    return g_plugin_name;
+}
+
+const char *
+EmulateInstructionMIPS64::GetPluginDescriptionStatic ()
+{
+    return "Emulate instructions for the MIPS64 architecture.";
+}
+
+EmulateInstruction *
+EmulateInstructionMIPS64::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
+{
+    if (EmulateInstructionMIPS64::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
+    {
+        if (arch.GetTriple().getArch() == llvm::Triple::mips64)
+        {
+            std::auto_ptr<EmulateInstructionMIPS64> emulate_insn_ap (new EmulateInstructionMIPS64 (arch));
+            if (emulate_insn_ap.get())
+                return emulate_insn_ap.release();
+        }
+    }
+    
+    return NULL;
+}
+
+bool
+EmulateInstructionMIPS64::SetTargetTriple (const ArchSpec &arch)
+{
+    if (arch.GetTriple().getArch () == llvm::Triple::mips64)
+        return true;
+    return false;
+}
+
+const char *
+EmulateInstructionMIPS64::GetRegisterName (unsigned reg_num, bool alternate_name)
+{
+    if (alternate_name)
+    {
+        switch (reg_num)
+        {
+            case gcc_dwarf_sp_mips64: return "r29"; 
+            case gcc_dwarf_r30_mips64: return "r30"; 
+            case gcc_dwarf_ra_mips64: return "r31";
+            default:
+                break;
+        }
+        return nullptr;
+    }
+
+    switch (reg_num)
+    {
+        case gcc_dwarf_zero_mips64:     return "r0";
+        case gcc_dwarf_r1_mips64:       return "r1";
+        case gcc_dwarf_r2_mips64:       return "r2";
+        case gcc_dwarf_r3_mips64:       return "r3";
+        case gcc_dwarf_r4_mips64:       return "r4";
+        case gcc_dwarf_r5_mips64:       return "r5";
+        case gcc_dwarf_r6_mips64:       return "r6";
+        case gcc_dwarf_r7_mips64:       return "r7";
+        case gcc_dwarf_r8_mips64:       return "r8";
+        case gcc_dwarf_r9_mips64:       return "r9";
+        case gcc_dwarf_r10_mips64:      return "r10";
+        case gcc_dwarf_r11_mips64:      return "r11";
+        case gcc_dwarf_r12_mips64:      return "r12";
+        case gcc_dwarf_r13_mips64:      return "r13";
+        case gcc_dwarf_r14_mips64:      return "r14";
+        case gcc_dwarf_r15_mips64:      return "r15";
+        case gcc_dwarf_r16_mips64:      return "r16";
+        case gcc_dwarf_r17_mips64:      return "r17";
+        case gcc_dwarf_r18_mips64:      return "r18";
+        case gcc_dwarf_r19_mips64:      return "r19";
+        case gcc_dwarf_r20_mips64:      return "r20";
+        case gcc_dwarf_r21_mips64:      return "r21";
+        case gcc_dwarf_r22_mips64:      return "r22";
+        case gcc_dwarf_r23_mips64:      return "r23";
+        case gcc_dwarf_r24_mips64:      return "r24";
+        case gcc_dwarf_r25_mips64:      return "r25";
+        case gcc_dwarf_r26_mips64:      return "r26";
+        case gcc_dwarf_r27_mips64:      return "r27";
+        case gcc_dwarf_gp_mips64:       return "gp";
+        case gcc_dwarf_sp_mips64:       return "sp";
+        case gcc_dwarf_r30_mips64:      return "fp";
+        case gcc_dwarf_ra_mips64:       return "ra";
+        case gcc_dwarf_sr_mips64:       return "sr";
+        case gcc_dwarf_lo_mips64:       return "lo";
+        case gcc_dwarf_hi_mips64:       return "hi";
+        case gcc_dwarf_bad_mips64:      return "bad";
+        case gcc_dwarf_cause_mips64:    return "cause";
+        case gcc_dwarf_pc_mips64:       return "pc";
+
+    }
+    return nullptr;
+}
+
+bool
+EmulateInstructionMIPS64::GetRegisterInfo (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
+{
+    if (reg_kind == eRegisterKindGeneric)
+    {
+        switch (reg_num)
+        {
+            case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_pc_mips64; break;
+            case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_sp_mips64; break;
+            case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_r30_mips64; break;
+            case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_ra_mips64; break;
+            case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_sr_mips64; break;
+                 return true;
+
+            default: return false;
+        }
+    }
+
+    if (reg_kind == eRegisterKindDWARF)
+    {
+       ::memset (&reg_info, 0, sizeof(RegisterInfo));
+       ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
+
+       if (reg_num == gcc_dwarf_sr_mips64)
+       {
+           reg_info.byte_size = 4;
+           reg_info.format = eFormatHex;
+           reg_info.encoding = eEncodingUint;
+       }
+       else if (reg_num >= gcc_dwarf_zero_mips64 && reg_num <= gcc_dwarf_pc_mips64)
+       {
+           reg_info.byte_size = 8;
+           reg_info.format = eFormatHex;
+           reg_info.encoding = eEncodingUint;
+       }
+       else
+       {
+           return false;
+       }
+
+       reg_info.name = GetRegisterName (reg_num, false);
+       reg_info.alt_name = GetRegisterName (reg_num, true);
+       reg_info.kinds[eRegisterKindDWARF] = reg_num;
+
+       switch (reg_num)
+       {
+           case gcc_dwarf_r30_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
+           case gcc_dwarf_ra_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
+           case gcc_dwarf_sp_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
+           case gcc_dwarf_pc_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
+           case gcc_dwarf_sr_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break;
+           default: break;
+       }
+       return true;
+    }
+    return false;
+}
+
+EmulateInstructionMIPS64::Opcode*
+EmulateInstructionMIPS64::GetOpcodeForInstruction (const uint32_t opcode)
+{
+    static EmulateInstructionMIPS64::Opcode 
+    g_opcodes[] = 
+    {
+        //----------------------------------------------------------------------
+        // Prologue/Epilogue instructions
+        //----------------------------------------------------------------------
+
+        // stack adjustment
+        { 0xffff0000, 0x67bd0000, &EmulateInstructionMIPS64::Emulate_addsp_imm, "DADDIU rt, rs, immediate" },
+
+        // store register
+        { 0xfc000000, 0xfc000000, &EmulateInstructionMIPS64::Emulate_store, "SD rt, offset(Rn)" },
+
+        // Load register
+        { 0xfc000000, 0xdc000000, &EmulateInstructionMIPS64::Emulate_load, "LD rt, offset(base)" },
+
+    };
+    static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
+
+    for (size_t i=0; i<k_num_mips_opcodes; ++i)
+    {
+        if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
+            return &g_opcodes[i];
+    }
+    return NULL;
+}
+
+bool 
+EmulateInstructionMIPS64::ReadInstruction ()
+{
+    bool success = false;
+    m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
+    if (success)
+    {
+        Context read_inst_context;
+        read_inst_context.type = eContextReadOpcode;
+        read_inst_context.SetNoArgs ();
+        m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
+    }
+    if (!success)
+        m_addr = LLDB_INVALID_ADDRESS;
+    return success;
+}
+
+bool
+EmulateInstructionMIPS64::EvaluateInstruction (uint32_t evaluate_options)
+{
+    uint32_t opcode = m_opcode.GetOpcode32();
+
+    if (GetByteOrder() == eByteOrderBig)
+       opcode = llvm::ByteSwap_32(opcode);
+
+    Opcode *opcode_data = GetOpcodeForInstruction(opcode);
+    bool success = false;
+
+    if (opcode_data == NULL)
+        return false;
+
+    // Call the Emulate... function.
+    success = (this->*opcode_data->callback) (opcode);  
+    if (!success)
+        return false;
+        
+    return true;
+}
+
+bool
+EmulateInstructionMIPS64::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
+{
+    unwind_plan.Clear();
+    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+
+    UnwindPlan::RowSP row(new UnwindPlan::Row);
+    const bool can_replace = false;
+
+    // Our previous Call Frame Address is the stack pointer
+    row->GetCFAValue().SetIsRegisterPlusOffset(gcc_dwarf_sp_mips64, 0);
+
+    // Our previous PC is in the RA
+    row->SetRegisterLocationToRegister(gcc_dwarf_pc_mips64, gcc_dwarf_ra_mips64, can_replace);
+
+    unwind_plan.AppendRow (row);
+
+    // All other registers are the same.
+
+    unwind_plan.SetSourceName ("EmulateInstructionMIPS64");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS64::nonvolatile_reg_p (uint64_t regnum)
+{
+    switch (regnum)
+    {
+        case gcc_dwarf_r16_mips64:
+        case gcc_dwarf_r17_mips64:
+        case gcc_dwarf_r18_mips64:
+        case gcc_dwarf_r19_mips64:
+        case gcc_dwarf_r20_mips64:
+        case gcc_dwarf_r21_mips64:
+        case gcc_dwarf_r22_mips64:
+        case gcc_dwarf_r23_mips64:
+        case gcc_dwarf_sp_mips64:
+        case gcc_dwarf_r30_mips64:
+        case gcc_dwarf_ra_mips64:
+            return true;
+        default:
+            return false;
+    }
+    return false;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_addsp_imm (const uint32_t opcode)
+{
+
+    /* Get immediate operand */
+    const uint32_t imm16 = Bits32(opcode, 15, 0);
+    
+    bool success = false;
+    uint64_t result;
+    uint64_t imm = SignedBits(imm16, 15, 0);
+
+    uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_sp_mips64, 0, &success);
+    uint64_t operand2 = imm;
+
+    result = operand1 + operand2;
+    
+    Context context;
+    RegisterInfo reg_info_Rn;
+    if (GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_sp_mips64, reg_info_Rn))
+        context.SetRegisterPlusOffset (reg_info_Rn, imm);
+
+    /* We are allocating bytes on stack */
+    context.type = eContextAdjustStackPointer;
+
+    WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_sp_mips64, result);
+    
+    return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_store (const uint32_t opcode)
+{
+    uint32_t imm16 = Bits32(opcode, 15, 0);
+    uint32_t Rt = Bits32(opcode, 20, 16);
+    uint32_t base = Bits32(opcode, 25, 21);
+    uint64_t imm = SignedBits(imm16, 15, 0);
+    uint64_t address;
+
+    integer n = UInt(base);
+    integer t = UInt(Rt);
+
+    RegisterValue data_Rt;
+
+    RegisterInfo reg_info_base;
+    RegisterInfo reg_info_Rt;
+
+    if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + n, reg_info_base))
+        return false;
+
+    if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + t, reg_info_Rt))
+        return false;
+
+    bool success = false;
+    Context context_t;
+
+    /* We look for sp based non-volatile register stores */
+    if (n == 29 && nonvolatile_reg_p(t))
+        address = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_sp_mips64, 0, &success);
+    else
+        return false;
+
+    /* Calculate address to store */
+    address = address + imm;
+
+    context_t.type = eContextPushRegisterOnStack;
+    context_t.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, 0);
+
+    uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
+    Error error;
+
+    if (!ReadRegister (&reg_info_Rt, data_Rt))
+        return false;
+
+    if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
+        return false;
+
+    if (!WriteMemory(context_t, address, buffer, reg_info_Rt.byte_size))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_load (const uint32_t opcode)
+{
+    uint32_t Rt = Bits32(opcode, 20, 16);
+    uint32_t base = Bits32(opcode, 25, 21);
+
+    integer n = UInt(base);
+    integer t = UInt(Rt);
+   
+    RegisterValue data_Rt;
+    RegisterInfo reg_info_Rt;
+
+    if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + t, reg_info_Rt))
+        return false;
+
+    Context context_t;
+
+    /* We are looking for "saved register" being restored from stack */
+    if (!n == 29 || !nonvolatile_reg_p(t))
+        return false;
+
+    context_t.type = eContextRegisterLoad;
+
+    if (!WriteRegister (context_t, &reg_info_Rt, data_Rt))
+        return false;
+
+    return true;
+}

Added: lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h?rev=232619&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h (added)
+++ lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h Wed Mar 18 04:21:29 2015
@@ -0,0 +1,134 @@
+//===-- EmulateInstructionMIPS64.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EmulateInstructionMIPS64_h_
+#define EmulateInstructionMIPS64_h_
+
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+class EmulateInstructionMIPS64 : public lldb_private::EmulateInstruction
+{
+public: 
+    static void
+    Initialize ();
+
+    static void
+    Terminate ();
+
+    static lldb_private::ConstString
+    GetPluginNameStatic ();
+    
+    static const char *
+    GetPluginDescriptionStatic ();
+    
+    static lldb_private::EmulateInstruction *
+    CreateInstance (const lldb_private::ArchSpec &arch, 
+                    lldb_private::InstructionType inst_type);
+
+    static bool
+    SupportsEmulatingInstructionsOfTypeStatic (lldb_private::InstructionType inst_type)
+    {
+        switch (inst_type)
+        {
+            case lldb_private::eInstructionTypeAny:
+            case lldb_private::eInstructionTypePrologueEpilogue:
+                return true;
+
+            case lldb_private::eInstructionTypePCModifying:
+            case lldb_private::eInstructionTypeAll:
+                return false;
+        }
+        return false;
+    }
+
+    virtual lldb_private::ConstString
+    GetPluginName();
+
+    virtual lldb_private::ConstString
+    GetShortPluginName()
+    {
+        return GetPluginNameStatic();
+    }
+
+    virtual uint32_t
+    GetPluginVersion()
+    {
+        return 1;
+    }
+
+    bool
+    SetTargetTriple (const lldb_private::ArchSpec &arch);
+    
+    EmulateInstructionMIPS64 (const lldb_private::ArchSpec &arch) :
+        EmulateInstruction (arch)
+    {
+    }
+
+    virtual bool
+    SupportsEmulatingInstructionsOfType (lldb_private::InstructionType inst_type)
+    {
+        return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
+    }
+
+    virtual bool 
+    ReadInstruction ();
+    
+    virtual bool
+    EvaluateInstruction (uint32_t evaluate_options);
+    
+    virtual bool
+    TestEmulation (lldb_private::Stream *out_stream, 
+                   lldb_private::ArchSpec &arch, 
+                   lldb_private::OptionValueDictionary *test_data)
+    {
+        return false;
+    }
+
+    virtual bool
+    GetRegisterInfo (lldb::RegisterKind reg_kind,
+                     uint32_t reg_num, 
+                     lldb_private::RegisterInfo &reg_info);
+
+    virtual bool
+    CreateFunctionEntryUnwind (lldb_private::UnwindPlan &unwind_plan);
+
+
+protected:
+
+    typedef struct
+    {
+        uint32_t mask;
+        uint32_t value;
+        bool (EmulateInstructionMIPS64::*callback) (const uint32_t opcode);
+        const char *name;
+    }  Opcode;
+    
+    static Opcode*
+    GetOpcodeForInstruction (const uint32_t opcode);
+
+    bool
+    Emulate_addsp_imm (const uint32_t opcode);
+    
+    bool
+    Emulate_store (const uint32_t opcode);
+
+    bool
+    Emulate_load (const uint32_t opcode);
+
+    bool
+    nonvolatile_reg_p (uint64_t regnum);
+
+    const char *
+    GetRegisterName (unsigned reg_num, bool altnernate_name);
+
+};
+
+#endif  // EmulateInstructionMIPS64_h_

Added: lldb/trunk/source/Plugins/Instruction/MIPS64/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/MIPS64/Makefile?rev=232619&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS64/Makefile (added)
+++ lldb/trunk/source/Plugins/Instruction/MIPS64/Makefile Wed Mar 18 04:21:29 2015
@@ -0,0 +1,14 @@
+##===- source/Plugins/Instruction/MIPS64/Makefile -------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../../../..
+LIBRARYNAME := lldbPluginEmulateInstructionMIPS64
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile

Modified: lldb/trunk/source/Plugins/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Makefile?rev=232619&r1=232618&r2=232619&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Makefile (original)
+++ lldb/trunk/source/Plugins/Makefile Wed Mar 18 04:21:29 2015
@@ -19,7 +19,7 @@ PARALLEL_DIRS := ABI/MacOSX-arm ABI/MacO
 	ObjectContainer/Universal-Mach-O ObjectFile/Mach-O \
 	ObjectFile/JIT SymbolFile/DWARF SymbolFile/Symtab Process/Utility \
 	DynamicLoader/Static Platform Process/gdb-remote \
-	Instruction/ARM Instruction/ARM64 \
+	Instruction/ARM Instruction/ARM64 Instruction/MIPS64 \
 	UnwindAssembly/InstEmulation UnwindAssembly/x86 \
 	LanguageRuntime/CPlusPlus/ItaniumABI \
 	LanguageRuntime/ObjC/AppleObjCRuntime \

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=232619&r1=232618&r2=232619&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp Wed Mar 18 04:21:29 2015
@@ -610,7 +610,6 @@ UnwindAssemblyInstEmulation::WriteRegist
         case EmulateInstruction::eContextRegisterPlusOffset:
         case EmulateInstruction::eContextAdjustPC:
         case EmulateInstruction::eContextRegisterStore:
-        case EmulateInstruction::eContextRegisterLoad:  
         case EmulateInstruction::eContextAbsoluteBranchRegister:
         case EmulateInstruction::eContextSupervisorCall:
         case EmulateInstruction::eContextTableBranchReadMemory:
@@ -634,6 +633,35 @@ UnwindAssemblyInstEmulation::WriteRegist
 //            }
             break;
 
+        case EmulateInstruction::eContextRegisterLoad:
+            {
+                const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
+                const uint32_t reg_num = reg_info->kinds[unwind_reg_kind];
+                if (reg_num != LLDB_INVALID_REGNUM)
+                {
+                    m_curr_row->SetRegisterLocationToRegister (reg_num, reg_num, must_replace);
+                    m_curr_row_modified = true;
+                    m_curr_insn_restored_a_register = true;
+
+                    if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA)
+                    {
+                        // This load was restoring the return address register,
+                        // so this is also how we will unwind the PC...
+                        RegisterInfo pc_reg_info;
+                        if (instruction->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info))
+                        {
+                            uint32_t pc_reg_num = pc_reg_info.kinds[unwind_reg_kind];
+                            if (pc_reg_num != LLDB_INVALID_REGNUM)
+                            {
+                                m_curr_row->SetRegisterLocationToRegister (pc_reg_num, reg_num, must_replace);
+                                m_curr_row_modified = true;
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+
         case EmulateInstruction::eContextRelativeBranchImmediate:
             {
                 

Modified: lldb/trunk/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=232619&r1=232618&r2=232619&view=diff
==============================================================================
--- lldb/trunk/source/lldb.cpp (original)
+++ lldb/trunk/source/lldb.cpp Wed Mar 18 04:21:29 2015
@@ -37,6 +37,7 @@
 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
 #include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
 #include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
+#include "Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h"
 #include "Plugins/JITLoader/GDB/JITLoaderGDB.h"
 #include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
 #include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
@@ -224,6 +225,7 @@ lldb_private::Initialize ()
         UnwindAssembly_x86::Initialize();
         EmulateInstructionARM::Initialize();
         EmulateInstructionARM64::Initialize();
+        EmulateInstructionMIPS64::Initialize();
         SymbolFileDWARFDebugMap::Initialize();
         ItaniumABILanguageRuntime::Initialize();
         AppleObjCRuntimeV2::Initialize();
@@ -339,6 +341,7 @@ lldb_private::Terminate ()
         UnwindAssemblyInstEmulation::Terminate();
         EmulateInstructionARM::Terminate();
         EmulateInstructionARM64::Terminate();
+        EmulateInstructionMIPS64::Terminate();
         SymbolFileDWARFDebugMap::Terminate();
         ItaniumABILanguageRuntime::Terminate();
         AppleObjCRuntimeV2::Terminate();





More information about the lldb-commits mailing list