[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)®s, 0)) < 0) {
m_result = false;
} else {
- if (m_size == sizeof(uintptr_t))
- m_value = *(uintptr_t *)(((caddr_t)®s) + 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)®s) + m_offset);
+ else if (m_size == sizeof(uint64_t))
+ m_value = *(uint64_t *)(((caddr_t)®s) + m_offset);
+ else
memcpy(&m_value, (((caddr_t)®s) + 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