[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