This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Itanium unwind patch
- From: Richard Henderson <rth at redhat dot com>
- To: "Boehm, Hans" <hans_boehm at hp dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 28 Dec 2001 14:17:21 -0800
- Subject: Re: Itanium unwind patch
- References: <40700B4C02ABD5119F000090278766443BEE34@hplex1.hpl.hp.com>
On Fri, Dec 14, 2001 at 01:25:32PM -0800, Boehm, Hans wrote:
> Has anyone had a chance to look at
> http://gcc.gnu.org/ml/gcc-patches/2001-11/msg02039.html ?
I've edited it a bit and committed it.
I saw no reason for the #include linux.h hack. Examining the
preprocessor output, the header _was_ being included, just as
it ought to have been.
r~
* 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.
Index: linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/linux.h,v
retrieving revision 1.13
diff -c -p -d -r1.13 linux.h
*** linux.h 2001/12/15 11:46:52 1.13
--- linux.h 2001/12/28 22:10:00
***************
*** 60,63 ****
#undef LINK_EH_SPEC
#define LINK_EH_SPEC ""
! /* End of linux.h */
--- 60,122 ----
#undef LINK_EH_SPEC
#define LINK_EH_SPEC ""
! /* 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 <signal.h>
! #include <sys/ucontext.h>
!
! #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 */
Index: unwind-ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/unwind-ia64.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 unwind-ia64.c
*** unwind-ia64.c 2001/08/19 04:55:15 1.2
--- unwind-ia64.c 2001/12/28 22:10:00
***************
*** 36,44 ****
#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
--- 36,41 ----
*************** struct _Unwind_Context
*** 174,180 ****
unsigned long regstk_top; /* bsp for first frame */
/* Current frame info. */
! unsigned long bsp; /* backing store pointer value */
unsigned long sp; /* stack pointer value */
unsigned long psp; /* previous sp value */
unsigned long rp; /* return pointer */
--- 171,178 ----
unsigned long regstk_top; /* bsp for first frame */
/* Current frame info. */
! 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 */
*************** struct _Unwind_Context
*** 203,212 ****
enum unw_nat_type type : 3;
signed long off : 61; /* NaT word is at loc+nat.off */
} nat;
! } ireg[32 - 2];
unsigned long *br_loc[7];
void *fr_loc[32 - 2];
};
typedef unsigned long unw_word;
--- 201,214 ----
enum unw_nat_type type : 3;
signed long off : 61; /* NaT word is at loc+nat.off */
} nat;
! } ireg[32 - 2]; /* Indexed by <register number> - 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;
*************** unw_access_gr (struct _Unwind_Context *i
*** 1317,1323 ****
else if (regnum < 32)
{
/* Access a non-stacked register. */
! ireg = &info->ireg[regnum - 1];
addr = ireg->loc;
if (addr)
{
--- 1319,1325 ----
else if (regnum < 32)
{
/* Access a non-stacked register. */
! ireg = &info->ireg[regnum - 2];
addr = ireg->loc;
if (addr)
{
*************** uw_frame_state_for (struct _Unwind_Conte
*** 1468,1474 ****
{
/* Couldn't find unwind info for this function. Try an
os-specific fallback mechanism. This will necessarily
! not profide a personality routine or LSDA. */
#ifdef MD_FALLBACK_FRAME_STATE_FOR
MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
--- 1470,1476 ----
{
/* Couldn't find unwind info for this function. Try an
os-specific fallback mechanism. This will necessarily
! not provide a personality routine or LSDA. */
#ifdef MD_FALLBACK_FRAME_STATE_FOR
MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
*************** uw_update_context (struct _Unwind_Contex
*** 1727,1764 ****
}
/* Fill in CONTEXT for top-of-stack. The only valid registers at this
! level will be the return address and the CFA. */
! #define uw_init_context(CONTEXT) \
! uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), __builtin_ia64_bsp ())
static void
! uw_init_context_1 (struct _Unwind_Context *context, void *psp, void *bsp)
{
void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
! void *sp = __builtin_dwarf_cfa ();
_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->psp = (unsigned long) psp;
context->rp = (unsigned long) rp;
!
asm ("mov %0 = pr" : "=r" (context->pr));
/* ??? 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);
}
--- 1729,1768 ----
}
/* Fill in CONTEXT for top-of-stack. The only valid registers at this
! level will be the return address and the CFA. Note that CFA = SP+16. */
! #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 *bsp)
{
void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
! /* 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 = 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 ();
uw_update_context (context, &fs);
}
*************** uw_install_context (struct _Unwind_Conte
*** 1791,1798 ****
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);
/* Provide assembly with the offsets into the _Unwind_Context. */
asm volatile ("uc_rnat = %0"
--- 1795,1803 ----
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 = (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"