1# Expect script for ld-visibility tests 2# Copyright (C) 2000-2014 Free Software Foundation, Inc. 3# 4# This file is part of the GNU Binutils. 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 3 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19# MA 02110-1301, USA. 20# 21# Written by Ian Lance Taylor (ian@cygnus.com) 22# and H.J. Lu (hjl@gnu.org) 23# 24 25# Make sure that ld can generate ELF shared libraries with visibility. 26 27# This test can only be run on a couple of ELF platforms. 28# Square bracket expressions seem to confuse istarget. 29if { ![istarget hppa*64*-*-hpux*] \ 30 && ![istarget hppa*-*-linux*] \ 31 && ![istarget i?86-*-linux*] \ 32 && ![istarget i?86-*-gnu*] \ 33 && ![istarget *-*-nacl*] \ 34 && ![istarget ia64-*-linux*] \ 35 && ![istarget m68k-*-linux*] \ 36 && ![istarget mips*-*-linux*] \ 37 && ![istarget powerpc*-*-linux*] \ 38 && ![istarget arm*-*-linux*] \ 39 && ![istarget alpha*-*-linux*] \ 40 && ![istarget sparc*-*-linux*] \ 41 && ![istarget s390*-*-linux*] \ 42 && ![istarget sh\[34\]*-*-linux*] \ 43 && ![istarget x86_64-*-linux*] } { 44 return 45} 46 47if { [istarget *-*-linux*aout*] \ 48 || [istarget *-*-linux*oldld*] } { 49 return 50} 51 52set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]] 53foreach t $test_list { 54 # We need to strip the ".d", but can leave the dirname. 55 verbose [file rootname $t] 56 run_dump_test [file rootname $t] 57} 58 59# The remaining tests can only be run if ld generates native executables. 60if ![isnative] then {return} 61 62set tmpdir tmpdir 63set SHCFLAG "" 64set shared_needs_pic "no" 65 66if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { 67 68 # AIX shared libraries do not seem to support useful features, 69 # like overriding the shared library function or letting the 70 # shared library refer to objects defined in the main program. We 71 # avoid testing those features. 72 set SHCFLAG "-DXCOFF_TEST" 73 74 # The AIX 3.2.5 loader appears to randomly fail when loading 75 # shared libraries from NSF mounted partitions, so we avoid any 76 # potential problems by using a local directory. 77 catch {exec /bin/sh -c "echo $$"} pid 78 set tmpdir /usr/tmp/ld.$pid 79 catch "exec mkdir $tmpdir" exec_status 80 81 # On AIX, we need to explicitly export the symbols the shared 82 # library is going to provide, and need. 83 set file [open $tmpdir/xcoff.exp w] 84 puts $file shlibvar1 85 puts $file shlibvar2 86 puts $file shlib_shlibvar1 87 puts $file shlib_shlibvar2 88 puts $file shlib_shlibcall 89 puts $file shlib_shlibcalled 90 puts $file shlib_checkfunptr1 91 puts $file shlib_getfunptr1 92 puts $file shlib_check 93 close $file 94} 95 96if [istarget arm*-*-linux*] { 97 # On ARM section anchors can change the symbol pre-emptability for 98 # non-PIC shared libraries, causing these tests to fail. Turn section 99 # anchors off. 100 set SHCFLAG "-fno-section-anchors" 101 102 # On targets that have MOVW the compiler will emit relocations which 103 # the linker doesn't support when compiling -shared without -fpic. The 104 # test to find out whether we want to XFAIL the non-PIC tests requires 105 # a compile - so we pre-calculate it here. We also note that this can 106 # only affect arm*-*-*eabi* targets as the old ABI doesn't support v7. 107 if [istarget arm*-*-*eabi*] { 108 set file [open $tmpdir/movw-detect.c w] 109 puts $file "void foo(void) { __asm (\"movw r0, #0\"); }" 110 close $file 111 if [run_host_cmd_yesno "$CC" "$CFLAGS -c $tmpdir/movw-detect.c -o $tmpdir/movw-detect.o"] { 112 set shared_needs_pic "yes" 113 } 114 } 115} 116 117set support_protected "no" 118 119if { [istarget *-*-linux*] 120 || [istarget *-*-nacl*] 121 || [istarget *-*-gnu*] } { 122 if [ld_compile "$CC -g $CFLAGS -DPROTECTED_CHECK" $srcdir/$subdir/main.c $tmpdir/main.o] { 123 if [ld_simple_link $CC $tmpdir/main "$tmpdir/main.o"] { 124 catch "exec $tmpdir/main" support_protected 125 } 126 } 127} 128 129# The test procedure. 130proc visibility_test { visibility progname testname main sh1 sh2 dat args } { 131 global CC 132 global srcdir 133 global subdir 134 global exec_output 135 global link_output 136 global host_triplet 137 global tmpdir 138 139 if [llength $args] { set shldflags [lindex $args 0] } else { set shldflags "" } 140 141 # Build the shared library. 142 # On AIX, we need to use an export file. 143 set shared -shared 144 if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { 145 set shared "-bM:SRE -bE:$tmpdir/xcoff.exp" 146 } 147 if {![ld_simple_link $CC $tmpdir/$progname.so "$shared $shldflags $tmpdir/$sh1 $tmpdir/$sh2"]} { 148 if { [ string match $visibility "hidden_undef" ] 149 && [regexp "undefined reference to \`\.?visibility\'" $link_output] 150 && [regexp "undefined reference to \`visibility_var\'" $link_output] } { 151 pass "$testname" 152 } else { if { [ string match $visibility "protected_undef" ] 153 && [regexp "undefined reference to \`\.?visibility\'" $link_output] 154 && [regexp "undefined reference to \`visibility_var\'" $link_output] } { 155 pass "$testname" 156 } else { 157 fail "$testname" 158 }} 159 return 160 } 161 162 # Link against the shared library. Use -rpath so that the 163 # dynamic linker can locate the shared library at runtime. 164 # On AIX, we must include /lib in -rpath, as otherwise the loader 165 # can not find -lc. 166 set rpath $tmpdir 167 if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { 168 set rpath /lib:$tmpdir 169 } 170 if ![ld_simple_link $CC $tmpdir/$progname "-Wl,-rpath,$rpath $tmpdir/$main $tmpdir/$progname.so"] { 171 if { [ string match $visibility "hidden" ] 172 && [regexp "undefined reference to \`\.?visibility\'" $link_output] 173 && [regexp "undefined reference to \`visibility_var\'" $link_output] } { 174 pass "$testname" 175 } else { if { [ string match $visibility "hidden_undef_def" ] 176 && [regexp "undefined reference to \`\.?visibility\'" $link_output] 177 && [regexp "undefined reference to \`visibility_def\'" $link_output] 178 && [regexp "undefined reference to \`\.?visibility_func\'" $link_output] 179 && [regexp "undefined reference to \`visibility_var\'" $link_output] } { 180 pass "$testname" 181 } else { 182 fail "$testname" 183 }} 184 return 185 } 186 187 if { [ string match $visibility "hidden" ] 188 || [ string match $visibility "hidden_undef" ] 189 || [ string match $visibility "protected_undef" ] } { 190 fail "$testname" 191 } 192 193 # Run the resulting program 194 send_log "$tmpdir/$progname >$tmpdir/$progname.out\n" 195 verbose "$tmpdir/$progname >$tmpdir/$progname.out" 196 catch "exec $tmpdir/$progname >$tmpdir/$progname.out" exec_output 197 if ![string match "" $exec_output] then { 198 send_log "$exec_output\n" 199 verbose "$exec_output" 200 fail "$testname" 201 return 202 } 203 204 send_log "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat\n" 205 verbose "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat" 206 catch "exec diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat" exec_output 207 set exec_output [prune_warnings $exec_output] 208 209 if {![string match "" $exec_output]} then { 210 send_log "$exec_output\n" 211 verbose "$exec_output" 212 fail "$testname" 213 return 214 } 215 216 pass "$testname" 217} 218 219proc visibility_run {visibility} { 220 global CC 221 global CFLAGS 222 global SHCFLAG 223 global srcdir 224 global subdir 225 global tmpdir 226 global picflag 227 global target_triplet 228 global support_protected 229 global shared_needs_pic 230 231 if [ string match $visibility "hidden" ] { 232 set VSBCFLAG "-DHIDDEN_TEST" 233 } else { if [ string match $visibility "hidden_normal" ] { 234 set VSBCFLAG "-DHIDDEN_NORMAL_TEST" 235 } else { if [ string match $visibility "hidden_undef" ] { 236 set VSBCFLAG "-DHIDDEN_UNDEF_TEST" 237 } else { if [ string match $visibility "hidden_undef_def" ] { 238 set VSBCFLAG "-DHIDDEN_UNDEF_TEST -DDSO_DEFINE_TEST" 239 } else { if [ string match $visibility "hidden_weak" ] { 240 set VSBCFLAG "-DHIDDEN_WEAK_TEST" 241 } else { if [ string match $visibility "protected" ] { 242 set VSBCFLAG "-DPROTECTED_TEST" 243 } else { if [ string match $visibility "protected_undef" ] { 244 set VSBCFLAG "-DPROTECTED_UNDEF_TEST" 245 } else { if [ string match $visibility "protected_undef_def" ] { 246 set VSBCFLAG "-DPROTECTED_UNDEF_TEST -DDSO_DEFINE_TEST" 247 } else { if [ string match $visibility "protected_weak" ] { 248 set VSBCFLAG "-DPROTECTED_WEAK_TEST" 249 } else { 250 set VSBCFLAG "" 251 }}}}}}}}} 252 253 if { [istarget powerpc*-*-linux*] \ 254 || ( [istarget mips*-*-linux*] && [at_least_gcc_version 4 3] )} { 255 # Testing non-PIC libraries is a waste of effort on any target. 256 # If you don't pass -fpic or -fPIC to gcc, gcc will assume quite 257 # reasonably that you are not compiling for a shared library. 258 # It can then make optimisations that result in shared library 259 # functions and variables not being overridable. Newer versions 260 # of gcc are more likely to do this. 261 } else { 262 # Compile the main program. 263 if ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG" $srcdir/$subdir/main.c $tmpdir/mainnp.o] { 264 unresolved "visibility ($visibility) (non PIC)" 265 unresolved "visibility ($visibility)" 266 } else { 267 # The shared library is composed of two files. First compile them 268 # without using -fpic. That should work on an ELF system, 269 # although it will be less efficient because the dynamic linker 270 # will need to do more relocation work. However, note that not 271 # using -fpic will cause some of the tests to return different 272 # results. 273 if { ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG" $srcdir/$subdir/sh1.c $tmpdir/sh1np.o] 274 || ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG" $srcdir/$subdir/sh2.c $tmpdir/sh2np.o] } { 275 unresolved "visibility ($visibility) (non PIC)" 276 } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { 277 visibility_test $visibility vnp "visibility ($visibility) (non PIC)" mainnp.o sh1np.o sh2np.o xcoff 278 } else { 279 # SunOS non PIC shared libraries don't permit some cases of 280 # overriding. 281 if { [ string match $visibility "protected" ] 282 || [ string match $visibility "protected_undef_def" ] } { 283 if [ string match $support_protected "no" ] { 284 setup_xfail $target_triplet 285 } 286 } else { 287 setup_xfail "*-*-sunos4*" 288 } 289 290 # Non-pic code uses name binding rules for applications to 291 # reference variables by gp-relative relocs, which can't be 292 # used with overridable symbols. 293 if { ![ string match $visibility "hidden_undef" ] 294 && ![ string match $visibility "protected_undef" ] } { 295 setup_xfail "ia64-*-linux*" 296 setup_xfail "alpha*-*-linux*" 297 } 298 if { ![ string match $visibility "hidden" ] 299 && ![ string match $visibility "hidden_undef" ] 300 && ![ string match $visibility "hidden_undef_def" ] 301 && ![ string match $visibility "protected_undef" ] } { 302 setup_xfail "s390x-*-linux*" 303 if { [istarget sparc*-*-linux*] && [is_elf64 $tmpdir/mainnp.o] } { 304 setup_xfail "sparc*-*-linux*" 305 } 306 } 307 if { [is_elf64 $tmpdir/mainnp.o] } { 308 setup_xfail "x86_64-*-linux*" 309 } 310 setup_xfail "x86_64-*-linux-gnux32" 311 if { ![istarget hppa*64*-*-linux*] } { 312 setup_xfail "hppa*-*-linux*" 313 } 314 if [ string match $shared_needs_pic "yes" ] { 315 setup_xfail "arm*-*-linux*" 316 } 317 318 visibility_test $visibility vnp "visibility ($visibility) (non PIC)" mainnp.o sh1np.o sh2np.o elfvsb 319 320 # Test ELF shared library relocations with a non-zero load 321 # address for the library. Near as I can tell, the R_*_RELATIVE 322 # relocations for various targets are broken in the case where 323 # the load address is not zero (which is the default). 324 if { [ string match $visibility "protected" ] 325 || [ string match $visibility "protected_undef_def" ] } { 326 if [ string match $support_protected "no" ] { 327 setup_xfail $target_triplet 328 } 329 } else { 330 setup_xfail "*-*-sunos4*" 331 setup_xfail "*-*-linux*libc1" 332 } 333 if { [ string match $visibility "hidden_normal" ] 334 || [ string match $visibility "hidden_weak" ] 335 || [ string match $visibility "protected" ] 336 || [ string match $visibility "protected_undef_def" ] 337 || [ string match $visibility "protected_weak" ] 338 || [ string match $visibility "normal" ] } { 339 setup_xfail "powerpc-*-linux*" 340 setup_xfail "s390x-*-linux*" 341 if { [istarget sparc*-*-linux*] && [is_elf64 $tmpdir/mainnp.o] } { 342 setup_xfail "sparc*-*-linux*" 343 } 344 } 345 if { ![ string match $visibility "hidden_undef" ] 346 && ![ string match $visibility "protected_undef" ] } { 347 setup_xfail "ia64-*-linux*" 348 setup_xfail "alpha*-*-linux*" 349 setup_xfail "mips*-*-linux*" 350 } 351 if { [is_elf64 $tmpdir/mainnp.o] } { 352 setup_xfail "x86_64-*-linux*" 353 } 354 setup_xfail "x86_64-*-linux-gnux32" 355 if { ![istarget hppa*64*-*-linux*] } { 356 setup_xfail "hppa*-*-linux*" 357 } 358 if [ string match $shared_needs_pic "yes" ] { 359 setup_xfail "arm*-*-linux*" 360 } 361 362 visibility_test $visibility vnp "visibility ($visibility) (non PIC, load offset)" \ 363 mainnp.o sh1np.o sh2np.o elfvsb \ 364 "-T $srcdir/$subdir/elf-offset.ld" 365 } } 366 367 # Now compile the code using -fpic. 368 369 if { ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG -DSHARED $picflag" $srcdir/$subdir/sh1.c $tmpdir/sh1p.o] 370 || ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG -DSHARED $picflag" $srcdir/$subdir/sh2.c $tmpdir/sh2p.o] } { 371 unresolved "visibility ($visibility)" 372 } else { 373 if { [ string match $visibility "protected" ] 374 || [ string match $visibility "protected_undef_def" ] } { 375 if [ string match $support_protected "no" ] { 376 setup_xfail $target_triplet 377 } 378 } 379 # SunOS can not compare function pointers correctly 380 if [istarget "*-*-sunos4*"] { 381 visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o sun4 382 } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { 383 visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o xcoff 384 } else { 385 visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o elfvsb 386 } } 387 } 388 }} 389 390 if { [istarget powerpc*-*-linux*] } { 391 # Don't bother. 392 } else { 393 # Now do the same tests again, but this time compile main.c PIC. 394 if ![ld_compile "$CC -g $CFLAGS $SHCFLAG $VSBCFLAG -DSHARED $picflag" $srcdir/$subdir/main.c $tmpdir/mainp.o] { 395 unresolved "visibility ($visibility) (PIC main, non PIC so)" 396 unresolved "visibility ($visibility) (PIC main)" 397 } else { 398 if { [file exists $tmpdir/sh1np.o ] && [ file exists $tmpdir/sh2np.o ] } { 399 if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { 400 visibility_test $visibility vmpnp "visibility ($visibility) (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o xcoff 401 } else { 402 # SunOS non PIC shared libraries don't permit some cases of 403 # overriding. 404 if { [ string match $visibility "protected" ] 405 || [ string match $visibility "protected_undef_def" ] } { 406 if [ string match $support_protected "no" ] { 407 setup_xfail $target_triplet 408 } 409 } else { 410 setup_xfail "*-*-sunos4*" 411 } 412 if { ![ string match $visibility "hidden_undef" ] 413 && ![ string match $visibility "protected_undef" ] } { 414 setup_xfail "ia64-*-linux*" 415 setup_xfail "alpha*-*-linux*" 416 } 417 if { ![ string match $visibility "hidden" ] 418 && ![ string match $visibility "hidden_undef" ] 419 && ![ string match $visibility "hidden_undef_def" ] 420 && ![ string match $visibility "protected_undef" ] } { 421 setup_xfail "s390x-*-linux*" 422 if { [istarget sparc*-*-linux*] && [is_elf64 $tmpdir/mainp.o] } { 423 setup_xfail "sparc*-*-linux*" 424 } 425 } 426 if { [is_elf64 $tmpdir/mainp.o] } { 427 setup_xfail "x86_64-*-linux*" 428 } 429 setup_xfail "x86_64-*-linux-gnux32" 430 if { ![istarget hppa*64*-*-linux*] } { 431 setup_xfail "hppa*-*-linux*" 432 } 433 if [ string match $shared_needs_pic "yes" ] { 434 setup_xfail "arm*-*-linux*" 435 } 436 437 visibility_test $visibility vmpnp "visibility ($visibility) (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o elfvsb 438 } 439 } else { 440 unresolved "visibility (PIC main, non PIC so)" 441 } 442 443 if { [file exists $tmpdir/sh1p.o ] && [ file exists $tmpdir/sh2p.o ] } { 444 if { [ string match $visibility "protected" ] 445 || [ string match $visibility "protected_undef_def" ] } { 446 if [ string match $support_protected "no" ] { 447 setup_xfail $target_triplet 448 } 449 } 450 if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { 451 visibility_test $visibility vmpp "visibility ($visibility) (PIC main)" mainp.o sh1p.o sh2p.o xcoff 452 } else { 453 visibility_test $visibility vmpp "visibility ($visibility) (PIC main)" mainp.o sh1p.o sh2p.o elfvsb 454 } 455 } else { 456 unresolved "visibility ($visibility) (PIC main)" 457 } 458 }} 459} 460 461# Old version of GCC for MIPS default to enabling -fpic 462# and get confused if it is used on the command line. 463if { [istarget mips*-*-*] && ! [at_least_gcc_version 4 3] } then { 464 set picflag "" 465} else { 466 # Unfortunately, the gcc argument is -fpic and the cc argument is 467 # -KPIC. We have to try both. 468 set picflag "-fpic" 469 send_log "$CC $picflag\n" 470 verbose "$CC $picflag" 471 catch "exec $CC $picflag" exec_output 472 send_log "$exec_output\n" 473 verbose "--" "$exec_output" 474 if { [string match "*illegal option*" $exec_output] \ 475 || [string match "*option ignored*" $exec_output] \ 476 || [string match "*unrecognized option*" $exec_output] \ 477 || [string match "*passed to ld*" $exec_output] } { 478 if [istarget *-*-sunos4*] { 479 set picflag "-pic" 480 } else { 481 set picflag "-KPIC" 482 } 483 } 484} 485verbose "Using $picflag to compile PIC code" 486 487visibility_run hidden 488visibility_run hidden_normal 489visibility_run hidden_undef 490visibility_run hidden_undef_def 491visibility_run hidden_weak 492visibility_run protected 493visibility_run protected_undef 494visibility_run protected_undef_def 495visibility_run protected_weak 496visibility_run normal 497 498if { ![ld_compile "$CC -g $CFLAGS" $srcdir/$subdir/common.c tmpdir/common.o] } { 499 unresolved "common hidden symbol" 500} else { 501 if ![ld_simple_link $ld tmpdir/common "tmpdir/common.o"] { 502 fail "common hidden symbol" 503 } else { 504 pass "common hidden symbol" 505 } 506} 507 508if { ![ld_compile "$CC -g $CFLAGS" $srcdir/$subdir/test.c tmpdir/test.o] } { 509 unresolved "weak hidden symbol" 510} else { 511 if { ![ld_compile "$CC -g $CFLAGS -DSHARED $picflag" $srcdir/$subdir/sh3.c tmpdir/sh3.o] } { 512 unresolved "weak hidden symbol" 513 } else { 514 if ![ld_simple_link $ld tmpdir/sh3.so "-shared tmpdir/sh3.o"] { 515 fail "weak hidden symbol" 516 } else { 517 if ![ld_simple_link $ld tmpdir/weak "tmpdir/test.o tmpdir/sh3.o"] { 518 fail "weak hidden symbol DSO last" 519 } else { 520 pass "weak hidden symbol DSO last" 521 } 522 if ![ld_simple_link $ld tmpdir/weak "tmpdir/sh3.so tmpdir/test.o"] { 523 fail "weak hidden symbol DSO first" 524 } else { 525 pass "weak hidden symbol DSO first" 526 } 527 } 528 } 529} 530 531if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } { 532 # Remove the temporary directory. 533 catch "exec rm -rf $tmpdir" exec_status 534} 535