This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] Sanity check PIE displacement #2
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Sat, 13 Feb 2010 21:12:06 +0100
- Subject: [patch] Sanity check PIE displacement #2
Hi,
this file obsoletes:
[patch] Sanity check PIE displacement (like the PIC one)
http://sourceware.org/ml/gdb-patches/2010-02/msg00000.html
It is primarily separated from the PIC part. (+testcase, +PIC compatible print
/ no print messages rule).
No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu.
Thanks,
Jan
gdb/
2010-02-13 Jan Kratochvil <jan.kratochvil@redhat.com>
* solib-svr4.c (svr4_exec_displacement): New variable retval.
Initialize it and verify its validity.
gdb/testsuite/
2010-02-13 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/break-interp.exp: Create new displacement parameter value
for the test_ld calls.
(reach): New parameter displacement, verify its content. New push of
pf_prefix "reach-$func:".
(test_core): New parameter displacement, verify its content. New push
of pf_prefix "core:". New command "set verbose on".
(test_attach): New parameter displacement, verify its content. New
push of pf_prefix "attach:". New command "set verbose on".
(test_ld): New parameter displacement, pass it to the reach, test_core
and test_attach calls and verify its content in the "ld.so exit" test.
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1675,7 +1675,49 @@ svr4_exec_displacement (void)
return 0;
if (target_auxv_search (¤t_target, AT_ENTRY, &entry_point) == 1)
- return entry_point - bfd_get_start_address (exec_bfd);
+ {
+ CORE_ADDR retval = entry_point - bfd_get_start_address (exec_bfd);
+
+ /* If current executable is not PIE (Position Independent Executable)
+ suppress any messages. */
+ if (retval == 0)
+ return 0;
+
+ if (bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
+ {
+ const struct elf_backend_data *elf = get_elf_backend_data (exec_bfd);
+
+ /* Check of the alignment against max (p_align) of PT_LOAD segments
+ cannot be used here as in LM_ADDR_CHECK for PIC libraries as at
+ least amd64 PIE executables have 2MB p_align while Linux kernel
+ loads them with arbitrary 4KB displacement. As in this case there
+ is no LM_ADDR_FROM_LINK_MAP to verify the possible offset GDB has
+ to depend just on MINPAGESIZE. */
+
+ if ((retval & (elf->minpagesize - 1)) != 0)
+ {
+ warning (_("PIE (Position Independent Executable) displacement "
+ "%s is not aligned to the minimal page size %s "
+ "for \"%s\" (wrong executable or version mismatch?)"),
+ paddress (target_gdbarch, retval),
+ paddress (target_gdbarch, elf->minpagesize),
+ bfd_get_filename (exec_bfd));
+ return 0;
+ }
+ }
+
+ if (info_verbose)
+ {
+ /* It can be printed repeatedly as there is no easy way to check the
+ executable symbols/file has been already relocated to RETVAL. */
+
+ warning (_("Using PIE (Position Independent Executable) displacement "
+ "%s for \"%s\""),
+ paddress (target_gdbarch, retval),
+ bfd_get_filename (exec_bfd));
+ }
+ return retval;
+ }
return svr4_static_exec_displacement ();
}
--- a/gdb/testsuite/gdb.base/break-interp.exp
+++ b/gdb/testsuite/gdb.base/break-interp.exp
@@ -221,12 +221,28 @@ proc strip_debug {dest} {
}
# `runto' does not check we stopped really at the function we specified.
-proc reach {func command} {
+proc reach {func command displacement} {
global gdb_prompt
+ global pf_prefix
+ set old_ldprefix $pf_prefix
+ lappend pf_prefix "reach-$func:"
+
if [gdb_breakpoint $func allow-pending] {
- set test "reach $func"
+ set test "reach"
+ set test_displacement "seen displacement message"
gdb_test_multiple $command $test {
+ -re "Using PIE \\(Position Independent Executable\\) displacement" {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == 1} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement -1
+ } elseif {$displacement == 0} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
-re "Breakpoint \[0-9\]+, $func \\(.*\\) at .*:\[0-9\]+\r\n.*$gdb_prompt $" {
pass $test
}
@@ -234,10 +250,15 @@ proc reach {func command} {
pass $test
}
}
+ if {$displacement == 1} {
+ fail $test_displacement
+ }
}
+
+ set pf_prefix $old_ldprefix
}
-proc test_core {file} {
+proc test_core {file displacement} {
global srcdir subdir gdb_prompt
set corefile [core_find $file {} "segv"]
@@ -245,6 +266,10 @@ proc test_core {file} {
return
}
+ global pf_prefix
+ set old_ldprefix $pf_prefix
+ lappend pf_prefix "core:"
+
gdb_exit
gdb_start
# Clear it to never find any separate debug infos in $debug_root.
@@ -252,14 +277,39 @@ proc test_core {file} {
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $file
- # Do not check the binary filename as it may be truncated.
- gdb_test "core-file $corefile" "Core was generated by .*\r\n#0 .*" "core loaded"
+ # Print the "PIE (Position Independent Executable) displacement" message.
+ gdb_test "set verbose on"
+
+ set test "core loaded"
+ set test_displacement "seen displacement message"
+ gdb_test_multiple "core-file $corefile" $test {
+ -re "Using PIE \\(Position Independent Executable\\) displacement" {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == 1} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement -1
+ } elseif {$displacement == 0} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "Core was generated by .*\r\n#0 .*$gdb_prompt $" {
+ # Do not check the binary filename as it may be truncated.
+ pass $test
+ }
+ }
+ if {$displacement == 1} {
+ fail $test_displacement
+ }
gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "core main bt"
+
+ set pf_prefix $old_ldprefix
}
-proc test_attach {file} {
- global board_info
+proc test_attach {file displacement} {
+ global board_info gdb_prompt
gdb_exit
@@ -287,16 +337,55 @@ proc test_attach {file} {
}
}
+ global pf_prefix
+ set old_ldprefix $pf_prefix
+ lappend pf_prefix "attach:"
+
gdb_exit
gdb_start
- gdb_test "attach $pid" "Attaching to process $pid\r\n.*" "attach"
+
+ # Print the "PIE (Position Independent Executable) displacement" message.
+ gdb_test "set verbose on"
+
+ set test "attach"
+ gdb_test_multiple "attach $pid" $test {
+ -re "Attaching to process $pid\r\n" {
+ # Missing "$gdb_prompt $" is intentional.
+ pass $test
+ }
+ }
+
+ set test "attach final prompt"
+ set test_displacement "seen displacement message"
+ gdb_test_multiple "" $test {
+ -re "Using PIE \\(Position Independent Executable\\) displacement" {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == 1} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement -1
+ } elseif {$displacement == 0} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ pass $test
+ }
+ }
+ if {$displacement == 1} {
+ fail $test_displacement
+ }
+
gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "attach main bt"
gdb_exit
remote_exec host "kill -9 $pid"
+
+ set pf_prefix $old_ldprefix
}
-proc test_ld {file ifmain trynosym} {
+proc test_ld {file ifmain trynosym displacement} {
global srcdir subdir gdb_prompt
# First test normal `file'-command loaded $FILE with symbols.
@@ -308,20 +397,25 @@ proc test_ld {file ifmain trynosym} {
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $file
- reach "dl_main" "run segv"
+ # Print the "PIE (Position Independent Executable) displacement" message.
+ gdb_test "set verbose on"
+
+ reach "dl_main" "run segv" $displacement
gdb_test "bt" "#0 +\[^\r\n\]*\\mdl_main\\M.*" "dl bt"
if $ifmain {
- reach "main" continue
+ # Displacement message will be printed the second time on initializing
+ # the linker from svr4_special_symbol_handling.
+ reach "main" continue $displacement
- reach "libfunc" continue
+ reach "libfunc" continue 0
gdb_test "bt" "#0 +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#1 +\[^\r\n\]*\\mmain\\M.*" "main bt"
- test_core $file
+ test_core $file $displacement
- test_attach $file
+ test_attach $file $displacement
}
if !$trynosym {
@@ -341,12 +435,15 @@ proc test_ld {file ifmain trynosym} {
gdb_test "set debug-file-directory"
gdb_reinitialize_dir $srcdir/$subdir
+ # Print the "PIE (Position Independent Executable) displacement" message.
+ gdb_test "set verbose on"
+
# Test no (error) message has been printed by `exec-file'.
set escapedfile [string_to_regexp $file]
gdb_test "exec-file $file" "exec-file $escapedfile" "load"
if $ifmain {
- reach "dl_main" run
+ reach "dl_main" run $displacement
set test "info files"
set entrynohex ""
@@ -363,7 +460,29 @@ proc test_ld {file ifmain trynosym} {
} else {
# There is no symbol to break at ld.so. Moreover it can exit with an
# error code.
- gdb_test "run" "Program exited (normally|with code \[0-9\]+)\\." "ld.so exit"
+
+ set test "ld.so exit"
+ set test_displacement "seen displacement message"
+ gdb_test_multiple "run" $test {
+ -re "Using PIE \\(Position Independent Executable\\) displacement" {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$displacement == 1} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement -1
+ } elseif {$displacement == 0} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "Program exited (normally|with code \[0-9\]+)\\.\r\n$gdb_prompt $" {
+ # Do not check the binary filename as it may be truncated.
+ pass $test
+ }
+ }
+ if {$displacement == 1} {
+ fail $test_displacement
+ }
}
set pf_prefix $old_ldprefix
@@ -450,7 +569,7 @@ foreach ldprelink {NO YES} {
if ![prelink$ldprelink $interp] {
continue
}
- test_ld $interp 0 [expr {$ldsepdebug == "NO"}]
+ test_ld $interp 0 [expr {$ldsepdebug == "NO"}] [expr {$ldprelink == "NO"}]
if ![copy $interp $interp_saved] {
continue
@@ -531,7 +650,8 @@ foreach ldprelink {NO YES} {
if {[prelink$binprelink "--dynamic-linker=$interp --ld-library-path=$dir $exec $interp [concat $dests]" [file tail $exec]]
&& [copy $interp_saved $interp]} {
- test_ld $exec 1 [expr {$binsepdebug == "NO"}]
+ test_ld $exec 1 [expr {$binsepdebug == "NO"}] \
+ [expr {$binpie == "YES" && $binprelink == "NO"}]
}
}
}