2009-06-05 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Fri, 5 Jun 2009 21:32:57 +0000 (21:32 +0000)
committerDoug Kwan <dougkwan@google.com>
Fri, 5 Jun 2009 21:32:57 +0000 (21:32 +0000)
* Makefile.am (CCFILES): Add target.cc.
* Makefile.in: Regenerate.
* i386.cc (class Target_i386): Define new virtual method to
override do_is_local_label_name in parent.
* object.cc (Sized_relobj::do_count_local_symbols): Discard
local symbols if --discard-locals or -X is given.
* options.h (class General_options): Declare new options
'--discard-locals' and '-X' for discarding locals.
* target.h (class Target): Define new methods is_local_label_name.
Declare new virtual method do_is_local_label_name.
* target.cc: New file.
* testsuite/Makefile.am (check_PROGRAMS): Add discard_locals_test.
(check_SCRIPTS): Add discard_locals_test.sh.
(check_DATA): Add discard_local_tests.syms.
(discard_locals_test_SOURCES, discard_locals_test_LDFLAGS): Define.
(discard_local_tests.syms, discard_locals_test.o): New make rules.
* testsuite/Makefile.in: Regenerate.
* testsuite/discard_locals_test.c: New file.
* testsuite/discard_locals_test.sh: Same.

12 files changed:
gold/ChangeLog
gold/Makefile.am
gold/Makefile.in
gold/i386.cc
gold/object.cc
gold/options.h
gold/target.cc [new file with mode: 0644]
gold/target.h
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/discard_locals_test.c [new file with mode: 0644]
gold/testsuite/discard_locals_test.sh [new file with mode: 0755]

index d556e20fb3f7080c56134861d908f1b6577d160a..02ee8facc629bcbb760309c8216c44ef8b41ec4f 100644 (file)
@@ -1,3 +1,25 @@
+2009-06-05  Doug Kwan  <dougkwan@google.com>
+
+       * Makefile.am (CCFILES): Add target.cc.
+       * Makefile.in: Regenerate. 
+       * i386.cc (class Target_i386): Define new virtual method to
+       override do_is_local_label_name in parent.
+       * object.cc (Sized_relobj::do_count_local_symbols): Discard
+       local symbols if --discard-locals or -X is given.
+       * options.h (class General_options): Declare new options
+       '--discard-locals' and '-X' for discarding locals.
+       * target.h (class Target): Define new methods is_local_label_name.
+       Declare new virtual method do_is_local_label_name.
+       * target.cc: New file.
+       * testsuite/Makefile.am (check_PROGRAMS): Add discard_locals_test.
+       (check_SCRIPTS): Add discard_locals_test.sh.
+       (check_DATA): Add discard_local_tests.syms.
+       (discard_locals_test_SOURCES, discard_locals_test_LDFLAGS): Define.
+       (discard_local_tests.syms, discard_locals_test.o): New make rules.
+       * testsuite/Makefile.in: Regenerate.
+       * testsuite/discard_locals_test.c: New file.
+       * testsuite/discard_locals_test.sh: Same.
+
 2009-06-05  Doug Kwan  <dougkwan@google.com>
 
        * object.cc (Sized_relobj::Sized_relobj): Initialize
index c0ab159f230c47804bb3952f623343ddb1c2c146..0fdf615725d3257b0e0f741c49e9b5ec29421dd6 100644 (file)
@@ -68,6 +68,7 @@ CCFILES = \
        script.cc \
        stringpool.cc \
        symtab.cc \
+       target.cc \
        target-select.cc \
        version.cc \
        workqueue.cc \
index 3e6b7254d0694e9f72aa902426425e532e442190..0a3245ff1051df77c3fc190fa550b67559c4a3f8 100644 (file)
@@ -87,8 +87,8 @@ am__objects_1 = archive.$(OBJEXT) binary.$(OBJEXT) common.$(OBJEXT) \
        plugin.$(OBJEXT) readsyms.$(OBJEXT) \
        reduced_debug_output.$(OBJEXT) reloc.$(OBJEXT) \
        resolve.$(OBJEXT) script-sections.$(OBJEXT) script.$(OBJEXT) \
-       stringpool.$(OBJEXT) symtab.$(OBJEXT) target-select.$(OBJEXT) \
-       version.$(OBJEXT) workqueue.$(OBJEXT) \
+       stringpool.$(OBJEXT) symtab.$(OBJEXT) target.$(OBJEXT) \
+       target-select.$(OBJEXT) version.$(OBJEXT) workqueue.$(OBJEXT) \
        workqueue-threads.$(OBJEXT)
 am__objects_2 =
 am__objects_3 = yyscript.$(OBJEXT)
