[PATCH] Gold: Do not emit locals from discard .eh_frame sections.

Doug Kwan (關振德) dougkwan@google.com
Fri Jun 5 00:45:00 GMT 2009


Hi,

    This patches fixes a bug in which gold attempts to output local
symbols from discarded .eh_frame sections and triggers an assert in
Output_section::output_address because the function cannot find
corresponding input sections for those symbols.  This passed all gold
tests on x86_64-unknown-linux-gnu, including a new test in this patch.

-Doug

2009-06-04  Doug Kwan  <dougkwan@google.com>

        * object.cc (Sized_relobj::Sized_relobj): Initialize
        discarded_eh_frame_shndx_ to -1U.
        (Sized_relobj::do_layout): Record index of a discard .eh_frame
        section.
        (Sized_relobj::do_count_local_symbols): Skip local symbols in
        a discarded .eh_frame section.
        (Sized_relobj::do_finalize_local_symbols): Ditto.
        * object.h (class Sized_relobj): Declare new member
        discarded_eh_frame_shndx_.
        * testsuite/Makefile.am (check_PROGRAMS): Add local_labels_test.
        (local_labels_test_SOURCE, local_labels_test_LDFLAGS): Define new.
        (local_labels_test.o): New rule.
        * testsuite/Makefile.in: Regenerate.
        * testsuite/local_labels_test.cc: New file.
-------------- next part --------------
Index: gold/object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.91
diff -u -u -p -r1.91 object.cc
--- gold/object.cc	22 May 2009 18:31:22 -0000	1.91
+++ gold/object.cc	5 Jun 2009 00:30:22 -0000
@@ -327,7 +327,8 @@ Sized_relobj<size, big_endian>::Sized_re
     local_values_(),
     local_got_offsets_(),
     kept_comdat_sections_(),
-    has_eh_frame_(false)
+    has_eh_frame_(false),
+    discarded_eh_frame_shndx_(-1U)
 {
 }
 
@@ -1295,7 +1296,12 @@ Sized_relobj<size, big_endian>::do_layou
 						   &offset);
       out_sections[i] = os;
       if (offset == -1)
-        out_section_offsets[i] = invalid_address;
+	{
+	  // There can be at most one .eh_frame section per object.
+	  gold_assert(this->discarded_eh_frame_shndx_ == -1U);
+	  this->discarded_eh_frame_shndx_ = i;
+	  out_section_offsets[i] = invalid_address;
+	}
       else
         out_section_offsets[i] = convert_types<Address, off_t>(offset);
 
@@ -1453,7 +1459,8 @@ Sized_relobj<size, big_endian>::do_count
 
       // Decide whether this symbol should go into the output file.
 
-      if (shndx < shnum && out_sections[shndx] == NULL)
+      if ((shndx < shnum && out_sections[shndx] == NULL)
+	  || (shndx == this->discarded_eh_frame_shndx_))
         {
 	  lv.set_no_output_symtab_entry();
           gold_assert(!lv.needs_output_dynsym_entry());
@@ -1558,7 +1565,15 @@ Sized_relobj<size, big_endian>::do_final
 
 	      // This is a SHF_MERGE section or one which otherwise
 	      // requires special handling.
-	      if (!lv.is_section_symbol())
+	      if (shndx == this->discarded_eh_frame_shndx_)
+		{
+		  // This local symbol belongs to a discarded .eh_frame
+		  // section.  Just treat it like the case in which
+		  // os == NULL above.
+		  gold_assert(this->has_eh_frame_);
+		  continue;
+		}
+	      else if (!lv.is_section_symbol())
 		{
 		  // This is not a section symbol.  We can determine
 		  // the final value now.
Index: gold/object.h
===================================================================
RCS file: /cvs/src/src/gold/object.h,v
retrieving revision 1.74
diff -u -u -p -r1.74 object.h
--- gold/object.h	19 May 2009 22:14:17 -0000	1.74
+++ gold/object.h	5 Jun 2009 00:30:22 -0000
@@ -1815,6 +1815,9 @@ class Sized_relobj : public Relobj
   Kept_comdat_section_table kept_comdat_sections_;
   // Whether this object has a GNU style .eh_frame section.
   bool has_eh_frame_;
+  // If this object has a GNU sytle .eh_frame section that is discarded in
+  // output, record the index here.  Otherwise it is -1U.
+  unsigned int discarded_eh_frame_shndx_;
   // The list of sections whose layout was deferred.
   std::vector<Deferred_layout> deferred_layout_;
 };
Index: gold/testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.91
diff -u -u -p -r1.91 Makefile.am
--- gold/testsuite/Makefile.am	26 May 2009 22:52:56 -0000	1.91
+++ gold/testsuite/Makefile.am	5 Jun 2009 00:30:23 -0000
@@ -1074,5 +1074,11 @@ alt/libexclude_libs_test_3.a: exclude_li
 	test -d alt || mkdir -p alt
 	$(TEST_AR) rc $@ $^
 
+check_PROGRAMS += local_labels_test
+local_labels_test_SOURCES = local_labels_test.cc
+local_labels_test_LDFLAGS = -Bgcctestdir/
+local_labels_test.o: local_labels_test.cc
+	$(CXXCOMPILE) -g -c -Wa,--keep-locals -o $@ $<
+
 endif GCC
 endif NATIVE_LINKER
Index: gold/testsuite/Makefile.in
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.in,v
retrieving revision 1.96
diff -u -u -p -r1.96 Makefile.in
--- gold/testsuite/Makefile.in	26 May 2009 22:52:56 -0000	1.96
+++ gold/testsuite/Makefile.in	5 Jun 2009 00:30:23 -0000
@@ -318,7 +318,8 @@ check_PROGRAMS = object_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_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 \
@@ -429,7 +430,8 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest
 @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)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	exclude_libs_test$(EXEEXT) \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	local_labels_test$(EXEEXT)
 basic_pic_test_SOURCES = basic_pic_test.c
 basic_pic_test_OBJECTS = basic_pic_test.$(OBJEXT)
 basic_pic_test_LDADD = $(LDADD)
