diff options
author | Cary Coutant <ccoutant@google.com> | 2009-05-19 22:14:17 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2009-05-19 22:14:17 +0000 |
commit | 6551490093fe8f141c073324b2c4387ce93fa712 (patch) | |
tree | c35b9675ce37ee8303e3c60cc04b57b78beed857 /gold/options.cc | |
parent | c1711530e652a14bc0df9b603c73e350b5dfe5ec (diff) | |
download | fsf-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.cc | 61 |
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 |