@@ -352,6 +352,7 @@ CCFILES = \
        script.cc \
        stringpool.cc \
        symtab.cc \
+       target.cc \
        target-select.cc \
        version.cc \
        workqueue.cc \
@@ -542,6 +543,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/mremap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/pread.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archive.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arm.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/binary.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compressed_output.Po@am__quote@
@@ -581,6 +583,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stringpool.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symtab.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target-select.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/workqueue-threads.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/workqueue.Po@am__quote@
index ba01106e28ff4d06b33c5f1fbf302aeb1bd70cb3..11204f48b319f6e55e34a485960f2956a87bf025 100644 (file)
@@ -155,6 +155,19 @@ class Target_i386 : public Target_freebsd<32, false>
   do_is_defined_by_abi(const Symbol* sym) const
   { return strcmp(sym->name(), "___tls_get_addr") == 0; }
 
+  // Return whether a symbol name implies a local label.  The UnixWare
+  // 2.1 cc generates temporary symbols that start with .X, so we
+  // recognize them here.  FIXME: do other SVR4 compilers also use .X?.
+  // If so, we should move the .X recognition into
+  // Target::do_is_local_label_name.
+  bool
+  do_is_local_label_name(const char* name) const
+  {
+    if (name[0] == '.' && name[1] == 'X')
+      return true;
+    return Target::do_is_local_label_name(name);
+  }
+
   // Return the size of the GOT section.
   section_size_type
   got_size()
index 77ddce6e3820b3d8be279025e4d1f7de82202af8..88b6028287ee339a63735d897b756d31ce56582a 100644 (file)
@@ -1439,6 +1439,7 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
   unsigned int dyncount = 0;
   // Skip the first, dummy, symbol.
   psyms += sym_size;
+  bool discard_locals = parameters->options().discard_locals();
   for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
     {
       elfcpp::Sym<size, big_endian> sym(psyms);
@@ -1484,8 +1485,29 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
          continue;
        }
 
-      // Add the symbol to the symbol table string pool.
+      // If --discard-locals option is used, discard all temporary local
+      // symbols.  These symbols start with system-specific local label
+      // prefixes, typically .L for ELF system.  We want to be compatible
+      // with GNU ld so here we essentially use the same check in
+      // bfd_is_local_label().  The code is different because we already
+      // know that:
+      //
+      //   - the symbol is local and thus cannot have global or weak binding.
+      //   - the symbol is not a section symbol.
+      //   - the symbol has a name.
+      //
+      // We do not discard a symbol if it needs a dynamic symbol entry.
       const char* name = pnames + sym.get_st_name();
+      if (discard_locals
+         && sym.get_st_type() != elfcpp::STT_FILE
+         && !lv.needs_output_dynsym_entry()
+         && parameters->target().is_local_label_name(name))
+       {
+         lv.set_no_output_symtab_entry();
+         continue;
+       }
+
+      // Add the symbol to the symbol table string pool.
       pool->add(name, true, NULL);
       ++count;
 
index 47576c6d21708ee72524641af05ecaeda64a5532..d4255f1fb622e66f866674ff1f3caa477e8585b3 100644 (file)
@@ -645,6 +645,9 @@ class General_options
               N_("Try to detect violations of the One Definition Rule"),
               NULL);
 
+  DEFINE_bool(discard_locals, options::TWO_DASHES, 'X', false,
+              N_("Delete all temporary local symbols"), NULL);
+
   DEFINE_bool(dynamic_list_data, options::TWO_DASHES, '\0', false,
               N_("Add data symbols to dynamic symbols"), NULL);
 
diff --git a/gold/target.cc b/gold/target.cc
new file mode 100644 (file)
index 0000000..b6844d0
--- /dev/null
@@ -0,0 +1,58 @@
+// target.cc
+
+// 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.
+
+#include "gold.h"
+#include "target.h"
+
+namespace gold
+{
+
+// Return whether NAME is a local label name.  This is used to implement the
+// --discard-locals options and can be overriden by children classes to
+// implement system-specific behaviour.  The logic here is the same as that
+// in _bfd_elf_is_local_label_name().
+
+bool
+Target::do_is_local_label_name (const char* name) const
+{
+  // Normal local symbols start with ``.L''.
+  if (name[0] == '.' && name[1] == 'L')
+    return true;
+
+  // At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate
+  // DWARF debugging symbols starting with ``..''.
+  if (name[0] == '.' && name[1] == '.')
+    return true;
+
+  // gcc will sometimes generate symbols beginning with ``_.L_'' when
+  // emitting DWARF debugging output.  I suspect this is actually a
+  // small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call
+  // ASM_GENERATE_INTERNAL_LABEL, and this causes the leading
+  // underscore to be emitted on some ELF targets).  For ease of use,
+  // we treat such symbols as local.
+  if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
+    return true;
+
+  return false;
+}
+
+} // End namespace gold.
index fd6766e3b7b70c68983b152af3863e1644bd12fd..2a281050a8b071663356991b2536f2ab20d3720a 100644 (file)
@@ -173,6 +173,12 @@ class Target
   adjust_elf_header(unsigned char* view, int len) const
   { return this->do_adjust_elf_header(view, len); }
 
