This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH COMMITTED: Fix weak aliasing bug


I found a tricky weak aliasing bug in gold.  If gold sees the
following sequence:

1) Shared library S1 defines a weak symbol W.
2) Shared library S2 defines a strong symbol S which happens to have
   the same section index and value as W, although it is a different
   shared library.
3) Regular object O, seen after S1 and S2, also defines symbol the
   weak symbol W.

Then it will bring W into the main executable, as it should, but it
will also incorrectly bring S into the main executable as an alias for
W, which is wrong.

This patch fixes the bug, along with a test case.  The test case is
careful to ensure that W and S have the same section and index by
ensuring that the dynamic symbol table and dynamic string table in S1
and S2 are exactly the same length.  The test case also includes
unrelated tests for the correct behaviour of weak aliases.  These were
already working, but it obviously doesn't hurt to test them.

Ian


2008-04-09  Ian Lance Taylor  <iant@google.com>

	* symtab.cc (Symbol_table::add_from_dynobj): Only look for weak
	aliases for symbols defined in the same object.
	* testsuite/Makefile.am (check_PROGRAMS): Add weak_alias_test.
	(weak_alias_test_SOURCES): New variable.
	(weak_alias_test_DEPENDENCIES): New variable.
	(weak_alias_test_LDFLAGS): New variable.
	(weak_alias_test_LDADD): New variable.
	(weak_alias_test_1_pic.o, weak_alias_test_1.so): New targets.
	(weak_alias_test_2_pic.o, weak_alias_test_2.so): New targets.
	(weak_alias_test_3.o): New target.
	(weak_alias_test_4_pic.o, weak_alias_test_4.so): New targets.
	* testsuite/weak_alias_test_main.cc: New file.
	* testsuite/weak_alias_test_1.cc: New file.
	* testsuite/weak_alias_test_2.cc: New file.
	* testsuite/weak_alias_test_3.cc: New file.


Index: symtab.cc
===================================================================
RCS file: /cvs/src/src/gold/symtab.cc,v
retrieving revision 1.88
diff -u -p -r1.88 symtab.cc
--- symtab.cc	9 Apr 2008 00:48:13 -0000	1.88
+++ symtab.cc	9 Apr 2008 22:44:06 -0000
@@ -1006,8 +1006,12 @@ Symbol_table::add_from_dynobj(
 	    }
 	}
 
+      // Note that it is possible that RES was overridden by an
+      // earlier object, in which case it can be aliased here.
       if (sym.get_st_shndx() != elfcpp::SHN_UNDEF
-	  && sym.get_st_type() == elfcpp::STT_OBJECT)
+	  && sym.get_st_type() == elfcpp::STT_OBJECT
+	  && res->source() == Symbol::FROM_OBJECT
+	  && res->object() == dynobj)
 	object_symbols.push_back(res);
     }
 
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.57
diff -u -p -r1.57 Makefile.am
--- testsuite/Makefile.am	8 Apr 2008 14:33:35 -0000	1.57
+++ testsuite/Makefile.am	9 Apr 2008 22:44:06 -0000
@@ -380,6 +380,30 @@ alt/weak_undef_lib.so: weak_undef_file2.
 	test -d alt || mkdir -p alt
 	$(CXXLINK) -Bgcctestdir/ -shared weak_undef_file2.o
 
