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::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 . + +// 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; +}