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

Reply via email to