diff --git a/include/libunwind-ppc32.h b/include/libunwind-ppc32.h index 7fcdc385..b40a84ef 100644 --- a/include/libunwind-ppc32.h +++ b/include/libunwind-ppc32.h @@ -62,7 +62,7 @@ extern "C" { * round that up to 280. */ -#define UNW_TDEP_CURSOR_LEN 280 +#define UNW_TDEP_CURSOR_LEN 200 #if __WORDSIZE==32 typedef uint32_t unw_word_t; @@ -109,7 +109,22 @@ typedef enum UNW_PPC32_R30, UNW_PPC32_R31, /* called HARD_FRAME_POINTER in gcc */ - UNW_PPC32_F0 = 32, + /* Count Register */ + UNW_PPC32_CTR = 32, + /* Fixed-Point Status and Control Register */ + UNW_PPC32_XER = 33, + /* Condition Register */ + UNW_PPC32_CCR = 34, + /* Machine State Register */ + //UNW_PPC32_MSR = 35, + /* MQ or SPR0, not part of generic Power, part of MPC601 */ + //UNW_PPC32_MQ = 36, + /* Link Register */ + UNW_PPC32_LR = 36, + /* Floating Pointer Status and Control Register */ + UNW_PPC32_FPSCR = 37, + + UNW_PPC32_F0 = 48, UNW_PPC32_F1, UNW_PPC32_F2, UNW_PPC32_F3, @@ -142,43 +157,9 @@ typedef enum UNW_PPC32_F30, UNW_PPC32_F31, -/* Note that there doesn't appear to be an .eh_frame register column - for the FPSCR register. I don't know why this is. Since .eh_frame - info is what this implementation uses for unwinding, we have no way - to unwind this register, and so we will not expose an FPSCR register - number in the libunwind API. - */ + UNW_TDEP_LAST_REG = UNW_PPC32_F31, - UNW_PPC32_LR = 65, - UNW_PPC32_CTR = 66, - UNW_PPC32_ARG_POINTER = 67, - - UNW_PPC32_CR0 = 68, - UNW_PPC32_CR1, - UNW_PPC32_CR2, - UNW_PPC32_CR3, - UNW_PPC32_CR4, - - /* CR5 .. CR7 are currently unused */ - UNW_PPC32_CR5, - UNW_PPC32_CR6, - UNW_PPC32_CR7, - - UNW_PPC32_XER = 76, - - UNW_PPC32_VRSAVE = 109, - UNW_PPC32_VSCR = 110, - UNW_PPC32_SPE_ACC = 111, - UNW_PPC32_SPEFSCR = 112, - - /* frame info (read-only) */ - UNW_PPC32_FRAME_POINTER, - UNW_PPC32_NIP, - - - UNW_TDEP_LAST_REG = UNW_PPC32_NIP, - - UNW_TDEP_IP = UNW_PPC32_NIP, + UNW_TDEP_IP = UNW_PPC32_LR, UNW_TDEP_SP = UNW_PPC32_R1, UNW_TDEP_EH = UNW_PPC32_R12 } diff --git a/src/ppc32/Gglobal.c b/src/ppc32/Gglobal.c index 44be8bc4..c2d4604d 100644 --- a/src/ppc32/Gglobal.c +++ b/src/ppc32/Gglobal.c @@ -68,6 +68,12 @@ uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] = [UNW_PPC32_R30]=UNW_PPC32_R30, [UNW_PPC32_R31]=UNW_PPC32_R31, + [UNW_PPC32_CTR]=UNW_PPC32_CTR, + [UNW_PPC32_XER]=UNW_PPC32_XER, + [UNW_PPC32_CCR]=UNW_PPC32_CCR, + [UNW_PPC32_LR]=UNW_PPC32_LR, + [UNW_PPC32_FPSCR]=UNW_PPC32_FPSCR, + [UNW_PPC32_F0]=UNW_PPC32_F0, [UNW_PPC32_F1]=UNW_PPC32_F1, [UNW_PPC32_F2]=UNW_PPC32_F2, @@ -100,26 +106,7 @@ uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] = [UNW_PPC32_F29]=UNW_PPC32_F29, [UNW_PPC32_F30]=UNW_PPC32_F30, [UNW_PPC32_F31]=UNW_PPC32_F31, - - [UNW_PPC32_LR]=UNW_PPC32_LR, - [UNW_PPC32_CTR]=UNW_PPC32_CTR, - [UNW_PPC32_ARG_POINTER]=UNW_PPC32_ARG_POINTER, - - [UNW_PPC32_CR0]=UNW_PPC32_CR0, - [UNW_PPC32_CR1]=UNW_PPC32_CR1, - [UNW_PPC32_CR2]=UNW_PPC32_CR2, - [UNW_PPC32_CR3]=UNW_PPC32_CR3, - [UNW_PPC32_CR4]=UNW_PPC32_CR4, - [UNW_PPC32_CR5]=UNW_PPC32_CR5, - [UNW_PPC32_CR6]=UNW_PPC32_CR6, - [UNW_PPC32_CR7]=UNW_PPC32_CR7, - - [UNW_PPC32_XER]=UNW_PPC32_XER, - [UNW_PPC32_VRSAVE]=UNW_PPC32_VRSAVE, - [UNW_PPC32_VSCR]=UNW_PPC32_VSCR, - [UNW_PPC32_SPE_ACC]=UNW_PPC32_SPE_ACC, - [UNW_PPC32_SPEFSCR]=UNW_PPC32_SPEFSCR, - }; +}; HIDDEN void tdep_init (void) diff --git a/src/ppc32/Ginit.c b/src/ppc32/Ginit.c index 00d97a2f..47c66f11 100644 --- a/src/ppc32/Ginit.c +++ b/src/ppc32/Ginit.c @@ -55,7 +55,9 @@ uc_addr (ucontext_t *uc, int reg) if ((unsigned) (reg - UNW_PPC32_R0) < 32) addr = &uc->uc_mcontext.uc_regs->gregs[reg - UNW_PPC32_R0]; - else if ((unsigned) (reg - UNW_PPC32_F0) < 32) + else + if ( ((unsigned) (reg - UNW_PPC32_F0) < 32) && + ((unsigned) (reg - UNW_PPC32_F0) >= 0) ) addr = &uc->uc_mcontext.uc_regs->fpregs.fpregs[reg - UNW_PPC32_F0]; else @@ -64,9 +66,6 @@ uc_addr (ucontext_t *uc, int reg) switch (reg) { - case UNW_PPC32_NIP: - gregs_idx = NIP_IDX; - break; case UNW_PPC32_CTR: gregs_idx = CTR_IDX; break; @@ -76,7 +75,7 @@ uc_addr (ucontext_t *uc, int reg) case UNW_PPC32_XER: gregs_idx = XER_IDX; break; - case UNW_PPC32_CR0: + case UNW_PPC32_CCR: gregs_idx = CCR_IDX; break; default: @@ -138,7 +137,8 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, unw_word_t *addr; ucontext_t *uc = arg; - if ((unsigned int) (reg - UNW_PPC32_F0) < 32) + if ( ((unsigned int) (reg - UNW_PPC32_F0) < 32) && + ((unsigned int) (reg - UNW_PPC32_F0) >= 0)) goto badreg; addr = uc_addr (uc, reg); diff --git a/src/ppc32/Gstep.c b/src/ppc32/Gstep.c index a5afe0ab..d146e82d 100644 --- a/src/ppc32/Gstep.c +++ b/src/ppc32/Gstep.c @@ -44,7 +44,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ typedef struct { long unsigned back_chain; - long unsigned cr_save; long unsigned lr_save; /* many more fields here, but they are unused by this code */ } stack_frame_t; @@ -55,8 +54,8 @@ unw_step (unw_cursor_t * cursor) { struct cursor *c = (struct cursor *) cursor; stack_frame_t dummy; - unw_word_t back_chain_offset, lr_save_offset, v_regs_ptr; - struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc, v_regs_loc; + unw_word_t back_chain_offset, lr_save_offset; + struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc; int ret; Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); @@ -141,7 +140,7 @@ unw_step (unw_cursor_t * cursor) c->sigcontext_addr = ucontext; sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); - ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); + ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa); if (ret < 0) @@ -229,21 +228,14 @@ unw_step (unw_cursor_t * cursor) DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); c->dwarf.loc[UNW_PPC32_CTR] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0); + /* This CR0 assignment is probably wrong. There are 8 dwarf columns assigned to the CR registers, but only one CR register in the mcontext structure */ - c->dwarf.loc[UNW_PPC32_CR0] = + c->dwarf.loc[UNW_PPC32_CCR] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0); c->dwarf.loc[UNW_PPC32_XER] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0); - c->dwarf.loc[UNW_PPC32_NIP] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); - - /* TODO: Is there a way of obtaining the value of the - pseudo frame pointer (which is sp + some fixed offset, I - assume), based on the contents of the ucontext record - structure? For now, set this loc to null. */ - c->dwarf.loc[UNW_PPC32_FRAME_POINTER] = DWARF_NULL_LOC; c->dwarf.loc[UNW_PPC32_F0] = DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0); diff --git a/src/ppc32/init.h b/src/ppc32/init.h index 7d9221ee..8badb178 100644 --- a/src/ppc32/init.h +++ b/src/ppc32/init.h @@ -42,22 +42,13 @@ common_init_ppc32 (struct cursor *c) c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i); } - for (i = UNW_PPC32_CR0; i <= UNW_PPC32_CR7; i++) { - c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); - } - c->dwarf.loc[UNW_PPC32_ARG_POINTER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_ARG_POINTER); c->dwarf.loc[UNW_PPC32_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CTR); - c->dwarf.loc[UNW_PPC32_VSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_VSCR); - c->dwarf.loc[UNW_PPC32_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_XER); + c->dwarf.loc[UNW_PPC32_CCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CCR); c->dwarf.loc[UNW_PPC32_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_LR); - c->dwarf.loc[UNW_PPC32_VRSAVE] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_VRSAVE); - c->dwarf.loc[UNW_PPC32_SPEFSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_SPEFSCR); - c->dwarf.loc[UNW_PPC32_SPE_ACC] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_SPE_ACC); + c->dwarf.loc[UNW_PPC32_FPSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_FPSCR); - c->dwarf.loc[UNW_PPC32_NIP] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_NIP); - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC32_NIP], &c->dwarf.ip); + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC32_LR], &c->dwarf.ip); if (ret < 0) return ret; diff --git a/src/ppc32/regname.c b/src/ppc32/regname.c index d897a562..79ba88aa 100644 --- a/src/ppc32/regname.c +++ b/src/ppc32/regname.c @@ -62,6 +62,12 @@ static const char *regname[] = [UNW_PPC32_R30]="GPR30", [UNW_PPC32_R31]="GPR31", + [UNW_PPC32_CTR]="CTR", + [UNW_PPC32_XER]="XER", + [UNW_PPC32_CCR]="CCR", + [UNW_PPC32_LR]="LR", + [UNW_PPC32_FPSCR]="FPSCR", + [UNW_PPC32_F0]="FPR0", [UNW_PPC32_F1]="FPR1", [UNW_PPC32_F2]="FPR2", @@ -93,30 +99,8 @@ static const char *regname[] = [UNW_PPC32_F28]="FPR28", [UNW_PPC32_F29]="FPR29", [UNW_PPC32_F30]="FPR30", - [UNW_PPC32_F31]="FPR31", - - [UNW_PPC32_LR]="LR", - [UNW_PPC32_CTR]="CTR", - [UNW_PPC32_ARG_POINTER]="ARG_POINTER", - - [UNW_PPC32_CR0]="CR0", - [UNW_PPC32_CR1]="CR1", - [UNW_PPC32_CR2]="CR2", - [UNW_PPC32_CR3]="CR3", - [UNW_PPC32_CR4]="CR4", - [UNW_PPC32_CR5]="CR5", - [UNW_PPC32_CR6]="CR6", - [UNW_PPC32_CR7]="CR7", - - [UNW_PPC32_XER]="XER", - - [UNW_PPC32_VSCR]="VSCR", - - [UNW_PPC32_VRSAVE]="VRSAVE", - [UNW_PPC32_SPE_ACC]="SPE_ACC", - [UNW_PPC32_SPEFSCR]="SPEFSCR", - - }; + [UNW_PPC32_F31]="FPR31" +}; PROTECTED const char * unw_regname (unw_regnum_t reg) diff --git a/src/ppc32/ucontext_i.h b/src/ppc32/ucontext_i.h index c4cfe0fc..52c3dc7e 100644 --- a/src/ppc32/ucontext_i.h +++ b/src/ppc32/ucontext_i.h @@ -33,21 +33,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h */ -#define NIP_IDX 32 -#define MSR_IDX 33 -#define ORIG_GPR3_IDX 34 -#define CTR_IDX 35 +//#define NIP_IDX 32 +#define CTR_IDX 32 +#define XER_IDX 33 +#define CCR_IDX 34 +#define MSR_IDX 35 +//#define MQ_IDX 36 #define LINK_IDX 36 -#define XER_IDX 37 -#define CCR_IDX 38 -#define SOFTE_IDX 39 -#define TRAP_IDX 40 -#define DAR_IDX 41 -#define DSISR_IDX 42 -#define RESULT_IDX 43 - -#define VSCR_IDX 32 -#define VRSAVE_IDX 33 /* These are dummy structures used only for obtaining the offsets of the various structure members. */ @@ -86,7 +78,7 @@ static vrregset_t dmy_vrregset; #define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[29] - (void *)&dmy_ctxt) #define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[30] - (void *)&dmy_ctxt) #define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[31] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_NIP ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[NIP_IDX] - (void *)&dmy_ctxt) + #define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[MSR_IDX] - (void *)&dmy_ctxt) #define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt) #define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CTR_IDX] - (void *)&dmy_ctxt) @@ -133,41 +125,4 @@ static vrregset_t dmy_vrregset; #define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[31] - (void *)&dmy_ctxt) #define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[32] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_V_REGS ((void *)&dmy_ctxt.uc_mcontext.v_regs - (void *)&dmy_ctxt) - -#define UC_MCONTEXT_VREGS_R0 ((void *)&dmy_vrregset.vrregs[0] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R1 ((void *)&dmy_vrregset.vrregs[1] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R2 ((void *)&dmy_vrregset.vrregs[2] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R3 ((void *)&dmy_vrregset.vrregs[3] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R4 ((void *)&dmy_vrregset.vrregs[4] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R5 ((void *)&dmy_vrregset.vrregs[5] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R6 ((void *)&dmy_vrregset.vrregs[6] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R7 ((void *)&dmy_vrregset.vrregs[7] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R8 ((void *)&dmy_vrregset.vrregs[8] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R9 ((void *)&dmy_vrregset.vrregs[9] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R10 ((void *)&dmy_vrregset.vrregs[10] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R11 ((void *)&dmy_vrregset.vrregs[11] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R12 ((void *)&dmy_vrregset.vrregs[12] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R13 ((void *)&dmy_vrregset.vrregs[13] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R14 ((void *)&dmy_vrregset.vrregs[14] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R15 ((void *)&dmy_vrregset.vrregs[15] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R16 ((void *)&dmy_vrregset.vrregs[16] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R17 ((void *)&dmy_vrregset.vrregs[17] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R18 ((void *)&dmy_vrregset.vrregs[18] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R19 ((void *)&dmy_vrregset.vrregs[19] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R20 ((void *)&dmy_vrregset.vrregs[20] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R21 ((void *)&dmy_vrregset.vrregs[21] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R22 ((void *)&dmy_vrregset.vrregs[22] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R23 ((void *)&dmy_vrregset.vrregs[23] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R24 ((void *)&dmy_vrregset.vrregs[24] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R25 ((void *)&dmy_vrregset.vrregs[25] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R26 ((void *)&dmy_vrregset.vrregs[26] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R27 ((void *)&dmy_vrregset.vrregs[27] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R28 ((void *)&dmy_vrregset.vrregs[28] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R29 ((void *)&dmy_vrregset.vrregs[29] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R30 ((void *)&dmy_vrregset.vrregs[30] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R31 ((void *)&dmy_vrregset.vrregs[31] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_VSCR ((void *)&dmy_vrregset.vscr - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_VRSAVE ((void *)&dmy_vrregset.vrsave - (void *)&dmy_vrregset) - #endif