Commit 4d9720f0 by Hans Boehm Committed by Richard Henderson

linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.

        * 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.

From-SVN: r48352
parent be399691
2001-12-28 Hans Bohem <hans_boehm@hp.com>
* 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 <kazu@hxi.com> 2001-12-28 Kazu Hirata <kazu@hxi.com>
* except.c: Fix comment formatting. * except.c: Fix comment formatting.
......
...@@ -60,4 +60,63 @@ ...@@ -60,4 +60,63 @@
#undef LINK_EH_SPEC #undef LINK_EH_SPEC
#define 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 <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 */
...@@ -36,9 +36,6 @@ ...@@ -36,9 +36,6 @@
#include "unwind-ia64.h" #include "unwind-ia64.h"
#if !USING_SJLJ_EXCEPTIONS #if !USING_SJLJ_EXCEPTIONS
#define inline
#define UNW_VER(x) ((x) >> 48) #define UNW_VER(x) ((x) >> 48)
#define UNW_FLAG_MASK 0x0000ffff00000000 #define UNW_FLAG_MASK 0x0000ffff00000000
#define UNW_FLAG_OSMASK 0x0000f00000000000 #define UNW_FLAG_OSMASK 0x0000f00000000000
...@@ -174,7 +171,8 @@ struct _Unwind_Context ...@@ -174,7 +171,8 @@ struct _Unwind_Context
unsigned long regstk_top; /* bsp for first frame */ unsigned long regstk_top; /* bsp for first frame */
/* Current frame info. */ /* 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 sp; /* stack pointer value */
unsigned long psp; /* previous sp value */ unsigned long psp; /* previous sp value */
unsigned long rp; /* return pointer */ unsigned long rp; /* return pointer */
...@@ -203,10 +201,14 @@ struct _Unwind_Context ...@@ -203,10 +201,14 @@ struct _Unwind_Context
enum unw_nat_type type : 3; enum unw_nat_type type : 3;
signed long off : 61; /* NaT word is at loc+nat.off */ signed long off : 61; /* NaT word is at loc+nat.off */
} nat; } nat;
} ireg[32 - 2]; } ireg[32 - 2]; /* Indexed by <register number> - 2 */
unsigned long *br_loc[7]; unsigned long *br_loc[7];
void *fr_loc[32 - 2]; 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; typedef unsigned long unw_word;
...@@ -1317,7 +1319,7 @@ unw_access_gr (struct _Unwind_Context *info, int regnum, ...@@ -1317,7 +1319,7 @@ unw_access_gr (struct _Unwind_Context *info, int regnum,
else if (regnum < 32) else if (regnum < 32)
{ {
/* Access a non-stacked register. */ /* Access a non-stacked register. */
ireg = &info->ireg[regnum - 1]; ireg = &info->ireg[regnum - 2];
addr = ireg->loc; addr = ireg->loc;
if (addr) if (addr)
{ {
...@@ -1468,7 +1470,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) ...@@ -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 /* Couldn't find unwind info for this function. Try an
os-specific fallback mechanism. This will necessarily 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 #ifdef MD_FALLBACK_FRAME_STATE_FOR
MD_FALLBACK_FRAME_STATE_FOR (context, fs, success); MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
...@@ -1727,38 +1729,40 @@ uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) ...@@ -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 /* 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) \ #define uw_init_context(CONTEXT) \
uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), __builtin_ia64_bsp ()) 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 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 *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; _Unwind_FrameState fs;
/* Flush the register stack to memory so that we can access it. */ /* Flush the register stack to memory so that we can access it. */
__builtin_ia64_flushrs (); __builtin_ia64_flushrs ();
memset (context, 0, sizeof (struct _Unwind_Context)); memset (context, 0, sizeof (struct _Unwind_Context));
context->bsp = (unsigned long) bsp; context->bsp = context->regstk_top = (unsigned long) bsp;
context->sp = (unsigned long) sp;
context->psp = (unsigned long) psp; context->psp = (unsigned long) psp;
context->rp = (unsigned long) rp; context->rp = (unsigned long) rp;
asm ("mov %0 = sp" : "=r" (context->sp));
asm ("mov %0 = pr" : "=r" (context->pr)); 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? */ /* ??? Get rnat. Don't we have to turn off the rse for that? */
if (uw_frame_state_for (context, &fs) != _URC_NO_REASON) if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
abort (); 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); uw_update_context (context, &fs);
} }
...@@ -1791,8 +1795,9 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)), ...@@ -1791,8 +1795,9 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
target function. The value that we install below will be target function. The value that we install below will be
adjusted by the BR.RET instruction based on the contents adjusted by the BR.RET instruction based on the contents
of AR.PFS. So we must unadjust that here. */ of AR.PFS. So we must unadjust that here. */
target->bsp target->bsp = (unsigned long)
= ia64_rse_skip_regs (target->bsp, (*target->pfs_loc >> 7) & 0x7f); ia64_rse_skip_regs ((unsigned long *)target->bsp,
(*target->pfs_loc >> 7) & 0x7f);
/* Provide assembly with the offsets into the _Unwind_Context. */ /* Provide assembly with the offsets into the _Unwind_Context. */
asm volatile ("uc_rnat = %0" asm volatile ("uc_rnat = %0"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment