nitesh.jain updated this revision to Diff 64693.
nitesh.jain added a comment.

Removed dynamic_size_dwarf_len field from RegisterInfo struct.


https://reviews.llvm.org/D20357

Files:
  include/lldb/Host/common/NativeRegisterContext.h
  include/lldb/Host/common/NativeRegisterContextRegisterInfo.h
  include/lldb/Target/RegisterContext.h
  include/lldb/lldb-private-types.h
  source/Host/common/NativeRegisterContext.cpp
  source/Host/common/NativeRegisterContextRegisterInfo.cpp
  source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
  source/Plugins/Process/Utility/DynamicRegisterInfo.h
  source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
  source/Plugins/Process/Utility/RegisterContextLinux_mips.h
  source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
  source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
  source/Plugins/Process/Utility/RegisterInfoInterface.h
  source/Plugins/Process/Utility/RegisterInfos_mips.h
  source/Plugins/Process/Utility/RegisterInfos_mips64.h
  source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Target/RegisterContext.cpp

Index: source/Target/RegisterContext.cpp
===================================================================
--- source/Target/RegisterContext.cpp
+++ source/Target/RegisterContext.cpp
@@ -21,7 +21,9 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/Target.h"
-
+#include "lldb/Core/Module.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Core/Value.h"
 using namespace lldb;
 using namespace lldb_private;
 
@@ -76,6 +78,46 @@
     return nullptr;
 }
 
+uint32_t
+RegisterContext::UpdateDynamicRegisterSize (const lldb_private::ArchSpec &arch,
+                                            RegisterInfo* reg_info,
+                                            size_t opcode_len)
+{
+    ExecutionContext exe_ctx (CalculateThread());
+
+    // In MIPS, the floating point registers size is depends on FR bit of SR register.
+    // if SR.FR  == 1 then all floating point registers are 64 bits.
+    // else they are all 32 bits.
+    
+    int expr_result;
+    uint32_t addr_size =  arch.GetAddressByteSize ();
+    const uint8_t* opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes;
+
+    DataExtractor dwarf_data (opcode_ptr, opcode_len, 
+                              arch.GetByteOrder (), addr_size);
+    ModuleSP opcode_ctx;
+    DWARFExpression dwarf_expr (opcode_ctx, dwarf_data, nullptr, 0, opcode_len);
+    Value result;
+    Error error;
+    const lldb::offset_t offset = 0;
+    if(dwarf_expr.Evaluate (&exe_ctx, nullptr, nullptr, this, opcode_ctx, dwarf_data, nullptr,
+                            offset, opcode_len, eRegisterKindDWARF, nullptr, nullptr, result, &error))
+    {
+        expr_result = result.GetScalar().SInt(-1);
+        switch (expr_result)
+        {
+            case 0: return 4;
+            case 1: return 8;
+            default: return reg_info->byte_size;
+        }
+    }
+    else
+    {
+        printf("Error executing DwarfExpression::Evaluate %s\n", error.AsCString());
+        return reg_info->byte_size;
+    }
+}
+
 const RegisterInfo *
 RegisterContext::GetRegisterInfo (lldb::RegisterKind kind, uint32_t num)
 {
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -539,6 +539,8 @@
                 ConstString set_name;
                 std::vector<uint32_t> value_regs;
                 std::vector<uint32_t> invalidate_regs;
+                uint8_t *dwarf_opcode_bytes = NULL;
+                uint32_t dwarf_expr_bytes_len;
                 RegisterInfo reg_info = { NULL,                 // Name
                     NULL,                 // Alt name
                     0,                    // byte size
@@ -553,6 +555,7 @@
                         reg_num           // native register number
                     },
                     NULL,
+                    NULL,
                     NULL
                 };
 
@@ -638,6 +641,25 @@
                     {
                         SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16);
                     }
