Message ID | alpine.LFD.2.21.2011301023470.656242@eddie.linux-mips.org |
---|---|
State | Accepted |
Headers | show |
Series | VAX: Fix the LTO compiler downgrading code to non-PIC model | expand |
On 11/30/20 8:11 AM, Maciej W. Rozycki wrote: > Fix a testsuite failure: > > /tmp/ccL65Mmt.s: Assembler messages: > /tmp/ccL65Mmt.s:36: Warning: Symbol n used as immediate operand in PIC mode. > FAIL: gcc.dg/lto/pr55660 c_lto_pr55660_0.o-c_lto_pr55660_1.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin > > where non-PIC code is substituted by the LTO compiler at the link stage > for what used to be PIC code in the original compilation. This happens > because in the de-facto VAX ELF psABI we rely on code being PIC for GOT > support in dynamic executables and arrange that by having `-fPIC' passed > to the compiler by default by means of a specs recipe. > > That is however canceled where the LTO wrapper is used, by an internal > arrangement in the LTO compiler that clears the PIC flag whenever the > `-flinker-output=exec' option has been used. This has been deliberately > introduced with commit 1ff9ed6fb282 ("re PR lto/67548 (LTO drops weak > binding with "ld -r")")[1]: > > "In the log of PR67548 HJ actually pointed out that we do have API at > linker plugin side which says what type of output is done. This is cool > because we can also use it to drop -fpic when building static binary. > This is common in Firefox, where some objects are built with -fpic and > linked to both binaries and libraries." > > with this code: > > case LTO_LINKER_OUTPUT_EXEC: /* Normal executable */ > flag_pic = 0; > flag_pie = 0; > flag_shlib = 0; > break; > > Consequently code like: > > .L6: > addl3 -8(%fp),$n,%r0 > pushl %r0 > calls $1,foo > addl2 %r0,-12(%fp) > incl -8(%fp) > .L5: > > is produced by the LTO compiler, where a reference to `n' is used that > is invalid in PIC code, because it uses the immediate addressing mode, > denoted by the `$' prefix. > > For that not to happen we must never pass `-flinker-output=exec' to the > LTO compiler unless non-PIC code has been explicitly requested. Using > `-flinker-output=dyn' except for relocatable output would seem the > simplest approach, as it does not fiddle with any of the internal code > model settings beyond what the command-line options have arranged and > therefore lets them remain the same as with the original compilation, > but it breaks as well causing PR lto/69866 to retrigger, as that code > seems sensitive to `flag_shlib': > > lto1: internal compiler error: in add_symbol_to_partition_1, at lto/lto-partition.c:152 > 0x105be1cb add_symbol_to_partition_1 > .../gcc/lto/lto-partition.c:152 > 0x105be443 add_symbol_to_partition_1 > .../gcc/lto/lto-partition.c:194 > 0x105be80f add_symbol_to_partition > .../gcc/lto/lto-partition.c:270 > 0x105bee6f add_sorted_nodes > .../gcc/lto/lto-partition.c:395 > 0x105c0903 lto_balanced_map(int, int) > .../gcc/lto/lto-partition.c:815 > 0x105aa91f do_whole_program_analysis > .../gcc/lto/lto.c:499 > 0x105aac97 lto_main() > .../gcc/lto/lto.c:637 > Please submit a full bug report, > with preprocessed source if appropriate. > Please include the complete backtrace with any bug report. > See <https://gcc.gnu.org/bugs/> for instructions. > lto-wrapper: fatal error: .../gcc/xgcc returned 1 exit status > compilation terminated. > .../usr/bin/vax-netbsdelf-ld: error: lto-wrapper failed > collect2: error: ld returned 1 exit status > compiler exited with status 1 > FAIL: gcc.dg/lto/pr69866 c_lto_pr69866_0.o-c_lto_pr69866_1.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) > > Substitute `-flinker-output=pie' for `-flinker-output=exec' in the specs > then unless `-no-pie' has also been used, preserving the original intent > of emitting PIC code by default for executables while keeping the linker > arrangement unchanged. The LTO compiler uses the `cc1' spec, so keep > `cc1plus' unmodified. > > This makes code like: > > .L6: > movab n,%r0 > addl2 -8(%fp),%r0 > pushl %r0 > calls $1,foo > addl2 %r0,-12(%fp) > incl -8(%fp) > .L5: > > be produced instead corresponding to the fragment quoted above, which is > valid PIC code as it uses the PC-relative addressing mode denoted by the > absence of a prefix to `n' (which can be redirected to GOT as required, > by changing the addressing mode to PC-relative indirect in the operand > specifier). > > Ideally we would instead default to the PIE model for executables, but > that triggers a BFD bug where for a change the LTO wrapper is not used: > > .../usr/bin/vax-netbsdelf-ld: /tmp/ccV2sWQt.ltrans0.ltrans.o: warning: GOT addend of 3 to `n' does not match previous GOT addend of 0 > FAIL: gcc.dg/lto/pr55660 c_lto_pr55660_0.o-c_lto_pr55660_1.o link, -O2 -flto -flto-partition=1to1 -fno-use-linker-plugin > > which is due to assembly code like: > > main: > .word 0 > subl2 $4,%sp > movab n,%r0 > movab n+3,%r2 > clrl %r3 > movb $98,%r1 > .L4: > > and consequently object code like: > > 00000000 <main>: > 0: 00 00 .word 0x0000 # Entry mask: < > > 2: c2 04 5e subl2 $0x4,sp > 5: 9e ef 00 00 movab b <main+0xb>,r0 > 9: 00 00 50 > 7: R_VAX_GOT32 n > c: 9e ef 00 00 movab 12 <main+0x12>,r2 > 10: 00 00 52 > e: R_VAX_GOT32 n+0x3 > 13: d4 53 clrf r3 > 15: 90 8f 62 51 movb $0x62,r1 > > being produced. This would be problematic for external `n', because we > do not support multiple GOT entries for the same symbol referred to with > different offsets in a single link unit. In this case however the LTO > compiler correctly observes that `n' is defined by the executable and > not preemptible and therefore no GOT entry will be made for it. > > Indeed a valid executable is produced: > > 00010548 <main>: > 10548: 00 00 .word 0x0000 # Entry mask: < > > 1054a: c2 04 5e subl2 $0x4,sp > 1054d: 9e ef dd 14 movab 11a30 <n>,r0 > 10551: 00 00 50 > 10554: 9e ef d9 14 movab 11a33 <__bss_start>,r2 > 10558: 00 00 52 > 1055b: d4 53 clrf r3 > 1055d: 90 8f 62 51 movb $0x62,r1 > > despite the warning, but it would be rather bad to have users annoyed > with this message from BFD, however harmless, especially as it triggers > outside LTO compilations as well. > > Therefore this change is the best we can do until binutils have been > fixed. > > References: > > [1] Jan Hubicka, "Getting LTO incremental linking work", > <https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02986.html> > > gcc/ > * config/vax/elf.h (VAX_CC1_SPEC, VAX_CC1PLUS_SPEC): New macros. > * config/vax/netbsd-elf.h (CC1_SPEC): Use VAX_CC1_SPEC rather > than VAX_CC1_AND_CC1PLUS_SPEC. > (CC1PLUS_SPEC): Use VAX_CC1PLUS_SPEC rather than > VAX_CC1_AND_CC1PLUS_SPEC. OK jeff
Index: gcc/gcc/config/vax/elf.h =================================================================== --- gcc.orig/gcc/config/vax/elf.h +++ gcc/gcc/config/vax/elf.h @@ -89,6 +89,16 @@ along with GCC; see the file COPYING3. %{!fpic: \ %{!fPIC:-fPIC}}}" +/* Don't let the LTO compiler switch the PIC options off. */ +#define VAX_CC1_SPEC \ + VAX_CC1_AND_CC1PLUS_SPEC \ + " %{flinker-output=exec" \ + ":%{no-pie:-flinker-output=exec;:-flinker-output=pie};" \ + ":%{flinker-output=*}}" \ + "%<flinker-output*" +#define VAX_CC1PLUS_SPEC \ + VAX_CC1_AND_CC1PLUS_SPEC + /* VAX ELF is always gas; override the generic VAX ASM_SPEC. */ #undef ASM_SPEC Index: gcc/gcc/config/vax/netbsd-elf.h =================================================================== --- gcc.orig/gcc/config/vax/netbsd-elf.h +++ gcc/gcc/config/vax/netbsd-elf.h @@ -35,10 +35,10 @@ along with GCC; see the file COPYING3. #endif #undef CC1_SPEC -#define CC1_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC VAX_CC1_AND_CC1PLUS_SPEC +#define CC1_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC VAX_CC1_SPEC #undef CC1PLUS_SPEC -#define CC1PLUS_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC VAX_CC1_AND_CC1PLUS_SPEC +#define CC1PLUS_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC VAX_CC1PLUS_SPEC #define NETBSD_ENTRY_POINT "__start"