+  // Return whether NAME is a local label name.  This is used to implement the
+  // --discard-locals options.
+  bool
+  is_local_label_name(const char* name) const
+  { return this->do_is_local_label_name(name); }
+
  protected:
   // This struct holds the constant information for a child class.  We
   // use a struct to avoid the overhead of virtual function calls for
@@ -239,6 +245,10 @@ class Target
   do_adjust_elf_header(unsigned char*, int) const
   { }
 
+  // Virtual function which may be overriden by the child class.
+  virtual bool
+  do_is_local_label_name(const char*) const;
+
  private:
   Target(const Target&);
   Target& operator=(const Target&);
index e2bf8bd2aaedf1e07aa28534b10c4fc8bb146f81..3bb5bd3a5f86acbc9f48702cbea4bf6a0cd54ed5 100644 (file)
@@ -1080,5 +1080,17 @@ local_labels_test.o: ver_test_6.c
 local_labels_test: local_labels_test.o
        $(LINK) -Bgcctestdir/ local_labels_test.o
 
+check_PROGRAMS += discard_locals_test
+check_SCRIPTS += discard_locals_test.sh
+check_DATA += discard_locals_test.syms
+MOSTLYCLEANFILES += discard_locals_test.syms
+discard_locals_test_SOURCES = discard_locals_test.c
+discard_locals_test_LDFLAGS = -Bgcctestdir/ -Wl,--discard-locals
+discard_locals_test.syms: discard_locals_test
+       $(TEST_READELF) -sW $< >$@ 2>/dev/null
+# '-Wa,-L' is required to preserve the local label used for testing.
+discard_locals_test.o: discard_locals_test.c
+       $(COMPILE) -c -Wa,-L -o $@ $<
+
 endif GCC
 endif NATIVE_LINKER
index 0533e7bb8d9e504864e333b2d1537074bb5103b8..1bc579e76f7d90b39e3153c1b064c2adbd98a5d5 100644 (file)
@@ -319,12 +319,17 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
 @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@ local_labels_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 alt/libexclude_libs_test_3.a
-
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ local_labels_test \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_25 = exclude_libs_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.sh
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_26 = exclude_libs_test.syms \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.syms
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_27 = exclude_libs_test.syms \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ libexclude_libs_test_1.a \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ libexclude_libs_test_2.a \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/libexclude_libs_test_3.a \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.syms
 subdir = testsuite
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -431,7 +436,8 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS)
 @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) \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ local_labels_test$(EXEEXT)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ local_labels_test$(EXEEXT) \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test$(EXEEXT)
 basic_pic_test_SOURCES = basic_pic_test.c
 basic_pic_test_OBJECTS = basic_pic_test.$(OBJEXT)
 basic_pic_test_LDADD = $(LDADD)
@@ -490,6 +496,14 @@ am__copy_test_SOURCES_DIST = copy_test.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am_copy_test_OBJECTS =  \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ copy_test.$(OBJEXT)
 copy_test_OBJECTS = $(am_copy_test_OBJECTS)
+am__discard_locals_test_SOURCES_DIST = discard_locals_test.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am_discard_locals_test_OBJECTS =  \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.$(OBJEXT)
+discard_locals_test_OBJECTS = $(am_discard_locals_test_OBJECTS)
+discard_locals_test_LDADD = $(LDADD)
+discard_locals_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
+       ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
+       $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 am__exception_same_shared_test_SOURCES_DIST = exception_test_main.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am_exception_same_shared_test_OBJECTS =  \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ exception_test_main.$(OBJEXT)
@@ -899,6 +913,7 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \
        $(binary_test_SOURCES) $(binary_unittest_SOURCES) \
        $(common_test_1_SOURCES) $(constructor_static_test_SOURCES) \
        $(constructor_test_SOURCES) $(copy_test_SOURCES) \
+       $(discard_locals_test_SOURCES) \
        $(exception_same_shared_test_SOURCES) \
        $(exception_separate_shared_12_test_SOURCES) \
        $(exception_separate_shared_21_test_SOURCES) \
