aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog18
-rw-r--r--bfd/bfd-in.h3
-rw-r--r--bfd/bfd-in2.h6
-rw-r--r--bfd/elflink.c51
-rw-r--r--bfd/linker.c23
5 files changed, 70 insertions, 31 deletions
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 <hongjiu.lu@intel.com>
+
+ 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 <hongjiu.lu@intel.com>
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;
+}