Re: [patch-testcase] Re: RFC: Verify AT_ENTRY before using it

Jan Kratochvil
2010-03-11T21:54:29Z

On Mon, 08 Mar 2010 23:13:50 +0100, Daniel Jacobowitz wrote:
> On Mon, Mar 01, 2010 at 10:22:16PM +0100, Jan Kratochvil wrote:
> > + 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
> > + displacement. */
> > +
> > + warning (_("Using PIE (Position Independent Executable) "
> > + "displacement %s for \"%s\""),
> > + paddress (target_gdbarch, displacement),
> > + bfd_get_filename (exec_bfd));
> > + }
> > +
> > return displacement;
> > }
>
> This isn't a warning; just use printf_unfiltered.

While I agree I wanted to keep this message in sync with its existing PIC
counterpart. Therefore changed even the PIC message now in this patch.

The PIC message printing is already changed by gdb-7.0->7.1 only if
(info_verbose) therefore possible expectations on GDB output have been already
broken.

> > + -re "Using PIE \\(Position Independent Executable\\) displacement 0x0 " {
> > + -re "Using PIE \\(Position Independent Executable\\) displacement" {
>
> This isn't a safe way to use expect, unfortunately. If you have two
> patterns, and the second one matches a subset of the first, either
> might match; it depends where the OS and C library break up GDB's call
> to 'write'.

Missed that, thanks.

This patch is no longer a pre-requisite for anything and while it would be
fine I do not find it too important myself. There will be changes in this
code anyway on some planned unposted PIE cleanup/fixup patches.

No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu.

Thanks,
Jan

gdb/
2010-03-11 Jan Kratochvil <jan.kratochvil@redhat.com>

* solib-svr4.c (LM_ADDR_CHECK) <info_verbose>: Use printf_unfiltered
for the PIC displacement, print also the displacement value.
(svr4_exec_displacement): Print DISPLACEMENT if INFO_VERBOSE.

gdb/testsuite/
2010-03-11 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:". Import global expect_out.
(test_core): New parameter displacement, verify its content. New push
of pf_prefix "core:". New command "set verbose on". Import global
expect_out.
(test_attach): New parameter displacement, verify its content. New
push of pf_prefix "attach:". New command "set verbose on". Import
global expect_out.
(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.
* gdb.base/prelink.exp: Remove gdb_exit and final return.
(prelink): Update expected text, use gdb_test.

--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -243,12 +243,10 @@ LM_ADDR_CHECK (struct so_list *so, bfd *abfd)
l_addr = l_dynaddr - dynaddr;

if (info_verbose)
- {
- warning (_(".dynamic section for \"%s\" "
- "is not at the expected address"), so->so_name);
- warning (_("difference appears to be caused by prelink, "
- "adjusting expectations"));
- }
+ printf_unfiltered (_("Using PIC (Position Independent Code) "
+ "prelink displacement %s for \"%s\".\n"),
+ paddress (target_gdbarch, l_addr),
+ so->so_name);
}
else
warning (_(".dynamic section for \"%s\" "
@@ -1767,6 +1765,18 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
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
+ displacement. */
+
+ printf_unfiltered (_("Using PIE (Position Independent Executable) "
+ "displacement %s for \"%s\".\n"),
+ paddress (target_gdbarch, displacement),
+ bfd_get_filename (exec_bfd));
+ }
+
*displacementp = displacement;
return 1;
}
--- a/gdb/testsuite/gdb.base/break-interp.exp
+++ b/gdb/testsuite/gdb.base/break-interp.exp
@@ -221,30 +221,61 @@ proc strip_debug {dest} {
}

# `runto' does not check we stopped really at the function we specified.
-proc reach {func command} {
- global gdb_prompt
+# DISPLACEMENT can be "NONE", "ZERO" or "NONZERO"
+proc reach {func command displacement} {
+ global gdb_prompt expect_out
+
+ 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 as $displacement"
gdb_test_multiple $command $test {
+ -re "Using PIE \\(Position Independent Executable\\) displacement (0x\[0-9a-f\]+) " {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$expect_out(1,string) == "0x0"} {
+ set case "ZERO"
+ } else {
+ set case "NONZERO"
+ }
+ if {$displacement == $case} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-$case"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
-re "Breakpoint \[0-9\]+, $func \\(.*\\) at .*:\[0-9\]+\r\n.*$gdb_prompt $" {
pass $test
}
- -re "Breakpoint \[0-9\]+, \[0-9xa-f\]+ in $func \\(\\)( from .*)?\r\n$gdb_prompt $" {
+ -re "Breakpoint \[0-9\]+, \[0-9xa-f\]+ in $func \\(\\)( from .*)?\r\n$gdb_prompt $" {
pass $test
}
}
+ if ![regexp {^(NONE|FOUND-.*)$} $displacement] {
+ fail $test_displacement
+ }
}
+
+ set pf_prefix $old_ldprefix
}

-proc test_core {file} {
- global srcdir subdir gdb_prompt
+proc test_core {file displacement} {
+ global srcdir subdir gdb_prompt expect_out

set corefile [core_find $file {} "segv"]
if {$corefile == ""} {
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 +283,44 @@ 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 (0x\[0-9a-f\]+) " {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$expect_out(1,string) == "0x0"} {
+ set case "ZERO"
+ } else {
+ set case "NONZERO"
+ }
+ if {$displacement == $case} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-$case"} {
+ 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 ![regexp {^(NONE|FOUND-.*)$} $displacement] {
+ 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 expect_out

gdb_exit

@@ -287,17 +348,61 @@ 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 (0x\[0-9a-f\]+) " {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$expect_out(1,string) == "0x0"} {
+ set case "ZERO"
+ } else {
+ set case "NONZERO"
+ }
+ if {$displacement == $case} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-$case"} {
+ fail $test_displacement
+ }
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ pass $test
+ }
+ }
+ if ![regexp {^(NONE|FOUND-.*)$} $displacement] {
+ 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} {
- global srcdir subdir gdb_prompt
+proc test_ld {file ifmain trynosym displacement} {
+ global srcdir subdir gdb_prompt expect_out

# First test normal `file'-command loaded $FILE with symbols.

@@ -308,20 +413,31 @@ 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. If any ANOFFSET has
+ # been already set as non-zero the detection will no longer be run.
+ if {$displacement == "NONZERO"} {
+ set displacement_main "NONE"
+ } else {
+ set displacement_main $displacement
+ }
+ reach "main" continue $displacement_main

- reach "libfunc" continue
+ reach "libfunc" continue "NONE"

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,18 +457,21 @@ 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 ""
gdb_test_multiple $test $test {
-re "\r\n\[\t \]*Entry point:\[\t \]*0x(\[0-9a-f\]+)\r\n.*$gdb_prompt $" {
- set entrynohex $expect_out(1,string)
+ set entrynohex $expect_out(1,string)
pass $test
}
}
@@ -363,7 +482,34 @@ 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 (0x\[0-9a-f\]+) " {
+ # Missing "$gdb_prompt $" is intentional.
+ if {$expect_out(1,string) == "0x0"} {
+ set case "ZERO"
+ } else {
+ set case "NONZERO"
+ }
+ if {$displacement == $case} {
+ pass $test_displacement
+ # Permit multiple such messages.
+ set displacement "FOUND-$displacement"
+ } elseif {$displacement != "FOUND-$case"} {
+ 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 ![regexp {^(NONE|FOUND-.*)$} $displacement] {
+ fail $test_displacement
+ }
}

set pf_prefix $old_ldprefix
@@ -450,7 +596,12 @@ foreach ldprelink {NO YES} {
if ![prelink$ldprelink $interp] {
continue
}
- test_ld $interp 0 [expr {$ldsepdebug == "NO"}]
+ if {$ldprelink == "NO"} {
+ set displacement "NONZERO"
+ } else {
+ set displacement "ZERO"
+ }
+ test_ld $interp 0 [expr {$ldsepdebug == "NO"}] $displacement

if ![copy $interp $interp_saved] {
continue
@@ -531,7 +682,14 @@ 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"}]
+ if {$binpie == "NO"} {
+ set displacement "NONE"
+ } elseif {$binprelink == "NO"} {
+ set displacement "NONZERO"
+ } else {
+ set displacement "ZERO"
+ }
+ test_ld $exec 1 [expr {$binsepdebug == "NO"}] $displacement
}
}
}
--- a/gdb/testsuite/gdb.base/prelink.exp
+++ b/gdb/testsuite/gdb.base/prelink.exp
@@ -112,15 +112,4 @@ gdb_load ${binfile}
# Print the "adjusting expectations" message.
gdb_test "set verbose on"

-set test "prelink"
-global gdb_prompt
-gdb_test_multiple "core-file $objdir/$subdir/prelink.core" "$test" {
- -re "warning: \.dynamic section.*not at the expected address.*warning: difference.*caused by prelink, adjusting expectations.*$gdb_prompt $" {
- pass "$test"
- }
-}
-
-gdb_exit
-
-return 0
-
+gdb_test "core-file $objdir/$subdir/prelink.core" {Using PIC \(Position Independent Code\) prelink displacement.*} "prelink"