Index: lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp =================================================================== --- lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp +++ lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp @@ -1012,13 +1012,12 @@ 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"); Index: lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp =================================================================== --- lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp +++ lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp @@ -1013,13 +1013,12 @@ 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->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->SetCFARegister (sp_reg_num); + row->SetCFAType(lldb_private::UnwindPlan::Row::CFAIsRegisterDereferenced); + + 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"); Index: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -312,9 +312,14 @@ 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; } Index: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp +++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp @@ -123,8 +123,13 @@ } 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); } Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp @@ -153,7 +153,8 @@ 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 @@ 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; } Index: lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h +++ lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h @@ -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 @@ 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