From 433817dddee6fed37aa16714f124cbb359d530ee Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 9 May 2005 10:30:40 +0000 Subject: [PATCH] * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add has_dotsym. (ppc64_elf_add_symbol_hook): Set has_dotsym. (ppc64_elf_check_directives): Only process syms when has_dotsym. (func_desc_adjust): Hide fake function descriptors when function code entry is defined. (adjust_opd_syms): Adjust for deleted_section becoming union field. --- bfd/ChangeLog | 9 ++++++++ bfd/elf64-ppc.c | 56 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7ab00f0993..bf8f14b391 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2005-05-09 Alan Modra + + * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add has_dotsym. + (ppc64_elf_add_symbol_hook): Set has_dotsym. + (ppc64_elf_check_directives): Only process syms when has_dotsym. + (func_desc_adjust): Hide fake function descriptors when function + code entry is defined. + (adjust_opd_syms): Adjust for deleted_section becoming union field. + 2005-05-09 Alan Modra * elfcode.h (elf_object_p): Add more sanity checks on elf header. diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index fa6b095a1f..f05c783472 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -2369,9 +2369,14 @@ struct ppc64_elf_obj_tdata asection *got; asection *relgot; - /* Used during garbage collection. We attach global symbols defined - on removed .opd entries to this section so that the sym is removed. */ - asection *deleted_section; + union { + /* Used during garbage collection. We attach global symbols defined + on removed .opd entries to this section so that the sym is removed. */ + asection *deleted_section; + + /* Used when adding symbols. */ + bfd_boolean has_dotsym; + } u; /* TLS local dynamic got entry handling. Suppose for multiple GOT sections means we potentially need one of these for each input bfd. */ @@ -4042,10 +4047,10 @@ make_fdh (struct bfd_link_info *info, function type. */ static bfd_boolean -ppc64_elf_add_symbol_hook (bfd *ibfd ATTRIBUTE_UNUSED, +ppc64_elf_add_symbol_hook (bfd *ibfd, struct bfd_link_info *info ATTRIBUTE_UNUSED, Elf_Internal_Sym *isym, - const char **name ATTRIBUTE_UNUSED, + const char **name, flagword *flags ATTRIBUTE_UNUSED, asection **sec, bfd_vma *value ATTRIBUTE_UNUSED) @@ -4053,6 +4058,13 @@ ppc64_elf_add_symbol_hook (bfd *ibfd ATTRIBUTE_UNUSED, if (*sec != NULL && strcmp (bfd_get_section_name (ibfd, *sec), ".opd") == 0) isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC); + + if ((*name)[0] == '.' + && ELF_ST_BIND (isym->st_info) == STB_GLOBAL + && ELF_ST_TYPE (isym->st_info) < STT_SECTION + && is_ppc64_elf_target (ibfd->xvec)) + ppc64_elf_tdata (ibfd)->u.has_dotsym = 1; + return TRUE; } @@ -4166,12 +4178,18 @@ add_symbol_adjust (struct elf_link_hash_entry *h, void *inf) } static bfd_boolean -ppc64_elf_check_directives (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info) +ppc64_elf_check_directives (bfd *abfd, struct bfd_link_info *info) { struct ppc_link_hash_table *htab; struct add_symbol_adjust_data data; + if (!is_ppc64_elf_target (abfd->xvec)) + return TRUE; + + if (!ppc64_elf_tdata (abfd)->u.has_dotsym) + return TRUE; + ppc64_elf_tdata (abfd)->u.deleted_section = NULL; + htab = ppc_hash_table (info); if (!is_ppc64_elf_target (htab->elf.root.creator)) return TRUE; @@ -5491,15 +5509,25 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf) } /* Fake function descriptors are made undefweak. If the function - code symbol is strong undefined, make the fake sym the same. */ + code symbol is strong undefined, make the fake sym the same. + If the function code symbol is defined, then force the fake + descriptor local; We can't support overriding of symbols in a + shared library on a fake descriptor. */ if (fdh != NULL && fdh->fake - && fdh->elf.root.type == bfd_link_hash_undefweak - && fh->elf.root.type == bfd_link_hash_undefined) + && fdh->elf.root.type == bfd_link_hash_undefweak) { - fdh->elf.root.type = bfd_link_hash_undefined; - bfd_link_add_undef (&htab->elf.root, &fdh->elf.root); + if (fh->elf.root.type == bfd_link_hash_undefined) + { + fdh->elf.root.type = bfd_link_hash_undefined; + bfd_link_add_undef (&htab->elf.root, &fdh->elf.root); + } + else if (fh->elf.root.type == bfd_link_hash_defined + || fh->elf.root.type == bfd_link_hash_defweak) + { + _bfd_elf_link_hash_hide_symbol (info, &fdh->elf, TRUE); + } } if (fdh != NULL @@ -5976,13 +6004,13 @@ adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED) if (adjust == -1) { /* This entry has been deleted. */ - asection *dsec = ppc64_elf_tdata (sym_sec->owner)->deleted_section; + asection *dsec = ppc64_elf_tdata (sym_sec->owner)->u.deleted_section; if (dsec == NULL) { for (dsec = sym_sec->owner->sections; dsec; dsec = dsec->next) if (elf_discarded_section (dsec)) { - ppc64_elf_tdata (sym_sec->owner)->deleted_section = dsec; + ppc64_elf_tdata (sym_sec->owner)->u.deleted_section = dsec; break; } } -- 2.34.1