From 1d27f980c3af08651e5173522512629a69dab35a Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 8 May 2003 05:11:57 +0000 Subject: 2003-05-07 H.J. Lu * elflink.h (elf_link_check_versioned_symbol): Also handle the case that a DSO references a hidden symbol which may be satisfied by a versioned symbol in another DSO. (elf_link_output_extsym): Check versioned definition for hidden symbol referenced by a DSO. --- bfd/ChangeLog | 8 ++++++++ bfd/elflink.h | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5767cdf9ab4..8944e3f98d7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2003-05-07 H.J. Lu + + * elflink.h (elf_link_check_versioned_symbol): Also handle the + case that a DSO references a hidden symbol which may be + satisfied by a versioned symbol in another DSO. + (elf_link_output_extsym): Check versioned definition for hidden + symbol referenced by a DSO. + 2003-05-07 Nick Clifton * elf32-xstormy16.c (xstormy16_elf_howto_table): Reset diff --git a/bfd/elflink.h b/bfd/elflink.h index 0f590a4c294..ade717dc74f 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -6230,21 +6230,45 @@ elf_link_sec_merge_syms (h, data) /* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in allowing an unsatisfied unversioned symbol in the DSO to match a - versioned symbol that would normally require an explicit version. */ + versioned symbol that would normally require an explicit version. + We also handle the case that a DSO references a hidden symbol + which may be satisfied by a versioned symbol in another DSO. */ static bfd_boolean elf_link_check_versioned_symbol (info, h) struct bfd_link_info *info; struct elf_link_hash_entry *h; { - bfd *undef_bfd = h->root.u.undef.abfd; + bfd *abfd; struct elf_link_loaded_list *loaded; - if ((undef_bfd->flags & DYNAMIC) == 0 - || info->hash->creator->flavour != bfd_target_elf_flavour - || elf_dt_soname (undef_bfd) == NULL) + if (info->hash->creator->flavour != bfd_target_elf_flavour) return FALSE; + switch (h->root.type) + { + default: + abfd = NULL; + break; + + case bfd_link_hash_undefined: + case bfd_link_hash_undefweak: + abfd = h->root.u.undef.abfd; + if ((abfd->flags & DYNAMIC) == 0 || elf_dt_soname (abfd) == NULL) + return FALSE; + break; + + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + abfd = h->root.u.def.section->owner; + break; + + case bfd_link_hash_common: + abfd = h->root.u.c.p->section->owner; + break; + } + BFD_ASSERT (abfd != NULL); + for (loaded = elf_hash_table (info)->loaded; loaded != NULL; loaded = loaded->next) @@ -6264,7 +6288,7 @@ elf_link_check_versioned_symbol (info, h) input = loaded->abfd; /* We check each DSO for a possible hidden versioned definition. */ - if (input == undef_bfd + if (input == abfd || (input->flags & DYNAMIC) == 0 || elf_dynversym (input) == 0) continue; @@ -6416,7 +6440,8 @@ elf_link_output_extsym (h, data) && (h->elf_link_hash_flags & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK)) - == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC)) + == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC) + && ! elf_link_check_versioned_symbol (finfo->info, h)) { (*_bfd_error_handler) (_("%s: %s symbol `%s' in %s is referenced by DSO"), -- cgit v1.2.1