[Lldb-commits] [lldb] r221789 - Improve PowerPC unwind support

Justin Hibbits jrh29 at alumni.cwru.edu
Wed Nov 12 07:14:09 PST 2014


Author: jhibbits
Date: Wed Nov 12 09:14:08 2014
New Revision: 221789

URL: http://llvm.org/viewvc/llvm-project?rev=221789&view=rev
Log:
Improve PowerPC unwind support

Summary:
Taking advantage of the new 'CFAIsRegisterDereferenced' CFA register type, add
full stack unwind support to the PowerPC/PowerPC64 ABI.  Also, add a new
register set for powerpc32-on-64, so the register sizes are correct.  This also
requires modifying the ProcessMonitor to add support for non-uintptr_t-sized
register values.

Reviewers: jasonmolenda, emaste

Subscribers: emaste, lldb-commits

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

Modified:
    lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
    lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
    lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h

Modified: lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp?rev=221789&r1=221788&r2=221789&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp Wed Nov 12 09:14:08 2014
@@ -1012,13 +1012,12 @@ ABISysV_ppc::CreateDefaultUnwindPlan (Un
 
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
-    const int32_t ptr_size = 8;
-    row->SetCFARegister (LLDB_REGNUM_GENERIC_SP);
-    row->SetCFAOffset (8);
-    row->SetOffset (0);
+    const int32_t ptr_size = 4;
+    row->SetCFARegister (sp_reg_num);
+    row->SetCFAType(lldb_private::UnwindPlan::Row::CFAIsRegisterDereferenced);
 
-    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
-    row->SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * -2, true);
+    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 1, true);
+    row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
 
     unwind_plan.AppendRow (row);
     unwind_plan.SetSourceName ("ppc default unwind plan");

Modified: lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp?rev=221789&r1=221788&r2=221789&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp Wed Nov 12 09:14:08 2014
@@ -1013,13 +1013,12 @@ ABISysV_ppc64::CreateDefaultUnwindPlan (
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
     const int32_t ptr_size = 8;
-    row->SetCFARegister (LLDB_REGNUM_GENERIC_SP);
-    row->SetCFAOffset (48);
-    row->SetOffset (0);
+    row->SetCFARegister (sp_reg_num);
+    row->SetCFAType(lldb_private::UnwindPlan::Row::CFAIsRegisterDereferenced);
 
-    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -4, true);
-    row->SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * -6, true);
-    row->SetRegisterLocationToAtCFAPlusOffset(gcc_dwarf_cr, ptr_size * -5, true);
+    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true);
+    row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
+    row->SetRegisterLocationToAtCFAPlusOffset(gcc_dwarf_cr, ptr_size, true);
 
     unwind_plan.AppendRow (row);
     unwind_plan.SetSourceName ("ppc64 default unwind plan");

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=221789&r1=221788&r2=221789&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Wed Nov 12 09:14:08 2014
@@ -312,9 +312,14 @@ ReadRegOperation::Execute(ProcessMonitor
     if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
         m_result = false;
     } else {
-        if (m_size == sizeof(uintptr_t))
-            m_value = *(uintptr_t *)(((caddr_t)&regs) + m_offset);
-        else 
+        // 'struct reg' contains only 32- or 64-bit register values.  Punt on
+        // others.  Also, not all entries may be uintptr_t sized, such as 32-bit
+        // processes on powerpc64 (probably the same for i386 on amd64)
+        if (m_size == sizeof(uint32_t))
+            m_value = *(uint32_t *)(((caddr_t)&regs) + m_offset);
+        else if (m_size == sizeof(uint64_t))
+            m_value = *(uint64_t *)(((caddr_t)&regs) + m_offset);
+        else
             memcpy(&m_value, (((caddr_t)&regs) + m_offset), m_size);
         m_result = true;
     }

Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp?rev=221789&r1=221788&r2=221789&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp Wed Nov 12 09:14:08 2014
@@ -123,8 +123,13 @@ RegisterContextPOSIXProcessMonitor_power
     }
 
     ProcessMonitor &monitor = GetMonitor();
