aboutsummaryrefslogtreecommitdiff
path: root/bfd/linker.c
diff options
context:
space:
mode:
authorDave Korn <dave.korn@artimi.com>2009-05-04 12:09:30 +0000
committerDave Korn <dave.korn@artimi.com>2009-05-04 12:09:30 +0000
commit09e2aba4327cd450908bed05c6e1d4d2dcb09b32 (patch)
tree7de8a83faab244723b3ead159c4eb39065ae9e72 /bfd/linker.c
parent67ce33d768510c7f826be66a2b4ea22c7caea801 (diff)
downloadfsf-binutils-gdb-09e2aba4327cd450908bed05c6e1d4d2dcb09b32.zip
fsf-binutils-gdb-09e2aba4327cd450908bed05c6e1d4d2dcb09b32.tar.gz
fsf-binutils-gdb-09e2aba4327cd450908bed05c6e1d4d2dcb09b32.tar.bz2
bfd/ChangeLog
* elflink.c (find_version_for_sym): Remove from here, ... * linker.c (bfd_find_version_for_sym): ... rename, replace here, make public and update all callers. * bfd-in2.h: Regenerate. ld/ChangeLog * NEWS: Mention new feature. * ld.texinfo (--version-script): Document extent of PE support. (WIN32): Mention --version-script. Extend auto-export description. * pe-dll.c (process_def_file): Use version script info to filter symbols from auto-export. * testsuite/ld-pe/vers-script-1.d: New file. * testsuite/ld-pe/vers-script-2.d: New file. * testsuite/ld-pe/vers-script-3.d: New file. * testsuite/ld-pe/vers-script-4.d: New file. * testsuite/ld-pe/vers-script-1.ver: New file. * testsuite/ld-pe/vers-script-2.ver: New file. * testsuite/ld-pe/vers-script-3.ver: New file. * testsuite/ld-pe/vers-script-4.ver: New file. * testsuite/ld-pe/vers-script-dll.c: New file. * testsuite/ld-pe/vers-script.exp: New test script.
Diffstat (limited to 'bfd/linker.c')
-rw-r--r--bfd/linker.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/bfd/linker.c b/bfd/linker.c
index bfbd886..66ec2fa 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -3245,3 +3245,95 @@ bfd_generic_define_common_symbol (bfd *output_bfd,
section->flags &= ~SEC_IS_COMMON;
return TRUE;
}
+
+/*
+FUNCTION
+ bfd_find_version_for_sym
+
+SYNOPSIS
+ struct bfd_elf_version_tree * bfd_find_version_for_sym
+ (struct bfd_elf_version_tree *verdefs,
+ const char *sym_name, bfd_boolean *hide);
+
+DESCRIPTION
+ Search an elf version script tree for symbol versioning
+ info and export / don't-export status for a given symbol.
+ Return non-NULL on success and NULL on failure; also sets
+ the output @samp{hide} boolean parameter.
+
+*/
+
+struct bfd_elf_version_tree *
+bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs,
+ const char *sym_name,
+ bfd_boolean *hide)
+{
+ struct bfd_elf_version_tree *t;
+ struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver;
+
+ local_ver = NULL;
+ global_ver = NULL;
+ exist_ver = NULL;
+ for (t = verdefs; t != NULL; t = t->next)
+ {
+ if (t->globals.list != NULL)
+ {
+ struct bfd_elf_version_expr *d = NULL;
+
+ while ((d = (*t->match) (&t->globals, d, sym_name)) != NULL)
+ {
+ global_ver = t;
+ if (d->symver)
+ exist_ver = t;
+ d->script = 1;
+ /* If the match is a wildcard pattern, keep looking for
+ a more explicit, perhaps even local, match. */
+ if (d->literal)
+ break;
+ }
+
+ if (d != NULL)
+ break;
+ }
+
+ if (t->locals.list != NULL)
+ {
+ struct bfd_elf_version_expr *d = NULL;
+
+ while ((d = (*t->match) (&t->locals, d, sym_name)) != NULL)
+ {
+ local_ver = t;
+ /* If the match is a wildcard pattern, keep looking for
+ a more explicit, perhaps even global, match. */
+ if (d->literal)
+ {
+ /* An exact match overrides a global wildcard. */
+ global_ver = NULL;
+ break;
+ }
+ }
+
+ if (d != NULL)
+ break;
+ }
+ }
+
+ if (global_ver != NULL)
+ {
+ /* If we already have a versioned symbol that matches the
+ node for this symbol, then we don't want to create a
+ duplicate from the unversioned symbol. Instead hide the
+ unversioned symbol. */
+ *hide = exist_ver == global_ver;
+ return global_ver;
+ }
+
+ if (local_ver != NULL)
+ {
+ *hide = TRUE;
+ return local_ver;
+ }
+
+ return NULL;
+}
+