+2014-07-17 Maciej W. Rozycki <macro@codesourcery.com>
+
+ [BZ #17078]
+ * sysdeps/arm/dl-machine.h (elf_machine_rela)
+ [RESOLVE_CONFLICT_FIND_MAP]: Handle R_ARM_TLS_DESC relocation.
+ (elf_machine_lazy_rel): Handle prelinked R_ARM_TLS_DESC entries.
+
2014-07-17 Joseph Myers <joseph@codesourcery.com>
[BZ #17088]
16882, 16885, 16888, 16890, 16912, 16915, 16916, 16917, 16918, 16922,
16927, 16928, 16932, 16943, 16958, 16965, 16966, 16967, 16977, 16978,
16984, 16990, 16996, 17009, 17022, 17031, 17042, 17048, 17050, 17058,
- 17061, 17062, 17069, 17075, 17079, 17084, 17086, 17088, 17092, 17097,
- 17125, 17135, 17137, 17153.
+ 17061, 17062, 17069, 17075, 17078, 17079, 17084, 17086, 17088, 17092,
+ 17097, 17125, 17135, 17137, 17153.
* Optimized strchr implementation for AArch64. Contributed by ARM Ltd.
case R_ARM_ABS32:
*reloc_addr = value + reloc->r_addend;
break;
+# ifdef RESOLVE_CONFLICT_FIND_MAP
+ case R_ARM_TLS_DESC:
+ {
+ struct tlsdesc volatile *td =
+ (struct tlsdesc volatile *) reloc_addr;
+
+ 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. */
+ *(Elf32_Addr *) (D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_GOT)])
+ + map->l_addr)
+ = (Elf32_Addr) &_dl_tlsdesc_lazy_resolver;
+ ((Elf32_Addr *) D_PTR (map, l_info[DT_PLTGOT]))[1]
+ = (Elf32_Addr) map;
+ }
+ break;
+# endif /* RESOLVE_CONFLICT_FIND_MAP */
case R_ARM_PC24:
relocate_pc24 (map, value, reloc_addr, reloc->r_addend);
break;
(struct tlsdesc volatile *)reloc_addr;
/* The linker must have given us the parameter we need in the
- first GOT entry, and left the second one empty. We fill the
- last with the resolver address */
- assert (td->entry == 0);
+ first GOT entry, and left the second one empty. The latter
+ will have been preset by the prelinker if used though.
+ We fill it with the resolver address. */
+ assert (td->entry == 0
+ || map->l_info[VALIDX (DT_GNU_PRELINKED)] != NULL);
td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
+ map->l_addr);
}