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 protected symbols in shared libraries


"Andreas Hartmetz" <ahartmetz@gmail.com> writes:

> -when "copying" a symbol from a dynamic library to the output file
> gold will not change the visibility. This is broken for symbols with
> protected visibility in the source. As hidden symbols will be ignored
> anyway it's safe to always give those symbols default (=="public")
> visibility. This mattered when linking the xine multimedia libraries
> which contain protected and exported symbols.

Thanks for the clear description of the problem, and the sample patch.
I committed this patch to fix it, along with a test case.

Ian


2008-05-06  Ian Lance Taylor  <iant@google.com>

	* symtab.cc (Symbol_table::add_from_dynobj): If we see a protected
	symbol, change it to have default visibility.
	* testsuite/protected_1.cc: New file.
	* testsuite/protected_2.cc: New file.
	* testsuite/protected_3.cc: New file.
	* testsuite/protected_main_1.cc: New file.
	* testsuite/protected_main_2.cc: New file.
	* testsuite/protected_main_3.cc: New file.
	* testsuite/Makefile.am (check_PROGRAMS): Add protected_1.
	(protected_1_SOURCES, protected_1_DEPENDENCIES): Define.
	(protected_1_LDFLAGS, protected_1_LDADD): Define.
	(protected_1.so): New target.
	(protected_1_pic.o, protected_2_pic.o): New targets.
	(protected_3_pic.o): New target.
	(check_PROGRAMS): Add protected_2.
	(protected_2_SOURCES, protected_2_DEPENDENCIES): Define.
	(protected_2_LDFLAGS, protected_2_LDADD): Define.
	* testsuite/Makefile.in: Rebuild.


Index: symtab.cc
===================================================================
RCS file: /cvs/src/src/gold/symtab.cc,v
retrieving revision 1.95
diff -p -u -r1.95 symtab.cc
--- symtab.cc	1 May 2008 00:25:33 -0000	1.95
+++ symtab.cc	6 May 2008 21:52:17 -0000
@@ -942,7 +942,21 @@ Symbol_table::add_from_dynobj(
           || sym.get_st_visibility() == elfcpp::STV_HIDDEN)
 	continue;
 