+                    else if (name.compare("dynamic_size_dwarf_expr_bytes") == 0)
+                    {
+                       dwarf_expr_bytes_len = value.length () / 2;
+                       assert(dwarf_expr_bytes_len > 0);
+                       dwarf_opcode_bytes = new uint8_t[dwarf_expr_bytes_len];
+                       StringExtractor name_extractor;
+                       
+                       if (dwarf_opcode_bytes)
+                       {
+                           // Swap "value" over into "name_extractor"
+                           name_extractor.GetStringRef().swap(value);
+                           uint32_t ret_val = name_extractor.GetHexBytesAvail (dwarf_opcode_bytes, dwarf_expr_bytes_len);
+                           assert (dwarf_expr_bytes_len == ret_val);
+
+                           // Right now the dynamic_size_dwarf_expr_bytes is pointing to a temporary location
+                           // the actual location will be updated in DynamicRegisterInfo class
+                           reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes;
+                       }
+                    }
                 }
 
                 reg_info.byte_offset = reg_offset;
@@ -661,7 +683,11 @@
 
                 AugmentRegisterInfoViaABI (reg_info, reg_name, abi_to_use);
 
-                m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+                m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name, dwarf_expr_bytes_len);
+
+                // Free the allocated memory
+                if (dwarf_opcode_bytes)
+                    delete[] dwarf_opcode_bytes; 
             }
             else
             {
@@ -4373,6 +4399,8 @@
         ConstString set_name;
         std::vector<uint32_t> value_regs;
         std::vector<uint32_t> invalidate_regs;
+        uint8_t *dwarf_opcode_bytes = NULL;
+        uint32_t dwarf_expr_bytes_len;
         bool encoding_set = false;
         bool format_set = false;
         RegisterInfo reg_info = { NULL,                 // Name
@@ -4389,10 +4417,11 @@
                 cur_reg_num         // native register number
             },
             NULL,
+            NULL,
             NULL
         };
 
-        reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type, &reg_name, &alt_name, &set_name, &value_regs, &invalidate_regs, &encoding_set, &format_set, &reg_info, &cur_reg_num, &reg_offset](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
+        reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type, &reg_name, &alt_name, &set_name, &value_regs, &invalidate_regs, &encoding_set, &format_set, &reg_info, &cur_reg_num, &reg_offset, &dwarf_expr_bytes_len, &dwarf_opcode_bytes](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
             if (name == "name")
             {
                 reg_name.SetString(value);
@@ -4480,6 +4509,25 @@
             {
                 SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
             }
+            else if (name == "dynamic_size_dwarf_expr_bytes")
+            {
+                StringExtractor name_extractor;
+                std::string opcode_string = value.str();
+                dwarf_expr_bytes_len = opcode_string.length() / 2;
+                assert(dwarf_expr_bytes_len > 0);
+                dwarf_opcode_bytes = new uint8_t[dwarf_expr_bytes_len];
+
+                if (dwarf_opcode_bytes)
+                {    
+                    name_extractor.GetStringRef().swap(opcode_string);
+                    uint32_t ret_val = name_extractor.GetHexBytesAvail (dwarf_opcode_bytes, dwarf_expr_bytes_len);
+                    assert(dwarf_expr_bytes_len == ret_val);
+
+                    // Right now the dynamic_size_dwarf_expr_bytes point to temporary location
+                    // the actual location will be updated in DynamicRegisterInfo
+                    reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes;
+                }
+            }
             else
             {
                 printf("unhandled attribute %s = %s\n", name.data(), value.data());
@@ -4527,7 +4575,11 @@
 
         ++cur_reg_num;
         AugmentRegisterInfoViaABI (reg_info, reg_name, abi_sp);
-        dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+        dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name, dwarf_expr_bytes_len);
+
+        //Free allocated memory
+        if (dwarf_opcode_bytes)
+            delete[] dwarf_opcode_bytes;
 
         return true; // Keep iterating through all "reg" elements
     });
Index: source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -89,7 +89,16 @@
 const RegisterInfo *
 GDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg)
 {
-    return m_reg_info.GetRegisterInfoAtIndex (reg);
+    RegisterInfo* reg_info = m_reg_info.GetRegisterInfoAtIndex (reg);
+
+    if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes)
+    {
+        const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
+        size_t opcode_len = m_reg_info.GetDwarfOpcodeLength (reg);
+        uint8_t reg_size = UpdateDynamicRegisterSize (arch, reg_info, opcode_len);
+        reg_info->byte_size = reg_size;
+    }
+    return reg_info;
 }
 
 size_t
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1634,6 +1634,14 @@
         response.PutChar (';');
     }
 
