i386: Avoid rely on linker optimization to avoid relocation

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>
This commit is contained in:
Adhemerval Zanella Netto 2022-11-17 15:13:08 -03:00 committed by Adhemerval Zanella
parent eb4181e9f4
commit 59aa41585f

View File

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