@@ -573,6 +575,14 @@ am__justsyms_SOURCES_DIST = justsyms_1.c
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	justsyms_1.$(OBJEXT)
 justsyms_OBJECTS = $(am_justsyms_OBJECTS)
 justsyms_LDADD = $(LDADD)
+am__local_labels_test_SOURCES_DIST = local_labels_test.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am_local_labels_test_OBJECTS =  \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	local_labels_test.$(OBJEXT)
+local_labels_test_OBJECTS = $(am_local_labels_test_OBJECTS)
+local_labels_test_LDADD = $(LDADD)
+local_labels_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
+	../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 many_sections_r_test_SOURCES = many_sections_r_test.c
 many_sections_r_test_OBJECTS = many_sections_r_test.$(OBJEXT)
 many_sections_r_test_LDADD = $(LDADD)
@@ -900,7 +910,8 @@ SOURCES = $(libgoldtest_a_SOURCES) basic
 	$(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 \
+	$(initpri1_SOURCES) $(justsyms_SOURCES) \
+	$(local_labels_test_SOURCES) many_sections_r_test.c \
 	$(many_sections_test_SOURCES) $(object_unittest_SOURCES) \
 	plugin_test_1.c plugin_test_2.c plugin_test_3.c \
 	plugin_test_4.c $(protected_1_SOURCES) $(protected_2_SOURCES) \
@@ -955,7 +966,8 @@ DIST_SOURCES = $(libgoldtest_a_SOURCES) 
 	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) \
-	many_sections_r_test.c $(am__many_sections_test_SOURCES_DIST) \
+	$(am__local_labels_test_SOURCES_DIST) many_sections_r_test.c \
+	$(am__many_sections_test_SOURCES_DIST) \
 	$(object_unittest_SOURCES) plugin_test_1.c plugin_test_2.c \
 	plugin_test_3.c plugin_test_4.c \
 	$(am__protected_1_SOURCES_DIST) \
@@ -1519,6 +1531,8 @@ binary_unittest_SOURCES = binary_unittes
 @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_SOURCES = local_labels_test.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@local_labels_test_LDFLAGS = -Bgcctestdir/
 all: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -1659,6 +1673,9 @@ initpri1$(EXEEXT): $(initpri1_OBJECTS) $
 justsyms$(EXEEXT): $(justsyms_OBJECTS) $(justsyms_DEPENDENCIES) 
 	@rm -f justsyms$(EXEEXT)
 	$(CXXLINK) $(justsyms_LDFLAGS) $(justsyms_OBJECTS) $(justsyms_LDADD) $(LIBS)
+local_labels_test$(EXEEXT): $(local_labels_test_OBJECTS) $(local_labels_test_DEPENDENCIES) 
+	@rm -f local_labels_test$(EXEEXT)
+	$(CXXLINK) $(local_labels_test_LDFLAGS) $(local_labels_test_OBJECTS) $(local_labels_test_LDADD) $(LIBS)
 @GCC_FALSE@many_sections_r_test$(EXEEXT): $(many_sections_r_test_OBJECTS) $(many_sections_r_test_DEPENDENCIES) 
 @GCC_FALSE@	@rm -f many_sections_r_test$(EXEEXT)
 @GCC_FALSE@	$(LINK) $(many_sections_r_test_LDFLAGS) $(many_sections_r_test_OBJECTS) $(many_sections_r_test_LDADD) $(LIBS)
@@ -1891,6 +1908,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_o_specialfile_and_compress_debug_sections.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initpri1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/justsyms_1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local_labels_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/many_sections_r_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/many_sections_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object_unittest.Po@am__quote@
@@ -2613,6 +2631,8 @@ uninstall-am: uninstall-info-am
 @GCC_TRUE@@NATIVE_LINKER_TRUE@alt/libexclude_libs_test_3.a: exclude_libs_test_3.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	test -d alt || mkdir -p alt
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	$(TEST_AR) rc $@ $^
+@GCC_TRUE@@NATIVE_LINKER_TRUE@local_labels_test.o: local_labels_test.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXCOMPILE) -g -c -Wa,--keep-locals -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:
Index: gold/testsuite/local_labels_test.cc
===================================================================
RCS file: gold/testsuite/local_labels_test.cc
diff -N gold/testsuite/local_labels_test.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/local_labels_test.cc	5 Jun 2009 00:30:23 -0000
@@ -0,0 +1,32 @@
+// local_labels_test.cc -- test case for local labels in .eh_frame sections.
+
+// 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 is assembled with the -Wa,--keep-locals option to preserve all
+// local labels in the object.  gold had a bug in which local symbols from
+// discarded .eh_frame sections were not removed.  Those local symbols caused
+// gold to abort because no output sections were found.
+
+int
+main (int, char**)
+{
+  return 0;
+}


More information about the Binutils mailing list