diff options
-rw-r--r-- | bfd/ChangeLog | 15 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 24 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 30 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 29 | ||||
-rw-r--r-- | bfd/elf32-sh.c | 27 | ||||
-rw-r--r-- | bfd/elfxx-sparc.c | 29 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-vxworks/tls-3.d | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-vxworks/tls-3.s | 34 |
9 files changed, 196 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 37aaa38..d248775 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2008-03-25 Nathan Sidwell <nathan@codesourcery.com> + + * elf32-arm.c (elf32_arm_final_link_relocate): Skip dynamic relocs + in vxworks tls_vars sections. + (allocate_dynrelocs, elf32_arm_size_dynamic_sections): Likewise. + * elf32-i386.c (allocate_dynrelocs, + elf_i386_size_dynamic_sections, elf_i386_relocate_section): Likewise. + * elf32-ppc.c (allocate_dynrelocs, ppc_elf_size_dynamic_sections, + ppc_elf_relocate_section): Likewise. + * elf32-sh.c (allocate_dynrelocs, sh_elf_size_dynamic_sections, + sh_elf_relocate_section): Likewise. + * elfxx-sparc.c (allocate_dynrelocs, + _bfd_sparc_elf_size_dynamic_sections, + _bfd_sparc_elf_relocate_section): Likewise. + 2008-03-21 Adam Nemet <anemet@caviumnetworks.com> * elf.c (_bfd_elf_print_private_bfd_data): Use bfd_fprintf_vma to diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 580d590..d372975 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -4752,6 +4752,9 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, run time. */ if ((info->shared || globals->root.is_relocatable_executable) && (input_section->flags & SEC_ALLOC) + && !(elf32_arm_hash_table (info)->vxworks_p + && strcmp (input_section->output_section->name, + ".tls_vars") == 0) && ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI) || !SYMBOL_CALLS_LOCAL (info, h)) && (h == NULL @@ -8577,6 +8580,19 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) } } + if (elf32_arm_hash_table (info)->vxworks_p) + { + struct elf32_arm_relocs_copied **pp; + + for (pp = &eh->relocs_copied; (p = *pp) != NULL; ) + { + if (strcmp (p->section->output_section->name, ".tls_vars") == 0) + *pp = p->next; + else + pp = &p->next; + } + } + /* Also discard relocs on undefined weak syms with non-default visibility. */ if (eh->relocs_copied != NULL @@ -8728,6 +8744,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, bfd_size_type locsymcount; Elf_Internal_Shdr *symtab_hdr; asection *srel; + bfd_boolean is_vxworks = elf32_arm_hash_table (info)->vxworks_p; if (! is_arm_elf (ibfd)) continue; @@ -8746,6 +8763,13 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, linker script /DISCARD/, so we'll be discarding the relocs too. */ } + else if (is_vxworks + && strcmp (p->section->output_section->name, + ".tls_vars") == 0) + { + /* Relocations in vxworks .tls_vars sections are + handled specially by the loader. */ + } else if (p->count != 0) { srel = elf_section_data (p->section)->sreloc; diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index c10dbb3..578f595 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2030,8 +2030,20 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) } } + if (htab->is_vxworks) + { + struct elf_i386_dyn_relocs **pp; + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + { + if (strcmp (p->sec->output_section->name, ".tls_vars") == 0) + *pp = p->next; + else + pp = &p->next; + } + } + /* Also discard relocs on undefined weak syms with non-default - visibility. */ + visibility. */ if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak) { @@ -2182,6 +2194,13 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, linker script /DISCARD/, so we'll be discarding the relocs too. */ } + else if (htab->is_vxworks + && strcmp (p->sec->output_section->name, + ".tls_vars") == 0) + { + /* Relocations in vxworks .tls_vars sections are + handled specially by the loader. */ + } else if (p->count != 0) { srel = elf_section_data (p->sec)->sreloc; @@ -2502,6 +2521,7 @@ elf_i386_relocate_section (bfd *output_bfd, bfd_vma *local_tlsdesc_gotents; Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; + bfd_boolean is_vxworks_tls; BFD_ASSERT (is_i386_elf (input_bfd)); @@ -2510,6 +2530,11 @@ elf_i386_relocate_section (bfd *output_bfd, sym_hashes = elf_sym_hashes (input_bfd); local_got_offsets = elf_local_got_offsets (input_bfd); local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd); + /* We have to handle relocations in vxworks .tls_vars sections + specially, because the dynamic loader is 'weird'. */ + is_vxworks_tls = (htab->is_vxworks && info->shared + && !strcmp (input_section->output_section->name, + ".tls_vars")); rel = relocs; relend = relocs + input_section->reloc_count; @@ -2837,7 +2862,8 @@ elf_i386_relocate_section (bfd *output_bfd, case R_386_32: case R_386_PC32: - if ((input_section->flags & SEC_ALLOC) == 0) + if ((input_section->flags & SEC_ALLOC) == 0 + || is_vxworks_tls) break; if ((info->shared diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index c7f419a..db380d2 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -4811,6 +4811,19 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) } } + if (htab->is_vxworks) + { + struct ppc_elf_dyn_relocs **pp; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + { + if (strcmp (p->sec->output_section->name, ".tls_vars") == 0) + *pp = p->next; + else + pp = &p->next; + } + } + /* Discard relocs on undefined symbols that must be local. */ if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefined @@ -4962,6 +4975,13 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, linker script /DISCARD/, so we'll be discarding the relocs too. */ } + else if (htab->is_vxworks + && strcmp (p->sec->output_section->name, + ".tls_vars") == 0) + { + /* Relocations in vxworks .tls_vars sections are + handled specially by the loader. */ + } else if (p->count != 0) { elf_section_data (p->sec)->sreloc->size @@ -5800,6 +5820,7 @@ ppc_elf_relocate_section (bfd *output_bfd, bfd_vma *local_got_offsets; bfd_boolean ret = TRUE; bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0); + bfd_boolean is_vxworks_tls; #ifdef DEBUG _bfd_error_handler ("ppc_elf_relocate_section called for %B section %A, " @@ -5819,6 +5840,11 @@ ppc_elf_relocate_section (bfd *output_bfd, local_got_offsets = elf_local_got_offsets (input_bfd); symtab_hdr = &elf_symtab_hdr (input_bfd); sym_hashes = elf_sym_hashes (input_bfd); + /* We have to handle relocations in vxworks .tls_vars sections + specially, because the dynamic loader is 'weird'. */ + is_vxworks_tls = (htab->is_vxworks && info->shared + && !strcmp (input_section->output_section->name, + ".tls_vars")); rel = relocs; relend = relocs + input_section->reloc_count; for (; rel < relend; rel++) @@ -6461,7 +6487,8 @@ ppc_elf_relocate_section (bfd *output_bfd, /* fall through */ dodyn: - if ((input_section->flags & SEC_ALLOC) == 0) + if ((input_section->flags & SEC_ALLOC) == 0 + || is_vxworks_tls) break; if ((info->shared diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 1c7b290..26c69bc 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -2817,6 +2817,19 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) } } + if (htab->vxworks_p) + { + struct elf_sh_dyn_relocs **pp; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + { + if (strcmp (p->sec->output_section->name, ".tls_vars") == 0) + *pp = p->next; + else + pp = &p->next; + } + } + /* Also discard relocs on undefined weak syms with non-default visibility. */ if (eh->dyn_relocs != NULL @@ -2977,6 +2990,13 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, linker script /DISCARD/, so we'll be discarding the relocs too. */ } + else if (htab->vxworks_p + && strcmp (p->sec->output_section->name, + ".tls_vars") == 0) + { + /* Relocations in vxworks .tls_vars sections are + handled specially by the loader. */ + } else if (p->count != 0) { srel = elf_section_data (p->sec)->sreloc; @@ -3166,6 +3186,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, asection *splt; asection *sreloc; asection *srelgot; + bfd_boolean is_vxworks_tls; BFD_ASSERT (is_sh_elf (input_bfd)); @@ -3180,6 +3201,11 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, splt = htab->splt; sreloc = NULL; srelgot = NULL; + /* We have to handle relocations in vxworks .tls_vars sections + specially, because the dynamic loader is 'weird'. */ + is_vxworks_tls = (htab->vxworks_p && info->shared + && !strcmp (input_section->output_section->name, + ".tls_vars")); rel = relocs; relend = relocs + input_section->reloc_count; @@ -3586,6 +3612,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, || h->root.type != bfd_link_hash_undefweak) && r_symndx != 0 && (input_section->flags & SEC_ALLOC) != 0 + && !is_vxworks_tls && (r_type == R_SH_DIR32 || !SYMBOL_CALLS_LOCAL (info, h))) { diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index cb22eaf..057e719 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2016,6 +2016,19 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf) } } + if (htab->is_vxworks) + { + struct _bfd_sparc_elf_dyn_relocs **pp; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + { + if (strcmp (p->sec->output_section->name, ".tls_vars") == 0) + *pp = p->next; + else + pp = &p->next; + } + } + /* Also discard relocs on undefined weak syms with non-default visibility. */ if (eh->dyn_relocs != NULL @@ -2178,6 +2191,13 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd, linker script /DISCARD/, so we'll be discarding the relocs too. */ } + else if (htab->is_vxworks + && strcmp (p->sec->output_section->name, + ".tls_vars") == 0) + { + /* Relocations in vxworks .tls_vars sections are + handled specially by the loader. */ + } else if (p->count != 0) { srel = elf_section_data (p->sec)->sreloc; @@ -2488,6 +2508,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; int num_relocs; + bfd_boolean is_vxworks_tls; htab = _bfd_sparc_elf_hash_table (info); symtab_hdr = &elf_symtab_hdr (input_bfd); @@ -2500,6 +2521,11 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, got_base = elf_hash_table (info)->hgot->root.u.def.value; sreloc = elf_section_data (input_section)->sreloc; + /* We have to handle relocations in vxworks .tls_vars sections + specially, because the dynamic loader is 'weird'. */ + is_vxworks_tls = (htab->is_vxworks && info->shared + && !strcmp (input_section->output_section->name, + ".tls_vars")); rel = relocs; if (ABI_64_P (output_bfd)) @@ -2766,7 +2792,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, case R_SPARC_L44: case R_SPARC_UA64: r_sparc_plt32: - if ((input_section->flags & SEC_ALLOC) == 0) + if ((input_section->flags & SEC_ALLOC) == 0 + || is_vxworks_tls) break; if ((info->shared diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 5a4e27d..2cd6d03 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-03-25 Nathan Sidwell <nathan@codesourcery.com> + + * ld-vxworks/tls-3.s: New. + * ld-vxworks/tls-3.d: New. + 2008-03-22 Hans-Peter Nilsson <hp@axis.com> * ld-cris/libdso-10.d: Adjust for change in objdump output. diff --git a/ld/testsuite/ld-vxworks/tls-3.d b/ld/testsuite/ld-vxworks/tls-3.d new file mode 100644 index 0000000..53f7e81 --- /dev/null +++ b/ld/testsuite/ld-vxworks/tls-3.d @@ -0,0 +1,7 @@ +# source: tls-3.s +# ld: -shared -z now +# objdump: -R + +#... +DYNAMIC RELOCATION RECORDS \(none\) + diff --git a/ld/testsuite/ld-vxworks/tls-3.s b/ld/testsuite/ld-vxworks/tls-3.s new file mode 100644 index 0000000..39420c2 --- /dev/null +++ b/ld/testsuite/ld-vxworks/tls-3.s @@ -0,0 +1,34 @@ + .globl foo +foo: + + .section .tls_data,"a" + .p2align 2 + + .type i,%object + .size i,4 +i: + .space 4 + + .globl j + .type j,%object + .size j,4 +j: + .space 4 + + .section .tls_vars,"a" + .p2align 2 + .type __tls__i,%object + .size __tls__i,12 +__tls__i: + .4byte i + .4byte 0 + .4byte 4 + + .globl __tls__j + .type __tls__j,%object + .size __tls__j,12 +__tls__j: + .4byte j + .4byte 0 + .4byte 4 + |