+    if (reg_info->dynamic_size_dwarf_expr_bytes)
+    {
+       const size_t dwarf_opcode_len = reg_context_sp->GetDwarfOpcodeLength (reg_index);
+       response.PutCString("dynamic_size_dwarf_expr_bytes:");
+       for(uint32_t i = 0; i < dwarf_opcode_len; ++i)
+           response.PutHex8 (reg_info->dynamic_size_dwarf_expr_bytes[i]);
+       response.PutChar(';');
+    }
     return SendPacketNoLock(response.GetData(), response.GetSize());
 }
 
@@ -1829,7 +1837,10 @@
         return SendErrorResponse (0x47);
     }
 
-    if (reg_size != reg_info->byte_size)
+    // The dwarf expression are evaluate on LLDB side
+    // which may cause register size to change
+    // Hence the reg_size may not be same as reg_info->bytes_size
+    if ((reg_size != reg_info->byte_size) && !(reg_info->dynamic_size_dwarf_expr_bytes))
     {
         return SendIllFormedResponse (packet, "P packet register size is incorrect");
     }
Index: source/Plugins/Process/Utility/RegisterInfos_mips64.h
===================================================================
--- source/Plugins/Process/Utility/RegisterInfos_mips64.h
+++ source/Plugins/Process/Utility/RegisterInfos_mips64.h
@@ -13,7 +13,7 @@
 // C++ Includes
 // Other libraries and framework includes
 #include "llvm/Support/Compiler.h"
-
+#include "lldb/Core/dwarf.h"
 // Project includes
 
 #ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
@@ -44,32 +44,39 @@
 #ifdef LINUX_MIPS64
     #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
          { #reg, alt, sizeof(((GPR_linux_mips*)0)->reg), GPR_OFFSET(reg), eEncodingUint, \
-          eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL }
+          eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL, NULL}
 #else
     #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4)    \
          { #reg, alt, sizeof(((GPR_freebsd_mips*)0)->reg), GPR_OFFSET(reg), eEncodingUint, \
-          eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL }
+          eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL, NULL}
 #endif
 
 #define DEFINE_GPR_INFO(reg, alt, kind1, kind2, kind3, kind4)    \
     { #reg, alt, sizeof(((GPR_linux_mips*)0)->reg) / 2, GPR_OFFSET(reg), eEncodingUint, \
-      eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL }
+      eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL, NULL}
+
+const uint8_t dwarf_opcode_mips64 [] = {
+                                           llvm::dwarf::DW_OP_regx, dwarf_sr_mips64, llvm::dwarf::DW_OP_lit1,
+                                           llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and, 
+                                           llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr
+                                       };
+
 
 #define DEFINE_FPR(reg, alt, kind1, kind2, kind3, kind4)    \
     { #reg, alt, sizeof(((FPR_linux_mips*)0)->reg), FPR_OFFSET(reg), eEncodingIEEE754,  \
-      eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL }
+      eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL, dwarf_opcode_mips64}
 
 #define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3, kind4)    \
     { #reg, alt, sizeof(((FPR_linux_mips*)0)->reg), FPR_OFFSET(reg), eEncodingUint,   \
-      eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL }
+      eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL, NULL}
 
 #define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4)    \
     { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingVector,   \
-      eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL }
+      eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL, NULL}
 
 #define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4)    \
     { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingUint,   \
-      eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL }
+      eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL, NULL}
 
 static RegisterInfo
 g_register_infos_mips64[] =
Index: source/Plugins/Process/Utility/RegisterInfos_mips.h
===================================================================
--- source/Plugins/Process/Utility/RegisterInfos_mips.h
+++ source/Plugins/Process/Utility/RegisterInfos_mips.h
@@ -13,7 +13,7 @@
 // C++ Includes
 // Other libraries and framework includes
 #include "llvm/Support/Compiler.h"
-
+#include "lldb/Core/dwarf.h"
 // Project includes
 
 #ifdef DECLARE_REGISTER_INFOS_MIPS_STRUCT
