Index: source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp =================================================================== --- source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp +++ source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp @@ -1012,13 +1012,14 @@ UnwindPlan::RowSP row(new UnwindPlan::Row); - const int32_t ptr_size = 8; - row->SetCFARegister (LLDB_REGNUM_GENERIC_SP); - row->SetCFAOffset (8); + const int32_t ptr_size = 4; + row->SetCFARegister (sp_reg_num); + row->SetCFAOffset (0); row->SetOffset (0); + 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: source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp =================================================================== --- source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp +++ source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp @@ -1013,13 +1013,13 @@ UnwindPlan::RowSP row(new UnwindPlan::Row); const int32_t ptr_size = 8; - row->SetCFARegister (LLDB_REGNUM_GENERIC_SP); - row->SetCFAOffset (48); + row->SetCFARegister (sp_reg_num); row->SetOffset (0); + 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"); Index: source/Plugins/Process/FreeBSD/ProcessMonitor.cpp =================================================================== --- source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -312,9 +312,16 @@ if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)®s, 0)) < 0) { m_result = false; } 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(uintptr_t)) m_value = *(uintptr_t *)(((caddr_t)®s) + m_offset); - else + else 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: source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp =================================================================== --- source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp +++ 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: source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp =================================================================== --- source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp +++ source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp @@ -56,6 +56,86 @@ uint64_t pc; } GPR64; +typedef struct _GPR32_on_64 +{ + uint32_t unused0; + uint32_t r0; + uint32_t unused1; + uint32_t r1; + uint32_t unused2; + uint32_t r2; + uint32_t unused3; + uint32_t r3; + uint32_t unused4; + uint32_t r4; + uint32_t unused5; + uint32_t r5; + uint32_t unused6; + uint32_t r6; + uint32_t unused7; + uint32_t r7; + uint32_t unused8; + uint32_t r8; + uint32_t unused9; + uint32_t r9; + uint32_t unused10; + uint32_t r10; + uint32_t unused11; + uint32_t r11; + uint32_t unused12; + uint32_t r12; + uint32_t unused13; + uint32_t r13; + uint32_t unused14; + uint32_t r14; + uint32_t unused15; + uint32_t r15; + uint32_t unused16; + uint32_t r16; + uint32_t unused17; + uint32_t r17; + uint32_t unused18; + uint32_t r18; + uint32_t unused19; + uint32_t r19; + uint32_t unused20; + uint32_t r20; + uint32_t unused21; + uint32_t r21; + uint32_t unused22; + uint32_t r22; + uint32_t unused23; + uint32_t r23; + uint32_t unused24; + uint32_t r24; + uint32_t unused25; + uint32_t r25; + uint32_t unused26; + uint32_t r26; + uint32_t unused27; + uint32_t r27; + uint32_t unused28; + uint32_t r28; + uint32_t unused29; + uint32_t r29; + uint32_t unused30; + uint32_t r30; + uint32_t unused31; + uint32_t r31; + uint32_t unused32; + uint32_t lr; + uint32_t unused33; + uint32_t cr; + uint32_t unused34; + uint32_t xer; + uint32_t unused35; + uint32_t ctr; + uint32_t unused36; + uint32_t pc; +} GPR32_on_64; + +static_assert(sizeof(GPR32_on_64) == sizeof(GPR64), "Size mismatch"); + typedef struct _GPR32 { uint32_t r0; @@ -153,7 +233,7 @@ size_t RegisterContextFreeBSD_powerpc::GetGPRSize() const { - return sizeof(GPR64); + return 0; } const RegisterInfo * @@ -217,6 +297,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: source/Plugins/Process/Utility/RegisterInfos_powerpc.h =================================================================== --- source/Plugins/Process/Utility/RegisterInfos_powerpc.h +++ source/Plugins/Process/Utility/RegisterInfos_powerpc.h @@ -97,7 +97,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[] = { @@ -107,6 +106,14 @@ }; static RegisterInfo +g_register_infos_powerpc64_32[] = +{ +#define GPR GPR32_on_64 + POWERPC_REGS +#undef GPR +}; + +static RegisterInfo g_register_infos_powerpc32[] = { #define GPR GPR32 @@ -117,6 +124,8 @@ "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