@@ -952,6 +967,7 @@ DIST_SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \
        $(am__constructor_static_test_SOURCES_DIST) \
        $(am__constructor_test_SOURCES_DIST) \
        $(am__copy_test_SOURCES_DIST) \
+       $(am__discard_locals_test_SOURCES_DIST) \
        $(am__exception_same_shared_test_SOURCES_DIST) \
        $(am__exception_separate_shared_12_test_SOURCES_DIST) \
        $(am__exception_separate_shared_21_test_SOURCES_DIST) \
@@ -1528,7 +1544,8 @@ binary_unittest_SOURCES = binary_unittest.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@exclude_libs_test_LDADD = -lexclude_libs_test_1 -lexclude_libs_test_2 \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/libexclude_libs_test_3.a
 
-@GCC_TRUE@@NATIVE_LINKER_TRUE@local_labels_test_LDFLAGS = -Bgcctestdir/
+@GCC_TRUE@@NATIVE_LINKER_TRUE@discard_locals_test_SOURCES = discard_locals_test.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@discard_locals_test_LDFLAGS = -Bgcctestdir/ -Wl,--discard-locals
 all: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -1543,9 +1560,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  testsuite/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  testsuite/Makefile'; \
        cd $(top_srcdir) && \
-         $(AUTOMAKE) --gnu  testsuite/Makefile
+         $(AUTOMAKE) --foreign  testsuite/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \
@@ -1615,6 +1632,9 @@ constructor_test$(EXEEXT): $(constructor_test_OBJECTS) $(constructor_test_DEPEND
 copy_test$(EXEEXT): $(copy_test_OBJECTS) $(copy_test_DEPENDENCIES) 
        @rm -f copy_test$(EXEEXT)
        $(CXXLINK) $(copy_test_LDFLAGS) $(copy_test_OBJECTS) $(copy_test_LDADD) $(LIBS)
+discard_locals_test$(EXEEXT): $(discard_locals_test_OBJECTS) $(discard_locals_test_DEPENDENCIES) 
+       @rm -f discard_locals_test$(EXEEXT)
+       $(LINK) $(discard_locals_test_LDFLAGS) $(discard_locals_test_OBJECTS) $(discard_locals_test_LDADD) $(LIBS)
 exception_same_shared_test$(EXEEXT): $(exception_same_shared_test_OBJECTS) $(exception_same_shared_test_DEPENDENCIES) 
        @rm -f exception_same_shared_test$(EXEEXT)
        $(CXXLINK) $(exception_same_shared_test_LDFLAGS) $(exception_same_shared_test_OBJECTS) $(exception_same_shared_test_LDADD) $(LIBS)
@@ -1898,6 +1918,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_test_1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constructor_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copy_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/discard_locals_test.Po@am__quote@
 @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@
@@ -2634,6 +2655,11 @@ uninstall-am: uninstall-info-am
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(COMPILE) -g -c -Wa,-L -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@local_labels_test: local_labels_test.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(LINK) -Bgcctestdir/ local_labels_test.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@discard_locals_test.syms: discard_locals_test
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -sW $< >$@ 2>/dev/null
+# '-Wa,-L' is required to preserve the local label used for testing.
+@GCC_TRUE@@NATIVE_LINKER_TRUE@discard_locals_test.o: discard_locals_test.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(COMPILE) -c -Wa,-L -o $@ $<
 # 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/discard_locals_test.c b/gold/testsuite/discard_locals_test.c
new file mode 100644 (file)
index 0000000..b722447
--- /dev/null
@@ -0,0 +1,40 @@
+/* discard_locals_test.c -- test --discard-locals option.
+
+   Copyright 2009 Free Software Foundation, Inc.
+   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 is a test of a common symbol in the main program and a
+   versioned symbol in a shared library.  The common symbol in the
+   main program should override the shared library symbol.  */
+
+/* Local symbol format for generic ELF target. */
+asm (".Lshould_be_discarded:");
+
+#ifdef __i386__
+/* Additional local symbol format for the i386 target. */
+asm (".Xshould_be_discarded:");
+#endif
+
+int
+main (void)
+{
+  return 0;
+}
+
diff --git a/gold/testsuite/discard_locals_test.sh b/gold/testsuite/discard_locals_test.sh
new file mode 100755 (executable)
index 0000000..c09f833
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# discard_locals_test.sh -- test that local symbols are discarded.
+
+# 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
+
+    found=`egrep "should_be_discarded" $file`
+    if test -n "$found"; then
+       echo "These local symbols are not discarded in $file:"
+       echo "$found"
+       exit 1
+    fi
+}
+
+check "discard_locals_test.syms"
+
+exit 0