blob: 9fae3c11ce530c04ed76eaa2ad1f35055ed903ee [file] [log] [blame]
# Copyright 2005 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
if $tracelevel then {
strace $tracelevel
}
#
# This tests if for gdb's handling of files produced with
# ld -r. There are two things being tested here. In the
# -gfull -Wl,-Sp case, it's whether we properly get the BINCL/EINCL
# dependencies when we are reading out of a .o. And for -gused
# it is whether the debug info survives the coalescing process.
#
set prms_id 0
set bug_id 0
proc do_tests {use_ld} {
global srcdir objdir subdir gdb_prompt
global debug_default_format_is_dwarf gdb_test_apple_dsym
set ld_flags {}
set test_name "ld-r testing"
if {!$use_ld} {
append test_name " - ar"
}
if {$debug_default_format_is_dwarf && $gdb_test_apple_dsym == 0} {
append test_name " - debug info in .o files"
}
set testfile "test-ld-r"
set ld_r_file "ld-r.o"
set main "main"
set fooName "foo"
set barName "bar"
# These two we build oddly...
set bazName "baz"
set multName "multiplier"
set binfile "${objdir}/${subdir}/${testfile}"
set additional_flags additional_flags=""
# This is a bit complicated seeming. What I want to make sure is that I have
# 1) two "ld -r" .o files.
# 2) nested BINCL/EINCL's
# 3) two BINCL/EINCL's with the same filename but different hashes.
foreach {src} {main foo foo-2 bar bar-2} {
if { [gdb_compile "$srcdir/$subdir/$src.cc" "$objdir/$subdir/$src.o" object [list debug $additional_flags c++]] != "" } {
gdb_suppress_entire_file "Testcase compile failed for $test_name, so all tests in this file will automatically fail."
}
}
if { [gdb_compile "$srcdir/$subdir/multiplier.cc" "$objdir/$subdir/multiplier.o" object [list debug $additional_flags c++]] != "" } {
gdb_suppress_entire_file "Testcase compile failed for $test_name, so all tests in this file will automatically fail."
}
set additional_flags "additional_flags= -DUSE_LONG"
if { [gdb_compile "$srcdir/$subdir/multiplier.cc" "$objdir/$subdir/multiplier-long.o" object [list debug $additional_flags c++]] != "" } {
gdb_suppress_entire_file "Testcase compile failed for $test_name, so all tests in this file will automatically fail."
}
foreach {src} {baz baz-2} {
if { [gdb_compile "$srcdir/$subdir/$src.cc" "$objdir/$subdir/$src.o" object [list debug $additional_flags c++]] != "" } {
gdb_suppress_entire_file "Testcase compile failed for $test_name, so all tests in this file will automatically fail."
}
}
if {$use_ld} {
set intermediate_obj $objdir/$subdir/ld-r.o
set command "ld -r \"$objdir/$subdir/foo.o\" \"$objdir/$subdir/bar.o\" \"$objdir/$subdir/baz.o\" -o \"$intermediate_obj\""
} else {
set intermediate_obj $objdir/$subdir/ld-r.a
file delete $intermediate_obj
set command "ar -c -q \"$intermediate_obj\" \"$objdir/$subdir/foo.o\" \"$objdir/$subdir/bar.o\" \"$objdir/$subdir/baz.o\""
}
set status [remote_exec host $command]
if {[lindex $status 0] != 0} {
puts [lindex $status 1]
gdb_suppress_entire_file "Testcase ld -r failed for $test_name, so all tests in this file will automatically fail."
}
if {!$use_ld} {
set command "ranlib \"$intermediate_obj\""
set status [remote_exec host $command]
if {[lindex $status 0] != 0} {
puts [lindex $status 1]
gdb_suppress_entire_file "Testcase ld -r failed for $test_name, so all tests in this file will automatically fail."
}
}
set command "ld -r \"$objdir/$subdir/foo-2.o\" \"$objdir/$subdir/bar-2.o\" \"$objdir/$subdir/baz-2.o\" -o \"$objdir/$subdir/ld-r-2.o\""
set status [remote_exec host $command]
if {[lindex $status 0] != 0} {
puts [lindex $status 1]
gdb_suppress_entire_file "Testcase ld -r failed for $test_name, so all tests in this file will automatically fail."
}
set command "ld -r \"$objdir/$subdir/multiplier-long.o\" \"$objdir/$subdir/multiplier.o\" -o \"$objdir/$subdir/ld-r-3.o\""
set status [remote_exec host $command]
if {[lindex $status 0] != 0} {
puts [lindex $status 1]
gdb_suppress_entire_file "Testcase ld -r failed for $test_name, so all tests in this file will automatically fail."
}
set additional_flags additional_flags=""
if { [gdb_compile "$objdir/$subdir/ld-r-2.o $objdir/$subdir/ld-r-3.o $objdir/$subdir/main.o $intermediate_obj" "${binfile}" executable [list debug $additional_flags c++]] != "" } {
gdb_suppress_entire_file "Testcase compile failed for $test_name, so all tests in this file will automatically fail."
}
if [get_compiler_info ${binfile} "c++"] {
return -1
}
# Start with a fresh gdb
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_file_cmd "${binfile}"
send_gdb "set width 0\n"
gdb_expect -re "$gdb_prompt $"
# The order is a little tricky here for the -gfull -Wl,-Sp case.
# foo.cc in the ld-r file actually has the BINCL/EINCL,
# and the other files the EXCL. We want to make sure we hit the one with the EXCL first,
# so we test that the debugger actually builds the dependency list correctly.
gdb_test "break barFunc" "Breakpoint 1.*bar.cc.*" "First break at bar: $test_name"
# Note, runto_main does delete_breakpoint, that's why we have to reset it below.
if {![runto_main]} {
fail "Running to main suppressing testcase"
return -1
}
gdb_test "break fooFunc" "Breakpoint 3.*foo.cc.*" "Break at foo: $test_name"
gdb_test "break barFunc" "Breakpoint 4.*bar.cc.*" "Break at bar: $test_name"
gdb_test "break bazFunc" "Breakpoint 5.*baz.cc.*" "Break at baz: $test_name"
foreach {break func value} {3 foo 4000 4 bar 25 5 baz 4000} {
gdb_test "continue" "Continuing\\..*Breakpoint $break, ${func}Func.*$func.cc.*" "Hit breakpoint at ${func}Func: $test_name"
gdb_test "ptype mine" "type = class MyBlubby \{\r\n.*private:\r\n.*use_me value;(\r\n.*)*" "ptype mine in ${func}Func: $test_name"
gdb_test "finish" "Run till exit from \#0.*${func}Func.* at .*$func.cc.*\\r\\n.*in main.*main.cc.*\\r\\n.*\\r\\nValue returned is \\\$\[0-9\] = $value" "Finish from ${func}Func: $test_name"
}
gdb_test "break fooFunc2" "Breakpoint 6.*foo-2.cc.*" "Break at foo-2: $test_name"
gdb_test "break bazFunc2" "Breakpoint 7.*baz-2.cc.*" "Break at baz-2: $test_name"
gdb_test "continue" "Continuing\\..*Breakpoint 6, fooFunc2.*foo-2.cc.*" "Hit breakpoint at fooFunc2: $test_name"
gdb_test "ptype multiplier" "type = long long int" "ptype in fooFunc2: $test_name"
gdb_test "continue" "Continuing\\..*Breakpoint 7, bazFunc2.*baz-2.cc.*" "Hit breakpoint at bazFunc2: $test_name"
gdb_test "ptype multiplier" "type = long int" "ptype in bazFunc2: $test_name"
gdb_exit
# If the debug info was left in the .o files, let's make sure our time
# check is working correctly.
if {$debug_default_format_is_dwarf == 1&& $gdb_test_apple_dsym == 0} {
# Start with a fresh gdb
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_file_cmd "${binfile}"
send_gdb "set width 0\n"
gdb_expect -re "$gdb_prompt $"
if {$use_ld == 0} {
# If this is the "ar" case, we have to rebuild the .a file as well,
# since we are using the time of the .o file in the archive, not the
# archive time.
# First make sure we aren't fooled by the archive time changing:
set intermediate_obj $objdir/$subdir/ld-r.a
file mtime $intermediate_obj [clock seconds]
send_gdb "break barFunc\n"
gdb_expect {
-re ".*warning: .o.*\[\r\n\].*$gdb_prompt" {
fail "No warning for just changing .a file timestamp: $test_name"
}
-re ".*Breakpoint 1.*bar.cc.*\[\r\n\].*$gdb_prompt" {
pass "No warning for just changing .a file timestamp: $test_name"
}
-re "$gdb_prompt $" {
fail "No warning for just changing .a file timestamp: $test_name"
}
timeout {
fail "No warning for just changing .a file timestamp: $test_name"
}
}
# Now really alter the .o file in the archive and test again.
file mtime $objdir/$subdir/foo.o [clock seconds]
file delete $intermediate_obj
set command "ar -c -q \"$intermediate_obj\" \"$objdir/$subdir/foo.o\" \"$objdir/$subdir/bar.o\" \"$objdir/$subdir/baz.o\""
set status [remote_exec host $command]
if {[lindex $status 0] != 0} {
puts [lindex $status 1]
fail "Could not rebuild .a file: $test_name"
}
gdb_test "break fooFunc" "(warning:.*\r\n)+Breakpoint 2.*foo.cc.*" "Got warnings for mismatched timestamp1: $test_name"
} else {
file mtime $objdir/$subdir/ld-r.o [clock seconds]
if { [gdb_compile "$srcdir/$subdir/foo.cc" "$objdir/$subdir/foo.o" object [list debug $additional_flags c++]] != "" } {
gdb_suppress_entire_file "Testcase compile failed for $test_name, so all tests in this file will automatically fail."
}
gdb_test "break fooFunc" "warning: .o file.*more recent than executable timestamp.*Breakpoint 1.*foo.cc.*" "Got warnings for mismatched timestamp2: $test_name"
}
}
}
do_tests 0
do_tests 1
return 0