diff options
author | Alan Modra <amodra@gmail.com> | 2008-11-26 01:04:17 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2008-11-26 01:04:17 +0000 |
commit | ae5a359786fb21bf95678a4e9eebf2ff90114c7a (patch) | |
tree | 553563478a9db484d0305122e3f15748073bfb1d /bfd/elflink.c | |
parent | 6cf7d91b7e79070a10ad6012559ac9adac60499a (diff) | |
download | gdb-ae5a359786fb21bf95678a4e9eebf2ff90114c7a.zip gdb-ae5a359786fb21bf95678a4e9eebf2ff90114c7a.tar.gz gdb-ae5a359786fb21bf95678a4e9eebf2ff90114c7a.tar.bz2 |
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.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index ce1dff7..43379c7 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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"), |