From 7dc98aeaf1f3fe256e284347a41f1c150955c37d Mon Sep 17 00:00:00 2001 From: Rainer Orth Date: Thu, 21 Oct 2010 12:29:02 +0000 Subject: [PATCH] * elf-bfd.h (struct elf_backend_data): New member static_tls_alignment. * elfxx-target.h (elf_backend_static_tls_alignment): Provide default. (elfNN_bed): Initialize static_tls_alignment. * elflink.c (bfd_elf_final_link): Don't round end of TLS section if static TLS has special alignment requirements. * elf32-i386.c (elf_i386_tpoff): Define bed, static_tls_size. Consider static_tls_alignment. (elf_backend_static_tls_alignment): Redefine for Solaris 2. Undef again for VxWorks. * elf64-x86-64.c (elf64_x86_64_tpoff): Define bed, static_tls_size. Consider static_tls_alignment. (elf_backend_static_tls_alignment): Redefine for Solaris 2. Undef again for Intel L1OM. --- bfd/ChangeLog | 19 +++++++++++++++++++ bfd/elf-bfd.h | 3 +++ bfd/elf32-i386.c | 13 ++++++++++++- bfd/elf64-x86-64.c | 13 ++++++++++++- bfd/elflink.c | 6 +++++- bfd/elfxx-target.h | 6 +++++- 6 files changed, 56 insertions(+), 4 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7981dce223..47381a4919 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,22 @@ +2010-10-21 Rainer Orth + + * elf-bfd.h (struct elf_backend_data): New member + static_tls_alignment. + * elfxx-target.h (elf_backend_static_tls_alignment): Provide + default. + (elfNN_bed): Initialize static_tls_alignment. + * elflink.c (bfd_elf_final_link): Don't round end of TLS section + if static TLS has special alignment requirements. + * elf32-i386.c (elf_i386_tpoff): Define bed, static_tls_size. + Consider static_tls_alignment. + (elf_backend_static_tls_alignment): Redefine for Solaris 2. + Undef again for VxWorks. + * elf64-x86-64.c (elf64_x86_64_tpoff): Define bed, + static_tls_size. + Consider static_tls_alignment. + (elf_backend_static_tls_alignment): Redefine for Solaris 2. + Undef again for Intel L1OM. + 2010-10-14 Dave Korn Apply LD plugin patch series (part 6/6). diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 66dcbcd5ea..0527bbd38a 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1256,6 +1256,9 @@ struct elf_backend_data actual tag number to place in the input position. */ int (*obj_attrs_order) (int); + /* This is non-zero if static TLS segments require a special alignment. */ + unsigned static_tls_alignment; + /* This is TRUE if the linker should act like collect and gather global constructors and destructors by name. This is TRUE for MIPS ELF because the Irix 5 tools can not handle the .init diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 8d8bc855c1..ae749c6b4e 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2828,11 +2828,16 @@ static bfd_vma elf_i386_tpoff (struct bfd_link_info *info, bfd_vma address) { struct elf_link_hash_table *htab = elf_hash_table (info); + const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd); + bfd_vma static_tls_size; /* If tls_sec is NULL, we should have signalled an error already. */ if (htab->tls_sec == NULL) return 0; - return htab->tls_size + htab->tls_sec->vma - address; + + /* Consider special static TLS alignment requirements. */ + static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment); + return static_tls_size + htab->tls_sec->vma - address; } /* Relocate an i386 ELF section. */ @@ -4795,6 +4800,11 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) #undef elf32_bed #define elf32_bed elf32_i386_sol2_bed +/* The 32-bit static TLS arena size is rounded to the nearest 8-byte + boundary. */ +#undef elf_backend_static_tls_alignment +#define elf_backend_static_tls_alignment 8 + /* The Solaris 2 ABI requires a plt symbol on all platforms. Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output @@ -4848,6 +4858,7 @@ elf_i386_vxworks_link_hash_table_create (bfd *abfd) #undef elf_backend_final_write_processing #define elf_backend_final_write_processing \ elf_vxworks_final_write_processing +#undef elf_backend_static_tls_alignment /* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so define it. */ diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 677d9c457b..83656aead1 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2607,11 +2607,16 @@ static bfd_vma elf64_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address) { struct elf_link_hash_table *htab = elf_hash_table (info); + const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd); + bfd_vma static_tls_size; /* If tls_segment is NULL, we should have signalled an error already. */ if (htab->tls_sec == NULL) return 0; - return address - htab->tls_size - htab->tls_sec->vma; + + /* Consider special static TLS alignment requirements. */ + static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment); + return address - static_tls_size - htab->tls_sec->vma; } /* Is the instruction before OFFSET in CONTENTS a 32bit relative @@ -4565,6 +4570,11 @@ static const struct bfd_elf_special_section #undef elf64_bed #define elf64_bed elf64_x86_64_sol2_bed +/* The 64-bit static TLS arena size is rounded to the nearest 16-byte + boundary. */ +#undef elf_backend_static_tls_alignment +#define elf_backend_static_tls_alignment 16 + /* The Solaris 2 ABI requires a plt symbol on all platforms. Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output @@ -4603,6 +4613,7 @@ elf64_l1om_elf_object_p (bfd *abfd) #define elf_backend_object_p elf64_l1om_elf_object_p #undef elf_backend_post_process_headers +#undef elf_backend_static_tls_alignment #include "elf64-target.h" diff --git a/bfd/elflink.c b/bfd/elflink.c index 6d37dc8d4e..6726d464c6 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -10624,7 +10624,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) end = sec->vma + size; } base = elf_hash_table (info)->tls_sec->vma; - end = align_power (end, elf_hash_table (info)->tls_sec->alignment_power); + /* Only align end of TLS section if static TLS doesn't have special + alignment requirements. */ + if (bed->static_tls_alignment == 1) + end = align_power (end, + elf_hash_table (info)->tls_sec->alignment_power); elf_hash_table (info)->tls_size = end - base; } diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 00fd693ba7..57f352c6ed 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -1,6 +1,6 @@ /* Target definitions for NN-bit ELF Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -477,6 +477,9 @@ #ifndef elf_backend_obj_attrs_order #define elf_backend_obj_attrs_order NULL #endif +#ifndef elf_backend_static_tls_alignment +#define elf_backend_static_tls_alignment 1 +#endif #ifndef elf_backend_post_process_headers #define elf_backend_post_process_headers NULL #endif @@ -738,6 +741,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_obj_attrs_arg_type, elf_backend_obj_attrs_section_type, elf_backend_obj_attrs_order, + elf_backend_static_tls_alignment, elf_backend_collect, elf_backend_type_change_ok, elf_backend_may_use_rel_p, -- 2.34.1