1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-29 02:07:39 +01:00

If UNW_REMOTE_ONLY is defined, make unw_init_local() a stub that

unconditionally returns -UNW_EINVAL.

(access_reg): IP is now read via UNW_IA64_IP (instead of
	UNW_IA64_BR+0).  CFM is now read via UNW_IA64_CFM
	instead of UNW_IA64_AR_PFS.  For UNW_IA64_AR_BSP
	(and UNW_IA64_AR_BSPSTORE), adjust the pointer so
	that it points to the first stacked register in
	the current frame.
(resume): "rp_loc" has been renamed to "ip_loc".
(unw_init_local): Add an #error directive to prevent compilation
	with UNW_LOCAL_ONLY until this case has been implemented.

(Logical change 1.5)
This commit is contained in:
(none)!davidm 2002-02-22 21:58:53 +00:00
parent 7c934e9308
commit 172cc2ba9b

View file

@ -26,7 +26,17 @@ License. */
#include "rse.h" #include "rse.h"
#include "unwind_i.h" #include "unwind_i.h"
#ifdef IA64_UNW_ACCESSORS #ifdef UNW_REMOTE_ONLY
int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
{
return -UNW_EINVAL;
}
#else /* !UNW_REMOTE_ONLY */
#ifndef UNW_LOCAL_ONLY
static int static int
access_mem (unw_word_t addr, unw_word_t *val, int write, void *arg) access_mem (unw_word_t addr, unw_word_t *val, int write, void *arg)
@ -48,12 +58,14 @@ static int
access_reg (unw_regnum_t reg, unw_word_t *val, int write, void *arg) access_reg (unw_regnum_t reg, unw_word_t *val, int write, void *arg)
{ {
ucontext_t *uc = arg; ucontext_t *uc = arg;
unw_word_t *addr, mask; unw_word_t *addr, mask, sol;
switch (reg) switch (reg)
{ {
case UNW_IA64_IP: addr = &uc->uc_mcontext.sc_br[0]; break;
case UNW_IA64_SP: addr = &uc->uc_mcontext.sc_gr[12]; break; case UNW_IA64_SP: addr = &uc->uc_mcontext.sc_gr[12]; break;
case UNW_IA64_AR_PFS: addr = &uc->uc_mcontext.sc_ar_pfs; break; case UNW_IA64_CFM: addr = &uc->uc_mcontext.sc_ar_pfs; break;
case UNW_IA64_AR_RNAT: addr = &uc->uc_mcontext.sc_ar_rnat; break; case UNW_IA64_AR_RNAT: addr = &uc->uc_mcontext.sc_ar_rnat; break;
case UNW_IA64_AR_UNAT: addr = &uc->uc_mcontext.sc_ar_unat; break; case UNW_IA64_AR_UNAT: addr = &uc->uc_mcontext.sc_ar_unat; break;
case UNW_IA64_AR_LC: addr = &uc->uc_mcontext.sc_ar_lc; break; case UNW_IA64_AR_LC: addr = &uc->uc_mcontext.sc_ar_lc; break;
@ -61,9 +73,25 @@ access_reg (unw_regnum_t reg, unw_word_t *val, int write, void *arg)
case UNW_IA64_PR: addr = &uc->uc_mcontext.sc_pr; break; case UNW_IA64_PR: addr = &uc->uc_mcontext.sc_pr; break;
case UNW_IA64_AR_BSP: case UNW_IA64_AR_BSP:
/* bsp and bspstore are equal after a flushrs: */ case UNW_IA64_AR_BSPSTORE:
addr = &uc->uc_mcontext.sc_ar_bsp; /* bsp and bspstore are equal after a flushrs. Account for the
break; fact that sc_ar_bsp points to *end* of register frame of the
initial call frame. */
if (write)
{
sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f;
uc->uc_mcontext.sc_ar_bsp = ia64_rse_skip_regs (*val, sol);
debug (100, "%s: %s <- %lx\n",
__FUNCTION__, _U_ia64_regname (reg), *val);
}
else
{
sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f;
*val = ia64_rse_skip_regs (uc->uc_mcontext.sc_ar_bsp, -sol);
debug (100, "%s: %s -> %lx\n",
__FUNCTION__, _U_ia64_regname (reg), *val);
}
return 0;
case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7:
addr = &uc->uc_mcontext.sc_gr[reg - UNW_IA64_GR]; addr = &uc->uc_mcontext.sc_gr[reg - UNW_IA64_GR];
@ -82,31 +110,34 @@ access_reg (unw_regnum_t reg, unw_word_t *val, int write, void *arg)
*val = (uc->uc_mcontext.sc_nat & mask) != 0; *val = (uc->uc_mcontext.sc_nat & mask) != 0;
if (write) if (write)
debug (100, "%s: %s <- %lx\n", __FUNCTION__, _U_ia64_regname(reg), debug (100, "%s: %s <- %lx\n", __FUNCTION__, _U_ia64_regname (reg),
*val); *val);
else else
debug (100, "%s: %s -> %lx\n", __FUNCTION__, _U_ia64_regname(reg), debug (100, "%s: %s -> %lx\n", __FUNCTION__, _U_ia64_regname (reg),
*val); *val);
return 0; return 0;
case UNW_IA64_BR + 0 ... UNW_IA64_BR + 5: case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5:
addr = &uc->uc_mcontext.sc_br[reg - UNW_IA64_BR]; addr = &uc->uc_mcontext.sc_br[reg - UNW_IA64_BR];
break; break;
default: default:
debug (1, "%s: bad register number %u\n", __FUNCTION__, reg); debug (1, "%s: bad register number %u\n", __FUNCTION__, reg);
return -1; /* attempt to access a non-preserved register */ /* attempt to access a non-preserved register */
return -UNW_EBADREG;
} }
if (write) if (write)
{ {
*(unw_word_t *) addr = *val; *(unw_word_t *) addr = *val;
debug (100, "%s: %s <- %lx\n", __FUNCTION__, _U_ia64_regname(reg), *val); debug (100, "%s: %s <- %lx\n",
__FUNCTION__, _U_ia64_regname (reg), *val);
} }
else else
{ {
*val = *(unw_word_t *) addr; *val = *(unw_word_t *) addr;
debug (100, "%s: %s -> %lx\n", __FUNCTION__, _U_ia64_regname(reg), *val); debug (100, "%s: %s -> %lx\n",
__FUNCTION__, _U_ia64_regname (reg), *val);
} }
return 0; return 0;
} }
@ -125,20 +156,21 @@ access_fpreg (unw_regnum_t reg, unw_fpreg_t *val, int write, void *arg)
default: default:
debug (1, "%s: bad register number %u\n", __FUNCTION__, reg); debug (1, "%s: bad register number %u\n", __FUNCTION__, reg);
return -1; /* attempt to access a non-preserved register */ /* attempt to access a non-preserved register */
return -UNW_EBADREG;
} }
if (write) if (write)
{ {
debug (100, "%s: %s <- %016lx.%016lx\n", __FUNCTION__, debug (100, "%s: %s <- %016lx.%016lx\n", __FUNCTION__,
_U_ia64_regname(reg), val->raw.bits[1], val->raw.bits[0]); _U_ia64_regname (reg), val->raw.bits[1], val->raw.bits[0]);
*(unw_fpreg_t *) addr = *val; *(unw_fpreg_t *) addr = *val;
} }
else else
{ {
*val = *(unw_fpreg_t *) addr; *val = *(unw_fpreg_t *) addr;
debug (100, "%s: %s -> %016lx.%016lx\n", __FUNCTION__, debug (100, "%s: %s -> %016lx.%016lx\n", __FUNCTION__,
_U_ia64_regname(reg), val->raw.bits[1], val->raw.bits[0]); _U_ia64_regname (reg), val->raw.bits[1], val->raw.bits[0]);
} }
return 0; return 0;
} }
@ -147,10 +179,9 @@ static int
resume (unw_cursor_t *cursor, void *arg) resume (unw_cursor_t *cursor, void *arg)
{ {
struct ia64_cursor *c = (struct ia64_cursor *) cursor; struct ia64_cursor *c = (struct ia64_cursor *) cursor;
unsigned long *bsp, sol;
unw_fpreg_t fpval; unw_fpreg_t fpval;
ucontext_t *uc = arg; ucontext_t *uc = arg;
unw_word_t val; unw_word_t val, sol;
int i, ret; int i, ret;
# define SET_NAT(n, r) \ # define SET_NAT(n, r) \
do \ do \
@ -183,7 +214,7 @@ resume (unw_cursor_t *cursor, void *arg)
while (0) while (0)
SET_REG (sc_ar_pfs, pfs_loc); SET_REG (sc_ar_pfs, pfs_loc);
SET_REG (sc_br[0], rp_loc); SET_REG (sc_br[0], ip_loc);
SET_REG (sc_pr, pr_loc); SET_REG (sc_pr, pr_loc);
SET_REG (sc_ar_rnat, rnat_loc); SET_REG (sc_ar_rnat, rnat_loc);
SET_REG (sc_ar_lc, lc_loc); SET_REG (sc_ar_lc, lc_loc);
@ -212,11 +243,9 @@ resume (unw_cursor_t *cursor, void *arg)
/* Account for the fact that __ia64_install_context() returns via /* Account for the fact that __ia64_install_context() returns via
br.ret, which will decrement bsp by size-of-locals. */ br.ret, which will decrement bsp by size-of-locals. */
bsp = (unsigned long *) c->bsp;
sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f; sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f;
bsp = ia64_rse_skip_regs (bsp, sol); uc->uc_mcontext.sc_ar_bsp = ia64_rse_skip_regs (c->bsp, sol);
uc->uc_mcontext.sc_ar_bsp = (unsigned long) bsp;
uc->uc_mcontext.sc_flags = 0; uc->uc_mcontext.sc_flags = 0;
uc->uc_mcontext.sc_gr[1] = c->pi.gp; uc->uc_mcontext.sc_gr[1] = c->pi.gp;
uc->uc_mcontext.sc_gr[12] = c->psp; uc->uc_mcontext.sc_gr[12] = c->psp;
@ -225,7 +254,7 @@ resume (unw_cursor_t *cursor, void *arg)
c->eh_args[3]); c->eh_args[3]);
} }
#endif /* IA64_UNW_ACCESSORS */ #endif /* !UNW_LOCAL_ONLY */
int int
unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
@ -240,24 +269,13 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
ia64_init (); ia64_init ();
} }
#ifdef IA64_UNW_ACCESSORS #ifdef UNW_LOCAL_ONLY
{
unw_accessors_t a;
a.arg = uc;
a.acquire_unwind_info = ia64_glibc_acquire_unwind_info;
a.release_unwind_info = ia64_glibc_release_unwind_info;
a.access_mem = access_mem;
a.access_reg = access_reg;
a.access_fpreg = access_fpreg;
a.resume = resume;
ret = ia64_init_remote (cursor, &a);
}
#else
{ {
struct ia64_cursor *c = (struct ia64_cursor *) cursor; struct ia64_cursor *c = (struct ia64_cursor *) cursor;
unw_word_t bsp, sol; unw_word_t bsp, sol;
# error this needs updating/testing
c->uc = uc; c->uc = uc;
/* What we do here is initialize the unwind cursor so unwinding /* What we do here is initialize the unwind cursor so unwinding
@ -267,13 +285,28 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
c->cfm_loc = &uc->uc_mcontext.sc_ar_pfs; c->cfm_loc = &uc->uc_mcontext.sc_ar_pfs;
bsp = uc->uc_mcontext.sc_ar_bsp; bsp = uc->uc_mcontext.sc_ar_bsp;
sol = (*c->cfm_loc >> 7) & 0x7f; sol = (*c->cfm_loc >> 7) & 0x7f;
c->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) bsp, -sol); c->bsp = ia64_rse_skip_regs (bsp, -sol);
c->ip = uc->uc_mcontext.sc_br[0]; c->ip = uc->uc_mcontext.sc_br[0];
c->pr = uc->uc_mcontext.sc_pr; c->pr = uc->uc_mcontext.sc_pr;
ret = ia64_find_save_locs (c); ret = ia64_find_save_locs (c);
} }
#endif #else /* !UNW_LOCAL_ONLY */
{
unw_accessors_t a;
a.arg = uc;
a.acquire_unwind_info = ia64_glibc_acquire_unwind_info;
a.release_unwind_info = ia64_glibc_release_unwind_info;
a.access_mem = access_mem;
a.access_reg = access_reg;
a.access_fpreg = access_fpreg;
a.resume = resume;
ret = unw_init_remote (cursor, &a);
}
#endif /* !UNW_LOCAL_ONLY */
STAT(unw.stat.api.init_time += ia64_get_itc() - start;) STAT(unw.stat.api.init_time += ia64_get_itc() - start;)
return ret; return ret;
} }
#endif /* !UNW_REMOTE_ONLY */