@@ -36,23 +36,29 @@
 // Note that the size and offset will be updated by platform-specific classes.
 #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4)            \
     { #reg, alt, sizeof(((GPR_linux_mips*)NULL)->reg) / 2, GPR_OFFSET(reg), eEncodingUint,  \
-      eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips }, NULL, NULL }
+      eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips }, NULL, NULL, NULL}
+
+const uint8_t dwarf_opcode_mips [] = {
+                                        llvm::dwarf::DW_OP_regx, dwarf_sr_mips, llvm::dwarf::DW_OP_lit1,
+                                        llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
+                                        llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr
+                                     };
 
 #define DEFINE_FPR(reg, alt, kind1, kind2, kind3, kind4)           \
     { #reg, alt, sizeof(((FPR_linux_mips*)NULL)->reg), FPR_OFFSET(reg), eEncodingIEEE754,   \
-      eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL }
+      eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL, dwarf_opcode_mips}
 
 #define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3, kind4)      \
    { #reg, alt, sizeof(((FPR_linux_mips*)NULL)->reg), FPR_OFFSET(reg), eEncodingUint,   \
-     eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL }
+     eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL, NULL}
 
 #define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4)    \
     { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingVector,   \
-      eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL }
+      eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL, NULL}
 
 #define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4)    \
     { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingUint, \
-      eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL }
+      eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL, NULL}
 
 // RegisterKind: EH_Frame, DWARF, Generic, Procss Plugin, LLDB
 
Index: source/Plugins/Process/Utility/RegisterInfoInterface.h
===================================================================
--- source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -48,6 +48,12 @@
             return GetRegisterCount();
         }
 
+        virtual size_t
+        GetDwarfOpcodeLength (const uint32_t i) const
+        {
+            return 0;  
+        }
+
         const lldb_private::ArchSpec&
         GetTargetArchitecture() const
             { return m_target_arch; }
Index: source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
+++ source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
@@ -33,6 +33,9 @@
     uint32_t
     GetUserRegisterCount () const override;
 
+    size_t
+    GetDwarfOpcodeLength (const uint32_t i) const override;
+
 private:
     const lldb_private::RegisterInfo *m_register_info_p;
     uint32_t m_register_info_count;
Index: source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
+++ source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
@@ -121,6 +121,19 @@
     return m_register_info_count;
 }
 
+size_t
+RegisterContextLinux_mips64::GetDwarfOpcodeLength (const uint32_t i) const
+{
+    if (i < GetRegisterCount ())
+    {
+        const RegisterInfo *reg_info = GetRegisterInfo() + i;
+
+        if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes)
+            return sizeof(dwarf_opcode_mips64);
+    }
+    return 0;
+}
+
 uint32_t
 RegisterContextLinux_mips64::GetUserRegisterCount () const
 {
Index: source/Plugins/Process/Utility/RegisterContextLinux_mips.h
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_mips.h
+++ source/Plugins/Process/Utility/RegisterContextLinux_mips.h
@@ -31,6 +31,9 @@
     uint32_t
     GetUserRegisterCount () const override;
 
+    size_t
+    GetDwarfOpcodeLength (const uint32_t i) const override;
+
 private:
     uint32_t m_user_register_count;
 };
Index: source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
+++ source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
@@ -69,6 +69,19 @@
     return static_cast<uint32_t> (sizeof (g_register_infos_mips) / sizeof (g_register_infos_mips [0]));
 }
 
+size_t
+RegisterContextLinux_mips::GetDwarfOpcodeLength (const uint32_t i) const
+{
+    if (i < GetRegisterCount ())
+    {
+        const RegisterInfo *reg_info = GetRegisterInfo() + i;
+
+        if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes)
+            return sizeof(dwarf_opcode_mips);
+    }
+    return 0;
+}
+
 uint32_t
 RegisterContextLinux_mips::GetUserRegisterCount () const
 {
Index: source/Plugins/Process/Utility/DynamicRegisterInfo.h
===================================================================
--- source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -39,7 +39,8 @@
     AddRegister (lldb_private::RegisterInfo &reg_info, 
                  lldb_private::ConstString &reg_name, 
                  lldb_private::ConstString &reg_alt_name, 
-                 lldb_private::ConstString &set_name);
+                 lldb_private::ConstString &set_name,
+                 uint32_t dwarf_expr_bytes_len = 0);
 
     void
     Finalize (const lldb_private::ArchSpec &arch);
@@ -53,9 +54,16 @@
     size_t
     GetRegisterDataByteSize() const;
 
+    // Get length of the Dwarf Opcode
+    size_t
+    GetDwarfOpcodeLength (uint32_t i);
+
     const lldb_private::RegisterInfo *
     GetRegisterInfoAtIndex (uint32_t i) const;
 
+    lldb_private::RegisterInfo *
+    GetRegisterInfoAtIndex (uint32_t i);
+
     const lldb_private::RegisterSet *
     GetRegisterSet (uint32_t i) const;
 
@@ -81,6 +89,8 @@
     typedef std::vector <reg_num_collection> set_reg_num_collection;
     typedef std::vector <lldb_private::ConstString> name_collection;
     typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
+    typedef std::vector <uint8_t> dwarf_opcode;
+    typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
 
     lldb_private::RegisterInfo *
     GetRegisterInfo (const lldb_private::ConstString &reg_name);
@@ -91,6 +101,7 @@
     name_collection m_set_names;
     reg_to_regs_map m_value_regs_map;
     reg_to_regs_map m_invalidate_regs_map;
+    dynamic_reg_size_map m_dynamic_reg_size_map;
     size_t m_reg_data_byte_size;   // The number of bytes required to store all registers
     bool m_finalized;
 };
Index: source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
===================================================================
--- source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -19,7 +19,7 @@
 #include "lldb/Core/StructuredData.h"
 #include "lldb/DataFormatters/FormatManager.h"
 #include "lldb/Host/StringConvert.h"
-
+#include "lldb/Utility/StringExtractor.h"
 using namespace lldb;
 using namespace lldb_private;
 
@@ -30,6 +30,7 @@
     m_set_names (),
     m_value_regs_map (),
     m_invalidate_regs_map (),
+    m_dynamic_reg_size_map (),
     m_reg_data_byte_size (0),
     m_finalized (false)
 {
@@ -43,6 +44,7 @@
     m_set_names (),
     m_value_regs_map (),
     m_invalidate_regs_map (),
+    m_dynamic_reg_size_map (),
     m_reg_data_byte_size (0),
     m_finalized (false)
 {
@@ -292,6 +294,31 @@
 
         reg_info.byte_size = bitsize / 8;
 
+        std::string dwarf_opcode_string;
+        if (reg_info_dict->GetValueForKeyAsString("dynamic_size_dwarf_expr_bytes", dwarf_opcode_string))
+        {
+            uint8_t *dwarf_opcode_ptr = NULL;
+            uint32_t dwarf_expr_bytes_len = dwarf_opcode_string.length () / 2;
+            uint32_t j;
+            StringExtractor name_extractor;
+            dwarf_opcode_ptr = new uint8_t[dwarf_expr_bytes_len];
+            if (dwarf_opcode_ptr)
+            {
+                // Swap "dwarf_opcode_string" over into "name_extractor"
+                name_extractor.GetStringRef ().swap (dwarf_opcode_string);
+                uint32_t ret_val = name_extractor.GetHexBytesAvail (dwarf_opcode_ptr, dwarf_expr_bytes_len);
+                assert(ret_val == dwarf_expr_bytes_len);
+                for (j = 0; j < dwarf_expr_bytes_len; ++j)
+                    m_dynamic_reg_size_map[i].push_back(dwarf_opcode_ptr[j]);
+
+                delete[] dwarf_opcode_ptr;
+
+                // Update the actual location
+                reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data ();
+            }
+            else
+                reg_info.dynamic_size_dwarf_expr_bytes = NULL;
+        }
         std::string format_str;
         if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr))
         {
@@ -394,12 +421,18 @@
     return m_regs.size();
 }
 
+size_t
+DynamicRegisterInfo::GetDwarfOpcodeLength (uint32_t i)
+{
+    return m_dynamic_reg_size_map[i].size();
+}
 
 void
 DynamicRegisterInfo::AddRegister (RegisterInfo &reg_info,
                                   ConstString &reg_name, 
                                   ConstString &reg_alt_name, 
-                                  ConstString &set_name)
+                                  ConstString &set_name,
+                                  uint32_t dwarf_expr_bytes_len)
 {
     assert(!m_finalized);
     const uint32_t reg_num = m_regs.size();
@@ -417,6 +450,14 @@
         for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
             m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
     }
