# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2007, 2008 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
set EXEEXT $env(EXEEXT)
}
+set octal "\[0-7\]+"
+
### Only procedures should come after this point.
#
}
send_gdb "run $args\n"
# This doesn't work quite right yet.
- gdb_expect 60 {
+# Use -notransfer here so that test cases (like chng-sym.exp)
+# may test for additional start-up messages.
+ gdb_expect 60 {
-re "The program .* has been started already.*y or n. $" {
send_gdb "y\n"
exp_continue
}
- # Use -notransfer here so that test cases (like chng-sym.exp)
- # may test for additional start-up messages.
-notransfer -re "Starting program: \[^\r\n\]*" {}
}
}
}
# Set a breakpoint at FUNCTION. If there is an additional argument it is
-# a list of options; the supported options are allow-pending and temporary.
+# a list of options; the supported options are allow-pending, temporary,
+# and no-message.
proc gdb_breakpoint { function args } {
global gdb_prompt
}
set break_command "break"
+ set break_message "Breakpoint"
if {[lsearch -exact [lindex $args 0] temporary] != -1} {
set break_command "tbreak"
+ set break_message "Temporary breakpoint"
+ }
+
+ set no_message 0
+ if {[lsearch -exact [lindex $args 0] no-message] != -1} {
+ set no_message 1
}
send_gdb "$break_command $function\n"
# The first two regexps are what we get with -g, the third is without -g.
gdb_expect 30 {
- -re "Breakpoint \[0-9\]* at .*: file .*, line $decimal.\r\n$gdb_prompt $" {}
- -re "Breakpoint \[0-9\]*: file .*, line $decimal.\r\n$gdb_prompt $" {}
- -re "Breakpoint \[0-9\]* at .*$gdb_prompt $" {}
- -re "Breakpoint \[0-9\]* \\(.*\\) pending.*$gdb_prompt $" {
+ -re "$break_message \[0-9\]* at .*: file .*, line $decimal.\r\n$gdb_prompt $" {}
+ -re "$break_message \[0-9\]*: file .*, line $decimal.\r\n$gdb_prompt $" {}
+ -re "$break_message \[0-9\]* at .*$gdb_prompt $" {}
+ -re "$break_message \[0-9\]* \\(.*\\) pending.*$gdb_prompt $" {
if {$pending_response == "n"} {
- fail "setting breakpoint at $function"
+ if { $no_message == 0 } {
+ fail "setting breakpoint at $function"
+ }
return 0
}
}
send_gdb "$pending_response\n"
exp_continue
}
- -re "$gdb_prompt $" { fail "setting breakpoint at $function" ; return 0 }
- timeout { fail "setting breakpoint at $function (timeout)" ; return 0 }
+ -re "$gdb_prompt $" {
+ if { $no_message == 0 } {
+ fail "setting breakpoint at $function"
+ }
+ return 0
+ }
+ timeout {
+ if { $no_message == 0 } {
+ fail "setting breakpoint at $function (timeout)"
+ }
+ return 0
+ }
}
return 1;
}
### worked. Use NAME as part of the test name; each call to
### continue_to_breakpoint should use a NAME which is unique within
### that test file.
-proc gdb_continue_to_breakpoint {name} {
+proc gdb_continue_to_breakpoint {name {location_pattern .*}} {
global gdb_prompt
set full_name "continue to breakpoint: $name"
send_gdb "continue\n"
gdb_expect {
- -re "Breakpoint .* at .*\r\n$gdb_prompt $" {
+ -re "Breakpoint .* (at|in) $location_pattern\r\n$gdb_prompt $" {
pass $full_name
}
-re ".*$gdb_prompt $" {
return $skip_vmx_tests_saved
}
+# Run a test on the target to see if it supports vmx hardware. Return 0 if so,
+# 1 if it does not. Based on 'check_vmx_hw_available' from the GCC testsuite.
+
+proc skip_vsx_tests {} {
+ global skip_vsx_tests_saved
+ global srcdir subdir gdb_prompt
+
+ # Use the cached value, if it exists.
+ set me "skip_vsx_tests"
+ if [info exists skip_vsx_tests_saved] {
+ verbose "$me: returning saved $skip_vsx_tests_saved" 2
+ return $skip_vsx_tests_saved
+ }
+
+ # Some simulators are known to not support Altivec instructions, so
+ # they won't support VSX instructions as well.
+ if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } {
+ verbose "$me: target known to not support VSX, returning 1" 2
+ return [set skip_vsx_tests_saved 1]
+ }
+
+ # Make sure we have a compiler that understands altivec.
+ set compile_flags {debug nowarnings quiet}
+ if [get_compiler_info not-used] {
+ warning "Could not get compiler info"
+ return 1
+ }
+ if [test_compiler_info gcc*] {
+ set compile_flags "$compile_flags additional_flags=-mvsx"
+ } elseif [test_compiler_info xlc*] {
+ set compile_flags "$compile_flags additional_flags=-qvsx"
+ } else {
+ verbose "Could not compile with vsx support, returning 1" 2
+ return 1
+ }
+
+ set src vsx[pid].c
+ set exe vsx[pid].x
+
+ set f [open $src "w"]
+ puts $f "int main() {"
+ puts $f "#ifdef __MACH__"
+ puts $f " asm volatile (\"lxvd2x v0,v0,v0\");"
+ puts $f "#else"
+ puts $f " asm volatile (\"lxvd2x 0,0,0\");"
+ puts $f "#endif"
+ puts $f " return 0; }"
+ close $f
+
+ 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
+ return [set skip_vsx_tests_saved 1]
+ }
+
+ # No error message, compilation succeeded so now run it via gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load "$exe"
+ gdb_run_cmd
+ gdb_expect {
+ -re ".*Illegal instruction.*${gdb_prompt} $" {
+ verbose -log "\n$me VSX hardware not detected"
+ set skip_vsx_tests_saved 1
+ }
+ -re ".*Program exited normally.*${gdb_prompt} $" {
+ verbose -log "\n$me: VSX hardware detected"
+ set skip_vsx_tests_saved 0
+ }
+ default {
+ warning "\n$me: default case taken"
+ set skip_vsx_tests_saved 1
+ }
+ }
+ gdb_exit
+ remote_file build delete $exe
+
+ verbose "$me: returning $skip_vsx_tests_saved" 2
+ return $skip_vsx_tests_saved
+}
+
# Skip all the tests in the file if you are not on an hppa running
# hpux target.
set gdb_wrapper_initialized 1
}
+# 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 ""
+
proc gdb_compile {source dest type options} {
global GDB_TESTCASE_OPTIONS;
global gdb_wrapper_file;
global gdb_wrapper_flags;
global gdb_wrapper_initialized;
+ global srcdir
+ global objdir
+ global gdb_saved_set_unbuffered_mode_obj
set outdir [file dirname $dest]
set options [lreplace $options $nowarnings $nowarnings $flag]
}
+ if { $type == "executable" } {
+ if { ([istarget "*-*-mingw*"]
+ || [istarget "*-*-cygwin*"])} {
+ # 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:
+ # 1) Insulate it from $options.
+ # 2) Avoid compiling it for every gdb_compile invocation,
+ # which is time consuming, especially if we're remote
+ # host testing.
+ #
+ if { $gdb_saved_set_unbuffered_mode_obj == "" } {
+ verbose "compiling gdb_saved_set_unbuffered_obj"
+ set unbuf_src ${srcdir}/lib/set_unbuffered_mode.c
+ set unbuf_obj ${objdir}/set_unbuffered_mode.o
+
+ set result [gdb_compile "${unbuf_src}" "${unbuf_obj}" object {nowarnings}]
+ if { $result != "" } {
+ return $result
+ }
+
+ set gdb_saved_set_unbuffered_mode_obj ${objdir}/set_unbuffered_mode_saved.o
+ # Link a copy of the output object, because the
+ # original may be automatically deleted.
+ remote_exec host "cp -f $unbuf_obj $gdb_saved_set_unbuffered_mode_obj"
+ } else {
+ verbose "gdb_saved_set_unbuffered_obj already compiled"
+ }
+
+ # Rely on the internal knowledge that the global ctors are ran in
+ # reverse link order. In that case, we can use ldflags to
+ # avoid copying the object file to the host multiple
+ # times.
+ lappend options "ldflags=$gdb_saved_set_unbuffered_mode_obj"
+ }
+ }
+
set result [target_compile $source $dest $type $options];
# Prune uninteresting compiler (and linker) output.
proc gdb_expect { args } {
if { [llength $args] == 2 && [lindex $args 0] != "-re" } {
- set gtimeout [lindex $args 0];
+ set atimeout [lindex $args 0];
set expcode [list [lindex $args 1]];
} else {
- upvar timeout timeout;
-
set expcode $args;
- if [target_info exists gdb,timeout] {
- if [info exists timeout] {
- if { $timeout < [target_info gdb,timeout] } {
- set gtimeout [target_info gdb,timeout];
- } else {
- set gtimeout $timeout;
- }
- } else {
+ }
+
+ upvar timeout timeout;
+
+ if [target_info exists gdb,timeout] {
+ if [info exists timeout] {
+ if { $timeout < [target_info gdb,timeout] } {
set gtimeout [target_info gdb,timeout];
+ } else {
+ set gtimeout $timeout;
}
+ } else {
+ set gtimeout [target_info gdb,timeout];
+ }
+ }
+
+ if ![info exists gtimeout] {
+ global timeout;
+ if [info exists timeout] {
+ set gtimeout $timeout;
}
+ }
+ if [info exists atimeout] {
+ if { ![info exists gtimeout] || $gtimeout < $atimeout } {
+ set $gtimeout $atimeout;
+ }
+ } else {
if ![info exists gtimeout] {
- global timeout;
- if [info exists timeout] {
- set gtimeout $timeout;
- } else {
- # Eeeeew.
- set gtimeout 60;
- }
+ # Eeeeew.
+ set gtimeout 60;
}
}
+
global suppress_flag;
global remote_suppress_flag;
if [info exists remote_suppress_flag] {
set loadtimeout 1600
}
send_gdb "load $args\n"
- verbose "Timeout is now $timeout seconds" 2
+ verbose "Timeout is now $loadtimeout seconds" 2
gdb_expect $loadtimeout {
-re "Loading section\[^\r\]*\r\n" {
exp_continue
return -1
}
timeout {
- perror "Timed out trying to load $arg."
+ perror "Timed out trying to load $args."
return -1
}
}
return ""
}
set fi [open $tmp]
+ fconfigure $fi -translation binary
# Skip the NOTE header.
read $fi 16
set data [read $fi]
close $fi
file delete $tmp
- if {$data eq ""} {
+ if ![string compare $data ""] then {
return ""
}
# Convert it to hex.
proc gdb_gnu_strip_debug { dest args } {
- # First, make sure that we can do this. This is nasty. We need to
- # check for the stabs debug format. To do this we must run gdb on
- # the unstripped executable, list 'main' (as to have a default
- # source file), use get_debug_format (which does 'info source')
- # and then see if the debug info is stabs. If so, we bail out. We
- # cannot do this any other way because get_debug_format finds out
- # the debug format using gdb itself, and in case of stabs we get
- # an error loading the program if it is already stripped. An
- # alternative would be to find out the debug info from the flags
- # passed to dejagnu when the test is run.
-
- gdb_exit
- gdb_start
- gdb_load ${dest}
- gdb_test "list main" "" ""
- get_debug_format
- if { [test_debug_format "stabs"] } then {
- # The separate debug info feature doesn't work well in
- # binutils with stabs. It produces a corrupted debug info
- # only file, and gdb chokes on it. It is almost impossible to
- # capture the failing message out of gdb, because it happens
- # inside gdb_load. At that point any error message is
- # intercepted by dejagnu itself, and, because of the error
- # threshold, any faulty test result is changed into an
- # UNRESOLVED. (see dejagnu/lib/framework.exp)
- unsupported "no separate debug info handling with stabs"
- return -1
- } elseif { [test_debug_format "unknown"] } then {
- # gdb doesn't know what the debug format is. We are out of luck here.
- unsupported "unknown debugging format"
- return -1
- }
- gdb_exit
-
set debug_file [separate_debug_filename $dest]
set strip_to_file_program [transform strip]
set objcopy_program [transform objcopy]
help_test_raw "help ${command}" $l_entire_body
}
}
+
+# Build executable named EXECUTABLE, from SOURCES. If SOURCES are not
+# provided, uses $EXECUTABLE.c. The TESTNAME paramer is the name of test
+# to pass to untested, if something is wrong. OPTIONS are passed
+# to gdb_compile directly.
+proc build_executable { testname executable {sources ""} {options {debug}} } {
+
+ global objdir
+ global subdir
+ global srcdir
+ if {[llength $sources]==0} {
+ set sources ${executable}.c
+ }
+
+ set binfile ${objdir}/${subdir}/${executable}
+
+ set objects {}
+ for {set i 0} "\$i<[llength $sources]" {incr i} {
+ set s [lindex $sources $i]
+ if { [gdb_compile "${srcdir}/${subdir}/${s}" "${binfile}${i}.o" object $options] != "" } {
+ untested $testname
+ return -1
+ }
+ lappend objects "${binfile}${i}.o"
+ }
+
+ if { [gdb_compile $objects "${binfile}" executable $options] != "" } {
+ untested $testname
+ return -1
+ }
+
+ if [get_compiler_info ${binfile}] {
+ return -1
+ }
+ return 0
+}
+
+# Starts fresh GDB binary and loads EXECUTABLE into GDB. EXECUTABLE is
+# the name of binary in ${objdir}/${subdir}.
+proc clean_restart { executable } {
+ global srcdir
+ global objdir
+ global subdir
+ set binfile ${objdir}/${subdir}/${executable}
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+
+ if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+ }
+}
+
+# Prepares for testing, by calling build_executable, and then clean_restart.
+# Please refer to build_executable for parameter description.
+proc prepare_for_testing { testname executable {sources ""} {options {debug}}} {
+
+ if {[build_executable $testname $executable $sources $options] == -1} {
+ return -1
+ }
+ clean_restart $executable
+
+ return 0
+}