[PATCH] Work around Solaris ld.so bug

Jakub Jelinek jakub@redhat.com
Thu Dec 27 09:41:00 GMT 2001


Hi!

As has been already discussed, the following patch:
a) forces DW_EH_PE_aligned if using Solaris native as/linker, due to
   Solaris ld.so bug
b) if using recent enough binutils, uses unaligned PC relative relocs
   (although Solaris as accepts .uaword %r_disp32(.LFB234), it fails
   to link it unless the data is aligned in the section)
Ok to commit?

2001-12-27  Jakub Jelinek  <jakub@redhat.com>

	* config/sparc/sparc.h (ASM_PREFERRED_EH_DATA_FORMAT,
	ASM_OUTPUT_DWARF_PCREL): Define.
	* config/sparc/sol2.h (ASM_PREFERRED_EH_DATA_FORMAT): Define.
	* configure.in (HAVE_AS_SPARC_UA_PCREL): Check whether as supports
	.uaword %r_disp32() and linker handles it correctly.
	* configure, config.in: Rebuilt.

--- gcc/config/sparc/sparc.h.jj	Thu Dec 27 13:49:49 2001
+++ gcc/config/sparc/sparc.h	Thu Dec 27 19:19:35 2001
@@ -1969,6 +1969,32 @@ do {									\
 #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 24 : INVALID_REGNUM)
 #define EH_RETURN_STACKADJ_RTX	gen_rtx_REG (Pmode, 1)	/* %g1 */
 #define EH_RETURN_HANDLER_RTX	gen_rtx_REG (Pmode, 31)	/* %i7 */
+
+/* Select a format to encode pointers in exception handling data.  CODE
+   is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
+   true if the symbol may be affected by dynamic relocations.
+
+   If assembler and linker properly support .uaword %r_disp32(foo),
+   then use PC relative 32-bit relocations instead of absolute relocs
+   for shared libraries.  On sparc64, use pc relative 32-bit relocs even
+   for binaries, to save memory.  */
+#ifdef HAVE_AS_SPARC_UA_PCREL
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)			\
+  (flag_pic								\
+   ? (GLOBAL ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4\
+   : ((TARGET_ARCH64 && ! GLOBAL)					\
+      ? (DW_EH_PE_pcrel | DW_EH_PE_sdata4)				\
+      : DW_EH_PE_absptr))
+
+/* Emit a PC-relative relocation.  */
+#define ASM_OUTPUT_DWARF_PCREL(FILE, SIZE, LABEL)	\
+  do {							\
+    fputs (integer_asm_op (SIZE, FALSE), FILE);		\
+    fprintf (FILE, "%%r_disp%d(", SIZE * 8);		\
+    assemble_name (FILE, LABEL);			\
+    fputc (')', FILE);					\
+  } while (0)
+#endif
 
 /* Addressing modes, and classification of registers for them.  */
 
--- gcc/config/sparc/sol2.h.jj	Tue Dec 18 01:29:19 2001
+++ gcc/config/sparc/sol2.h	Thu Dec 27 19:01:08 2001
@@ -184,6 +184,17 @@ Boston, MA 02111-1307, USA.  */
    || (CHAR) == 'h' \
    || (CHAR) == 'x' \
    || (CHAR) == 'z')
+
+/* Select a format to encode pointers in exception handling data.  CODE
+   is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
+   true if the symbol may be affected by dynamic relocations.
+
+   Some Solaris dynamic linkers don't handle unaligned section relative
+   relocs properly, so force them to be aligned.  */
+#ifndef HAVE_AS_SPARC_UA_PCREL
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)	\
+  (flag_pic ? DW_EH_PE_aligned : DW_EH_PE_absptr)
+#endif
 
 /* ??? This does not work in SunOS 4.x, so it is not enabled in sparc.h.
    Instead, it is enabled here, because it does work under Solaris.  */
--- gcc/configure.jj	Thu Dec 27 13:49:24 2001
+++ gcc/configure	Thu Dec 27 19:04:41 2001
@@ -7408,6 +7408,34 @@ EOF
 
     fi
 
+    echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
+echo "configure:7413: checking assembler and linker support unaligned pc related relocs" >&5
+if eval "test \"`echo '$''{'gcc_cv_as_sparc_ua_pcrel'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	gcc_cv_as_sparc_ua_pcrel=unknown
+	if test x$gcc_cv_as != x -a x$gcc_cv_ld != x; then
+	    gcc_cv_as_sparc_ua_pcrel=no
+	    echo ".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo)" > conftest.s
+	    if $gcc_cv_as -K PIC -o conftest.o conftest.s > /dev/null 2>&1; then
+		if $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
+		    gcc_cv_as_sparc_ua_pcrel=yes
+		fi
+	    fi
+	    rm -f conftest.s conftest.o conftest
+	fi
+    
+fi
+
+echo "$ac_t""$gcc_cv_as_sparc_ua_pcrel" 1>&6
+    if test "x$gcc_cv_as_sparc_ua_pcrel" = xyes; then
+	cat >> confdefs.h <<\EOF
+#define HAVE_AS_SPARC_UA_PCREL 1
+EOF
+
+    fi
+
     case "$tm_file" in
     *64*)
 	echo $ac_n "checking for 64 bit support in assembler ($gcc_cv_as)""... $ac_c" 1>&6
--- gcc/configure.in.jj	Thu Dec 27 13:49:24 2001
+++ gcc/configure.in	Thu Dec 27 19:04:27 2001
@@ -1706,6 +1706,25 @@ EOF
 		[Define if your assembler supports -relax option.])
     fi
 
+    AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
+	gcc_cv_as_sparc_ua_pcrel, [
+	gcc_cv_as_sparc_ua_pcrel=unknown
+	if test x$gcc_cv_as != x -a x$gcc_cv_ld != x; then
+	    gcc_cv_as_sparc_ua_pcrel=no
+	    echo ".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo)" > conftest.s
+	    if $gcc_cv_as -K PIC -o conftest.o conftest.s > /dev/null 2>&1; then
+		if $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
+		    gcc_cv_as_sparc_ua_pcrel=yes
+		fi
+	    fi
+	    rm -f conftest.s conftest.o conftest
+	fi
+    ])
+    if test "x$gcc_cv_as_sparc_ua_pcrel" = xyes; then
+	AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
+		[Define if your assembler and linker support unaligned PC relative relocs.])
+    fi
+
     case "$tm_file" in
     *64*)
 	AC_CACHE_CHECK([for 64 bit support in assembler ($gcc_cv_as)],
--- gcc/config.in.jj	Tue Dec 18 01:28:09 2001
+++ gcc/config.in	Thu Dec 27 18:33:47 2001
@@ -535,6 +535,9 @@
 /* Define if your assembler supports -relax option. */
 #undef HAVE_AS_RELAX_OPTION
 
+/* Define if your assembler and linker support unaligned PC relative relocs. */
+#undef HAVE_AS_SPARC_UA_PCREL
+
 /* Define if the assembler supports 64bit sparc. */
 #undef AS_SPARC64_FLAG
 

	Jakub



More information about the Gcc-patches mailing list