Commit 4fcb5d87 by Eric Botcazou Committed by Eric Botcazou

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
parent 2ac2f83d
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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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. */
......
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