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:
Richard Sandiford 2009-09-20 10:36:05 +00:00 committed by Richard Sandiford
parent 63c6c7e070
commit 49576e25cb
7 changed files with 159 additions and 0 deletions

View 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

View file

@ -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

View 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.

View 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)

51
gcc/configure vendored
View file

@ -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

View 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

View 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,