aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2003-09-30 23:01:47 -0700
committerRichard Henderson <rth@gcc.gnu.org>2003-09-30 23:01:47 -0700
commited80cd6809e600cf021fc66cbc1d5fa5c682cab7 (patch)
tree20abd603a5bcb42f4ffe7929126e0ebc032fc438 /gcc
parent6ab7003d15f074b44f4a521a7ac46b9759492f86 (diff)
downloadgcc-ed80cd6809e600cf021fc66cbc1d5fa5c682cab7.zip
gcc-ed80cd6809e600cf021fc66cbc1d5fa5c682cab7.tar.gz
gcc-ed80cd6809e600cf021fc66cbc1d5fa5c682cab7.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/alpha/alpha.c50
-rw-r--r--gcc/config/alpha/alpha.h1
-rw-r--r--gcc/config/alpha/linux.h8
-rw-r--r--gcc/doc/tm.texi8
-rw-r--r--gcc/dwarf2out.c12
-rw-r--r--gcc/unwind-dw2.c9
7 files changed, 88 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fc2546b..e2b09d7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+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>
* sdbout.c: Convert to ISO C90 prototypes.
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 18b2d53..ad6b619 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -6700,13 +6700,20 @@ alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
/* We need to restore these for the handler. */
if (current_function_calls_eh_return)
- for (i = 0; ; ++i)
- {
- unsigned regno = EH_RETURN_DATA_REGNO (i);
- if (regno == INVALID_REGNUM)
- break;
- imask |= 1UL << regno;
- }
+ {
+ for (i = 0; ; ++i)
+ {
+ unsigned regno = EH_RETURN_DATA_REGNO (i);
+ if (regno == INVALID_REGNUM)
+ break;
+ 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. */
/* ??? This is required by the Digital stack unwind specification
@@ -7168,7 +7175,7 @@ alpha_expand_prologue (void)
}
/* 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))
{
mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
@@ -7177,7 +7184,25 @@ alpha_expand_prologue (void)
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))
{
mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
@@ -7588,7 +7613,7 @@ alpha_expand_epilogue (void)
reg_offset += 8;
imask &= ~(1UL << REG_RA);
- for (i = 0; i < 32; ++i)
+ for (i = 0; i < 31; ++i)
if (imask & (1UL << i))
{
if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
@@ -7602,7 +7627,10 @@ alpha_expand_epilogue (void)
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))
{
mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index e68cb48..5faadfb 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -1208,6 +1208,7 @@ do { \
/* Before the prologue, RA lives in $26. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 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. */
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 16 : INVALID_REGNUM)
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index 0853369..2c9cc8e 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -85,6 +85,8 @@ Boston, MA 02111-1307, USA. */
if (pc_[0] != 0x47fe0410 /* mov $30,$16 */ \
|| pc_[2] != 0x00000083 /* callsys */) \
break; \
+ if ((CONTEXT)->cfa == 0) \
+ break; \
if (pc_[1] == 0x201f0067) /* lda $0,NR_sigreturn */ \
sc_ = (CONTEXT)->cfa; \
else if (pc_[1] == 0x201f015f) /* lda $0,NR_rt_sigreturn */ \
@@ -113,8 +115,8 @@ Boston, MA 02111-1307, USA. */
(FS)->regs.reg[i_+32].loc.offset \
= (long)&sc_->sc_fpregs[i_] - new_cfa_; \
} \
- (FS)->regs.reg[31].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[31].loc.offset = (long)&sc_->sc_pc - new_cfa_; \
- (FS)->retaddr_column = 31; \
+ (FS)->regs.reg[64].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[64].loc.offset = (long)&sc_->sc_pc - new_cfa_; \
+ (FS)->retaddr_column = 64; \
goto SUCCESS; \
} while (0)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 582953b..1e9a45c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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)}.
@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
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
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index f22ca50..9a23c76 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -482,10 +482,20 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
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)
{
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);
emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
}
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index f94eaf9..09396c8 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -82,7 +82,7 @@ struct _Unwind_Context
};
/* 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.
@@ -186,6 +186,8 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
void *ptr;
index = DWARF_REG_TO_UNWIND_COLUMN (index);
+ if (index >= sizeof(dwarf_reg_size_table))
+ abort ();
size = dwarf_reg_size_table[index];
ptr = context->reg[index];
@@ -222,6 +224,8 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
void *ptr;
index = DWARF_REG_TO_UNWIND_COLUMN (index);
+ if (index >= sizeof(dwarf_reg_size_table))
+ abort ();
size = dwarf_reg_size_table[index];
ptr = context->reg[index];
@@ -1002,6 +1006,9 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
context->args_size = 0;
context->lsda = 0;
+ if (context->ra == 0)
+ return _URC_END_OF_STACK;
+
fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
if (fde == NULL)
{