https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94391

Fangrui Song <i at maskray dot me> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |i at maskray dot me

--- Comment #5 from Fangrui Song <i at maskray dot me> ---
This bug exposes several problems:

* GNU ld does not reject a PC-relative relocation referencing a SHN_ABS symbol
* GCC should not produce R_X86_64_PC32 referencing an external symbol in -fpie
mode. 

% gcc -fuse-ld=lld -nostdlib -fpie -pie a.c
% objdump -dr a.o
...
0000000000000000 <foo>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 8d 05 00 00 00 00    lea    0x0(%rip),%rax        # b <foo+0xb>
                        7: R_X86_64_PC32        _binary_a_c_size-0x4
   b:   5d                      pop    %rbp
   c:   c3                      retq

% gcc -fuse-ld=bfd -nostdlib -fpie -pie a.c b.o -o a
/usr/bin/ld.bfd: warning: cannot find entry symbol _start; defaulting to
0000000000001000
% objdump -dr a
...
0000000000001000 <foo>:
    1000:       55                      push   %rbp
    1001:       48 89 e5                mov    %rsp,%rbp
    1004:       48 8d 05 39 f0 ff ff    lea    -0xfc7(%rip),%rax        # 44
<_binary_a_c_size>
    100b:       5d                      pop    %rbp
    100c:       c3                      retq

It is incorrect to reference a non-preemptible symbol with a PC relative
relocation in a -pie link. GNU ld allows it but the code can be incorrect at
runtime.

lea    -0xfc7(%rip),%rax  # loads 44 to %rax only if the load base is 0. Due to
ASLR (-pie), this is simply not true.

lld correctly rejects the relocation.

To fix this, I had a write-up last year:
https://gcc.gnu.org/legacy-ml/gcc/2019-05/msg00215.html
We should change the configure-time HAVE_LD_PIE_COPYRELOC to an option,
probably -f(no-)direct-access-extern

In clang, HAVE_LD_PIE_COPYRELOC is a compile-time option:
-mpie-copy-relocations. But I think we should improve the option name. At the
very least, we can also let -fno-pic code reference an external symbol with GOT
to avoid copy relocations. -f(no-)direct-access-extern may be a candidate.

Reply via email to