Commit ed80cd68 by Richard Henderson Committed by Richard Henderson

dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Honor DWARF_ALT_FRAME_RETURN_COLUMN.

        * dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Honor
        DWARF_ALT_FRAME_RETURN_COLUMN.
        * unwind-dw2.c (dwarf_reg_size_table): Expand by one.
        (_Unwind_GetGR, _Unwind_SetGR): Validate lookup column.
        (uw_frame_state_for): Return end-of-stack for null return address.
        * doc/tm.texi (DWARF_ALT_FRAME_RETURN_COLUMN): Add.

        * config/alpha/alpha.c (alpha_sa_mask): Add r31 for eh_return.
        (alpha_expand_prologue): Store a zero for it.
        (alpha_expand_epilogue): Don't reload it.
        * config/alpha/alpha.h (DWARF_ALT_FRAME_RETURN_COLUMN): New.
        * config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Use column 64
        for the sigframe return address.

From-SVN: r71967
parent 6ab7003d
2003-09-30 Richard Henderson <rth@redhat.com>
* dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Honor
DWARF_ALT_FRAME_RETURN_COLUMN.
* unwind-dw2.c (dwarf_reg_size_table): Expand by one.
(_Unwind_GetGR, _Unwind_SetGR): Validate lookup column.
(uw_frame_state_for): Return end-of-stack for null return address.
* doc/tm.texi (DWARF_ALT_FRAME_RETURN_COLUMN): Add.
* config/alpha/alpha.c (alpha_sa_mask): Add r31 for eh_return.
(alpha_expand_prologue): Store a zero for it.
(alpha_expand_epilogue): Don't reload it.
* config/alpha/alpha.h (DWARF_ALT_FRAME_RETURN_COLUMN): New.
* config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Use column 64
for the sigframe return address.
2003-09-30 Kelley Cook <kelleycoook@wideopenwest.com> 2003-09-30 Kelley Cook <kelleycoook@wideopenwest.com>
* sdbout.c: Convert to ISO C90 prototypes. * sdbout.c: Convert to ISO C90 prototypes.
......
...@@ -6700,6 +6700,7 @@ alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP) ...@@ -6700,6 +6700,7 @@ alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
/* We need to restore these for the handler. */ /* We need to restore these for the handler. */
if (current_function_calls_eh_return) if (current_function_calls_eh_return)
{
for (i = 0; ; ++i) for (i = 0; ; ++i)
{ {
unsigned regno = EH_RETURN_DATA_REGNO (i); unsigned regno = EH_RETURN_DATA_REGNO (i);
...@@ -6708,6 +6709,12 @@ alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP) ...@@ -6708,6 +6709,12 @@ alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
imask |= 1UL << regno; imask |= 1UL << regno;
} }
/* Glibc likes to use $31 as an unwind stopper for crt0. To
avoid hackery in unwind-dw2.c, we need to actively store a
zero in the prologue of _Unwind_RaiseException et al. */
imask |= 1UL << 31;
}
/* If any register spilled, then spill the return address also. */ /* If any register spilled, then spill the return address also. */
/* ??? This is required by the Digital stack unwind specification /* ??? This is required by the Digital stack unwind specification
and isn't needed if we're doing Dwarf2 unwinding. */ and isn't needed if we're doing Dwarf2 unwinding. */
...@@ -7168,7 +7175,7 @@ alpha_expand_prologue (void) ...@@ -7168,7 +7175,7 @@ alpha_expand_prologue (void)
} }
/* Now save any other registers required to be saved. */ /* Now save any other registers required to be saved. */
for (i = 0; i < 32; i++) for (i = 0; i < 31; i++)
if (imask & (1UL << i)) if (imask & (1UL << i))
{ {
mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)); mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
...@@ -7177,7 +7184,25 @@ alpha_expand_prologue (void) ...@@ -7177,7 +7184,25 @@ alpha_expand_prologue (void)
reg_offset += 8; reg_offset += 8;
} }
for (i = 0; i < 32; i++) /* Store a zero if requested for unwinding. */
if (imask & (1UL << 31))
{
rtx insn, t;
mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
insn = emit_move_insn (mem, const0_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
t = gen_rtx_REG (Pmode, 31);
t = gen_rtx_SET (VOIDmode, mem, t);
t = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, t, REG_NOTES (insn));
REG_NOTES (insn) = t;
reg_offset += 8;
}
for (i = 0; i < 31; i++)
if (fmask & (1UL << i)) if (fmask & (1UL << i))
{ {
mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset)); mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
...@@ -7588,7 +7613,7 @@ alpha_expand_epilogue (void) ...@@ -7588,7 +7613,7 @@ alpha_expand_epilogue (void)
reg_offset += 8; reg_offset += 8;
imask &= ~(1UL << REG_RA); imask &= ~(1UL << REG_RA);
for (i = 0; i < 32; ++i) for (i = 0; i < 31; ++i)
if (imask & (1UL << i)) if (imask & (1UL << i))
{ {
if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer) if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
...@@ -7602,7 +7627,10 @@ alpha_expand_epilogue (void) ...@@ -7602,7 +7627,10 @@ alpha_expand_epilogue (void)
reg_offset += 8; reg_offset += 8;
} }
for (i = 0; i < 32; ++i) if (imask & (1UL << 31))
reg_offset += 8;
for (i = 0; i < 31; ++i)
if (fmask & (1UL << i)) if (fmask & (1UL << i))
{ {
mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset)); mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
......
...@@ -1208,6 +1208,7 @@ do { \ ...@@ -1208,6 +1208,7 @@ do { \
/* Before the prologue, RA lives in $26. */ /* Before the prologue, RA lives in $26. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26) #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26)
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (26) #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (26)
#define DWARF_ALT_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (64)
/* Describe how we implement __builtin_eh_return. */ /* Describe how we implement __builtin_eh_return. */
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 16 : INVALID_REGNUM) #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 16 : INVALID_REGNUM)
......
...@@ -85,6 +85,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -85,6 +85,8 @@ Boston, MA 02111-1307, USA. */
if (pc_[0] != 0x47fe0410 /* mov $30,$16 */ \ if (pc_[0] != 0x47fe0410 /* mov $30,$16 */ \
|| pc_[2] != 0x00000083 /* callsys */) \ || pc_[2] != 0x00000083 /* callsys */) \
break; \ break; \
if ((CONTEXT)->cfa == 0) \
break; \
if (pc_[1] == 0x201f0067) /* lda $0,NR_sigreturn */ \ if (pc_[1] == 0x201f0067) /* lda $0,NR_sigreturn */ \
sc_ = (CONTEXT)->cfa; \ sc_ = (CONTEXT)->cfa; \
else if (pc_[1] == 0x201f015f) /* lda $0,NR_rt_sigreturn */ \ else if (pc_[1] == 0x201f015f) /* lda $0,NR_rt_sigreturn */ \
...@@ -113,8 +115,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -113,8 +115,8 @@ Boston, MA 02111-1307, USA. */
(FS)->regs.reg[i_+32].loc.offset \ (FS)->regs.reg[i_+32].loc.offset \
= (long)&sc_->sc_fpregs[i_] - new_cfa_; \ = (long)&sc_->sc_fpregs[i_] - new_cfa_; \
} \ } \
(FS)->regs.reg[31].how = REG_SAVED_OFFSET; \ (FS)->regs.reg[64].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[31].loc.offset = (long)&sc_->sc_pc - new_cfa_; \ (FS)->regs.reg[64].loc.offset = (long)&sc_->sc_pc - new_cfa_; \
(FS)->retaddr_column = 31; \ (FS)->retaddr_column = 64; \
goto SUCCESS; \ goto SUCCESS; \
} while (0) } while (0)
...@@ -2904,6 +2904,14 @@ If this RTL is a @code{REG}, you should also define ...@@ -2904,6 +2904,14 @@ If this RTL is a @code{REG}, you should also define
@code{DWARF_FRAME_RETURN_COLUMN} to @code{DWARF_FRAME_REGNUM (REGNO)}. @code{DWARF_FRAME_RETURN_COLUMN} to @code{DWARF_FRAME_REGNUM (REGNO)}.
@end defmac @end defmac
@defmac DWARF_ALT_FRAME_RETURN_COLUMN
A C expression whose value is an integer giving a DWARF 2 column
number that may be used as an alternate return column. This should
be defined only if @code{DWARF_FRAME_RETURN_COLUMN} is set to a
general register, but an alternate column needs to be used for
signal frames.
@end defmac
@defmac INCOMING_FRAME_SP_OFFSET @defmac INCOMING_FRAME_SP_OFFSET
A C expression whose value is an integer giving the offset, in bytes, A C expression whose value is an integer giving the offset, in bytes,
from the value of the stack pointer register to the top of the stack from the value of the stack pointer register to the top of the stack
......
...@@ -482,10 +482,20 @@ expand_builtin_init_dwarf_reg_sizes (tree address) ...@@ -482,10 +482,20 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size)); emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
} }
#ifdef DWARF_ALT_FRAME_RETURN_COLUMN
if (! wrote_return_column)
abort ();
i = DWARF_ALT_FRAME_RETURN_COLUMN;
wrote_return_column = false;
#else
i = DWARF_FRAME_RETURN_COLUMN;
#endif
if (! wrote_return_column) if (! wrote_return_column)
{ {
enum machine_mode save_mode = Pmode; enum machine_mode save_mode = Pmode;
HOST_WIDE_INT offset = DWARF_FRAME_RETURN_COLUMN * GET_MODE_SIZE (mode); HOST_WIDE_INT offset = i * GET_MODE_SIZE (mode);
HOST_WIDE_INT size = GET_MODE_SIZE (save_mode); HOST_WIDE_INT size = GET_MODE_SIZE (save_mode);
emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size)); emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
} }
......
...@@ -82,7 +82,7 @@ struct _Unwind_Context ...@@ -82,7 +82,7 @@ struct _Unwind_Context
}; };
/* Byte size of every register managed by these routines. */ /* Byte size of every register managed by these routines. */
static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS]; static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
/* The result of interpreting the frame unwind info for a frame. /* The result of interpreting the frame unwind info for a frame.
...@@ -186,6 +186,8 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index) ...@@ -186,6 +186,8 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
void *ptr; void *ptr;
index = DWARF_REG_TO_UNWIND_COLUMN (index); index = DWARF_REG_TO_UNWIND_COLUMN (index);
if (index >= sizeof(dwarf_reg_size_table))
abort ();
size = dwarf_reg_size_table[index]; size = dwarf_reg_size_table[index];
ptr = context->reg[index]; ptr = context->reg[index];
...@@ -222,6 +224,8 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val) ...@@ -222,6 +224,8 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
void *ptr; void *ptr;
index = DWARF_REG_TO_UNWIND_COLUMN (index); index = DWARF_REG_TO_UNWIND_COLUMN (index);
if (index >= sizeof(dwarf_reg_size_table))
abort ();
size = dwarf_reg_size_table[index]; size = dwarf_reg_size_table[index];
ptr = context->reg[index]; ptr = context->reg[index];
...@@ -1002,6 +1006,9 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) ...@@ -1002,6 +1006,9 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
context->args_size = 0; context->args_size = 0;
context->lsda = 0; context->lsda = 0;
if (context->ra == 0)
return _URC_END_OF_STACK;
fde = _Unwind_Find_FDE (context->ra - 1, &context->bases); fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
if (fde == NULL) if (fde == NULL)
{ {
......
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