[gdb/testsuite] Fix "text file busy" errors with cc-with-tweaks.exp
[binutils-gdb.git] / gdb / testsuite / lib / gdb.exp
index 25d370ebb52832af97287a3b9e1d807d35960bd4..55e58584c8f30e81027afe5633eb71946a9b21bb 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 1992-2019 Free Software Foundation, Inc.
+# Copyright 1992-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
@@ -117,7 +117,7 @@ if ![info exists env(EXEEXT)] {
 
 set octal "\[0-7\]+"
 
-set inferior_exited_re "(\\\[Inferior \[0-9\]+ \\(.*\\) exited)"
+set inferior_exited_re "(?:\\\[Inferior \[0-9\]+ \\(\[^\n\r\]*\\) exited)"
 
 # A regular expression that matches a value history number.
 # E.g., $1, $2, etc.
@@ -159,7 +159,6 @@ proc gdb_version { } {
 #
 
 proc gdb_unload {} {
-    global verbose
     global GDB
     global gdb_prompt
     send_gdb "file\n"
@@ -167,11 +166,11 @@ proc gdb_unload {} {
        -re "No executable file now\[^\r\n\]*\[\r\n\]" { exp_continue }
        -re "No symbol file now\[^\r\n\]*\[\r\n\]" { exp_continue }
        -re "A program is being debugged already.*Are you sure you want to change the file.*y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -re "Discard symbol table from .*y or n.*$" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -re "$gdb_prompt $" {}
@@ -201,7 +200,7 @@ proc delete_breakpoints {} {
     set deleted 0
     gdb_test_multiple "delete breakpoints" "$msg" {
        -re "Delete all breakpoints.*y or n.*$" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -re "$gdb_prompt $" {
@@ -307,7 +306,7 @@ proc gdb_run_cmd {args} {
                    set start_attempt 0
                }
                -re "Line.* Jump anyway.*y or n. $" {
-                   send_gdb "y\n"
+                   send_gdb "y\n" answer
                }
                -re "The program is not being run.*$gdb_prompt $" {
                    if { [gdb_reload] != 0 } {
@@ -335,7 +334,7 @@ proc gdb_run_cmd {args} {
 # may test for additional start-up messages.
    gdb_expect 60 {
        -re "The program .* has been started already.*y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -notransfer -re "Starting program: \[^\r\n\]*" {}
@@ -374,7 +373,7 @@ proc gdb_start_cmd {args} {
     # may test for additional start-up messages.
     gdb_expect 60 {
        -re "The program .* has been started already.*y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -notransfer -re "Starting program: \[^\r\n\]*" {
@@ -411,7 +410,7 @@ proc gdb_starti_cmd {args} {
     send_gdb "starti $args\n"
     gdb_expect 60 {
        -re "The program .* has been started already.*y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            exp_continue
        }
        -re "Starting program: \[^\r\n\]*" {
@@ -633,10 +632,14 @@ proc gdb_continue_to_breakpoint {name {location_pattern .*}} {
     global gdb_prompt
     set full_name "continue to breakpoint: $name"
 
+    set kfail_pattern "Process record does not support instruction 0xfae64 at.*"
     gdb_test_multiple "continue" $full_name {
        -re "(?:Breakpoint|Temporary breakpoint) .* (at|in) $location_pattern\r\n$gdb_prompt $" {
            pass $full_name
        }
+       -re "\[\r\n\]*(?:$kfail_pattern)\[\r\n\]+$gdb_prompt $" {
+           kfail "gdb/25038" $full_name
+       }
     }
 }
 
@@ -673,11 +676,11 @@ proc gdb_internal_error_resync {} {
     while {$count < 10} {
        gdb_expect {
            -re "Quit this debugging session\\? \\(y or n\\) $" {
-               send_gdb "n\n"
+               send_gdb "n\n" answer
                incr count
            }
            -re "Create a core file of GDB\\? \\(y or n\\) $" {
-               send_gdb "n\n"
+               send_gdb "n\n" answer
                incr count
            }
            -re "$gdb_prompt $" {
@@ -695,13 +698,17 @@ proc gdb_internal_error_resync {} {
 }
 
 
-# gdb_test_multiple COMMAND MESSAGE EXPECT_ARGUMENTS
+# gdb_test_multiple COMMAND MESSAGE [ -promp PROMPT_REGEXP] [ -lbl ]
+#                   EXPECT_ARGUMENTS
 # Send a command to gdb; test the result.
 #
 # COMMAND is the command to execute, send to GDB with send_gdb.  If
 #   this is the null string no command is sent.
 # MESSAGE is a message to be printed with the built-in failure patterns
 #   if one of them matches.  If MESSAGE is empty COMMAND will be used.
+# -prompt PROMPT_REGEXP specifies a regexp matching the expected prompt
+#   after the command output.  If empty, defaults to "$gdb_prompt $".
+# -lbl specifies that line-by-line matching will be used.
 # EXPECT_ARGUMENTS will be fed to expect in addition to the standard
 #   patterns.  Pattern elements will be evaluated in the caller's
 #   context; action elements will be executed in the caller's context.
@@ -717,10 +724,24 @@ proc gdb_internal_error_resync {} {
 #
 # gdb_test_multiple "print foo" "test foo" {
 #    -re "expected output 1" {
-#        pass "print foo"
+#        pass "test foo"
+#    }
+#    -re "expected output 2" {
+#        fail "test foo"
+#    }
+# }
+#
+# Within action elements you can also make use of the variable
+# gdb_test_name.  This variable is setup automatically by
+# gdb_test_multiple, and contains the value of MESSAGE.  You can then
+# write this, which is equivalent to the above:
+#
+# gdb_test_multiple "print foo" "test foo" {
+#    -re "expected output 1" {
+#        pass $gdb_test_name
 #    }
 #    -re "expected output 2" {
-#        fail "print foo"
+#        fail $gdb_test_name
 #    }
 # }
 #
@@ -744,7 +765,35 @@ proc gdb_internal_error_resync {} {
 # expected from $gdb_spawn_id.  IOW, callers do not need to worry
 # about resetting "-i" back to $gdb_spawn_id explicitly.
 #
-proc gdb_test_multiple { command message user_code } {
+# In EXPECT_ARGUMENTS we can use a -wrap pattern flag, that wraps the regexp
+# pattern as gdb_test wraps its message argument.
+# This allows us to rewrite:
+#   gdb_test <command> <pattern> <message>
+# into:
+#   gdb_test_multiple <command> <message> {
+#       -re -wrap <pattern> {
+#           pass $gdb_test_name
+#       }
+#   }
+#
+# In EXPECT_ARGUMENTS, a pattern flag -early can be used.  It makes sure the
+# pattern is inserted before any implicit pattern added by gdb_test_multiple.
+# Using this pattern flag, we can f.i. setup a kfail for an assertion failure
+# <assert> during gdb_continue_to_breakpoint by the rewrite:
+#   gdb_continue_to_breakpoint <msg> <pattern>
+# into:
+#   set breakpoint_pattern "(?:Breakpoint|Temporary breakpoint) .* (at|in)"
+#   gdb_test_multiple "continue" "continue to breakpoint: <msg>"  {
+#      -early -re "internal-error: <assert>" {
+#          setup_kfail gdb/nnnnn "*-*-*"
+#          exp_continue
+#      }
+#      -re "$breakpoint_pattern <pattern>\r\n$gdb_prompt $" {
+#          pass $gdb_test_name
+#      }
+#    }
+#
+proc gdb_test_multiple { command message args } {
     global verbose use_gdb_stub
     global gdb_prompt pagination_prompt
     global GDB
@@ -754,6 +803,30 @@ proc gdb_test_multiple { command message user_code } {
     upvar expect_out expect_out
     global any_spawn_id
 
+    set line_by_line 0
+    set prompt_regexp ""
+    for {set i 0} {$i < [llength $args]} {incr i} {
+       set arg [lindex $args $i]
+       if { $arg  == "-prompt" } {
+           incr i
+           set prompt_regexp [lindex $args $i]
+       } elseif { $arg == "-lbl" } {
+           set line_by_line 1
+       } else {
+           set user_code $arg
+           break
+       }
+    }
+    if { [expr $i + 1] < [llength $args] } {
+       error "Too many arguments to gdb_test_multiple"
+    } elseif { ![info exists user_code] } {
+       error "Too few arguments to gdb_test_multiple"
+    }
+
+    if { "$prompt_regexp" == "" } {
+       set prompt_regexp "$gdb_prompt $"
+    }
+
     if { $message == "" } {
        set message $command
     }
@@ -798,37 +871,59 @@ proc gdb_test_multiple { command message user_code } {
     set subst_code [uplevel list $subst_code]
 
     set processed_code ""
+    set early_processed_code ""
+    # The variable current_list holds the name of the currently processed
+    # list, either processed_code or early_processed_code.
+    set current_list "processed_code"
     set patterns ""
     set expecting_action 0
     set expecting_arg 0
+    set wrap_pattern 0
     foreach item $user_code subst_item $subst_code {
        if { $item == "-n" || $item == "-notransfer" || $item == "-nocase" } {
-           lappend processed_code $item
+           lappend $current_list $item
            continue
        }
        if { $item == "-indices" || $item == "-re" || $item == "-ex" } {
-           lappend processed_code $item
+           lappend $current_list $item
+           continue
+       }
+       if { $item == "-early" } {
+           set current_list "early_processed_code"
            continue
        }
        if { $item == "-timeout" || $item == "-i" } {
            set expecting_arg 1
-           lappend processed_code $item
+           lappend $current_list $item
+           continue
+       }
+       if { $item == "-wrap" } {
+           set wrap_pattern 1
            continue
        }
        if { $expecting_arg } {
            set expecting_arg 0
-           lappend processed_code $subst_item
+           lappend $current_list $subst_item
            continue
        }
        if { $expecting_action } {
-           lappend processed_code "uplevel [list $item]"
+           lappend $current_list "uplevel [list $item]"
            set expecting_action 0
            # Cosmetic, no effect on the list.
-           append processed_code "\n"
+           append $current_list "\n"
+           # End the effect of -early, it only applies to one action.
+           set current_list "processed_code"
            continue
        }
        set expecting_action 1
-       lappend processed_code $subst_item
+       if { $wrap_pattern } {
+           # Wrap subst_item as is done for the gdb_test PATTERN argument.
+           lappend $current_list \
+               "\[\r\n\]*(?:$subst_item)\[\r\n\]+$gdb_prompt $"
+           set wrap_pattern 0
+       } else {
+           lappend $current_list $subst_item
+       }
        if {$patterns != ""} {
            append patterns "; "
        }
@@ -891,7 +986,8 @@ proc gdb_test_multiple { command message user_code } {
        }
     }
 
-    set code {
+    set code $early_processed_code
+    append code {
        -re ".*A problem internal to GDB has been detected" {
            fail "$message (GDB internal error)"
            gdb_internal_error_resync
@@ -913,7 +1009,7 @@ proc gdb_test_multiple { command message user_code } {
     }
 
     append code {
-       -re "Ending remote debugging.*$gdb_prompt $" {
+       -re "Ending remote debugging.*$prompt_regexp" {
            if ![isnative] then {
                warning "Can`t communicate to remote target."
            }
@@ -921,17 +1017,17 @@ proc gdb_test_multiple { command message user_code } {
            gdb_start
            set result -1
        }
-       -re "Undefined\[a-z\]* command:.*$gdb_prompt $" {
+       -re "Undefined\[a-z\]* command:.*$prompt_regexp" {
            perror "Undefined command \"$command\"."
            fail "$message"
            set result 1
        }
-       -re "Ambiguous command.*$gdb_prompt $" {
+       -re "Ambiguous command.*$prompt_regexp" {
            perror "\"$command\" is not a unique command name."
            fail "$message"
            set result 1
        }
-       -re "$inferior_exited_re with code \[0-9\]+.*$gdb_prompt $" {
+       -re "$inferior_exited_re with code \[0-9\]+.*$prompt_regexp" {
            if ![string match "" $message] then {
                set errmsg "$message (the program exited)"
            } else {
@@ -940,7 +1036,7 @@ proc gdb_test_multiple { command message user_code } {
            fail "$errmsg"
            set result -1
        }
-       -re "$inferior_exited_re normally.*$gdb_prompt $" {
+       -re "$inferior_exited_re normally.*$prompt_regexp" {
            if ![string match "" $message] then {
                set errmsg "$message (the program exited)"
            } else {
@@ -949,7 +1045,7 @@ proc gdb_test_multiple { command message user_code } {
            fail "$errmsg"
            set result -1
        }
-       -re "The program is not being run.*$gdb_prompt $" {
+       -re "The program is not being run.*$prompt_regexp" {
            if ![string match "" $message] then {
                set errmsg "$message (the program is no longer running)"
            } else {
@@ -958,7 +1054,7 @@ proc gdb_test_multiple { command message user_code } {
            fail "$errmsg"
            set result -1
        }
-       -re "\r\n$gdb_prompt $" {
+       -re "\r\n$prompt_regexp" {
            if ![string match "" $message] then {
                fail "$message"
            }
@@ -971,14 +1067,14 @@ proc gdb_test_multiple { command message user_code } {
            set result -1
        }
        -re "\\((y or n|y or \\\[n\\\]|\\\[y\\\] or n)\\) " {
-           send_gdb "n\n"
-           gdb_expect -re "$gdb_prompt $"
+           send_gdb "n\n" answer
+           gdb_expect -re "$prompt_regexp"
            fail "$message (got interactive prompt)"
            set result -1
        }
        -re "\\\[0\\\] cancel\r\n\\\[1\\\] all.*\r\n> $" {
            send_gdb "0\n"
-           gdb_expect -re "$gdb_prompt $"
+           gdb_expect -re "$prompt_regexp"
            fail "$message (got breakpoint menu)"
            set result -1
        }
@@ -995,6 +1091,14 @@ proc gdb_test_multiple { command message user_code } {
        }
     }
 
+    if {$line_by_line} {
+       append code {
+           -re "\r\n\[^\r\n\]*(?=\r\n)" {
+               exp_continue
+           }
+       }
+    }
+
     # Now patterns that apply to any spawn id specified.
     append code {
        -i $any_spawn_id
@@ -1032,8 +1136,28 @@ proc gdb_test_multiple { command message user_code } {
        }
     }
 
+    # Create gdb_test_name in the parent scope.  If this variable
+    # already exists, which it might if we have nested calls to
+    # gdb_test_multiple, then preserve the old value, otherwise,
+    # create a new variable in the parent scope.
+    upvar gdb_test_name gdb_test_name
+    if { [info exists gdb_test_name] } {
+       set gdb_test_name_old "$gdb_test_name"
+    }
+    set gdb_test_name "$message"
+
     set result 0
     set code [catch {gdb_expect $code} string]
+
+    # Clean up the gdb_test_name variable.  If we had a
+    # previous value then restore it, otherwise, delete the variable
+    # from the parent scope.
+    if { [info exists gdb_test_name_old] } {
+       set gdb_test_name "$gdb_test_name_old"
+    } else {
+       unset gdb_test_name
+    }
+
     if {$code == 1} {
        global errorInfo errorCode
        return -code error -errorinfo $errorInfo -errorcode $errorCode $string
@@ -1077,24 +1201,66 @@ proc gdb_test { args } {
     set command [lindex $args 0]
     set pattern [lindex $args 1]
 
-    if [llength $args]==5 {
-       set question_string [lindex $args 3]
-       set response_string [lindex $args 4]
-    } else {
-       set question_string "^FOOBAR$"
-    }
-
-    return [gdb_test_multiple $command $message {
+    set user_code {}
+    lappend user_code {
        -re "\[\r\n\]*(?:$pattern)\[\r\n\]+$gdb_prompt $" {
            if ![string match "" $message] then {
                pass "$message"
             }
         }
-       -re "(${question_string})$" {
-           send_gdb "$response_string\n"
-           exp_continue
+    }
+
+    if { [llength $args] == 5 } {
+       set question_string [lindex $args 3]
+       set response_string [lindex $args 4]
+       lappend user_code {
+           -re "(${question_string})$" {
+               send_gdb "$response_string\n"
+               exp_continue
+           }
        }
-     }]
+     }
+
+    set user_code [join $user_code]
+    return [gdb_test_multiple $command $message $user_code]
+}
+
+# Return 1 if version MAJOR.MINOR is at least AT_LEAST_MAJOR.AT_LEAST_MINOR.
+proc version_at_least { major minor at_least_major at_least_minor} {
+    if { $major > $at_least_major } {
+        return 1
+    } elseif { $major == $at_least_major \
+                  && $minor >= $at_least_minor } {
+        return 1
+    } else {
+        return 0
+    }
+}
+
+# Return 1 if tcl version used is at least MAJOR.MINOR
+proc tcl_version_at_least { major minor } {
+    global tcl_version
+    regexp {^([0-9]+)\.([0-9]+)$} $tcl_version \
+       dummy tcl_version_major tcl_version_minor
+    return [version_at_least $tcl_version_major $tcl_version_minor \
+               $major $minor]
+}
+
+if { [tcl_version_at_least 8 5] == 0 } {
+    # lrepeat was added in tcl 8.5.  Only add if missing.
+    proc lrepeat { n element } {
+        if { [string is integer -strict $n] == 0 } {
+            error "expected integer but got \"$n\""
+        }
+        if { $n < 0 } {
+            error "bad count \"$n\": must be integer >= 0"
+        }
+        set res [list]
+        for {set i 0} {$i < $n} {incr i} {
+            lappend res $element
+        }
+        return $res
+    }
 }
 
 # gdb_test_no_output COMMAND MESSAGE
@@ -1264,11 +1430,10 @@ proc gdb_test_exact { args } {
     regsub -all "\n" $pattern "\r\n" pattern
     if [llength $args]==3 then {
        set message [lindex $args 2]
-    } else {
-       set message $command
+       return [gdb_test $command $pattern $message]
     }
 
-    return [gdb_test $command $pattern $message]
+    return [gdb_test $command $pattern]
 }
 
 # Wrapper around gdb_test_multiple that looks for a list of expected
@@ -1451,7 +1616,7 @@ proc gdb_reinitialize_dir { subdir } {
     send_gdb "dir\n"
     gdb_expect 60 {
        -re "Reinitialize source path to empty.*y or n. " {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            gdb_expect 60 {
                -re "Source directories searched.*$gdb_prompt $" {
                    send_gdb "dir $subdir\n"
@@ -1481,7 +1646,6 @@ proc gdb_reinitialize_dir { subdir } {
 proc default_gdb_exit {} {
     global GDB
     global INTERNAL_GDBFLAGS GDBFLAGS
-    global verbose
     global gdb_spawn_id inferior_spawn_id
     global inotify_log_file
 
@@ -1511,7 +1675,7 @@ proc default_gdb_exit {} {
        send_gdb "quit\n"
        gdb_expect 10 {
            -re "y or n" {
-               send_gdb "y\n"
+               send_gdb "y\n" answer
                exp_continue
            }
            -re "DOSEXIT code" { }
@@ -1547,7 +1711,6 @@ proc default_gdb_exit {} {
 
 proc gdb_file_cmd { arg } {
     global gdb_prompt
-    global verbose
     global GDB
     global last_loaded_file
 
@@ -1568,11 +1731,12 @@ proc gdb_file_cmd { arg } {
     }
 
     # The file command used to kill the remote target.  For the benefit
-    # of the testsuite, preserve this behavior.
-    send_gdb "kill\n"
+    # of the testsuite, preserve this behavior.  Mark as optional so it doesn't
+    # get written to the stdin log.
+    send_gdb "kill\n" optional
     gdb_expect 120 {
        -re "Kill the program being debugged. .y or n. $" {
-           send_gdb "y\n"
+           send_gdb "y\n" answer
            verbose "\t\tKilling previous program being debugged"
            exp_continue
        }
@@ -1599,7 +1763,7 @@ proc gdb_file_cmd { arg } {
            return 0
         }
         -re "Load new symbol table from \".*\".*y or n. $" {
-            send_gdb "y\n"
+            send_gdb "y\n" answer
             gdb_expect 120 {
                 -re "Reading symbols from.*$gdb_prompt $" {
                     verbose "\t\tLoaded $arg with new symbol table into $GDB"
@@ -1663,6 +1827,7 @@ proc default_gdb_spawn { } {
     set use_gdb_stub [target_info exists use_gdb_stub]
 
     verbose "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS"
+    gdb_write_cmd_file "$GDB $INTERNAL_GDBFLAGS $GDBFLAGS"
 
     if [info exists gdb_spawn_id] {
        return 0
@@ -1695,6 +1860,12 @@ proc default_gdb_start { } {
        return 0
     }
 
+    # Keep track of the number of times GDB has been launched.
+    global gdb_instances
+    incr gdb_instances
+
+    gdb_stdin_log_init
+
     set res [gdb_spawn]
     if { $res != 0} {
        return $res
@@ -1746,6 +1917,8 @@ proc default_gdb_start { } {
            warning "Couldn't set the width to 0."
        }
     }
+
+    gdb_debug_init
     return 0
 }
 
@@ -1853,22 +2026,24 @@ proc skip_rust_tests {} {
 proc skip_python_tests_prompt { prompt_regexp } {
     global gdb_py_is_py3k
 
-    gdb_test_multiple "python print ('test')" "verify python support" {
-       -re "not supported.*$prompt_regexp" {
-           unsupported "Python support is disabled."
-           return 1
+    gdb_test_multiple "python print ('test')" "verify python support" \
+       -prompt "$prompt_regexp" {
+           -re "not supported.*$prompt_regexp" {
+               unsupported "Python support is disabled."
+               return 1
+           }
+           -re "$prompt_regexp" {}
        }
-       -re "$prompt_regexp" {}
-    }
 
-    gdb_test_multiple "python print (sys.version_info\[0\])" "check if python 3" {
-       -re "3.*$prompt_regexp" {
-            set gdb_py_is_py3k 1
-        }
-       -re ".*$prompt_regexp" {
-            set gdb_py_is_py3k 0
-        }
-    }
+    gdb_test_multiple "python print (sys.version_info\[0\])" "check if python 3" \
+       -prompt "$prompt_regexp" {
+           -re "3.*$prompt_regexp" {
+               set gdb_py_is_py3k 1
+           }
+           -re ".*$prompt_regexp" {
+               set gdb_py_is_py3k 0
+           }
+       }
 
     return 0
 }
@@ -2015,7 +2190,16 @@ proc foreach_with_prefix {var list body} {
     upvar 1 $var myvar
     foreach myvar $list {
        with_test_prefix "$var=$myvar" {
-           uplevel 1 $body
+           set code [catch {uplevel 1 $body} result]
+       }
+
+       if {$code == 1} {
+           global errorInfo errorCode
+           return -code $code -errorinfo $errorInfo -errorcode $errorCode $result
+       } elseif {$code == 3} {
+           break
+       } elseif {$code == 2} {
+           return -code $code $result
        }
     }
 }
@@ -2301,6 +2485,18 @@ proc with_timeout_factor { factor body } {
     }
 }
 
+# Run BODY with timeout factor FACTOR if check-read1 is used.
+
+proc with_read1_timeout_factor { factor body } {
+    if { [info exists ::env(READ1)] == 1 && $::env(READ1) == 1 } {
+       # Use timeout factor
+    } else {
+       # Reset timeout factor
+       set factor 1
+    }
+    return [uplevel [list with_timeout_factor $factor $body]]
+}
+
 # Return 1 if _Complex types are supported, otherwise, return 0.
 
 gdb_caching_proc support_complex_tests {
@@ -2323,6 +2519,18 @@ gdb_caching_proc support_complex_tests {
     } executable]
 }
 
+# Return 1 if compiling go is supported.
+gdb_caching_proc support_go_compile {
+
+    return [gdb_can_simple_compile go-hello {
+       package main
+       import "fmt"
+       func main() {
+           fmt.Println("hello world")
+       }
+    } executable go]
+}
+
 # Return 1 if GDB can get a type for siginfo from the target, otherwise
 # return 0.
 
@@ -2775,7 +2983,7 @@ gdb_caching_proc skip_btrace_tests {
     # Compile a test program.
     set src { int main() { return 0; } }
     if {![gdb_simple_compile $me $src executable]} {
-        return 0
+        return 1
     }
 
     # No error message, compilation succeeded so now run it via gdb.
@@ -2826,7 +3034,7 @@ gdb_caching_proc skip_btrace_pt_tests {
     # Compile a test program.
     set src { int main() { return 0; } }
     if {![gdb_simple_compile $me $src executable]} {
-        return 0
+        return 1
     }
 
     # No error message, compilation succeeded so now run it via gdb.
@@ -3083,22 +3291,29 @@ proc skip_unwinder_tests {} {
     return $ok
 }
 
-# Return 0 if we should skip tests that require the libstdc++ stap
+# Return 1 if we should skip tests that require the libstdc++ stap
 # probes.  This must be invoked while gdb is running, after shared
-# libraries have been loaded.
+# libraries have been loaded.  PROMPT_REGEXP is the expected prompt.
+
+proc skip_libstdcxx_probe_tests_prompt { prompt_regexp } {
+    set supported 0
+    gdb_test_multiple "info probe" "check for stap probe in libstdc++" \
+       -prompt "$prompt_regexp" {
+           -re ".*libstdcxx.*catch.*\r\n$prompt_regexp" {
+               set supported 1
+           }
+           -re "\r\n$prompt_regexp" {
+           }
+       }
+    set skip [expr !$supported]
+    return $skip
+}
+
+# As skip_libstdcxx_probe_tests_prompt, with gdb_prompt.
 
 proc skip_libstdcxx_probe_tests {} {
     global gdb_prompt
-
-    set ok 0
-    gdb_test_multiple "info probe" "check for stap probe in libstdc++" {
-       -re ".*libstdcxx.*catch.*\r\n$gdb_prompt $" {
-           set ok 1
-       }
-       -re "\r\n$gdb_prompt $" {
-       }
-    }
-    return $ok
+    return [skip_libstdcxx_probe_tests_prompt "$gdb_prompt $"]
 }
 
 # Return 1 if we should skip tests of the "compile" feature.
@@ -3129,15 +3344,16 @@ proc skip_compile_feature_tests {} {
 
 proc gdb_is_target_1 { target_name target_stack_regexp prompt_regexp } {
     set test "probe for target ${target_name}"
-    gdb_test_multiple "maint print target-stack" $test {
-       -re "${target_stack_regexp}${prompt_regexp}" {
-           pass $test
-           return 1
-       }
-       -re "$prompt_regexp" {
-           pass $test
+    gdb_test_multiple "maint print target-stack" $test \
+       -prompt "$prompt_regexp" {
+           -re "${target_stack_regexp}${prompt_regexp}" {
+               pass $test
+               return 1
+           }
+           -re "$prompt_regexp" {
+               pass $test
+           }
        }
-    }
     return 0
 }
 
@@ -3392,11 +3608,20 @@ proc gdb_wrapper_init { args } {
     global gdb_wrapper_flags
     global gdb_wrapper_target
 
+    # If the wrapper is initialized but the wrapper file cannot be
+    # found anymore, the wrapper file must be built again.
+    if { $gdb_wrapper_initialized == 1 && \
+           [info exists gdb_wrapper_file] && \
+           ![file exists $gdb_wrapper_file] } {
+       verbose "reinitializing the wrapper"
+       set gdb_wrapper_initialized 0
+    }
+
     if { $gdb_wrapper_initialized == 1 } { return; }
 
     if {[target_info exists needs_status_wrapper] && \
            [target_info needs_status_wrapper] != "0"} {
-       set result [build_wrapper "testglue.o"]
+       set result [build_wrapper [standard_output_file "testglue.o"]]
        if { $result != "" } {
            set gdb_wrapper_file [lindex $result 0]
            set gdb_wrapper_flags [lindex $result 1]
@@ -3458,7 +3683,14 @@ proc gdb_simple_compile {name code {type object} {compile_flags {}} {object obj}
             set postfix "s"
         }
     }
-    set src [standard_temp_file $name-[pid].c]
+    set ext "c"
+    foreach flag $compile_flags {
+       if { "$flag" == "go" } {
+           set ext "go"
+           break
+       }
+    }
+    set src [standard_temp_file $name-[pid].$ext]
     set obj [standard_temp_file $name-[pid].$postfix]
     set compile_flags [concat $compile_flags {debug nowarnings quiet}]
 
@@ -3546,6 +3778,16 @@ proc gdb_compile {source dest type options} {
     } else {
        set new_options [universal_compile_options]
     }
+
+    # Place (and look for) Fortran `.mod` files in the output
+    # directory for this specific test.
+    if {[lsearch -exact $options f77] != -1 \
+           || [lsearch -exact $options f90] != -1 } {
+       # Fortran compile.
+       set mod_path [standard_output_file ""]
+       lappend new_options "additional_flags=-J${mod_path}"
+    }
+
     set shlib_found 0
     set shlib_load 0
     set getting_compiler_info 0
@@ -3629,7 +3871,7 @@ proc gdb_compile {source dest type options} {
     verbose "options are $options"
     verbose "source is $source $dest $type $options"
 
-    if { $gdb_wrapper_initialized == 0 } { gdb_wrapper_init }
+    gdb_wrapper_init
 
     if {[target_info exists needs_status_wrapper] && \
            [target_info needs_status_wrapper] != "0" && \
@@ -3694,7 +3936,7 @@ proc gdb_compile {source dest type options} {
            # Force output to unbuffered mode, by linking in an object file
            # with a global contructor that calls setvbuf.
            #
-           # Compile the special object seperatelly for two reasons:
+           # Compile the special object separately for two reasons:
            #  1) Insulate it from $options.
            #  2) Avoid compiling it for every gdb_compile invocation,
            #  which is time consuming, especially if we're remote
@@ -3741,6 +3983,16 @@ proc gdb_compile {source dest type options} {
     regsub "\[\r\n\]*$" "$result" "" result
     regsub "^\[\r\n\]*" "$result" "" result
     
+    if { $type == "executable" && $result == "" \
+            && ($nopie != -1 || $pie != -1) } {
+       set is_pie [exec_is_pie "$dest"]
+       if { $nopie != -1 && $is_pie == 1 } {
+           set result "nopie failed to prevent PIE executable"
+       } elseif { $pie != -1 && $is_pie == 0 } {
+           set result "pie failed to generate PIE executable"
+       }
+    }
+
     if {[lsearch $options quiet] < 0} {
        # We shall update this on a per language basis, to avoid
        # changing the entire testsuite in one go.
@@ -3758,6 +4010,9 @@ proc gdb_compile {source dest type options} {
 # against several different thread libraries, to see which one this
 # system has.
 proc gdb_compile_pthreads {source dest type options} {
+    if {$type != "executable"} {
+       return [gdb_compile $source $dest $type $options]
+    }
     set built_binfile 0
     set why_msg "unrecognized error"
     foreach lib {-lpthreads -lpthread -lthread ""} {
@@ -3832,11 +4087,16 @@ proc gdb_compile_shlib {sources dest options} {
     set outdir [file dirname $dest]
     set objects ""
     foreach source $sources {
-       set sourcebase [file tail $source]
-       if {[gdb_compile $source "${outdir}/${sourcebase}.o" object $obj_options] != ""} {
-           return -1
-       }
-       lappend objects ${outdir}/${sourcebase}.o
+       set sourcebase [file tail $source]
+       if {[file extension $source] == ".o"} {
+           # Already a .o file.
+           lappend objects $source
+       } elseif {[gdb_compile $source "${outdir}/${sourcebase}.o" object \
+                      $obj_options] != ""} {
+           return -1
+       } else {
+           lappend objects ${outdir}/${sourcebase}.o
+       }
     }
 
     set link_options $options
@@ -3958,11 +4218,23 @@ proc gdb_compile_objc {source dest type options} {
     }
 }
 
-proc send_gdb { string } {
+# Build an OpenMP program from SOURCE.  See prefatory comment for
+# gdb_compile, above, for discussion of the parameters to this proc.
+
+proc gdb_compile_openmp {source dest type options} {
+    lappend options "additional_flags=-fopenmp"
+    return [gdb_compile $source $dest $type $options]
+}
+
+# Send a command to GDB.
+# For options for TYPE see gdb_stdin_log_write
+
+proc send_gdb { string {type standard}} {
     global suppress_flag
     if { $suppress_flag } {
        return "suppressed"
     }
+    gdb_stdin_log_write $string $type
     return [remote_send host "$string"]
 }
 
@@ -4625,9 +4897,27 @@ proc standard_output_file {basename} {
 
     set dir [make_gdb_parallel_path outputs $subdir $gdb_test_file_name]
     file mkdir $dir
+    # If running on MinGW, replace /c/foo with c:/foo
+    if { [ishost *-*-mingw*] } {
+        set dir [regsub {^/([a-z])/} $dir {\1:/}]
+    }
     return [file join $dir $basename]
 }
 
+# Turn BASENAME into a full file name in the standard output directory.  If
+# GDB has been launched more than once then append the count, starting with
+# a ".1" postfix.
+
+proc standard_output_file_with_gdb_instance {basename} {
+    global gdb_instances
+    set count [expr $gdb_instances - 1 ]
+
+    if {$count == 0} {
+      return [standard_output_file $basename]
+    }
+    return [standard_output_file ${basename}.${count}]
+}
+
 # Return the name of a file in our standard temporary directory.
 
 proc standard_temp_file {basename} {
@@ -4639,6 +4929,48 @@ proc standard_temp_file {basename} {
     return [file join $dir $basename]
 }
 
+# Rename file A to file B, if B does not already exists.  Otherwise, leave B
+# as is and delete A.  Return 1 if rename happened.
+
+proc tentative_rename { a b } {
+    global errorInfo errorCode
+    set code [catch {file rename -- $a $b} result]
+    if { $code == 1 && [lindex $errorCode 0] == "POSIX" \
+            && [lindex $errorCode 1] == "EEXIST" } {
+       file delete $a
+       return 0
+    }
+    if {$code == 1} {
+       return -code error -errorinfo $errorInfo -errorcode $errorCode $result
+    } elseif {$code > 1} {
+       return -code $code $result
+    }
+    return 1
+}
+
+# Create a file with name FILENAME and contents TXT in the cache directory.
+# If EXECUTABLE, mark the new file for execution.
+
+proc cached_file { filename txt {executable 0}} {
+    set filename [make_gdb_parallel_path cache $filename]
+
+    if { [file exists $filename] } {
+       return $filename
+    }
+
+    set tmp_filename $filename.[pid]
+    set fd [open $tmp_filename w]
+    puts $fd $txt
+    close $fd
+
+    if { $executable } {
+       exec chmod +x $tmp_filename
+    }
+    tentative_rename $tmp_filename $filename
+
+    return $filename
+}
+
 # Set 'testfile', 'srcfile', and 'binfile'.
 #
 # ARGS is a list of source file specifications.
@@ -4807,6 +5139,12 @@ proc gdb_init { test_file_name } {
     # tests.
     setenv TERM "dumb"
 
+    # Ensure that GDBHISTFILE and GDBHISTSIZE are removed from the
+    # environment, we don't want these modifications to the history
+    # settings.
+    unset -nocomplain ::env(GDBHISTFILE)
+    unset -nocomplain ::env(GDBHISTSIZE)
+
     # 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
@@ -4822,6 +5160,14 @@ proc gdb_init { test_file_name } {
     set gdbserver_reconnect_p 1
     unset gdbserver_reconnect_p
 
+    # Clear $last_loaded_file
+    global last_loaded_file
+    unset -nocomplain last_loaded_file
+
+    # Reset GDB number of instances
+    global gdb_instances
+    set gdb_instances 0
+
     return [default_gdb_init $test_file_name]
 }
 
@@ -4864,7 +5210,6 @@ set debug_format "unknown"
 
 proc get_debug_format { } {
     global gdb_prompt
-    global verbose
     global expect_out
     global debug_format
 
@@ -5090,7 +5435,7 @@ proc rerun_to_main {} {
     send_gdb "run\n"
     gdb_expect {
       -re "The program .* has been started already.*y or n. $" {
-         send_gdb "y\n"
+         send_gdb "y\n" answer
          exp_continue
       }
       -re "Starting program.*$gdb_prompt $"\
@@ -5102,6 +5447,70 @@ proc rerun_to_main {} {
   }
 }
 
+# Return true if EXECUTABLE contains a .gdb_index or .debug_names index section.
+
+proc exec_has_index_section { executable } {
+    set readelf_program [gdb_find_readelf]
+    set res [catch {exec $readelf_program -S $executable \
+                       | grep -E "\.gdb_index|\.debug_names" }]
+    if { $res == 0 } {
+       return 1
+    }
+    return 0
+}
+
+# Return list with major and minor version of readelf, or an empty list.
+gdb_caching_proc readelf_version {
+    set readelf_program [gdb_find_readelf]
+    set res [catch {exec $readelf_program --version} output]
+    if { $res != 0 } {
+       return [list]
+    }
+    set lines [split $output \n]
+    set line [lindex $lines 0]
+    set res [regexp {[ \t]+([0-9]+)[.]([0-9]+)[^ \t]*$} \
+                $line dummy major minor]
+    if { $res != 1 } {
+       return [list]
+    }
+    return [list $major $minor]
+}
+
+# Return 1 if readelf prints the PIE flag, 0 if is doesn't, and -1 if unknown.
+proc readelf_prints_pie { } {
+    set version [readelf_version]
+    if { [llength $version] == 0 } {
+       return -1
+    }
+    set major [lindex $version 0]
+    set minor [lindex $version 1]
+    # It would be better to construct a PIE executable and test if the PIE
+    # flag is printed by readelf, but we cannot reliably construct a PIE
+    # executable if the multilib_flags dictate otherwise
+    # (--target_board=unix/-no-pie/-fno-PIE).
+    return [version_at_least $major $minor 2 26]
+}
+
+# Return 1 if EXECUTABLE is a Position Independent Executable, 0 if it is not,
+# and -1 if unknown.
+
+proc exec_is_pie { executable } {
+    set res [readelf_prints_pie]
+    if { $res != 1 } {
+       return -1
+    }
+    set readelf_program [gdb_find_readelf]
+    set res [catch {exec $readelf_program -d $executable} output]
+    if { $res != 0 } {
+       return -1
+    }
+    set res [regexp -line {\(FLAGS_1\).*Flags:.* PIE($| )} $output]
+    if { $res == 1 } {
+       return 1
+    }
+    return 0
+}
+
 # Return true if a test should be skipped due to lack of floating
 # point support or GDB can't fetch the contents from floating point
 # registers.
@@ -5501,35 +5910,64 @@ proc gdb_gnu_strip_debug { dest args } {
 # Test the output of GDB_COMMAND matches the pattern obtained
 # by concatenating all elements of EXPECTED_LINES.  This makes
 # it possible to split otherwise very long string into pieces.
-# If third argument is not empty, it's used as the name of the
+# If third argument TESTNAME is not empty, it's used as the name of the
 # test to be printed on pass/fail.
-proc help_test_raw { gdb_command expected_lines args } {
-    set message $gdb_command
-    if [llength $args]>0 then {
-       set message [lindex $args 0]
-    } 
+proc help_test_raw { gdb_command expected_lines {testname {}} } {
     set expected_output [join $expected_lines ""]
-    gdb_test "${gdb_command}" "${expected_output}" $message
+    if {$testname != {}} {
+       gdb_test "${gdb_command}" "${expected_output}" $testname
+       return
+    }
+
+    gdb_test "${gdb_command}" "${expected_output}"
+}
+
+# A regexp that matches the end of help CLASS|PREFIX_COMMAND
+set help_list_trailer {
+    "Type \"apropos word\" to search for commands related to \"word\"\.[\r\n]+"
+    "Type \"apropos -v word\" for full documentation of commands related to \"word\"\.[\r\n]+"
+    "Command name abbreviations are allowed if unambiguous\."
 }
 
-# Test the output of "help COMMAND_CLASS". EXPECTED_INITIAL_LINES
+# Test the output of "help COMMAND_CLASS".  EXPECTED_INITIAL_LINES
 # are regular expressions that should match the beginning of output,
-# before the list of commands in that class.  The presence of 
-# command list and standard epilogue will be tested automatically.
+# before the list of commands in that class.
+# LIST_OF_COMMANDS are regular expressions that should match the
+# list of commands in that class.  If empty, the command list will be
+# matched automatically.  The presence of standard epilogue will be tested
+# automatically.
+# If last argument TESTNAME is not empty, it's used as the name of the
+# test to be printed on pass/fail.
 # Notice that the '[' and ']' characters don't need to be escaped for strings
 # wrapped in {} braces.
-proc test_class_help { command_class expected_initial_lines args } {
+proc test_class_help { command_class expected_initial_lines {list_of_commands {}} {testname {}} } {
+    global help_list_trailer
+    if {[llength $list_of_commands]>0} {
+       set l_list_of_commands {"List of commands:[\r\n]+[\r\n]+"}
+        set l_list_of_commands [concat $l_list_of_commands $list_of_commands]
+       set l_list_of_commands [concat $l_list_of_commands {"[\r\n]+[\r\n]+"}]
+    } else {
+        set l_list_of_commands {"List of commands\:.*[\r\n]+"}
+    }
     set l_stock_body {
-        "List of commands\:.*[\r\n]+"
         "Type \"help\" followed by command name for full documentation\.[\r\n]+"
-        "Type \"apropos word\" to search for commands related to \"word\"\.[\r\n]+"
-        "Command name abbreviations are allowed if unambiguous\." 
     }
-    set l_entire_body [concat $expected_initial_lines $l_stock_body]
+    set l_entire_body [concat $expected_initial_lines $l_list_of_commands \
+                      $l_stock_body $help_list_trailer]
 
-    eval [list help_test_raw "help ${command_class}" $l_entire_body] $args
+    help_test_raw "help ${command_class}" $l_entire_body $testname
 }
 
+# Like test_class_help but specialised to test "help user-defined".
+proc test_user_defined_class_help { {list_of_commands {}} {testname {}} } {
+    test_class_help "user-defined" {
+       "User-defined commands\.[\r\n]+"
+       "The commands in this class are those defined by the user\.[\r\n]+"
+       "Use the \"define\" command to define a command\.[\r\n]+"
+    } $list_of_commands $testname
+}
+
+
 # COMMAND_LIST should have either one element -- command to test, or
 # two elements -- abbreviated command to test, and full command the first
 # element is abbreviation of.
@@ -5538,6 +5976,7 @@ proc test_class_help { command_class expected_initial_lines args } {
 # before the list of subcommands.  The presence of 
 # subcommand list and standard epilogue will be tested automatically.
 proc test_prefix_command_help { command_list expected_initial_lines args } {
+    global help_list_trailer
     set command [lindex $command_list 0]   
     if {[llength $command_list]>1} {        
         set full_command [lindex $command_list 1]
@@ -5548,10 +5987,8 @@ proc test_prefix_command_help { command_list expected_initial_lines args } {
     # be expanded in this list.
     set l_stock_body [list\
          "List of $full_command subcommands\:.*\[\r\n\]+"\
-         "Type \"help $full_command\" followed by $full_command subcommand name for full documentation\.\[\r\n\]+"\
-         "Type \"apropos word\" to search for commands related to \"word\"\.\[\r\n\]+"\
-         "Command name abbreviations are allowed if unambiguous\."]
-    set l_entire_body [concat $expected_initial_lines $l_stock_body]
+         "Type \"help $full_command\" followed by $full_command subcommand name for full documentation\.\[\r\n\]+"]
+    set l_entire_body [concat $expected_initial_lines $l_stock_body $help_list_trailer]
     if {[llength $args]>0} {
         help_test_raw "help ${command}" $l_entire_body [lindex $args 0]
     } else {
@@ -5585,7 +6022,7 @@ proc build_executable_from_specs {testname executable options args} {
     }
 
     set func gdb_compile
-    set func_index [lsearch -regexp $options {^(pthreads|shlib|shlib_pthreads)$}]
+    set func_index [lsearch -regexp $options {^(pthreads|shlib|shlib_pthreads|openmp)$}]
     if {$func_index != -1} {
        set func "${func}_[lindex $options $func_index]"
     }
@@ -5620,7 +6057,7 @@ proc build_executable_from_specs {testname executable options args} {
            if { ! [regexp "^/" "$s"] } then {
                set s "$srcdir/$subdir/$s"
            }
-           if  { [gdb_compile "${s}" "${binfile}${i}.o" object $local_options] != "" } {
+           if  { [$func "${s}" "${binfile}${i}.o" object $local_options] != "" } {
                untested $testname
                return -1
            }
@@ -5904,53 +6341,6 @@ proc relative_filename {root full} {
     return [eval file join [lrange $full_split $len end]]
 }
 
-# Log gdb command line and script if requested.
-if {[info exists TRANSCRIPT]} {
-  rename send_gdb real_send_gdb
-  rename remote_spawn real_remote_spawn
-  rename remote_close real_remote_close
-
-  global gdb_transcript
-  set gdb_transcript ""
-
-  global gdb_trans_count
-  set gdb_trans_count 1
-
-  proc remote_spawn {args} {
-    global gdb_transcript gdb_trans_count outdir
-
-    if {$gdb_transcript != ""} {
-      close $gdb_transcript
-    }
-    set gdb_transcript [open [file join $outdir transcript.$gdb_trans_count] w]
-    puts $gdb_transcript [lindex $args 1]
-    incr gdb_trans_count
-
-    return [uplevel real_remote_spawn $args]
-  }
-
-  proc remote_close {args} {
-    global gdb_transcript
-
-    if {$gdb_transcript != ""} {
-      close $gdb_transcript
-      set gdb_transcript ""
-    }
-
-    return [uplevel real_remote_close $args]
-  }
-
-  proc send_gdb {args} {
-    global gdb_transcript
-
-    if {$gdb_transcript != ""} {
-      puts -nonewline $gdb_transcript [lindex $args 0]
-    }
-
-    return [uplevel real_send_gdb $args]
-  }
-}
-
 # If GDB_PARALLEL exists, then set up the parallel-mode directories.
 if {[info exists GDB_PARALLEL]} {
     if {[is_remote host]} {
@@ -6115,6 +6505,21 @@ gdb_caching_proc target_supports_scheduler_locking {
     return $supports_schedule_locking
 }
 
+# Return 1 if compiler supports use of nested functions.  Otherwise,
+# return 0.
+
+gdb_caching_proc support_nested_function_tests {
+    # Compile a test program containing a nested function
+    return [gdb_can_simple_compile nested_func {
+       int main () {
+           int foo () {
+               return 0;
+           }
+           return foo ();
+       }
+    } executable]
+}
+
 # gdb_target_symbol returns the provided symbol with the correct prefix
 # prepended.  (See gdb_target_symbol_prefix, above.)
 
@@ -6392,6 +6797,58 @@ proc gdb_supported_languages {} {
                opencl rust minimal ada]
 }
 
+# Check if debugging is enabled for gdb.
+
+proc gdb_debug_enabled { } {
+    global gdbdebug
+
+    # If not already read, get the debug setting from environment or board setting.
+    if {![info exists gdbdebug]} {
+       global env
+       if [info exists env(GDB_DEBUG)] {
+           set gdbdebug $env(GDB_DEBUG)
+       } elseif [target_info exists gdb,debug] {
+           set gdbdebug [target_info gdb,debug]
+       } else {
+           return 0
+       }
+    }
+
+    # Ensure it not empty.
+    return [expr { $gdbdebug != "" }]
+}
+
+# Turn on debugging if enabled, or reset if already on.
+
+proc gdb_debug_init { } {
+
+    global gdb_prompt
+
+    if ![gdb_debug_enabled] {
+      return;
+    }
+
+    # First ensure logging is off.
+    send_gdb "set logging off\n"
+
+    set debugfile [standard_output_file gdb.debug]
+    send_gdb "set logging file $debugfile\n"
+
+    send_gdb "set logging debugredirect\n"
+
+    global gdbdebug
+    foreach entry [split $gdbdebug ,] {
+      send_gdb "set debug $entry 1\n"
+    }
+
+    # Now that everything is set, enable logging.
+    send_gdb "set logging on\n"
+    gdb_expect 10 {
+       -re "Copying output to $debugfile.*Redirecting debug output to $debugfile.*$gdb_prompt $" {}
+       timeout { warning "Couldn't set logging file" }
+    }
+}
+
 # Check if debugging is enabled for gdbserver.
 
 proc gdbserver_debug_enabled { } {
@@ -6399,5 +6856,93 @@ proc gdbserver_debug_enabled { } {
     return 0
 }
 
+# Open the file for logging gdb input
+
+proc gdb_stdin_log_init { } {
+    global in_file
+
+    if {[info exists in_file]} {
+      # Close existing file.
+      catch "close $in_file"
+    }
+
+    set logfile [standard_output_file_with_gdb_instance gdb.in]
+    set in_file [open $logfile w]
+}
+
+# Write to the file for logging gdb input.
+# TYPE can be one of the following:
+# "standard" : Default. Standard message written to the log
+# "answer" : Answer to a question (eg "Y"). Not written the log.
+# "optional" : Optional message. Not written to the log.
+
+proc gdb_stdin_log_write { message {type standard} } {
+
+    global in_file
+    if {![info exists in_file]} {
+      return
+    }
+
+    # Check message types.
+    switch -regexp -- $type {
+        "answer" {
+            return
+        }
+        "optional" {
+            return
+        }
+    }
+
+    #Write to the log
+    puts -nonewline $in_file "$message"
+}
+
+# Write the command line used to invocate gdb to the cmd file.
+
+proc gdb_write_cmd_file { cmdline } {
+    set logfile [standard_output_file_with_gdb_instance gdb.cmd]
+    set cmd_file [open $logfile w]
+    puts $cmd_file $cmdline
+    catch "close $cmd_file"
+}
+
+# Compare contents of FILE to string STR.  Pass with MSG if equal, otherwise
+# fail with MSG.
+
+proc cmp_file_string { file str msg } {
+    if { ![file exists $file]} {
+       fail "$msg"
+       return
+    }
+
+    set caught_error [catch {
+       set fp [open "$file" r]
+       set file_contents [read $fp]
+       close $fp
+    } error_message]
+    if { $caught_error } then {
+       error "$error_message"
+       fail "$msg"
+       return
+    }
+
+    if { $file_contents == $str } {
+       pass "$msg"
+    } else {
+       fail "$msg"
+    }
+}
+
+# Does the compiler support CTF debug output using '-gt' compiler
+# flag?  If not then we should skip these tests.
+
+gdb_caching_proc skip_ctf_tests {
+    return ![gdb_can_simple_compile ctfdebug {
+       int main () {
+           return 0;
+       }
+    } executable "additional_flags=-gt"]
+}
+
 # Always load compatibility stuff.
 load_lib future.exp