This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: x86-64 prelink support for TLS dialect gnu2
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!
--- ./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)
{