[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:
Cupertino Miranda 2018-10-04 10:17:03 +01:00
parent fda57deda7
commit d07b621f4c
2 changed files with 105 additions and 44 deletions

View File

@ -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;

View File

@ -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;
}