Message ID | 20221117124317.2816607-1-adhemerval.zanella@linaro.org |
---|---|
State | New |
Headers | show |
Series | i386: Avoid avoid rely on linker optimization to avoid relocation | expand |
On Thu, Nov 17, 2022 at 4:43 AM Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote: > > 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. > --- > sysdeps/i386/start.S | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > > diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S > index 4ec04bdfd7..d593c4de00 100644 > --- a/sysdeps/i386/start.S > +++ b/sysdeps/i386/start.S > @@ -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 Shouldn't it be "jmp main@PLT"? > +#endif > END (_start) > > /* To fulfill the System V/i386 ABI we need this symbol. Yuck, it's so > -- > 2.34.1 >
On 17/11/22 13:07, H.J. Lu wrote: > On Thu, Nov 17, 2022 at 4:43 AM Adhemerval Zanella > <adhemerval.zanella@linaro.org> wrote: >> >> 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. >> --- >> sysdeps/i386/start.S | 13 +++++++++---- >> 1 file changed, 9 insertions(+), 4 deletions(-) >> >> diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S >> index 4ec04bdfd7..d593c4de00 100644 >> --- a/sysdeps/i386/start.S >> +++ b/sysdeps/i386/start.S >> @@ -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 > > Shouldn't it be "jmp main@PLT"? My understanding is for static build we can handle main as hidden, so there is no need use a PLT relocation here.
On Thu, Nov 17, 2022 at 8:42 AM Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> wrote: > > > > On 17/11/22 13:07, H.J. Lu wrote: > > On Thu, Nov 17, 2022 at 4:43 AM Adhemerval Zanella > > <adhemerval.zanella@linaro.org> wrote: > >> > >> 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. > >> --- > >> sysdeps/i386/start.S | 13 +++++++++---- > >> 1 file changed, 9 insertions(+), 4 deletions(-) > >> > >> diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S > >> index 4ec04bdfd7..d593c4de00 100644 > >> --- a/sysdeps/i386/start.S > >> +++ b/sysdeps/i386/start.S > >> @@ -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 > > > > Shouldn't it be "jmp main@PLT"? > > My understanding is for static build we can handle main as hidden, so there > is no need use a PLT relocation here. The original comments have it is relocated. Don't use "leal main@GOTOFF(%ebx), %eax" since main may be in a shared object. Linker will convert If this is only used for static build, we can use "leal main@GOTOFF(%ebx), %eax".
On 17/11/22 13:52, H.J. Lu wrote: > On Thu, Nov 17, 2022 at 8:42 AM Adhemerval Zanella Netto > <adhemerval.zanella@linaro.org> wrote: >> >> >> >> On 17/11/22 13:07, H.J. Lu wrote: >>> On Thu, Nov 17, 2022 at 4:43 AM Adhemerval Zanella >>> <adhemerval.zanella@linaro.org> wrote: >>>> >>>> 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. >>>> --- >>>> sysdeps/i386/start.S | 13 +++++++++---- >>>> 1 file changed, 9 insertions(+), 4 deletions(-) >>>> >>>> diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S >>>> index 4ec04bdfd7..d593c4de00 100644 >>>> --- a/sysdeps/i386/start.S >>>> +++ b/sysdeps/i386/start.S >>>> @@ -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 >>>> + 955774751b71c4bc94029dd541ad9d34634ec995 __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 >>> >>> Shouldn't it be "jmp main@PLT"? >> >> My understanding is for static build we can handle main as hidden, so there >> is no need use a PLT relocation here. > > The original comments have > > it is relocated. Don't use "leal main@GOTOFF(%ebx), %eax" > since main may be in a shared object. Linker will convert > > If this is only used for static build, we can use "leal > main@GOTOFF(%ebx), %eax". > It does not work with binutils (and that's why you installed 955774751b71c4): $ make test t=elf/tst-main1 [...] csu/crt1.o(.text+0x1e): unresolvable R_386_GOTOFF relocation against symbol `main' collect2: error: ld returned 1 exit status The start.o (PIC and !SHARED) is used for crt1.o. With 'main' requirement, leal does work for building tst-main1, so maybe one option could to add a .global main to pull the symbol.
On Thu, Nov 17, 2022 at 9:28 AM Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> wrote: > > > > On 17/11/22 13:52, H.J. Lu wrote: > > On Thu, Nov 17, 2022 at 8:42 AM Adhemerval Zanella Netto > > <adhemerval.zanella@linaro.org> wrote: > >> > >> > >> > >> On 17/11/22 13:07, H.J. Lu wrote: > >>> On Thu, Nov 17, 2022 at 4:43 AM Adhemerval Zanella > >>> <adhemerval.zanella@linaro.org> wrote: > >>>> > >>>> 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. > >>>> --- > >>>> sysdeps/i386/start.S | 13 +++++++++---- > >>>> 1 file changed, 9 insertions(+), 4 deletions(-) > >>>> > >>>> diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S > >>>> index 4ec04bdfd7..d593c4de00 100644 > >>>> --- a/sysdeps/i386/start.S > >>>> +++ b/sysdeps/i386/start.S > >>>> @@ -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 > >>>> + 955774751b71c4bc94029dd541ad9d34634ec995 __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 > >>> > >>> Shouldn't it be "jmp main@PLT"? > >> > >> My understanding is for static build we can handle main as hidden, so there > >> is no need use a PLT relocation here. > > > > The original comments have > > > > it is relocated. Don't use "leal main@GOTOFF(%ebx), %eax" > > since main may be in a shared object. Linker will convert > > > > If this is only used for static build, we can use "leal > > main@GOTOFF(%ebx), %eax". > > > > It does not work with binutils (and that's why you installed 955774751b71c4): > > $ make test t=elf/tst-main1 > [...] > csu/crt1.o(.text+0x1e): unresolvable R_386_GOTOFF relocation against symbol `main' > collect2: error: ld returned 1 exit status > > The start.o (PIC and !SHARED) is used for crt1.o. With 'main' requirement, leal > does work for building tst-main1, so maybe one option could to add a .global main > to pull the symbol. That is because it is also used for dynamic executables. I think PLT should be used.
On Nov 17 2022, Adhemerval Zanella via Libc-alpha wrote:
> + it is relocated. This also avoid rely on linker optimization to
avoids relying
diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S index 4ec04bdfd7..d593c4de00 100644 --- a/sysdeps/i386/start.S +++ b/sysdeps/i386/start.S @@ -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 +#endif END (_start) /* To fulfill the System V/i386 ABI we need this symbol. Yuck, it's so