diff --git a/gdb/testsuite/gdb.base/solib-mismatch-lib.c b/gdb/testsuite/gdb.base/solib-mismatch-lib.c new file mode 100644 index 0000000..19f1545 --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-mismatch-lib.c @@ -0,0 +1,29 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 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 3 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, see . */ + + +int _bar = 42; + +int bar(void) +{ + return _bar + 21; +} + +int foo(void) +{ + return _bar; +} diff --git a/gdb/testsuite/gdb.base/solib-mismatch-libmod.c b/gdb/testsuite/gdb.base/solib-mismatch-libmod.c new file mode 100644 index 0000000..3b025a8 --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-mismatch-libmod.c @@ -0,0 +1,29 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 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 3 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, see . */ + + +int _bar = 21; + +int bar(void) +{ + return 42 - _bar; +} + +int foo(void) +{ + return 24 + bar(); +} diff --git a/gdb/testsuite/gdb.base/solib-mismatch.c b/gdb/testsuite/gdb.base/solib-mismatch.c new file mode 100644 index 0000000..85a2784 --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-mismatch.c @@ -0,0 +1,59 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 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 3 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, see . */ + + +#include +#include +#include +#include + +#define lib "./solib-mismatch.so" + + +/* First argument is working directory. */ + +int main(int argc, char *argv[]) +{ + void *h; + int (*foo)(void); + char buff[1024]; + + if (argc < 2) + { + printf ("ERROR - CWD not provided\n"); + return 1; + } + + if (chdir (argv[1]) != 0) + { + printf ("ERROR - Could not cd to '%s'\n", argv[1]); + return 1; + } + + h = dlopen(lib, RTLD_NOW); + + if (h == NULL) + { + printf ("ERROR - could not open lib %s\n", lib); + return 1; + } + foo = dlsym(h, "foo"); + printf ("foo: %p\n", foo); /* set breakpoint 1 here */ + dlclose(h); + return 0; +} + diff --git a/gdb/testsuite/gdb.base/solib-mismatch.exp b/gdb/testsuite/gdb.base/solib-mismatch.exp new file mode 100644 index 0000000..c2192a5 --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-mismatch.exp @@ -0,0 +1,186 @@ +# Copyright 2013 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 3 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, see . */ + +# are we on a target board +standard_testfile +set executable $testfile + +# Test overview: +# generate two shared objects. One that will be used by the process +# and another, modified, that will be found by gdb. Gdb should +# detect the mismatch and refuse to use mismatched shared object. + +if { [get_compiler_info] } { + untested ${testfile}.exp +} + +# First version of the object, to be loaded by ld +set srclibfilerun ${testfile}-lib.c +# Modified version of the object to be loaded by gdb +# Code in -libmod.c is tuned so it gives a mismatch but +# leaves .dynamic at the same point. +set srclibfilegdb ${testfile}-libmod.c + +# So file name: +set binlibfilebase ${testfile}.so + +# Setup run directory (where program is run from) +# It contains executable and '-lib' version of the library. +set binlibfiledirrun ${objdir}/${subdir}/${testfile}_wd +set binlibfilerun ${binlibfiledirrun}/${binlibfilebase} + +# Second solib version is in current directory, '-libmod' version. +set binlibfiledirgdb ${objdir}/${subdir} +set binlibfilegdb ${binlibfiledirgdb}/${binlibfilebase} + +# Executeable +set srcfile ${testfile}.c +set executable ${testfile} +set objfile ${objdir}/${subdir}/${executable}.o +set binfile ${objdir}/${subdir}/${executable} + +send_user "Current WD: [eval pwd]\r\n" + +file mkdir "${binlibfiledirrun}" + +if { ![istarget "*-*-nto-*"] } { + set exec_opts [list debug shlib_load] +} + +if { [prepare_for_testing $testfile.exp $executable $srcfile $exec_opts] != 0 } { + untested ${testfile}.exp + return -1 +} + +if { [gdb_compile_shlib "${srcdir}/${subdir}/${srclibfilerun}" "${binlibfilerun}" [list debug ldflags=-Wl,-soname,${binlibfilebase},--build-id]] != "" + || [gdb_gnu_strip_debug "${binlibfilerun}"] + || [gdb_compile_shlib "${srcdir}/${subdir}/${srclibfilegdb}" "${binlibfilegdb}" [list debug ldflags=-Wl,-soname,${binlibfilebase},--build-id]] != "" } { + untested ${testfile}.exp + return -1 +} + +proc solib_matching_test { solibfile symsloaded } { + global gdb_prompt + global testfile + global executable + global srcdir + global subdir + global binlibfiledirrun + global binlibfiledirgdb + global srcfile + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + + send_gdb "set verbose 1\n" + send_gdb "file \"${binlibfiledirrun}/${executable}\"\n" + send_gdb "set solib-search-path \"${binlibfiledirgdb}\"\n" + send_gdb "cd ${binlibfiledirgdb}\n" + send_gdb "show solib-search-path\n" + send_gdb "set auto-solib-add off\n" + send_gdb "set args \"${binlibfiledirrun}\"\n" + send_gdb "set verbose 1\n" + + set bp_location [gdb_get_line_number "set breakpoint 1 here"] + + send_gdb "tbreak ${srcfile}:${bp_location}\n" + gdb_expect { + -re ".*Temporary breakpoint.*${gdb_prompt} $" { + } + default { + untested "${testfile}: Failed to set temp. breakpoint at ${bp_location}" + return -1 + } + } + + send_gdb "run\r\n" + gdb_expect { + -re "Starting program.*${gdb_prompt} $" { + } + default { + untested "${testfile}: Failed to hit breakpoint at ${bp_location}" + return -1 + } + } + + send_gdb "sharedlibrary\n" + gdb_expect { + -re ".*${gdb_prompt} $" { + } + default { + untested "${testfile}: sharedlibrary failure" + return -1 + } + } + + gdb_test "info sharedlibrary ${solibfile}" \ + ".*From.*To.*Syms.*Read.*Shared.*\r\n.*${symsloaded}.*" \ + "Symbols for ${solibfile} loaded: expected '${symsloaded}'" + + send_gdb "p/x foo\n" + gdb_expect { + -re ".*${gdb_prompt} $" { +#Nothing, just drain the buffer + } + default { + untested "${testfile}: Failed 'info symbol foo'" + return -1 + } + } + + send_gdb "detach\n" + gdb_expect { + -re ".*Detaching from program.*${executable}.*${gdb_prompt} $" { +#Nothing, just drain the buffer + } + default { + untested "${testfile}: Could not detach from ${testpid}" + return -1 + } + } + return 0 +} + +# Copy binary to working dir so it pulls in the library from that dir +# (by the virtue of $ORIGIN). +file copy -force "${binlibfiledirgdb}/${executable}" \ + "${binlibfiledirrun}/${executable}" + +# Test unstripped, .dynamic matching +send_user "test unstripped, .dynamic matching\r\n" +solib_matching_test "${binlibfilebase}" "No" + +# Test --only-keep-debug, .dynamic matching so +send_user "test --only-keep-debug\r\n" +# Keep original so for debugging purposes +file copy -force "${binlibfilegdb}" "${binlibfilegdb}-orig" +set objcopy_program [transform objcopy] +set result [catch "exec $objcopy_program --only-keep-debug ${binlibfilegdb}"] +if {$result != 0} { + untested "${testfile} test --only-keep-debug" + return -1 +} +solib_matching_test "${binlibfilebase}" "No" + +# Now test it does not mis-invalidate matching libraries +send_user "test matching libraries\r\n" +# Keep previous so for debugging puroses +file copy -force "${binlibfilegdb}" "${binlibfilegdb}-orig1" +# Copy loaded so over the one gdb will find +file copy -force "${binlibfilerun}" "${binlibfilegdb}" +solib_matching_test "${binlibfilebase}" "Yes" + + -- 1.7.10.4