aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorJames Clarke <jrtc27@jrtc27.com>2017-10-13 15:44:39 -0300
committerTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>2017-10-13 16:14:16 -0300
commit8644588807215ab09716ac04a150f91ac83acffd (patch)
treea102e789349ae949df505458c19b41abf5f327d2 /sysdeps
parente8dbd6a36d8e4d30e736e28a364f7a4d1404079a (diff)
downloadglibc-8644588807215ab09716ac04a150f91ac83acffd.zip
glibc-8644588807215ab09716ac04a150f91ac83acffd.tar.gz
glibc-8644588807215ab09716ac04a150f91ac83acffd.tar.bz2
Fix TLS relocations against local symbols on powerpc32, sparc32 and sparc64
Normally, TLS relocations against local symbols are optimised by the linker to be absolute. However, gold does not do this, and so it is possible to end up with, for example, R_SPARC_TLS_DTPMOD64 referring to a local symbol. Since sym_map is left as null in elf_machine_rela for the special local symbol case, the relocation handling thinks it has nothing to do, and so the module gets left as 0. Havoc then ensues when the variable in question is accessed. Before this fix, the main_local_gold program would receive a SIGBUS on sparc64, and SIGSEGV on powerpc32. With this fix applied, that test now passes like the rest of them. * sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela): Assign sym_map to be map for local symbols, as TLS relocations use sym_map to determine whether the symbol is defined and to extract the TLS information. * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): Likewise. * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Likewise.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h5
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h1
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h1
3 files changed, 6 insertions, 1 deletions
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index 1f8437e..c19b3b7 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -310,7 +310,10 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
against local symbols. */
if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0)
&& sym->st_shndx != SHN_UNDEF)
- value = map->l_addr;
+ {
+ sym_map = map;
+ value = map->l_addr;
+ }
else
{
sym_map = RESOLVE_MAP (&sym, version, r_type);
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index 436e4e6..debf67b 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -376,6 +376,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0)
&& sym->st_shndx != SHN_UNDEF)
{
+ sym_map = map;
value = map->l_addr;
}
else
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index c2871dc..e1ec7a5 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -403,6 +403,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
if (__builtin_expect (ELF64_ST_BIND (sym->st_info) == STB_LOCAL, 0)
&& sym->st_shndx != SHN_UNDEF)
{
+ sym_map = map;
value = map->l_addr;
}
else