mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-12-25 04:23:42 +01:00
Initial revision
This commit is contained in:
parent
b4a52cc9cc
commit
6e5840f132
3 changed files with 0 additions and 572 deletions
|
@ -1,256 +0,0 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2003 Hewlett-Packard Co
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of libunwind.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
/* Logically, we like to think of the stack as a contiguous region of
|
||||
memory. Unfortunately, this logical view doesn't work for the
|
||||
register backing store, because the RSE is an asynchronous engine and
|
||||
because UNIX/Linux allow for stack-switching via sigaltstack(2).
|
||||
Specifically, this means that any given stacked register may or may
|
||||
not be backed up by memory in the current stack. If not, then the
|
||||
backing memory may be found in any of the "more inner" (younger)
|
||||
stacks. The routines in this file help manage the discontiguous
|
||||
nature of the register backing store. The routines are completely
|
||||
independent of UNIX/Linux, but each stack frame that switches the
|
||||
backing store is expected to reserve 4 words for use by libunwind. For
|
||||
example, in the Linux sigcontext, sc_fr[0] and sc_fr[1] serve this
|
||||
purpose. */
|
||||
|
||||
#include "unwind_i.h"
|
||||
|
||||
HIDDEN int
|
||||
rbs_switch (struct cursor *c,
|
||||
unw_word_t saved_bsp, unw_word_t saved_bspstore,
|
||||
ia64_loc_t saved_rnat_loc)
|
||||
{
|
||||
struct rbs_area *rbs = &c->rbs_area[c->rbs_curr];
|
||||
unw_word_t lo, ndirty;
|
||||
|
||||
debug (10, "%s: (left=%u, curr=%u)\n\t",
|
||||
__FUNCTION__, c->rbs_left_edge, c->rbs_curr);
|
||||
|
||||
/* Calculate address "lo" at which the backing store starts: */
|
||||
ndirty = ia64_rse_num_regs (saved_bspstore, saved_bsp);
|
||||
lo = ia64_rse_skip_regs (c->bsp, -ndirty);
|
||||
|
||||
rbs->size = (rbs->end - lo);
|
||||
|
||||
/* If the previously-recorded rbs-area is empty we don't need to
|
||||
track it and we can simply overwrite it... */
|
||||
if (rbs->size)
|
||||
{
|
||||
debug (10, "inner=[0x%lx-0x%lx)\n\t",
|
||||
(long) (rbs->end - rbs->size), (long) rbs->end);
|
||||
|
||||
c->rbs_curr = (c->rbs_curr + 1) % NELEMS (c->rbs_area);
|
||||
rbs = c->rbs_area + c->rbs_curr;
|
||||
|
||||
if (c->rbs_curr == c->rbs_left_edge)
|
||||
c->rbs_left_edge = (c->rbs_left_edge + 1) % NELEMS (c->rbs_area);
|
||||
}
|
||||
rbs->end = saved_bspstore;
|
||||
rbs->size = ((unw_word_t) 1) << 63; /* initial guess... */
|
||||
rbs->rnat_loc = saved_rnat_loc;
|
||||
|
||||
c->bsp = saved_bsp;
|
||||
|
||||
debug (10, "outer=[?????????????????\?-0x%llx), rnat@%s\n",
|
||||
(long long) rbs->end, ia64_strloc (rbs->rnat_loc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
HIDDEN int
|
||||
rbs_find_stacked (struct cursor *c, unw_word_t regs_to_skip,
|
||||
ia64_loc_t *locp, ia64_loc_t *rnat_locp)
|
||||
{
|
||||
unw_word_t nregs, bsp = c->bsp, curr = c->rbs_curr, n;
|
||||
unw_word_t left_edge = c->rbs_left_edge;
|
||||
#ifdef UNW_DEBUG
|
||||
int reg = 32 + regs_to_skip;
|
||||
#endif
|
||||
|
||||
while (!rbs_contains (&c->rbs_area[curr], bsp))
|
||||
{
|
||||
if (curr == left_edge)
|
||||
{
|
||||
debug (1, "%s: could not find register r%d!\n", __FUNCTION__, reg);
|
||||
return -UNW_EBADREG;
|
||||
}
|
||||
|
||||
n = ia64_rse_num_regs (c->rbs_area[curr].end, bsp);
|
||||
curr = (curr + NELEMS (c->rbs_area) - 1) % NELEMS (c->rbs_area);
|
||||
bsp = ia64_rse_skip_regs (c->rbs_area[curr].end - c->rbs_area[curr].size,
|
||||
n);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
nregs = ia64_rse_num_regs (bsp, c->rbs_area[curr].end);
|
||||
|
||||
if (regs_to_skip < nregs)
|
||||
{
|
||||
/* found it: */
|
||||
unw_word_t addr;
|
||||
|
||||
addr = ia64_rse_skip_regs (bsp, regs_to_skip);
|
||||
if (locp)
|
||||
*locp = rbs_loc (c->rbs_area + curr, addr);
|
||||
if (rnat_locp)
|
||||
*rnat_locp = rbs_get_rnat_loc (c->rbs_area + curr, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (curr == left_edge)
|
||||
{
|
||||
debug (1, "%s: could not find register r%d!\n", __FUNCTION__, reg);
|
||||
return -UNW_EBADREG;
|
||||
}
|
||||
|
||||
regs_to_skip -= nregs;
|
||||
|
||||
curr = (curr + NELEMS (c->rbs_area) - 1) % NELEMS (c->rbs_area);
|
||||
bsp = c->rbs_area[curr].end - c->rbs_area[curr].size;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
get_rnat (struct cursor *c, struct rbs_area *rbs, unw_word_t bsp,
|
||||
ia64_loc_t *__restrict rnat_locp, unw_word_t *__restrict rnatp)
|
||||
{
|
||||
*rnat_locp = rbs_get_rnat_loc (rbs, bsp);
|
||||
return ia64_get (c, *rnat_locp, rnatp);
|
||||
}
|
||||
|
||||
/* Ensure that the first "nregs" stacked registers are on the current
|
||||
register backing store area. This effectively simulates the effect
|
||||
of a "cover" followed by a "flushrs" for the current frame.
|
||||
|
||||
Note: This does not modify the rbs_area[] structure in any way. */
|
||||
HIDDEN int
|
||||
rbs_cover_and_flush (struct cursor *c, unw_word_t nregs)
|
||||
{
|
||||
unw_word_t src_mask, dst_mask, curr, val, left_edge = c->rbs_left_edge;
|
||||
unw_word_t src_bsp, dst_bsp, src_rnat, dst_rnat, dst_rnat_addr;
|
||||
ia64_loc_t src_rnat_loc, dst_rnat_loc;
|
||||
unw_word_t final_bsp;
|
||||
struct rbs_area *dst_rbs;
|
||||
int ret;
|
||||
|
||||
if (nregs < 1)
|
||||
return 0; /* nothing to do... */
|
||||
|
||||
/* Handle the common case quickly: */
|
||||
|
||||
curr = c->rbs_curr;
|
||||
dst_rbs = c->rbs_area + curr;
|
||||
final_bsp = ia64_rse_skip_regs (c->bsp, nregs); /* final bsp */
|
||||
if (likely (rbs_contains (dst_rbs, final_bsp) || curr == left_edge))
|
||||
{
|
||||
dst_rnat_addr = ia64_rse_rnat_addr (ia64_rse_skip_regs (c->bsp,
|
||||
nregs - 1));
|
||||
if (rbs_contains (dst_rbs, dst_rnat_addr))
|
||||
c->loc[IA64_REG_RNAT] = rbs_loc (dst_rbs, dst_rnat_addr);
|
||||
c->bsp = final_bsp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Skip over regs that are already on the destination rbs-area: */
|
||||
|
||||
dst_bsp = src_bsp = dst_rbs->end;
|
||||
|
||||
if ((ret = get_rnat (c, dst_rbs, dst_bsp, &dst_rnat_loc, &dst_rnat)) < 0)
|
||||
return ret;
|
||||
|
||||
/* This may seem a bit surprising, but with a hyper-lazy RSE, it's
|
||||
perfectly common that ar.bspstore points to an RNaT slot at the
|
||||
time of a backing-store switch. When that happens, install the
|
||||
appropriate RNaT value (if necessary) and move on to the next
|
||||
slot. */
|
||||
if (ia64_rse_is_rnat_slot (dst_bsp))
|
||||
{
|
||||
if ((IA64_IS_REG_LOC (dst_rnat_loc)
|
||||
|| IA64_GET_ADDR (dst_rnat_loc) != dst_bsp)
|
||||
&& (ret = ia64_put (c, rbs_loc (dst_rbs, dst_bsp), dst_rnat)) < 0)
|
||||
return ret;
|
||||
dst_bsp = src_bsp = dst_bsp + 8;
|
||||
}
|
||||
|
||||
while (dst_bsp != final_bsp)
|
||||
{
|
||||
while (!rbs_contains (&c->rbs_area[curr], src_bsp))
|
||||
{
|
||||
/* switch to next rbs-area, adjust src_bsp accordingly: */
|
||||
if (curr == left_edge)
|
||||
{
|
||||
debug (1, "%s: rbs-underflow while flushing %lu regs, "
|
||||
"src_bsp=0x%lx, dst_bsp=0x%lx\n",
|
||||
__FUNCTION__, nregs, src_bsp, dst_bsp);
|
||||
return -UNW_EBADREG;
|
||||
}
|
||||
curr = (curr + NELEMS (c->rbs_area) - 1) % NELEMS (c->rbs_area);
|
||||
src_bsp = c->rbs_area[curr].end - c->rbs_area[curr].size;
|
||||
}
|
||||
|
||||
/* OK, found the right rbs-area. Now copy both the register
|
||||
value and its NaT bit: */
|
||||
|
||||
if ((ret = get_rnat (c, c->rbs_area + curr, src_bsp,
|
||||
&src_rnat_loc, &src_rnat)) < 0)
|
||||
return ret;
|
||||
|
||||
src_mask = ((unw_word_t) 1) << ia64_rse_slot_num (src_bsp);
|
||||
dst_mask = ((unw_word_t) 1) << ia64_rse_slot_num (dst_bsp);
|
||||
|
||||
if (src_rnat & src_mask)
|
||||
dst_rnat |= dst_mask;
|
||||
else
|
||||
dst_rnat &= ~dst_mask;
|
||||
|
||||
if ((ret = ia64_get (c, rbs_loc (c->rbs_area + curr, src_bsp), &val)) < 0
|
||||
|| (ret = ia64_put (c, rbs_loc (dst_rbs, dst_bsp), val)) < 0)
|
||||
return ret;
|
||||
|
||||
/* advance src_bsp & dst_bsp to next slot: */
|
||||
|
||||
src_bsp += 8;
|
||||
if (ia64_rse_is_rnat_slot (src_bsp))
|
||||
src_bsp += 8;
|
||||
|
||||
dst_bsp += 8;
|
||||
if (ia64_rse_is_rnat_slot (dst_bsp))
|
||||
{
|
||||
if ((ret = ia64_put (c, rbs_loc (dst_rbs, dst_bsp), dst_rnat)) < 0)
|
||||
return ret;
|
||||
|
||||
dst_bsp += 8;
|
||||
|
||||
if ((ret = get_rnat (c, dst_rbs, dst_bsp,
|
||||
&dst_rnat_loc, &dst_rnat)) < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
c->bsp = dst_bsp;
|
||||
c->loc[IA64_REG_RNAT] = dst_rnat_loc;
|
||||
return ia64_put (c, dst_rnat_loc, dst_rnat);
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
||||
#include "Grbs-ia64.c"
|
||||
#endif
|
|
@ -1,311 +0,0 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2001-2003 Hewlett-Packard Co
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of libunwind.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#include "ucontext_i.h"
|
||||
#include "cursor_i.h"
|
||||
|
||||
#define SYS_sigreturn 1181
|
||||
|
||||
#ifndef UNW_REMOTE_ONLY
|
||||
|
||||
/* _Uia64_install_cursor (const cursor *c, long pri_unat, long *extra)
|
||||
|
||||
Restores the machine-state represented by C and thereby resumes execution
|
||||
in that frame. If the frame or one of its descendants was interrupted
|
||||
by a signal, all registers are restored (including the signal mask).
|
||||
Otherwise, only the preserved registers, the global-pointer (r1), and
|
||||
the exception-arguments (r15-r18) are restored. */
|
||||
|
||||
#define pRet p6
|
||||
#define pSig p7
|
||||
|
||||
.align 32
|
||||
.hidden _Uia64_install_cursor
|
||||
.global _Uia64_install_cursor
|
||||
.proc _Uia64_install_cursor
|
||||
_Uia64_install_cursor:
|
||||
alloc r3 = ar.pfs, 3, 0, 0, 0
|
||||
invala
|
||||
add r2 = FR_LOC_OFF, in0
|
||||
;;
|
||||
|
||||
ld8 r16 = [r2], 8 // r16 = loc[IA64_REG_FR16]
|
||||
mov.m r10 = ar.rsc // (ar.rsc: ~ 12 cycle latency)
|
||||
add r3 = FR_LOC_OFF + 16, in0
|
||||
;;
|
||||
|
||||
ld8 r17 = [r2], 16 // r17 = loc[IA64_REG_FR17]
|
||||
ld8 r18 = [r3], 16 // r18 = loc[IA64_REG_FR18]
|
||||
and r16 = -4, r16
|
||||
;;
|
||||
|
||||
ld8 r19 = [r2], 16 // r19 = loc[IA64_REG_FR19]
|
||||
ld8 r20 = [r3], 16 // r20 = loc[IA64_REG_FR20]
|
||||
and r17 = -4, r17
|
||||
;;
|
||||
|
||||
ldf.fill f16 = [r16] // f16 restored (don't touch no more)
|
||||
ldf.fill f17 = [r17] // f17 restored (don't touch no more)
|
||||
and r18 = -4, r18
|
||||
|
||||
ld8 r21 = [r2], 16 // r21 = loc[IA64_REG_FR21]
|
||||
ld8 r22 = [r3], 16 // r22 = loc[IA64_REG_FR22]
|
||||
and r19 = -4, r19
|
||||
;;
|
||||
|
||||
ldf.fill f18 = [r18] // f18 restored (don't touch no more)
|
||||
ldf.fill f19 = [r19] // f19 restored (don't touch no more)
|
||||
and r20 = -4, r20
|
||||
|
||||
ld8 r23 = [r2], 16 // r23 = loc[IA64_REG_FR23]
|
||||
ld8 r24 = [r3], 16 // r24 = loc[IA64_REG_FR24]
|
||||
and r21 = -4, r21
|
||||
;;
|
||||
|
||||
ldf.fill f20 = [r20] // f20 restored (don't touch no more)
|
||||
ldf.fill f21 = [r21] // f21 restored (don't touch no more)
|
||||
and r22 = -4, r22
|
||||
|
||||
ld8 r25 = [r2], 16 // r25 = loc[IA64_REG_FR25]
|
||||
ld8 r26 = [r3], 16 // r26 = loc[IA64_REG_FR26]
|
||||
and r23 = -4, r23
|
||||
;;
|
||||
|
||||
ldf.fill f22 = [r22] // f22 restored (don't touch no more)
|
||||
ldf.fill f23 = [r23] // f23 restored (don't touch no more)
|
||||
and r24 = -4, r24
|
||||
|
||||
ld8 r27 = [r2], 16 // r27 = loc[IA64_REG_FR27]
|
||||
ld8 r28 = [r3], 16 // r28 = loc[IA64_REG_FR28]
|
||||
and r25 = -4, r25
|
||||
;;
|
||||
|
||||
ldf.fill f24 = [r24] // f24 restored (don't touch no more)
|
||||
ldf.fill f25 = [r25] // f25 restored (don't touch no more)
|
||||
and r26 = -4, r26
|
||||
|
||||
ld8 r29 = [r2], 16 // r29 = loc[IA64_REG_FR29]
|
||||
ld8 r30 = [r3], 16 // r30 = loc[IA64_REG_FR30]
|
||||
and r27 = -4, r27
|
||||
;;
|
||||
|
||||
ldf.fill f26 = [r26] // f26 restored (don't touch no more)
|
||||
ldf.fill f27 = [r27] // f27 restored (don't touch no more)
|
||||
and r28 = -4, r28
|
||||
|
||||
ld8 r31 = [r2] // r31 = loc[IA64_REG_FR31]
|
||||
mov.m ar.unat = in1
|
||||
and r29 = -4, r29
|
||||
;;
|
||||
|
||||
ldf.fill f28 = [r28] // f28 restored (don't touch no more)
|
||||
ldf.fill f29 = [r29] // f29 restored (don't touch no more)
|
||||
and r30 = -4, r30
|
||||
|
||||
ld8 r1 = [in2], 8 // gp restored (don't touch no more)
|
||||
add r8 = SIGCONTEXT_ADDR_OFF, in0
|
||||
and r31 = -4, r31
|
||||
;;
|
||||
|
||||
ld8 r8 = [r8] // r8 = sigcontext_addr
|
||||
and r11 = 0x1c, r10 // clear all but rsc.be and rsc.pl
|
||||
add r2 = PFS_LOC_OFF, in0
|
||||
|
||||
ldf.fill f30 = [r30] // f30 restored (don't touch no more)
|
||||
ldf.fill f31 = [r31] // f31 restored (don't touch no more)
|
||||
add r3 = 16, in2
|
||||
;;
|
||||
|
||||
ld8.fill r4 = [in2], 16 // r4 restored (don't touch no more)
|
||||
ld8.fill r5 = [r3], 16 // r5 restored (don't touch no more)
|
||||
cmp.eq pRet, pSig = r0, r8 // sigcontext_addr == NULL?
|
||||
;;
|
||||
ld8.fill r6 = [in2], 16 // r6 restored (don't touch no more)
|
||||
ld8.fill r7 = [r3] // r7 restored (don't touch no more)
|
||||
add r3 = IP_OFF, in0
|
||||
;;
|
||||
|
||||
ld8 r14 = [r2], (B1_LOC_OFF - PFS_LOC_OFF) // r14 = pfs_loc
|
||||
ld8 r15 = [r3], (B2_LOC_OFF - IP_OFF) // r15 = ip
|
||||
nop 0
|
||||
;;
|
||||
|
||||
ld8 r16 = [r2], (B3_LOC_OFF - B1_LOC_OFF) // r16 = b1_loc
|
||||
ld8 r17= [r3], (B4_LOC_OFF - B2_LOC_OFF) // r17 = b2_loc
|
||||
and r14 = -4, r14
|
||||
;;
|
||||
|
||||
ld8 r18 = [r2], (B5_LOC_OFF - B3_LOC_OFF) // r18 = b3_loc
|
||||
ld8 r19 = [r3], (F2_LOC_OFF - B4_LOC_OFF) // r19 = b4_loc
|
||||
and r16 = -4, r16
|
||||
;;
|
||||
|
||||
ld8 r20 = [r2], (F3_LOC_OFF - B5_LOC_OFF) // r20 = b5_loc
|
||||
ld8 r21 = [r3], (F4_LOC_OFF - F2_LOC_OFF) // r21 = f2_loc
|
||||
and r17 = -4, r17
|
||||
;;
|
||||
|
||||
ld8 r16 = [r16] // r16 = *b1_loc
|
||||
ld8 r17 = [r17] // r17 = *b2_loc
|
||||
and r18 = -4, r18
|
||||
|
||||
ld8 r22 = [r2], (F5_LOC_OFF - F3_LOC_OFF) // r21 = f3_loc
|
||||
ld8 r23 = [r3], (UNAT_LOC_OFF - F4_LOC_OFF) // r22 = f4_loc
|
||||
and r19 = -4, r19
|
||||
;;
|
||||
|
||||
ld8 r18 = [r18] // r18 = *b3_loc
|
||||
ld8 r19 = [r19] // r19 = *b4_loc
|
||||
and r20 = -4, r20
|
||||
|
||||
ld8 r24 = [r2], (LC_LOC_OFF - F5_LOC_OFF) // r24 = f5_loc
|
||||
ld8 r25 = [r3], (FPSR_LOC_OFF - UNAT_LOC_OFF) // r25 = unat_loc
|
||||
and r21 = -4, r21
|
||||
;;
|
||||
|
||||
and r22 = -4, r22
|
||||
and r23 = -4, r23
|
||||
and r24 = -4, r24
|
||||
|
||||
ld8 r20 = [r20] // r20 = *b5_loc
|
||||
ldf.fill f2 = [r21] // f2 restored (don't touch no more)
|
||||
mov b1 = r16 // b1 restored (don't touch no more)
|
||||
;;
|
||||
|
||||
ldf.fill f3 = [r22] // f3 restored (don't touch no more)
|
||||
ldf.fill f4 = [r23] // f4 restored (don't touch no more)
|
||||
mov b2 = r17 // b2 restored (don't touch no more)
|
||||
|
||||
ld8 r26 = [r2], (RNAT_LOC_OFF - LC_LOC_OFF) // r26 = lc_loc
|
||||
ld8 r27 = [r3], (PSP_OFF - FPSR_LOC_OFF) // r27 = fpsr_loc
|
||||
and r25 = -4, r25
|
||||
;;
|
||||
|
||||
ldf.fill f5 = [r24] // f5 restored (don't touch no more)
|
||||
(pRet) ld8 r25 = [r25] // r25 = *unat_loc
|
||||
mov b3 = r18 // b3 restored (don't touch no more)
|
||||
|
||||
ld8 r28 = [r2], (BSP_OFF - RNAT_LOC_OFF) // r28 = rnat_loc
|
||||
ld8 r29 = [r3], (PR_OFF - PSP_OFF) // r29 = sp
|
||||
mov b4 = r19 // b4 restored (don't touch no more)
|
||||
|
||||
and r26 = -4, r26
|
||||
and r27 = -4, r27
|
||||
mov b5 = r20 // b5 restored (don't touch no more)
|
||||
;;
|
||||
|
||||
ld8 r26 = [r26] // r26 = *lc_loc
|
||||
ld8 r27 = [r27] // r27 = *fpsr_loc
|
||||
and r28 = -4, r28
|
||||
|
||||
ld8 r30 = [r2] // r30 = bsp
|
||||
ld8 r31 = [r3] // r31 = pr
|
||||
mov rp = r15
|
||||
;;
|
||||
|
||||
ld8 r28 = [r28] // r28 = rnat
|
||||
mov.m ar.rsc = r11 // put RSE into enforced lazy mode
|
||||
mov.i ar.lc = r26 // lc restored (don't touch no more)
|
||||
;;
|
||||
|
||||
loadrs // drop dirty partition
|
||||
;;
|
||||
mov.m ar.bspstore = r30 // restore register backing-store
|
||||
add r3 = 8, in2 // r3 = &extra[r16]
|
||||
;;
|
||||
|
||||
(pRet) mov.m ar.fpsr = r27 // fpsr restored (don't touch no more)
|
||||
mov.m ar.rnat = r28
|
||||
(pSig) br.cond.dpnt.many .next
|
||||
|
||||
/****** Return via br.ret: */
|
||||
|
||||
ld8 r14 = [r14] // r14 = *pfs_loc
|
||||
ld8 r15 = [in2], 16 // r15 restored (don't touch no more)
|
||||
mov pr = r31, -1 // pr restored (don't touch no more)
|
||||
;;
|
||||
|
||||
ld8 r16 = [r3], 16 // r16 restored (don't touch no more)
|
||||
ld8 r17 = [in2] // r17 restored (don't touch no more)
|
||||
nop.i 0
|
||||
;;
|
||||
|
||||
ld8 r18 = [r3] // r18 restored (don't touch no more)
|
||||
mov.m ar.rsc = r10 // restore original ar.rsc
|
||||
mov sp = r29
|
||||
|
||||
mov.m ar.unat = r25 // unat restored (don't touch no more)
|
||||
mov.i ar.pfs = r14
|
||||
br.ret.sptk.many rp
|
||||
;;
|
||||
|
||||
/****** Return via sigreturn(): */
|
||||
|
||||
.next: mov.m ar.rsc = r10 // restore original ar.rsc
|
||||
add r2 = (SC_FR + 6*16), r8
|
||||
add r3 = (SC_FR + 7*16), r8
|
||||
;;
|
||||
|
||||
ldf.fill f6 = [r2], 32
|
||||
ldf.fill f7 = [r3], 32
|
||||
nop 0
|
||||
;;
|
||||
|
||||
ldf.fill f8 = [r2], 32
|
||||
ldf.fill f9 = [r3], 32
|
||||
nop 0
|
||||
;;
|
||||
|
||||
ldf.fill f10 = [r2], 32
|
||||
ldf.fill f11 = [r3], 32
|
||||
nop 0
|
||||
;;
|
||||
|
||||
ldf.fill f12 = [r2], 32
|
||||
ldf.fill f13 = [r3], 32
|
||||
nop 0
|
||||
;;
|
||||
|
||||
ldf.fill f14 = [r2], 32
|
||||
ldf.fill f15 = [r3], 32
|
||||
mov sp = r29
|
||||
;;
|
||||
|
||||
#if NEW_SYSCALL
|
||||
add r2 = -8, tp;;
|
||||
ld8 r2 = [r2]
|
||||
mov r15 = SYS_sigreturn
|
||||
mov b7 = r2
|
||||
br.call.sptk.many b6 = b7
|
||||
;;
|
||||
#else
|
||||
mov r15 = SYS_sigreturn
|
||||
break 0x100000
|
||||
#endif
|
||||
break 0 // bug out if sigreturn() returns
|
||||
|
||||
.endp _Uia64_install_cursor
|
||||
|
||||
#endif /* !UNW_REMOTE_ONLY */
|
Loading…
Reference in a new issue