aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-sh.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf32-sh.c')
-rw-r--r--bfd/elf32-sh.c27
1 files changed, 27 insertions, 0 deletions
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)))
{