aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorCupertino Miranda <cmiranda@synopsys.com>2018-10-04 10:17:03 +0100
committerCupertino Miranda <cmiranda@synopsys.com>2018-11-09 15:34:37 +0000
commitd07b621f4cc585607c7eee7cc58ce54a7dde52f5 (patch)
tree766c99bcb5938ebb172201b347c5ecf2fb42e183 /bfd
parentUpdated French translation for the ld subdirectory. (diff)
downloadbinutils-gdb-d07b621f4cc585607c7eee7cc58ce54a7dde52f5.tar.gz
binutils-gdb-d07b621f4cc585607c7eee7cc58ce54a7dde52f5.tar.bz2
binutils-gdb-d07b621f4cc585607c7eee7cc58ce54a7dde52f5.zip
[ARC] More fixes for TLS.
Added warning for static TLS reloc. Fixed issue related to TLS and partial static linking of libraries: This issue was detected when throwing exceptions in C++ while linking with -static-libstdc++. TLS relocation from the libstdc++ wasn't being patched as local now that it was static linked with the executable. Fix for TLS with static and pie. Problem introduced by earlier patch: Fixes the following glibc tests: - elf/tst-tls1-static bfd/ xxxx-xx-xx Cupertino Miranda <cmiranda@synopsys.com> * arc-got.h (arc_got_entry_type_for_reloc): Changed to correct static TLS relocs. * elf32-arc.c (elf_arc_check_relocs): Introduced warning to TLS relocs which require -fPIC. (arc_create_forced_local_got_entries_for_tls): Created. Traverses list of GOT entries to be resolved statically when needed. (elf_arc_finish_dynamic_sections): Changed. Calls arc_create_forced_local_got_entries_for_tls for each known possibly GOT symbol.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/arc-got.h33
-rw-r--r--bfd/elf32-arc.c116
2 files changed, 105 insertions, 44 deletions
diff --git a/bfd/arc-got.h b/bfd/arc-got.h
index 69e9aa32759..253578b90c4 100644
--- a/bfd/arc-got.h
+++ b/bfd/arc-got.h
@@ -208,7 +208,7 @@ arc_got_entry_type_for_reloc (reloc_howto_type *howto)
__LINE__, name_for_global_symbol (H)); \
} \
if (H) \
- if (h->dynindx == -1 && !h->forced_local) \
+ if (H->dynindx == -1 && !H->forced_local) \
if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
return FALSE; \
htab->s##SECNAME->size += 4; \
@@ -284,6 +284,7 @@ relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p,
BFD_ASSERT (entry);
if (h == NULL
+ || h->forced_local == TRUE
|| (! elf_hash_table (info)->dynamic_sections_created
|| (bfd_link_pic (info)
&& SYMBOL_REFERENCES_LOCAL (info, h))))
@@ -331,27 +332,31 @@ relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p,
BFD_ASSERT (tls_sec && tls_sec->output_section);
bfd_vma sec_vma = tls_sec->output_section->vma;
- bfd_put_32 (output_bfd,
+ if (h == NULL || h->forced_local
+ || !elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd_put_32 (output_bfd,
sym_value - sec_vma
+ (elf_hash_table (info)->dynamic_sections_created
? 0
- : (align_power (TCB_SIZE,
+ : (align_power (0,
tls_sec->alignment_power))),
htab->sgot->contents + entry->offset
+ (entry->existing_entries == TLS_GOT_MOD_AND_OFF
? 4 : 0));
- ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
- "@ %lx, for symbol %s\n",
- (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
- "GOT_TLS_IE"),
- (long) (sym_value - sec_vma),
- (long) (htab->sgot->output_section->vma
- + htab->sgot->output_offset
- + entry->offset
- + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
- ? 4 : 0)),
- symbol_name);
+ ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
+ "@ %lx, for symbol %s\n",
+ (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
+ "GOT_TLS_IE"),
+ (long) (sym_value - sec_vma),
+ (long) (htab->sgot->output_section->vma
+ + htab->sgot->output_offset
+ + entry->offset
+ + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
+ ? 4 : 0)),
+ symbol_name);
+ }
}
break;
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
index 668642c3024..e96b3f86974 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -1989,36 +1989,35 @@ elf_arc_check_relocs (bfd * abfd,
switch (r_type)
{
- case R_ARC_32:
- case R_ARC_32_ME:
- /* During shared library creation, these relocs should not
- appear in a shared library (as memory will be read only
- and the dynamic linker can not resolve these. However
- the error should not occur for e.g. debugging or
- non-readonly sections. */
- if (h != NULL
- && (bfd_link_dll (info) && !bfd_link_pie (info))
- && (sec->flags & SEC_ALLOC) != 0
- && (sec->flags & SEC_READONLY) != 0
- && ((sec->flags & SEC_CODE) != 0
- || (sec->flags & SEC_DEBUGGING) != 0))
- {
- const char *name;
- if (h)
- name = h->root.root.string;
- else
- /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
- name = "UNKNOWN";
- _bfd_error_handler
- /* xgettext:c-format */
- (_("%pB: relocation %s against `%s' can not be used"
- " when making a shared object; recompile with -fPIC"),
- abfd,
- arc_elf_howto (r_type)->name,
- name);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
+ case R_ARC_32:
+ case R_ARC_32_ME:
+ /* During shared library creation, these relocs should not
+ appear in a shared library (as memory will be read only
+ and the dynamic linker can not resolve these. However
+ the error should not occur for e.g. debugging or
+ non-readonly sections. */
+ if (h != NULL
+ && (bfd_link_dll (info) && !bfd_link_pie (info))
+ && (sec->flags & SEC_ALLOC) != 0
+ && (sec->flags & SEC_READONLY) != 0
+ && ((sec->flags & SEC_CODE) != 0
+ || (sec->flags & SEC_DEBUGGING) != 0))
+ {
+ const char *name;
+ if (h)
+ name = h->root.root.string;
+ else
+ name = "UNKNOWN";
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: relocation %s against `%s' can not be used"
+ " when making a shared object; recompile with -fPIC"),
+ abfd,
+ arc_elf_howto (r_type)->name,
+ name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
/* In some cases we are not setting the 'non_got_ref'
flag, even though the relocations don't require a GOT
@@ -2068,6 +2067,25 @@ elf_arc_check_relocs (bfd * abfd,
if (is_reloc_for_GOT (howto)
|| is_reloc_for_TLS (howto))
{
+ if (bfd_link_dll (info) && !bfd_link_pie (info)
+ && (r_type == R_ARC_TLS_LE_32 || r_type == R_ARC_TLS_LE_S9))
+ {
+ const char *name;
+ if (h)
+ name = h->root.root.string;
+ else
+ /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
+ name = "UNKNOWN";
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: relocation %s against `%s' can not be used"
+ " when making a shared object; recompile with -fPIC"),
+ abfd,
+ arc_elf_howto (r_type)->name,
+ name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
if (! _bfd_elf_create_got_section (dynobj, info))
return FALSE;
@@ -2490,6 +2508,38 @@ elf_arc_finish_dynamic_symbol (bfd * output_bfd,
s = bfd_get_linker_section (dynobj, SECTION); \
break;
+
+struct obfd_info_group {
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+};
+
+static bfd_boolean
+arc_create_forced_local_got_entries_for_tls (struct bfd_hash_entry *bh,
+ void *data)
+{
+ struct elf_arc_link_hash_entry * h =
+ (struct elf_arc_link_hash_entry *) bh;
+ struct obfd_info_group *tmp = (struct obfd_info_group *) data;
+
+ if (h->got_ents != NULL)
+ {
+ BFD_ASSERT (h);
+
+ struct got_entry *list = h->got_ents;
+
+ while (list != NULL)
+ {
+ create_got_dynrelocs_for_single_entry (list, tmp->output_bfd,
+ tmp->info, h);
+ list = list->next;
+ }
+ }
+
+ return TRUE;
+}
+
+
/* Function : elf_arc_finish_dynamic_sections
Brief : Finish up the dynamic sections handling.
Args : output_bfd :
@@ -2623,6 +2673,12 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd,
}
}
+ struct obfd_info_group group;
+ group.output_bfd = output_bfd;
+ group.info = info;
+ bfd_hash_traverse (&info->hash->table,
+ arc_create_forced_local_got_entries_for_tls, &group);
+
return TRUE;
}