diff options
author | Sandra Loosemore <sandra@codesourcery.com> | 2020-01-31 16:46:50 -0800 |
---|---|---|
committer | Sandra Loosemore <sandra@codesourcery.com> | 2020-01-31 16:46:50 -0800 |
commit | 2d33dcfe9f0494c9b56a8d704c3d27c5a4329ebc (patch) | |
tree | f552c2ff1a82a7100904140e5c4f9f20085aee0e /gcc/config/nios2 | |
parent | 20fa702b32c7ec7a7215df322d3e8d19b79f2068 (diff) | |
download | gcc-2d33dcfe9f0494c9b56a8d704c3d27c5a4329ebc.zip gcc-2d33dcfe9f0494c9b56a8d704c3d27c5a4329ebc.tar.gz gcc-2d33dcfe9f0494c9b56a8d704c3d27c5a4329ebc.tar.bz2 |
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.
Diffstat (limited to 'gcc/config/nios2')
-rw-r--r-- | gcc/config/nios2/nios2.h | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/gcc/config/nios2/nios2.h b/gcc/config/nios2/nios2.h index 78b538b..e81b928 100644 --- a/gcc/config/nios2/nios2.h +++ b/gcc/config/nios2/nios2.h @@ -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. */ |