X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftestsuite%2Flib%2Fgdb.exp;h=25d370ebb52832af97287a3b9e1d807d35960bd4;hb=2e62ab400ff96334c92e5acf0a462cb9dc0d19a7;hp=3e2f755e5b77a0db9e7294d3b117dc17a5293367;hpb=c708f4d256f1f1a92310fcb323a108d95d5fd5da;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 3e2f755e5b..25d370ebb5 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -1,4 +1,4 @@ -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2019 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 @@ -906,10 +906,13 @@ proc gdb_test_multiple { command message user_code } { } } append code $processed_code + + # Reset the spawn id, in case the processed code used -i. append code { - # Reset the spawn id, in case the processed code used -i. -i "$gdb_spawn_id" + } + append code { -re "Ending remote debugging.*$gdb_prompt $" { if ![isnative] then { warning "Can`t communicate to remote target." @@ -980,7 +983,20 @@ proc gdb_test_multiple { command message user_code } { set result -1 } - # Patterns below apply to any spawn id specified. + -i $gdb_spawn_id + eof { + perror "GDB process no longer exists" + set wait_status [wait -i $gdb_spawn_id] + verbose -log "GDB process exited with wait status $wait_status" + if { $message != "" } { + fail "$message" + } + return -1 + } + } + + # Now patterns that apply to any spawn id specified. + append code { -i $any_spawn_id eof { perror "Process no longer exists" @@ -1002,6 +1018,20 @@ proc gdb_test_multiple { command message user_code } { } } + # remote_expect calls the eof section if there is an error on the + # expect call. We already have eof sections above, and we don't + # want them to get called in that situation. Since the last eof + # section becomes the error section, here we define another eof + # section, but with an empty spawn_id list, so that it won't ever + # match. + append code { + -i "" eof { + # This comment is here because the eof section must not be + # the empty string, otherwise remote_expect won't realize + # it exists. + } + } + set result 0 set code [catch {gdb_expect $code} string] if {$code == 1} { @@ -1360,6 +1390,36 @@ proc gdb_test_stdio {command inferior_pattern {gdb_pattern ""} {message ""}} { return $res } +# get_print_expr_at_depths EXP OUTPUTS +# +# Used for testing 'set print max-depth'. Prints the expression EXP +# with 'set print max-depth' set to various depths. OUTPUTS is a list +# of `n` different patterns to match at each of the depths from 0 to +# (`n` - 1). +# +# This proc does one final check with the max-depth set to 'unlimited' +# which is tested against the last pattern in the OUTPUTS list. The +# OUTPUTS list is therefore required to match every depth from 0 to a +# depth where the whole of EXP is printed with no ellipsis. +# +# This proc leaves the 'set print max-depth' set to 'unlimited'. +proc gdb_print_expr_at_depths {exp outputs} { + for { set depth 0 } { $depth <= [llength $outputs] } { incr depth } { + if { $depth == [llength $outputs] } { + set expected_result [lindex $outputs [expr [llength $outputs] - 1]] + set depth_string "unlimited" + } else { + set expected_result [lindex $outputs $depth] + set depth_string $depth + } + + with_test_prefix "exp='$exp': depth=${depth_string}" { + gdb_test_no_output "set print max-depth ${depth_string}" + gdb_test "p $exp" "$expected_result" + } + } +} + # Issue a PASS and return true if evaluating CONDITION in the caller's @@ -1523,17 +1583,17 @@ proc gdb_file_cmd { arg } { send_gdb "file $arg\n" gdb_expect 120 { - -re "Reading symbols from.*LZMA support was disabled.*done.*$gdb_prompt $" { + -re "Reading symbols from.*LZMA support was disabled.*$gdb_prompt $" { verbose "\t\tLoaded $arg into $GDB; .gnu_debugdata found but no LZMA available" set gdb_file_cmd_debug_info "lzma" return 0 } - -re "Reading symbols from.*no debugging symbols found.*done.*$gdb_prompt $" { + -re "Reading symbols from.*no debugging symbols found.*$gdb_prompt $" { verbose "\t\tLoaded $arg into $GDB with no debugging symbols" set gdb_file_cmd_debug_info "nodebug" return 0 } - -re "Reading symbols from.*done.*$gdb_prompt $" { + -re "Reading symbols from.*$gdb_prompt $" { verbose "\t\tLoaded $arg into $GDB" set gdb_file_cmd_debug_info "debug" return 0 @@ -1541,7 +1601,7 @@ proc gdb_file_cmd { arg } { -re "Load new symbol table from \".*\".*y or n. $" { send_gdb "y\n" gdb_expect 120 { - -re "Reading symbols from.*done.*$gdb_prompt $" { + -re "Reading symbols from.*$gdb_prompt $" { verbose "\t\tLoaded $arg with new symbol table into $GDB" set gdb_file_cmd_debug_info "debug" return 0 @@ -1627,7 +1687,7 @@ proc default_gdb_spawn { } { # Default gdb_start procedure. proc default_gdb_start { } { - global gdb_prompt pagination_prompt + global gdb_prompt global gdb_spawn_id global inferior_spawn_id @@ -1648,29 +1708,20 @@ proc default_gdb_start { } { # When running over NFS, particularly if running many simultaneous # tests on different hosts all using the same server, things can # get really slow. Give gdb at least 3 minutes to start up. - set loop_again 1 - while { $loop_again } { - set loop_again 0 - gdb_expect 360 { - -re "$pagination_prompt" { - verbose "Hit pagination during startup. Pressing enter to continue." - send_gdb "\n" - set loop_again 1 - } - -re "\[\r\n\]$gdb_prompt $" { - verbose "GDB initialized." - } - -re "$gdb_prompt $" { - perror "GDB never initialized." - unset gdb_spawn_id - return -1 - } - timeout { - perror "(timeout) GDB never initialized after 10 seconds." - remote_close host - unset gdb_spawn_id - return -1 - } + gdb_expect 360 { + -re "\[\r\n\]$gdb_prompt $" { + verbose "GDB initialized." + } + -re "$gdb_prompt $" { + perror "GDB never initialized." + unset gdb_spawn_id + return -1 + } + timeout { + perror "(timeout) GDB never initialized after 10 seconds." + remote_close host + unset gdb_spawn_id + return -1 } } @@ -1801,7 +1852,6 @@ proc skip_rust_tests {} { proc skip_python_tests_prompt { prompt_regexp } { global gdb_py_is_py3k - global gdb_py_is_py24 gdb_test_multiple "python print ('test')" "verify python support" { -re "not supported.*$prompt_regexp" { @@ -1811,7 +1861,6 @@ proc skip_python_tests_prompt { prompt_regexp } { -re "$prompt_regexp" {} } - set gdb_py_is_py24 0 gdb_test_multiple "python print (sys.version_info\[0\])" "check if python 3" { -re "3.*$prompt_regexp" { set gdb_py_is_py3k 1 @@ -1820,16 +1869,6 @@ proc skip_python_tests_prompt { prompt_regexp } { set gdb_py_is_py3k 0 } } - if { $gdb_py_is_py3k == 0 } { - gdb_test_multiple "python print (sys.version_info\[1\])" "check if python 2.4" { - -re "\[45\].*$prompt_regexp" { - set gdb_py_is_py24 1 - } - -re ".*$prompt_regexp" { - set gdb_py_is_py24 0 - } - } - } return 0 } @@ -2272,35 +2311,16 @@ gdb_caching_proc support_complex_tests { return 0 } - # Set up, compile, and execute a test program containing _Complex types. - # Include the current process ID in the file names to prevent conflicts - # with invocations for multiple testsuites. - set src [standard_temp_file complex[pid].c] - set exe [standard_temp_file complex[pid].x] + # Compile a test program containing _Complex types. - gdb_produce_source $src { + return [gdb_can_simple_compile complex { int main() { _Complex float cf; _Complex double cd; _Complex long double cld; return 0; } - } - - verbose "compiling testfile $src" 2 - set compile_flags {debug nowarnings quiet} - set lines [gdb_compile $src $exe executable $compile_flags] - file delete $src - file delete $exe - - if ![string match "" $lines] then { - verbose "testfile compilation failed, returning 0" 2 - set result 0 - } else { - set result 1 - } - - return $result + } executable] } # Return 1 if GDB can get a type for siginfo from the target, otherwise @@ -2395,21 +2415,9 @@ proc readline_is_used { } { gdb_caching_proc is_elf_target { set me "is_elf_target" - set src [standard_temp_file is_elf_target[pid].c] - set obj [standard_temp_file is_elf_target[pid].o] - - gdb_produce_source $src { - int foo () {return 0;} - } - - verbose "$me: compiling testfile $src" 2 - set lines [gdb_compile $src $obj object {quiet}] - - file delete $src - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 0" 2 - return 0 + set src { int foo () {return 0;} } + if {![gdb_simple_compile elf_target $src]} { + return 0 } set fp_obj [open $obj "r"] @@ -2462,86 +2470,32 @@ proc gdb_produce_source { name sources } { # This cannot be decided simply from looking at the target string, # as it might depend on externally passed compiler options like -m64. gdb_caching_proc is_ilp32_target { - set me "is_ilp32_target" - - set src [standard_temp_file ilp32[pid].c] - set obj [standard_temp_file ilp32[pid].o] - - gdb_produce_source $src { + return [gdb_can_simple_compile is_ilp32_target { int dummy[sizeof (int) == 4 && sizeof (void *) == 4 && sizeof (long) == 4 ? 1 : -1]; - } - - verbose "$me: compiling testfile $src" 2 - set lines [gdb_compile $src $obj object {quiet}] - file delete $src - file delete $obj - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 0" 2 - return 0 - } - - verbose "$me: returning 1" 2 - return 1 + }] } # Return 1 if target is LP64. # This cannot be decided simply from looking at the target string, # as it might depend on externally passed compiler options like -m64. gdb_caching_proc is_lp64_target { - set me "is_lp64_target" - - set src [standard_temp_file lp64[pid].c] - set obj [standard_temp_file lp64[pid].o] - - gdb_produce_source $src { + return [gdb_can_simple_compile is_lp64_target { int dummy[sizeof (int) == 4 && sizeof (void *) == 8 && sizeof (long) == 8 ? 1 : -1]; - } - - verbose "$me: compiling testfile $src" 2 - set lines [gdb_compile $src $obj object {quiet}] - file delete $src - file delete $obj - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 0" 2 - return 0 - } - - verbose "$me: returning 1" 2 - return 1 + }] } # Return 1 if target has 64 bit addresses. # This cannot be decided simply from looking at the target string, # as it might depend on externally passed compiler options like -m64. gdb_caching_proc is_64_target { - set me "is_64_target" - - set src [standard_temp_file is64[pid].c] - set obj [standard_temp_file is64[pid].o] - - gdb_produce_source $src { + return [gdb_can_simple_compile is_64_target { int function(void) { return 3; } int dummy[sizeof (&function) == 8 ? 1 : -1]; - } - - verbose "$me: compiling testfile $src" 2 - set lines [gdb_compile $src $obj object {quiet}] - file delete $src - file delete $obj - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 0" 2 - return 0 - } - - verbose "$me: returning 1" 2 - return 1 + }] } # Return 1 if target has x86_64 registers - either amd64 or x32. @@ -2552,30 +2506,14 @@ gdb_caching_proc is_amd64_regs_target { return 0 } - set me "is_amd64_regs_target" - - set src [standard_temp_file reg64[pid].s] - set obj [standard_temp_file reg64[pid].o] + return [gdb_can_simple_compile is_amd64_regs_target { + int main (void) { + asm ("incq %rax"); + asm ("incq %r15"); - set list {} - foreach reg \ - {rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15} { - lappend list "\tincq %$reg" + return 0; } - gdb_produce_source $src [join $list \n] - - verbose "$me: compiling testfile $src" 2 - set lines [gdb_compile $src $obj object {quiet}] - file delete $src - file delete $obj - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 0" 2 - return 0 - } - - verbose "$me: returning 1" 2 - return 1 + }] } # Return 1 if this target is an x86 or x86-64 with -m32. @@ -2597,30 +2535,13 @@ gdb_caching_proc is_aarch32_target { return 0 } - set me "is_aarch32_target" - - set src [standard_temp_file aarch32[pid].s] - set obj [standard_temp_file aarch32[pid].o] - set list {} foreach reg \ {r0 r1 r2 r3} { lappend list "\tmov $reg, $reg" } - gdb_produce_source $src [join $list \n] - - verbose "$me: compiling testfile $src" 2 - set lines [gdb_compile $src $obj object {quiet}] - file delete $src - file delete $obj - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 0" 2 - return 0 - } - verbose "$me: returning 1" 2 - return 1 + return [gdb_can_simple_compile aarch32 [join $list \n]] } # Return 1 if this target is an aarch64, either lp64 or ilp32. @@ -2661,27 +2582,21 @@ gdb_caching_proc skip_altivec_tests { } # Make sure we have a compiler that understands altivec. - set compile_flags {debug nowarnings} if [get_compiler_info] { warning "Could not get compiler info" return 1 } if [test_compiler_info gcc*] { - set compile_flags "$compile_flags additional_flags=-maltivec" + set compile_flags "additional_flags=-maltivec" } elseif [test_compiler_info xlc*] { - set compile_flags "$compile_flags additional_flags=-qaltivec" + set compile_flags "additional_flags=-qaltivec" } else { verbose "Could not compile with altivec support, returning 1" 2 return 1 } - # Set up, compile, and execute a test program containing VMX instructions. - # Include the current process ID in the file names to prevent conflicts - # with invocations for multiple testsuites. - set src [standard_temp_file vmx[pid].c] - set exe [standard_temp_file vmx[pid].x] - - gdb_produce_source $src { + # Compile a test program containing VMX instructions. + set src { int main() { #ifdef __MACH__ asm volatile ("vor v0,v0,v0"); @@ -2691,22 +2606,16 @@ gdb_caching_proc skip_altivec_tests { return 0; } } - - verbose "$me: compiling testfile $src" 2 - set lines [gdb_compile $src $exe executable $compile_flags] - file delete $src - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 1" 2 + if {![gdb_simple_compile $me $src executable $compile_flags]} { return 1 } - # No error message, compilation succeeded so now run it via gdb. + # Compilation succeeded so now run it via gdb. gdb_exit gdb_start gdb_reinitialize_dir $srcdir/$subdir - gdb_load "$exe" + gdb_load "$obj" gdb_run_cmd gdb_expect { -re ".*Illegal instruction.*${gdb_prompt} $" { @@ -2723,7 +2632,7 @@ gdb_caching_proc skip_altivec_tests { } } gdb_exit - remote_file build delete $exe + remote_file build delete $obj verbose "$me: returning $skip_vmx_tests" 2 return $skip_vmx_tests @@ -2745,24 +2654,21 @@ gdb_caching_proc skip_vsx_tests { } # Make sure we have a compiler that understands altivec. - set compile_flags {debug nowarnings quiet} if [get_compiler_info] { warning "Could not get compiler info" return 1 } if [test_compiler_info gcc*] { - set compile_flags "$compile_flags additional_flags=-mvsx" + set compile_flags "additional_flags=-mvsx" } elseif [test_compiler_info xlc*] { - set compile_flags "$compile_flags additional_flags=-qasm=gcc" + set compile_flags "additional_flags=-qasm=gcc" } else { verbose "Could not compile with vsx support, returning 1" 2 return 1 } - set src [standard_temp_file vsx[pid].c] - set exe [standard_temp_file vsx[pid].x] - - gdb_produce_source $src { + # Compile a test program containing VSX instructions. + set src { int main() { double a[2] = { 1.0, 2.0 }; #ifdef __MACH__ @@ -2773,13 +2679,7 @@ gdb_caching_proc skip_vsx_tests { return 0; } } - - verbose "$me: compiling testfile $src" 2 - set lines [gdb_compile $src $exe executable $compile_flags] - file delete $src - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 1" 2 + if {![gdb_simple_compile $me $src executable $compile_flags]} { return 1 } @@ -2788,7 +2688,7 @@ gdb_caching_proc skip_vsx_tests { gdb_exit gdb_start gdb_reinitialize_dir $srcdir/$subdir - gdb_load "$exe" + gdb_load "$obj" gdb_run_cmd gdb_expect { -re ".*Illegal instruction.*${gdb_prompt} $" { @@ -2805,7 +2705,7 @@ gdb_caching_proc skip_vsx_tests { } } gdb_exit - remote_file build delete $exe + remote_file build delete $obj verbose "$me: returning $skip_vsx_tests" 2 return $skip_vsx_tests @@ -2819,24 +2719,16 @@ gdb_caching_proc skip_tsx_tests { set me "skip_tsx_tests" - set src [standard_temp_file tsx[pid].c] - set exe [standard_temp_file tsx[pid].x] - - gdb_produce_source $src { - int main() { - asm volatile ("xbegin .L0"); - asm volatile ("xend"); - asm volatile (".L0: nop"); - return 0; - } + # Compile a test program. + set src { + int main() { + asm volatile ("xbegin .L0"); + asm volatile ("xend"); + asm volatile (".L0: nop"); + return 0; + } } - - verbose "$me: compiling testfile $src" 2 - set lines [gdb_compile $src $exe executable {nowarnings quiet}] - file delete $src - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed." 2 + if {![gdb_simple_compile $me $src executable]} { return 1 } @@ -2845,7 +2737,7 @@ gdb_caching_proc skip_tsx_tests { gdb_exit gdb_start gdb_reinitialize_dir $srcdir/$subdir - gdb_load "$exe" + gdb_load "$obj" gdb_run_cmd gdb_expect { -re ".*Illegal instruction.*${gdb_prompt} $" { @@ -2862,7 +2754,7 @@ gdb_caching_proc skip_tsx_tests { } } gdb_exit - remote_file build delete $exe + remote_file build delete $obj verbose "$me: returning $skip_tsx_tests" 2 return $skip_tsx_tests @@ -2880,24 +2772,10 @@ gdb_caching_proc skip_btrace_tests { return 1 } - # Set up, compile, and execute a test program. - # Include the current process ID in the file names to prevent conflicts - # with invocations for multiple testsuites. - set src [standard_temp_file btrace[pid].c] - set exe [standard_temp_file btrace[pid].x] - - gdb_produce_source $src { - int main(void) { return 0; } - } - - verbose "$me: compiling testfile $src" 2 - set compile_flags {debug nowarnings quiet} - set lines [gdb_compile $src $exe executable $compile_flags] - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 1" 2 - file delete $src - return 1 + # Compile a test program. + set src { int main() { return 0; } } + if {![gdb_simple_compile $me $src executable]} { + return 0 } # No error message, compilation succeeded so now run it via gdb. @@ -2905,12 +2783,10 @@ gdb_caching_proc skip_btrace_tests { gdb_exit gdb_start gdb_reinitialize_dir $srcdir/$subdir - gdb_load $exe + gdb_load $obj if ![runto_main] { - file delete $src return 1 } - file delete $src # In case of an unexpected output, we return 2 as a fail value. set skip_btrace_tests 2 gdb_test_multiple "record btrace" "check btrace support" { @@ -2928,7 +2804,7 @@ gdb_caching_proc skip_btrace_tests { } } gdb_exit - remote_file build delete $exe + remote_file build delete $obj verbose "$me: returning $skip_btrace_tests" 2 return $skip_btrace_tests @@ -2947,24 +2823,10 @@ gdb_caching_proc skip_btrace_pt_tests { return 1 } - # Set up, compile, and execute a test program. - # Include the current process ID in the file names to prevent conflicts - # with invocations for multiple testsuites. - set src [standard_temp_file btrace[pid].c] - set exe [standard_temp_file btrace[pid].x] - - gdb_produce_source $src { - int main(void) { return 0; } - } - - verbose "$me: compiling testfile $src" 2 - set compile_flags {debug nowarnings quiet} - set lines [gdb_compile $src $exe executable $compile_flags] - - if ![string match "" $lines] then { - verbose "$me: testfile compilation failed, returning 1" 2 - file delete $src - return 1 + # Compile a test program. + set src { int main() { return 0; } } + if {![gdb_simple_compile $me $src executable]} { + return 0 } # No error message, compilation succeeded so now run it via gdb. @@ -2972,12 +2834,10 @@ gdb_caching_proc skip_btrace_pt_tests { gdb_exit gdb_start gdb_reinitialize_dir $srcdir/$subdir - gdb_load $exe + gdb_load $obj if ![runto_main] { - file delete $src return 1 } - file delete $src # In case of an unexpected output, we return 2 as a fail value. set skip_btrace_tests 2 gdb_test_multiple "record btrace pt" "check btrace pt support" { @@ -2998,30 +2858,68 @@ gdb_caching_proc skip_btrace_pt_tests { } } gdb_exit - remote_file build delete $exe + remote_file build delete $obj verbose "$me: returning $skip_btrace_tests" 2 return $skip_btrace_tests } -# A helper that compiles a test case to see if __int128 is supported. -proc gdb_int128_helper {lang} { - set src [standard_temp_file i128[pid].c] - set obj [standard_temp_file i128[pid].o] +# Run a test on the target to see if it supports Aarch64 SVE hardware. +# Return 0 if so, 1 if it does not. Note this causes a restart of GDB. - verbose -log "checking $lang for __int128" - gdb_produce_source $src { - __int128 x; - int main() { return 0; } +gdb_caching_proc skip_aarch64_sve_tests { + global srcdir subdir gdb_prompt inferior_exited_re + + set me "skip_aarch64_sve_tests" + + if { ![is_aarch64_target]} { + return 1 } - set lines [gdb_compile $src $obj object [list nowarnings quiet $lang]] - file delete $src - file delete $obj + set compile_flags "{additional_flags=-march=armv8-a+sve}" - set result [expr {!![string match "" $lines]}] - verbose -log "__int128 for $lang result = $result" - return $result + # Compile a test program containing SVE instructions. + set src { + int main() { + asm volatile ("ptrue p0.b"); + return 0; + } + } + if {![gdb_simple_compile $me $src executable $compile_flags]} { + return 1 + } + + # Compilation succeeded so now run it via gdb. + clean_restart $obj + gdb_run_cmd + gdb_expect { + -re ".*Illegal instruction.*${gdb_prompt} $" { + verbose -log "\n$me sve hardware not detected" + set skip_sve_tests 1 + } + -re ".*$inferior_exited_re normally.*${gdb_prompt} $" { + verbose -log "\n$me: sve hardware detected" + set skip_sve_tests 0 + } + default { + warning "\n$me: default case taken" + set skip_sve_tests 1 + } + } + gdb_exit + remote_file build delete $obj + + verbose "$me: returning $skip_sve_tests" 2 + return $skip_sve_tests +} + + +# A helper that compiles a test case to see if __int128 is supported. +proc gdb_int128_helper {lang} { + return [gdb_can_simple_compile "i128-for-$lang" { + __int128 x; + int main() { return 0; } + } executable $lang] } # Return true if the C compiler understands the __int128 type. @@ -3034,6 +2932,20 @@ gdb_caching_proc has_int128_cxx { return [gdb_int128_helper c++] } +# Return true if the IFUNC feature is unsupported. +gdb_caching_proc skip_ifunc_tests { + if [gdb_can_simple_compile ifunc { + extern void f_ (); + typedef void F (void); + F* g (void) { return &f_; } + void f () __attribute__ ((ifunc ("g"))); + } object] { + return 0 + } else { + return 1 + } +} + # Return whether we should skip tests for showing inlined functions in # backtraces. Requires get_compiler_info and get_debug_format. @@ -3392,12 +3304,12 @@ proc get_compiler_info {{arg ""}} { # We have to use -E and -o together, despite the comments # above, because of how DejaGnu handles remote host testing. set ppout "$outdir/compiler.i" - gdb_compile "${ifile}" "$ppout" preprocess [list "$arg" quiet] + gdb_compile "${ifile}" "$ppout" preprocess [list "$arg" quiet getting_compiler_info] set file [open $ppout r] set cppout [read $file] close $file } else { - set cppout [ gdb_compile "${ifile}" "" preprocess [list "$arg" quiet] ] + set cppout [ gdb_compile "${ifile}" "" preprocess [list "$arg" quiet getting_compiler_info] ] } eval log_file $saved_log @@ -3524,6 +3436,57 @@ gdb_caching_proc universal_compile_options { return $options } +# Compile the code in $code to a file based on $name, using the flags +# $compile_flag as well as debug, nowarning and quiet. +# Return 1 if code can be compiled +# Leave the file name of the resulting object in the upvar object. + +proc gdb_simple_compile {name code {type object} {compile_flags {}} {object obj}} { + upvar $object obj + + switch -regexp -- $type { + "executable" { + set postfix "x" + } + "object" { + set postfix "o" + } + "preprocess" { + set postfix "i" + } + "assembly" { + set postfix "s" + } + } + set src [standard_temp_file $name-[pid].c] + set obj [standard_temp_file $name-[pid].$postfix] + set compile_flags [concat $compile_flags {debug nowarnings quiet}] + + gdb_produce_source $src $code + + verbose "$name: compiling testfile $src" 2 + set lines [gdb_compile $src $obj $type $compile_flags] + + file delete $src + + if ![string match "" $lines] then { + verbose "$name: compilation failed, returning 0" 2 + return 0 + } + return 1 +} + +# Compile the code in $code to a file based on $name, using the flags +# $compile_flag as well as debug, nowarning and quiet. +# Return 1 if code can be compiled +# Delete all created files and objects. + +proc gdb_can_simple_compile {name code {type object} {compile_flags ""}} { + set ret [gdb_simple_compile $name $code $type $compile_flags temp_obj] + file delete $temp_obj + return $ret +} + # Some targets need to always link a special object in. Save its path here. global gdb_saved_set_unbuffered_mode_obj set gdb_saved_set_unbuffered_mode_obj "" @@ -3547,6 +3510,8 @@ set gdb_saved_set_unbuffered_mode_obj "" # dynamically load libraries at runtime. For example, on Linux, this adds # -ldl so that the test can use dlopen. # - nowarnings: Inhibit all compiler warnings. +# - pie: Force creation of PIE executables. +# - nopie: Prevent creation of PIE executables. # # And here are some of the not too obscure options understood by DejaGnu that # influence the compilation: @@ -3583,6 +3548,7 @@ proc gdb_compile {source dest type options} { } set shlib_found 0 set shlib_load 0 + set getting_compiler_info 0 foreach opt $options { if {[regexp {^shlib=(.*)} $opt dummy_var shlib_name] && $type == "executable"} { @@ -3613,11 +3579,27 @@ proc gdb_compile {source dest type options} { } } elseif { $opt == "shlib_load" && $type == "executable" } { set shlib_load 1 + } elseif { $opt == "getting_compiler_info" } { + # If this is set, calling test_compiler_info will cause recursion. + set getting_compiler_info 1 } else { lappend new_options $opt } } + # Ensure stack protector is disabled for GCC, as this causes problems with + # DWARF line numbering. + # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88432 + # This option defaults to on for Debian/Ubuntu. + if { $getting_compiler_info == 0 + && [test_compiler_info {gcc-*-*}] + && !([test_compiler_info {gcc-[0-3]-*}] + || [test_compiler_info {gcc-4-0-*}]) + && [lsearch -exact $options rust] == -1} { + # Put it at the front to not override any user-provided value. + lappend new_options "early_flags=-fno-stack-protector" + } + # Because we link with libraries using their basename, we may need # (depending on the platform) to set a special rpath value, to allow # the executable to find the libraries it depends on. @@ -3668,6 +3650,43 @@ proc gdb_compile {source dest type options} { set options [lreplace $options $nowarnings $nowarnings $flag] } + # Replace the "pie" option with the appropriate compiler and linker flags + # to enable PIE executables. + set pie [lsearch -exact $options pie] + if {$pie != -1} { + if [target_info exists gdb,pie_flag] { + set flag "additional_flags=[target_info gdb,pie_flag]" + } else { + # For safety, use fPIE rather than fpie. On AArch64, m68k, PowerPC + # and SPARC, fpie can cause compile errors due to the GOT exceeding + # a maximum size. On other architectures the two flags are + # identical (see the GCC manual). Note Debian9 and Ubuntu16.10 + # onwards default GCC to using fPIE. If you do require fpie, then + # it can be set using the pie_flag. + set flag "additional_flags=-fPIE" + } + set options [lreplace $options $pie $pie $flag] + + if [target_info exists gdb,pie_ldflag] { + set flag "ldflags=[target_info gdb,pie_ldflag]" + } else { + set flag "ldflags=-pie" + } + lappend options "$flag" + } + + # Replace the "nopie" option with the appropriate linker flag to disable + # PIE executables. There are no compiler flags for this option. + set nopie [lsearch -exact $options nopie] + if {$nopie != -1} { + if [target_info exists gdb,nopie_flag] { + set flag "ldflags=[target_info gdb,nopie_flag]" + } else { + set flag "ldflags=-no-pie" + } + set options [lreplace $options $nopie $nopie $flag] + } + if { $type == "executable" } { if { ([istarget "*-*-mingw*"] || [istarget "*-*-*djgpp"] @@ -4784,10 +4803,14 @@ proc gdb_init { test_file_name } { # read from this file. setenv INPUTRC "/dev/null" - # The gdb.base/readline.exp arrow key test relies on the standard VT100 - # bindings, so make sure that an appropriate terminal is selected. - # The same bug doesn't show up if we use ^P / ^N instead. - setenv TERM "vt100" + # This disables style output, which would interfere with many + # tests. + setenv TERM "dumb" + + # Initialize GDB's pty with a fixed size, to make sure we avoid pagination + # during startup. See "man expect" for details about stty_init. + global stty_init + set stty_init "rows 25 cols 80" # Some tests (for example gdb.base/maint.exp) shell out from gdb to use # grep. Clear GREP_OPTIONS to make the behavior predictable, @@ -5225,18 +5248,13 @@ gdb_caching_proc gdb_skip_xml_test { gdb_caching_proc gdb_has_argv0 { set result 0 - # Set up, compile, and execute a test program to check whether - # argv[0] is available. - set src [standard_temp_file has_argv0[pid].c] - set exe [standard_temp_file has_argv0[pid].x] - - gdb_produce_source $src { + # Compile and execute a test program to check whether argv[0] is available. + gdb_simple_compile has_argv0 { int main (int argc, char **argv) { return 0; } - } + } executable - gdb_compile $src $exe executable {debug} # Helper proc. proc gdb_has_argv0_1 { exe } { @@ -5307,11 +5325,10 @@ gdb_caching_proc gdb_has_argv0 { return $retval } - set result [gdb_has_argv0_1 $exe] + set result [gdb_has_argv0_1 $obj] gdb_exit - file delete $src - file delete $exe + file delete $obj if { !$result && ([istarget *-*-linux*] @@ -5707,7 +5724,7 @@ proc get_valueof { fmt exp default {test ""} } { gdb_test_multiple "print${fmt} ${exp}" "$test" { -re "\\$\[0-9\]* = (\[^\r\n\]*)\[\r\n\]*$gdb_prompt $" { set val $expect_out(1,string) - pass "$test ($val)" + pass "$test" } timeout { fail "$test (timeout)" @@ -6018,39 +6035,84 @@ proc core_find {binfile {deletefiles {}} {arg ""}} { # for linker symbol prefixes. gdb_caching_proc gdb_target_symbol_prefix { - # Set up and compile a simple test program... - set src [standard_temp_file main[pid].c] - set exe [standard_temp_file main[pid].x] + # Compile a simple test program... + set src { int main() { return 0; } } + if {![gdb_simple_compile target_symbol_prefix $src executable]} { + return 0 + } - gdb_produce_source $src { - int main() { - return 0; - } + set prefix "" + + set objdump_program [gdb_find_objdump] + set result [catch "exec $objdump_program --syms $obj" output] + + if { $result == 0 \ + && ![regexp -lineanchor \ + { ([^ a-zA-Z0-9]*)main$} $output dummy prefix] } { + verbose "gdb_target_symbol_prefix: Could not find main in objdump output; returning null prefix" 2 } - verbose "compiling testfile $src" 2 - set compile_flags {debug nowarnings quiet} - set lines [gdb_compile $src $exe executable $compile_flags] + file delete $obj - set prefix "" + return $prefix +} - if ![string match "" $lines] then { - verbose "gdb_target_symbol_prefix: testfile compilation failed, returning null prefix" 2 - } else { - set objdump_program [gdb_find_objdump] - set result [catch "exec $objdump_program --syms $exe" output] +# Return 1 if target supports scheduler locking, otherwise return 0. + +gdb_caching_proc target_supports_scheduler_locking { + global gdb_prompt + + set me "gdb_target_supports_scheduler_locking" + + set src { int main() { return 0; } } + if {![gdb_simple_compile $me $src executable]} { + return 0 + } + + clean_restart $obj + if ![runto_main] { + return 0 + } - if { $result == 0 \ - && ![regexp -lineanchor \ - { ([^ a-zA-Z0-9]*)main$} $output dummy prefix] } { - verbose "gdb_target_symbol_prefix: Could not find main in objdump output; returning null prefix" 2 + set supports_schedule_locking -1 + set current_schedule_locking_mode "" + + set test "reading current scheduler-locking mode" + gdb_test_multiple "show scheduler-locking" $test { + -re "Mode for locking scheduler during execution is \"(\[\^\"\]*)\".*$gdb_prompt" { + set current_schedule_locking_mode $expect_out(1,string) + } + -re "$gdb_prompt $" { + set supports_schedule_locking 0 + } + timeout { + set supports_schedule_locking 0 } } - file delete $src - file delete $exe + if { $supports_schedule_locking == -1 } { + set test "checking for scheduler-locking support" + gdb_test_multiple "set scheduler-locking $current_schedule_locking_mode" $test { + -re "Target '\[^'\]+' cannot support this command\..*$gdb_prompt $" { + set supports_schedule_locking 0 + } + -re "$gdb_prompt $" { + set supports_schedule_locking 1 + } + timeout { + set supports_schedule_locking 0 + } + } + } - return $prefix + if { $supports_schedule_locking == -1 } { + set supports_schedule_locking 0 + } + + gdb_exit + remote_file build delete $obj + verbose "$me: returning $supports_schedule_locking" 2 + return $supports_schedule_locking } # gdb_target_symbol returns the provided symbol with the correct prefix @@ -6286,5 +6348,56 @@ proc gdb_define_cmd {command command_list} { } } +# Override the 'cd' builtin with a version that ensures that the +# log file keeps pointing at the same file. We need this because +# unfortunately the path to the log file is recorded using an +# relative path name, and, we sometimes need to close/reopen the log +# after changing the current directory. See get_compiler_info. + +rename cd builtin_cd + +proc cd { dir } { + + # Get the existing log file flags. + set log_file_info [log_file -info] + + # Split the flags into args and file name. + set log_file_flags "" + set log_file_file "" + foreach arg [ split "$log_file_info" " "] { + if [string match "-*" $arg] { + lappend log_file_flags $arg + } else { + lappend log_file_file $arg + } + } + + # If there was an existing file, ensure it is an absolute path, and then + # reset logging. + if { $log_file_file != "" } { + set log_file_file [file normalize $log_file_file] + log_file + log_file $log_file_flags "$log_file_file" + } + + # Call the builtin version of cd. + builtin_cd $dir +} + +# Return a list of all languages supported by GDB, suitable for use in +# 'set language NAME'. This doesn't include either the 'local' or +# 'auto' keywords. +proc gdb_supported_languages {} { + return [list c objective-c c++ d go fortran modula-2 asm pascal \ + opencl rust minimal ada] +} + +# Check if debugging is enabled for gdbserver. + +proc gdbserver_debug_enabled { } { + # Always disabled for GDB only setups. + return 0 +} + # Always load compatibility stuff. load_lib future.exp