

-------- Original Message --------
Subject: Re: gcc 2.95.3 patch for exception handlers
Date: Mon, 22 Jan 2001 10:54:33 +0000
From: Philip Blundell <pb@futuretv.com>
To: doko@debian.org, scottb@netwinder.org

Philip Blundell writes:
>This is a 2.95.3 port of a patch I just checked in to the trunk.  It's needed 
>to make exception handlers in shared libraries work correctly.  (The patch to 
>linux-gas.h is unrelated but I've included it here anyway.)

Here's the corrected version of this patch.  Turns out I'd left part of
it out 
the first time, which was causing some parentheses to go missing.

p.

Content-Description: arm-exception.dpatch
Content-Disposition: attachment; filename="arm-exception.dpatch"

#! /bin/sh -e

# DP: ARM patch for PIC exception handlers

src=gcc
if [ $# -eq 3 -a "$2" = '-d' ]; then
    pdir="-d $3"
    src=$3/gcc
elif [ $# -ne 1 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch)
        patch $pdir -f --no-backup-if-mismatch -p1 --fuzz 10 < $0
        cd $src && autoconf
        ;;
    -unpatch)
        patch $pdir -f --no-backup-if-mismatch -R -p1 --fuzz 10 < $0
        cd $src && autoconf
        ;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as
argument"
        exit 1
esac
exit 0

Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.59.4.4
diff -u -p -u -r1.59.4.4 varasm.c
--- src/gcc/varasm.c	1999/06/09 12:13:49	1.59.4.4
+++ src/gcc/varasm.c	2001/01/16 07:41:57
@@ -3285,7 +3285,10 @@ decode_rtx_const (mode, x, value)
 	  value->un.addr.offset = - INTVAL (XEXP (x, 1));
 	}
       else
-	abort ();
+	{
+	  value->un.addr.base = x;
+	  value->un.addr.offset = 0;
+	}
       break;
 
     default:
Index: config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/arm.c,v
retrieving revision 1.43.4.7
diff -u -p -u -r1.43.4.7 arm.c
--- src/gcc/config/arm/arm.c	2000/12/05 19:55:48	1.43.4.7
+++ src/gcc/config/arm/arm.c	2001/01/16 07:42:21
@@ -1533,22 +1533,16 @@ legitimize_pic_address (orig, mode, reg)
   return orig;
 }
 
-static rtx pic_rtx;
-
-int
-is_pic(x)
-     rtx x;
-{
-  if (x == pic_rtx)
-    return 1;
-  return 0;
-}
-
+/* Generate code to load the PIC register.  PROLOGUE is true if
+   called from arm_expand_prologue (in which case we want the 
+   generated insns at the start of the function);  false if called
+   by an exception receiver that needs the PIC register reloaded
+   (in which case the insns are just dumped at the current location). */
 void
-arm_finalize_pic ()
+arm_finalize_pic (int prologue)
 {
 #ifndef AOF_ASSEMBLER
-  rtx l1, pic_tmp, pic_tmp2, seq;
+  rtx l1, pic_tmp, pic_tmp2, seq, pic_rtx;
   rtx global_offset_table;
 
   if (current_function_uses_pic_offset_table == 0)
@@ -1577,7 +1571,10 @@ arm_finalize_pic ()
 
   seq = gen_sequence ();
   end_sequence ();
-  emit_insn_after (seq, get_insns ());
+  if (prologue)
+    emit_insn_after (seq, get_insns ());
+  else
+    emit_insn (seq);
 
   /* Need to emit this whether or not we obey regdecls,
      since setjmp/longjmp can cause life info to screw up.  */
Index: config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/arm.h,v
retrieving revision 1.34.4.4
diff -u -p -u -r1.34.4.4 arm.h
--- src/gcc/config/arm/arm.h	2000/12/05 19:55:49	1.34.4.4
+++ src/gcc/config/arm/arm.h	2001/01/16 07:42:46
@@ -1811,7 +1811,7 @@ extern int arm_pic_register;
    data addresses in memory.  */
 #define PIC_OFFSET_TABLE_REGNUM arm_pic_register
 
-#define FINALIZE_PIC arm_finalize_pic ()
+#define FINALIZE_PIC arm_finalize_pic (1)
 
 /* We can't directly access anything that contains a symbol,
    nor can we indirect via the constant pool.  */
@@ -2045,17 +2045,9 @@ extern struct rtx_def *arm_compare_op0, 
   else output_addr_const(STREAM, X);					\
 }
 
-/* Handles PIC addr specially */
 #define OUTPUT_INT_ADDR_CONST(STREAM,X) \
   {									\
-    if (flag_pic && GET_CODE(X) == CONST && is_pic(X))			\
-      {									\
-	output_addr_const(STREAM, XEXP (XEXP (XEXP (X, 0), 0), 0));	\
-	fputs(" - (", STREAM);						\
-	output_addr_const(STREAM, XEXP (XEXP (XEXP (X, 0), 1), 0));	\
-	fputs(")", STREAM);						\
-      }									\
-    else output_addr_const(STREAM, X);					\
+    output_addr_const(STREAM, X);					\
 									\
     /* Mark symbols as position independent.  We only do this in the	\
       .text segment, not in the .data segment. */			\
@@ -2169,8 +2161,7 @@ Rcode  arm_canonicalize_comparison RTX_C
 int    arm_return_in_memory PROTO ((Tree));
 int    legitimate_pic_operand_p PROTO ((Rtx));
 Rtx    legitimize_pic_address PROTO ((Rtx, Mmode, Rtx));
-int    is_pic PROTO ((Rtx));
-void   arm_finalize_pic PROTO ((void));
+void   arm_finalize_pic PROTO ((int));
 int    arm_rtx_costs RTX_CODE_PROTO ((Rtx, Rcode));
 int    arm_adjust_cost PROTO ((Rtx, Rtx, Rtx, int));
 int    const_double_rtx_ok_for_fpu PROTO ((Rtx));
Index: config/arm/arm.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/arm.md,v
retrieving revision 1.27.4.4
diff -u -p -u -r1.27.4.4 arm.md
--- src/gcc/config/arm/arm.md	2000/12/05 19:48:09	1.27.4.4
+++ src/gcc/config/arm/arm.md	2001/01/16 07:43:05
@@ -2720,6 +2720,15 @@
   return \"add%?\\t%0, %|pc, %0\";
 ")
 
+(define_expand "builtin_setjmp_receiver"
+  [(label_ref (match_operand 0 "" ""))]
+  "flag_pic"
+  "
+{
+  arm_finalize_pic (0);
+  DONE;
+}")
+
 ;; If copying one reg to another we can set the condition codes according to
 ;; its value.  Such a move is common after a return from subroutine and the
 ;; result is being tested against zero.
Index: config/arm/linux-gas.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/linux-gas.h,v
retrieving revision 1.4
diff -u -p -u -r1.4 linux-gas.h
--- src/gcc/config/arm/linux-gas.h	1999/02/22 16:47:57	1.4
+++ src/gcc/config/arm/linux-gas.h	2001/01/16 07:43:12
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler.
    ARM Linux-based GNU systems version.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    Contributed by Russell King  <rmk92@ecs.soton.ac.uk>.
 
 This file is part of GNU CC.
@@ -79,5 +79,7 @@ Boston, MA 02111-1307, USA.  */
   register unsigned long _beg __asm ("a1") = (unsigned long) (BEG);	\
   register unsigned long _end __asm ("a2") = (unsigned long) (END);	\
   register unsigned long _flg __asm ("a3") = 0;				\
-  __asm __volatile ("swi 0x9f0002");					\
+  __asm __volatile ("swi 0x9f0002		@ sys_cacheflush"	\
+		    : "=r" (_beg)					\
+		    : "0" (_beg), "r" (_end), "r" (_flg));		\
 }
Index: final.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/final.c,v
retrieving revision 1.77.4.1
diff -u -p -u -r1.77.4.1 final.c
--- src/gcc/final.c	1999/06/21 23:21:23	1.77.4.1
+++ src/gcc/final.c	2001/01/21 17:13:56
@@ -3652,8 +3652,9 @@ output_addr_const (file, x)
 
       output_addr_const (file, XEXP (x, 0));
       fprintf (file, "-");
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
-	  && INTVAL (XEXP (x, 1)) < 0)
+      if ((GET_CODE (XEXP (x, 1)) == CONST_INT
+	   && INTVAL (XEXP (x, 1)) < 0)
+	  || GET_CODE (XEXP (x, 1)) != CONST_INT)
 	{
 	  fprintf (file, ASM_OPEN_PAREN);
 	  output_addr_const (file, XEXP (x, 1));
