From cf122306fbc5b8e9fe025a2433af6fb1d4940613 Mon Sep 17 00:00:00 2001 From: rth Date: Fri, 28 Dec 2001 22:15:41 +0000 Subject: [PATCH] * config/ia64/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New. * config/ia64/unwind-ia64.c (uw_init_context_1): Redo sp, psp, bsp setup. Set pri_unat_loc to something reasonable. (uw_install_context): Add missing cast. (unw_access_gr): Fix off-by-1 indexing error. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@48352 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++ gcc/config/ia64/linux.h | 61 ++++++++++++++++++++++++++++++++++++++++++- gcc/config/ia64/unwind-ia64.c | 49 ++++++++++++++++++---------------- 3 files changed, 95 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 70fb073130e4..c81563f79ec5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2001-12-28 Hans Bohem + + * config/ia64/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New. + * config/ia64/unwind-ia64.c (uw_init_context_1): Redo sp, psp, + bsp setup. Set pri_unat_loc to something reasonable. + (uw_install_context): Add missing cast. + (unw_access_gr): Fix off-by-1 indexing error. + 2001-12-28 Kazu Hirata * except.c: Fix comment formatting. diff --git a/gcc/config/ia64/linux.h b/gcc/config/ia64/linux.h index 91f2f39d8457..61e80a4a0396 100644 --- a/gcc/config/ia64/linux.h +++ b/gcc/config/ia64/linux.h @@ -60,4 +60,63 @@ #undef LINK_EH_SPEC #define LINK_EH_SPEC "" -/* End of linux.h */ +/* Do code reading to identify a signal frame, and set the frame + state data appropriately. See unwind-dw2.c for the structs. */ + +#ifdef IN_LIBGCC2 +#include +#include + +#define IA64_GATE_AREA_START 0xa000000000000100LL +#define IA64_GATE_AREA_END 0xa000000000010000LL + +#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ + if ((CONTEXT)->rp >= IA64_GATE_AREA_START \ + && (CONTEXT)->rp < IA64_GATE_AREA_END) \ + { \ + struct sigframe { \ + char scratch[16]; \ + unsigned long sig_number; \ + struct siginfo *info; \ + struct sigcontext *sc; \ + } *frame_ = (struct sigframe *)(CONTEXT)->psp; \ + struct sigcontext *sc_ = frame_->sc; \ + \ + /* Restore scratch registers in case the unwinder needs to \ + refer to a value stored in one of them. */ \ + { \ + int i_; \ + \ + for (i_ = 2; i_ < 4; i_++) \ + (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \ + for (i_ = 8; i_ < 12; i_++) \ + (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \ + for (i_ = 14; i_ < 32; i_++) \ + (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \ + } \ + \ + (CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \ + (CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \ + (CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \ + (CONTEXT)->pr = sc_->sc_pr; \ + (CONTEXT)->psp = sc_->sc_gr[12]; \ + \ + /* Don't touch the branch registers. The kernel doesn't \ + pass the preserved branch registers in the sigcontext but \ + leaves them intact, so there's no need to do anything \ + with them here. */ \ + \ + { \ + unsigned long sof = sc_->sc_cfm & 0x7f; \ + (CONTEXT)->bsp = (unsigned long) \ + ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \ + } \ + \ + (FS)->curr.reg[UNW_REG_RP].where = UNW_WHERE_SPREL; \ + (FS)->curr.reg[UNW_REG_RP].val \ + = (unsigned long)&(sc_->sc_ip) - (CONTEXT)->psp; \ + (FS)->curr.reg[UNW_REG_RP].when = -1; \ + \ + goto SUCCESS; \ + } +#endif /* IN_LIBGCC2 */ diff --git a/gcc/config/ia64/unwind-ia64.c b/gcc/config/ia64/unwind-ia64.c index 052f83948392..045abe5b7f60 100644 --- a/gcc/config/ia64/unwind-ia64.c +++ b/gcc/config/ia64/unwind-ia64.c @@ -36,9 +36,6 @@ #include "unwind-ia64.h" #if !USING_SJLJ_EXCEPTIONS - -#define inline - #define UNW_VER(x) ((x) >> 48) #define UNW_FLAG_MASK 0x0000ffff00000000 #define UNW_FLAG_OSMASK 0x0000f00000000000 @@ -174,7 +171,8 @@ struct _Unwind_Context unsigned long regstk_top; /* bsp for first frame */ /* Current frame info. */ - unsigned long bsp; /* backing store pointer value */ + unsigned long bsp; /* backing store pointer value + corresponding to psp. */ unsigned long sp; /* stack pointer value */ unsigned long psp; /* previous sp value */ unsigned long rp; /* return pointer */ @@ -203,10 +201,14 @@ struct _Unwind_Context enum unw_nat_type type : 3; signed long off : 61; /* NaT word is at loc+nat.off */ } nat; - } ireg[32 - 2]; + } ireg[32 - 2]; /* Indexed by - 2 */ unsigned long *br_loc[7]; void *fr_loc[32 - 2]; + + /* ??? We initially point pri_unat_loc here. The entire NAT bit + logic needs work. */ + unsigned long initial_unat; }; typedef unsigned long unw_word; @@ -1317,7 +1319,7 @@ unw_access_gr (struct _Unwind_Context *info, int regnum, else if (regnum < 32) { /* Access a non-stacked register. */ - ireg = &info->ireg[regnum - 1]; + ireg = &info->ireg[regnum - 2]; addr = ireg->loc; if (addr) { @@ -1468,7 +1470,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) { /* Couldn't find unwind info for this function. Try an os-specific fallback mechanism. This will necessarily - not profide a personality routine or LSDA. */ + not provide a personality routine or LSDA. */ #ifdef MD_FALLBACK_FRAME_STATE_FOR MD_FALLBACK_FRAME_STATE_FOR (context, fs, success); @@ -1727,38 +1729,40 @@ uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) } /* Fill in CONTEXT for top-of-stack. The only valid registers at this - level will be the return address and the CFA. */ + level will be the return address and the CFA. Note that CFA = SP+16. */ -#define uw_init_context(CONTEXT) \ - uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), __builtin_ia64_bsp ()) +#define uw_init_context(CONTEXT) \ + do { \ + /* ??? There is a whole lot o code in uw_install_context that \ + tries to avoid spilling the entire machine state here. We \ + should try to make that work again. */ \ + __builtin_unwind_init(); \ + uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \ + } while (0) static void -uw_init_context_1 (struct _Unwind_Context *context, void *psp, void *bsp) +uw_init_context_1 (struct _Unwind_Context *context, void *bsp) { void *rp = __builtin_extract_return_addr (__builtin_return_address (0)); - void *sp = __builtin_dwarf_cfa (); + /* Set psp to the caller's stack pointer. */ + void *psp = __builtin_dwarf_cfa () - 16; _Unwind_FrameState fs; /* Flush the register stack to memory so that we can access it. */ __builtin_ia64_flushrs (); memset (context, 0, sizeof (struct _Unwind_Context)); - context->bsp = (unsigned long) bsp; - context->sp = (unsigned long) sp; + context->bsp = context->regstk_top = (unsigned long) bsp; context->psp = (unsigned long) psp; context->rp = (unsigned long) rp; - + asm ("mov %0 = sp" : "=r" (context->sp)); asm ("mov %0 = pr" : "=r" (context->pr)); + context->pri_unat_loc = &context->initial_unat; /* ??? */ /* ??? Get rnat. Don't we have to turn off the rse for that? */ if (uw_frame_state_for (context, &fs) != _URC_NO_REASON) abort (); - /* Force the frame state to use the known cfa value. */ - fs.curr.reg[UNW_REG_PSP].when = -1; - fs.curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE; - fs.curr.reg[UNW_REG_PSP].val = sp - psp; - uw_update_context (context, &fs); } @@ -1791,8 +1795,9 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)), target function. The value that we install below will be adjusted by the BR.RET instruction based on the contents of AR.PFS. So we must unadjust that here. */ - target->bsp - = ia64_rse_skip_regs (target->bsp, (*target->pfs_loc >> 7) & 0x7f); + target->bsp = (unsigned long) + ia64_rse_skip_regs ((unsigned long *)target->bsp, + (*target->pfs_loc >> 7) & 0x7f); /* Provide assembly with the offsets into the _Unwind_Context. */ asm volatile ("uc_rnat = %0" -- 2.11.4.GIT