mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +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:
@ -208,7 +208,7 @@ arc_got_entry_type_for_reloc (reloc_howto_type *howto)
|
|||||||
__LINE__, name_for_global_symbol (H)); \
|
__LINE__, name_for_global_symbol (H)); \
|
||||||
} \
|
} \
|
||||||
if (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)) \
|
if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
|
||||||
return FALSE; \
|
return FALSE; \
|
||||||
htab->s##SECNAME->size += 4; \
|
htab->s##SECNAME->size += 4; \
|
||||||
@ -284,6 +284,7 @@ relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p,
|
|||||||
BFD_ASSERT (entry);
|
BFD_ASSERT (entry);
|
||||||
|
|
||||||
if (h == NULL
|
if (h == NULL
|
||||||
|
|| h->forced_local == TRUE
|
||||||
|| (! elf_hash_table (info)->dynamic_sections_created
|
|| (! elf_hash_table (info)->dynamic_sections_created
|
||||||
|| (bfd_link_pic (info)
|
|| (bfd_link_pic (info)
|
||||||
&& SYMBOL_REFERENCES_LOCAL (info, h))))
|
&& SYMBOL_REFERENCES_LOCAL (info, h))))
|
||||||
@ -331,11 +332,14 @@ relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p,
|
|||||||
BFD_ASSERT (tls_sec && tls_sec->output_section);
|
BFD_ASSERT (tls_sec && tls_sec->output_section);
|
||||||
bfd_vma sec_vma = tls_sec->output_section->vma;
|
bfd_vma sec_vma = tls_sec->output_section->vma;
|
||||||
|
|
||||||
|
if (h == NULL || h->forced_local
|
||||||
|
|| !elf_hash_table (info)->dynamic_sections_created)
|
||||||
|
{
|
||||||
bfd_put_32 (output_bfd,
|
bfd_put_32 (output_bfd,
|
||||||
sym_value - sec_vma
|
sym_value - sec_vma
|
||||||
+ (elf_hash_table (info)->dynamic_sections_created
|
+ (elf_hash_table (info)->dynamic_sections_created
|
||||||
? 0
|
? 0
|
||||||
: (align_power (TCB_SIZE,
|
: (align_power (0,
|
||||||
tls_sec->alignment_power))),
|
tls_sec->alignment_power))),
|
||||||
htab->sgot->contents + entry->offset
|
htab->sgot->contents + entry->offset
|
||||||
+ (entry->existing_entries == TLS_GOT_MOD_AND_OFF
|
+ (entry->existing_entries == TLS_GOT_MOD_AND_OFF
|
||||||
@ -353,6 +357,7 @@ relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p,
|
|||||||
? 4 : 0)),
|
? 4 : 0)),
|
||||||
symbol_name);
|
symbol_name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOT_TLS_IE:
|
case GOT_TLS_IE:
|
||||||
|
@ -2007,7 +2007,6 @@ elf_arc_check_relocs (bfd * abfd,
|
|||||||
if (h)
|
if (h)
|
||||||
name = h->root.root.string;
|
name = h->root.root.string;
|
||||||
else
|
else
|
||||||
/* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
|
|
||||||
name = "UNKNOWN";
|
name = "UNKNOWN";
|
||||||
_bfd_error_handler
|
_bfd_error_handler
|
||||||
/* xgettext:c-format */
|
/* xgettext:c-format */
|
||||||
@ -2068,6 +2067,25 @@ elf_arc_check_relocs (bfd * abfd,
|
|||||||
if (is_reloc_for_GOT (howto)
|
if (is_reloc_for_GOT (howto)
|
||||||
|| is_reloc_for_TLS (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))
|
if (! _bfd_elf_create_got_section (dynobj, info))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -2490,6 +2508,38 @@ elf_arc_finish_dynamic_symbol (bfd * output_bfd,
|
|||||||
s = bfd_get_linker_section (dynobj, SECTION); \
|
s = bfd_get_linker_section (dynobj, SECTION); \
|
||||||
break;
|
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
|
/* Function : elf_arc_finish_dynamic_sections
|
||||||
Brief : Finish up the dynamic sections handling.
|
Brief : Finish up the dynamic sections handling.
|
||||||
Args : output_bfd :
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user