mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 12:03:41 +08:00
[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.
This commit is contained in:
parent
fda57deda7
commit
d07b621f4c
@ -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;
|
||||
|
||||
|
116
bfd/elf32-arc.c
116
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user