x86-64 prelink support for TLS dialect gnu2

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

x86-64 prelink support for TLS dialect gnu2

Steven Newbury-2
I'm working on gettting TLS gnu2 dialect support working for x86-64
with prelink.  Yes, it's still maintained, see:
https://git.yoctoproject.org/cgit/cgit.cgi/prelink-cross/

I've written the attached patch which enables prelink to recognise
R_X86_64_TLSDESC relocations and do the same as is done currently for
ARM.  Unfortunately, while this seems to work, when a prelinked binary
is loaded with a shared library with such a relocation it fails with:

  "error while loading shared libraries: unexpected reloc type 0x24".

reloc type 0x24 is indeed R_X86_64_TLSDESC.

The strange thing is the code in glibc which generates this error
(sysdeps/x86_64/dl-machine.h) specifically handles R_X86_64_TLSDESC.
I can't understand how it is falling through to _dl_reloc_bad_type ()
with reloc 0x24 since in both instances the error case shouldn't be
reached!

Can anybody help?

0001-Add-support-for-R_X86_64_TLSDESC.patch (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: x86-64 prelink support for TLS dialect gnu2

Andreas Schwab
On Nov 05 2018, Steven Newbury <[hidden email]> wrote:

> The strange thing is the code in glibc which generates this error
> (sysdeps/x86_64/dl-machine.h) specifically handles R_X86_64_TLSDESC.
> I can't understand how it is falling through to _dl_reloc_bad_type ()
> with reloc 0x24 since in both instances the error case shouldn't be
> reached!

Are you sure you are running the patched ld.so?

Andreas.

--
Andreas Schwab, SUSE Labs, [hidden email]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
Reply | Threaded
Open this post in threaded view
|

Re: x86-64 prelink support for TLS dialect gnu2

Steven Newbury-2
ld.so isn't (yet) patched.  The patch is for prelink, and mirrors what
is already in
place for ARM.  The ld.so appears, to me at least, to already have all the
support in place, although possibly never tested.  Up to now prelink just failed
on tls-dialect=gnu2 with an "Unsupported relocation type" error.  This only
applies of course objects ending up with type 0x24 relocations, like libstdc++!!
;-)



On Mon, 5 Nov 2018 at 17:02, Andreas Schwab <[hidden email]> wrote:

>
> On Nov 05 2018, Steven Newbury <[hidden email]> wrote:
>
> > The strange thing is the code in glibc which generates this error
> > (sysdeps/x86_64/dl-machine.h) specifically handles R_X86_64_TLSDESC.
> > I can't understand how it is falling through to _dl_reloc_bad_type ()
> > with reloc 0x24 since in both instances the error case shouldn't be
> > reached!
>
> Are you sure you are running the patched ld.so?
>
> Andreas.
>
> --
> Andreas Schwab, SUSE Labs, [hidden email]
> GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
> "And now for something completely different."
Reply | Threaded
Open this post in threaded view
|

Re: x86-64 prelink support for TLS dialect gnu2

Szabolcs Nagy-2
In reply to this post by Steven Newbury-2
On 05/11/18 16:21, Steven Newbury wrote:
> I'm working on gettting TLS gnu2 dialect support working for x86-64
> with prelink.  Yes, it's still maintained, see:
> https://git.yoctoproject.org/cgit/cgit.cgi/prelink-cross/
>

prelinking for tlsdesc was never supported in ld.so
on any target.

at some point arm had support in case of lazy binding,
but now lazy binding of tlsdesc is disabled on arm
so that code got removed:

https://sourceware.org/ml/libc-alpha/2017-10/msg01121.html

> I've written the attached patch which enables prelink to recognise
> R_X86_64_TLSDESC relocations and do the same as is done currently for
> ARM.  Unfortunately, while this seems to work, when a prelinked binary
> is loaded with a shared library with such a relocation it fails with:
>
>   "error while loading shared libraries: unexpected reloc type 0x24".
>
> reloc type 0x24 is indeed R_X86_64_TLSDESC.
>
> The strange thing is the code in glibc which generates this error
> (sysdeps/x86_64/dl-machine.h) specifically handles R_X86_64_TLSDESC.
> I can't understand how it is falling through to _dl_reloc_bad_type ()
> with reloc 0x24 since in both instances the error case shouldn't be
> reached!
>
> Can anybody help?
>

Reply | Threaded
Open this post in threaded view
|

Re: x86-64 prelink support for TLS dialect gnu2

Steven Newbury-2
On 05/11/2018, Szabolcs Nagy <[hidden email]> wrote:

> On 05/11/18 16:21, Steven Newbury wrote:
>> I'm working on gettting TLS gnu2 dialect support working for x86-64
>> with prelink.  Yes, it's still maintained, see:
>> https://git.yoctoproject.org/cgit/cgit.cgi/prelink-cross/
>>
>
> prelinking for tlsdesc was never supported in ld.so
> on any target.
>
> at some point arm had support in case of lazy binding,
> but now lazy binding of tlsdesc is disabled on arm
> so that code got removed:
>
I've been comparing the removed code to what is currently in the
x86_64 dl-machine.h and it's almost identical, which makes sense since
x86_64 still supports lazy binding of tlsdesc AFAIK.  The only notable
difference that I see is:

Removed ARM support code

-  if (l->l_info[ADDRIDX (DT_TLSDESC_GOT)] && lazy)
-    *(Elf32_Addr*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_GOT)]) + l->l_addr)
-      = (Elf32_Addr) &_dl_tlsdesc_lazy_resolver;

