nios2: Support for GOT-relative DW_EH_PE_datarel encoding.
On nios2-linux-gnu, there has been a long-standing bug in C++ exception handling that sometimes resulted in link errors like ../nios2-linux-gnu/bin/ld: FDE encoding in /tmp/cccfpQ2l.o(.eh_frame) prevents .eh_frame_hdr table being created when building some shared libraries or PIE executables. The root of the problem is that GCC was incorrectly emitting an absolute encoding in EH tables for PIC. This patch changes it to use either DW_EH_PE_indirect (for global) or DW_EH_PE_datarel (for local), and fixes libgcc so it can find the address of the GOT as the base address for DW_EH_PE_datarel. Complicating matters somewhat, GAS was missing support for %gotoff(symbol) relocation syntax. I have just pushed a fix for that, but I've added a configure check to test for presence of the binutils support and fall back to the current absolute encoding (which works most of the time) if it is not available. Once the fix makes it into an official binutils release it might be appropriate to make this error out instead. Since this is a wrong-code bug and affects only nios2 target, I think this is appropriate for Stage 4. I regression-tested on both nios2-linux-gnu and nios2-elf, with and without the binutils support present, before committing this. 2020-01-31 Sandra Loosemore <sandra@codesourcery.com> gcc/ * configure.ac [nios2-*-*]: Check HAVE_AS_NIOS2_GOTOFF_RELOCATION. * config.in: Regenerated. * configure: Regenerated. * config/nios2/nios2.h (ASM_PREFERRED_EH_DATA_FORMAT): Fix handling for PIC when HAVE_AS_NIOS2_GOTOFF_RELOCATION. (ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): New. gcc/testsuite/ * g++.target/nios2/hello-pie.C: New. * g++.target/nios2/nios2.exp: New. libgcc/ * config.host [nios2-*-linux*] (tmake_file, tm_file): Adjust. * config/nios2-elf-lib.h: New. * unwind-dw2-fde-dip.c (_Unwind_IteratePhdrCallback): Use existing code for finding GOT base for nios2.
This commit is contained in:
parent
20fa702b32
commit
2d33dcfe9f
@ -1,3 +1,14 @@
|
||||
2020-01-31 Sandra Loosemore <sandra@codesourcery.com>
|
||||
|
||||
nios2: Support for GOT-relative DW_EH_PE_datarel encoding.
|
||||
|
||||
* configure.ac [nios2-*-*]: Check HAVE_AS_NIOS2_GOTOFF_RELOCATION.
|
||||
* config.in: Regenerated.
|
||||
* configure: Regenerated.
|
||||
* config/nios2/nios2.h (ASM_PREFERRED_EH_DATA_FORMAT): Fix handling
|
||||
for PIC when HAVE_AS_NIOS2_GOTOFF_RELOCATION.
|
||||
(ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): New.
|
||||
|
||||
2020-02-01 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
@ -571,6 +571,12 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Define if your assembler supports %gotoff relocation syntax. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_AS_NIOS2_GOTOFF_RELOCATION
|
||||
#endif
|
||||
|
||||
|
||||
/* Define if your assembler supports the -no-mul-bug-abort option. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_AS_NO_MUL_BUG_ABORT_OPTION
|
||||
|
@ -494,14 +494,40 @@ do { \
|
||||
#define EH_RETURN_DATA_REGNO(N) ((N) <= (LAST_ARG_REGNO - FIRST_ARG_REGNO) \
|
||||
? (N) + FIRST_ARG_REGNO : INVALID_REGNUM)
|
||||
|
||||
/* Nios II has no appropriate relocations for a 32-bit PC-relative or
|
||||
section-relative pointer encoding. This therefore always chooses an
|
||||
absolute representation for pointers. An unfortunate consequence of
|
||||
this is that ld complains about the absolute fde encoding when linking
|
||||
with -shared or -fpie, but the warning is harmless and there seems to
|
||||
be no good way to suppress it. */
|
||||
/* For PIC, use indirect for global references; it'll end up using a dynamic
|
||||
relocation, which we want to keep out of read-only EH sections.
|
||||
For local references, we want to use GOT-relative offsets provided
|
||||
the assembler supports them. For non-PIC, use an absolute encoding. */
|
||||
#ifdef HAVE_AS_NIOS2_GOTOFF_RELOCATION
|
||||
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
|
||||
(flag_pic ? DW_EH_PE_aligned : DW_EH_PE_sdata4)
|
||||
(flag_pic \
|
||||
? ((GLOBAL) \
|
||||
? DW_EH_PE_indirect | DW_EH_PE_absptr \
|
||||
: DW_EH_PE_datarel | DW_EH_PE_sdata4) \
|
||||
: DW_EH_PE_absptr)
|
||||
|
||||
#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
|
||||
do { \
|
||||
if (((ENCODING) & 0xf0) == DW_EH_PE_datarel) \
|
||||
{ \
|
||||
fputs ("\t.4byte %gotoff(", FILE); \
|
||||
output_addr_const (FILE, ADDR); \
|
||||
fputs (")", FILE); \
|
||||
goto DONE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
/* We don't have %gotoff support in the assembler. Fall back to the encoding
|
||||
it used to use instead before the assembler was fixed. This has known
|
||||
bugs but mostly works. */
|
||||
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
|
||||
(flag_pic \
|
||||
? ((GLOBAL) \
|
||||
? DW_EH_PE_indirect | DW_EH_PE_absptr \
|
||||
: DW_EH_PE_aligned) \
|
||||
: DW_EH_PE_absptr)
|
||||
#endif
|
||||
|
||||
/* Misc. parameters. */
|
||||
|
||||
|
37
gcc/configure
vendored
37
gcc/configure
vendored
@ -27973,6 +27973,43 @@ $as_echo "#define HAVE_NEWLIB_NANO_FORMATTED_IO 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
;;
|
||||
nios2-*-*)
|
||||
# Versions 2.33 and earlier lacked support for the %gotoff relocation
|
||||
# syntax that is documented in the ABI specification.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for support for %gotoff relocations in constant data" >&5
|
||||
$as_echo_n "checking assembler for support for %gotoff relocations in constant data... " >&6; }
|
||||
if ${gcc_cv_as_nios2_gotoff_relocation+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
gcc_cv_as_nios2_gotoff_relocation=no
|
||||
if test x$gcc_cv_as != x; then
|
||||
$as_echo ' .extern foo
|
||||
.data
|
||||
.long %gotoff(foo)' > conftest.s
|
||||
if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
|
||||
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; }
|
||||
then
|
||||
gcc_cv_as_nios2_gotoff_relocation=yes
|
||||
else
|
||||
echo "configure: failed program was" >&5
|
||||
cat conftest.s >&5
|
||||
fi
|
||||
rm -f conftest.o conftest.s
|
||||
fi
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_nios2_gotoff_relocation" >&5
|
||||
$as_echo "$gcc_cv_as_nios2_gotoff_relocation" >&6; }
|
||||
if test $gcc_cv_as_nios2_gotoff_relocation = yes; then
|
||||
|
||||
$as_echo "#define HAVE_AS_NIOS2_GOTOFF_RELOCATION 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
;;
|
||||
riscv*-*-*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .attribute support" >&5
|
||||
$as_echo_n "checking assembler for .attribute support... " >&6; }
|
||||
|
@ -5032,6 +5032,17 @@ pointers into PC-relative form.])
|
||||
configured with --enable-newlib-nano-formatted-io.])
|
||||
fi
|
||||
;;
|
||||
nios2-*-*)
|
||||
# Versions 2.33 and earlier lacked support for the %gotoff relocation
|
||||
# syntax that is documented in the ABI specification.
|
||||
gcc_GAS_CHECK_FEATURE([support for %gotoff relocations in constant data],
|
||||
gcc_cv_as_nios2_gotoff_relocation,,,
|
||||
[ .extern foo
|
||||
.data
|
||||
.long %gotoff(foo)],,
|
||||
[AC_DEFINE(HAVE_AS_NIOS2_GOTOFF_RELOCATION, 1,
|
||||
[Define if your assembler supports %gotoff relocation syntax.])])
|
||||
;;
|
||||
riscv*-*-*)
|
||||
gcc_GAS_CHECK_FEATURE([.attribute support],
|
||||
gcc_cv_as_riscv_attribute, [2,32,0],,
|
||||
|
@ -1,3 +1,10 @@
|
||||
2020-01-31 Sandra Loosemore <sandra@codesourcery.com>
|
||||
|
||||
nios2: Support for GOT-relative DW_EH_PE_datarel encoding.
|
||||
|
||||
* g++.target/nios2/hello-pie.C: New.
|
||||
* g++.target/nios2/nios2.exp: New.
|
||||
|
||||
2020-01-31 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
PR analyzer/93457
|
||||
|
14
gcc/testsuite/g++.target/nios2/hello-pie.C
Normal file
14
gcc/testsuite/g++.target/nios2/hello-pie.C
Normal file
@ -0,0 +1,14 @@
|
||||
// { dg-do run { target *-*-linux* } }
|
||||
// { dg-options "-pie -fpie" }
|
||||
// { dg-output "Hello, pie World" }
|
||||
|
||||
// This test used to give an "FDE encoding" error from the linker due to
|
||||
// the ABI not having appropriate relocations for PIE.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
std::cout << "Hello, pie World" << std::endl;
|
||||
}
|
34
gcc/testsuite/g++.target/nios2/nios2.exp
Normal file
34
gcc/testsuite/g++.target/nios2/nios2.exp
Normal file
@ -0,0 +1,34 @@
|
||||
# Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# GCC testsuite that uses the `dg.exp' driver.
|
||||
|
||||
# Exit immediately if this isn't a nios2 target.
|
||||
if ![istarget nios2*-*-*] then {
|
||||
return
|
||||
}
|
||||
|
||||
# Load support procs.
|
||||
load_lib g++-dg.exp
|
||||
|
||||
# Initialize `dg'.
|
||||
dg-init
|
||||
|
||||
# Main loop.
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] "" ""
|
||||
|
||||
# All done.
|
||||
dg-finish
|
@ -1,3 +1,12 @@
|
||||
2020-01-31 Sandra Loosemore <sandra@codesourcery.com>
|
||||
|
||||
nios2: Support for GOT-relative DW_EH_PE_datarel encoding.
|
||||
|
||||
* config.host [nios2-*-linux*] (tmake_file, tm_file): Adjust.
|
||||
* config/nios2-elf-lib.h: New.
|
||||
* unwind-dw2-fde-dip.c (_Unwind_IteratePhdrCallback): Use existing
|
||||
code for finding GOT base for nios2.
|
||||
|
||||
2020-01-27 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR gcov-profile/93403
|
||||
|
@ -1112,7 +1112,8 @@ nds32*-elf*)
|
||||
esac
|
||||
;;
|
||||
nios2-*-linux*)
|
||||
tmake_file="$tmake_file nios2/t-nios2 nios2/t-linux t-libgcc-pic t-slibgcc-libgcc"
|
||||
tmake_file="$tmake_file nios2/t-nios2 nios2/t-linux t-libgcc-pic t-eh-dw2-dip t-slibgcc-libgcc"
|
||||
tm_file="$tm_file nios2/elf-lib.h"
|
||||
md_unwind_header=nios2/linux-unwind.h
|
||||
;;
|
||||
nios2-*-*)
|
||||
|
24
libgcc/config/nios2/elf-lib.h
Normal file
24
libgcc/config/nios2/elf-lib.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* Target macros for the Nios II port of GCC.
|
||||
Copyright (C) 2015-2020 Free Software Foundation, Inc.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define CRT_GET_RFIB_DATA(dbase) \
|
||||
({ extern void *_gp_got; (dbase) = &_gp_got; })
|
@ -329,7 +329,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
return 1;
|
||||
|
||||
#ifdef CRT_GET_RFIB_DATA
|
||||
# ifdef __i386__
|
||||
# if defined __i386__ || defined __nios2__
|
||||
data->dbase = NULL;
|
||||
if (p_dynamic)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user