+    if (reg_info.dynamic_size_dwarf_expr_bytes)
+    {
+        for (i = 0; i < dwarf_expr_bytes_len; ++i)
+           m_dynamic_reg_size_map[reg_num].push_back(reg_info.dynamic_size_dwarf_expr_bytes[i]);
+
+        // Update the actual location
+        reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[reg_num].data ();
+    }
     m_regs.push_back (reg_info);
     uint32_t set = GetRegisterSetIndexByName (set_name, true);
     assert (set < m_sets.size());
@@ -641,6 +682,14 @@
     return NULL;
 }
 
+RegisterInfo *
+DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i)
+{
+    if (i < m_regs.size())
+        return &m_regs[i];
+    return NULL;
+}
+
 const RegisterSet *
 DynamicRegisterInfo::GetRegisterSet (uint32_t i) const
 {
@@ -688,6 +737,7 @@
     m_set_names.clear();
     m_value_regs_map.clear();
     m_invalidate_regs_map.clear();
+    m_dynamic_reg_size_map.clear();
     m_reg_data_byte_size = 0;
     m_finalized = false;
 }
Index: source/Host/common/NativeRegisterContextRegisterInfo.cpp
===================================================================
--- source/Host/common/NativeRegisterContextRegisterInfo.cpp
+++ source/Host/common/NativeRegisterContextRegisterInfo.cpp
@@ -48,3 +48,11 @@
 {
     return *m_register_info_interface_up;
 }
+
+size_t
+NativeRegisterContextRegisterInfo::GetDwarfOpcodeLength (const uint32_t i) const
+{
+    const RegisterInfoInterface& reg_info_interface = GetRegisterInfoInterface ();
+    return reg_info_interface.GetDwarfOpcodeLength (i);
+}
+
Index: source/Host/common/NativeRegisterContext.cpp
===================================================================
--- source/Host/common/NativeRegisterContext.cpp
+++ source/Host/common/NativeRegisterContext.cpp
@@ -270,6 +270,12 @@
     return 0;
 }
 
+size_t
+NativeRegisterContext::GetDwarfOpcodeLength (const uint32_t i) const
+{
+    return 0;
+}
+
 uint32_t
 NativeRegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
 {
Index: include/lldb/lldb-private-types.h
===================================================================
--- include/lldb/lldb-private-types.h
+++ include/lldb/lldb-private-types.h
@@ -54,6 +54,8 @@
                                    // null, all registers in this list will be invalidated when the value of this
                                    // register changes.  For example, the invalidate list for eax would be rax
                                    // ax, ah, and al.
+        const uint8_t *dynamic_size_dwarf_expr_bytes; // A DWARF expression that when evaluated gives 
+                                                      // the byte size of this register. 
     };
 
     //----------------------------------------------------------------------
Index: include/lldb/Target/RegisterContext.h
===================================================================
--- include/lldb/Target/RegisterContext.h
+++ include/lldb/Target/RegisterContext.h
@@ -46,6 +46,12 @@
     virtual const RegisterInfo *
     GetRegisterInfoAtIndex (size_t reg) = 0;
 
+    // Detect the register size dynamically.
+    uint32_t
+    UpdateDynamicRegisterSize (const lldb_private::ArchSpec &arch,
+                               RegisterInfo* reg_info,
+                               size_t opcode_len);
+
     virtual size_t
     GetRegisterSetCount () = 0;
 
Index: include/lldb/Host/common/NativeRegisterContextRegisterInfo.h
===================================================================
--- include/lldb/Host/common/NativeRegisterContextRegisterInfo.h
+++ include/lldb/Host/common/NativeRegisterContextRegisterInfo.h
@@ -37,6 +37,9 @@
         const RegisterInfo *
         GetRegisterInfoAtIndex (uint32_t reg_index) const override;
 
+        size_t
+        GetDwarfOpcodeLength (const uint32_t i) const override;
+
         const RegisterInfoInterface&
         GetRegisterInfoInterface () const;
 
Index: include/lldb/Host/common/NativeRegisterContext.h
===================================================================
--- include/lldb/Host/common/NativeRegisterContext.h
+++ include/lldb/Host/common/NativeRegisterContext.h
@@ -87,6 +87,9 @@
     virtual bool
     ClearHardwareBreakpoint (uint32_t hw_idx);
 
+    virtual size_t
+    GetDwarfOpcodeLength (const uint32_t i) const;
+
     virtual uint32_t
     NumSupportedHardwareWatchpoints ();
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to