aboutsummaryrefslogtreecommitdiff
path: root/gold/options.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2009-05-19 22:14:17 +0000
committerCary Coutant <ccoutant@google.com>2009-05-19 22:14:17 +0000
commit6551490093fe8f141c073324b2c4387ce93fa712 (patch)
treec35b9675ce37ee8303e3c60cc04b57b78beed857 /gold/options.cc
parentc1711530e652a14bc0df9b603c73e350b5dfe5ec (diff)
downloadfsf-binutils-gdb-6551490093fe8f141c073324b2c4387ce93fa712.zip
fsf-binutils-gdb-6551490093fe8f141c073324b2c4387ce93fa712.tar.gz
fsf-binutils-gdb-6551490093fe8f141c073324b2c4387ce93fa712.tar.bz2
2009-05-19 Doug Kwan <dougkwan@google.com>
* archive.cc (Archive::Archive): Move constructor from archive.h to here. Initialize no_export_. (Archive::get_elf_object_for_member): Set no_export flag of object. * archive.h (Archive::Archive): Move constructor body to archive.cc. (Archive::no_export): New method. (Archive::no_export_): New field. * object.h (Object::Object): Initialize no_export_ to false. (Object::no_export, Object::set_no_export): New methods. (Object::no_export_): New field. * options.cc (General_options::parse_exclude_libs): New method. (General_options::check_excluded_libs) Same. * options.h (exclude_libs): New option. (General_options::check_excluded_libs): New method declaration. (General_options::excluded_libs_): New field. * symtab.cc (Symbol_table::add_from_relobj): Hide symbols with default or protected visibility if an object has no-export flag set. testsuite/Makefile.am (check_PROGRAMS): Add exclude_libs_test. (check_SCRIPTS): Add exclude_libs_test.sh. (check_DATA): Add exclude_libs_test.syms. (MOSTLYCLEANFILES): Add exclude_libs_test.syms, libexclude_libs_test_1.a and libexclude_libs_test_2.a. (exclude_libs_test_SOURCES, exclude_libs_test_DEPENDENCIES, exclude_libs_test_LDFLAGS and exclude_libs_test_LDADD): Define. (exclude_libs_test.syms, libexclude_libs_test_1.a, libexclude_libs_test_2.a): New rules. * testsuite/Makefile.in: Regenerate. * testsuite/exclude_libs_test.c: New file. * testsuite/exclude_libs_test.sh: Ditto. * testsuite/exclude_libs_test_1.c: Ditto. * testsuite/exclude_libs_test_2.c: Ditto.
Diffstat (limited to 'gold/options.cc')
-rw-r--r--gold/options.cc61
1 files changed, 61 insertions, 0 deletions
diff --git a/gold/options.cc b/gold/options.cc
index a62c6e1..78e14dc 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -402,6 +402,67 @@ General_options::parse_end_group(const char*, const char*,
cmdline->inputs().end_group();
}
+// The function add_excluded_libs() in ld/ldlang.c of GNU ld breaks up a list
+// of names seperated by commas or semi-colons and puts them in a linked list.
+// We implement the same parsing of names here but store names in an unordered
+// map to speed up searching of names.
+
+void
+General_options::parse_exclude_libs(const char*, const char* arg,
+ Command_line*)
+{
+ const char *p = arg;
+
+ while (*p != '\0')
+ {
+ size_t length = strcspn(p, ",:");
+ this->excluded_libs_.insert(std::string(p, length));
+ p += (p[length] ? length + 1 : length);
+ }
+}
+
+// The checking logic is based on the function check_excluded_libs() in
+// ld/ldlang.c of GNU ld but our implementation is different because we use
+// an unordered map instead of a linked list, which is what GNU ld uses. GNU
+// ld searches sequentially in the excluded libs list. For a given archive,
+// a match is found if the archive's name matches exactly one of the list
+// entry or if the archive's name is of the form FOO.a and FOO matches exactly
+// one of the list entry. An entry "ALL" in the list is considered as a
+// wild-card and matches any given name.
+
+bool
+General_options::check_excluded_libs (const std::string &name) const
+{
+ Unordered_set<std::string>::const_iterator p;
+
+ // Exit early for the most common case.
+ if (excluded_libs_.empty())
+ return false;
+
+ // If we see "ALL", all archives are excluded from automatic export.
+ p = excluded_libs_.find(std::string("ALL"));
+ if (p != excluded_libs_.end())
+ return true;
+
+ // Try finding an exact match.
+ p = excluded_libs_.find(name);
+ if (p != excluded_libs_.end())
+ return true;
+
+ // Try matching NAME without ".a" at the end.
+ size_t length = name.length();
+ if ((length >= 2)
+ && (name[length-2] == '.')
+ && (name[length-1] == 'a'))
+ {
+ p = excluded_libs_.find(name.substr(0, length - 2));
+ if (p != excluded_libs_.end())
+ return true;
+ }
+
+ return false;
+}
+
} // End namespace gold.
namespace