x86-64 prelink support for TLS dialect gnu2

Message ID CAMZr8UrKwJN2aP6SV7RAx2ONpjJ5PWKVa2z7NnrVnCqzpGdEjg@mail.gmail.com
State New, archived
Headers

Commit Message

Steven Newbury Nov. 6, 2018, noon UTC
  On 06/11/2018, Steven Newbury <steven.newbury@googlemail.com> 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!
  

Comments

Steven Newbury Nov. 6, 2018, 3:16 p.m. UTC | #1
On 06/11/2018, Steven Newbury <steven.newbury@googlemail.com> wrote:
> On 06/11/2018, Steven Newbury <steven.newbury@googlemail.com> 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..?
  

Patch

--- ./sysdeps/x86_64/dl-machine.h.orig	2018-11-06 09:51:14.316220266 +0000
+++ ./sysdeps/x86_64/dl-machine.h	2018-11-06 09:53:17.511458780 +0000
@@ -392,6 +392,29 @@ 
 	    struct tlsdesc volatile *td =
 	      (struct tlsdesc volatile *)reloc_addr;
 
+#  ifdef RESOLVE_CONFLICT_FIND_MAP
+	    if (map->l_info[VALIDX (DT_GNU_PRELINKED)] != NULL)
+	      {
+		RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr);
+
+		/* Make sure we know what's going on.  */
+		assert (td->entry
+		    == (void *) (D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
+				 + map->l_addr));
+		assert (map->l_info[ADDRIDX (DT_TLSDESC_GOT)]);
+
+		/* Set up the lazy resolver and store the pointer to our link
+		map in _GLOBAL_OFFSET_TABLE[1] now as for a prelinked
+		binary elf_machine_runtime_setup() is not called and hence
+		neither has been initialized.  */
+		*(ElfW(Addr) *) (D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_GOT)])
+			     + map->l_addr)
+			= (ElfW(Addr)) &_dl_tlsdesc_lazy_resolver;
+		((ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]))[1]
+			= (ElfW(Addr)) map;
+	      }
+	    else
+#  endif
 #  ifndef RTLD_BOOTSTRAP
 	    if (! sym)
 	      {