summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2008-07-28 18:07:05 +0000
committerAlexandre Oliva <aoliva@redhat.com>2008-07-28 18:07:05 +0000
commitfb07749d3666bde289ee83977d5d8240e444384b (patch)
tree7ab7bda8cf92eccdb4ac462e5ba2c675c52a48ef
parent39be822413e238e9e1d5c04cda45ab466d7153d6 (diff)
downloadbinutils-redhat-fb07749d3666bde289ee83977d5d8240e444384b.tar.gz
bfd/ChangeLog:
* elf32-i386.c (struct elf_i386_link_hash_table): Added field tls_module_base. (elf_i386_link_hash_table_create): Initialize it. (elf_i386_always_size_sections): Set it. (set_tls_module_base): New. (elf_i386_relocate_sections): Call it. * elf64-x86-64.c (struct elf64_x86_64_link_hash_table): Added field tls_module_base. (elf64_x86_64_link_hash_table_create): Initialize it. (elf64_x86_64_always_size_sections): Set it. (set_tls_module_base): New. (elf64_x86_64_relocate_sections): Call it. Reported by Cary Coutant <ccoutant@google.com> ld/testsuite/ChangeLog: * ld-i386/tlsbindesc.dd: Adjust incorrect expectations for LD to LE relaxation. * ld-x86-64/tlsbindesc.dd: Likewise. * ld-i386/tlsbindesc.rd: Adjust address of _TLS_MODULE_BASE_. * ld-x86-64/tlsbindesc.rd: Likewise. Reported by Cary Coutant <ccoutant@google.com>
-rw-r--r--bfd/ChangeLog16
-rw-r--r--bfd/elf32-i386.c30
-rw-r--r--bfd/elf64-x86-64.c30
-rw-r--r--ld/testsuite/ChangeLog9
-rw-r--r--ld/testsuite/ld-i386/tlsbindesc.dd4
-rw-r--r--ld/testsuite/ld-i386/tlsbindesc.rd2
-rw-r--r--ld/testsuite/ld-x86-64/tlsbindesc.dd2
-rw-r--r--ld/testsuite/ld-x86-64/tlsbindesc.rd2
8 files changed, 90 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 8626b267a2..8eae4909c4 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,19 @@
+2008-07-28 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-i386.c (struct elf_i386_link_hash_table): Added field
+ tls_module_base.
+ (elf_i386_link_hash_table_create): Initialize it.
+ (elf_i386_always_size_sections): Set it.
+ (set_tls_module_base): New.
+ (elf_i386_relocate_sections): Call it.
+ * elf64-x86-64.c (struct elf64_x86_64_link_hash_table): Added
+ field tls_module_base.
+ (elf64_x86_64_link_hash_table_create): Initialize it.
+ (elf64_x86_64_always_size_sections): Set it.
+ (set_tls_module_base): New.
+ (elf64_x86_64_relocate_sections): Call it.
+ Reported by Cary Coutant <ccoutant@google.com>
+
2008-07-28 Ineiev <ineiev@yahoo.co.uk>
* elf32-arm.c (arm_map_one_stub): Declare variables at beginning
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 578f595959..9e96e215fb 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -692,6 +692,9 @@ struct elf_i386_link_hash_table
/* Small local sym to section mapping cache. */
struct sym_sec_cache sym_sec;
+
+ /* _TLS_MODULE_BASE_ symbol. */
+ struct bfd_link_hash_entry *tls_module_base;
};
/* Get the i386 ELF linker hash table from a link_info structure. */
@@ -767,6 +770,7 @@ elf_i386_link_hash_table_create (bfd *abfd)
ret->is_vxworks = 0;
ret->srelplt2 = NULL;
ret->plt0_pad_byte = 0;
+ ret->tls_module_base = NULL;
return &ret->elf.root;
}
@@ -2431,6 +2435,9 @@ elf_i386_always_size_sections (bfd *output_bfd,
tls_sec, 0, NULL, FALSE,
bed->collect, &bh)))
return FALSE;
+
+ elf_i386_hash_table (info)->tls_module_base = bh;
+
tlsbase = (struct elf_link_hash_entry *)bh;
tlsbase->def_regular = 1;
tlsbase->other = STV_HIDDEN;
@@ -2475,6 +2482,27 @@ elf_i386_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
return TRUE;
}
+/* _TLS_MODULE_BASE_ needs to be treated especially when linking
+ executables. Rather than setting it to the beginning of the TLS
+ section, we have to set it to the end. This function may be called
+ multiple times, it is idempotent. */
+
+static void
+set_tls_module_base (struct bfd_link_info *info)
+{
+ struct bfd_link_hash_entry *base;
+
+ if (!info->executable)
+ return;
+
+ base = elf_i386_hash_table (info)->tls_module_base;
+
+ if (!base)
+ return;
+
+ base->u.def.value = elf_hash_table (info)->tls_size;
+}
+
/* Return the base VMA address which should be subtracted from real addresses
when resolving @dtpoff relocation.
This is PT_TLS segment p_vaddr. */
@@ -2536,6 +2564,8 @@ elf_i386_relocate_section (bfd *output_bfd,
&& !strcmp (input_section->output_section->name,
".tls_vars"));
+ set_tls_module_base (info);
+
rel = relocs;
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 71c10a7696..bc8c652d74 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -503,6 +503,9 @@ struct elf64_x86_64_link_hash_table
/* Small local sym to section mapping cache. */
struct sym_sec_cache sym_sec;
+
+ /* _TLS_MODULE_BASE_ symbol. */
+ struct bfd_link_hash_entry *tls_module_base;
};
/* Get the x86-64 ELF linker hash table from a link_info structure. */
@@ -575,6 +578,7 @@ elf64_x86_64_link_hash_table_create (bfd *abfd)
ret->tlsdesc_got = 0;
ret->tls_ld_got.refcount = 0;
ret->sgotplt_jump_table_size = 0;
+ ret->tls_module_base = NULL;
return &ret->elf.root;
}
@@ -2239,6 +2243,9 @@ elf64_x86_64_always_size_sections (bfd *output_bfd,
tls_sec, 0, NULL, FALSE,
bed->collect, &bh)))
return FALSE;
+
+ elf64_x86_64_hash_table (info)->tls_module_base = bh;
+
tlsbase = (struct elf_link_hash_entry *)bh;
tlsbase->def_regular = 1;
tlsbase->other = STV_HIDDEN;
@@ -2249,6 +2256,27 @@ elf64_x86_64_always_size_sections (bfd *output_bfd,
return TRUE;
}
+/* _TLS_MODULE_BASE_ needs to be treated especially when linking
+ executables. Rather than setting it to the beginning of the TLS
+ section, we have to set it to the end. This function may be called
+ multiple times, it is idempotent. */
+
+static void
+set_tls_module_base (struct bfd_link_info *info)
+{
+ struct bfd_link_hash_entry *base;
+
+ if (!info->executable)
+ return;
+
+ base = elf64_x86_64_hash_table (info)->tls_module_base;
+
+ if (!base)
+ return;
+
+ base->u.def.value = elf_hash_table (info)->tls_size;
+}
+
/* Return the base VMA address which should be subtracted from real addresses
when resolving @dtpoff relocation.
This is PT_TLS segment p_vaddr. */
@@ -2319,6 +2347,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
local_got_offsets = elf_local_got_offsets (input_bfd);
local_tlsdesc_gotents = elf64_x86_64_local_tlsdesc_gotent (input_bfd);
+ set_tls_module_base (info);
+
rel = relocs;
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index d7c67245fb..6d881ca85f 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2008-07-28 Alexandre Oliva <aoliva@redhat.com>
+
+ * ld-i386/tlsbindesc.dd: Adjust incorrect expectations for LD to
+ LE relaxation.
+ * ld-x86-64/tlsbindesc.dd: Likewise.
+ * ld-i386/tlsbindesc.rd: Adjust address of _TLS_MODULE_BASE_.
+ * ld-x86-64/tlsbindesc.rd: Likewise.
+ Reported by Cary Coutant <ccoutant@google.com>
+
2008-07-27 Alan Modra <amodra@bigpond.net.au>
* ld-gc/gc.exp (test_gc): xfail powerpc64.
diff --git a/ld/testsuite/ld-i386/tlsbindesc.dd b/ld/testsuite/ld-i386/tlsbindesc.dd
index 00e164f3e2..f77d1c8d5f 100644
--- a/ld/testsuite/ld-i386/tlsbindesc.dd
+++ b/ld/testsuite/ld-i386/tlsbindesc.dd
@@ -90,7 +90,7 @@ Disassembly of section .text:
[0-9a-f]+: 90[ ]+nop *
[0-9a-f]+: 90[ ]+nop *
# LD -> LE
- [0-9a-f]+: 8d 05 00 f0 ff ff[ ]+lea 0xfffff000,%eax
+ [0-9a-f]+: 8d 05 00 00 00 00[ ]+lea 0x0,%eax
[0-9a-f]+: 66 90[ ]+xchg %ax,%ax
[0-9a-f]+: 90[ ]+nop *
[0-9a-f]+: 90[ ]+nop *
@@ -105,7 +105,7 @@ Disassembly of section .text:
[0-9a-f]+: 90[ ]+nop *
[0-9a-f]+: 90[ ]+nop *
# LD -> LE against hidden variables
- [0-9a-f]+: 8d 05 00 f0 ff ff[ ]+lea 0xfffff000,%eax
+ [0-9a-f]+: 8d 05 00 00 00 00[ ]+lea 0x0,%eax
[0-9a-f]+: 66 90[ ]+xchg %ax,%ax
[0-9a-f]+: 90[ ]+nop *
[0-9a-f]+: 90[ ]+nop *
diff --git a/ld/testsuite/ld-i386/tlsbindesc.rd b/ld/testsuite/ld-i386/tlsbindesc.rd
index 29f195b17b..dd3e65eeea 100644
--- a/ld/testsuite/ld-i386/tlsbindesc.rd
+++ b/ld/testsuite/ld-i386/tlsbindesc.rd
@@ -109,7 +109,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
+[0-9]+: 00000094 +0 TLS +LOCAL DEFAULT +8 bl6
+[0-9]+: 00000098 +0 TLS +LOCAL DEFAULT +8 bl7
+[0-9]+: 0000009c +0 TLS +LOCAL DEFAULT +8 bl8
- +[0-9]+: 00000000 +0 TLS +LOCAL HIDDEN +7 _TLS_MODULE_BASE_
+ +[0-9]+: 00001000 +0 TLS +LOCAL HIDDEN +7 _TLS_MODULE_BASE_
+[0-9]+: 0+804a060 +0 OBJECT LOCAL HIDDEN 9 _DYNAMIC
+[0-9]+: [0-9a-f]+ +0 OBJECT LOCAL HIDDEN 11 _GLOBAL_OFFSET_TABLE_
+[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT UND sG3
diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.dd b/ld/testsuite/ld-x86-64/tlsbindesc.dd
index 4cfba5e246..9e82eab4be 100644
--- a/ld/testsuite/ld-x86-64/tlsbindesc.dd
+++ b/ld/testsuite/ld-x86-64/tlsbindesc.dd
@@ -63,7 +63,7 @@ Disassembly of section .text:
[0-9a-f]+: 90[ ]+nop *
[0-9a-f]+: 90[ ]+nop *
# LD -> LE
- [0-9a-f]+: 48 c7 c0 60 ff ff ff[ ]+mov \$0xf+60,%rax
+ [0-9a-f]+: 48 c7 c0 00 00 00 00[ ]+mov \$0x0,%rax
[0-9a-f]+: 66 90[ ]+xchg %ax,%ax
[0-9a-f]+: 90[ ]+nop *
[0-9a-f]+: 90[ ]+nop *
diff --git a/ld/testsuite/ld-x86-64/tlsbindesc.rd b/ld/testsuite/ld-x86-64/tlsbindesc.rd
index e90a06150a..b70d78f02d 100644
--- a/ld/testsuite/ld-x86-64/tlsbindesc.rd
+++ b/ld/testsuite/ld-x86-64/tlsbindesc.rd
@@ -100,7 +100,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
+[0-9]+: 0+94 +0 TLS +LOCAL DEFAULT +8 bl6
+[0-9]+: 0+98 +0 TLS +LOCAL DEFAULT +8 bl7
+[0-9]+: 0+9c +0 TLS +LOCAL DEFAULT +8 bl8
- +[0-9]+: 0+0 +0 TLS +LOCAL HIDDEN +7 _TLS_MODULE_BASE_
+ +[0-9]+: 0+a0 +0 TLS +LOCAL HIDDEN +7 _TLS_MODULE_BASE_
+[0-9]+: 0+601258 +0 OBJECT LOCAL HIDDEN 9 _DYNAMIC
+[0-9]+: 0+601378 +0 OBJECT LOCAL HIDDEN 11 _GLOBAL_OFFSET_TABLE_
+[0-9]+: 0+1c +0 TLS +GLOBAL DEFAULT +7 sg8