2002-07-13 H.J. Lu * elflink.h (elf_link_assign_sym_version): Bail out if a symbol with a default version conflicts with a hidden symbol with the same version. --- bfd/elflink.h.dup Mon Jul 8 08:58:42 2002 +++ bfd/elflink.h Sat Jul 13 19:48:37 2002 @@ -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,52 @@ elf_link_assign_sym_version (h, data) (*bed->elf_backend_hide_symbol) (info, h, true); } } + + /* We need to check if there is a conflict. */ + if (h->dynindx != -1) + { + const char *verstr, *name; + size_t namelen, verlen, newlen; + char *newname, *p; + 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) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } + memcpy (newname, name, namelen); + + /* Check the hidden symbol. */ + 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) + { + /* We find a versioned definition. Bail out. */ + (*_bfd_error_handler) + (_("%s (%s): duplicated versioned symbol: %s (%s)"), + h->root.root.string, + bfd_get_filename (h->root.u.def.section->owner), + newname, + bfd_get_filename (newh->root.u.def.section->owner)); + free (newname); + bfd_set_error (bfd_error_bad_value); + goto error_return; + } + + free (newname); + } } return true;