* sysdeps/x86_64/dl-machine.h (elf_machine_rela): For x32, sign extend relocation result to 64bit for R_X86_64_DTPOFF64 and R_X86_64_TPOFF64. diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index d1906a4..6b999f2 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -328,7 +328,14 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, /* During relocation all TLS symbols are defined and used. Therefore the offset is already correct. */ if (sym != NULL) +# ifdef __ILP32__ + /* R_X86_64_DTPOFF64 is applied to a signed 64bit GOT entry. */ + *(Elf64_Sxword *) reloc_addr + = (Elf64_Sxword) + ((Elf32_Sword) (sym->st_value + reloc->r_addend)); +# else *reloc_addr = sym->st_value + reloc->r_addend; +# endif # endif break; case R_X86_64_TLSDESC: @@ -378,8 +385,16 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, /* We know the offset of the object the symbol is contained in. It is a negative value which will be added to the thread pointer. */ +# ifdef __ILP32__ + /* R_X86_64_TPOFF64 is applied to a signed 64bit GOT entry. */ + *(Elf64_Sxword *) reloc_addr + = (Elf64_Sxword) + ((Elf32_Sword) (sym->st_value + reloc->r_addend + - sym_map->l_tls_offset)); +# else *reloc_addr = (sym->st_value + reloc->r_addend - sym_map->l_tls_offset); +# endif } break; # endif