diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 13 | ||||
-rwxr-xr-x | bfd/configure | 2 | ||||
-rw-r--r-- | bfd/configure.in | 2 | ||||
-rw-r--r-- | bfd/elflink.c | 72 |
4 files changed, 54 insertions, 35 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9d4a323..e060288 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2008-11-26 Alan Modra <amodra@bigpond.net.au> + + 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. + 2008-11-25 Joel Brobecker <brobecker@adacore.com> * configure.in: Deactivate large-file support on native x86-solaris diff --git a/bfd/configure b/bfd/configure index 042f5d1..8ff1234 100755 --- a/bfd/configure +++ b/bfd/configure @@ -3033,7 +3033,7 @@ fi # Define the identity of the package. PACKAGE=bfd - VERSION=2.19.50 + VERSION=2.19.51 cat >>confdefs.h <<_ACEOF diff --git a/bfd/configure.in b/bfd/configure.in index 7297ee0..47ef10c 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -8,7 +8,7 @@ AC_CONFIG_SRCDIR([libbfd.c]) AC_CANONICAL_TARGET AC_ISC_POSIX -AM_INIT_AUTOMAKE(bfd, 2.19.50) +AM_INIT_AUTOMAKE(bfd, 2.19.51) dnl These must be called before LT_INIT, because it may want dnl to call AC_CHECK_PROG. 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"), |