-      unsigned int st_name = sym.get_st_name();
+      // A protected symbol in a shared library must be treated as a
+      // normal symbol when viewed from outside the shared library.
+      // Implement this by overriding the visibility here.
+      elfcpp::Sym<size, big_endian>* psym = &sym;
+      unsigned char symbuf[sym_size];
+      elfcpp::Sym<size, big_endian> sym2(symbuf);
+      if (sym.get_st_visibility() == elfcpp::STV_PROTECTED)
+	{
+	  memcpy(symbuf, p, sym_size);
+	  elfcpp::Sym_write<size, big_endian> sw(symbuf);
+	  sw.put_st_other(elfcpp::STV_DEFAULT, sym.get_st_nonvis());
+	  psym = &sym2;
+	}
+
+      unsigned int st_name = psym->get_st_name();
       if (st_name >= sym_name_size)
 	{
 	  dynobj->error(_("bad symbol name offset %u at %zu"),
@@ -953,7 +967,7 @@ Symbol_table::add_from_dynobj(
       const char* name = sym_names + st_name;
 
       bool is_ordinary;
-      unsigned int st_shndx = dynobj->adjust_sym_shndx(i, sym.get_st_shndx(),
+      unsigned int st_shndx = dynobj->adjust_sym_shndx(i, psym->get_st_shndx(),
 						       &is_ordinary);
 
       Sized_symbol<size>* res;
@@ -963,7 +977,7 @@ Symbol_table::add_from_dynobj(
 	  Stringpool::Key name_key;
 	  name = this->namepool_.add(name, true, &name_key);
 	  res = this->add_from_object(dynobj, name, name_key, NULL, 0,
-				      false, sym, st_shndx, is_ordinary,
+				      false, *psym, st_shndx, is_ordinary,
 				      st_shndx);
 	}
       else
@@ -998,7 +1012,7 @@ Symbol_table::add_from_dynobj(
 	    {
 	      // This symbol does not have a version.
 	      res = this->add_from_object(dynobj, name, name_key, NULL, 0,
-					  false, sym, st_shndx, is_ordinary,
+					  false, *psym, st_shndx, is_ordinary,
 					  st_shndx);
 	    }
 	  else
@@ -1030,14 +1044,14 @@ Symbol_table::add_from_dynobj(
 		  && !is_ordinary
 		  && name_key == version_key)
 		res = this->add_from_object(dynobj, name, name_key, NULL, 0,
-					    false, sym, st_shndx, is_ordinary,
+					    false, *psym, st_shndx, is_ordinary,
 					    st_shndx);
 	      else
 		{
 		  const bool def = (!hidden
 				    && st_shndx != elfcpp::SHN_UNDEF);
 		  res = this->add_from_object(dynobj, name, name_key, version,
-					      version_key, def, sym, st_shndx,
+					      version_key, def, *psym, st_shndx,
 					      is_ordinary, st_shndx);
 		}
 	    }
@@ -1047,7 +1061,7 @@ Symbol_table::add_from_dynobj(
       // earlier object, in which case it can't be aliased here.
       if (st_shndx != elfcpp::SHN_UNDEF
 	  && is_ordinary
-	  && sym.get_st_type() == elfcpp::STT_OBJECT
+	  && psym->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.67
diff -p -u -r1.67 Makefile.am
--- testsuite/Makefile.am	19 Apr 2008 19:43:13 -0000	1.67
+++ testsuite/Makefile.am	6 May 2008 21:52:17 -0000
@@ -750,6 +750,28 @@ check_DATA += ver_test_7.syms
 ver_test_7.syms: ver_test_7.so
 	$(TEST_READELF) -s $< >$@ 2>/dev/null
 
+check_PROGRAMS += protected_1
+protected_1_SOURCES = \
+	protected_main_1.cc protected_main_2.cc protected_main_3.cc
+protected_1_DEPENDENCIES = gcctestdir/ld protected_1.so
+protected_1_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
+protected_1_LDADD = protected_1.so
+
+protected_1.so: gcctestdir/ld protected_1_pic.o protected_2_pic.o protected_3_pic.o
+	$(CXXLINK) -Bgcctestdir/ -shared protected_1_pic.o protected_2_pic.o protected_3_pic.o
+protected_1_pic.o: protected_1.cc
+	$(CXXCOMPILE) -c -fpic -o $@ $<
+protected_2_pic.o: protected_2.cc
+	$(CXXCOMPILE) -c -fpic -o $@ $<
+protected_3_pic.o: protected_3.cc
+	$(CXXCOMPILE) -c -fpic -o $@ $<
+
+check_PROGRAMS += protected_2
+protected_2_SOURCES = protected_main_1.cc protected_3.cc
+protected_2_DEPENDENCIES = gcctestdir/ld protected_1.so
+protected_2_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
+protected_2_LDADD = protected_1.so
+
 check_PROGRAMS += script_test_1
 script_test_1_SOURCES = script_test_1.cc
 script_test_1_DEPENDENCIES = gcctestdir/ld script_test_1.t
Index: testsuite/protected_1.cc
===================================================================
RCS file: testsuite/protected_1.cc
diff -N testsuite/protected_1.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/protected_1.cc	6 May 2008 21:52:17 -0000
@@ -0,0 +1,33 @@
+// protected_1.cc -- a test case 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.
+
+// The function f1 is protected, which means that other callers in the
+// same shared library will call this version.
+
+int
+f1() __attribute__ ((__visibility__ ("protected")));
+
+int
+f1()
+{
+  return 1;
+}
Index: testsuite/protected_2.cc
===================================================================
RCS file: testsuite/protected_2.cc
diff -N testsuite/protected_2.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/protected_2.cc	6 May 2008 21:52:17 -0000
@@ -0,0 +1,31 @@
+// protected_2.cc -- a test case 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 should call the protected version of f1.
+
+extern int f1();
+
+bool
+t1()
+{
+  return f1() == 1;
+}
Index: testsuite/protected_3.cc
===================================================================
RCS file: testsuite/protected_3.cc
diff -N testsuite/protected_3.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/protected_3.cc	6 May 2008 21:52:17 -0000
@@ -0,0 +1,33 @@
+// protected_2.cc -- a test case 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 will also call the protected version of f1.  In some versions
+// of the test this will be overridden by a version in the main
+// program.
+
+extern int f1();
+
+bool
+t2()
+{
+  return f1() == 1;
+}
Index: testsuite/protected_main_1.cc
===================================================================
RCS file: testsuite/protected_main_1.cc
diff -N testsuite/protected_main_1.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/protected_main_1.cc	6 May 2008 21:52:17 -0000
@@ -0,0 +1,36 @@
+// protected_main_1.cc -- a test case 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 <cassert>
+
+// This function in the shared library will call the protected version
+// of f1 in the shared library.
+
+extern bool t1();
+extern bool t2();
+
+int
+main()
+{
+  assert(t1());
+  assert(t2());
+}
Index: testsuite/protected_main_2.cc
===================================================================
RCS file: testsuite/protected_main_2.cc
diff -N testsuite/protected_main_2.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/protected_main_2.cc	6 May 2008 21:52:17 -0000
@@ -0,0 +1,29 @@
+// protected_main_2.cc -- a test case 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 version of f1 will not be called by the shared library code.
+
+int
+f1()
+{
+  return 2;
+}
Index: testsuite/protected_main_3.cc
===================================================================
RCS file: testsuite/protected_main_3.cc
diff -N testsuite/protected_main_3.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/protected_main_3.cc	6 May 2008 21:52:17 -0000
@@ -0,0 +1,31 @@
+// protected_main_3.cc -- a test case 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 should call the unprotected version of f1.
+
+extern int f1();
+
+bool
+t2()
+{
+  return f1() == 2;
+}

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