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