Home | History | Annotate | Line # | Download | only in gdb.base
      1 # Copyright 2011-2024 Free Software Foundation, Inc.
      2 
      3 # This program is free software; you can redistribute it and/or modify
      4 # it under the terms of the GNU General Public License as published by
      5 # the Free Software Foundation; either version 3 of the License, or
      6 # (at your option) any later version.
      7 #
      8 # This program is distributed in the hope that it will be useful,
      9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11 # GNU General Public License for more details.
     12 #
     13 # You should have received a copy of the GNU General Public License
     14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15 
     16 # The same tests as in jit.exp, but loading JITer itself from a shared
     17 # library.
     18 
     19 require allow_shlib_tests
     20 
     21 load_lib jit-elf-helpers.exp
     22 
     23 # Increase this to see more detail.
     24 set test_verbose 0
     25 
     26 # The "real" main of this test, which loads jit-elf-main
     27 # as a shared library.
     28 set main_loader_basename jit-elf-dlmain
     29 set main_loader_srcfile ${srcdir}/${subdir}/${main_loader_basename}.c
     30 set main_loader_binfile [standard_output_file ${main_loader_basename}]
     31 
     32 # The main code that loads and registers JIT objects.
     33 set main_solib_basename jit-elf-main
     34 set main_solib_srcfile ${srcdir}/${subdir}/${main_solib_basename}.c
     35 set main_solib_binfile [standard_output_file ${main_solib_basename}.so]
     36 
     37 # The shared library that gets loaded as JIT objects.
     38 set jit_solib_basename jit-elf-solib
     39 set jit_solib_srcfile ${srcdir}/${subdir}/${jit_solib_basename}.c
     40 
     41 # Compile the testcase shared library loader.
     42 #
     43 # OPTIONS is passed to gdb_compile when compiling the binary.
     44 #
     45 # On success, return 0.
     46 # On failure, return -1.
     47 proc compile_jit_dlmain {options} {
     48     global main_loader_srcfile main_loader_binfile main_loader_basename
     49     set options [concat $options debug]
     50 
     51     if { [gdb_compile ${main_loader_srcfile} ${main_loader_binfile} \
     52 	    executable $options] != "" } {
     53 	untested "failed to compile ${main_loader_basename}.c as an executable"
     54 	return -1
     55     }
     56 
     57     return 0
     58 }
     59 
     60 # Run $main_loader_binfile and load $main_solib_binfile in
     61 # GDB.  Check jit-related debug output and matches `info function`
     62 # output for a jit loaded function using MATCH_STR.
     63 #
     64 # SOLIB_BINFILES_TARGETS is a list of shared libraries to pass
     65 # as arguments when running $main_loader_binfile.
     66 # MATCH_STR is a regular expression that output of `info function`
     67 # must match.
     68 proc one_jit_test {solib_binfiles_target match_str} {
     69     set count [llength $solib_binfiles_target]
     70     with_test_prefix "one_jit_test-$count" {
     71 	global test_verbose
     72 	global main_loader_binfile main_loader_srcfile
     73 	global main_solib_binfile main_solib_binfile_target main_solib_srcfile
     74 
     75 	clean_restart $main_loader_binfile
     76 	gdb_locate_shlib $main_solib_binfile
     77 
     78 	# This is just to help debugging when things fail
     79 	if {$test_verbose > 0} {
     80 	    gdb_test "set debug jit 1"
     81 	}
     82 
     83 	if { ![runto_main] } {
     84 	    return
     85 	}
     86 
     87 	gdb_breakpoint [gdb_get_line_number "break here before-dlopen" \
     88 			    $main_loader_srcfile]
     89 	gdb_continue_to_breakpoint "break here before-dlopen"
     90 	gdb_test_no_output "set var jit_libname = \"$main_solib_binfile_target\"" \
     91 	    "setting library name"
     92 
     93 	gdb_breakpoint [gdb_get_line_number "break here after-dlopen" \
     94 			$main_loader_srcfile]
     95 	gdb_continue_to_breakpoint "break here after-dlopen"
     96 
     97 	set line [gdb_get_line_number {break here 0} $main_solib_srcfile]
     98 	gdb_breakpoint "$main_solib_srcfile:$line"
     99 	gdb_continue_to_breakpoint "break here 0"
    100 
    101 	# Poke desired values directly into inferior instead of using "set args"
    102 	# because "set args" does not work under gdbserver.
    103 	gdb_test_no_output "set var argc=[expr $count + 1]" "forging argc"
    104 	gdb_test_no_output "set var argv=fake_argv" "forging argv"
    105 	for {set i 1} {$i <= $count} {incr i} {
    106 	    set binfile_target [lindex $solib_binfiles_target [expr $i-1]]
    107 	    gdb_test_no_output "set var argv\[$i\]=\"${binfile_target}\"" \
    108 		"forging argv\[$i\]"
    109 	}
    110 
    111 	set line [gdb_get_line_number {break here 1} $main_solib_srcfile]
    112 	gdb_breakpoint "$main_solib_srcfile:$line"
    113 	gdb_continue_to_breakpoint "break here 1"
    114 
    115 	gdb_test "info function jit_function" "$match_str"
    116 
    117 	# This is just to help debugging when things fail
    118 	if {$test_verbose > 0} {
    119 	    gdb_test "maintenance print objfiles"
    120 	    gdb_test "maintenance info break"
    121 	}
    122 
    123 	set line [gdb_get_line_number {break here 2} $main_solib_srcfile]
    124 	gdb_breakpoint "$main_solib_srcfile:$line"
    125 	gdb_continue_to_breakpoint "break here 2"
    126 
    127 	# All jit librares must have been unregistered
    128 	gdb_test "info function jit_function" \
    129 	    "All functions matching regular expression \"jit_function\":" \
    130 	    "info function jit_function after unregistration"
    131     }
    132 }
    133 
    134 # Compile the main code (which loads the JIT objects) as a shared library.
    135 if { [compile_jit_elf_main_as_so $main_solib_srcfile $main_solib_binfile \
    136 	{additional_flags="-DMAIN=jit_dl_main"}] < 0 } {
    137     return
    138 }
    139 
    140 set main_solib_binfile_target \
    141     [gdb_download_shlib $main_solib_binfile]
    142 
    143 # Compile the "real" main for this test.
    144 if { [compile_jit_dlmain {shlib_load}] < 0 } {
    145     return
    146 }
    147 
    148 # Compile two shared libraries to use as JIT objects.
    149 set jit_solibs_target [compile_and_download_n_jit_so \
    150 		      $jit_solib_basename $jit_solib_srcfile 2]
    151 if { $jit_solibs_target == -1 } {
    152     return
    153 }
    154 
    155 one_jit_test [lindex $jit_solibs_target 0] "${hex}  jit_function_0001"
    156 one_jit_test $jit_solibs_target "${hex}  jit_function_0001\[\r\n\]+${hex}  jit_function_0002"
    157 
    158 foreach solib $jit_solibs_target {
    159     # We don't intend to load the .so as a JIT debuginfo reader, but we
    160     # need some handy file name for a completion test.
    161     set input [string range $solib 0 [expr { [string length $solib] - 2 }]]
    162     gdb_test \
    163 	"complete jit-reader-load [standard_output_file $input]" \
    164 	"jit-reader-load \[^\r\n\]*$solib" \
    165 	"test jit-reader-load filename completion [file tail $solib]"
    166 }
    167