# 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 {c_flags {use_es 1} {use_ld 1}} { global srcdir objdir subdir gdb_prompt if {$use_es} { set ld_flags "-Wl,-Sp" } else { set ld_flags {} } set test_name "cflags: \"$c_flags\" - ldflags: \"$ld_flags\"" if {!$use_ld} { append testname " - ar" } 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=$c_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 $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 $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=$c_flags -DUSE_LONG" if { [gdb_compile "$srcdir/$subdir/multiplier.cc" "$objdir/$subdir/multiplier-long.o" object [list $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 $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." } 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=$ld_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 $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 # Then for the "Essential Symbols" case, let's make sure our time # check is working correctly. if {$use_es} { # 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: $testname" } gdb_test "break fooFunc" "(warning:.*\r\n)+Breakpoint 2.*foo.cc.*" "Got warnings for mismatched timestamp: $test_name" } else { file mtime $objdir/$subdir/ld-r.o [clock seconds] gdb_test "break fooFunc" "(warning:.*\r\n)+Breakpoint 1.*foo.cc.*" "Got warnings for mismatched timestamp: $test_name" } } } # These two just test ordinary gused & gfull operation. #do_tests -gused 0 #do_tests -gfull 0 # These two test the "Essential Symbols" do_tests -gused 1 do_tests -gfull 1 # This one test "Essentials Symbols" with # one of the "ld-r" intermediate files an archive instead. do_tests -gfull 1 0 return 0