diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2008-07-28 18:07:05 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@redhat.com> | 2008-07-28 18:07:05 +0000 |
commit | 9f03412ac677d4f228026de9174c23a4bc47dd74 (patch) | |
tree | d1bcbd579987a05ff60fb13cbdc695b18fb11c62 /bfd/elf64-x86-64.c | |
parent | 7f4b89d1b63f8ba812b911639f264b8e7ff51285 (diff) | |
download | gdb-9f03412ac677d4f228026de9174c23a4bc47dd74.zip gdb-9f03412ac677d4f228026de9174c23a4bc47dd74.tar.gz gdb-9f03412ac677d4f228026de9174c23a4bc47dd74.tar.bz2 |
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>
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 71c10a7..bc8c652 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++) |