gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 20 Sep 2009 10:36:05 +0000 (10:36 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 20 Sep 2009 10:36:05 +0000 (10:36 +0000)
* configure.ac (gcc_cv_ld_mips_personality_relaxation): New
feature check.
(HAVE_LD_PERSONALITY_RELAXATION): New macro definition.
* configure, config.in: Regenerate.
* dwarf2asm.c (eh_data_format_name): Handle DW_EH_PE_indirect |
DW_EH_PE_absptr.
* config/mips/mips.h (TARGET_WRITABLE_EH_FRAME): New macro.
(ASM_PREFERRED_EH_DATA_FORMAT): Define.  Use MIPS_EH_INDIRECT
for global data if the output could be used in a shared library.
* config/mips/mips.c (mips_override_options): Set flag_dwarf2_cfi_asm
to 0 if TARGET_WRITABLE_EH_FRAME.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151896 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config.in
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/configure
gcc/configure.ac
gcc/dwarf2asm.c

index 9ed696d..91b323e 100644 (file)
@@ -1,3 +1,17 @@
+2009-09-20  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * configure.ac (gcc_cv_ld_mips_personality_relaxation): New
+       feature check.
+       (HAVE_LD_PERSONALITY_RELAXATION): New macro definition.
+       * configure, config.in: Regenerate.
+       * dwarf2asm.c (eh_data_format_name): Handle DW_EH_PE_indirect |
+       DW_EH_PE_absptr.
+       * config/mips/mips.h (TARGET_WRITABLE_EH_FRAME): New macro.
+       (ASM_PREFERRED_EH_DATA_FORMAT): Define.  Use MIPS_EH_INDIRECT
+       for global data if the output could be used in a shared library.
+       * config/mips/mips.c (mips_override_options): Set flag_dwarf2_cfi_asm
+       to 0 if TARGET_WRITABLE_EH_FRAME.
+
 2009-09-20  Paolo Bonzini <bonzini@gnu.org>
 
        PR/39886
index 40d7e4d..9ee0bde 100644 (file)
 #endif
 
 
+/* Define if your linker can relax absolute .eh_frame personality pointers
+   into PC-relative form. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_LD_PERSONALITY_RELAXATION
+#endif
+
+
 /* Define if your linker supports -pie option. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_LD_PIE
index 2f0c56d..ace48ba 100644 (file)
@@ -15528,6 +15528,11 @@ mips_override_options (void)
   if (mips_abi == ABI_EABI && TARGET_64BIT)
     flag_dwarf2_cfi_asm = 0;
 
+  /* .cfi_* directives generate a read-only section, so fall back on
+     manual .eh_frame creation if we need the section to be writable.  */
+  if (TARGET_WRITABLE_EH_FRAME)
+    flag_dwarf2_cfi_asm = 0;
+
   mips_init_print_operand_punct ();
 
   /* Set up array to map GCC register number to debug register number.
index 71b9b1b..defcd6e 100644 (file)
@@ -230,6 +230,14 @@ enum mips_code_readable_setting {
    && !TARGET_ABSOLUTE_ABICALLS                        \
    && !(mips_abi == ABI_64 && TARGET_IRIX))
 
+/* True if the output must have a writable .eh_frame.
+   See ASM_PREFERRED_EH_DATA_FORMAT for details.  */
+#ifdef HAVE_LD_PERSONALITY_RELAXATION
+#define TARGET_WRITABLE_EH_FRAME 0
+#else
+#define TARGET_WRITABLE_EH_FRAME (flag_pic && TARGET_SHARED)
+#endif
+
 /* Generate mips16 code */
 #define TARGET_MIPS16          ((target_flags & MASK_MIPS16) != 0)
 /* Generate mips16e code. Default 16bit ASE for mips32* and mips64* */
@@ -3182,3 +3190,30 @@ extern enum mips_code_readable_setting mips_code_readable;
 /* This is necessary to avoid a warning about comparing different enum
    types.  */
 #define mips_tune_attr ((enum attr_cpu) mips_tune)
+
+/* As on most targets, we want the .eh_frame section to be read-only where
+   possible.  And as on most targets, this means two things:
+
+     (a) Non-locally-binding pointers must have an indirect encoding,
+        so that the addresses in the .eh_frame section itself become
+        locally-binding.
+
+     (b) A shared library's .eh_frame section must encode locally-binding
+        pointers in a relative (relocation-free) form.
+
+   However, MIPS has traditionally not allowed directives like:
+
+       .long   x-.
+
+   in cases where "x" is in a different section, or is not defined in the
+   same assembly file.  We are therefore unable to emit the PC-relative
+   form required by (b) at assembly time.
+
+   Fortunately, the linker is able to convert absolute addresses into
+   PC-relative addresses on our behalf.  Unfortunately, only certain
+   versions of the linker know how to do this for indirect pointers,
+   and for personality data.  We must fall back on using writable
+   .eh_frame sections for shared libraries if the linker does not
+   support this feature.  */
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
+  (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_absptr)
index 2369ba7..ced17cd 100755 (executable)
@@ -23725,6 +23725,57 @@ $as_echo_n "checking assembler and linker for explicit JALR relocation... " >&6;
     fi
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ld_jalr_reloc" >&5
 $as_echo "$gcc_cv_as_ld_jalr_reloc" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for .eh_frame personality relaxation" >&5
+$as_echo_n "checking linker for .eh_frame personality relaxation... " >&6; }
+if test "${gcc_cv_ld_mips_personality_relaxation+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_ld_mips_personality_relaxation=no
+       if test $in_tree_ld = yes ; then
+        if test "$gcc_cv_gld_major_version" -eq 2 \
+                -a "$gcc_cv_gld_minor_version" -ge 21 \
+                -o "$gcc_cv_gld_major_version" -gt 2; then
+          gcc_cv_ld_mips_personality_relaxation=yes
+        fi
+       elif test x$gcc_cv_as != x \
+                        -a x$gcc_cv_ld != x \
+                -a x$gcc_cv_readelf != x ; then
+        cat > conftest.s <<EOF
+       .cfi_startproc
+       .cfi_personality 0x80,indirect_ptr
+       .ent test
+test:
+       nop
+       .end test
+       .cfi_endproc
+
+       .section .data,"aw",@progbits
+indirect_ptr:
+       .dc.a personality
+EOF
+        if $gcc_cv_as -KPIC -o conftest.o conftest.s > /dev/null 2>&1 \
+           && $gcc_cv_ld -o conftest conftest.o -shared > /dev/null 2>&1; then
+          if $gcc_cv_readelf -d conftest 2>&1 \
+             | grep TEXTREL > /dev/null 2>&1; then
+            :
+          elif $gcc_cv_readelf --relocs conftest 2>&1 \
+               | grep 'R_MIPS_REL32 *$' > /dev/null 2>&1; then
+            :
+          else
+            gcc_cv_ld_mips_personality_relaxation=yes
+          fi
+        fi
+       fi
+       rm -f conftest.s conftest.o conftest
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_mips_personality_relaxation" >&5
+$as_echo "$gcc_cv_ld_mips_personality_relaxation" >&6; }
+    if test x$gcc_cv_ld_mips_personality_relaxation = xyes; then
+
+$as_echo "#define HAVE_LD_PERSONALITY_RELAXATION 1" >>confdefs.h
+
+    fi
     ;;
 esac
 
