1# Test code for libgccjit.so 2# 3# We will compile each of jit.dg/test-*.c into an executable 4# dynamically linked against libgccjit.so, and then run each 5# such executable. 6# 7# These executables call into the libgccjit.so API to create 8# code, compile it, and run it, verifying that the results 9# are as expected. See harness.h for shared code used by all 10# such executables. 11# 12# The executables call into DejaGnu's unit testing C API to 13# report PASS/FAIL results, which this script gathers back 14# up into the Tcl world, reporting a summary of all results 15# across all of the executables. 16 17# Kludge alert: 18# We need g++_init so that it can find the stdlib include path. 19# 20# g++_init (in lib/g++.exp) uses g++_maybe_build_wrapper, 21# which normally comes from the definition of 22# ${tool}_maybe_build_wrapper within lib/wrapper.exp. 23# 24# However, for us, ${tool} is "jit". 25# Hence we load wrapper.exp with tool == "g++", so that 26# g++_maybe_build_wrapper is defined. 27set tool g++ 28load_lib wrapper.exp 29set tool jit 30 31load_lib dg.exp 32load_lib prune.exp 33load_lib target-supports.exp 34load_lib gcc-defs.exp 35load_lib timeout.exp 36load_lib target-libpath.exp 37load_lib gcc.exp 38load_lib g++.exp 39load_lib dejagnu.exp 40 41# Look for lines of the form: 42# definitely lost: 11,316 bytes in 235 blocks 43# indirectly lost: 352 bytes in 4 blocks 44# Ideally these would report zero bytes lost (which is a PASS); 45# for now, report non-zero leaks as XFAILs. 46proc report_leak {kind name logfile line} { 47 set match [regexp "$kind lost: .*" $line result] 48 if $match { 49 verbose "Saw \"$result\" within \"$line\"" 4 50 # Extract bytes and blocks. 51 # These can contain commas as well as numerals, 52 # but we only care about whether we have zero. 53 regexp "$kind lost: (.+) bytes in (.+) blocks" \ 54 $result -> bytes blocks 55 verbose "bytes: '$bytes'" 4 56 verbose "blocks: '$blocks'" 4 57 if { $bytes == 0 } { 58 pass "$name: $logfile: $result" 59 } else { 60 xfail "$name: $logfile: $result" 61 } 62 } 63} 64 65proc parse_valgrind_logfile {name logfile} { 66 verbose "parse_valgrind_logfile: $logfile" 2 67 if [catch {set f [open $logfile]}] { 68 fail "$name: unable to read $logfile" 69 return 70 } 71 72 while { [gets $f line] >= 0 } { 73 # Strip off the PID prefix e.g. ==7675== 74 set line [regsub "==\[0-9\]*== " $line ""] 75 verbose $line 2 76 77 report_leak "definitely" $name $logfile $line 78 report_leak "indirectly" $name $logfile $line 79 } 80 close $f 81} 82 83# Given WRES, the result from "wait", issue a PASS 84# if the spawnee exited cleanly, or a FAIL for various kinds of 85# unexpected exits. 86 87proc verify_exit_status { executable wres } { 88 lassign $wres pid spawnid os_error_flag value 89 verbose "pid: $pid" 3 90 verbose "spawnid: $spawnid" 3 91 verbose "os_error_flag: $os_error_flag" 3 92 verbose "value: $value" 3 93 94 # Detect segfaults etc: 95 if { [llength $wres] > 4 } { 96 if { [lindex $wres 4] == "CHILDKILLED" } { 97 fail "$executable killed: $wres" 98 return 99 } 100 } 101 if { $os_error_flag != 0 } { 102 fail "$executable: OS error: $wres" 103 return 104 } 105 if { $value != 0 } { 106 fail "$executable: non-zero exit code: $wres" 107 return 108 } 109 pass "$executable exited cleanly" 110} 111 112# This is host_execute from dejagnu.exp commit 113# 126a089777158a7891ff975473939f08c0e31a1c 114# with the following patch applied, and renaming to "fixed_host_execute". 115# See the discussion at 116# http://lists.gnu.org/archive/html/dejagnu/2014-10/msg00000.html 117# 118# --- /usr/share/dejagnu/dejagnu.exp.old 2014-10-08 13:38:57.274068541 -0400 119# +++ /usr/share/dejagnu/dejagnu.exp 2014-10-10 12:27:51.113813659 -0400 120# @@ -113,8 +113,6 @@ proc host_execute {args} { 121# set timetol 0 122# set arguments "" 123# 124# - expect_before buffer_full { perror "Buffer full" } 125# - 126# if { [llength $args] == 0} { 127# set executable $args 128# } else { 129 130 131# Execute the executable file, and anaylyse the output for the 132# test state keywords. 133# Returns: 134# A "" (empty) string if everything worked, or an error message 135# if there was a problem. 136# 137proc fixed_host_execute {args} { 138 global env 139 global text 140 global spawn_id 141 142 verbose "fixed_host_execute: $args" 143 144 set timeoutmsg "Timed out: Never got started, " 145 set timeout 100 146 set file all 147 set timetol 0 148 set arguments "" 149 150 if { [llength $args] == 0} { 151 set executable $args 152 } else { 153 set executable [lindex $args 0] 154 set params [lindex $args 1] 155 } 156 157 verbose "The executable is $executable" 2 158 if {![file exists ${executable}]} { 159 perror "The executable, \"$executable\" is missing" 0 160 return "No source file found" 161 } 162 163 verbose "params: $params" 2 164 165 # spawn the executable and look for the DejaGnu output messages from the 166 # test case. 167 # spawn -noecho -open [open "|./${executable}" "r"] 168 169 # Run under valgrind if RUN_UNDER_VALGRIND is present in the environment. 170 # Note that it's best to configure gcc with --enable-valgrind-annotations 171 # when testing under valgrind. 172 set run_under_valgrind [info exists env(RUN_UNDER_VALGRIND)] 173 if $run_under_valgrind { 174 set valgrind_logfile "${executable}.valgrind.txt" 175 set valgrind_params {"valgrind"} 176 lappend valgrind_params "--leak-check=full" 177 lappend valgrind_params "--log-file=${valgrind_logfile}" 178 } else { 179 set valgrind_params {} 180 } 181 verbose "valgrind_params: $valgrind_params" 2 182 183 set args ${valgrind_params} 184 lappend args "./${executable}" 185 set args [concat $args ${params}] 186 verbose "args: $args" 2 187 188 eval spawn -noecho $args 189 190 expect_after full_buffer { error "got full_buffer" } 191 192 set prefix "\[^\r\n\]*" 193 expect { 194 -re "^$prefix\[0-9\]\[0-9\]:..:..:${text}*\r\n" { 195 regsub "\[\n\r\t\]*NOTE: $text\r\n" $expect_out(0,string) "" output 196 verbose "$output" 3 197 set timetol 0 198 exp_continue 199 } 200 -re "^$prefix\tNOTE:${text}*" { 201 regsub "\[\n\r\t\]*NOTE: $text\r\n" $expect_out(0,string) "" output 202 set output [string range $output 6 end] 203 verbose "$output" 2 204 set timetol 0 205 exp_continue 206 } 207 -re "^$prefix\tPASSED:${text}*" { 208 regsub "\[\n\r\t\]*PASSED: $text\r\n" $expect_out(0,string) "" output 209 set output [string range $output 8 end] 210 pass "$output" 211 set timetol 0 212 exp_continue 213 } 214 -re "^$prefix\tFAILED:${text}*" { 215 regsub "\[\n\r\t\]*FAILED: $text\r\n" $expect_out(0,string) "" output 216 set output [string range $output 8 end] 217 fail "$output" 218 set timetol 0 219 exp_continue 220 } 221 -re "^$prefix\tUNTESTED:${text}*" { 222 regsub "\[\n\r\t\]*TESTED: $text\r\n" $expect_out(0,string) "" output 223 set output [string range $output 8 end] 224 untested "$output" 225 set timetol 0 226 exp_continue 227 } 228 -re "^$prefix\tUNRESOLVED:${text}*" { 229 regsub "\[\n\r\t\]*UNRESOLVED: $text\r\n" $expect_out(0,string) "" output 230 set output [string range $output 8 end] 231 unresolved "$output" 232 set timetol 0 233 exp_continue 234 } 235 -re "^Totals" { 236 verbose "All done" 2 237 } 238 eof { 239 # unresolved "${executable} died prematurely" 240 # catch close 241 # return "${executable} died prematurely" 242 } 243 timeout { 244 warning "Timed out executing test case" 245 if { $timetol <= 2 } { 246 incr timetol 247 exp_continue 248 } else { 249 catch close 250 return "Timed out executing test case" 251 } 252 } 253 -re "^$prefix\r\n" { 254 exp_continue 255 } 256 } 257 258 # Use "wait" before "close": valgrind might not have finished 259 # writing the log out before we parse it, so we need to wait for 260 # the spawnee to finish. 261 262 catch wait wres 263 verbose "wres: $wres" 2 264 verify_exit_status $executable $wres 265 266 if $run_under_valgrind { 267 upvar 2 name name 268 parse_valgrind_logfile $name $valgrind_logfile 269 } 270 271 # force a close of the executable to be safe. 272 catch close 273 274 return "" 275} 276 277# (end of code from dejagnu.exp) 278 279# GCC_UNDER_TEST is needed by gcc_target_compile 280global GCC_UNDER_TEST 281if ![info exists GCC_UNDER_TEST] { 282 set GCC_UNDER_TEST "[find_gcc]" 283} 284 285g++_init 286 287# Initialize dg. 288dg-init 289 290# Gather a list of all tests. 291 292# C tests within the testsuite: gcc/testsuite/jit.dg/test-*.c 293set tests [find $srcdir/$subdir test-*.c] 294 295# C++ tests within the testsuite: gcc/testsuite/jit.dg/test-*.cc 296set tests [concat $tests [find $srcdir/$subdir test-*.cc]] 297 298# We also test the examples within the documentation, to ensure that 299# they compile: 300set tests [concat $tests [find $srcdir/../jit/docs/examples *.c]] 301set tests [concat $tests [find $srcdir/../jit/docs/examples *.cc]] 302 303set tests [lsort $tests] 304 305verbose "tests: $tests" 306 307# Is testcase NAME meant to generate a reproducer? 308proc is_testcase_meant_to_generate_a_reproducer {name} { 309 # We expect most testcases to generate a reproducer. 310 # The exceptions are the tutorials (which don't have a "test-" 311 # prefix), and test-threads.c and test-benchmark.c (which are each 312 # unique). 313 verbose "is_testcase_meant_to_generate_a_reproducer: $name" 314 if { [string match "*test-*" $name] } { 315 if { [string match "*test-threads.c" $name] } { 316 return 0 317 } 318 if { [string match "*test-benchmark.c" $name] } { 319 return 0 320 } 321 return 1 322 } 323 return 0 324} 325 326# libgloss has found the driver (as "xgcc" or "gcc) and stored 327# its full path as GCC_UNDER_TEST. 328proc get_path_of_driver {} { 329 global GCC_UNDER_TEST 330 331 verbose "GCC_UNDER_TEST: $GCC_UNDER_TEST" 332 set binary [lindex $GCC_UNDER_TEST 0] 333 verbose "binary: $binary" 334 335 return [file dirname $binary] 336} 337 338# Expand "SRCDIR" within ARG to the location of the top-level 339# src directory 340 341proc jit-expand-vars {arg} { 342 verbose "jit-expand-vars: $arg" 343 global srcdir 344 verbose " srcdir: $srcdir" 345 # "srcdir" is that of the gcc/testsuite directory, so 346 # we need to go up two levels. 347 set arg [string map [list "SRCDIR" $srcdir/../..] $arg] 348 verbose " new arg: $arg" 349 return $arg 350} 351 352# Parameters used when invoking the executables built from the test cases. 353 354global jit-exe-params 355set jit-exe-params {} 356 357# Set "jit-exe-params", expanding "SRCDIR" in each arg to the location of 358# the top-level srcdir. 359 360proc dg-jit-set-exe-params { args } { 361 verbose "dg-jit-set-exe-params: $args" 362 363 global jit-exe-params 364 set jit-exe-params {} 365 # Skip initial arg (line number) 366 foreach arg [lrange $args 1 [llength $args] ] { 367 lappend jit-exe-params [jit-expand-vars $arg] 368 } 369} 370 371proc jit-dg-test { prog do_what extra_tool_flags } { 372 verbose "within jit-dg-test..." 373 verbose " prog: $prog" 374 verbose " do_what: $do_what" 375 verbose " extra_tool_flags: $extra_tool_flags" 376 377 # test-threads.c needs to be linked against pthreads 378 if {[string match "*test-threads.c" $prog]} { 379 append extra_tool_flags " -lpthread" 380 } 381 382 # Any test case that uses jit-verify-output-file-was-created 383 # needs to call jit-setup-compile-to-file here. 384 # (is there a better way to handle setup/finish pairs in dg?) 385 set tmp [grep $prog "jit-verify-output-file-was-created"] 386 if {![string match "" $tmp]} { 387 jit-setup-compile-to-file $prog 388 } 389 390 # Determine what to name the built executable. 391 # 392 # We simply append .exe to the filename, e.g. 393 # "test-foo.c.exe" 394 # since some testcases exist in both 395 # "test-foo.c" and 396 # "test-foo.cc" 397 # variants, and we don't want them to clobber each other's 398 # executables. 399 # 400 # This also ensures that the source name makes it into the 401 # pass/fail output, so that we can distinguish e.g. which test-foo 402 # is failing. 403 set output_file "[file tail $prog].exe" 404 verbose "output_file: $output_file" 405 406 # Create the test executable: 407 set extension [file extension $prog] 408 if {$extension == ".cc"} { 409 set compilation_function "g++_target_compile" 410 set options "{additional_flags=$extra_tool_flags}" 411 } else { 412 set compilation_function "gcc_target_compile" 413 # Until recently, <dejagnu.h> assumed -fgnu89-inline 414 # Ideally we should fixincludes it (PR other/63613), but 415 # for now add -fgnu89-inline when compiling C JIT testcases. 416 # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63613 417 # and http://lists.gnu.org/archive/html/dejagnu/2014-10/msg00011.html 418 set options "{additional_flags=$extra_tool_flags -fgnu89-inline}" 419 } 420 verbose "compilation_function=$compilation_function" 421 verbose "options=$options" 422 423 set comp_output [$compilation_function $prog $output_file \ 424 "executable" $options] 425 upvar 1 name name 426 if ![jit_check_compile "$name" "initial compilation" \ 427 $output_file $comp_output] then { 428 return 429 } 430 431 # Most of the test cases use gcc_jit_context_dump_reproducer_to_file 432 # as they run to write out a .c file that reproduces their behavior, 433 # exercising that API. 434 set generated_reproducer "${output_file}.reproducer.c" 435 436 # Delete any such generated .c file from a previous run. 437 catch "exec rm -f $generated_reproducer" 438 439 # Run the test executable, capturing the PASS/FAIL textual output 440 # from the C API, converting it into the Tcl API. 441 442 # We need to set LD_LIBRARY_PATH so that the test files can find 443 # libgccjit.so 444 # Do this using set_ld_library_path_env_vars from target-libpath.exp 445 # We will restore the old value later using 446 # restore_ld_library_path_env_vars. 447 448 # Unfortunately this API only supports a single saved value, rather 449 # than a stack, and g++_init has already called into this API, 450 # injecting the appropriate value for LD_LIBRARY_PATH for finding 451 # the built copy of libstdc++. 452 # Hence the call to restore_ld_library_path_env_vars would restore 453 # the *initial* value of LD_LIBRARY_PATH, and attempts to run 454 # a C++ testcase after running any prior testcases would thus look 455 # in the wrong place for libstdc++. This led to failures at startup 456 # of the form: 457 # ./tut01-hello-world.cc.exe: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./tut01-hello-world.cc.exe) 458 # when the built libstdc++ is more recent that the system libstdc++. 459 # 460 # As a workaround, reset the variable "orig_environment_saved" within 461 # target-libpath.exp, so that the {set|restore}_ld_library_path_env_vars 462 # API saves/restores the current value of LD_LIBRARY_PATH (as set up 463 # by g++_init). 464 global orig_environment_saved 465 set orig_environment_saved 0 466 467 global ld_library_path 468 global base_dir 469 set ld_library_path "$base_dir/../../" 470 set_ld_library_path_env_vars 471 472 # libgccjit uses the driver to convert .s files to .so libraries 473 # via its *installed* name, FULL_DRIVER_NAME 474 # ${target_noncanonical}-gcc-${gcc_BASEVER}${exeext} 475 # e.g. "x86_64-unknown-linux-gnu-gcc-5.0.0" 476 # looking for it on PATH. Hence we need to prepend the location of 477 # that executable to PATH when running the tests 478 set dir_containing_driver [get_path_of_driver ] 479 verbose "dir_containing_driver: $dir_containing_driver" 480 global env 481 set old_path $env(PATH) 482 setenv "PATH" $dir_containing_driver:$old_path 483 verbose -log "PATH=[getenv PATH]" 484 485 # We have: 486 # test-executables 487 # linked to -> libgccjit.so 488 # -> invokes driver: 489 # -> invokes the assembler 490 # -> invokes the linker 491 # We want to be able to run this from the builddir without installing 492 # but the linker needs to be able to locate various libraries, or we 493 # get: 494 # ld: cannot find crtbeginS.o: No such file or directory 495 # ld: cannot find -lgcc 496 # ld: cannot find -lgcc_s 497 # These can be found in the "gcc" subdir of the build. 498 # Hence to be able to run the testsuite without installing, we need 499 # to set or prepend the "gcc" subdir of the build to LIBRARY_PATH: 500 if { [info exists env(LIBRARY_PATH) ] } { 501 set old_library_path $env(LIBRARY_PATH) 502 setenv "LIBRARY_PATH" $dir_containing_driver:$old_library_path 503 } else { 504 setenv "LIBRARY_PATH" $dir_containing_driver 505 } 506 verbose -log "LIBRARY_PATH=[getenv LIBRARY_PATH]" 507 508 # dejagnu.exp's host_execute has code to scrape out test results 509 # from the DejaGnu C API and bring back into the tcl world, so we 510 # use that to invoke the built code. 511 # However, it appears to be buggy; see: 512 # http://lists.gnu.org/archive/html/dejagnu/2014-10/msg00000.html 513 # We instead call a patched local copy, "fixed_host_execute", defined 514 # above. 515 516 global jit-exe-params 517 set args ${jit-exe-params} 518 set jit-exe-params {} 519 520 set result [fixed_host_execute $output_file $args ] 521 verbose "result: $result" 522 523 # Restore PATH 524 setenv "PATH" $old_path 525 526 # Restore LIBRARY_PATH 527 if { [info exists old_library_path] } { 528 setenv "LIBRARY_PATH" $old_library_path 529 } else { 530 unsetenv "LIBRARY_PATH" 531 } 532 533 restore_ld_library_path_env_vars 534 535 # Most of the test cases use gcc_jit_context_dump_reproducer_to_file 536 # as they run to write out a .c file that reproduces their behavior, 537 # exercising that API. 538 539 if { [is_testcase_meant_to_generate_a_reproducer $name] } { 540 verbose "$name is meant to generate a reproducer" 541 # Verify that a reproducer was generated 542 if { [file exists $generated_reproducer] == 1} { 543 pass "found generated reproducer: $generated_reproducer" 544 set output_file "${generated_reproducer}.exe" 545 # (this overwrites output_file) 546 547 # Try to compile the generated reproducer 548 verbose "compilation_function=$compilation_function" 549 550 # The .c file written by gcc_jit_context_dump_reproducer_to_file 551 # assigns the result of each API call to a unique variable, and not 552 # all are necessarily used, so we need -Wno-unused-variable. 553 set options \ 554 "{additional_flags=$extra_tool_flags -Wno-unused-variable}" 555 verbose "options=$options" 556 557 set comp_output2 [$compilation_function $generated_reproducer \ 558 $output_file "executable" $options] 559 if ![jit_check_compile "generated reproducer from $name" "initial compilation" \ 560 $output_file $comp_output2] then { 561 return 562 } 563 564 # The caller, dg-test, will verify comp_output, which contains 565 # the output from compiling the testcase and will issue a fail 566 # if it's non-empty (e.g. containing warnings, the 567 # "test for excess errors"). 568 # 569 # Append the output from compiling the reproducer, so that this is also 570 # verified: 571 append comp_output $comp_output2 572 573 # TODO: we should try to run the built executable 574 # It's not quite a quine, since it embeds ptrs which could change 575 # from run to run. 576 } else { 577 fail "did not find a generated reproducer: $generated_reproducer" 578 } 579 } else { 580 verbose "$name is not meant to generate a reproducer" 581 } 582 583 # Normally we would return $comp_output and $output_file to the 584 # caller, which would delete $output_file, the generated executable. 585 # If we need to debug, it's handy to be able to suppress this behavior, 586 # keeping the executable around. 587 set preserve_executables [info exists env(PRESERVE_EXECUTABLES)] 588 if $preserve_executables { 589 set output_file "" 590 } 591 592 return [list $comp_output $output_file] 593} 594 595# Given source file PROG, scrape out the value of 596# #define OUTPUT_FILENAME 597# failing if it's not found. 598 599proc jit-get-output-filename {prog} { 600 set tmp [grep $prog "#define OUTPUT_FILENAME (.*)"] 601 if {![string match "" $tmp]} { 602 foreach i $tmp { 603 verbose "i: $i" 604 if {[regexp "^\#define OUTPUT_FILENAME\[ \t\]\+\"(.*)\"$" $i i group] } { 605 verbose "group: '$group'" 606 return $group 607 } else { 608 fail "Unable to parse line: $i" 609 } 610 } 611 } 612 fail "Unable to locate OUTPUT_FILENAME" 613 return "" 614} 615 616# For testcases that use jit-verify-output-file-was-created 617# delete OUTPUT_FILENAME beforehand, to ensure that the 618# testcase is indeed creating it. 619 620proc jit-setup-compile-to-file { prog } { 621 verbose "jit-setup-compile-to-file: $prog" 622 set output_filename [jit-get-output-filename $prog] 623 verbose " output_filename: $output_filename" 624 if {![string match "" $output_filename]} { 625 verbose " deleting any $output_filename" 626 catch "exec rm -f $output_filename" 627 } 628} 629 630proc jit-verify-output-file-was-created { args } { 631 verbose "jit-verify-output-file-was-created: $args" 632 633 upvar 2 prog prog 634 verbose "prog: $prog" 635 set output_filename [jit-get-output-filename $prog] 636 verbose " output_filename: $output_filename" 637 638 # Verify that the expected file was written out 639 if { [file exists $output_filename] == 1} { 640 pass "$output_filename exists" 641 } else { 642 fail "$output_filename does not exist" 643 } 644} 645 646# Verify that the given file exists, and is executable. 647# Attempt to execute it, and verify that its stdout matches 648# the given regex. 649 650proc jit-run-executable { args } { 651 verbose "jit-run-executable: $args" 652 653 set executable-name [lindex $args 0] 654 verbose "executable-name: ${executable-name}" 655 656 set dg-output-text [lindex $args 1] 657 verbose "dg-output-text: ${dg-output-text}" 658 659 if { [file executable ${executable-name}] } { 660 pass "${executable-name} has executable bit set" 661 } else { 662 fail "${executable-name} does not have executable bit set" 663 } 664 665 # Attempt to run the executable; adapted from dg.exp's dg-test 666 set status -1 667 set result [jit_load ./${executable-name}] 668 set status [lindex $result 0] 669 set output [lindex $result 1] 670 verbose " status: $status" 671 verbose " output: $output" 672 # send_user "After exec, status: $status\n" 673 if { "$status" == "pass" } { 674 pass "${executable-name} execution test" 675 verbose "Exec succeeded." 3 676 set texttmp ${dg-output-text} 677 if { ![regexp $texttmp ${output}] } { 678 fail "${executable-name} output pattern test, is ${output}, should match $texttmp" 679 verbose "Failed test for output pattern $texttmp" 3 680 } else { 681 pass "${executable-name} output pattern test, $texttmp" 682 verbose "Passed test for output pattern $texttmp" 3 683 } 684 unset texttmp 685 } elseif { "$status" == "fail" } { 686 # It would be nice to get some info out of errorCode. 687 if {[info exists errorCode]} { 688 verbose "Exec failed, errorCode: $errorCode" 3 689 } else { 690 verbose "Exec failed, errorCode not defined!" 3 691 } 692 fail "${executable-name} execution test" 693 } else { 694 $status "${executable-name} execution test" 695 } 696} 697 698# Assuming that a .s file has been written out named 699# OUTPUT_FILENAME, invoke the driver to try to turn it into 700# an executable, and try to run the result. 701# For use by the test-compile-to-assembler.c testcase. 702proc jit-verify-assembler { args } { 703 verbose "jit-verify-assembler: $args" 704 705 set dg-output-text [lindex $args 0] 706 verbose "dg-output-text: ${dg-output-text}" 707 708 upvar 2 name name 709 verbose "name: $name" 710 711 upvar 2 prog prog 712 verbose "prog: $prog" 713 set asm_filename [jit-get-output-filename $prog] 714 verbose " asm_filename: ${asm_filename}" 715 716 # Name the built executable as OUTPUT_FILENAME with 717 # ".exe" appended. 718 set executable_from_asm ${asm_filename}.exe 719 verbose " executable_from_asm: ${executable_from_asm}" 720 721 # Invoke the driver to assemble/link the .s file to the .exe 722 set comp_output [gcc_target_compile \ 723 ${asm_filename} \ 724 ${executable_from_asm} \ 725 "executable" \ 726 "{}"] 727 if ![jit_check_compile \ 728 "$name" \ 729 "assemble/link of ${asm_filename}" \ 730 ${executable_from_asm} \ 731 $comp_output] then { 732 return 733 } 734 735 # Verify that the executable was created. 736 if { [file exists $executable_from_asm] == 1} { 737 pass "$executable_from_asm exists" 738 } else { 739 fail "$executable_from_asm does not exist" 740 } 741 742 # Run it and verify that the output matches the regex. 743 jit-run-executable ${executable_from_asm} ${dg-output-text} 744} 745 746# Assuming that a .o file has been written out named 747# OUTPUT_FILENAME, invoke the driver to try to turn it into 748# an executable, and try to run the result. 749# For use by the test-compile-to-object.c testcase. 750proc jit-verify-object { args } { 751 verbose "jit-verify-object: $args" 752 753 set dg-output-text [lindex $args 0] 754 verbose "dg-output-text: ${dg-output-text}" 755 756 upvar 2 name name 757 verbose "name: $name" 758 759 upvar 2 prog prog 760 verbose "prog: $prog" 761 set obj_filename [jit-get-output-filename $prog] 762 verbose " obj_filename: ${obj_filename}" 763 764 # Name the linked executable as OUTPUT_FILENAME with 765 # ".exe" appended. 766 set executable_from_obj ${obj_filename}.exe 767 verbose " executable_from_obj: ${executable_from_obj}" 768 769 # Invoke the driver to link the .o file to the .exe 770 set comp_output [gcc_target_compile \ 771 ${obj_filename} \ 772 ${executable_from_obj} \ 773 "executable" \ 774 "{}"] 775 if ![jit_check_compile \ 776 "$name" \ 777 "link of ${obj_filename}" \ 778 ${executable_from_obj} \ 779 $comp_output] then { 780 return 781 } 782 783 # Verify that the executable was created. 784 if { [file exists $executable_from_obj] == 1} { 785 pass "$executable_from_obj exists" 786 } else { 787 fail "$executable_from_obj does not exist" 788 } 789 790 # Run it and verify that the output matches the regex. 791 jit-run-executable ${executable_from_obj} ${dg-output-text} 792} 793 794# Assuming that a .so file has been written out named 795# OUTPUT_FILENAME, build a test executable to use it, 796# and try to run the result. 797# For use by the test-compile-to-dynamic-library.c testcase. 798proc jit-verify-dynamic-library { args } { 799 verbose "jit-verify-object: $args" 800 801 global srcdir 802 global subdir 803 804 set dg-output-text [lindex $args 0] 805 verbose "dg-output-text: ${dg-output-text}" 806 807 upvar 2 name name 808 verbose "name: $name" 809 810 upvar 2 prog prog 811 verbose "prog: $prog" 812 set obj_filename [jit-get-output-filename $prog] 813 verbose " obj_filename: ${obj_filename}" 814 815 # Build a test executable from 816 # verify-dynamic-library.c 817 set test_src "verify-dynamic-library.c" 818 set test_executable ${test_src}.exe 819 verbose " test_executable: ${test_executable}" 820 821 # Invoke the driver to build the test executable 822 set comp_output [gcc_target_compile \ 823 $srcdir/$subdir/${test_src} \ 824 ${test_executable} \ 825 "executable" \ 826 "{additional_flags=-ldl}"] 827 if ![jit_check_compile \ 828 "$name" \ 829 "build of ${test_executable}" \ 830 ${test_executable} \ 831 $comp_output] then { 832 return 833 } 834 835 # Verify that the test executable was created. 836 if { [file exists $test_executable] == 1} { 837 pass "$test_executable exists" 838 } else { 839 fail "$test_executable does not exist" 840 } 841 842 # Run it and verify that the output matches the regex. 843 jit-run-executable ${test_executable} ${dg-output-text} 844} 845 846# A way to invoke "jit-run-executable" with the given regex, 847# using OUTPUT_FILENAME within the testcase to determine 848# the name of the executable to run. 849# For use by the test-compile-to-executable.c testcase. 850 851proc jit-verify-executable { args } { 852 verbose "jit-verify-executable: $args" 853 854 set dg-output-text [lindex $args 0] 855 verbose "dg-output-text: ${dg-output-text}" 856 857 upvar 2 name name 858 verbose "name: $name" 859 860 upvar 2 prog prog 861 verbose "prog: $prog" 862 set output_filename [jit-get-output-filename $prog] 863 verbose " output_filename: $output_filename" 864 865 jit-run-executable $output_filename ${dg-output-text} 866} 867 868# We need to link with --export-dynamic for test-calling-external-function.c 869# so that the JIT-built code can call into functions from the main program. 870set DEFAULT_CFLAGS "-I$srcdir/../jit -lgccjit -g -Wall -Werror -Wl,--export-dynamic" 871 872# Main loop. This will invoke jig-dg-test on each test-*.c file. 873dg-runtest $tests "" $DEFAULT_CFLAGS 874 875# All done. 876dg-finish 877