aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorHans Boehm <Hans_Boehm@hp.com>2001-12-28 14:15:41 -0800
committerRichard Henderson <rth@gcc.gnu.org>2001-12-28 14:15:41 -0800
commit4d9720f0c7f0f8fe29b036198c07750d0538b806 (patch)
tree8f8b1cf4bd5e6d0b98e28646d4e99653f59495d3 /gcc
parentbe3996918fa6ab11da8e1a9a78e2fa54af428f1a (diff)
downloadgcc-4d9720f0c7f0f8fe29b036198c07750d0538b806.zip
gcc-4d9720f0c7f0f8fe29b036198c07750d0538b806.tar.gz
gcc-4d9720f0c7f0f8fe29b036198c07750d0538b806.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/ia64/linux.h61
-rw-r--r--gcc/config/ia64/unwind-ia64.c49
3 files changed, 95 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 70fb073..c81563f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+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.
diff --git a/gcc/config/ia64/linux.h b/gcc/config/ia64/linux.h
index 91f2f39..61e80a4 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 <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 */
diff --git a/gcc/config/ia64/unwind-ia64.c b/gcc/config/ia64/unwind-ia64.c
index 052f839..045abe5 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 <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"