index d1eed72..3f0ff7d 100644 (file)
@@ -3315,6 +3315,51 @@ x:
       fi
     fi
     AC_MSG_RESULT($gcc_cv_as_ld_jalr_reloc)
+
+    AC_CACHE_CHECK([linker for .eh_frame personality relaxation],
+      [gcc_cv_ld_mips_personality_relaxation],
+      [gcc_cv_ld_mips_personality_relaxation=no
+       if test $in_tree_ld = yes ; then
+        if test "$gcc_cv_gld_major_version" -eq 2 \
+                -a "$gcc_cv_gld_minor_version" -ge 21 \
+                -o "$gcc_cv_gld_major_version" -gt 2; then
+          gcc_cv_ld_mips_personality_relaxation=yes
+        fi
+       elif test x$gcc_cv_as != x \
+                        -a x$gcc_cv_ld != x \
+                -a x$gcc_cv_readelf != x ; then
+        cat > conftest.s <<EOF
+       .cfi_startproc
+       .cfi_personality 0x80,indirect_ptr
+       .ent test
+test:
+       nop
+       .end test
+       .cfi_endproc
+
+       .section .data,"aw",@progbits
+indirect_ptr:
+       .dc.a personality
+EOF
+        if $gcc_cv_as -KPIC -o conftest.o conftest.s > /dev/null 2>&1 \
+           && $gcc_cv_ld -o conftest conftest.o -shared > /dev/null 2>&1; then
+          if $gcc_cv_readelf -d conftest 2>&1 \
+             | grep TEXTREL > /dev/null 2>&1; then
+            :
+          elif $gcc_cv_readelf --relocs conftest 2>&1 \
+               | grep 'R_MIPS_REL32 *$' > /dev/null 2>&1; then
+            :
+          else
+            gcc_cv_ld_mips_personality_relaxation=yes
+          fi
+        fi
+       fi
+       rm -f conftest.s conftest.o conftest])
+    if test x$gcc_cv_ld_mips_personality_relaxation = xyes; then
+           AC_DEFINE(HAVE_LD_PERSONALITY_RELAXATION, 1,
+      [Define if your linker can relax absolute .eh_frame personality
+pointers into PC-relative form.])
+    fi
     ;;
 esac
 
index c12f809..c779e07 100644 (file)
@@ -446,6 +446,8 @@ eh_data_format_name (int format)
   S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
   S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
 
+  S(DW_EH_PE_indirect | DW_EH_PE_absptr, "indirect absolute")
+
   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
     "indirect pcrel")
   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,