+    // Account for the fact that 32-bit targets on powerpc64 really use 64-bit
+    // registers in ptrace, but expose here 32-bit registers with a higher
+    // offset.
+    uint64_t offset = GetRegisterOffset(reg_to_write);
+    offset &= ~(sizeof(uintptr_t) - 1);
     return monitor.WriteRegisterValue(m_thread.GetID(),
-                                      GetRegisterOffset(reg_to_write),
+                                      offset,
                                       GetRegisterName(reg_to_write),
                                       value_to_write);
 }

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp?rev=221789&r1=221788&r2=221789&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp Wed Nov 12 09:14:08 2014
@@ -153,7 +153,8 @@ RegisterContextFreeBSD_powerpc::~Registe
 size_t
 RegisterContextFreeBSD_powerpc::GetGPRSize() const
 {
-    return sizeof(GPR64);
+    // This is an 'abstract' base, so no GPR struct.
+    return 0;
 }
 
 const RegisterInfo *
@@ -217,6 +218,8 @@ const RegisterInfo *
 RegisterContextFreeBSD_powerpc64::GetRegisterInfo() const
 {
     //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+    if (m_target_arch.GetMachine() == llvm::Triple::ppc)
+        return g_register_infos_powerpc64_32;
     return g_register_infos_powerpc64;
 }
 

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h?rev=221789&r1=221788&r2=221789&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h Wed Nov 12 09:14:08 2014
@@ -14,12 +14,14 @@
     (offsetof(GPR, regname))
 #define FPR_OFFSET(regname)                                                 \
     (offsetof(FPR, regname))
+#define GPR_SIZE(regname)                                                   \
+    (sizeof(((GPR*)NULL)->regname))
 
 #ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
 
 // Note that the size and offset will be updated by platform-specific classes.
 #define DEFINE_GPR(reg, alt, lldb_kind)           \
-    { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
+    { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
       eFormatHex, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, gpr_##reg##_powerpc }, NULL, NULL }
 #define DEFINE_FPR(reg, lldb_kind)           \
     { #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \
@@ -97,7 +99,6 @@
     DEFINE_FPR(f30,      LLDB_INVALID_REGNUM), \
     DEFINE_FPR(f31,      LLDB_INVALID_REGNUM), \
     { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL },
-    //{ NULL, NULL, sizeof(((GPR*)NULL)->r0), 0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_cfa_powerpc}, NULL, NULL}
 static RegisterInfo
 g_register_infos_powerpc64[] =
 {
@@ -113,10 +114,26 @@ g_register_infos_powerpc32[] =
     POWERPC_REGS
 #undef GPR
 };
+
+static RegisterInfo
+g_register_infos_powerpc64_32[] =
+{
+#define GPR GPR64
+#undef GPR_SIZE
+#define GPR_SIZE(reg)   (sizeof(uint32_t))
+#undef GPR_OFFSET
+#define GPR_OFFSET(regname)                                                 \
+    (offsetof(GPR, regname) + (sizeof(((GPR *)NULL)->regname) - GPR_SIZE(reg)))
+    POWERPC_REGS
+#undef GPR
+};
+
 static_assert((sizeof(g_register_infos_powerpc32) / sizeof(g_register_infos_powerpc32[0])) == k_num_registers_powerpc,
     "g_register_infos_powerpc32 has wrong number of register infos");
 static_assert((sizeof(g_register_infos_powerpc64) / sizeof(g_register_infos_powerpc64[0])) == k_num_registers_powerpc,
     "g_register_infos_powerpc64 has wrong number of register infos");
+static_assert(sizeof(g_register_infos_powerpc64_32) == sizeof(g_register_infos_powerpc64),
+    "g_register_infos_powerpc64_32 doesn't match size of g_register_infos_powerpc64");
 
 #undef DEFINE_FPR
 #undef DEFINE_GPR





More information about the lldb-commits mailing list