+check_PROGRAMS += weak_alias_test
+weak_alias_test_SOURCES = weak_alias_test_main.cc
+weak_alias_test_DEPENDENCIES = \
+	gcctestdir/ld weak_alias_test_1.so weak_alias_test_2.so \
+	weak_alias_test_3.o weak_alias_test_4.so
+weak_alias_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
+weak_alias_test_LDADD = \
+	weak_alias_test_1.so weak_alias_test_2.so weak_alias_test_3.o \
+	weak_alias_test_4.so
+weak_alias_test_1_pic.o: weak_alias_test_1.cc
+	$(CXXCOMPILE) -c -fpic -o $@ $<
+weak_alias_test_1.so: weak_alias_test_1_pic.o
+	$(CXXLINK) -Bgcctestdir/ -shared weak_alias_test_1_pic.o
+weak_alias_test_2_pic.o: weak_alias_test_2.cc
+	$(CXXCOMPILE) -c -fpic -o $@ $<
+weak_alias_test_2.so: weak_alias_test_2_pic.o
+	$(CXXLINK) -Bgcctestdir/ -shared weak_alias_test_2_pic.o
+weak_alias_test_3.o: weak_alias_test_3.cc
+	$(CXXCOMPILE) -c -o $@ $<
+weak_alias_test_4_pic.o: weak_alias_test_4.cc
+	$(CXXCOMPILE) -c -fpic -o $@ $<
+weak_alias_test_4.so: weak_alias_test_4_pic.o
+	$(CXXLINK) -Bgcctestdir/ -shared weak_alias_test_4_pic.o
+
 if TLS
 
 check_PROGRAMS += tls_test
