Patch to not create GOT and dynamic relocation entries for unresolved symbols with --warn-unresolved-symbols.

Sriraman Tallam tmsriram@google.com
Thu Apr 23 17:27:00 GMT 2015


On Thu, Apr 23, 2015 at 8:09 AM, Cary Coutant <ccoutant@gmail.com> wrote:
>> +      // If --weak-unresolved-symbols is set, change binding of unresolved
>> +      // global symbols to STB_WEAK.
>> +      if (parameters->options().weak_unresolved_symbols()
>> +         && (binding == elfcpp::STB_GLOBAL
>> +             || binding == elfcpp::STB_LOCAL)
>>
>> Why check for STB_LOCAL? Local symbols can't be unresolved. What about
>> STB_GNU_UNIQUE symbols? (Perhaps that's what you meant.)
>
> On further thought, I doubt we will see an undefined GNU_UNIQUE
> symbol, and if we do, I'm not sure we should be changing it to WEAK
> (unless the very next if statement converts it to GLOBAL).

Patch redone and attached.

Thanks
Sri

>
> -cary
-------------- next part --------------
This patch adds option --weak-unresolved-symbols to treat unresolved symbols as
weak references.  This is helpful when we want the link to succeed with unresolved
symbols and the dynamic loader to not complain at run-time.  Option
--warn-unresolved-symbols lets the link succeed but could fail at run-time with
unresolved symbol warnings especially when the unresolved symbols have GOT entries
and dynamic relocations against them, like when -fPIE is used.

	* options.h (--weak-unresolved-symbols): New option.
	* symtab.cc (Symbol_table::sized_write_globals): Change symbol
	binding to weak with new option.
	* symtab.h (is_weak_undefined): Check for new option.
	(is_strong_undefined): Check for new option.
	* testsuite/Makefile.am(weak_unresolved_symbols_test): New test.
	* testsuite/Makefile.in: Regenerate.
	* testsuite/weak_unresolved_symbols_test.cc: New file.

diff --git a/gold/options.h b/gold/options.h
index c1a5743..bb3bee6 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -1219,6 +1219,9 @@ class General_options
 		    options::TWO_DASHES, '\0',
 		    N_("Report unresolved symbols as errors"),
 		    NULL, true);
+  DEFINE_bool(weak_unresolved_symbols, options::TWO_DASHES, '\0', false,
+	      N_("Convert unresolved symbols to weak references"),
+	      NULL);
 
   DEFINE_bool(wchar_size_warning, options::TWO_DASHES, '\0', true, NULL,
 	      N_("(ARM only) Do not warn about objects with incompatible "
diff --git a/gold/symtab.cc b/gold/symtab.cc
index d4f40c8..19f79367a 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -2916,6 +2916,13 @@ Symbol_table::sized_write_globals(const Stringpool* sympool,
       typename elfcpp::Elf_types<size>::Elf_Addr dynsym_value = sym_value;
       elfcpp::STB binding = sym->binding();
 
+      // If --weak-unresolved-symbols is set, change binding of unresolved
+      // global symbols to STB_WEAK.
+      if (parameters->options().weak_unresolved_symbols()
+	  && binding == elfcpp::STB_GLOBAL
+	  && sym->is_undefined())
+	binding = elfcpp::STB_WEAK;
+
       // If --no-gnu-unique is set, change STB_GNU_UNIQUE to STB_GLOBAL.
       if (binding == elfcpp::STB_GNU_UNIQUE
 	  && !parameters->options().gnu_unique())
diff --git a/gold/symtab.h b/gold/symtab.h
index 9413360..6f47c5e 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -526,7 +526,8 @@ class Symbol
   {
     return (this->is_undefined()
 	    && (this->binding() == elfcpp::STB_WEAK
-		|| this->is_undef_binding_weak()));
+		|| this->is_undef_binding_weak()
+		|| parameters->options().weak_unresolved_symbols()));
   }
 
   // Return whether this is a strong undefined symbol.
@@ -535,7 +536,8 @@ class Symbol
   {
     return (this->is_undefined()
 	    && this->binding() != elfcpp::STB_WEAK
-	    && !this->is_undef_binding_weak());
+	    && !this->is_undef_binding_weak()
+	    && !parameters->options().weak_unresolved_symbols());
   }
 
   // Return whether this is an absolute symbol.
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index c57b2b3..e47174d 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -533,6 +533,11 @@ pie_copyrelocs_shared_test.o: pie_copyrelocs_shared_test.cc
 pie_copyrelocs_shared_test.so: pie_copyrelocs_shared_test.o gcctestdir/ld
 	$(CXXLINK) -Bgcctestdir/ -shared pie_copyrelocs_shared_test.o
 
+check_PROGRAMS += weak_unresolved_symbols_test
+weak_unresolved_symbols_test_SOURCES = weak_unresolved_symbols_test.cc
+weak_unresolved_symbols_test_CXXFLAGS = -fPIE
+weak_unresolved_symbols_test_LDFLAGS = -Bgcctestdir/ -pie -Wl,--weak-unresolved-symbols
+
 check_SCRIPTS += two_file_shared.sh
 check_DATA += two_file_shared.dbg
 MOSTLYCLEANFILES += two_file_shared.dbg
--- /dev/null
+++ b/gold/testsuite/weak_unresolved_symbols_test.cc
@@ -0,0 +1,45 @@
+// weak_unresolved_symbols_test.cc -- a test case for gold
+
+// Copyright (C) 2014-2015 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.
+
+// Test --weak-unresolved-symbols.  Symbol foo remains unresolved but
+// with -fPIE, needs a GOT entry and has a dynsym entry and a dynamic
+// relocation against it created.  This  will fail to link and run without
+// --weak-unresolved-symbols.  With --warn-unresolved-symbols, it will link
+// but the dynamic linker will complain that foo(_Z3foov) is unresolved.
+
+extern int foo();
+
+int bar() {
+  return 0;
+}
+
+int (*p)() = &bar;
+
+int main() {
+  if (p == &foo)
+    {
+      foo();
+    }
+  else
+    (*p)();
+  return 0;
+}


More information about the Binutils mailing list