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 | |
parent | c1711530e652a14bc0df9b603c73e350b5dfe5ec (diff) | |
download | binutils-gdb-6551490093fe8f141c073324b2c4387ce93fa712.tar.gz |
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.
-rw-r--r-- | gold/ChangeLog | 34 | ||||
-rw-r--r-- | gold/archive.cc | 21 | ||||
-rw-r--r-- | gold/archive.h | 14 | ||||
-rw-r--r-- | gold/object.h | 13 | ||||
-rw-r--r-- | gold/options.cc | 61 | ||||
-rw-r--r-- | gold/options.h | 11 | ||||
-rw-r--r-- | gold/symtab.cc | 20 | ||||
-rw-r--r-- | gold/testsuite/Makefile.am | 18 | ||||
-rw-r--r-- | gold/testsuite/Makefile.in | 47 | ||||
-rw-r--r-- | gold/testsuite/exclude_libs_test.c | 12 | ||||
-rwxr-xr-x | gold/testsuite/exclude_libs_test.sh | 59 | ||||
-rw-r--r-- | gold/testsuite/exclude_libs_test_1.c | 24 | ||||
-rw-r--r-- | gold/testsuite/exclude_libs_test_2.c | 24 |
13 files changed, 341 insertions, 17 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index b2d6a5ecbd9..e06c35f622e 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,37 @@ +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. + 2009-05-15 Ian Lance Taylor <iant@google.com> * configure.ac: Check for declarations for cases where libiberty.h diff --git a/gold/archive.cc b/gold/archive.cc index 2dec571e13a..8e809e25d1c 100644 --- a/gold/archive.cc +++ b/gold/archive.cc @@ -83,6 +83,17 @@ const char Archive::armagt[sarmag] = const char Archive::arfmag[2] = { '`', '\n' }; +Archive::Archive(const std::string& name, Input_file* input_file, + bool is_thin_archive, Dirsearch* dirpath, Task* task) + : name_(name), input_file_(input_file), armap_(), armap_names_(), + extended_names_(), armap_checked_(), seen_offsets_(), members_(), + is_thin_archive_(is_thin_archive), included_member_(false), + nested_archives_(), dirpath_(dirpath), task_(task), num_members_(0) +{ + this->no_export_ = + parameters->options().check_excluded_libs(input_file->found_name()); +} + // Set up the archive: read the symbol map and the extended name // table. @@ -549,10 +560,12 @@ Archive::get_elf_object_for_member(off_t off, bool* punconfigured) return NULL; } - return make_elf_object((std::string(this->input_file_->filename()) - + "(" + member_name + ")"), - input_file, memoff, ehdr, read_size, - punconfigured); + Object *obj = make_elf_object((std::string(this->input_file_->filename()) + + "(" + member_name + ")"), + input_file, memoff, ehdr, read_size, + punconfigured); + obj->set_no_export(this->no_export()); + return obj; } // Read the symbols from all the archive members in the link. diff --git a/gold/archive.h b/gold/archive.h index e1d0262d42a..7f567b7f0d5 100644 --- a/gold/archive.h +++ b/gold/archive.h @@ -49,12 +49,7 @@ class Archive { public: Archive(const std::string& name, Input_file* input_file, - bool is_thin_archive, Dirsearch* dirpath, Task* task) - : name_(name), input_file_(input_file), armap_(), armap_names_(), - extended_names_(), armap_checked_(), seen_offsets_(), members_(), - is_thin_archive_(is_thin_archive), included_member_(false), - nested_archives_(), dirpath_(dirpath), task_(task), num_members_(0) - { } + bool is_thin_archive, Dirsearch* dirpath, Task* task); // The length of the magic string at the start of an archive. static const int sarmag = 8; @@ -148,6 +143,11 @@ class Archive size_t count_members(); + // Return the no-export flag. + bool + no_export() + { return this->no_export_; } + private: Archive(const Archive&); Archive& operator=(const Archive&); @@ -293,6 +293,8 @@ class Archive Task *task_; // Number of members in this archive; unsigned int num_members_; + // True if we exclude this library archive from automatic export. + bool no_export_; }; // This class is used to read an archive and pick out the desired diff --git a/gold/object.h b/gold/object.h index 97c126d52b1..a2836d04863 100644 --- a/gold/object.h +++ b/gold/object.h @@ -195,7 +195,7 @@ class Object Object(const std::string& name, Input_file* input_file, bool is_dynamic, off_t offset = 0) : name_(name), input_file_(input_file), offset_(offset), shnum_(-1U), - is_dynamic_(is_dynamic), target_(NULL), xindex_(NULL) + is_dynamic_(is_dynamic), target_(NULL), xindex_(NULL), no_export_(false) { input_file->file().add_object(); } virtual ~Object() @@ -463,6 +463,14 @@ class Object searched_for() const { return this->input_file()->will_search_for(); } + bool + no_export() const + { return this->no_export_; } + + void + set_no_export(bool value) + { this->no_export_ = value; } + protected: // Returns NULL for Objects that are not plugin objects. This method // is overridden in the Pluginobj class. @@ -581,6 +589,9 @@ class Object Target* target_; // Many sections for objects with more than SHN_LORESERVE sections. Xindex* xindex_; + // True if exclude this object from automatic symbol export. + // This is used only for archive objects. + bool no_export_; }; // Implement sized_target inline for efficiency. This approach breaks diff --git a/gold/options.cc b/gold/options.cc index a62c6e1f797..78e14dcd305 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 diff --git a/gold/options.h b/gold/options.h index b811332406f..47576c6d217 100644 --- a/gold/options.h +++ b/gold/options.h @@ -660,6 +660,10 @@ class General_options DEFINE_string(entry, options::TWO_DASHES, 'e', NULL, N_("Set program start address"), N_("ADDRESS")); + DEFINE_special(exclude_libs, options::TWO_DASHES, '\0', + N_("Exclude libraries from automatic export"), + N_(("lib,lib ..."))); + DEFINE_bool(export_dynamic, options::TWO_DASHES, 'E', false, N_("Export all dynamic symbols"), N_("Do not export all dynamic symbols (default)")); @@ -1022,6 +1026,11 @@ class General_options incremental_disposition() const { return this->incremental_disposition_; } + // Return true if S is the name of a library excluded from automatic + // symbol export. + bool + check_excluded_libs (const std::string &s) const; + private: // Don't copy this structure. General_options(const General_options&); @@ -1087,6 +1096,8 @@ class General_options // build (--incremental-changed, --incremental-unchanged or // --incremental-unknown) bool implicit_incremental_; + // Libraries excluded from automatic export via --exclude-libs + Unordered_set<std::string> excluded_libs_; }; // The position-dependent options. We use this to store the state of diff --git a/gold/symtab.cc b/gold/symtab.cc index 30e7d1057b4..3d179ef035d 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -1126,6 +1126,26 @@ Symbol_table::add_from_relobj( psym = &sym2; } + // Fix up visibility if object has no-export set. + if (relobj->no_export()) + { + // We may have copied symbol already above. + if (psym != &sym2) + { + memcpy(symbuf, p, sym_size); + psym = &sym2; + } + + elfcpp::STV visibility = sym2.get_st_visibility(); + if (visibility == elfcpp::STV_DEFAULT + || visibility == elfcpp::STV_PROTECTED) + { + elfcpp::Sym_write<size, big_endian> sw(symbuf); + unsigned char nonvis = sym2.get_st_nonvis(); + sw.put_st_other(elfcpp::STV_HIDDEN, nonvis); + } + } + Stringpool::Key name_key; name = this->namepool_.add_with_length(name, namelen, true, &name_key); diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 1c699f7d3b9..80298ce0e81 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -1038,5 +1038,23 @@ empty.syms: endif PLUGINS +check_PROGRAMS += exclude_libs_test +check_SCRIPTS += exclude_libs_test.sh +check_DATA += exclude_libs_test.syms +MOSTLYCLEANFILES += exclude_libs_test.syms libexclude_libs_test_1.a \ + libexclude_libs_test_2.a +exclude_libs_test_SOURCES = exclude_libs_test.c +exclude_libs_test_DEPENDENCIES = gcctestdir/ld libexclude_libs_test_1.a \ + libexclude_libs_test_2.a +exclude_libs_test_LDFLAGS = -Bgcctestdir/ -L. \ + -Wl,--exclude-libs,dummy:libexclude_libs_test_1 +exclude_libs_test_LDADD = -lexclude_libs_test_1 -lexclude_libs_test_2 +exclude_libs_test.syms: exclude_libs_test + $(TEST_READELF) -sW $< >$@ 2>/dev/null +libexclude_libs_test_1.a: exclude_libs_test_1.o + $(TEST_AR) rc $@ $^ +libexclude_libs_test_2.a: exclude_libs_test_2.o + $(TEST_AR) rc $@ $^ + endif GCC endif NATIVE_LINKER diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 56fe7ac95ca..40ee958a26f 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -48,7 +48,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ $(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_9) \ $(am__EXEEXT_10) $(am__EXEEXT_11) $(am__EXEEXT_12) \ $(am__EXEEXT_13) $(am__EXEEXT_14) $(am__EXEEXT_15) \ - $(am__EXEEXT_16) + $(am__EXEEXT_16) $(am__EXEEXT_17) @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_1 = basic_test \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ basic_static_test basic_pic_test \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ basic_static_pic_test \ @@ -317,6 +317,14 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_2.err \ @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_3.err \ @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_4.err +@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_24 = exclude_libs_test +@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_25 = exclude_libs_test.sh +@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_26 = exclude_libs_test.syms +@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_27 = exclude_libs_test.syms libexclude_libs_test_1.a \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ libexclude_libs_test_2.a + +@GCC_FALSE@exclude_libs_test_DEPENDENCIES = +@NATIVE_LINKER_FALSE@exclude_libs_test_DEPENDENCIES = subdir = testsuite DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -421,6 +429,8 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS) @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_2$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_3$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_4$(EXEEXT) +@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_17 = \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ exclude_libs_test$(EXEEXT) basic_pic_test_SOURCES = basic_pic_test.c basic_pic_test_OBJECTS = basic_pic_test.$(OBJEXT) basic_pic_test_LDADD = $(LDADD) @@ -528,6 +538,10 @@ am__exception_test_SOURCES_DIST = exception_test_main.cc \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ exception_test_2.$(OBJEXT) exception_test_OBJECTS = $(am_exception_test_OBJECTS) exception_test_LDADD = $(LDADD) +am__exclude_libs_test_SOURCES_DIST = exclude_libs_test.c +@GCC_TRUE@@NATIVE_LINKER_TRUE@am_exclude_libs_test_OBJECTS = \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ exclude_libs_test.$(OBJEXT) +exclude_libs_test_OBJECTS = $(am_exclude_libs_test_OBJECTS) flagstest_compress_debug_sections_SOURCES = \ flagstest_compress_debug_sections.c flagstest_compress_debug_sections_OBJECTS = \ @@ -884,6 +898,7 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \ $(exception_shared_1_test_SOURCES) \ $(exception_shared_2_test_SOURCES) \ $(exception_static_test_SOURCES) $(exception_test_SOURCES) \ + $(exclude_libs_test_SOURCES) \ flagstest_compress_debug_sections.c flagstest_o_specialfile.c \ flagstest_o_specialfile_and_compress_debug_sections.c \ $(initpri1_SOURCES) $(justsyms_SOURCES) many_sections_r_test.c \ @@ -937,6 +952,7 @@ DIST_SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \ $(am__exception_shared_2_test_SOURCES_DIST) \ $(am__exception_static_test_SOURCES_DIST) \ $(am__exception_test_SOURCES_DIST) \ + $(am__exclude_libs_test_SOURCES_DIST) \ flagstest_compress_debug_sections.c flagstest_o_specialfile.c \ flagstest_o_specialfile_and_compress_debug_sections.c \ $(am__initpri1_SOURCES_DIST) $(am__justsyms_SOURCES_DIST) \ @@ -1158,13 +1174,14 @@ TEST_AR = $(top_builddir)/../binutils/ar # .o's), but not all of them (such as .so's and .err files). We # improve on that here. automake-1.9 info docs say "mostlyclean" is # the right choice for files 'make' builds that people rebuild. -MOSTLYCLEANFILES = *.so $(am__append_16) $(am__append_23) +MOSTLYCLEANFILES = *.so $(am__append_16) $(am__append_23) \ + $(am__append_27) # We will add to these later, for each individual test. Note # that we add each test under check_SCRIPTS or check_PROGRAMS; # the TESTS variable is automatically populated from these. -check_SCRIPTS = $(am__append_2) $(am__append_21) -check_DATA = $(am__append_3) $(am__append_22) +check_SCRIPTS = $(am__append_2) $(am__append_21) $(am__append_25) +check_DATA = $(am__append_3) $(am__append_22) $(am__append_26) BUILT_SOURCES = $(am__append_14) TESTS = $(check_SCRIPTS) $(check_PROGRAMS) @@ -1491,6 +1508,14 @@ binary_unittest_SOURCES = binary_unittest.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@thin_archive_test_2_DEPENDENCIES = gcctestdir/ld libthinall.a @GCC_TRUE@@NATIVE_LINKER_TRUE@thin_archive_test_2_LDFLAGS = -Bgcctestdir/ -L. @GCC_TRUE@@NATIVE_LINKER_TRUE@thin_archive_test_2_LDADD = -lthinall +@GCC_TRUE@@NATIVE_LINKER_TRUE@exclude_libs_test_SOURCES = exclude_libs_test.c +@GCC_TRUE@@NATIVE_LINKER_TRUE@exclude_libs_test_DEPENDENCIES = gcctestdir/ld libexclude_libs_test_1.a \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ libexclude_libs_test_2.a + +@GCC_TRUE@@NATIVE_LINKER_TRUE@exclude_libs_test_LDFLAGS = -Bgcctestdir/ -L. \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ -Wl,--exclude-libs,dummy:libexclude_libs_test_1 + +@GCC_TRUE@@NATIVE_LINKER_TRUE@exclude_libs_test_LDADD = -lexclude_libs_test_1 -lexclude_libs_test_2 all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am @@ -1505,9 +1530,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu testsuite/Makefile'; \ cd $(top_srcdir) && \ - $(AUTOMAKE) --foreign testsuite/Makefile + $(AUTOMAKE) --gnu testsuite/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -1598,6 +1623,9 @@ exception_static_test$(EXEEXT): $(exception_static_test_OBJECTS) $(exception_sta exception_test$(EXEEXT): $(exception_test_OBJECTS) $(exception_test_DEPENDENCIES) @rm -f exception_test$(EXEEXT) $(CXXLINK) $(exception_test_LDFLAGS) $(exception_test_OBJECTS) $(exception_test_LDADD) $(LIBS) +exclude_libs_test$(EXEEXT): $(exclude_libs_test_OBJECTS) $(exclude_libs_test_DEPENDENCIES) + @rm -f exclude_libs_test$(EXEEXT) + $(LINK) $(exclude_libs_test_LDFLAGS) $(exclude_libs_test_OBJECTS) $(exclude_libs_test_LDADD) $(LIBS) @GCC_FALSE@flagstest_compress_debug_sections$(EXEEXT): $(flagstest_compress_debug_sections_OBJECTS) $(flagstest_compress_debug_sections_DEPENDENCIES) @GCC_FALSE@ @rm -f flagstest_compress_debug_sections$(EXEEXT) @GCC_FALSE@ $(LINK) $(flagstest_compress_debug_sections_LDFLAGS) $(flagstest_compress_debug_sections_OBJECTS) $(flagstest_compress_debug_sections_LDADD) $(LIBS) @@ -1854,6 +1882,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception_test_1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception_test_2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception_test_main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exclude_libs_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_compress_debug_sections.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_o_specialfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_o_specialfile_and_compress_debug_sections.Po@am__quote@ @@ -2564,6 +2593,12 @@ uninstall-am: uninstall-info-am @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@empty.syms: @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ @echo "" >empty.syms @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ @echo "Symbol table" >>empty.syms +@GCC_TRUE@@NATIVE_LINKER_TRUE@exclude_libs_test.syms: exclude_libs_test +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -sW $< >$@ 2>/dev/null +@GCC_TRUE@@NATIVE_LINKER_TRUE@libexclude_libs_test_1.a: exclude_libs_test_1.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AR) rc $@ $^ +@GCC_TRUE@@NATIVE_LINKER_TRUE@libexclude_libs_test_2.a: exclude_libs_test_2.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AR) rc $@ $^ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/gold/testsuite/exclude_libs_test.c b/gold/testsuite/exclude_libs_test.c new file mode 100644 index 00000000000..3cb564587eb --- /dev/null +++ b/gold/testsuite/exclude_libs_test.c @@ -0,0 +1,12 @@ +extern void lib1_default (void); +extern void lib2_default (void); + +int +main (int argc __attribute__ ((unused)), + char** argv __attribute__ ((unused))) +{ + lib1_default (); + lib2_default (); + return 0; +} + diff --git a/gold/testsuite/exclude_libs_test.sh b/gold/testsuite/exclude_libs_test.sh new file mode 100755 index 00000000000..a82be89a680 --- /dev/null +++ b/gold/testsuite/exclude_libs_test.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +# exclude_libs_test.sh -- test that library symbols are not exported. + +# Copyright 2009 Free Software Foundation, Inc. +# Written by Doug Kwan <dougkwan@google.com> + +# This file is part of gold. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# This file goes with exclude_libs_test.c, a C source file +# linked with option -Wl,--exclude-libs. We run readelf on +# the resulting executable and check that symbols from two test library +# archives are correctly hidden or left unmodified. + +check() +{ + file=$1 + sym=$2 + vis=$3 + + found=`grep " $sym\$" $file` + if test -z "$found"; then + echo "Symbol $sym not found." + exit 1 + fi + + match_vis=`grep " $sym\$" $file | grep " $vis "` + if test -z "$match_vis"; then + echo "Expected symbol $sym to have visibility $vis but found" + echo "$found" + exit 1 + fi +} + +check "exclude_libs_test.syms" "lib1_default" "HIDDEN" +check "exclude_libs_test.syms" "lib1_protected" "HIDDEN" +check "exclude_libs_test.syms" "lib1_internal" "INTERNAL" +check "exclude_libs_test.syms" "lib1_hidden" "HIDDEN" +check "exclude_libs_test.syms" "lib2_default" "DEFAULT" +check "exclude_libs_test.syms" "lib2_protected" "PROTECTED" +check "exclude_libs_test.syms" "lib2_internal" "INTERNAL" +check "exclude_libs_test.syms" "lib2_hidden" "HIDDEN" + +exit 0 diff --git a/gold/testsuite/exclude_libs_test_1.c b/gold/testsuite/exclude_libs_test_1.c new file mode 100644 index 00000000000..ced1aade14c --- /dev/null +++ b/gold/testsuite/exclude_libs_test_1.c @@ -0,0 +1,24 @@ +void lib1_default (void); +void lib1_hidden (void); +void lib1_internal (void); +void lib1_protected (void); + +void __attribute__((visibility ("default"))) +lib1_default (void) +{ +} + +void __attribute__((visibility ("hidden"))) +lib1_hidden (void) +{ +} + +void __attribute__((visibility ("internal"))) +lib1_internal (void) +{ +} + +void __attribute__((visibility ("protected"))) +lib1_protected (void) +{ +} diff --git a/gold/testsuite/exclude_libs_test_2.c b/gold/testsuite/exclude_libs_test_2.c new file mode 100644 index 00000000000..a8952e7a6b3 --- /dev/null +++ b/gold/testsuite/exclude_libs_test_2.c @@ -0,0 +1,24 @@ +void lib2_default (void); +void lib2_hidden (void); +void lib2_internal (void); +void lib2_protected (void); + +void __attribute__((visibility ("default"))) +lib2_default (void) +{ +} + +void __attribute__((visibility ("hidden"))) +lib2_hidden (void) +{ +} + +void __attribute__((visibility ("internal"))) +lib2_internal (void) +{ +} + +void __attribute__((visibility ("protected"))) +lib2_protected (void) +{ +} |