| # Copyright 2011-2020 Free Software Foundation, Inc. |
| |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| |
| if {[skip_shlib_tests]} { |
| untested "skipping shared library tests" |
| return -1 |
| } |
| |
| if {[get_compiler_info]} { |
| untested "could not get compiler info" |
| return 1 |
| } |
| |
| # Compile the testcase program and library. BINSUFFIX is the suffix |
| # to append to the program and library filenames, to make them unique |
| # between invocations. OPTIONS is passed to gdb_compile when |
| # compiling the program. |
| |
| proc compile_jit_test {testname binsuffix options} { |
| global testfile srcfile binfile srcdir subdir |
| global solib_testfile solib_srcfile solib_binfile solib_binfile_test_msg |
| global solib_binfile_target |
| |
| set testfile jit-main |
| set srcfile ${testfile}.c |
| set binfile [standard_output_file $testfile$binsuffix] |
| if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ |
| executable [concat debug $options]] != "" } { |
| untested $testname |
| return -1 |
| } |
| |
| set solib_testfile "jit-solib" |
| set solib_srcfile "${srcdir}/${subdir}/${solib_testfile}.c" |
| set solib_binfile [standard_output_file ${solib_testfile}$binsuffix.so] |
| set solib_binfile_test_msg "SHLIBDIR/${solib_testfile}$binsuffix.so" |
| |
| # Note: compiling without debug info: the library goes through |
| # symbol renaming by munging on its symbol table, and that |
| # wouldn't work for .debug sections. Also, output for "info |
| # function" changes when debug info is present. |
| if { [gdb_compile_shlib ${solib_srcfile} ${solib_binfile} {-fPIC}] != "" } { |
| untested $testname |
| return -1 |
| } |
| |
| set solib_binfile_target [gdb_remote_download target ${solib_binfile}] |
| |
| return 0 |
| } |
| |
| # Detach, restart GDB, and re-attach to the program. |
| |
| proc clean_reattach {} { |
| global decimal gdb_prompt srcfile testfile |
| |
| # Get PID of test program. |
| set testpid -1 |
| set test "get inferior process ID" |
| gdb_test_multiple "p mypid" $test { |
| -re ".* = ($decimal).*$gdb_prompt $" { |
| set testpid $expect_out(1,string) |
| pass $test |
| } |
| } |
| |
| gdb_test_no_output "set var wait_for_gdb = 1" |
| gdb_test "detach" "Detaching from .*" |
| |
| clean_restart $testfile |
| |
| set test "attach" |
| gdb_test_multiple "attach $testpid" "$test" { |
| -re "Attaching to program.*.*main.*at .*$srcfile:.*$gdb_prompt $" { |
| pass "$test" |
| } |
| } |
| |
| gdb_test_no_output "set var wait_for_gdb = 0" |
| } |
| |
| # Continue to LOCATION in the program. If REATTACH, detach and |
| # re-attach to the program from scratch. |
| proc continue_to_test_location {location reattach} { |
| gdb_breakpoint [gdb_get_line_number $location] |
| gdb_continue_to_breakpoint $location |
| if {$reattach} { |
| with_test_prefix "$location" { |
| clean_reattach |
| } |
| } |
| } |
| |
| proc one_jit_test {count match_str reattach} { |
| with_test_prefix "one_jit_test-$count" { |
| global verbose testfile solib_binfile_target solib_binfile_test_msg |
| |
| clean_restart $testfile |
| |
| # This is just to help debugging when things fail |
| if {$verbose > 0} { |
| gdb_test "set debug jit 1" |
| } |
| |
| if { ![runto_main] } { |
| fail "can't run to main" |
| return |
| } |
| |
| gdb_breakpoint [gdb_get_line_number "break here 0"] |
| gdb_continue_to_breakpoint "break here 0" |
| |
| # Poke desired values directly into inferior instead of using "set args" |
| # because "set args" does not work under gdbserver. |
| gdb_test_no_output "set var argc = 2" |
| gdb_test_no_output "set var libname = \"$solib_binfile_target\"" "set var libname = \"$solib_binfile_test_msg\"" |
| gdb_test_no_output "set var count = $count" |
| |
| continue_to_test_location "break here 1" $reattach |
| |
| gdb_test "info function ^jit_function" "$match_str" |
| |
| # This is just to help debugging when things fail |
| if {$verbose > 0} { |
| gdb_test "maintenance print objfiles" |
| gdb_test "maintenance info break" |
| } |
| |
| continue_to_test_location "break here 2" $reattach |
| |
| # All jit librares must have been unregistered |
| gdb_test "info function jit_function" \ |
| "All functions matching regular expression \"jit_function\":" |
| } |
| } |
| |
| if {[compile_jit_test jit.exp "" {}] < 0} { |
| return |
| } |
| one_jit_test 1 "${hex} jit_function_0000" 0 |
| one_jit_test 2 "${hex} jit_function_0000\[\r\n\]+${hex} jit_function_0001" 0 |
| |
| # Test attaching to an inferior with some JIT libraries already |
| # registered. We reuse the normal test, and detach/reattach at |
| # specific interesting points. |
| if {[can_spawn_for_attach]} { |
| if {[compile_jit_test "jit.exp attach tests" \ |
| "-attach" {additional_flags=-DATTACH=1}] < 0} { |
| return |
| } |
| |
| with_test_prefix attach { |
| one_jit_test 2 "${hex} jit_function_0000\[\r\n\]+${hex} jit_function_0001" 1 |
| } |
| } |
| |
| with_test_prefix PIE { |
| if {[compile_jit_test "jit.exp PIE tests" \ |
| "-pie" {additional_flags=-fPIE ldflags=-pie}] < 0} { |
| return |
| } |
| |
| one_jit_test 1 "${hex} jit_function_0000" 0 |
| } |