forked from Imagelibrary/binutils-gdb
include/
PR 7047
* bfdlink.h (struct bfd_elf_version_expr): Delete "symbol".
Add "literal".
bfd/
PR 7047
* configure.in: Bump version.
* configure: Regenerate.
* elflink.c (_bfd_elf_link_assign_sym_version): Continue matching
against version nodes when a global match is a wildcard. Similarly
continue matching on local wildcard matches, rather than only
continuing for "*". Have any global wildcard match override a
local wildcard match. Correct logic hiding unversioned symbol.
(bfd_elf_size_dynamic_sections): Update for changes to struct
bfd_elf_version_expr.
ld/
PR 7047
* emultempl/ppc64elf.em (gld${EMULATION_NAME}_new_vers_pattern): Update
for changes to struct bfd_elf_version_expr.
* ldlang.c (lang_vers_match, version_expr_head_hash): Likewise.
(version_expr_head_eq, lang_finalize_version_expr_head): Likewise.
(lang_register_vers_node): Likewise.
(lang_new_vers_pattern): Likewise. Ensure "literal" is set when
no glob chars found in "pattern".
(realsymbol): Correct backslash quote logic.
* ld.texinfo (VERSION): Warn about global wildcards.
This commit is contained in:
@@ -2010,41 +2010,36 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
|
||||
if (h->verinfo.vertree == NULL && sinfo->verdefs != NULL)
|
||||
{
|
||||
struct bfd_elf_version_tree *t;
|
||||
struct bfd_elf_version_tree *local_ver;
|
||||
struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver;
|
||||
struct bfd_elf_version_expr *d;
|
||||
|
||||
/* See if can find what version this symbol is in. If the
|
||||
symbol is supposed to be local, then don't actually register
|
||||
it. */
|
||||
local_ver = NULL;
|
||||
global_ver = NULL;
|
||||
exist_ver = NULL;
|
||||
for (t = sinfo->verdefs; t != NULL; t = t->next)
|
||||
{
|
||||
if (t->globals.list != NULL)
|
||||
{
|
||||
bfd_boolean matched;
|
||||
|
||||
matched = FALSE;
|
||||
d = NULL;
|
||||
while ((d = (*t->match) (&t->globals, d,
|
||||
h->root.root.string)) != NULL)
|
||||
if (d->symver)
|
||||
matched = TRUE;
|
||||
else
|
||||
{
|
||||
/* There is a version without definition. Make
|
||||
the symbol the default definition for this
|
||||
version. */
|
||||
h->verinfo.vertree = t;
|
||||
local_ver = NULL;
|
||||
d->script = 1;
|
||||
{
|
||||
global_ver = t;
|
||||
local_ver = NULL;
|
||||
if (d->symver)
|
||||
exist_ver = t;
|
||||
d->script = 1;
|
||||
/* If the match is a wildcard pattern, keep looking for
|
||||
a more explicit, perhaps even local, match. */
|
||||
if (d->literal)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (d != NULL)
|
||||
break;
|
||||
else if (matched)
|
||||
/* There is no undefined version for this symbol. Hide the
|
||||
default one. */
|
||||
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
|
||||
}
|
||||
|
||||
if (t->locals.list != NULL)
|
||||
@@ -2054,11 +2049,14 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
|
||||
h->root.root.string)) != NULL)
|
||||
{
|
||||
local_ver = t;
|
||||
/* If the match is "*", keep looking for a more
|
||||
explicit, perhaps even global, match.
|
||||
XXX: Shouldn't this be !d->wildcard instead? */
|
||||
if (d->pattern[0] != '*' || d->pattern[1] != '\0')
|
||||
break;
|
||||
/* If the match is a wildcard pattern, keep looking for
|
||||
a more explicit, perhaps even global, match. */
|
||||
if (d->literal)
|
||||
{
|
||||
/* An exact match overrides a global wildcard. */
|
||||
global_ver = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (d != NULL)
|
||||
@@ -2066,14 +2064,22 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
if (local_ver != NULL)
|
||||
if (global_ver != NULL)
|
||||
{
|
||||
h->verinfo.vertree = global_ver;
|
||||
/* If we already have a versioned symbol that matches the
|
||||
node for this symbol, then we don't want to create a
|
||||
duplicate from the unversioned symbol. Instead hide the
|
||||
unversioned symbol. */
|
||||
if (exist_ver == global_ver)
|
||||
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
|
||||
}
|
||||
else if (local_ver != NULL)
|
||||
{
|
||||
h->verinfo.vertree = local_ver;
|
||||
if (h->dynindx != -1
|
||||
&& ! info->export_dynamic)
|
||||
{
|
||||
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
|
||||
}
|
||||
if (!info->export_dynamic
|
||||
|| exist_ver == local_ver)
|
||||
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5566,14 +5572,14 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
/* Make all global versions with definition. */
|
||||
for (t = verdefs; t != NULL; t = t->next)
|
||||
for (d = t->globals.list; d != NULL; d = d->next)
|
||||
if (!d->symver && d->symbol)
|
||||
if (!d->symver && d->literal)
|
||||
{
|
||||
const char *verstr, *name;
|
||||
size_t namelen, verlen, newlen;
|
||||
char *newname, *p;
|
||||
struct elf_link_hash_entry *newh;
|
||||
|
||||
name = d->symbol;
|
||||
name = d->pattern;
|
||||
namelen = strlen (name);
|
||||
verstr = t->name;
|
||||
verlen = strlen (verstr);
|
||||
@@ -5631,7 +5637,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
all_defined = TRUE;
|
||||
for (t = verdefs; t != NULL; t = t->next)
|
||||
for (d = t->globals.list; d != NULL; d = d->next)
|
||||
if (!d->symver && !d->script)
|
||||
if (d->literal && !d->symver && !d->script)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: undefined version: %s"),
|
||||
|
||||
Reference in New Issue
Block a user