[Lldb-commits] [lldb] r178252 - Introduces extended register sets whose availability can vary with the target processor.

Ashok Thirumurthi ashok.thirumurthi at intel.com
Thu Mar 28 10:27:40 PDT 2013


Author: athirumu
Date: Thu Mar 28 12:27:40 2013
New Revision: 178252

URL: http://llvm.org/viewvc/llvm-project?rev=178252&view=rev
Log:
Introduces extended register sets whose availability can vary with the target processor.
- Includes a stub for AVX support in the x86-64 register context and a failing test for register sets that are unavailable.

Thanks to Greg Clayton for his review feedback.



Modified:
    lldb/trunk/source/Commands/CommandObjectRegister.cpp
    lldb/trunk/source/Core/RegisterValue.cpp
    lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
    lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.h
    lldb/trunk/test/functionalities/register/TestRegisters.py

Modified: lldb/trunk/source/Commands/CommandObjectRegister.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectRegister.cpp?rev=178252&r1=178251&r2=178252&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectRegister.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectRegister.cpp Thu Mar 28 12:27:40 2013
@@ -134,6 +134,10 @@ public:
     {
         uint32_t unavailable_count = 0;
         uint32_t available_count = 0;
+
+        if (!reg_ctx)
+            return false; // thread has no registers (i.e. core files are corrupt, incomplete crash logs...)
+
         const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
         if (reg_set)
         {
@@ -147,6 +151,7 @@ public:
                 // Skip the dumping of derived register if primitive_only is true.
                 if (primitive_only && reg_info && reg_info->value_regs)
                     continue;
+
                 if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
                     ++available_count;
                 else
@@ -182,18 +187,21 @@ protected:
                 for (size_t i=0; i<set_array_size; ++i)
                 {
                     set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
-                    if (set_idx != UINT32_MAX)
+                    if (set_idx < reg_ctx->GetRegisterSetCount())
                     {
                         if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx))
                         {
-                            result.AppendErrorWithFormat ("invalid register set index: %zu\n", set_idx);
+                            if (errno)
+                                result.AppendErrorWithFormat ("register read failed with errno: %d\n", errno);
+                            else
+                                result.AppendError ("unknown error while reading registers.\n");
                             result.SetStatus (eReturnStatusFailed);
                             break;
                         }
                     }
                     else
                     {
-                        result.AppendError ("invalid register set index\n");
+                        result.AppendErrorWithFormat ("invalid register set index: %zu\n", set_idx);
                         result.SetStatus (eReturnStatusFailed);
                         break;
                     }

Modified: lldb/trunk/source/Core/RegisterValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/RegisterValue.cpp?rev=178252&r1=178251&r2=178252&view=diff
==============================================================================
--- lldb/trunk/source/Core/RegisterValue.cpp (original)
+++ lldb/trunk/source/Core/RegisterValue.cpp Thu Mar 28 12:27:40 2013
@@ -981,12 +981,11 @@ RegisterValue::SetBytes (const void *byt
     // m_data.buffer.bytes, or make it something that is allocated on
     // the heap. Since the data buffer is in a union, we can't make it
     // a collection class like SmallVector...
-    assert (length <= sizeof (m_data.buffer.bytes));
     if (bytes && length > 0)
     {
+        assert (length <= sizeof (m_data.buffer.bytes) && "Storing too many bytes in a RegisterValue.");
         m_type = eTypeBytes;
         m_data.buffer.length = length;
-        assert (length <= sizeof (m_data.buffer.bytes));
         memcpy (m_data.buffer.bytes, bytes, length);
         m_data.buffer.byte_order = byte_order;
     }

Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp?rev=178252&r1=178251&r2=178252&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp Thu Mar 28 12:27:40 2013
@@ -105,15 +105,30 @@ enum
     fpu_xmm15,
     k_last_fpr = fpu_xmm15,
 
-    k_num_registers,
-    k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
-    k_num_fpu_registers = k_last_fpr - k_first_fpr + 1
-};
+    k_num_registers, // TODO: Add support for AVX registers
 
-// Number of register sets provided by this context.
-enum
-{
-    k_num_register_sets = 2
+    k_first_avx,
+    fpu_ymm0 = k_first_avx,
+    fpu_ymm1,
+    fpu_ymm2,
+    fpu_ymm3,
+    fpu_ymm4,
+    fpu_ymm5,
+    fpu_ymm6,
+    fpu_ymm7,
+    fpu_ymm8,
+    fpu_ymm9,
+    fpu_ymm10,
+    fpu_ymm11,
+    fpu_ymm12,
+    fpu_ymm13,
+    fpu_ymm14,
+    fpu_ymm15,
+    k_last_avx = fpu_ymm15,
+
+    k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
+    k_num_fpu_registers = k_last_fpr - k_first_fpr + 1,
+    k_num_avx_registers = k_last_avx - k_first_avx + 1
 };
 
 enum
@@ -300,11 +315,40 @@ g_fpu_regnums[k_num_fpu_registers] =
     fpu_xmm15
 };
 
+static const uint32_t
+g_avx_regnums[k_num_avx_registers] =
+{
+    fpu_ymm0,
+    fpu_ymm1,
+    fpu_ymm2,
+    fpu_ymm3,
+    fpu_ymm4,
+    fpu_ymm5,
+    fpu_ymm6,
+    fpu_ymm7,
+    fpu_ymm8,
+    fpu_ymm9,
+    fpu_ymm10,
+    fpu_ymm11,
+    fpu_ymm12,
+    fpu_ymm13,
+    fpu_ymm14,
+    fpu_ymm15
+};
+
+// Number of register sets provided by this context.
+enum
+{
+    k_num_extended_register_sets = 1,
+    k_num_register_sets = 3
+};
+
 static const RegisterSet
 g_reg_sets[k_num_register_sets] =
 {
-    { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
-    { "Floating Point Registers",  "fpu", k_num_fpu_registers, g_fpu_regnums }
+    { "General Purpose Registers",  "gpr", k_num_gpr_registers, g_gpr_regnums },
+    { "Floating Point Registers",   "fpu", k_num_fpu_registers, g_fpu_regnums },
+    { "Advanced Vector Extensions", "avx", k_num_avx_registers, g_avx_regnums }
 };
 
 // Computes the offset of the given GPR in the user data area.
@@ -462,8 +506,13 @@ static bool IsFPR(unsigned reg)
     return (k_first_fpr <= reg && reg <= k_last_fpr);
 }
 
+static bool IsAVX(unsigned reg)
+{
+    return (k_first_avx <= reg && reg <= k_last_avx);
+}
+
 RegisterContext_x86_64::RegisterContext_x86_64(Thread &thread,
-                                                         uint32_t concrete_frame_idx)
+                                               uint32_t concrete_frame_idx)
     : RegisterContextPOSIX(thread, concrete_frame_idx)
 {
 }
@@ -508,13 +557,18 @@ RegisterContext_x86_64::GetRegisterInfoA
 size_t
 RegisterContext_x86_64::GetRegisterSetCount()
 {
-    return k_num_register_sets;
+    size_t sets = 0;
+    for (size_t set = 0; set < k_num_register_sets; ++set)
+        if (IsRegisterSetAvailable(set))
+            ++sets;
+
+    return sets;
 }
 
 const RegisterSet *
 RegisterContext_x86_64::GetRegisterSet(size_t set)
 {
-    if (set < k_num_register_sets)
+    if (IsRegisterSetAvailable(set))
         return &g_reg_sets[set];
     else
         return NULL;
@@ -541,17 +595,27 @@ RegisterContext_x86_64::GetRegisterName(
 }
 
 bool
+RegisterContext_x86_64::IsRegisterSetAvailable(size_t set_index)
+{
+    // Note: Extended register sets are assumed to be at the end of g_reg_sets.
+    return (set_index < k_num_register_sets - k_num_extended_register_sets);
+}   
+
+bool
 RegisterContext_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
 {
     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
 
-    if (reg >= k_first_fpr && reg <= k_last_fpr) {
+    if (IsAVX(reg))
+        return false;
+
+    if (IsFPR(reg)) {
         if (!ReadFPR())
             return false;
     }
     else {
         ProcessMonitor &monitor = GetMonitor();
-        return monitor.ReadRegisterValue(m_thread.GetID(), GetRegOffset(reg),GetRegSize(reg), value);
+        return monitor.ReadRegisterValue(m_thread.GetID(), GetRegOffset(reg), GetRegSize(reg), value);
     }
 
     if (reg_info->encoding == eEncodingVector) {
@@ -624,6 +688,9 @@ RegisterContext_x86_64::WriteRegister(co
                                            const lldb_private::RegisterValue &value)
 {
     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+    if (IsAVX(reg))
+        return false;
+
     ProcessMonitor &monitor = GetMonitor();
     return monitor.WriteRegisterValue(m_thread.GetID(), GetRegOffset(reg), value);
 }

Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.h?rev=178252&r1=178251&r2=178252&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.h Thu Mar 28 12:27:40 2013
@@ -128,6 +128,11 @@ public:
         uint64_t fault_address; // Control register CR3.
     };
 
+protected:
+    // Determines if an extended register set is supported on the processor running the inferior process.
+    virtual bool
+    IsRegisterSetAvailable(size_t set_index);
+
 private:
     UserArea user;
 

Modified: lldb/trunk/test/functionalities/register/TestRegisters.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/register/TestRegisters.py?rev=178252&r1=178251&r2=178252&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/register/TestRegisters.py (original)
+++ lldb/trunk/test/functionalities/register/TestRegisters.py Thu Mar 28 12:27:40 2013
@@ -56,6 +56,10 @@ class RegisterCommandsTestCase(TestBase)
         self.expect("register read -a", MISSING_EXPECTED_REGISTERS,
             substrs = ['registers were unavailable'], matching = False)
         self.runCmd("register read xmm0")
+        self.runCmd("register read ymm15") # may be available
+
+        self.expect("register read -s 3",
+            substrs = ['invalid register set index: 3'], error = True)
 
         # rdar://problem/10611315
         # expression command doesn't handle xmm or stmm registers...





More information about the lldb-commits mailing list