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>
* except.c: Fix comment formatting.
......
......@@ -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 <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 @@
#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 <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;
......@@ -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"
......
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