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