Patch to fix a bug when a kept comdat section is garbage collected.

Sriraman Tallam tmsriram@google.com
Fri May 22 18:17:00 GMT 2009


Hi,

      I noticed this bug when --gc-sections is used and the kept
comdat sections get
garbage collected.

How to reproduce :

comd1.cc
---------------
template <class T>
T GetMax (T a, T b)
{
 return (a > b)?a:b;
}

int foo();
int bar ()
{
 return GetMax <int> (4,5) + foo();
}

int main()
{
 return 0;
}


comd2.cc
--------------
template <class T>
T GetMax (T a, T b)
{
 return (a > b)?a:b;
}

int foo ()
{
 return GetMax <int> (10,11);
}


$ g++  -g  -c -ffunction-sections comd1.cc
$ g++  -g  -c -ffunction-sections comd2.cc

$g++   -Wl,--gc-sections  comd1.o comd2.o


ld: internal error in map_to_kept_section, at ../../src/gold/object.cc:1876

The reason is that a debug_section corresponding to a discarded comdat
section is trying to find
the appropriate kept section. However, the kept section is garbage
collected and it's os = NULL.
Hence, the assertion failure.

Here is a patch to fix the bug along with a test case :

Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.90
diff -u -p -u -r1.90 object.cc
--- object.cc	24 Mar 2009 18:42:10 -0000	1.90
+++ object.cc	22 May 2009 18:12:55 -0000
@@ -1873,8 +1873,8 @@ Sized_relobj<size, big_endian>::map_to_k
       *found = true;
       Output_section* os = kept->object_->output_section(kept->shndx_);
       Address offset = kept->object_->get_output_section_offset(kept->shndx_);
-      gold_assert(os != NULL && offset != invalid_address);
-      return os->address() + offset;
+      if (os != NULL && offset != invalid_address)
+        return os->address() + offset;
     }
   *found = false;
   return 0;
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.88
diff -u -p -u -r1.88 Makefile.am
--- testsuite/Makefile.am	19 May 2009 22:14:17 -0000	1.88
+++ testsuite/Makefile.am	22 May 2009 18:12:55 -0000
@@ -23,6 +23,7 @@ TEST_OBJDUMP = $(top_builddir)/../binuti
 TEST_CXXFILT = $(top_builddir)/../binutils/cxxfilt
 TEST_STRIP = $(top_builddir)/../binutils/strip-new
 TEST_AR = $(top_builddir)/../binutils/ar
+TEST_NM = $(top_builddir)/../binutils/nm-new

 if PLUGINS
 LIBDL = -ldl
@@ -103,6 +104,18 @@ flagstest_ndebug.o: constructor_test.cc
 	$(CXXCOMPILE) -O0 -c -o $@ $<


+check_SCRIPTS += gc_comdat_test.sh
+check_DATA += gc_comdat_test.stdout
+gc_comdat_test_1.o: gc_comdat_test_1.cc
+	$(CXXCOMPILE) -O0 -c -g -o $@ $<
+gc_comdat_test_2.o: gc_comdat_test_2.cc
+	$(CXXCOMPILE) -O0 -c -g -o $@ $<
+gc_comdat_test: gc_comdat_test_1.o gc_comdat_test_2.o gcctestdir/ld
+	$(CXXLINK) -Bgcctestdir/ --gc-sections gc_comdat_test_1.o gc_comdat_test_2.o
+gc_comdat_test.stdout: gc_comdat_test
+	$(TEST_NM) -C gc_comdat_test > gc_comdat_test.stdout
+
+
 check_PROGRAMS += basic_test
 check_PROGRAMS += basic_static_test
 check_PROGRAMS += basic_pic_test
Index: testsuite/gc_comdat_test.sh
===================================================================
RCS file: testsuite/gc_comdat_test.sh
diff -N testsuite/gc_comdat_test.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gc_comdat_test.sh	22 May 2009 18:12:55 -0000
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# gc_comdat_test.sh -- test --gc-sections
+
+# Copyright 2009 Free Software Foundation, Inc.
+# Written by Sriraman Tallam <tmsriram@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.
+
+# The goal of this program is to verify if comdat's and garbage
+# collection work together.  Files gc_comdat_test_1.cc and
+# gc_comdat_test_2.cc are used in this test.  This program checks
+# if the kept comdat section is garbage collected.
+
+check()
+{
+    if ! grep -q "$2" "$1"
+    then
+        echo "Garbage collection failed to collect :"
+        echo "   $2"
+	exit 1
+    fi
+}
+
+check gc_comdat_test.stdout "foo()"
+check gc_comdat_test.stdout "bar()"
+check gc_comdat_test.stdout "int GetMax<int>(int, int)"
Index: testsuite/gc_comdat_test_1.cc
===================================================================
RCS file: testsuite/gc_comdat_test_1.cc
diff -N testsuite/gc_comdat_test_1.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gc_comdat_test_1.cc	22 May 2009 18:12:55 -0000
@@ -0,0 +1,42 @@
+// gc_comdat_test_1.cc -- a test case for gold
+
+// Copyright 2009 Free Software Foundation, Inc.
+// Written by Sriraman Tallam <tmsriram@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.
+
+// The goal of this program is to verify if comdat's and garbage
+// collection work together.  This file is compiled with -g.  The
+// comdat kept function for GetMax is garbage.
+
+int foo();
+template <class T>
+T GetMax (T a, T b)
+{
+  return (a > b)?a:b;
+}
+
+int bar ()
+{
+  return GetMax <int> (4,5);
+}
+
+int main()
+{
+  return 0;
+}
Index: testsuite/gc_comdat_test_2.cc
===================================================================
RCS file: testsuite/gc_comdat_test_2.cc
diff -N testsuite/gc_comdat_test_2.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gc_comdat_test_2.cc	22 May 2009 18:12:55 -0000
@@ -0,0 +1,35 @@
+// gc_comdat_test_2.cc -- a test case for gold
+
+// Copyright 2009 Free Software Foundation, Inc.
+// Written by Sriraman Tallam <tmsriram@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.
+
+// The goal of this program is to verify if comdat's and garbage
+// collection work together.  This file is compiled with -g.
+
+template <class T>
+T GetMax (T a, T b)
+{
+  return (a > b)?a:b;
+}
+
+int foo ()
+{
+  return GetMax <int> (10,11);
+}


Changes :

	* object.cc (Sized_relobj::map_to_kept_section): Return NULL if the
	kept comdat section was garbage collected.
	* testsuite/Makefile.am: Add test gc_comdat_test.sh.
	* testsuite/Makefile.in: Regenerate.
	* testsuite/gc_comdat_test.sh: New file.
	* testsuite/gc_comdat_test_1.cc: New file.
	* testsuite/gc_comdat_test_2.cc: New file.


Thanks,
-Sriraman Tallam.



More information about the Binutils mailing list