1# Expect script for ld-plugin tests 2# Copyright (C) 2010-2016 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# These tests require the plugin API to be configured in. 22if ![check_plugin_api_available] { 23 return 24} 25 26# And a compiler to be available. 27set can_compile 1 28set failure_kind "unresolved" 29if { [which $CC] == 0 } { 30 # Don't fail immediately, 31 set can_compile 0 32 set failure_kind "unsupported" 33} 34 35pass "plugin API enabled" 36 37global base_dir 38 39# Look for the name we can dlopen in the test plugin's libtool control script. 40set plugin_name [file_contents "$base_dir/libldtestplug.la"] 41set plugin_name [regsub "'.*" [regsub ".*dlname='" "$plugin_name" ""] ""] 42# Even though the API supports plugins it does not mean that the 43# linker was configured with --enable-plugins. Check for that here. 44if { $plugin_name == "" } { 45 verbose "The linker is not configured to support plugins" 46 return 47} 48verbose "plugin name is '$plugin_name'" 49 50set plugin2_name [file_contents "$base_dir/libldtestplug2.la"] 51set plugin2_name [regsub "'.*" [regsub ".*dlname='" "$plugin2_name" ""] ""] 52verbose "plugin2 name is '$plugin2_name'" 53 54set plugin3_name [file_contents "$base_dir/libldtestplug3.la"] 55set plugin3_name [regsub "'.*" [regsub ".*dlname='" "$plugin3_name" ""] ""] 56verbose "plugin3 name is '$plugin3_name'" 57 58set plugin4_name [file_contents "$base_dir/libldtestplug4.la"] 59set plugin4_name [regsub "'.*" [regsub ".*dlname='" "$plugin4_name" ""] ""] 60verbose "plugin4 name is '$plugin4_name'" 61 62# Use libtool to find full path to plugin rather than worrying 63# about run paths or anything like that. 64catch "exec $base_dir/libtool --config" lt_config 65verbose "Full lt config: $lt_config" 3 66# Look for "objdir=.libs" 67regexp -line "^objdir=.*$" "$lt_config" lt_objdir 68verbose "lt_objdir line is '$lt_objdir'" 3 69set lt_objdir [regsub "objdir=" "$lt_objdir" ""] 70set plugin_path "$base_dir/$lt_objdir/$plugin_name" 71set plugin2_path "$base_dir/$lt_objdir/$plugin2_name" 72set plugin3_path "$base_dir/$lt_objdir/$plugin3_name" 73set plugin4_path "$base_dir/$lt_objdir/$plugin4_name" 74verbose "Full plugin path $plugin_path" 2 75verbose "Full plugin2 path $plugin2_path" 2 76verbose "Full plugin3 path $plugin3_path" 2 77verbose "Full plugin4 path $plugin4_path" 2 78 79set regclm "-plugin-opt registerclaimfile" 80set regas "-plugin-opt registerallsymbolsread" 81set regassilent "-plugin-opt registerallsymbolsreadsilent" 82set regcln "-plugin-opt registercleanup" 83 84if { [istarget m681*-*-*] || [istarget m68hc1*-*-*] || [istarget m9s12x*-*-*] } { 85 # otherwise get FAILS due to _.frame 86 set CFLAGS "$CFLAGS -fomit-frame-pointer" 87} 88# In order to define symbols in plugin options in the list of tests below, 89# we need to know if the platform prepends an underscore to C symbols, 90# which we find out by compiling the test objects now. If there is any 91# error compiling, we defer reporting it until after the list of tests has 92# been initialised, so that we can use the names in the list to report; 93# otherwise, we scan one of the files with 'nm' and look for a known symbol 94# in the output to see if it is prefixed or not. 95set failed_compile 0 96set _ "" 97set plugin_nm_output "" 98if { $can_compile && \ 99 (![ld_compile "$CC $CFLAGS" $srcdir/$subdir/main.c tmpdir/main.o] \ 100 || ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/func.c tmpdir/func.o] \ 101 || ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/text.c tmpdir/text.o] \ 102 || ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/pr20070a.c tmpdir/pr20070a.o] \ 103 || ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/dummy.s tmpdir/dummy.o] \ 104 || ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/pr17973.s tmpdir/pr17973.o]) } { 105 # Defer fail until we have list of tests set. 106 set failed_compile 1 107} 108 109if { $can_compile && !$failed_compile } { 110 # Find out if symbols have prefix on this platform before setting tests. 111 catch "exec $NM tmpdir/func.o" plugin_nm_output 112 if { [regexp "_func" "$plugin_nm_output"] } { 113 set _ "_" 114 } 115} 116 117set testobjfiles "tmpdir/main.o tmpdir/func.o tmpdir/text.o" 118set testobjfiles_notext "tmpdir/main.o tmpdir/func.o" 119set testsrcfiles "tmpdir/main.o $srcdir/$subdir/func.c tmpdir/text.o" 120set testsrcfiles_notext "tmpdir/main.o $srcdir/$subdir/func.c" 121# Rather than having libs we just define dummy values for anything 122# we may need to link a target exe; we aren't going to run it anyway. 123set libs "[ld_simple_link_defsyms] --defsym ${_}printf=${_}main --defsym ${_}puts=${_}main" 124 125set plugin_tests [list \ 126 [list "load plugin" "-plugin $plugin_path \ 127 $testobjfiles $libs" "" "" "" {{ld plugin-1.d}} "main.x" ] \ 128 [list "fail plugin onload" "-plugin $plugin_path -plugin-opt failonload \ 129 $testobjfiles $libs" "" "" "" {{ld plugin-2.d}} "main.x" ] \ 130 [list "fail plugin allsymbolsread" "-plugin $plugin_path $regas \ 131 -plugin-opt failallsymbolsread \ 132 $testobjfiles $libs" "" "" "" {{ld plugin-3.d}} "main.x" ] \ 133 [list "fail plugin cleanup" "-plugin $plugin_path -plugin-opt failcleanup \ 134 $regcln \ 135 $testobjfiles $libs" "" "" "" {{ld plugin-4.d}} "main.x" ] \ 136 [list "plugin all hooks" "-plugin $plugin_path $regclm $regas $regcln \ 137 $testobjfiles $libs" "" "" "" {{ld plugin-5.d}} "main.x" ] \ 138 [list "plugin claimfile lost symbol" "-plugin $plugin_path $regclm \ 139 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 140 $testobjfiles $libs" "" "" "" {{ld plugin-6.d}} "main.x" ] \ 141 [list "plugin claimfile replace symbol" "-plugin $plugin_path $regclm \ 142 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 143 -plugin-opt sym:${_}func::0:0:0 \ 144 $testobjfiles $libs" "" "" "" {{ld plugin-7.d}} "main.x" ] \ 145 [list "plugin claimfile resolve symbol" "-plugin $plugin_path $regclm \ 146 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 147 -plugin-opt sym:${_}func::0:0:0 \ 148 -plugin-opt sym:${_}func2::0:0:0 \ 149 -plugin-opt dumpresolutions \ 150 $testobjfiles $libs" "" "" "" {{ld plugin-8.d}} "main.x" ] \ 151 [list "plugin claimfile replace file" "-plugin $plugin_path $regclm \ 152 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 153 -plugin-opt sym:${_}func::0:0:0 \ 154 -plugin-opt sym:${_}func2::0:0:0 \ 155 -plugin-opt dumpresolutions \ 156 -plugin-opt add:tmpdir/func.o \ 157 $testobjfiles $libs" "" "" "" {{ld plugin-9.d}} "main.x" ] \ 158 [list "load plugin with source" "-plugin $plugin_path $regclm \ 159 -plugin-opt claim:$srcdir/$subdir/func.c \ 160 $testsrcfiles $libs" "" "" "" {{ld plugin-13.d}} "main.x" ] \ 161 [list "plugin claimfile lost symbol with source" \ 162 "-plugin $plugin_path $regclm $regas $regcln \ 163 -plugin-opt claim:$srcdir/$subdir/func.c \ 164 $testsrcfiles $libs" "" "" "" {{ld plugin-14.d}} "main.x" ] \ 165 [list "plugin claimfile replace symbol with source" \ 166 "-plugin $plugin_path $regclm $regas $regcln \ 167 -plugin-opt claim:$srcdir/$subdir/func.c \ 168 -plugin-opt sym:${_}func::0:0:0 \ 169 $testsrcfiles $libs" "" "" "" {{ld plugin-15.d}} "main.x" ] \ 170 [list "plugin claimfile resolve symbol with source" \ 171 "-plugin $plugin_path $regclm $regas $regcln \ 172 -plugin-opt claim:$srcdir/$subdir/func.c \ 173 -plugin-opt sym:${_}func::0:0:0 \ 174 -plugin-opt sym:${_}func2::0:0:0 \ 175 -plugin-opt dumpresolutions \ 176 $testsrcfiles $libs" "" "" "" {{ld plugin-16.d}} "main.x" ] \ 177 [list "plugin claimfile replace file with source" \ 178 "-plugin $plugin_path $regclm $regas $regcln \ 179 -plugin-opt claim:$srcdir/$subdir/func.c \ 180 -plugin-opt sym:${_}func::0:0:0 \ 181 -plugin-opt sym:${_}func2::0:0:0 \ 182 -plugin-opt dumpresolutions \ 183 -plugin-opt add:tmpdir/func.o \ 184 $testsrcfiles $libs" "" "" "" {{ld plugin-17.d}} "main.x" ] \ 185 [list "load plugin with source not claimed" "-plugin $plugin_path $regclm \ 186 $testsrcfiles $libs" "" "" "" {{ld plugin-26.d}} "main.x" ] \ 187 [list "plugin fatal error" "-plugin $plugin2_path -plugin-opt fatal \ 188 $testobjfiles $libs" "" "" "" {{ld plugin-27.d}} "main.x" ] \ 189 [list "plugin error" "-plugin $plugin2_path -plugin-opt error \ 190 $testobjfiles $libs" "" "" "" {{ld plugin-28.d}} "main.x" ] \ 191 [list "plugin warning" "-plugin $plugin2_path -plugin-opt warning \ 192 $testobjfiles $libs" "" "" "" {{ld plugin-29.d}} "main.x" ] \ 193] 194 195if [check_shared_lib_support] { 196 lappend plugin_tests [list "PR ld/17973" "-plugin $plugin2_path -shared $regassilent \ 197 -plugin-opt add:tmpdir/pr17973.o \ 198 tmpdir/dummy.o" "" "" "" {{readelf -sW pr17973.d}} "main.x" ] 199} 200 201 202set plugin_lib_tests [list \ 203 [list "plugin ignore lib" "-plugin $plugin_path $regclm \ 204 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 205 -plugin-opt sym:${_}func::0:0:0 \ 206 -plugin-opt sym:${_}func2::0:0:0 \ 207 -plugin-opt dumpresolutions \ 208 -plugin-opt add:tmpdir/func.o \ 209 $testobjfiles_notext -Ltmpdir -ltext $libs" "" "" "" {{ld plugin-10.d}} "main.x" ] \ 210 [list "plugin claimfile replace lib" "-plugin $plugin_path $regclm \ 211 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 212 -plugin-opt sym:${_}func::0:0:0 \ 213 -plugin-opt sym:${_}func2::0:0:0 \ 214 -plugin-opt dumpresolutions \ 215 -plugin-opt add:tmpdir/func.o \ 216 -plugin-opt claim:tmpdir/libtext.a \ 217 -plugin-opt sym:${_}text::0:0:0 \ 218 -plugin-opt add:tmpdir/text.o \ 219 $testobjfiles_notext -Ltmpdir -ltext $libs" "" "" "" {{ld plugin-11.d}} "main.x" ] \ 220 [list "plugin ignore lib with source" \ 221 "-plugin $plugin_path $regclm $regas $regcln \ 222 -plugin-opt claim:$srcdir/$subdir/func.c \ 223 -plugin-opt sym:${_}func::0:0:0 \ 224 -plugin-opt sym:${_}func2::0:0:0 \ 225 -plugin-opt dumpresolutions \ 226 -plugin-opt add:tmpdir/func.o \ 227 $testsrcfiles_notext -Ltmpdir -ltext $libs" "" "" "" {{ld plugin-18.d}} "main.x" ] \ 228 [list "plugin claimfile replace lib with source" \ 229 "-plugin $plugin_path $regclm $regas $regcln \ 230 -plugin-opt claim:$srcdir/$subdir/func.c \ 231 -plugin-opt sym:${_}func::0:0:0 \ 232 -plugin-opt sym:${_}func2::0:0:0 \ 233 -plugin-opt dumpresolutions \ 234 -plugin-opt add:tmpdir/func.o \ 235 -plugin-opt claim:tmpdir/libtext.a \ 236 -plugin-opt sym:${_}text::0:0:0 \ 237 -plugin-opt add:tmpdir/text.o \ 238 $testsrcfiles_notext -Ltmpdir -ltext $libs" "" "" "" {{ld plugin-19.d}} "main.x" ] \ 239] 240 241set plugin_extra_elf_tests [list \ 242 [list "plugin set symbol visibility" "-plugin $plugin_path $regclm \ 243 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 244 -plugin-opt sym:${_}func::0:0:0 \ 245 -plugin-opt sym:${_}func1::0:1:0 \ 246 -plugin-opt sym:${_}func2::0:2:0 \ 247 -plugin-opt sym:${_}func3::0:3:0 \ 248 -plugin-opt dumpresolutions \ 249 -plugin-opt add:tmpdir/func.o \ 250 -plugin-opt add:tmpdir/func1p.o \ 251 -plugin-opt add:tmpdir/func2i.o \ 252 -plugin-opt add:tmpdir/func3h.o \ 253 $testobjfiles $libs --verbose=2" "" "" "" {{ld plugin-12.d} \ 254 {readelf -s plugin-vis-1.d}} "main.x" ] \ 255 [list "plugin set symbol visibility with source" \ 256 "-plugin $plugin_path $regclm $regas $regcln \ 257 -plugin-opt claim:$srcdir/$subdir/func.c \ 258 -plugin-opt sym:${_}func::0:0:0 \ 259 -plugin-opt sym:${_}func1::0:1:0 \ 260 -plugin-opt sym:${_}func2::0:2:0 \ 261 -plugin-opt sym:${_}func3::0:3:0 \ 262 -plugin-opt dumpresolutions \ 263 -plugin-opt add:tmpdir/func.o \ 264 -plugin-opt add:tmpdir/func1p.o \ 265 -plugin-opt add:tmpdir/func2i.o \ 266 -plugin-opt add:tmpdir/func3h.o \ 267 $testsrcfiles $libs --verbose=2" "" "" "" {{ld plugin-12.d} \ 268 {readelf -s plugin-vis-1.d}} "main.x" ] \ 269] 270 271if { !$can_compile || $failed_compile } { 272 foreach testitem $plugin_tests { 273 $failure_kind [lindex $testitem 0] 274 } 275 if { [is_elf_format] } { 276 foreach testitem $plugin_extra_elf_tests { 277 $failure_kind [lindex $testitem 0] 278 } 279 } 280 return 281} 282 283run_ld_link_tests $plugin_tests 284 285if { [is_elf_format] \ 286 && [ld_compile "$CC $CFLAGS" $srcdir/$subdir/func1p.c tmpdir/func1p.o] \ 287 && [ld_compile "$CC $CFLAGS" $srcdir/$subdir/func2i.c tmpdir/func2i.o] \ 288 && [ld_compile "$CC $CFLAGS" $srcdir/$subdir/func3h.c tmpdir/func3h.o] } { 289 run_ld_link_tests $plugin_extra_elf_tests 290} 291 292if ![ar_simple_create $ar "" "tmpdir/libtext.a" "tmpdir/text.o"] { 293 foreach testitem $plugin_lib_tests { 294 unresolved [lindex $testitem 0] 295 } 296} else { 297 run_ld_link_tests $plugin_lib_tests 298} 299 300set plugin_src_tests [list \ 301 [list "plugin 2 with source lib" \ 302 "-plugin $plugin2_path $regclm $regas $regcln \ 303 -plugin-opt dumpresolutions \ 304 tmpdir/main.o -Ltmpdir -ltext -lfunc $libs" "" "" "" {{ld plugin-20.d}} "main.x" ] \ 305 [list "load plugin 2 with source" \ 306 "-plugin $plugin2_path $regclm $regas $regcln \ 307 -plugin-opt dumpresolutions \ 308 $testsrcfiles $libs" "" "" "" {{ld plugin-21.d}} "main.x" ] \ 309 [list "load plugin 2 with source and -r" \ 310 "-r -plugin $plugin2_path $regclm $regas $regcln \ 311 -plugin-opt dumpresolutions \ 312 $testsrcfiles $libs" "" "" "" {{ld plugin-24.d}} "main.x" ] \ 313 [list "plugin 3 with source lib" \ 314 "-plugin $plugin3_path $regclm $regas $regcln \ 315 -plugin-opt dumpresolutions \ 316 tmpdir/main.o -Ltmpdir -ltext -lfunc $libs" "" "" "" {{ld plugin-22.d}} "main.x" ] \ 317 [list "load plugin 3 with source" \ 318 "-plugin $plugin3_path $regclm $regas $regcln \ 319 -plugin-opt dumpresolutions \ 320 $testsrcfiles $libs" "" "" "" {{ld plugin-23.d}} "main.x" ] \ 321 [list "load plugin 3 with source and -r" \ 322 "-r -plugin $plugin3_path $regclm $regas $regcln \ 323 -plugin-opt dumpresolutions \ 324 $testsrcfiles $libs" "" "" "" {{ld plugin-25.d}} "main.x" ] \ 325] 326 327# Check if nm --plugin works. 328set testname "nm --plugin" 329set nm_plugin "$NM --plugin $plugin2_path $srcdir/$subdir/func.c" 330catch "exec $nm_plugin" plugin_nm_output 331send_log "$nm_plugin\n" 332send_log "$plugin_nm_output\n" 333if { [regexp "0+ T func" "$plugin_nm_output"] && 334 [regexp "0+ T _func" "$plugin_nm_output"] } { 335 pass $testname 336} else { 337 fail $testname 338} 339 340# Check if ar --plugin works. 341file delete tmpdir/libfunc.a 342if [ar_simple_create $ar "--plugin $plugin2_path" "tmpdir/libfunc.a" \ 343 "tmpdir/main.o $srcdir/$subdir/func.c"] { 344 set testname "ar --plugin" 345 set nm_plugin "$NM -s --plugin $plugin2_path tmpdir/libfunc.a" 346 catch "exec $nm_plugin" plugin_nm_output 347 send_log "$nm_plugin\n" 348 send_log "$plugin_nm_output\n" 349 if { [regexp "func in func.c" "$plugin_nm_output"] && 350 [regexp "_func in func.c" "$plugin_nm_output"] } { 351 pass $testname 352 run_ld_link_tests $plugin_src_tests 353 } else { 354 fail $testname 355 } 356} else { 357 foreach testitem $plugin_src_tests { 358 unresolved [lindex $testitem 0] 359 } 360} 361 362file delete tmpdir/libpr20070.a 363if [ar_simple_create $ar "--plugin $plugin4_path" "tmpdir/libpr20070.a" \ 364 "$srcdir/$subdir/pr20070b.c"] { 365 run_ld_link_tests [list \ 366 [list \ 367 "PR ld/20070" \ 368 "-Bstatic -plugin $plugin4_path $regclm \ 369 $regas $regcln \ 370 -plugin-opt claim:$srcdir/$subdir/pr20070b.c \ 371 -plugin-opt claim:tmpdir/libpr20070.a \ 372 -plugin-opt dumpresolutions \ 373 tmpdir/pr20070a.o tmpdir/text.o tmpdir/libpr20070.a $libs" \ 374 "" "" "" {{ld pr20070.d}} "pr20070.x" \ 375 ] \ 376 ] 377} else { 378 unresolved "PR ld/20070" 379} 380