bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/21782] Fail to create static PIE with undefined weak symbols


From: i at maskray dot me
Subject: [Bug ld/21782] Fail to create static PIE with undefined weak symbols
Date: Thu, 08 Jul 2021 19:32:24 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=21782

Fangrui Song <i at maskray dot me> changed:

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

--- Comment #6 from Fangrui Song <i at maskray dot me> ---
I think suppressing the diagnostic is wrong (QoI issue).

% cat x86.s
.globl _start
.weak foo
_start:
  leaq foo(%rip), %rax
% gcc -fuse-ld=bfd -pie -nostdlib x86.s
# incorrectly passed

The correct behavior should be an error like aarch64 (and many other ports):

% cat a64.s
.globl _start
.weak foo
_start:
  adrp    x0, foo
% aarch64-linux-gnu-gcc -pie -nostdlib a64.s
/usr/lib/gcc-cross/aarch64-linux-gnu/10/../../../../aarch64-linux-gnu/bin/ld:
/tmp/ccdNIlJG.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `foo'
which may bind externally can not be used when making a shared object;
recompile with -fPIC
/tmp/ccdNIlJG.o: in function `_start':
(.text+0x0): dangerous relocation: unsupported relocation
collect2: error: ld returned 1 exit status


The compiler uses GOT indirection for external weak objects, so being rigid for
PC-relative relocation referencing an undefined weak symbol in ld isn't a
compatibility problem.

% cat a.c
__attribute__((weak)) extern int var;
int *f() { return &var; }
% gcc -fpie -O2 -S a.c -o - | grep var
        movq    var@GOTPCREL(%rip), %rax
        .weak   var

---

The glibc configure-time check should be changed to use GOT:

--- i/sysdeps/x86_64/configure
+++ w/sysdeps/x86_64/configure
@@ -118,7 +118,7 @@ else
        .global _start
        .weak foo
 _start:
-       leaq    foo(%rip), %rax
+       leaq    foo@gotpcrel(%rip), %rax
 EOF
   libc_cv_pie_option="-Wl,-pie"
   if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib
$no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&5'
diff --git i/sysdeps/x86_64/configure.ac w/sysdeps/x86_64/configure.ac
index ec776274af..e0639bc68e 100644
--- i/sysdeps/x86_64/configure.ac
+++ w/sysdeps/x86_64/configure.ac
@@ -64,7 +64,7 @@ cat > conftest.s <<\EOF
        .global _start
        .weak foo
 _start:
-       leaq    foo(%rip), %rax
+       leaq    foo@gotpcrel(%rip), %rax
 EOF
   libc_cv_pie_option="-Wl,-pie"
   if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles
-nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s
1>&AS_MESSAGE_LOG_FD); then


I tested a trunk ld.lld (will be included in 13.0.0) which reports `error:
relocation R_X86_64_PC32 cannot be used against symbol foo; recompile with
-fPIC`
glibc build with /usr/local/bin/ld pointing to ld.lld works
with
"csu: Skip ARCH_SETUP_IREL if _dl_relocate_static_pie applied IRELATIVE
relocations"
and
"configure: Allow LD to be LLD 9.0.0 or above"
i.e. glibc build doesn't need the diagnostic suppression.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]