From fd91d41947667d30f47b06c45cc57d4b4fcefade Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 16 Sep 2011 01:15:20 +0000 Subject: Check if a symbol is hidden by linker script. bfd/ 2011-09-15 H.J. Lu PR ld/12975 * bfd-in.h (bfd_elf_size_dynamic_sections): Remove pointer to struct bfd_elf_version_tree. * elflink.c (elf_info_failed): Remove verdefs. (_bfd_elf_export_symbol): Updated. _bfd_elf_link_assign_sym_version): Likewise. (bfd_elf_size_dynamic_sections): Remove pointer to struct bfd_elf_version_tree. Updated. (bfd_elf_gc_mark_dynamic_ref_symbol): Check if a symbol is hidden by linker script. * linker.c (bfd_hide_sym_by_version): New. * bfd-in2.h: Regenerated. include/ 2011-09-15 H.J. Lu PR ld/12975 * bfdlink.h (bfd_link_info): Add version_info. ld/ 2011-09-15 H.J. Lu PR ld/12975 * ldlang.c (lang_elf_version_info): Removed. (lang_register_vers_node): Replace lang_elf_version_info with link_info.version_info. (lang_add_vers_depend): Likewise. * pe-dll.c (process_def_file_and_drectve): Likewise. * emultempl/solaris2.em (elf_solaris2_before_allocation): Likewise. * ldlang.h (lang_elf_version_info): Removed. * plugin.c (is_visible_from_outside): Check if symbol is hidden by version script. * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Remove lang_elf_version_info. ld/testsuite/ 2011-09-15 H.J. Lu PR ld/12975 * ld-elf/pr12975.d: New. * ld-elf/pr12975.s: Likewise. * ld-elf/pr12975.t: Likewise. --- bfd/ChangeLog | 18 ++++++++++++++++++ bfd/bfd-in.h | 3 +-- bfd/bfd-in2.h | 6 ++++-- bfd/elflink.c | 51 ++++++++++++++++++++++++--------------------------- bfd/linker.c | 23 +++++++++++++++++++++++ 5 files changed, 70 insertions(+), 31 deletions(-) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9d63ff6..b063de9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,21 @@ +2011-09-15 H.J. Lu + + PR ld/12975 + * bfd-in.h (bfd_elf_size_dynamic_sections): Remove pointer + to struct bfd_elf_version_tree. + + * elflink.c (elf_info_failed): Remove verdefs. + (_bfd_elf_export_symbol): Updated. + _bfd_elf_link_assign_sym_version): Likewise. + (bfd_elf_size_dynamic_sections): Remove pointer to struct + bfd_elf_version_tree. Updated. + (bfd_elf_gc_mark_dynamic_ref_symbol): Check if a symbol is hidden + by linker script. + + * linker.c (bfd_hide_sym_by_version): New. + + * bfd-in2.h: Regenerated. + 2011-09-12 H.J. Lu PR ld/13178 diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 718d72e..a477b49 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -645,8 +645,7 @@ extern bfd_boolean bfd_elf_get_bfd_needed_list (bfd *, struct bfd_link_needed_list **); extern bfd_boolean bfd_elf_size_dynamic_sections (bfd *, const char *, const char *, const char *, const char *, const char *, - const char * const *, struct bfd_link_info *, struct bfd_section **, - struct bfd_elf_version_tree *); + const char * const *, struct bfd_link_info *, struct bfd_section **); extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr (bfd *, struct bfd_link_info *); extern void bfd_elf_set_dt_needed_name diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 7cf3b7e..22fcdf6 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -652,8 +652,7 @@ extern bfd_boolean bfd_elf_get_bfd_needed_list (bfd *, struct bfd_link_needed_list **); extern bfd_boolean bfd_elf_size_dynamic_sections (bfd *, const char *, const char *, const char *, const char *, const char *, - const char * const *, struct bfd_link_info *, struct bfd_section **, - struct bfd_elf_version_tree *); + const char * const *, struct bfd_link_info *, struct bfd_section **); extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr (bfd *, struct bfd_link_info *); extern void bfd_elf_set_dt_needed_name @@ -6199,6 +6198,9 @@ struct bfd_elf_version_tree * bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, const char *sym_name, bfd_boolean *hide); +bfd_boolean bfd_hide_sym_by_version + (struct bfd_elf_version_tree *verdefs, const char *sym_name); + /* Extracted from simple.c. */ bfd_byte *bfd_simple_get_relocated_section_contents (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table); diff --git a/bfd/elflink.c b/bfd/elflink.c index 528f705..2560104 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -36,7 +36,6 @@ struct elf_info_failed { struct bfd_link_info *info; - struct bfd_elf_version_tree *verdefs; bfd_boolean failed; }; @@ -1820,20 +1819,14 @@ _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) return TRUE; if (h->dynindx == -1 - && (h->def_regular - || h->ref_regular)) + && (h->def_regular || h->ref_regular) + && ! bfd_hide_sym_by_version (eif->info->version_info, + h->root.root.string)) { - bfd_boolean hide; - - if (eif->verdefs == NULL - || (bfd_find_version_for_sym (eif->verdefs, h->root.root.string, &hide) - && !hide)) + if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) { - if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) - { - eif->failed = TRUE; - return FALSE; - } + eif->failed = TRUE; + return FALSE; } } @@ -1981,7 +1974,7 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) } /* Look for the version. If we find it, it is no longer weak. */ - for (t = sinfo->verdefs; t != NULL; t = t->next) + for (t = sinfo->info->version_info; t != NULL; t = t->next) { if (strcmp (t->name, p) == 0) { @@ -2050,9 +2043,12 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) version_index = 1; /* Don't count anonymous version tag. */ - if (sinfo->verdefs != NULL && sinfo->verdefs->vernum == 0) + if (sinfo->info->version_info != NULL + && sinfo->info->version_info->vernum == 0) version_index = 0; - for (pp = &sinfo->verdefs; *pp != NULL; pp = &(*pp)->next) + for (pp = &sinfo->info->version_info; + *pp != NULL; + pp = &(*pp)->next) ++version_index; t->vernum = version_index; @@ -2078,12 +2074,13 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) /* If we don't have a version for this symbol, see if we can find something. */ - if (h->verinfo.vertree == NULL && sinfo->verdefs != NULL) + if (h->verinfo.vertree == NULL && sinfo->info->version_info != NULL) { bfd_boolean hide; - h->verinfo.vertree = bfd_find_version_for_sym (sinfo->verdefs, - h->root.root.string, &hide); + h->verinfo.vertree + = bfd_find_version_for_sym (sinfo->info->version_info, + h->root.root.string, &hide); if (h->verinfo.vertree != NULL && hide) (*bed->elf_backend_hide_symbol) (info, h, TRUE); } @@ -5493,8 +5490,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, const char *depaudit, const char * const *auxiliary_filters, struct bfd_link_info *info, - asection **sinterpptr, - struct bfd_elf_version_tree *verdefs) + asection **sinterpptr) { bfd_size_type soname_indx; bfd *dynobj; @@ -5671,7 +5667,6 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, } eif.info = info; - eif.verdefs = verdefs; eif.failed = FALSE; /* If we are supposed to export all symbols into the dynamic symbol @@ -5687,7 +5682,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, } /* Make all global versions with definition. */ - for (t = verdefs; t != NULL; t = t->next) + for (t = info->version_info; t != NULL; t = t->next) for (d = t->globals.list; d != NULL; d = d->next) if (!d->symver && d->literal) { @@ -5740,7 +5735,6 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, /* Attach all the symbols to their version information. */ asvinfo.info = info; - asvinfo.verdefs = verdefs; asvinfo.failed = FALSE; elf_link_hash_traverse (elf_hash_table (info), @@ -5753,7 +5747,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, { /* Check if all global versions have a definition. */ all_defined = TRUE; - for (t = verdefs; t != NULL; t = t->next) + for (t = info->version_info; t != NULL; t = t->next) for (d = t->globals.list; d != NULL; d = d->next) if (d->literal && !d->symver && !d->script) { @@ -5886,6 +5880,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, if (elf_hash_table (info)->dynamic_sections_created) { unsigned long section_sym_count; + struct bfd_elf_version_tree *verdefs; asection *s; /* Set up the version definition section. */ @@ -5894,7 +5889,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, /* We may have created additional version definitions if we are just linking a regular application. */ - verdefs = asvinfo.verdefs; + verdefs = info->version_info; /* Skip anonymous version tag. */ if (verdefs != NULL && verdefs->vernum == 0) @@ -11913,7 +11908,9 @@ bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf) || (!info->executable && h->def_regular && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL - && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN))) + && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN + && !bfd_hide_sym_by_version (info->version_info, + h->root.root.string)))) h->root.u.def.section->flags |= SEC_KEEP; return TRUE; diff --git a/bfd/linker.c b/bfd/linker.c index e443862..7a01e11 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -3380,3 +3380,26 @@ bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, return NULL; } + +/* +FUNCTION + bfd_hide_sym_by_version + +SYNOPSIS + bfd_boolean bfd_hide_sym_by_version + (struct bfd_elf_version_tree *verdefs, const char *sym_name); + +DESCRIPTION + Search an elf version script tree for symbol versioning + info for a given symbol. Return TRUE if the symbol is hidden. + +*/ + +bfd_boolean +bfd_hide_sym_by_version (struct bfd_elf_version_tree *verdefs, + const char *sym_name) +{ + bfd_boolean hidden = FALSE; + bfd_find_version_for_sym (verdefs, sym_name, &hidden); + return hidden; +} -- cgit v1.1