1# Expect script for ld-plugin tests 2# Copyright (C) 2010-2017 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 109set dotsym 0 110if { $can_compile && !$failed_compile } { 111 # Find out if symbols have prefix on this platform before setting tests. 112 catch "exec $NM tmpdir/func.o" plugin_nm_output 113 if { [regexp "_func" "$plugin_nm_output"] } { 114 set _ "_" 115 } 116 if { [regexp "\\.func" "$plugin_nm_output"] } { 117 set dotsym 1 118 } 119} 120 121set testobjfiles "tmpdir/main.o tmpdir/func.o tmpdir/text.o" 122set testobjfiles_notext "tmpdir/main.o tmpdir/func.o" 123set testsrcfiles "tmpdir/main.o $srcdir/$subdir/func.c tmpdir/text.o" 124set testsrcfiles_notext "tmpdir/main.o $srcdir/$subdir/func.c" 125# Rather than having libs we just define dummy values for anything 126# we may need to link a target exe; we aren't going to run it anyway. 127set libs "[ld_simple_link_defsyms] --defsym ${_}printf=${_}main --defsym ${_}puts=${_}main" 128if { $dotsym } { 129 append libs " --defsym .printf=.main --defsym .puts=.main" 130} 131 132set plugin_tests [list \ 133 [list "load plugin" "-plugin $plugin_path \ 134 $testobjfiles $libs" "" "" "" {{ld plugin-1.d}} "main.x" ] \ 135 [list "fail plugin onload" "-plugin $plugin_path -plugin-opt failonload \ 136 $testobjfiles $libs" "" "" "" {{ld plugin-2.d}} "main.x" ] \ 137 [list "fail plugin allsymbolsread" "-plugin $plugin_path $regas \ 138 -plugin-opt failallsymbolsread \ 139 $testobjfiles $libs" "" "" "" {{ld plugin-3.d}} "main.x" ] \ 140 [list "fail plugin cleanup" "-plugin $plugin_path -plugin-opt failcleanup \ 141 $regcln \ 142 $testobjfiles $libs" "" "" "" {{ld plugin-4.d}} "main.x" ] \ 143 [list "plugin all hooks" "-plugin $plugin_path $regclm $regas $regcln \ 144 $testobjfiles $libs" "" "" "" {{ld plugin-5.d}} "main.x" ] \ 145 [list "plugin claimfile lost symbol" "-plugin $plugin_path $regclm \ 146 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 147 $testobjfiles $libs" "" "" "" {{ld plugin-6.d}} "main.x" ] \ 148 [list "plugin claimfile replace symbol" "-plugin $plugin_path $regclm \ 149 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 150 -plugin-opt sym:${_}func::0:0:0 \ 151 $testobjfiles $libs" "" "" "" {{ld plugin-7.d}} "main.x" ] \ 152 [list "plugin claimfile resolve symbol" "-plugin $plugin_path $regclm \ 153 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 154 -plugin-opt sym:${_}func::0:0:0 \ 155 -plugin-opt sym:${_}func2::0:0:0 \ 156 -plugin-opt dumpresolutions \ 157 $testobjfiles $libs" "" "" "" {{ld plugin-8.d}} "main.x" ] \ 158 [list "plugin claimfile replace file" "-plugin $plugin_path $regclm \ 159 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 160 -plugin-opt sym:${_}func::0:0:0 \ 161 -plugin-opt sym:${_}func2::0:0:0 \ 162 -plugin-opt dumpresolutions \ 163 -plugin-opt add:tmpdir/func.o \ 164 $testobjfiles $libs" "" "" "" {{ld plugin-9.d}} "main.x" ] \ 165 [list "load plugin with source" "-plugin $plugin_path $regclm \ 166 -plugin-opt claim:$srcdir/$subdir/func.c \ 167 $testsrcfiles $libs" "" "" "" {{ld plugin-13.d}} "main.x" ] \ 168 [list "plugin claimfile lost symbol with source" \ 169 "-plugin $plugin_path $regclm $regas $regcln \ 170 -plugin-opt claim:$srcdir/$subdir/func.c \ 171 $testsrcfiles $libs" "" "" "" {{ld plugin-14.d}} "main.x" ] \ 172 [list "plugin claimfile replace symbol with source" \ 173 "-plugin $plugin_path $regclm $regas $regcln \ 174 -plugin-opt claim:$srcdir/$subdir/func.c \ 175 -plugin-opt sym:${_}func::0:0:0 \ 176 $testsrcfiles $libs" "" "" "" {{ld plugin-15.d}} "main.x" ] \ 177 [list "plugin claimfile resolve symbol 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 $testsrcfiles $libs" "" "" "" {{ld plugin-16.d}} "main.x" ] \ 184 [list "plugin claimfile replace file with source" \ 185 "-plugin $plugin_path $regclm $regas $regcln \ 186 -plugin-opt claim:$srcdir/$subdir/func.c \ 187 -plugin-opt sym:${_}func::0:0:0 \ 188 -plugin-opt sym:${_}func2::0:0:0 \ 189 -plugin-opt dumpresolutions \ 190 -plugin-opt add:tmpdir/func.o \ 191 $testsrcfiles $libs" "" "" "" {{ld plugin-17.d}} "main.x" ] \ 192 [list "load plugin with source not claimed" "-plugin $plugin_path $regclm \ 193 $testsrcfiles $libs" "" "" "" {{ld plugin-26.d}} "main.x" ] \ 194 [list "plugin fatal error" "-plugin $plugin2_path -plugin-opt fatal \ 195 $testobjfiles $libs" "" "" "" {{ld plugin-27.d}} "main.x" ] \ 196 [list "plugin error" "-plugin $plugin2_path -plugin-opt error \ 197 $testobjfiles $libs" "" "" "" {{ld plugin-28.d}} "main.x" ] \ 198 [list "plugin warning" "-plugin $plugin2_path -plugin-opt warning \ 199 $testobjfiles $libs" "" "" "" {{ld plugin-29.d}} "main.x" ] \ 200] 201 202if [check_shared_lib_support] { 203 lappend plugin_tests [list "PR ld/17973" "-plugin $plugin2_path -shared $regassilent \ 204 -plugin-opt add:tmpdir/pr17973.o \ 205 tmpdir/dummy.o" "" "" "" {{readelf -sW pr17973.d}} "main.x" ] 206} 207 208 209set plugin_lib_tests [list \ 210 [list "plugin ignore 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 $testobjfiles_notext -Ltmpdir -ltext $libs" "" "" "" {{ld plugin-10.d}} "main.x" ] \ 217 [list "plugin claimfile replace lib" "-plugin $plugin_path $regclm \ 218 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 219 -plugin-opt sym:${_}func::0:0:0 \ 220 -plugin-opt sym:${_}func2::0:0:0 \ 221 -plugin-opt dumpresolutions \ 222 -plugin-opt add:tmpdir/func.o \ 223 -plugin-opt claim:tmpdir/libtext.a \ 224 -plugin-opt sym:${_}text::0:0:0 \ 225 -plugin-opt add:tmpdir/text.o \ 226 $testobjfiles_notext -Ltmpdir -ltext $libs" "" "" "" {{ld plugin-11.d}} "main.x" ] \ 227 [list "plugin ignore lib with source" \ 228 "-plugin $plugin_path $regclm $regas $regcln \ 229 -plugin-opt claim:$srcdir/$subdir/func.c \ 230 -plugin-opt sym:${_}func::0:0:0 \ 231 -plugin-opt sym:${_}func2::0:0:0 \ 232 -plugin-opt dumpresolutions \ 233 -plugin-opt add:tmpdir/func.o \ 234 $testsrcfiles_notext -Ltmpdir -ltext $libs" "" "" "" {{ld plugin-18.d}} "main.x" ] \ 235 [list "plugin claimfile replace lib with source" \ 236 "-plugin $plugin_path $regclm $regas $regcln \ 237 -plugin-opt claim:$srcdir/$subdir/func.c \ 238 -plugin-opt sym:${_}func::0:0:0 \ 239 -plugin-opt sym:${_}func2::0:0:0 \ 240 -plugin-opt dumpresolutions \ 241 -plugin-opt add:tmpdir/func.o \ 242 -plugin-opt claim:tmpdir/libtext.a \ 243 -plugin-opt sym:${_}text::0:0:0 \ 244 -plugin-opt add:tmpdir/text.o \ 245 $testsrcfiles_notext -Ltmpdir -ltext $libs" "" "" "" {{ld plugin-19.d}} "main.x" ] \ 246 [list "plugin with empty archive" \ 247 "-plugin $plugin_path $regclm \ 248 -plugin-opt read:8 \ 249 $testobjfiles tmpdir/libempty.a $libs" "" "" "" {{ld plugin-30.d}} "main.x" ] \ 250] 251 252set plugin_extra_elf_tests [list \ 253 [list "plugin set symbol visibility" "-plugin $plugin_path $regclm \ 254 $regas $regcln -plugin-opt claim:tmpdir/func.o \ 255 -plugin-opt sym:${_}func::0:0:0 \ 256 -plugin-opt sym:${_}func1::0:1:0 \ 257 -plugin-opt sym:${_}func2::0:2:0 \ 258 -plugin-opt sym:${_}func3::0:3:0 \ 259 -plugin-opt dumpresolutions \ 260 -plugin-opt add:tmpdir/func.o \ 261 -plugin-opt add:tmpdir/func1p.o \ 262 -plugin-opt add:tmpdir/func2i.o \ 263 -plugin-opt add:tmpdir/func3h.o \ 264 $testobjfiles $libs --verbose=2" "" "" "" {{ld plugin-12.d} \ 265 {readelf -s plugin-vis-1.d}} "main.x" ] \ 266 [list "plugin set symbol visibility with source" \ 267 "-plugin $plugin_path $regclm $regas $regcln \ 268 -plugin-opt claim:$srcdir/$subdir/func.c \ 269 -plugin-opt sym:${_}func::0:0:0 \ 270 -plugin-opt sym:${_}func1::0:1:0 \ 271 -plugin-opt sym:${_}func2::0:2:0 \ 272 -plugin-opt sym:${_}func3::0:3:0 \ 273 -plugin-opt dumpresolutions \ 274 -plugin-opt add:tmpdir/func.o \ 275 -plugin-opt add:tmpdir/func1p.o \ 276 -plugin-opt add:tmpdir/func2i.o \ 277 -plugin-opt add:tmpdir/func3h.o \ 278 $testsrcfiles $libs --verbose=2" "" "" "" {{ld plugin-12.d} \ 279 {readelf -s plugin-vis-1.d}} "main.x" ] \ 280] 281 282if { !$can_compile || $failed_compile } { 283 foreach testitem $plugin_tests { 284 $failure_kind [lindex $testitem 0] 285 } 286 if { [is_elf_format] } { 287 foreach testitem $plugin_extra_elf_tests { 288 $failure_kind [lindex $testitem 0] 289 } 290 } 291 return 292} 293 294run_ld_link_tests $plugin_tests 295 296if { [is_elf_format] \ 297 && [ld_compile "$CC $CFLAGS" $srcdir/$subdir/func1p.c tmpdir/func1p.o] \ 298 && [ld_compile "$CC $CFLAGS" $srcdir/$subdir/func2i.c tmpdir/func2i.o] \ 299 && [ld_compile "$CC $CFLAGS" $srcdir/$subdir/func3h.c tmpdir/func3h.o] } { 300 run_ld_link_tests $plugin_extra_elf_tests 301} 302 303if {![ar_simple_create $ar "" "tmpdir/libtext.a" "tmpdir/text.o"] || \ 304 ![ar_simple_create $ar "" "tmpdir/libempty.a" ""]} { 305 foreach testitem $plugin_lib_tests { 306 unresolved [lindex $testitem 0] 307 } 308} else { 309 run_ld_link_tests $plugin_lib_tests 310} 311 312set plugin_src_tests [list \ 313 [list "plugin 2 with source lib" \ 314 "-plugin $plugin2_path $regclm $regas $regcln \ 315 -plugin-opt dumpresolutions \ 316 tmpdir/main.o -Ltmpdir -ltext -lfunc $libs" "" "" "" {{ld plugin-20.d}} "main.x" ] \ 317 [list "load plugin 2 with source" \ 318 "-plugin $plugin2_path $regclm $regas $regcln \ 319 -plugin-opt dumpresolutions \ 320 $testsrcfiles $libs" "" "" "" {{ld plugin-21.d}} "main.x" ] \ 321 [list "load plugin 2 with source and -r" \ 322 "-r -plugin $plugin2_path $regclm $regas $regcln \ 323 -plugin-opt dumpresolutions \ 324 $testsrcfiles $libs" "" "" "" {{ld plugin-24.d}} "main.x" ] \ 325 [list "plugin 3 with source lib" \ 326 "-plugin $plugin3_path $regclm $regas $regcln \ 327 -plugin-opt dumpresolutions \ 328 tmpdir/main.o -Ltmpdir -ltext -lfunc $libs" "" "" "" {{ld plugin-22.d}} "main.x" ] \ 329 [list "load plugin 3 with source" \ 330 "-plugin $plugin3_path $regclm $regas $regcln \ 331 -plugin-opt dumpresolutions \ 332 $testsrcfiles $libs" "" "" "" {{ld plugin-23.d}} "main.x" ] \ 333 [list "load plugin 3 with source and -r" \ 334 "-r -plugin $plugin3_path $regclm $regas $regcln \ 335 -plugin-opt dumpresolutions \ 336 $testsrcfiles $libs" "" "" "" {{ld plugin-25.d}} "main.x" ] \ 337] 338 339# Check if nm --plugin works. 340set testname "nm --plugin" 341set nm_plugin "$NM --plugin $plugin2_path $srcdir/$subdir/func.c" 342catch "exec $nm_plugin" plugin_nm_output 343send_log "$nm_plugin\n" 344send_log "$plugin_nm_output\n" 345if { [regexp "0+ T func" "$plugin_nm_output"] && 346 [regexp "0+ T _func" "$plugin_nm_output"] } { 347 pass $testname 348} else { 349 fail $testname 350} 351 352# Check if ar --plugin works. 353file delete tmpdir/libfunc.a 354if [ar_simple_create $ar "--plugin $plugin2_path" "tmpdir/libfunc.a" \ 355 "tmpdir/main.o $srcdir/$subdir/func.c"] { 356 set testname "ar --plugin" 357 set nm_plugin "$NM -s --plugin $plugin2_path tmpdir/libfunc.a" 358 catch "exec $nm_plugin" plugin_nm_output 359 send_log "$nm_plugin\n" 360 send_log "$plugin_nm_output\n" 361 if { [regexp "func in func.c" "$plugin_nm_output"] && 362 [regexp "_func in func.c" "$plugin_nm_output"] } { 363 pass $testname 364 run_ld_link_tests $plugin_src_tests 365 } else { 366 fail $testname 367 } 368} else { 369 foreach testitem $plugin_src_tests { 370 unresolved [lindex $testitem 0] 371 } 372} 373 374file delete tmpdir/libpr20070.a 375if [ar_simple_create $ar "--plugin $plugin4_path" "tmpdir/libpr20070.a" \ 376 "$srcdir/$subdir/pr20070b.c"] { 377 run_ld_link_tests [list \ 378 [list \ 379 "PR ld/20070" \ 380 "-Bstatic -plugin $plugin4_path $regclm \ 381 $regas $regcln \ 382 -plugin-opt claim:$srcdir/$subdir/pr20070b.c \ 383 -plugin-opt claim:tmpdir/libpr20070.a \ 384 -plugin-opt dumpresolutions \ 385 tmpdir/pr20070a.o tmpdir/text.o tmpdir/libpr20070.a $libs" \ 386 "" "" "" {{ld pr20070.d}} "pr20070.x" \ 387 ] \ 388 ] 389} else { 390 unresolved "PR ld/20070" 391} 392