]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
i386: Avoid rely on linker optimization to avoid relocation
authorAdhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Thu, 17 Nov 2022 18:13:08 +0000 (15:13 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 21 Nov 2022 14:25:35 +0000 (11:25 -0300)
lld does not implement all the linker optimization to avoid the GOT
relocation as done by binutils (bfd/elf32-i386.c:elf_i386_convert_load_reloc).
The current 'movl main@GOT(%ebx), %eax' will then create a GOT
relocation when building with lld, which make static-pie status to
not being able to start the provided main function.

The change uses a __wrap_main local symbol, which in turn calls main
(similar as used by aarch64 and s390x).

Checked on i686-linux-gnu with binutils and lld.
Reviewed-by: Fangrui Song <maskray@google.com>
sysdeps/i386/start.S

index 4ec04bdfd7b118c1aaaed3ddd809455d93f65885..23e4f2b012d02701e95cdb3d43e64e6be3212236 100644 (file)
@@ -98,11 +98,10 @@ ENTRY (_start)
        pushl main@GOT(%ebx)
 # else
        /* Avoid relocation in static PIE since _start is called before
-          it is relocated.  Don't use "leal main@GOTOFF(%ebx), %eax"
-          since main may be in a shared object.  Linker will convert
-          "movl main@GOT(%ebx), %eax" to "leal main@GOTOFF(%ebx), %eax"
+          it is relocated.  This also avoid rely on linker optimization to
+          transform 'movl main@GOT(%ebx), %eax' to 'leal main@GOTOFF(%ebx)'
           if main is defined locally.  */
-       movl main@GOT(%ebx), %eax
+       leal __wrap_main@GOTOFF(%ebx), %eax
        pushl %eax
 # endif
 
@@ -130,6 +129,12 @@ ENTRY (_start)
 1:     movl    (%esp), %ebx
        ret
 #endif
+
+#if defined PIC && !defined SHARED
+__wrap_main:
+       _CET_ENDBR
+       jmp     main@PLT
+#endif
 END (_start)
 
 /* To fulfill the System V/i386 ABI we need this symbol.  Yuck, it's so