This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

hackery for alpha backtract


I discovered this bit of libgcj lossage via a tussle between
debian and myself which version of libc to install, and so 
wound up with a mixture of glibc 3.3 and cvs.  While I realize
this is hardly a supported configuration, I do believe it 
points to a real bug in libgcc.

At one point I had thought it a good idea to use the zero 
register to terminate the stack backtrace.  This worked great
in gdb, since gdb knows all about such zero registers.  But
the libgcc unwinder doesn't know anything about any registers
that aren't saved to the stack.

Just about exactly a year ago I tried to fix this in libgcc
by arranging for a zero to be stored into the stack frame of
_Unwind_RaiseException.  This worked well, and avoided changes
to the generic part of the compiler.

Except that the mechanism to store the zero triggers off
__builtin_eh_return.  Which is used by _Unwind_RaiseException,
but not _Unwind_Backtrace.  So _Unwind_Backtrace will crash at
the top of the stack, and unlike _Unwind_RaiseException, it's
much more likely to *see* the top of the stack.

So I'm caving and adding a hack to the generic code instead.


r~


        * unwind-dw2.c (_Unwind_GetGR): Honor DWARF_ZERO_REG.
        * doc/tm.texi (DWARF_ZERO_REG): New.

        * config/alpha/alpha.c (alpha_sa_mask, alpha_expand_prologue,
        alpha_expand_epilogue): Revert 2003-09-30 change to store zero.
        * config/alpha/alpha.h (DWARF_ZERO_REG): New.

Index: unwind-dw2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unwind-dw2.c,v
retrieving revision 1.47
diff -c -p -d -r1.47 unwind-dw2.c
*** unwind-dw2.c	20 Sep 2004 22:23:12 -0000	1.47
--- unwind-dw2.c	30 Sep 2004 08:17:18 -0000
*************** _Unwind_GetGR (struct _Unwind_Context *c
*** 125,130 ****
--- 125,135 ----
    int size;
    void *ptr;
  
+ #ifdef DWARF_ZERO_REG
+   if (index == DWARF_ZERO_REG)
+     return 0;
+ #endif
+ 
    index = DWARF_REG_TO_UNWIND_COLUMN (index);
    if (index >= (int) sizeof(dwarf_reg_size_table))
      abort ();
Index: config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.396
diff -c -p -d -r1.396 alpha.c
*** config/alpha/alpha.c	24 Sep 2004 22:57:05 -0000	1.396
--- config/alpha/alpha.c	30 Sep 2004 08:17:19 -0000
*************** alpha_sa_mask (unsigned long *imaskP, un
*** 5924,5934 ****
  	    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.  */
--- 5924,5929 ----
*************** alpha_expand_prologue (void)
*** 6451,6464 ****
  	    reg_offset += 8;
  	  }
  
-       /* Store a zero if requested for unwinding.  */
-       if (imask & (1UL << 31))
- 	{
- 	  emit_frame_store_1 (const0_rtx, sa_reg, sa_bias, reg_offset,
- 			      gen_rtx_REG (Pmode, 31));
- 	  reg_offset += 8;
- 	}
- 
        for (i = 0; i < 31; i++)
  	if (fmask & (1UL << i))
  	  {
--- 6446,6451 ----
*************** alpha_expand_epilogue (void)
*** 6876,6884 ****
  	    reg_offset += 8;
  	  }
  
-       if (imask & (1UL << 31))
- 	reg_offset += 8;
- 
        for (i = 0; i < 31; ++i)
  	if (fmask & (1UL << i))
  	  {
--- 6863,6868 ----
Index: config/alpha/alpha.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.h,v
retrieving revision 1.232
diff -c -p -d -r1.232 alpha.h
*** config/alpha/alpha.h	24 Sep 2004 22:57:08 -0000	1.232
--- config/alpha/alpha.h	30 Sep 2004 08:17:19 -0000
*************** do {						\
*** 1183,1188 ****
--- 1183,1189 ----
  #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)
+ #define DWARF_ZERO_REG 31
  
  /* Describe how we implement __builtin_eh_return.  */
  #define EH_RETURN_DATA_REGNO(N)	((N) < 4 ? (N) + 16 : INVALID_REGNUM)
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.373
diff -c -p -d -r1.373 tm.texi
*** doc/tm.texi	24 Sep 2004 06:17:04 -0000	1.373
--- doc/tm.texi	30 Sep 2004 08:17:20 -0000
*************** general register, but an alternate colum
*** 2974,2979 ****
--- 2974,2987 ----
  signal frames.
  @end defmac
  
+ @defmac DWARF_ZERO_REG
+ A C expression whose value is an integer giving a DWARF 2 register
+ number that is considered to always have the value zero.  This should
+ only be defined if the target has an architected zero register, and
+ someone decided it was a good idea to use that register number to
+ terminate the stack backtrace.  New ports should avoid this.
+ @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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]