# 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