summaryrefslogtreecommitdiff
path: root/sysdeps/i386/dl-machine.h
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-09-14 09:17:58 +0000
committerRoland McGrath <roland@gnu.org>2002-09-14 09:17:58 +0000
commit4730fc68821285c245e1d90a5c866f2845f9411c (patch)
tree0888cd52d16c8ab8428320abaa1d1aa71542bb92 /sysdeps/i386/dl-machine.h
parentb63429360053ea95d28defeccfc2c764fdfd90ab (diff)
* sysdeps/i386/dl-machine.h (elf_machine_rel)
(case R_386_TLS_DTPMOD32): Don't use addend. [case R_386_TLS_TPOFF32]: Remove redundant SYM_MAP != NULL check. (elf_machine_rela): Add support for TLS relocs.
Diffstat (limited to 'sysdeps/i386/dl-machine.h')
-rw-r--r--sysdeps/i386/dl-machine.h45
1 files changed, 40 insertions, 5 deletions
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index fa6ce04d99..8f17441dd8 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -410,8 +410,6 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
*reloc_addr = value;
break;
- /* XXX Remove TLS relocations which are not needed. */
-
#ifdef USE_TLS
case R_386_TLS_DTPMOD32:
# ifdef RTLD_BOOTSTRAP
@@ -432,7 +430,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
/* During relocation all TLS symbols are defined and used.
Therefore the offset is already correct. */
if (sym != NULL)
- *reloc_addr += sym->st_value;
+ *reloc_addr = sym->st_value;
# endif
break;
case R_386_TLS_TPOFF32:
@@ -444,7 +442,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
It is a positive value which will be subtracted from the
thread pointer. To get the variable position in the TLS
block we subtract the offset from that of the TLS block. */
- if (sym_map != NULL && sym != NULL)
+ if (sym != NULL)
*reloc_addr += sym_map->l_tls_offset - sym->st_value;
# endif
break;
@@ -516,7 +514,44 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
case R_386_PC32:
*reloc_addr = (value + reloc->r_addend - (Elf32_Addr) reloc_addr);
break;
- /* XXX Do we have to handle the TLS relocation here? */
+
+#ifdef USE_TLS
+ case R_386_TLS_DTPMOD32:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_386_TLS_DTPOFF32:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
+# endif
+ break;
+ case R_386_TLS_TPOFF32:
+ /* The offset is positive, backward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr = map->l_tls_offset - sym->st_value + reloc->r_addend;
+# else
+ /* We know the offset of object the symbol is contained in.
+ It is a positive value which will be subtracted from the
+ thread pointer. To get the variable position in the TLS
+ block we subtract the offset from that of the TLS block. */
+ *reloc_addr
+ = (sym == NULL ? 0 : sym_map->l_tls_offset - sym->st_value)
+ + reloc->r_addend;
+# endif
+ break;
+#endif /* use TLS */
default:
/* We add these checks in the version to relocate ld.so only
if we are still debugging. */