| # 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 |
| |