diff --git a/gdb/ChangeLog b/gdb/ChangeLog index aa0271ac147..061bf554b7d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2010-07-05 Jan Kratochvil + Joel Brobecker + + Fix re-run of PIE executable, PR shlibs/11776. + * solib-svr4.c (svr4_relocate_main_executable) : Remove + the part of pre-set SYMFILE_OBJFILE->SECTION_OFFSETS. + 2010-07-05 Jan Kratochvil Joel Brobecker diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 79138cc4753..1f135d450ec 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1989,17 +1989,32 @@ svr4_relocate_main_executable (void) { CORE_ADDR displacement; - if (symfile_objfile) - { - int i; + /* If we are re-running this executable, SYMFILE_OBJFILE->SECTION_OFFSETS + probably contains the offsets computed using the PIE displacement + from the previous run, which of course are irrelevant for this run. + So we need to determine the new PIE displacement and recompute the + section offsets accordingly, even if SYMFILE_OBJFILE->SECTION_OFFSETS + already contains pre-computed offsets. - /* Remote target may have already set specific offsets by `qOffsets' - which should be preferred. */ + If we cannot compute the PIE displacement, either: - for (i = 0; i < symfile_objfile->num_sections; i++) - if (ANOFFSET (symfile_objfile->section_offsets, i) != 0) - return; - } + - The executable is not PIE. + + - SYMFILE_OBJFILE does not match the executable started in the target. + This can happen for main executable symbols loaded at the host while + `ld.so --ld-args main-executable' is loaded in the target. + + Then we leave the section offsets untouched and use them as is for + this run. Either: + + - These section offsets were properly reset earlier, and thus + already contain the correct values. This can happen for instance + when reconnecting via the remote protocol to a target that supports + the `qOffsets' packet. + + - The section offsets were not reset earlier, and the best we can + hope is that the old offsets are still applicable to the new run. + */ if (! svr4_exec_displacement (&displacement)) return; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ced176cd578..f1b58b40901 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2010-07-05 Jan Kratochvil + Joel Brobecker + + Fix re-run of PIE executable, PR shlibs/11776. + * gdb.base/break-interp.exp (test_ld): Turn off "disable-randomization". + Remove $displacement_main to match the solib-svr4.c change. New "kill" + and re-"run" of the inferior. + 2010-07-05 Jan Kratochvil Joel Brobecker diff --git a/gdb/testsuite/gdb.base/break-interp.exp b/gdb/testsuite/gdb.base/break-interp.exp index a3b9c208a95..5039bcb0812 100644 --- a/gdb/testsuite/gdb.base/break-interp.exp +++ b/gdb/testsuite/gdb.base/break-interp.exp @@ -337,6 +337,11 @@ proc test_ld {file ifmain trynosym displacement} { # Print the "PIE (Position Independent Executable) displacement" message. gdb_test_no_output "set verbose on" + # We want to test the re-run of a PIE in the case where the executable + # is loaded with a different displacement, but disable-randomization + # prevents that from happening. So turn it off. + gdb_test "set disable-randomization off" + reach "dl_main" "run segv" $displacement gdb_test "bt" "#0 +\[^\r\n\]*\\mdl_main\\M.*" "dl bt" @@ -347,7 +352,13 @@ proc test_ld {file ifmain trynosym displacement} { reach "libfunc" continue "NONE" gdb_test "bt" "#0 +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#1 +\[^\r\n\]*\\mmain\\M.*" "main bt" + } + # Try re-run if the new PIE displacement takes effect. + gdb_test "kill" "" "kill" {Kill the program being debugged\? \(y or n\) } "y" + reach "dl_main" "run segv" $displacement + + if $ifmain { test_core $file $displacement test_attach $file $displacement