diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2012-07-03 14:44:35 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2012-07-03 14:44:35 +0000 |
commit | 90c984fc53ae23dcda0cba309ad4b51a9dd5d9ee (patch) | |
tree | a2dac07d507762cbaaa7f2a34d932618a2f8160d /ld | |
parent | 3146fac42836137f284d541266ece045d56b5895 (diff) | |
download | gdb-90c984fc53ae23dcda0cba309ad4b51a9dd5d9ee.zip gdb-90c984fc53ae23dcda0cba309ad4b51a9dd5d9ee.tar.gz gdb-90c984fc53ae23dcda0cba309ad4b51a9dd5d9ee.tar.bz2 |
Properly handle indirect symbols
2012-07-03 H.J. Lu <hongjiu.lu@intel.com>
PR ld/3351
* elflink.c (_bfd_elf_update_dynamic_flags): New.
(_bfd_elf_merge_symbol): Update both real and indirect symbol
dynamic flags.
(_bfd_elf_add_default_symbol): Make the real symbol dynamic if
the indirect symbol is defined in a shared library.
(elf_link_add_object_symbols): Likewise. If the indirect
symbol has been forced local, don't make the real symbol
dynamic.
(elf_link_check_versioned_symbol): Check indirect symbol.
(elf_link_output_extsym): Use real symbol definition when
reporting indirect symbol error. Check version info for
dynamic versioned symbol.
2012-07-03 H.J. Lu <hongjiu.lu@intel.com>
PR ld/3351
* ld-elf/indirect.exp: New file.
* ld-elf/indirect1a.c: Likewise.
* ld-elf/indirect1b.c: Likewise.
* ld-elf/indirect1c.c: Likewise.
* ld-elf/indirect2.c: Likewise.
* ld-elf/indirect3.out: Likewise.
* ld-elf/indirect3a.c: Likewise.
* ld-elf/indirect3b.c: Likewise.
* ld-elf/indirect3c.c: Likewise.
* ld-elf/indirect4.out: Likewise.
* ld-elf/indirect4a.c: Likewise.
* ld-elf/indirect4b.c: Likewise.
* ld-elf/indirect4c.c: Likewise.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/testsuite/ChangeLog | 17 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect.exp | 126 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect1a.c | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect1b.c | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect1c.c | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect2.c | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect3.out | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect3a.c | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect3b.c | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect3c.c | 15 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect4.out | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect4a.c | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect4b.c | 17 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/indirect4c.c | 15 |
14 files changed, 253 insertions, 0 deletions
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index da46574..c1cfb34 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,20 @@ +2012-07-03 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/3351 + * ld-elf/indirect.exp: New file. + * ld-elf/indirect1a.c: Likewise. + * ld-elf/indirect1b.c: Likewise. + * ld-elf/indirect1c.c: Likewise. + * ld-elf/indirect2.c: Likewise. + * ld-elf/indirect3.out: Likewise. + * ld-elf/indirect3a.c: Likewise. + * ld-elf/indirect3b.c: Likewise. + * ld-elf/indirect3c.c: Likewise. + * ld-elf/indirect4.out: Likewise. + * ld-elf/indirect4a.c: Likewise. + * ld-elf/indirect4b.c: Likewise. + * ld-elf/indirect4c.c: Likewise. + 2012-07-02 Roland McGrath <mcgrathr@google.com> * ld/testsuite/ld-i386/tlsbin-nacl.rd: Update for symbol table changes. diff --git a/ld/testsuite/ld-elf/indirect.exp b/ld/testsuite/ld-elf/indirect.exp new file mode 100644 index 0000000..165f89a --- /dev/null +++ b/ld/testsuite/ld-elf/indirect.exp @@ -0,0 +1,126 @@ +# Expect script for various indirect symbol tests. +# Copyright 2012 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 +} + +# Check if compiler works +if { [which $CC] == 0 } { + 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] } { + 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"} +} + +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_ld_link_exec_tests [] $run_tests diff --git a/ld/testsuite/ld-elf/indirect1a.c b/ld/testsuite/ld-elf/indirect1a.c new file mode 100644 index 0000000..6931542 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect1a.c @@ -0,0 +1,8 @@ +extern void bar (void); + +int +start (void) +{ + bar (); + return 0; +} diff --git a/ld/testsuite/ld-elf/indirect1b.c b/ld/testsuite/ld-elf/indirect1b.c new file mode 100644 index 0000000..51740f9 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect1b.c @@ -0,0 +1,6 @@ +void +foo (void) +{ +} + +asm (".symver foo,foo@FOO"); diff --git a/ld/testsuite/ld-elf/indirect1c.c b/ld/testsuite/ld-elf/indirect1c.c new file mode 100644 index 0000000..eae278d --- /dev/null +++ b/ld/testsuite/ld-elf/indirect1c.c @@ -0,0 +1,7 @@ +extern void foo (void); + +void +bar (void) +{ + foo (); +} diff --git a/ld/testsuite/ld-elf/indirect2.c b/ld/testsuite/ld-elf/indirect2.c new file mode 100644 index 0000000..6df29be --- /dev/null +++ b/ld/testsuite/ld-elf/indirect2.c @@ -0,0 +1,9 @@ +extern void foo (void); + +asm (".symver foo,foo@@@FOO"); + +void +bar (void) +{ + foo (); +} diff --git a/ld/testsuite/ld-elf/indirect3.out b/ld/testsuite/ld-elf/indirect3.out new file mode 100644 index 0000000..482e981 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect3.out @@ -0,0 +1,2 @@ +MAIN +DSO diff --git a/ld/testsuite/ld-elf/indirect3a.c b/ld/testsuite/ld-elf/indirect3a.c new file mode 100644 index 0000000..0f6ddc8 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect3a.c @@ -0,0 +1,10 @@ +extern void bar (void); +extern void foo (void); + +int +main (void) +{ + foo (); + bar (); + return 0; +} diff --git a/ld/testsuite/ld-elf/indirect3b.c b/ld/testsuite/ld-elf/indirect3b.c new file mode 100644 index 0000000..dbb37c3 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect3b.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +void +foo (void) +{ + printf ("MAIN\n"); +} + +asm (".symver foo,foo@FOO"); diff --git a/ld/testsuite/ld-elf/indirect3c.c b/ld/testsuite/ld-elf/indirect3c.c new file mode 100644 index 0000000..b52cb95 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect3c.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +extern void foo (void); + +void +foo (void) +{ + printf ("DSO\n"); +} + +void +bar (void) +{ + foo (); +} diff --git a/ld/testsuite/ld-elf/indirect4.out b/ld/testsuite/ld-elf/indirect4.out new file mode 100644 index 0000000..3b34ee4 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect4.out @@ -0,0 +1,2 @@ +MAIN2 +MAIN2 diff --git a/ld/testsuite/ld-elf/indirect4a.c b/ld/testsuite/ld-elf/indirect4a.c new file mode 100644 index 0000000..0f6ddc8 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect4a.c @@ -0,0 +1,10 @@ +extern void bar (void); +extern void foo (void); + +int +main (void) +{ + foo (); + bar (); + return 0; +} diff --git a/ld/testsuite/ld-elf/indirect4b.c b/ld/testsuite/ld-elf/indirect4b.c new file mode 100644 index 0000000..b8db9d0 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect4b.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +void +foo2 (void) +{ + printf ("MAIN2\n"); +} + +asm (".symver foo2,foo@@FOO2"); + +void +foo1 (void) +{ + printf ("MAIN1\n"); +} + +asm (".symver foo1,foo@FOO1"); diff --git a/ld/testsuite/ld-elf/indirect4c.c b/ld/testsuite/ld-elf/indirect4c.c new file mode 100644 index 0000000..b52cb95 --- /dev/null +++ b/ld/testsuite/ld-elf/indirect4c.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +extern void foo (void); + +void +foo (void) +{ + printf ("DSO\n"); +} + +void +bar (void) +{ + foo (); +} |