mirror of git://gcc.gnu.org/git/gcc.git
sol2-unwind.h (sparc64_frob_update_context): Do it for signal frames as well.
* config/sparc/sol2-unwind.h (sparc64_frob_update_context): Do it for signal frames as well. (MD_FALLBACK_FRAME_STATE_FOR): Do minor cleanups throughout and add the STACK_BIAS to the CFA offset. From-SVN: r199191
This commit is contained in:
parent
2ac2f83d0a
commit
4fcb5d87d4
|
|
@ -1,3 +1,10 @@
|
||||||
|
2013-05-22 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
|
* config/sparc/sol2-unwind.h (sparc64_frob_update_context): Do it for
|
||||||
|
signal frames as well.
|
||||||
|
(MD_FALLBACK_FRAME_STATE_FOR): Do minor cleanups throughout and add the
|
||||||
|
STACK_BIAS to the CFA offset.
|
||||||
|
|
||||||
2013-05-17 Richard Henderson <rth@redhat.com>
|
2013-05-17 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
PR target/49146
|
PR target/49146
|
||||||
|
|
|
||||||
|
|
@ -155,12 +155,10 @@ sparc64_frob_update_context (struct _Unwind_Context *context,
|
||||||
{
|
{
|
||||||
/* The column of %sp contains the old CFA, not the old value of %sp.
|
/* The column of %sp contains the old CFA, not the old value of %sp.
|
||||||
The CFA offset already comprises the stack bias so, when %sp is the
|
The CFA offset already comprises the stack bias so, when %sp is the
|
||||||
CFA register, we must avoid counting the stack bias twice. Do not
|
CFA register, we must avoid counting the stack bias twice. */
|
||||||
do that for signal frames as the offset is artificial for them. */
|
|
||||||
if (fs->regs.cfa_reg == __builtin_dwarf_sp_column ()
|
if (fs->regs.cfa_reg == __builtin_dwarf_sp_column ()
|
||||||
&& fs->regs.cfa_how == CFA_REG_OFFSET
|
&& fs->regs.cfa_how == CFA_REG_OFFSET
|
||||||
&& fs->regs.cfa_offset != 0
|
&& fs->regs.cfa_offset != 0)
|
||||||
&& !fs->signal_frame)
|
|
||||||
{
|
{
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
|
|
@ -296,9 +294,8 @@ MD_FALLBACK_FRAME_STATE_FOR (struct _Unwind_Context *context,
|
||||||
_Unwind_FrameState *fs)
|
_Unwind_FrameState *fs)
|
||||||
{
|
{
|
||||||
void *pc = context->ra;
|
void *pc = context->ra;
|
||||||
struct frame *fp = (struct frame *) context->cfa;
|
|
||||||
int nframes;
|
|
||||||
void *this_cfa = context->cfa;
|
void *this_cfa = context->cfa;
|
||||||
|
int nframes = 0;
|
||||||
long new_cfa;
|
long new_cfa;
|
||||||
void *ra_location, *shifted_ra_location;
|
void *ra_location, *shifted_ra_location;
|
||||||
mcontext_t *mctx;
|
mcontext_t *mctx;
|
||||||
|
|
@ -318,21 +315,22 @@ MD_FALLBACK_FRAME_STATE_FOR (struct _Unwind_Context *context,
|
||||||
return _URC_NO_REASON;
|
return _URC_NO_REASON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do some pattern matching at the return address. */
|
||||||
if (IS_SIGHANDLER (pc, this_cfa, &nframes))
|
if (IS_SIGHANDLER (pc, this_cfa, &nframes))
|
||||||
{
|
{
|
||||||
|
struct frame *fp = (struct frame *) this_cfa;
|
||||||
struct handler_args {
|
struct handler_args {
|
||||||
struct frame frwin;
|
struct frame frwin;
|
||||||
ucontext_t ucontext;
|
ucontext_t ucontext;
|
||||||
} *handler_args;
|
} *handler_args;
|
||||||
ucontext_t *ucp;
|
ucontext_t *ucp;
|
||||||
|
|
||||||
/* context->cfa points into the frame after the saved frame pointer and
|
/* this_cfa points into the frame after the saved frame pointer and
|
||||||
saved pc (struct frame).
|
saved pc (struct frame).
|
||||||
|
|
||||||
The ucontext_t structure is in the kernel frame after a struct
|
The ucontext_t structure is in the kernel frame after a struct
|
||||||
frame. Since the frame sizes vary even within OS releases, we
|
frame. Since the frame sizes vary even within OS releases, we
|
||||||
need to walk the stack to get there. */
|
need to walk the stack to get there. */
|
||||||
|
|
||||||
for (i = 0; i < nframes; i++)
|
for (i = 0; i < nframes; i++)
|
||||||
fp = (struct frame *) ((char *)fp->fr_savfp + STACK_BIAS);
|
fp = (struct frame *) ((char *)fp->fr_savfp + STACK_BIAS);
|
||||||
|
|
||||||
|
|
@ -340,19 +338,15 @@ MD_FALLBACK_FRAME_STATE_FOR (struct _Unwind_Context *context,
|
||||||
ucp = &handler_args->ucontext;
|
ucp = &handler_args->ucontext;
|
||||||
mctx = &ucp->uc_mcontext;
|
mctx = &ucp->uc_mcontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exit if the pattern at the return address does not match the
|
|
||||||
previous three patterns. */
|
|
||||||
else
|
else
|
||||||
return _URC_END_OF_STACK;
|
return _URC_END_OF_STACK;
|
||||||
|
|
||||||
new_cfa = mctx->gregs[REG_SP];
|
|
||||||
/* The frame address is %sp + STACK_BIAS in 64-bit mode. */
|
/* The frame address is %sp + STACK_BIAS in 64-bit mode. */
|
||||||
new_cfa += STACK_BIAS;
|
new_cfa = mctx->gregs[REG_SP] + STACK_BIAS;
|
||||||
|
|
||||||
fs->regs.cfa_how = CFA_REG_OFFSET;
|
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||||
fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
|
fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
|
||||||
fs->regs.cfa_offset = new_cfa - (long) this_cfa;
|
fs->regs.cfa_offset = new_cfa - (long) this_cfa + STACK_BIAS;
|
||||||
|
|
||||||
/* Restore global and out registers (in this order) from the
|
/* Restore global and out registers (in this order) from the
|
||||||
ucontext_t structure, uc_mcontext.gregs field. */
|
ucontext_t structure, uc_mcontext.gregs field. */
|
||||||
|
|
@ -372,7 +366,7 @@ MD_FALLBACK_FRAME_STATE_FOR (struct _Unwind_Context *context,
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
|
fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
|
||||||
fs->regs.reg[i + 16].loc.offset = i*sizeof(long);
|
fs->regs.reg[i + 16].loc.offset = i * sizeof(long);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether we need to restore FPU registers. */
|
/* Check whether we need to restore FPU registers. */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue