mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +08:00
Revert PR16467 change
This reverts the pr16467 change, which was incorrect due to faulty analysis of the pr16467 testcase. The failure was not due to a mismatch in symbol type (ifunc/non-ifunc) but due to a symbol loop being set up. See https://sourceware.org/ml/binutils/2016-06/msg00013.html for some rambling on versioned symbols and ELF shared library symbol overriding that explain this patch. bfd/ PR ld/20159 PR ld/16467 * elflink.c (_bfd_elf_merge_symbol): Revert PR16467 change. (_bfd_elf_add_default_symbol): Don't indirect to/from defined symbol given a version by a script different to the version of the symbol being added. (elf_link_add_object_symbols): Use _bfd_elf_strtab_save and _bfd_elf_strtab_restore. Don't fudge dynstr references. * elf-strtab.c (_bfd_elf_strtab_restore_size): Delete. (struct strtab_save): New. (_bfd_elf_strtab_save, _bfd_elf_strtab_restore): New functions. * elf-bfd.h (_bfd_elf_strtab_restore_size): Delete. (_bfd_elf_strtab_save, _bfd_elf_strtab_restore): Declare.
This commit is contained in:
@ -1,3 +1,19 @@
|
|||||||
|
2016-05-31 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR ld/20159
|
||||||
|
PR ld/16467
|
||||||
|
* elflink.c (_bfd_elf_merge_symbol): Revert PR16467 change.
|
||||||
|
(_bfd_elf_add_default_symbol): Don't indirect to/from defined
|
||||||
|
symbol given a version by a script different to the version
|
||||||
|
of the symbol being added.
|
||||||
|
(elf_link_add_object_symbols): Use _bfd_elf_strtab_save and
|
||||||
|
_bfd_elf_strtab_restore. Don't fudge dynstr references.
|
||||||
|
* elf-strtab.c (_bfd_elf_strtab_restore_size): Delete.
|
||||||
|
(struct strtab_save): New.
|
||||||
|
(_bfd_elf_strtab_save, _bfd_elf_strtab_restore): New functions.
|
||||||
|
* elf-bfd.h (_bfd_elf_strtab_restore_size): Delete.
|
||||||
|
(_bfd_elf_strtab_save, _bfd_elf_strtab_restore): Declare.
|
||||||
|
|
||||||
2016-06-01 Trevor Saunders <tbsaunde+binutils@tbsaunde.org>
|
2016-06-01 Trevor Saunders <tbsaunde+binutils@tbsaunde.org>
|
||||||
|
|
||||||
* elf32-hppa.h: Add extern "C".
|
* elf32-hppa.h: Add extern "C".
|
||||||
|
@ -2058,9 +2058,11 @@ extern void _bfd_elf_strtab_delref
|
|||||||
extern unsigned int _bfd_elf_strtab_refcount
|
extern unsigned int _bfd_elf_strtab_refcount
|
||||||
(struct elf_strtab_hash *, bfd_size_type);
|
(struct elf_strtab_hash *, bfd_size_type);
|
||||||
extern void _bfd_elf_strtab_clear_all_refs
|
extern void _bfd_elf_strtab_clear_all_refs
|
||||||
(struct elf_strtab_hash *tab);
|
(struct elf_strtab_hash *);
|
||||||
extern void _bfd_elf_strtab_restore_size
|
extern void *_bfd_elf_strtab_save
|
||||||
(struct elf_strtab_hash *, bfd_size_type);
|
(struct elf_strtab_hash *);
|
||||||
|
extern void _bfd_elf_strtab_restore
|
||||||
|
(struct elf_strtab_hash *, void *);
|
||||||
extern bfd_size_type _bfd_elf_strtab_size
|
extern bfd_size_type _bfd_elf_strtab_size
|
||||||
(struct elf_strtab_hash *);
|
(struct elf_strtab_hash *);
|
||||||
extern bfd_size_type _bfd_elf_strtab_offset
|
extern bfd_size_type _bfd_elf_strtab_offset
|
||||||
|
@ -215,16 +215,45 @@ _bfd_elf_strtab_clear_all_refs (struct elf_strtab_hash *tab)
|
|||||||
tab->array[idx]->refcount = 0;
|
tab->array[idx]->refcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Downsizes strtab. Entries from IDX up to the current size are
|
/* Save strtab refcounts prior to adding --as-needed library. */
|
||||||
removed from the array. */
|
|
||||||
void
|
struct strtab_save
|
||||||
_bfd_elf_strtab_restore_size (struct elf_strtab_hash *tab, bfd_size_type idx)
|
|
||||||
{
|
{
|
||||||
bfd_size_type curr_size = tab->size;
|
bfd_size_type size;
|
||||||
|
unsigned int refcount[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
void *
|
||||||
|
_bfd_elf_strtab_save (struct elf_strtab_hash *tab)
|
||||||
|
{
|
||||||
|
struct strtab_save *save;
|
||||||
|
bfd_size_type idx, size;
|
||||||
|
|
||||||
|
size = sizeof (*save) + (tab->size - 1) * sizeof (save->refcount[0]);
|
||||||
|
save = bfd_malloc (size);
|
||||||
|
if (save == NULL)
|
||||||
|
return save;
|
||||||
|
|
||||||
|
save->size = tab->size;
|
||||||
|
for (idx = 1; idx < tab->size; idx++)
|
||||||
|
save->refcount[idx] = tab->array[idx]->refcount;
|
||||||
|
return save;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore strtab refcounts on finding --as-needed library not needed. */
|
||||||
|
|
||||||
|
void
|
||||||
|
_bfd_elf_strtab_restore (struct elf_strtab_hash *tab, void *buf)
|
||||||
|
{
|
||||||
|
bfd_size_type idx, curr_size = tab->size;
|
||||||
|
struct strtab_save *save = (struct strtab_save *) buf;
|
||||||
|
|
||||||
BFD_ASSERT (tab->sec_size == 0);
|
BFD_ASSERT (tab->sec_size == 0);
|
||||||
BFD_ASSERT (idx <= curr_size);
|
BFD_ASSERT (save->size <= curr_size);
|
||||||
tab->size = idx;
|
tab->size = save->size;
|
||||||
|
for (idx = 1; idx < save->size; ++idx)
|
||||||
|
tab->array[idx]->refcount = save->refcount[idx];
|
||||||
|
|
||||||
for (; idx < curr_size; ++idx)
|
for (; idx < curr_size; ++idx)
|
||||||
{
|
{
|
||||||
/* We don't remove entries from the hash table, just set their
|
/* We don't remove entries from the hash table, just set their
|
||||||
|
@ -1202,21 +1202,20 @@ _bfd_elf_merge_symbol (bfd *abfd,
|
|||||||
oldfunc = (h->type != STT_NOTYPE
|
oldfunc = (h->type != STT_NOTYPE
|
||||||
&& bed->is_function_type (h->type));
|
&& bed->is_function_type (h->type));
|
||||||
|
|
||||||
/* When we try to create a default indirect symbol from the dynamic
|
/* If creating a default indirect symbol ("foo" or "foo@") from a
|
||||||
definition with the default version, we skip it if its type and
|
dynamic versioned definition ("foo@@") skip doing so if there is
|
||||||
the type of existing regular definition mismatch. */
|
an existing regular definition with a different type. We don't
|
||||||
|
want, for example, a "time" variable in the executable overriding
|
||||||
|
a "time" function in a shared library. */
|
||||||
if (pold_alignment == NULL
|
if (pold_alignment == NULL
|
||||||
&& newdyn
|
&& newdyn
|
||||||
&& newdef
|
&& newdef
|
||||||
&& !olddyn
|
&& !olddyn
|
||||||
&& (((olddef || h->root.type == bfd_link_hash_common)
|
&& (olddef || h->root.type == bfd_link_hash_common)
|
||||||
&& ELF_ST_TYPE (sym->st_info) != h->type
|
&& ELF_ST_TYPE (sym->st_info) != h->type
|
||||||
&& ELF_ST_TYPE (sym->st_info) != STT_NOTYPE
|
&& ELF_ST_TYPE (sym->st_info) != STT_NOTYPE
|
||||||
&& h->type != STT_NOTYPE
|
&& h->type != STT_NOTYPE
|
||||||
&& !(newfunc && oldfunc))
|
&& !(newfunc && oldfunc))
|
||||||
|| (olddef
|
|
||||||
&& ((h->type == STT_GNU_IFUNC)
|
|
||||||
!= (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)))))
|
|
||||||
{
|
{
|
||||||
*skip = TRUE;
|
*skip = TRUE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -1781,6 +1780,31 @@ _bfd_elf_add_default_symbol (bfd *abfd,
|
|||||||
if (skip)
|
if (skip)
|
||||||
goto nondefault;
|
goto nondefault;
|
||||||
|
|
||||||
|
if (hi->def_regular)
|
||||||
|
{
|
||||||
|
/* If the undecorated symbol will have a version added by a
|
||||||
|
script different to H, then don't indirect to/from the
|
||||||
|
undecorated symbol. This isn't ideal because we may not yet
|
||||||
|
have seen symbol versions, if given by a script on the
|
||||||
|
command line rather than via --version-script. */
|
||||||
|
if (hi->verinfo.vertree == NULL && info->version_info != NULL)
|
||||||
|
{
|
||||||
|
bfd_boolean hide;
|
||||||
|
|
||||||
|
hi->verinfo.vertree
|
||||||
|
= bfd_find_version_for_sym (info->version_info,
|
||||||
|
hi->root.root.string, &hide);
|
||||||
|
if (hi->verinfo.vertree != NULL && hide)
|
||||||
|
{
|
||||||
|
(*bed->elf_backend_hide_symbol) (info, hi, TRUE);
|
||||||
|
goto nondefault;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hi->verinfo.vertree != NULL
|
||||||
|
&& strcmp (p + 1 + (p[1] == '@'), hi->verinfo.vertree->name) != 0)
|
||||||
|
goto nondefault;
|
||||||
|
}
|
||||||
|
|
||||||
if (! override)
|
if (! override)
|
||||||
{
|
{
|
||||||
/* Add the default symbol if not performing a relocatable link. */
|
/* Add the default symbol if not performing a relocatable link. */
|
||||||
@ -3591,8 +3615,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||||||
void *old_ent;
|
void *old_ent;
|
||||||
struct bfd_link_hash_entry *old_undefs = NULL;
|
struct bfd_link_hash_entry *old_undefs = NULL;
|
||||||
struct bfd_link_hash_entry *old_undefs_tail = NULL;
|
struct bfd_link_hash_entry *old_undefs_tail = NULL;
|
||||||
long old_dynsymcount = 0;
|
void *old_strtab = NULL;
|
||||||
bfd_size_type old_dynstr_size = 0;
|
|
||||||
size_t tabsize = 0;
|
size_t tabsize = 0;
|
||||||
asection *s;
|
asection *s;
|
||||||
bfd_boolean just_syms;
|
bfd_boolean just_syms;
|
||||||
@ -4036,8 +4059,9 @@ error_free_dyn:
|
|||||||
old_table = htab->root.table.table;
|
old_table = htab->root.table.table;
|
||||||
old_size = htab->root.table.size;
|
old_size = htab->root.table.size;
|
||||||
old_count = htab->root.table.count;
|
old_count = htab->root.table.count;
|
||||||
old_dynsymcount = htab->dynsymcount;
|
old_strtab = _bfd_elf_strtab_save (htab->dynstr);
|
||||||
old_dynstr_size = _bfd_elf_strtab_size (htab->dynstr);
|
if (old_strtab == NULL)
|
||||||
|
goto error_free_vers;
|
||||||
|
|
||||||
for (i = 0; i < htab->root.table.size; i++)
|
for (i = 0; i < htab->root.table.size; i++)
|
||||||
{
|
{
|
||||||
@ -4762,7 +4786,9 @@ error_free_dyn:
|
|||||||
memcpy (htab->root.table.table, old_tab, tabsize);
|
memcpy (htab->root.table.table, old_tab, tabsize);
|
||||||
htab->root.undefs = old_undefs;
|
htab->root.undefs = old_undefs;
|
||||||
htab->root.undefs_tail = old_undefs_tail;
|
htab->root.undefs_tail = old_undefs_tail;
|
||||||
_bfd_elf_strtab_restore_size (htab->dynstr, old_dynstr_size);
|
_bfd_elf_strtab_restore (htab->dynstr, old_strtab);
|
||||||
|
free (old_strtab);
|
||||||
|
old_strtab = NULL;
|
||||||
for (i = 0; i < htab->root.table.size; i++)
|
for (i = 0; i < htab->root.table.size; i++)
|
||||||
{
|
{
|
||||||
struct bfd_hash_entry *p;
|
struct bfd_hash_entry *p;
|
||||||
@ -4775,9 +4801,6 @@ error_free_dyn:
|
|||||||
h = (struct elf_link_hash_entry *) p;
|
h = (struct elf_link_hash_entry *) p;
|
||||||
if (h->root.type == bfd_link_hash_warning)
|
if (h->root.type == bfd_link_hash_warning)
|
||||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||||
if (h->dynindx >= old_dynsymcount
|
|
||||||
&& h->dynstr_index < old_dynstr_size)
|
|
||||||
_bfd_elf_strtab_delref (htab->dynstr, h->dynstr_index);
|
|
||||||
|
|
||||||
/* Preserve the maximum alignment and size for common
|
/* Preserve the maximum alignment and size for common
|
||||||
symbols even if this dynamic lib isn't on DT_NEEDED
|
symbols even if this dynamic lib isn't on DT_NEEDED
|
||||||
@ -5099,6 +5122,8 @@ error_free_dyn:
|
|||||||
error_free_vers:
|
error_free_vers:
|
||||||
if (old_tab != NULL)
|
if (old_tab != NULL)
|
||||||
free (old_tab);
|
free (old_tab);
|
||||||
|
if (old_strtab != NULL)
|
||||||
|
free (old_strtab);
|
||||||
if (nondeflt_vers != NULL)
|
if (nondeflt_vers != NULL)
|
||||||
free (nondeflt_vers);
|
free (nondeflt_vers);
|
||||||
if (extversym != NULL)
|
if (extversym != NULL)
|
||||||
|
Reference in New Issue
Block a user