configure.ac (gcc_cv_ld_mips_personality_relaxation): New feature check.
gcc/ * 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. From-SVN: r151896
This commit is contained in:
parent
63c6c7e070
commit
49576e25cb
7 changed files with 159 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -1108,6 +1108,13 @@
|
|||
#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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
51
gcc/configure
vendored
51
gcc/configure
vendored
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue