6e33951edc
The hidden versioned symbol can only be merged with the versioned symbol with the same symbol version. _bfd_elf_merge_symbol should check the symbol version before merging the new hidden versioned symbol with the existing symbol. _bfd_elf_link_hash_copy_indirect can't copy any references to the hidden versioned symbol. We need to bind a symbol locally when linking executable if it is locally defined, hidden versioned, not referenced by shared library and not exported. bfd/ PR ld/18720 * elflink.c (_bfd_elf_merge_symbol): Add a parameter to indicate if the new symbol matches the existing one. The new hidden versioned symbol matches the existing symbol if they have the same symbol version. Update the existing symbol only if they match. (_bfd_elf_add_default_symbol): Update call to _bfd_elf_merge_symbol. (_bfd_elf_link_assign_sym_version): Don't set the hidden field here. (elf_link_add_object_symbols): Override a definition only if the new symbol matches the existing one. (_bfd_elf_link_hash_copy_indirect): Don't copy any references to the hidden versioned symbol. (elf_link_output_extsym): Bind a symbol locally when linking executable if it is locally defined, hidden versioned, not referenced by shared library and not exported. Turn on VERSYM_HIDDEN only if the hidden vesioned symbol is defined locally. ld/testsuite/ PR ld/18720 * ld-elf/indirect.exp: Run tests for PR ld/18720. * ld-elf/pr18720.out: New file. * ld-elf/pr18720a.c: Likewise. * ld-elf/pr18720b.c: Likewise. * ld-elf/pr18720c.c: Likewise.
160 lines
5.7 KiB
Text
160 lines
5.7 KiB
Text
# Expect script for various indirect symbol tests.
|
|
# Copyright (C) 2012-2015 Free Software Foundation, Inc.
|
|
#
|
|
# This file 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 2 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.
|
|
#
|
|
|
|
#
|
|
# Written by H.J. Lu (hongjiu.lu@intel.com)
|
|
#
|
|
|
|
# Exclude non-ELF targets.
|
|
|
|
if ![is_elf_format] {
|
|
return
|
|
}
|
|
|
|
# Skip target where -shared is not supported
|
|
|
|
if ![check_shared_lib_support] {
|
|
return
|
|
}
|
|
|
|
# Check if compiler works
|
|
if { [which $CC] == 0 } {
|
|
return
|
|
}
|
|
|
|
# Some bare-metal targets don't support shared libs or PIC.
|
|
if { ![run_host_cmd_yesno $CC "-shared -fPIC $srcdir/$subdir/dummy.c -o tmpdir/t.so"] } {
|
|
return
|
|
}
|
|
|
|
proc check_link_message { cmd string testname } {
|
|
send_log "$cmd\n"
|
|
verbose "$cmd"
|
|
catch "exec $cmd" exec_output
|
|
send_log "$exec_output\n"
|
|
verbose "$exec_output"
|
|
|
|
foreach str $string {
|
|
if [string match "*$str*" $exec_output] {
|
|
pass "$testname: $str"
|
|
} else {
|
|
fail "$testname: $str"
|
|
}
|
|
}
|
|
}
|
|
|
|
if { ![ld_compile $CC $srcdir/$subdir/indirect1a.c tmpdir/indirect1a.o]
|
|
|| ![ld_compile $CC $srcdir/$subdir/indirect1b.c tmpdir/indirect1b.o]
|
|
|| ![ld_compile "$CC -fPIC" $srcdir/$subdir/indirect2.c tmpdir/indirect2.o]
|
|
|| ![ld_compile $CC $srcdir/$subdir/indirect3a.c tmpdir/indirect3a.o]
|
|
|| ![ld_compile $CC $srcdir/$subdir/indirect3b.c tmpdir/indirect3b.o]
|
|
|| ![ld_compile $CC $srcdir/$subdir/indirect4a.c tmpdir/indirect4a.o]
|
|
|| ![ld_compile $CC $srcdir/$subdir/indirect4b.c tmpdir/indirect4b.o]
|
|
|| ![ld_compile "$CC -O2 -fPIC -I../bfd" $srcdir/$subdir/pr18720a.c tmpdir/pr18720a.o]
|
|
|| ![ld_compile $CC $srcdir/$subdir/pr18720b.c tmpdir/pr18720b.o] } {
|
|
unresolved "Indirect symbol tests"
|
|
return
|
|
}
|
|
|
|
set build_tests {
|
|
{"Build libindirect1c.so"
|
|
"-shared" "-fPIC"
|
|
{indirect1c.c} {} "libindirect1c.so"}
|
|
{"Build libindirect3c.so"
|
|
"-shared" "-fPIC"
|
|
{indirect3c.c} {} "libindirect3c.so"}
|
|
{"Build libindirect4c.so"
|
|
"-shared" "-fPIC"
|
|
{indirect4c.c} {} "libindirect4c.so"}
|
|
{"Build libpr18720c.so"
|
|
"-shared" "-fPIC"
|
|
{pr18720c.c} {} "libpr18720c.so"}
|
|
{"Build pr18720b1.o"
|
|
"-r -nostdlib tmpdir/pr18720b.o" ""
|
|
{dummy.c} {} "pr18720b1.o"}
|
|
}
|
|
|
|
run_cc_link_tests $build_tests
|
|
|
|
global ld
|
|
|
|
set string ": final link failed: Bad value"
|
|
set string1 ": local symbol \`foo\' in tmpdir/indirect1b.o is referenced by DSO"
|
|
|
|
set testname "Indirect symbol 1a"
|
|
set cmd "$ld -e start -o tmpdir/indirect1 tmpdir/indirect1a.o tmpdir/indirect1b.o tmpdir/libindirect1c.so"
|
|
check_link_message "$cmd" [list $string1 $string] "$testname"
|
|
|
|
set testname "Indirect symbol 1b"
|
|
set cmd "$ld -e start -o tmpdir/indirect1 tmpdir/indirect1a.o tmpdir/libindirect1c.so tmpdir/indirect1b.o"
|
|
check_link_message "$cmd" [list $string1 $string] "$testname"
|
|
|
|
set string ": final link failed: Nonrepresentable section on output"
|
|
set string2 ": No symbol version section for versioned symbol \`foo@FOO\'"
|
|
set testname "Indirect symbol 2"
|
|
set cmd "$ld -shared -o tmpdir/indirect2.so tmpdir/indirect2.o"
|
|
check_link_message "$cmd" [list $string2 $string] "$testname"
|
|
|
|
# The following tests require running the executable generated by ld.
|
|
if ![isnative] {
|
|
return
|
|
}
|
|
|
|
set run_tests {
|
|
{"Run with libindirect3c.so 1"
|
|
"tmpdir/indirect3a.o tmpdir/indirect3b.o tmpdir/libindirect3c.so" ""
|
|
{dummy.c} "indirect3a" "indirect3.out"}
|
|
{"Run with libindirect3c.so 2"
|
|
"tmpdir/indirect3a.o tmpdir/libindirect3c.so tmpdir/indirect3b.o" ""
|
|
{dummy.c} "indirect3b" "indirect3.out"}
|
|
{"Run with libindirect3c.so 3"
|
|
"tmpdir/indirect3b.o tmpdir/libindirect3c.so tmpdir/indirect3a.o" ""
|
|
{dummy.c} "indirect3c" "indirect3.out"}
|
|
{"Run with libindirect3c.so 4"
|
|
"tmpdir/libindirect3c.so tmpdir/indirect3b.o tmpdir/indirect3a.o" ""
|
|
{dummy.c} "indirect3d" "indirect3.out"}
|
|
{"Run with libindirect4c.so 1"
|
|
"tmpdir/indirect4a.o tmpdir/indirect4b.o tmpdir/libindirect4c.so" ""
|
|
{dummy.c} "indirect4a" "indirect4.out"}
|
|
{"Run with libindirect4c.so 2"
|
|
"tmpdir/indirect4a.o tmpdir/libindirect4c.so tmpdir/indirect4b.o" ""
|
|
{dummy.c} "indirect4b" "indirect4.out"}
|
|
{"Run with libindirect4c.so 3"
|
|
"tmpdir/indirect4b.o tmpdir/libindirect4c.so tmpdir/indirect4a.o" ""
|
|
{dummy.c} "indirect4c" "indirect4.out"}
|
|
{"Run with libindirect4c.so 4"
|
|
"tmpdir/libindirect4c.so tmpdir/indirect4b.o tmpdir/indirect4a.o" ""
|
|
{dummy.c} "indirect4d" "indirect4.out"}
|
|
{"Run with libpr18720c.so 1"
|
|
"tmpdir/pr18720a.o tmpdir/pr18720b.o tmpdir/libpr18720c.so" ""
|
|
{check-ptr-eq.c} "pr18720a" "pr18720.out"}
|
|
{"Run with libpr18720c.so 2"
|
|
"tmpdir/pr18720a.o tmpdir/libpr18720c.so tmpdir/pr18720b.o" ""
|
|
{check-ptr-eq.c} "pr18720b" "pr18720.out"}
|
|
{"Run with libpr18720c.so 3"
|
|
"tmpdir/pr18720b.o tmpdir/libpr18720c.so tmpdir/pr18720a.o" ""
|
|
{check-ptr-eq.c} "pr18720c" "pr18720.out"}
|
|
{"Run with libpr18720c.so 4"
|
|
"tmpdir/libpr18720c.so tmpdir/pr18720b.o tmpdir/pr18720a.o" ""
|
|
{check-ptr-eq.c} "pr18720d" "pr18720.out"}
|
|
{"Run with libpr18720c.so 5"
|
|
"tmpdir/libpr18720c.so tmpdir/pr18720b1.o tmpdir/pr18720a.o" ""
|
|
{check-ptr-eq.c} "pr18720d" "pr18720.out"}
|
|
}
|
|
|
|
run_ld_link_exec_tests [] $run_tests
|