This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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 (&current_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"}]
 		    }
 		}
 	    }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]