Index: testsuite/weak_alias_test_1.cc
===================================================================
RCS file: testsuite/weak_alias_test_1.cc
diff -N testsuite/weak_alias_test_1.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/weak_alias_test_1.cc	9 Apr 2008 22:44:07 -0000
@@ -0,0 +1,52 @@
+// weak_alias_test_1.cc -- test weak aliases for gold
+
+// Copyright 2008 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@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.
+
+// Define a weak symbol.
+
+extern int weak_symbol __attribute__ ((weak));
+int weak_symbol = 1;
+
+// Define a strong symbol with a weak alias.
+
+int strong_aliased = 2;
+extern int weak_aliased __attribute__ ((weak, alias ("strong_aliased")));
+
+// And another one.
+
+int strong_aliased_2 = 5;
+extern int weak_aliased_2 __attribute__ ((weak, alias ("strong_aliased_2")));
+
+// And a third.
+
+int strong_aliased_3 = 7;
+extern int weak_aliased_3 __attribute__ ((weak, alias ("strong_aliased_3")));
+
+// And a fourth.
+
+int strong_aliased_4 = 8;
+extern int weak_aliased_4 __attribute__ ((weak, alias ("strong_aliased_4")));
+
+// We want a symbol whose name is the same length as "strong_symbol",
+// so that weak_symbol here lines up with weak_symbol in
+// weak_alias_test_2.so.
+
+int Strong_Symbol = 101;
Index: testsuite/weak_alias_test_2.cc
===================================================================
RCS file: testsuite/weak_alias_test_2.cc
diff -N testsuite/weak_alias_test_2.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/weak_alias_test_2.cc	9 Apr 2008 22:44:07 -0000
@@ -0,0 +1,41 @@
+// weak_alias_test_2.cc -- test weak aliases for gold
+
+// Copyright 2008 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@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.
+
+// Define a strong symbol.
+
+int strong_symbol = 2;
+
+// Define a weak symbol.  This will be overridden by the weak symbol
+// in weak_alias_test_1.cc.
+
+extern int weak_symbol __attribute__ ((weak));
+int weak_symbol = 3;
+
+// These are overridden by weak_alias_test_1.cc
+int strong_aliased = 100;
+extern int weak_aliased __attribute__ ((weak, alias ("strong_aliased")));
+int strong_aliased_2 = 102;
+extern int weak_aliased_2 __attribute__ ((weak, alias ("strong_aliased_2")));
+int strong_aliased_3 = 104;
+extern int weak_aliased_3 __attribute__ ((weak, alias ("strong_aliased_3")));
+int strong_aliased_4 = 106;
+extern int weak_aliased_4 __attribute__ ((weak, alias ("strong_aliased_4")));
Index: testsuite/weak_alias_test_3.cc
===================================================================
RCS file: testsuite/weak_alias_test_3.cc
diff -N testsuite/weak_alias_test_3.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/weak_alias_test_3.cc	9 Apr 2008 22:44:07 -0000
@@ -0,0 +1,26 @@
+// weak_alias_test_3.cc -- test weak aliases for gold
+
+// Copyright 2008 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@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 linked into the main program.
+
+extern int weak_symbol __attribute__ ((weak));
+int weak_symbol = 4;
Index: testsuite/weak_alias_test_4.cc
===================================================================
RCS file: testsuite/weak_alias_test_4.cc
diff -N testsuite/weak_alias_test_4.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/weak_alias_test_4.cc	9 Apr 2008 22:44:07 -0000
@@ -0,0 +1,68 @@
+// weak_alias_test_4.cc -- test weak aliases for gold
+
+// Copyright 2008 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@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.
+
+// Verify that all the symbols look right from a shared library.
+
+extern int weak_symbol;
+extern int strong_aliased;
+extern int weak_aliased;
+extern int strong_aliased_2;
+extern int weak_aliased_2;
+extern int strong_aliased_3;
+extern int weak_aliased_3;
+extern int strong_aliased_4;
+extern int weak_aliased_4;
+extern int strong_symbol;
+
+bool
+t1()
+{
+  // Should come from weak_alias_test_3.cc.
+  if (weak_symbol != 4)
+    return false;
+
+  // Should come from weak_alias_test_main.cc.
+  if (strong_aliased != 3)
+    return false;
+
+  // weak_aliased need not match strong_aliased, which is overridden
+  // by weak_test_main.cc.
+
+  // Should come from weak_alias_test_main.cc.
+  if (weak_aliased_2 != 6)
+    return false;
+
+  // strong_aliased_2 need not match weak_aliased_2, which is
+  // overidden by weak_test_main.cc.
+
+  // The others should match.
+  if (weak_aliased_3 != 7 || strong_aliased_3 != 7)
+    return false;
+  if (weak_aliased_4 != 8 || strong_aliased_4 != 8)
+    return false;
+
+  // Should come from weak_alias_test_2.cc.
+  if (strong_symbol != 2)
+    return false;
+
+  return true;
+}
Index: testsuite/weak_alias_test_main.cc
===================================================================
RCS file: testsuite/weak_alias_test_main.cc
diff -N testsuite/weak_alias_test_main.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/weak_alias_test_main.cc	9 Apr 2008 22:44:07 -0000
@@ -0,0 +1,67 @@
+// weak_alias_test_main.cc -- test weak aliases for gold
+
+// Copyright 2008 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@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 <assert.h>
+
+// Defined in both weak_alias_test_1.cc and weak_alias_test_2.cc, but
+// we should get the one in weak_alias_test_1.cc.
+extern int weak_symbol;
+
+// Defined in weak_alias_test_2.cc.
+extern int strong_symbol;
+
+// weak_aliased is an alias for this.
+int strong_aliased = 3;
+
+// Defined as a weak alias in weak_alias_test_1.cc.
+int weak_aliased_2 = 6;
+
+// Defined in weak_alias_test_1.cc
+extern int strong_aliased_3;
+extern int weak_aliased_4;
+
+extern bool t1();
+
+int
+main()
+{
+  // weak_symbol should come from weak_alias_test_3.cc.
+  assert(weak_symbol == 4);
+
+  // strong_symbol should come from weak_alias_test_2.cc.
+  assert(strong_symbol == 2);
+
+  // strong_aliased should come from this file, above.
+  assert(strong_aliased == 3);
+
+  // weak_aliased_2 should come from this file, above.
+  assert(weak_aliased_2 == 6);
+
+  // strong_aliased_3 should come from weak_alias_test_1.cc.
+  assert(strong_aliased_3 == 7);
+
+  // weak_aliased_4 should come from weak_alias_test_1.cc.
+  assert(weak_aliased_4 == 8);
+
+  // Make sure the symbols look right from a shared library.
+  assert(t1());
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]