dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Honor DWARF_ALT_FRAME_RETURN_COLUMN.
authorRichard Henderson <rth@redhat.com>
Wed, 1 Oct 2003 06:01:47 +0000 (23:01 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 1 Oct 2003 06:01:47 +0000 (23:01 -0700)
        * 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

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/linux.h
gcc/doc/tm.texi
gcc/dwarf2out.c
gcc/unwind-dw2.c

index fc2546b493892462f005231fbb791c993833d921..e2b09d7819f7c650927ca1d0a92afb0655126e14 100644 (file)
@@ -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.
index 18b2d53667e5862e819fd5283774c105d84a780c..ad6b61977e295cb165c140d119e791f42d64ea33 100644 (file)
@@ -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));
index e68cb4848e6a655932851ffc759ae821b79fd6f0..5faadfbdbf04ae1f89bfc5bbd33b9e36d2769dac 100644 (file)
@@ -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)
index 0853369171d4641a35c9c22dd0cc7e2028ffc161..2c9cc8ea6a1a51c4fec01c06b03f453ca99b9234 100644 (file)
@@ -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)
index 582953b7bb5a1ee1ffa455b3c92c50e2260da341..1e9a45c75869aa8146e0b105e01bcd5c38a1be26 100644 (file)
@@ -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
index f22ca5045fd73314eb3123d3ff134f2258a72be6..9a23c76b79eef71e7ab6b3b2fb3ee79028e2c348 100644 (file)
@@ -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));
     }
index f94eaf99da9ca9d3f5dca948dbe3ba0de4cd8a15..09396c807546b0a1e642e4a1cb369eaf19732c24 100644 (file)
@@ -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];
 
 \f
 /* 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)
     {