Fix case where IR file provides symbol visibility but replacement file does not. In PR 22868, two IR files provide conflicting visibility for a symbol. When a def with PROTECTED visibility is seen after a def with DEFAULT visibility, gold does not override the visibility. Later, if the replacement object define the symbol with DEFAULT visibility, the symbol remains DEFAULT. This was caused by a recent change to allow multiply-defined absolute symbols, combined with the fact that the plugin framework was using SHN_ABS as the section index for placeholder symbols. The solution is to use a real (but arbitrary) section index. 2018-03-26 Cary Coutant gold/ PR gold/22868 * plugin.cc (Sized_pluginobj::do_add_symbols): Use a real section index instead of SHN_ABS for defined symbols. * testsuite/Makefile.am (plugin_pr22868): New test case. * testsuite/Makefile.in: Regenerate * testsuite/plugin_pr22868.sh: New test script. * testsuite/plugin_pr22868_a.c: New source file. * testsuite/plugin_pr22868_b.c: New source file. commit d4d2bace826b9ea2d2ffca16764714b0e9805a24 Author: Cary Coutant Date: Fri Mar 23 09:03:34 2018 -0700 WIP: Add testcase for PR 22868. diff --git a/gold/plugin.cc b/gold/plugin.cc index c921f7ca3d..3415b914ad 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -1424,7 +1424,8 @@ Sized_pluginobj::do_add_symbols(Symbol_table* symtab, { case LDPK_DEF: case LDPK_WEAKDEF: - shndx = elfcpp::SHN_ABS; + // We use an arbitrary section number for a defined symbol. + shndx = 1; break; case LDPK_COMMON: shndx = elfcpp::SHN_COMMON; diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index a732b53b45..cf0b970eaa 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -2469,6 +2469,27 @@ plugin_section_alignment.so: plugin_section_alignment.o gcctestdir/ld plugin_section_alignment.o: plugin_section_alignment.cc $(CXXCOMPILE) -O0 -c -fpic -o $@ $< +check_SCRIPTS += plugin_pr22868.sh +check_DATA += plugin_pr22868.stdout +MOSTLYCLEANFILES += plugin_pr22868.stdout +plugin_pr22868.stdout: plugin_pr22868.so + $(TEST_READELF) -W --dyn-syms $< >$@ 2>/dev/null +plugin_pr22868.so: plugin_pr22868_a.o.syms plugin_pr22868_b.o.syms plugin_pr22868_b.o plugin_test.so gcctestdir/ld + $(LINK) -Bgcctestdir/ -shared -Wl,--plugin,"./plugin_test.so" plugin_pr22868_a.o.syms plugin_pr22868_b.o.syms +plugin_pr22868_a.o.syms: plugin_pr22868_a.o + $(TEST_READELF) -sW $< >$@ 2>/dev/null +# Generate the .syms file from an alternate version of the original source +# file, with a "protected" visibility attribute. We'll link with a +# "replacement" object that does not have that attribute. +plugin_pr22868_b.o.syms: plugin_pr22868_b_ir.o + $(TEST_READELF) -sW $< >$@ 2>/dev/null +plugin_pr22868_a.o: plugin_pr22868_a.c + $(COMPILE) -c -fpic -o $@ $< +plugin_pr22868_b_ir.o: plugin_pr22868_b.c + $(COMPILE) -c -DIR -fpic -o $@ $< +plugin_pr22868_b.o: plugin_pr22868_b.c + $(COMPILE) -c -fpic -o $@ $< + endif PLUGINS check_PROGRAMS += exclude_libs_test diff --git a/gold/testsuite/plugin_pr22868.sh b/gold/testsuite/plugin_pr22868.sh new file mode 100755 index 0000000000..72f364b9a2 --- /dev/null +++ b/gold/testsuite/plugin_pr22868.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +# plugin_pr22868.sh -- a test case for the plugin API. + +# Copyright (C) 2018 Free Software Foundation, Inc. +# Written by Cary Coutant . + +# 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 file goes with plugin_pr22868_a.c and plugin_pr22868_b.c, +# which check that if a symbol is declared PROTECTED in any IR file, +# it will remain PROTECTED in the output even if the replacement file(s) +# fail to declare it PROTECTED. + +check() +{ + if ! grep -q "$2" "$1" + then + echo "Did not find expected output in $1:" + echo " $2" + echo "" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check plugin_pr22868.stdout "PROTECTED.*foo" + +exit 0 diff --git a/gold/testsuite/plugin_pr22868_a.c b/gold/testsuite/plugin_pr22868_a.c new file mode 100644 index 0000000000..86a9843287 --- /dev/null +++ b/gold/testsuite/plugin_pr22868_a.c @@ -0,0 +1,28 @@ +/* plugin_pr22868_a.c -- a test case for the plugin API with GC. + + Copyright (C) 2018 Free Software Foundation, Inc. + Written by Cary Coutant . + + 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. */ + +int foo(int i) __attribute__ (( weak )); + +int foo(int i) +{ + return i + 1; +} diff --git a/gold/testsuite/plugin_pr22868_b.c b/gold/testsuite/plugin_pr22868_b.c new file mode 100644 index 0000000000..92d2145b2d --- /dev/null +++ b/gold/testsuite/plugin_pr22868_b.c @@ -0,0 +1,39 @@ +/* plugin_pr22868_b_ir.c -- a test case for the plugin API with GC. + + Copyright (C) 2018 Free Software Foundation, Inc. + Written by Cary Coutant . + + 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 file is compiled with -DIR to generate the .syms file, + and without -DIR for use as the replacement object. + The .syms file declares foo with protected visibility, but + the replacement file does not. */ + +#ifdef IR +#define PROTECTED __attribute__ (( visibility ("protected") )) +#else +#define PROTECTED +#endif + +int foo(int i) __attribute__ (( weak )) PROTECTED; + +int foo(int i) +{ + return i + 1; +}