From 35b0ce5903637508ed25ab44ca5db3d1850b99ab Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 17 Aug 2004 05:38:28 +0000 Subject: [PATCH] * elf64-ppc.c (add_symbol_adjust): Correct mismatched function symbol visibility. (ppc64_elf_check_directives): Check that we have the right hash table before proceeding. --- bfd/ChangeLog | 7 +++++++ bfd/elf64-ppc.c | 30 ++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8cb7a6661fa..72fe05a19f5 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2004-08-17 Alan Modra + + * elf64-ppc.c (add_symbol_adjust): Correct mismatched function + symbol visibility. + (ppc64_elf_check_directives): Check that we have the right hash + table before proceeding. + 2004-08-17 Alan Modra * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add "deleted_section". diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index ccb80896462..9210ad1491b 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -3569,7 +3569,10 @@ ppc64_elf_archive_symbol_lookup (bfd *abfd, new ABI object defines "bar". Well, at least, undefined dot symbols are made weak. This stops later archive searches from including an object if we already have a function descriptor definition. It also - prevents the linker complaining about undefined symbols. */ + prevents the linker complaining about undefined symbols. + We also check and correct mismatched symbol visibility here. The + most restrictive visibility of the function descriptor and the + function entry symbol is used. */ static bfd_boolean add_symbol_adjust (struct elf_link_hash_entry *h, void *inf) @@ -3585,8 +3588,7 @@ add_symbol_adjust (struct elf_link_hash_entry *h, void *inf) if (h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type != bfd_link_hash_undefined - || h->root.root.string[0] != '.') + if (h->root.root.string[0] != '.') return TRUE; info = inf; @@ -3595,9 +3597,19 @@ add_symbol_adjust (struct elf_link_hash_entry *h, void *inf) fdh = get_fdh (eh, htab); if (fdh != NULL) { - eh->elf.root.type = bfd_link_hash_undefweak; - eh->was_undefined = 1; - htab->twiddled_syms = 1; + unsigned entry_vis = ELF_ST_VISIBILITY (eh->elf.other) - 1; + unsigned descr_vis = ELF_ST_VISIBILITY (fdh->elf.other) - 1; + if (entry_vis < descr_vis) + fdh->elf.other += entry_vis - descr_vis; + else if (entry_vis > descr_vis) + eh->elf.other += descr_vis - entry_vis; + + if (eh->elf.root.type == bfd_link_hash_undefined) + { + eh->elf.root.type = bfd_link_hash_undefweak; + eh->was_undefined = 1; + htab->twiddled_syms = 1; + } } return TRUE; @@ -3608,8 +3620,14 @@ ppc64_elf_check_directives (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) { struct ppc_link_hash_table *htab; + extern const bfd_target bfd_elf64_powerpc_vec; + extern const bfd_target bfd_elf64_powerpcle_vec; htab = ppc_hash_table (info); + if (htab->elf.root.creator != &bfd_elf64_powerpc_vec + && htab->elf.root.creator != &bfd_elf64_powerpcle_vec) + return TRUE; + elf_link_hash_traverse (&htab->elf, add_symbol_adjust, info); /* We need to fix the undefs list for any syms we have twiddled to -- 2.30.2