diff options
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elflink.h | 38 | ||||
-rw-r--r-- | ld/ChangeLog | 5 | ||||
-rw-r--r-- | ld/ld.texinfo | 3 |
4 files changed, 50 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 53d5199..27ff268 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2002-07-14 H.J. Lu <hjl@gnu.org> + + * elflink.h (elf_link_assign_sym_version): Hide the default + definition if there is a hidden versioned definition. + 2002-07-12 Hans-Peter Nilsson <hp@axis.com> * elf32-cris.c (cris_elf_relocate_section): Drop nonsensical diff --git a/bfd/elflink.h b/bfd/elflink.h index 57819e9..7fa2ccb 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -4345,6 +4345,7 @@ elf_link_assign_sym_version (h, data) (_("%s: undefined versioned symbol name %s"), bfd_get_filename (sinfo->output_bfd), h->root.root.string); bfd_set_error (bfd_error_bad_value); +error_return: sinfo->failed = true; return false; } @@ -4416,6 +4417,43 @@ elf_link_assign_sym_version (h, data) (*bed->elf_backend_hide_symbol) (info, h, true); } } + + /* We need to check if a hidden versioned definition should + hide the default one. */ + if (h->dynindx != -1 && h->verinfo.vertree != NULL) + { + const char *verstr, *name; + size_t namelen, verlen, newlen; + char *newname; + struct elf_link_hash_entry *newh; + + name = h->root.root.string; + namelen = strlen (name); + verstr = h->verinfo.vertree->name; + verlen = strlen (verstr); + newlen = namelen + verlen + 2; + + newname = (char *) bfd_malloc ((bfd_size_type) newlen); + if (newname == NULL) + goto error_return; + memcpy (newname, name, namelen); + + /* Check the hidden versioned definition. */ + p = newname + namelen; + *p++ = ELF_VER_CHR; + memcpy (p, verstr, verlen + 1); + newh = elf_link_hash_lookup (elf_hash_table (info), newname, + false, false, false); + + if (newh + && (newh->root.type == bfd_link_hash_defined + || newh->root.type == bfd_link_hash_defweak)) + /* We find a hidden versioned definition. Hide the default + one. */ + (*bed->elf_backend_hide_symbol) (info, h, true); + + free (newname); + } } return true; diff --git a/ld/ChangeLog b/ld/ChangeLog index 1f6c5fb..a32fefe 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2002-07-14 H.J. Lu <hjl@gnu.org> + + * ld.texinfo: Document a .symver takes precedence over a + version script. + 2002-07-12 Alan Modra <amodra@bigpond.net.au> * emulparams/elf64ppc.sh (ARCH): Set to powerpc:common64. diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 36a2877..dadc75b 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -3762,7 +3762,8 @@ __asm__(".symver original_foo,foo@@VERS_1.1"); in the C source file. This renames the function @samp{original_foo} to be an alias for @samp{foo} bound to the version node @samp{VERS_1.1}. The @samp{local:} directive can be used to prevent the symbol -@samp{original_foo} from being exported. +@samp{original_foo} from being exported. A @samp{.symver} directive +takes precedence over a version script. The second GNU extension is to allow multiple versions of the same function to appear in a given shared library. In this way you can make |