From 9f03412ac677d4f228026de9174c23a4bc47dd74 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Mon, 28 Jul 2008 18:07:05 +0000 Subject: [PATCH] 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 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 --- bfd/ChangeLog | 16 +++++++++++++++ bfd/elf32-i386.c | 30 ++++++++++++++++++++++++++++ bfd/elf64-x86-64.c | 30 ++++++++++++++++++++++++++++ ld/testsuite/ChangeLog | 9 +++++++++ ld/testsuite/ld-i386/tlsbindesc.dd | 4 ++-- ld/testsuite/ld-i386/tlsbindesc.rd | 2 +- ld/testsuite/ld-x86-64/tlsbindesc.dd | 2 +- ld/testsuite/ld-x86-64/tlsbindesc.rd | 2 +- 8 files changed, 90 insertions(+), 5 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8626b267a20..8eae4909c4b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2008-07-28 Alexandre Oliva + + * 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 + 2008-07-28 Ineiev * elf32-arm.c (arm_map_one_stub): Declare variables at beginning diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 578f5959590..9e96e215fb9 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 71c10a76969..bc8c652d745 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 d7c67245fbf..6d881ca85f7 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2008-07-28 Alexandre Oliva + + * 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 + 2008-07-27 Alan Modra * 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 00e164f3e29..f77d1c8d5fd 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 29f195b17b1..dd3e65eeea3 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 4cfba5e2466..9e82eab4be5 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 e90a06150a6..b70d78f02de 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 -- 2.30.2