aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog15
-rw-r--r--bfd/elf32-arm.c24
-rw-r--r--bfd/elf32-i386.c30
-rw-r--r--bfd/elf32-ppc.c29
-rw-r--r--bfd/elf32-sh.c27
-rw-r--r--bfd/elfxx-sparc.c29
-rw-r--r--ld/testsuite/ChangeLog5
-rw-r--r--ld/testsuite/ld-vxworks/tls-3.d7
-rw-r--r--ld/testsuite/ld-vxworks/tls-3.s34
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
+