Currently in x86_64

  if (l->l_info[ADDRIDX (DT_TLSDESC_GOT)] && lazy)
    *(ElfW(Addr)*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_GOT)]) + l->l_addr)
      = (ElfW(Addr)) &_dl_tlsdesc_resolve_rela;

Am I looking in the right place?
Reply | Threaded
Open this post in threaded view
|

Re: x86-64 prelink support for TLS dialect gnu2

Steven Newbury-2
On Mon, 5 Nov 2018, 19:32 Steven Newbury <[hidden email]
wrote:

> On 05/11/2018, Szabolcs Nagy <[hidden email]> wrote:
> > On 05/11/18 16:21, Steven Newbury wrote:
> >> I'm working on gettting TLS gnu2 dialect support working for x86-64
> >> with prelink.  Yes, it's still maintained, see:
> >> https://git.yoctoproject.org/cgit/cgit.cgi/prelink-cross/
> >>
> >
> > prelinking for tlsdesc was never supported in ld.so
> > on any target.
> >
> > at some point arm had support in case of lazy binding,
> > but now lazy binding of tlsdesc is disabled on arm
> > so that code got removed:
> >
> I've been comparing the removed code to what is currently in the
> x86_64 dl-machine.h and it's almost identical, which makes sense since
> x86_64 still supports lazy binding of tlsdesc AFAIK.  The only notable
> difference that I see is:
>
> Removed ARM support code
>
> -  if (l->l_info[ADDRIDX (DT_TLSDESC_GOT)] && lazy)
> -    *(Elf32_Addr*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_GOT)]) +
> l->l_addr)
> -      = (Elf32_Addr) &_dl_tlsdesc_lazy_resolver;
>
> Currently in x86_64
>
>   if (l->l_info[ADDRIDX (DT_TLSDESC_GOT)] && lazy)
>     *(ElfW(Addr)*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_GOT)]) + l->l_addr)
>       = (ElfW(Addr)) &_dl_tlsdesc_resolve_rela;


>
> Am I looking in the right place?
>
 I think not, since that snippet predates the prelink support.

From the reverted ARM prelink patch it's clear the magic is in the
section guarded
by RESOLVE_CONFLICT_FIND_MAP.  The x86_64 code already handles several
different cases of R_X86_64_TLSDESC in that switch so I still don't
understand how it falls through to _dl_reloc_bad_type rather than just
ignoring the prelink suppliied address.  Most of the ARM patch
consists of asserts presumably because the code wasn't fully trusted.
Reply | Threaded
Open this post in threaded view
|

Re: x86-64 prelink support for TLS dialect gnu2

Steven Newbury-2
On 06/11/2018, Steven Newbury <[hidden email]> wrote:

> From the reverted ARM prelink patch it's clear the magic is in the
> section guarded
> by RESOLVE_CONFLICT_FIND_MAP.  The x86_64 code already handles several
> different cases of R_X86_64_TLSDESC in that switch so I still don't
> understand how it falls through to _dl_reloc_bad_type rather than just
> ignoring the prelink suppliied address.  Most of the ARM patch
> consists of asserts presumably because the code wasn't fully trusted.
>
Okay, I've applied the attached patch inserting the code removed from
the ARM dl-machine.h into the x86_64 code handling R_X86_64_TLSDESC.
I still get the same error:

error while loading shared libraries: unexpected reloc type 0x24

Which can only be coming from _dl_reloc_bad_type() after it's fallen
through the switch in elf_machine_rela() or the if-else block in
elf_machine_lazy_rel(), both of which have should not fall through
since R_X86_64_TLSDESC is reloc type 0x24 and it is, or should be
handled!

tlsdesc-prelink.patch (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: x86-64 prelink support for TLS dialect gnu2

Steven Newbury-2
On 06/11/2018, Steven Newbury <[hidden email]> wrote:

> On 06/11/2018, Steven Newbury <[hidden email]> wrote:
>
>> From the reverted ARM prelink patch it's clear the magic is in the
>> section guarded
>> by RESOLVE_CONFLICT_FIND_MAP.  The x86_64 code already handles several
>> different cases of R_X86_64_TLSDESC in that switch so I still don't
>> understand how it falls through to _dl_reloc_bad_type rather than just
>> ignoring the prelink suppliied address.  Most of the ARM patch
>> consists of asserts presumably because the code wasn't fully trusted.
>>
> Okay, I've applied the attached patch inserting the code removed from
> the ARM dl-machine.h into the x86_64 code handling R_X86_64_TLSDESC.
> I still get the same error:
>
> error while loading shared libraries: unexpected reloc type 0x24
>
> Which can only be coming from _dl_reloc_bad_type() after it's fallen
> through the switch in elf_machine_rela() or the if-else block in
> elf_machine_lazy_rel(), both of which have should not fall through
> since R_X86_64_TLSDESC is reloc type 0x24 and it is, or should be
> handled!
>
Despite staring at the code for hours I didn't see the case was
guarded by an #ifdef block.  The patch I last attached doesn't compile
when the code is moved outside without the resolver being changed
since _dl_tlsdesc_lazy_resolver isnt present for x86-64.  Even then
the map->l_info[VALIDX (DT_GNU_PRELINKED)] != NULL doesn't seem to
work.  Mind you it no longer fails to run the binary, whether it's
actually using the prelinked value is another matter..?