From 7b8bd72d9a3f3cde322110ae90dccf2e4beaaedf Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Mar 29 2010 17:54:39 +0000 Subject: - Drop obsoleted `gdb-archer-pie-0315-breakpoint_address_match.patch'. - Do not consider memory error on reading _r_debug->r_map as fatal (BZ 576742). - PIE: Attach binary even after re-prelinked underneath. - PIE: Attach binary even after ld.so re-prelinked underneath. - PIE: Fix occasional error attaching i686 binary (BZ 576742). - testsuite: Fix unstable results of gdb.base/prelink.exp. --- diff --git a/gdb-6.7-testsuite-stable-results-prelink.patch b/gdb-6.7-testsuite-stable-results-prelink.patch new file mode 100644 index 0000000..3c51577 --- /dev/null +++ b/gdb-6.7-testsuite-stable-results-prelink.patch @@ -0,0 +1,68 @@ +http://sourceware.org/ml/gdb-patches/2010-03/msg01006.html +Subject: [patch or FYI] testsuite: Fix prelink.exp on system w/unprelinked system libs + +Hi, + +this is a more conservative variant superseded by: + [patch 4/6] testsuite: Unify to lib/prelink-support.exp + http://sourceware.org/ml/gdb-patches/2010-03/msg01002.html +where gdb.base/prelink.exp is reworked on generic lib/prelink-support.exp. + +I prefer the [patch 4/6] over this patch but this mail can serve also as an +illustration of the current problem. + +------------------------------------------------------------------------------ + +If your system for some reason currently does not have all the libraries +prelinked gdb.base/prelink.exp will get UNRESOLVED randomly also affecting +testsuite results diff. + +Apparently the testcase already tried to avoid any system libraries +dependencies by "-nodefaultlibs". But currently it does has not worked that +way. + +"-lm" is contained already even in dejagnu's default_target_compile (not just +in gdb/testsuite/lib/ada.exp). But I do not know why it is there and which +systems would get broken by some global gdb/testsuite/ "-lm" removal. + + +Thanks, +Jan + + +2010-03-29 Jan Kratochvil + + Fix testcase false UNRESOLVED if system libraries are not prelinked. + * gdb.base/prelink.exp: New variables compile, board, err and mathlib. + Set clear board mathlib for ${libfile} compilation. + +--- a/gdb/testsuite/gdb.base/prelink.exp ++++ b/gdb/testsuite/gdb.base/prelink.exp +@@ -42,7 +42,25 @@ set testfile "prelink" + + set libsrcfile ${testfile}-lib.c + set libfile ${objdir}/${subdir}/${testfile}.so +-if { [gdb_compile "${srcdir}/${subdir}/${libsrcfile}" "${libfile}" executable [list debug "additional_flags=-fpic -shared -nodefaultlibs"]] != ""} { ++ ++# default_target_compile would otherwise add "-lm" making the testcase ++# dependent on whether the system libraries are already prelinked. ++# prelink: Could not set /lib64/libm-2.11.1.so owner or mode: Operation not permitted ++set compile { ++ gdb_compile "${srcdir}/${subdir}/${libsrcfile}" "${libfile}" executable [list debug "additional_flags=-fpic -shared -nodefaultlibs"] ++} ++set board [target_info name] ++if [board_info $board exists mathlib] { ++ set mathlib [board_info $dest mathlib] ++ set_board_info mathlib "" ++ set err [eval $compile] ++ set_board_info mathlib $mathlib ++} else { ++ set_board_info mathlib "" ++ set err [eval $compile] ++ unset_board_info mathlib ++} ++if {$err != ""} { + # If creating the shared library fails, maybe we don't have the right tools + return -1 + } + diff --git a/gdb-archer-pie-0315-breakpoint_address_match.patch b/gdb-archer-pie-0315-breakpoint_address_match.patch deleted file mode 100644 index 0000597..0000000 --- a/gdb-archer-pie-0315-breakpoint_address_match.patch +++ /dev/null @@ -1,77 +0,0 @@ -[ Forward-ported context. ] - -http://sourceware.org/ml/gdb-patches/2009-11/msg00170.html -Subject: [patch 03/15] PIE: breakpoint_address_match gdbarch_addr_bit workaround - -Hi, - -there are already multiple cases of CORE_ADDR being masked by the width of -gdbarch_addr_bit. This specific new case was required the PIE support. - -Please read the C comment in attached patch. - -Checked that CORE_ADDR math operations are present on 6000+ lines of code of -GDB sources which makes it impossible to do some general fix by replacing all - a->addr < b->addr -by - addr_less_than (a->addr, b->addr) -etc. - -Even with this patch I think there are still many bugs left in the operation -of x86_64 gdb debugging i386 targets. Do you find the C++ way as a viable -one? - - -Thanks, -Jan - - -gdb/ - * breakpoint.c (breakpoint_address_match): New variables addr_bit and - addr_mask, initialize it. Mask addresses by ADDR_MASK. - * defs.h (CORE_ADDR): Extend the comment. - ---- a/gdb/breakpoint.c -+++ b/gdb/breakpoint.c -@@ -4559,9 +4559,15 @@ static int - breakpoint_address_match (struct address_space *aspace1, CORE_ADDR addr1, - struct address_space *aspace2, CORE_ADDR addr2) - { -+ int addr_bit = gdbarch_addr_bit (target_gdbarch); -+ CORE_ADDR addr_mask = CORE_ADDR_MAX; -+ -+ if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) -+ addr_mask = ((CORE_ADDR) 1 << addr_bit) - 1; -+ - return ((gdbarch_has_global_breakpoints (target_gdbarch) - || aspace1 == aspace2) -- && addr1 == addr2); -+ && (addr1 & addr_mask) == (addr2 & addr_mask)); - } - - /* Assuming LOC1 and LOC2's types' have meaningful target addresses ---- a/gdb/defs.h -+++ b/gdb/defs.h -@@ -98,7 +98,20 @@ - /* A byte from the program being debugged. */ - typedef bfd_byte gdb_byte; - --/* An address in the program being debugged. Host byte order. */ -+/* An address in the program being debugged. Host byte order. -+ -+ Its width is the maximum width of all the supported targets. That means -+ 32-bit target will run on such GDB using 64-bit CORE_ADDR cluttering the -+ bits 32...63 with random data from internal GDB calculations. GDB currently -+ in general truncates the address width only when it is being presented/used -+ externally (such as by the paddress function). -+ -+ FIXME: This is still not right as any GDB internal comparisons (such as >=) -+ of CORE_ADDR do not use the properly truncated width. As converting all the -+ CORE_ADDR operations to width-aware functions is not feasible the way out -+ could be a width-aware C++ class CORE_ADDR referencing gdbarch as its -+ constructor parameter. */ -+ - typedef bfd_vma CORE_ADDR; - - /* The largest CORE_ADDR value. */ - diff --git a/gdb-pie-1of6-reprelinked-bin.patch b/gdb-pie-1of6-reprelinked-bin.patch new file mode 100644 index 0000000..277bc77 --- /dev/null +++ b/gdb-pie-1of6-reprelinked-bin.patch @@ -0,0 +1,443 @@ +http://sourceware.org/ml/gdb-patches/2010-03/msg01008.html +Subject: [patch 1/6]: PIE: Attach binary even after re-prelinked underneath + +Hi, + +there is a regression (against previous unreleased commits) by: + Re: RFC: Verify AT_ENTRY before using it + http://sourceware.org/ml/gdb-patches/2010-03/msg00395.html + +for loading PIE executables which have changed on the disk since started. +There are in fact 3 different addresses one has to properly deal with. + +This patch uses explicit "file" so it is not dependent on pending: + [patch] Attach to running but deleted executable + http://sourceware.org/ml/gdb-patches/2010-03/msg00950.html + +The two copy-pasted blocks for elf32 and elf64 are "not nice" but this is the +current style in GDB. + +No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu for the whole +patch series together. + + +Thanks, +Jan + + +gdb/ +2010-03-29 Jan Kratochvil + + Fix attaching to PIEs prelinked on the disk since their start. + * solib-svr4.c (svr4_exec_displacement): New variable arch_size. + Verify it against bfd_get_arch_size. Try to match arbitrary + displacement for the phdrs comparison. + +gdb/testsuite/ +2010-03-29 Jan Kratochvil + + * gdb.base/break-interp.exp: Run $binpie with new value "ATTACH", new + code for it. New variable relink_args. + (prelinkYES): Call prelinkNO. + (test_attach): Accept new parameter relink_args. Re-prelink the binary + in such case. Move the core code to ... + (test_attach_gdb): ... a new function. Send GDB command "file". + Extend expected "Attaching to " string. + +--- a/gdb/solib-svr4.c ++++ b/gdb/solib-svr4.c +@@ -1750,13 +1750,183 @@ svr4_exec_displacement (CORE_ADDR *displacementp) + really do not match. */ + int phdrs_size, phdrs2_size, ok = 1; + gdb_byte *buf, *buf2; ++ int arch_size; + +- buf = read_program_header (-1, &phdrs_size, NULL); ++ buf = read_program_header (-1, &phdrs_size, &arch_size); + buf2 = read_program_headers_from_bfd (exec_bfd, &phdrs2_size); +- if (buf != NULL && buf2 != NULL +- && (phdrs_size != phdrs2_size +- || memcmp (buf, buf2, phdrs_size) != 0)) +- ok = 0; ++ if (buf != NULL && buf2 != NULL) ++ { ++ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); ++ ++ /* We are dealing with three different addresses. EXEC_BFD ++ represents current address in on-disk file. target memory content ++ may be different from EXEC_BFD as the file may have been prelinked ++ to a different address since the executable has been loaded. ++ Moreover the address of placement in target memory can be ++ different from what say the target memory program headers - this ++ is the goal of PIE. ++ ++ Detected DISPLACEMENT covers both the offsets of PIE placement and ++ possible new prelink since start of the program. Here relocate ++ BUF and BUF2 just by the EXEC_BFD vs. target memory content offset ++ for the verification purpose. */ ++ ++ if (phdrs_size != phdrs2_size ++ || bfd_get_arch_size (exec_bfd) != arch_size) ++ ok = 0; ++ else if (arch_size == 32 && phdrs_size >= sizeof (Elf32_External_Phdr) ++ && phdrs_size % sizeof (Elf32_External_Phdr) == 0) ++ { ++ Elf_Internal_Ehdr *ehdr2 = elf_tdata (exec_bfd)->elf_header; ++ Elf_Internal_Phdr *phdr2 = elf_tdata (exec_bfd)->phdr; ++ CORE_ADDR displacement = 0; ++ int i; ++ ++ /* DISPLACEMENT could be found easier by the difference of ++ ehdr2->e_entry but already read BUF does not contain ehdr. */ ++ ++ for (i = 0; i < ehdr2->e_phnum; i++) ++ if (phdr2[i].p_type == PT_LOAD) ++ { ++ Elf32_External_Phdr *phdrp; ++ gdb_byte *buf_vaddr_p, *buf_paddr_p; ++ CORE_ADDR vaddr, paddr; ++ CORE_ADDR displacement_vaddr = 0; ++ CORE_ADDR displacement_paddr = 0; ++ ++ phdrp = &((Elf32_External_Phdr *) buf)[i]; ++ buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr; ++ buf_paddr_p = (gdb_byte *) &phdrp->p_paddr; ++ ++ vaddr = extract_unsigned_integer (buf_vaddr_p, 4, ++ byte_order); ++ displacement_vaddr = vaddr - phdr2[i].p_vaddr; ++ ++ paddr = extract_unsigned_integer (buf_paddr_p, 4, ++ byte_order); ++ displacement_paddr = paddr - phdr2[i].p_paddr; ++ ++ if (displacement_vaddr == displacement_paddr) ++ displacement = displacement_vaddr; ++ ++ break; ++ } ++ ++ /* Now compare BUF and BUF2 with optional DISPLACEMENT. */ ++ ++ for (i = 0; i < phdrs_size / sizeof (Elf32_External_Phdr); i++) ++ { ++ Elf32_External_Phdr *phdrp; ++ Elf32_External_Phdr *phdr2p; ++ gdb_byte *buf_vaddr_p, *buf_paddr_p; ++ CORE_ADDR vaddr, paddr; ++ ++ phdrp = &((Elf32_External_Phdr *) buf)[i]; ++ buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr; ++ buf_paddr_p = (gdb_byte *) &phdrp->p_paddr; ++ phdr2p = &((Elf32_External_Phdr *) buf2)[i]; ++ ++ /* PT_GNU_STACK addresses are left as zero not being ++ relocated by prelink, their displacing would create false ++ verification failure. Feel free to test the unrelocated ++ comparison for any segment type. */ ++ ++ if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0) ++ continue; ++ ++ vaddr = extract_unsigned_integer (buf_vaddr_p, 4, byte_order); ++ vaddr -= displacement; ++ store_unsigned_integer (buf_vaddr_p, 4, byte_order, vaddr); ++ ++ paddr = extract_unsigned_integer (buf_paddr_p, 4, byte_order); ++ paddr -= displacement; ++ store_unsigned_integer (buf_paddr_p, 4, byte_order, paddr); ++ ++ if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0) ++ continue; ++ ++ ok = 0; ++ break; ++ } ++ } ++ else if (arch_size == 64 && phdrs_size >= sizeof (Elf64_External_Phdr) ++ && phdrs_size % sizeof (Elf64_External_Phdr) == 0) ++ { ++ Elf_Internal_Ehdr *ehdr2 = elf_tdata (exec_bfd)->elf_header; ++ Elf_Internal_Phdr *phdr2 = elf_tdata (exec_bfd)->phdr; ++ CORE_ADDR displacement = 0; ++ int i; ++ ++ /* DISPLACEMENT could be found easier by the difference of ++ ehdr2->e_entry but already read BUF does not contain ehdr. */ ++ ++ for (i = 0; i < ehdr2->e_phnum; i++) ++ if (phdr2[i].p_type == PT_LOAD) ++ { ++ Elf64_External_Phdr *phdrp; ++ gdb_byte *buf_vaddr_p, *buf_paddr_p; ++ CORE_ADDR vaddr, paddr; ++ CORE_ADDR displacement_vaddr = 0; ++ CORE_ADDR displacement_paddr = 0; ++ ++ phdrp = &((Elf64_External_Phdr *) buf)[i]; ++ buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr; ++ buf_paddr_p = (gdb_byte *) &phdrp->p_paddr; ++ ++ vaddr = extract_unsigned_integer (buf_vaddr_p, 8, ++ byte_order); ++ displacement_vaddr = vaddr - phdr2[i].p_vaddr; ++ ++ paddr = extract_unsigned_integer (buf_paddr_p, 8, ++ byte_order); ++ displacement_paddr = paddr - phdr2[i].p_paddr; ++ ++ if (displacement_vaddr == displacement_paddr) ++ displacement = displacement_vaddr; ++ ++ break; ++ } ++ ++ /* Now compare BUF and BUF2 with optional DISPLACEMENT. */ ++ ++ for (i = 0; i < phdrs_size / sizeof (Elf64_External_Phdr); i++) ++ { ++ Elf64_External_Phdr *phdrp; ++ Elf64_External_Phdr *phdr2p; ++ gdb_byte *buf_vaddr_p, *buf_paddr_p; ++ CORE_ADDR vaddr, paddr; ++ ++ phdrp = &((Elf64_External_Phdr *) buf)[i]; ++ buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr; ++ buf_paddr_p = (gdb_byte *) &phdrp->p_paddr; ++ phdr2p = &((Elf64_External_Phdr *) buf2)[i]; ++ ++ /* PT_GNU_STACK addresses are left as zero not being ++ relocated by prelink, their displacing would create false ++ verification failure. Feel free to test the unrelocated ++ comparison for any segment type. */ ++ ++ if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0) ++ continue; ++ ++ vaddr = extract_unsigned_integer (buf_vaddr_p, 8, byte_order); ++ vaddr -= displacement; ++ store_unsigned_integer (buf_vaddr_p, 8, byte_order, vaddr); ++ ++ paddr = extract_unsigned_integer (buf_paddr_p, 8, byte_order); ++ paddr -= displacement; ++ store_unsigned_integer (buf_paddr_p, 8, byte_order, paddr); ++ ++ if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0) ++ continue; ++ ++ ok = 0; ++ break; ++ } ++ } ++ else ++ ok = 0; ++ } + + xfree (buf); + xfree (buf2); +--- a/gdb/testsuite/gdb.base/break-interp.exp ++++ b/gdb/testsuite/gdb.base/break-interp.exp +@@ -154,6 +154,12 @@ proc prelinkYES {arg {name ""}} { + if {$name == ""} { + set name [file tail $arg] + } ++ ++ # Try to unprelink it first so that if it has been already prelinked before ++ # we get different address now and the result is not affected by the ++ # previous $arg state.. ++ prelinkNO $arg "$name pre-unprelink" ++ + set test "prelink $name" + set command "exec /usr/sbin/prelink -qNR --no-exec-shield $arg" + verbose -log "command is $command" +@@ -319,38 +325,12 @@ proc test_core {file displacement} { + set pf_prefix $old_ldprefix + } + +-proc test_attach {file displacement} { +- global board_info gdb_prompt expect_out +- +- gdb_exit +- +- set test "sleep function started" +- +- set command "${file} sleep" +- set res [remote_spawn host $command]; +- if { $res < 0 || $res == "" } { +- perror "Spawning $command failed." +- fail $test +- return +- } +- set pid [exp_pid -i $res] +- gdb_expect { +- -re "sleeping\r\n" { +- pass $test +- } +- eof { +- fail "$test (eof)" +- return +- } +- timeout { +- fail "$test (timeout)" +- return +- } +- } ++proc test_attach_gdb {file pid displacement prefix} { ++ global gdb_prompt expect_out + + global pf_prefix + set old_ldprefix $pf_prefix +- lappend pf_prefix "attach:" ++ lappend pf_prefix "$prefix:" + + gdb_exit + gdb_start +@@ -358,9 +338,13 @@ proc test_attach {file displacement} { + # Print the "PIE (Position Independent Executable) displacement" message. + gdb_test "set verbose on" + ++ if {$file != ""} { ++ gdb_test "file $file" "Reading symbols from .*done\\." "file" ++ } ++ + set test "attach" + gdb_test_multiple "attach $pid" $test { +- -re "Attaching to process $pid\r\n" { ++ -re "Attaching to (program: .*, )?process $pid\r\n" { + # Missing "$gdb_prompt $" is intentional. + pass $test + } +@@ -396,11 +380,56 @@ proc test_attach {file 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_attach {file displacement {relink_args ""}} { ++ global board_info ++ ++ gdb_exit ++ ++ set test "sleep function started" ++ ++ set command "${file} sleep" ++ set res [remote_spawn host $command]; ++ if { $res < 0 || $res == "" } { ++ perror "Spawning $command failed." ++ fail $test ++ return ++ } ++ set pid [exp_pid -i $res] ++ gdb_expect { ++ -re "sleeping\r\n" { ++ pass $test ++ } ++ eof { ++ fail "$test (eof)" ++ return ++ } ++ timeout { ++ fail "$test (timeout)" ++ return ++ } ++ } ++ ++ if {$relink_args == ""} { ++ test_attach_gdb "" $pid $displacement "attach" ++ } else { ++ # These could be rather passed as arguments. ++ global exec interp_saved interp ++ ++ foreach relink {YES NO} { ++ if {[prelink$relink $relink_args [file tail $exec]] ++ && [copy $interp_saved $interp]} { ++ # /proc/PID/exe cannot be loaded as it is "EXECNAME (deleted)". ++ test_attach_gdb $exec $pid $displacement "attach-relink$relink" ++ } ++ } ++ } ++ ++ remote_exec host "kill -9 $pid" ++} ++ + proc test_ld {file ifmain trynosym displacement} { + global srcdir subdir gdb_prompt expect_out + +@@ -609,7 +638,10 @@ foreach ldprelink {NO YES} { + set old_binprefix $pf_prefix + foreach binprelink {NO YES} { + foreach binsepdebug {NO IN SEP} { +- foreach binpie {NO YES} { ++ # "ATTACH" is like "YES" but it is modified during run. ++ # It cannot be used for problem reproducibility after the ++ # testcase ends. ++ foreach binpie {NO YES ATTACH} { + # This combination is not possible, non-PIE (fixed address) + # binary cannot be prelinked to any (other) address. + if {$binprelink == "YES" && $binpie == "NO"} { +@@ -628,7 +660,7 @@ foreach ldprelink {NO YES} { + if {$binsepdebug != "NO"} { + lappend opts {debug} + } +- if {$binpie == "YES"} { ++ if {$binpie != "NO"} { + lappend opts {additional_flags=-fPIE -pie} + } + if {[build_executable ${test}.exp [file tail $exec] $srcfile $opts] == -1} { +@@ -680,16 +712,45 @@ foreach ldprelink {NO YES} { + lappend dests $dest + } + +- if {[prelink$binprelink "--dynamic-linker=$interp --ld-library-path=$dir $exec $interp [concat $dests]" [file tail $exec]] ++ if {$binpie == "NO"} { ++ set displacement "NONE" ++ } elseif {$binprelink == "NO"} { ++ set displacement "NONZERO" ++ } else { ++ set displacement "ZERO" ++ } ++ ++ set relink_args "--dynamic-linker=$interp --ld-library-path=$dir $exec $interp [concat $dests]" ++ if {[prelink$binprelink $relink_args [file tail $exec]] + && [copy $interp_saved $interp]} { +- if {$binpie == "NO"} { +- set displacement "NONE" +- } elseif {$binprelink == "NO"} { +- set displacement "NONZERO" ++ if {$binpie != "ATTACH"} { ++ test_ld $exec 1 [expr {$binsepdebug == "NO"}] $displacement + } else { +- set displacement "ZERO" ++ # If the file has been randomly prelinked it must ++ # be "NONZERO". We could see "ZERO" only if it was ++ # unprelinked na it is now running at the same ++ # address - which is 0 but executable can never run ++ # at address 0. ++ ++ set displacement "NONZERO" ++ test_attach $exec $displacement $relink_args ++ ++ # ATTACH executables + libraries get modified since ++ # they have been run. They cannot be used for ++ # problem reproducibility after the testcase ends. ++ set exec_debug [system_debug_get $exec] ++ if {$exec_debug != ""} { ++ # `file delete [glob "${exec_debug}*"]' does not work. ++ foreach f [glob "${exec_debug}*"] { ++ file delete $f ++ } ++ } ++ file delete -force $dir ++ # `file delete [glob "${exec}*"]' does not work. ++ foreach f [glob "${exec}*"] { ++ file delete $f ++ } + } +- test_ld $exec 1 [expr {$binsepdebug == "NO"}] $displacement + } + } + } + diff --git a/gdb-pie-2of6-reprelinked-ld.patch b/gdb-pie-2of6-reprelinked-ld.patch new file mode 100644 index 0000000..4f054a8 --- /dev/null +++ b/gdb-pie-2of6-reprelinked-ld.patch @@ -0,0 +1,87 @@ +http://sourceware.org/ml/gdb-patches/2010-03/msg01000.html +Subject: [patch 2/6] PIE: Attach binary even after ld.so re-prelinked underneath + +Hi, + +when I have seen the PIE-binary-changed-sice-start tested also +ld.so-changed-since-start and it did not work. + +There is questionable when to print and when to not to print non-fatal memory +read errors. Similar change I requested in + Re: [RFC/ia64] memory error when reading wrong core file + http://sourceware.org/ml/gdb-patches/2010-02/msg00001.html +so that GDB prints at least as a warning + Cannot access memory at address ... +when some unexpected error happens. + +Contrary to it there is not such warning present in the code below as in the +case of non-valgrind PIE with re-prelinked ld.so the memory read error happens +there. Some GDB code rework could probably avoid it. + +Just for example all the memory read errors in read_program_header or even +- primarily - scan_dyntag are currently IMO-incorrectly silent and others. +Therefore posted the patch this way, making all these warnings printed and +possibly fixing code attempting incorrect reads along the way could be done by +a different patch. + +No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu for the whole +patch series together. + + +Thanks, +Jan + + +gdb/ +2010-03-29 Jan Kratochvil + + * auxv.c (ld_so_xfer_auxv): Do not error on failed read of data_address. + +gdb/testsuite/ +2010-03-29 Jan Kratochvil + + * gdb.base/break-interp.exp (test_attach): Keep $interp changed. Move + its restore after the <$relink_args != ""> loop. new comment. + +--- a/gdb/auxv.c ++++ b/gdb/auxv.c +@@ -96,7 +96,16 @@ ld_so_xfer_auxv (gdb_byte *readbuf, + + pointer_address = SYMBOL_VALUE_ADDRESS (msym); + +- data_address = read_memory_typed_address (pointer_address, ptr_type); ++ /* While it is an error I am not aware how to solve attaching to PIE under ++ valgrind --db-attach=yes different way when ld.so on-disk file has prelink ++ change in the meantime. Currently GDB will drop back to procfs_xfer_auxv ++ (so that at least non-valgrind PIE attachments with prelink change of ++ ld.so work). To make it working even with valgrind is PR 11440 requiring ++ a valgrind extension. */ ++ if (target_read_memory (pointer_address, ptr_buf, ptr_size) != 0) ++ return -1; ++ ++ data_address = extract_typed_address (ptr_buf, ptr_type); + + /* Possibly still not initialized such as during an inferior startup. */ + if (data_address == 0) +--- a/gdb/testsuite/gdb.base/break-interp.exp ++++ b/gdb/testsuite/gdb.base/break-interp.exp +@@ -419,12 +419,16 @@ proc test_attach {file displacement {relink_args ""}} { + global exec interp_saved interp + + foreach relink {YES NO} { +- if {[prelink$relink $relink_args [file tail $exec]] +- && [copy $interp_saved $interp]} { ++ # It would be more correct to also [copy $interp_saved $interp] ++ # here to really test just different prelink of $exec. ++ # But we would need a separate test for different prelink of ld.so ++ # where a bug occured. It is now all merged into this single test. ++ if [prelink$relink $relink_args [file tail $exec]] { + # /proc/PID/exe cannot be loaded as it is "EXECNAME (deleted)". + test_attach_gdb $exec $pid $displacement "attach-relink$relink" + } + } ++ copy $interp_saved $interp + } + + remote_exec host "kill -9 $pid" + diff --git a/gdb-pie-3of6-relocate-once.patch b/gdb-pie-3of6-relocate-once.patch new file mode 100644 index 0000000..397a5db --- /dev/null +++ b/gdb-pie-3of6-relocate-once.patch @@ -0,0 +1,412 @@ +http://sourceware.org/ml/gdb-patches/2010-03/msg01001.html +Subject: [patch 3/6] PIE: Fix occasional error attaching i686 binary + +[ Testcase diff backported. ] + +Hi, + +this is the real bugreport which started this patch series. + gdb "Cannot access memory" on a running process + https://bugzilla.redhat.com/show_bug.cgi?id=576742 + +Offsets on i686 cause that while attaching to an unprelinked running PIE +scan_dyntag will incorrectly get a successful read in scan_dyntag from DT_DEBUG +it expects is from the mani executable but in fact it is from some ld.so or +libc.so (located low for --exec-shield). Another issue is that scan_dyntag +could verify more that the target memory matches the .dynamic section it is +reading from exec_bfd. It could also complain when the read failed (as always +failed so for for PIE attaches first, succeeded later so nobody has noticed +anything). + +The successful read reads a bogus DT_DEBUG value and GDB errors on it later. +This is again a non-fatal error after the patch by Joel Brobecker above but it +was not so before and it is incorrect anyway. + +The svr4_relocate_main_executable call in svr4_special_symbol_handling was +there before delayed that way for svr4_static_exec_displacement. +But svr4_static_exec_displacement has been removed in the meantime by: + Re: RFC: Verify AT_ENTRY before using it + http://sourceware.org/ml/gdb-patches/2010-03/msg00030.html + +So it can be simplified + corrected now. Moreover GDB will now finally print +exactly "Using PIE (Position Independent Executable) displacement" exactly +once. + +The reproducer depends on various offsets which may be distro dependent but it +was made so that it is hopefully reproducible everywhere. Reproduced + fixed +on Fedora 12 x86_64 and i686. + +No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu for the whole +patch series together. + + +Thanks, +Jan + + +gdb/ +2010-03-29 Jan Kratochvil + + * auxv.c (memory_xfer_auxv): Update attach comment. + * solib-svr4.c (svr4_special_symbol_handling): Remove the call to + svr4_relocate_main_executable. + (svr4_solib_create_inferior_hook): Make the call to + svr4_relocate_main_executable unconditional. + +gdb/testsuite/ +2010-03-29 Jan Kratochvil + + * gdb.base/attach-pie-misread.exp, gdb.base/attach-pie-misread.c: New. + +--- a/gdb/auxv.c ++++ b/gdb/auxv.c +@@ -198,7 +198,8 @@ memory_xfer_auxv (struct target_ops *ops, + + /* ld_so_xfer_auxv is the only function safe for virtual executables being + executed by valgrind's memcheck. As using ld_so_xfer_auxv is problematic +- during inferior startup GDB does call it only for attached processes. */ ++ during inferior startup as ld.so symbol tables are not yet relocated GDB ++ calls ld_so_xfer_auxv only for attached processes. */ + + if (current_inferior ()->attach_flag != 0) + { +--- a/gdb/solib-svr4.c ++++ b/gdb/solib-svr4.c +@@ -1628,7 +1628,6 @@ enable_break (struct svr4_info *info, int from_tty) + static void + svr4_special_symbol_handling (void) + { +- svr4_relocate_main_executable (); + } + + /* Read the ELF program headers from ABFD. Return the contents and +@@ -2065,8 +2064,7 @@ svr4_solib_create_inferior_hook (int from_tty) + info = get_svr4_info (); + + /* Relocate the main executable if necessary. */ +- if (current_inferior ()->attach_flag == 0) +- svr4_relocate_main_executable (); ++ svr4_relocate_main_executable (); + + if (!svr4_have_link_map_offsets ()) + return; +--- /dev/null ++++ b/gdb/testsuite/gdb.base/attach-pie-misread.c +@@ -0,0 +1,47 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2010 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 ++ ++const char stub[] = { ++#ifdef GEN ++# include GEN ++#endif ++}; ++ ++int ++main (int argc, char **argv) ++{ ++ /* Generator of GEN written in Python takes about 15s for x86_64's 4MB. */ ++ if (argc == 2) ++ { ++ long count = strtol (argv[1], NULL, 0); ++ ++ while (count-- > 0) ++ puts ("0x55,"); ++ ++ return 0; ++ } ++ if (argc != 1) ++ return 1; ++ ++ puts ("sleeping"); ++ fflush (stdout); ++ ++ return sleep (60); ++} +--- /dev/null ++++ b/gdb/testsuite/gdb.base/attach-pie-misread.exp +@@ -0,0 +1,209 @@ ++# Copyright 2010 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 . ++ ++# This test only works on GNU/Linux. ++if { ![isnative] || [is_remote host] || ![istarget *-linux*] || [skip_shlib_tests]} { ++ continue ++} ++ ++set test "attach-pie-misread" ++set srcfile ${test}.c ++set genfile ${objdir}/${subdir}/${test}-gen.h ++set executable ${test} ++set binfile ${objdir}/${subdir}/${executable} ++ ++if {[build_executable ${test}.exp $executable $srcfile [list "additional_flags=-fPIE -pie"]] == -1} { ++ return -1 ++} ++ ++# Program Headers: ++# Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align ++# LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x134f5ec 0x134f5ec R E 0x200000 ++# LOAD 0x134f5f0 0x000000000194f5f0 0x000000000194f5f0 0x1dbc60 0x214088 RW 0x200000 ++# DYNAMIC 0x134f618 0x000000000194f618 0x000000000194f618 0x000200 0x000200 RW 0x8 ++# ++proc read_phdr {binfile test} { ++ set readelf_program [transform readelf] ++ set command "exec $readelf_program -Wl $binfile" ++ verbose -log "command is $command" ++ set result [catch $command output] ++ verbose -log "result is $result" ++ verbose -log "output is $output" ++ if {$result != 0} { ++ fail $test ++ return ++ } ++ if ![regexp {\nProgram Headers:\n *Type [^\n]* Align\n(.*?)\n\n} $output trash phdr] { ++ fail "$test (no Program Headers)" ++ return ++ } ++ if ![regexp -line {^ *DYNAMIC +0x[0-9a-f]+ +(0x[0-9a-f]+) } $phdr trash dynamic_vaddr] { ++ fail "$test (no DYNAMIC found)" ++ return ++ } ++ verbose -log "dynamic_vaddr is $dynamic_vaddr" ++ set align_max -1 ++ foreach {trash align} [regexp -line -all -inline {^ *LOAD .* (0x[0-9]+)$} $phdr] { ++ if {$align_max < $align} { ++ set align_max $align ++ } ++ } ++ verbose -log "align_max is $align_max" ++ if {$align_max == -1} { ++ fail "$test (no LOAD found)" ++ return ++ } ++ pass $test ++ return [list $dynamic_vaddr $align_max] ++} ++ ++set phdr [read_phdr $binfile "readelf initial scan"] ++set dynamic_vaddr [lindex $phdr 0] ++set align_max [lindex $phdr 1] ++ ++set stub_size [format 0x%x [expr "2 * $align_max - ($dynamic_vaddr & ($align_max - 1))"]] ++verbose -log "stub_size is $stub_size" ++ ++# On x86_64 it is commonly about 4MB. ++if {$stub_size > 25000000} { ++ xfail "stub size $stub_size is too large" ++ return ++} ++ ++set test "generate stub" ++set command "exec $binfile $stub_size >$genfile" ++verbose -log "command is $command" ++set result [catch $command output] ++verbose -log "result is $result" ++verbose -log "output is $output" ++if {$result == 0} { ++ pass $test ++} else { ++ fail $test ++} ++ ++if {[build_executable ${test}.exp $executable $srcfile [list "additional_flags=-fPIE -pie -DGEN=\"$genfile\""]] == -1} { ++ return -1 ++} ++ ++# x86_64 file has 25MB, no need to keep it. ++file delete -- $genfile ++ ++set phdr [read_phdr $binfile "readelf rebuilt with stub_size"] ++set dynamic_vaddr_prelinkno [lindex $phdr 0] ++ ++set command "exec /usr/sbin/prelink -q -N --no-exec-shield -R $binfile" ++verbose -log "command is $command" ++set result [catch $command output] ++verbose -log "result is $result" ++verbose -log "output is $output" ++ ++set test "prelink -R" ++if {$result == 0 && $output == ""} { ++ pass $test ++} elseif {$result == 1 && [regexp {^(couldn't execute "/usr/sbin/prelink[^\r\n]*": no such file or directory\n?)*$} $output]} { ++ untested attach-pie-misread.exp ++ return -1 ++} else { ++ fail $test ++} ++ ++set phdr [read_phdr $binfile "readelf with prelink -R"] ++set dynamic_vaddr_prelinkyes [lindex $phdr 0] ++ ++set first_offset [format 0x%x [expr $dynamic_vaddr_prelinkyes - $dynamic_vaddr_prelinkno]] ++verbose -log "first_offset is $first_offset" ++ ++set test "first offset is non-zero" ++if {$first_offset == 0} { ++ fail "$test (-fPIE -pie in effect?)" ++} else { ++ pass $test ++} ++ ++set test "start inferior" ++gdb_exit ++ ++set res [remote_spawn host $binfile]; ++if { $res < 0 || $res == "" } { ++ perror "Spawning $binfile failed." ++ fail $test ++ return ++} ++set pid [exp_pid -i $res] ++gdb_expect { ++ -re "sleeping\r\n" { ++ pass $test ++ } ++ eof { ++ fail "$test (eof)" ++ remote_exec host "kill -9 $pid" ++ return ++ } ++ timeout { ++ fail "$test (timeout)" ++ remote_exec host "kill -9 $pid" ++ return ++ } ++} ++ ++# Due to alignments it was reproducible with 1 on x86_64 but 2 on i686. ++foreach align_mult {1 2} { ++ set old_ldprefix $pf_prefix ++ lappend pf_prefix "shift-by-$align_mult:" ++ ++ # FIXME: We believe there is enough room under FIRST_OFFSET. ++ set shifted_offset [format 0x%x [expr "$first_offset - $align_mult * $align_max"]] ++ verbose -log "shifted_offset is $shifted_offset" ++ ++ set command "exec /usr/sbin/prelink -q -N --no-exec-shield -r $shifted_offset $binfile" ++ verbose -log "command is $command" ++ set result [catch $command output] ++ verbose -log "result is $result" ++ verbose -log "output is $output" ++ ++ set test "prelink -r" ++ if {$result == 0 && $output == ""} { ++ pass $test ++ } else { ++ fail $test ++ } ++ ++ clean_restart $executable ++ ++ set test "attach" ++ gdb_test_multiple "attach $pid" $test { ++ -re "Attaching to program: .*, process $pid\r\n" { ++ # Missing "$gdb_prompt $" is intentional. ++ pass $test ++ } ++ } ++ ++ set test "error on Cannot access memory at address" ++ gdb_test_multiple "" $test { ++ -re "\r\nCannot access memory at address .*$gdb_prompt $" { ++ fail $test ++ } ++ -re "$gdb_prompt $" { ++ pass $test ++ } ++ } ++ ++ gdb_test "detach" "Detaching from program: .*" ++ ++ set pf_prefix $old_ldprefix ++} ++ ++remote_exec host "kill -9 $pid" +--- a/gdb/testsuite/gdb.base/break-interp.exp ++++ b/gdb/testsuite/gdb.base/break-interp.exp +@@ -248,9 +248,8 @@ proc reach {func command displacement} { + } + if {$displacement == $case} { + pass $test_displacement +- # Permit multiple such messages. + set displacement "FOUND-$displacement" +- } elseif {$displacement != "FOUND-$case"} { ++ } else { + fail $test_displacement + } + exp_continue +@@ -304,9 +303,8 @@ proc test_core {file displacement} { + } + if {$displacement == $case} { + pass $test_displacement +- # Permit multiple such messages. + set displacement "FOUND-$displacement" +- } elseif {$displacement != "FOUND-$case"} { ++ } else { + fail $test_displacement + } + exp_continue +@@ -362,9 +360,8 @@ proc test_attach_gdb {file pid displacement prefix} { + } + if {$displacement == $case} { + pass $test_displacement +- # Permit multiple such messages. + set displacement "FOUND-$displacement" +- } elseif {$displacement != "FOUND-$case"} { ++ } else { + fail $test_displacement + } + exp_continue +@@ -451,9 +448,7 @@ + gdb_test "bt" "#0 +\[^\r\n\]*\\mdl_main\\M.*" "dl bt" + + if $ifmain { +- # Displacement message will be printed the second time on initializing +- # the linker from svr4_special_symbol_handling. +- reach "main" continue $displacement ++ reach "main" continue "NONE" + + reach "libfunc" continue "NONE" + +@@ -528,9 +517,8 @@ proc test_ld {file ifmain trynosym displacement} { + } + if {$displacement == $case} { + pass $test_displacement +- # Permit multiple such messages. + set displacement "FOUND-$displacement" +- } elseif {$displacement != "FOUND-$case"} { ++ } else { + fail $test_displacement + } + exp_continue + diff --git a/gdb-rhel5-gcc44.patch b/gdb-rhel5-gcc44.patch index 15d34df..d761538 100644 --- a/gdb-rhel5-gcc44.patch +++ b/gdb-rhel5-gcc44.patch @@ -69,7 +69,7 @@ Index: gdb-7.0.50.20100115/gdb/testsuite/gdb.base/break-interp.exp } @@ -480,9 +500,33 @@ foreach ldprelink {NO YES} { - if {$binpie == "YES"} { + if {$binpie != "NO"} { lappend opts {additional_flags=-fPIE -pie} } - if {[build_executable ${test}.exp [file tail $exec] $srcfile $opts] == -1} { diff --git a/gdb-solib-memory-error-nonfatal.patch b/gdb-solib-memory-error-nonfatal.patch new file mode 100644 index 0000000..f8d73d8 --- /dev/null +++ b/gdb-solib-memory-error-nonfatal.patch @@ -0,0 +1,41 @@ +[RFC/ia64] memory error when reading wrong core file +http://sourceware.org/ml/gdb-patches/2010-01/msg00645.html +http://sourceware.org/ml/gdb-patches/2010-02/msg00001.html +http://sourceware.org/ml/gdb-patches/2010-03/msg00298.html +http://sourceware.org/ml/gdb-cvs/2010-03/msg00065.html +c961a8da422283662e09ee498c0598d48fc9d70f + +--- src/gdb/solib-svr4.c 2010/02/24 00:29:02 1.125 ++++ src/gdb/solib-svr4.c 2010/03/08 07:45:49 1.126 +@@ -868,9 +868,16 @@ + { + struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); + struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; ++ CORE_ADDR addr = 0; ++ volatile struct gdb_exception ex; + +- return read_memory_typed_address (info->debug_base + lmo->r_map_offset, +- ptr_type); ++ TRY_CATCH (ex, RETURN_MASK_ERROR) ++ { ++ addr = read_memory_typed_address (info->debug_base + lmo->r_map_offset, ++ ptr_type); ++ } ++ exception_print (gdb_stderr, ex); ++ return addr; + } + + /* Find r_brk from the inferior's debug base. */ +### src/gdb/ChangeLog 2010/03/08 01:49:30 1.11441 +### src/gdb/ChangeLog 2010/03/08 07:45:49 1.11442 +## -1,3 +1,10 @@ ++2010-03-08 Joel Brobecker ++ ++ Memory error when reading wrong core file. ++ * solib-svr4.c (solib_svr4_r_map): catch and print all exception ++ errors while reading the inferior memory, and return zero if ++ an exception was raised. ++ + 2010-03-07 Michael Snyder + + * record.c (record_restore): Rename tmpu8 to rectype. diff --git a/gdb.spec b/gdb.spec index d6dbf09..4abeb84 100644 --- a/gdb.spec +++ b/gdb.spec @@ -36,7 +36,7 @@ Version: 7.1 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 1%{?_with_upstream:.upstream}%{dist} +Release: 2%{?_with_upstream:.upstream}%{dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and GFDL and BSD and Public Domain Group: Development/Debuggers @@ -119,7 +119,6 @@ Patch118: gdb-6.3-gstack-20050411.patch # VSYSCALL and PIE Patch122: gdb-6.3-test-pie-20050107.patch -Patch124: gdb-archer-pie-0315-breakpoint_address_match.patch Patch389: gdb-archer-pie-addons.patch Patch394: gdb-archer-pie-addons-keep-disabled.patch @@ -429,6 +428,19 @@ Patch429: gdb-bz562975-std-terminate-double-free.patch # PIE: Fix back re-reun. Patch430: gdb-pie-rerun.patch +# Do not consider memory error on reading _r_debug->r_map as fatal (BZ 576742). +Patch432: gdb-solib-memory-error-nonfatal.patch + +# testsuite: Fix unstable results of gdb.base/prelink.exp. +Patch433: gdb-6.7-testsuite-stable-results-prelink.patch + +# [patch 1/6] PIE: Attach binary even after re-prelinked underneath +# [patch 2/6] PIE: Attach binary even after ld.so re-prelinked underneath +# [patch 3/6] PIE: Fix occasional error attaching i686 binary +Patch434: gdb-pie-1of6-reprelinked-bin.patch +Patch435: gdb-pie-2of6-reprelinked-ld.patch +Patch436: gdb-pie-3of6-relocate-once.patch + BuildRequires: ncurses-devel%{?_isa} texinfo gettext flex bison expat-devel%{?_isa} Requires: readline%{?_isa} BuildRequires: readline-devel%{?_isa} @@ -567,7 +579,6 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch232 -p1 %patch349 -p1 %patch420 -p1 -%patch124 -p1 %patch1 -p1 %patch3 -p1 @@ -679,6 +690,11 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch422 -p1 %patch429 -p1 %patch430 -p1 +%patch432 -p1 +%patch433 -p1 +%patch434 -p1 +%patch435 -p1 +%patch436 -p1 %patch415 -p1 %patch393 -p1 @@ -1011,6 +1027,14 @@ fi %endif %changelog +* Mon Mar 29 2010 Jan Kratochvil - 7.1-2.fc13 +- Drop obsoleted `gdb-archer-pie-0315-breakpoint_address_match.patch'. +- Do not consider memory error on reading _r_debug->r_map as fatal (BZ 576742). + - PIE: Attach binary even after re-prelinked underneath. + - PIE: Attach binary even after ld.so re-prelinked underneath. + - PIE: Fix occasional error attaching i686 binary (BZ 576742). +- testsuite: Fix unstable results of gdb.base/prelink.exp. + * Thu Mar 25 2010 Jan Kratochvil - 7.1-1.fc13 - Update to new FSF GDB release.