1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-22 07:37:38 +01:00

[PPC32] Make PPC32 unwinding work for real.

This commit is contained in:
Jose Flavio Aguilar Paulino 2007-10-08 12:33:18 -06:00 committed by David Mosberger-Tang
parent 57e5696463
commit 9ea6af8ed5
7 changed files with 55 additions and 165 deletions

View file

@ -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
}

View file

@ -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)

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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)

View file

@ -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