From f13fc54bceae2b45336c7d70d6fbce36fb7a4def Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 21 Jul 2010 21:50:13 +0000 Subject: [PATCH] - Fix prelinked executables with sepdebug and copy relocations (BZ 614659). --- gdb-bz614659-prelink-dynbss.patch | 217 ++++++++++++++++++++++++++++++ gdb.spec | 9 +- 2 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 gdb-bz614659-prelink-dynbss.patch diff --git a/gdb-bz614659-prelink-dynbss.patch b/gdb-bz614659-prelink-dynbss.patch new file mode 100644 index 0000000..75514ec --- /dev/null +++ b/gdb-bz614659-prelink-dynbss.patch @@ -0,0 +1,217 @@ +http://sourceware.org/ml/gdb-patches/2010-07/msg00237.html +Subject: [patch] Fix regression on prelinked executables + +Hi, + +there is a regression since gdb-7.0 for a combination of: + * prelinked + * main executable + * using separate debug info + * using copy relocations + +It is since a patch for both PIE and (AFAIK) OSX support: + [commit] syms_from_objfile: Relativize also MAINLINE + http://sourceware.org/ml/gdb-patches/2010-01/msg00080.html + +which started to use problematic addr_info_make_relative even for main +executables. prelink<->gdb discussion at: + https://bugzilla.redhat.com/show_bug.cgi?id=614659 + +Currently in the unfortunately executables GDB has invalid displcement for +symbols in .bss: + int bssvar, *bssvarp = &bssvar; + (gdb) p &bssvar + $1 = (int *) 0x600b54 + (gdb) p bssvarp + $2 = (int *) 0x600b50 + + +addr_info_make_relative could just simply subtract entry point address and +provide single CORE_ADDR objfile->offset (instead of the current +section_offsets array with offsets specific for each section). Linux systems +use always single offset for the whole objfile. AFAIK these per-section +offsets are there for some embedded targets. Curiously GDB already uses at +many places + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); +instead of using offset for the appropriate section at that place and nobody +complains. + + +No regressions on {x86_64,x86_64-m32,i686}-fedora13-linux-gnu. + +Proposing for the gdb-7.2 branch. I had problems fixing up my crashing X. + + +Thanks, +Jan + + +gdb/ +2010-07-15 Jan Kratochvil + + * symfile.c (addr_section_name): New function. + (addrs_section_compar): Use it. + (addr_info_make_relative): Use it. Move variable sect_name into a more + inner block. Make ".dynbss" and ".sdynbss" checks more strict. + +gdb/testsuite/ +2010-07-15 Jan Kratochvil + + * gdb.base/prelink-lib.c (copyreloc): New initialized variable. + * gdb.base/prelink.c (copyreloc, bssvar, bssvarp): New variables. + (main): Use copyreloc. + * gdb.base/prelink.exp (split debug of executable) + (.dynbss vs. .bss address shift): New tests. + +--- a/gdb/symfile.c ++++ b/gdb/symfile.c +@@ -547,6 +547,23 @@ relative_addr_info_to_section_offsets (struct section_offsets *section_offsets, + } + } + ++/* Transform section name S for a name comparison. prelink can split section ++ `.bss' into two sections `.dynbss' and `.bss' (in this order). Similarly ++ prelink can split `.sbss' into `.sdynbss' and `.sbss'. Use virtual address ++ of the new `.dynbss' (`.sdynbss') section as the adjacent new `.bss' ++ (`.sbss') section has invalid (increased) virtual address. */ ++ ++static const char * ++addr_section_name (const char *s) ++{ ++ if (strcmp (s, ".dynbss") == 0) ++ return ".bss"; ++ if (strcmp (s, ".sdynbss") == 0) ++ return ".sbss"; ++ ++ return s; ++} ++ + /* qsort comparator for addrs_section_sort. Sort entries in ascending order by + their (name, sectindex) pair. sectindex makes the sort by name stable. */ + +@@ -557,7 +574,7 @@ addrs_section_compar (const void *ap, const void *bp) + const struct other_sections *b = *((struct other_sections **) bp); + int retval, a_idx, b_idx; + +- retval = strcmp (a->name, b->name); ++ retval = strcmp (addr_section_name (a->name), addr_section_name (b->name)); + if (retval) + return retval; + +@@ -641,14 +658,16 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) + + while (*addrs_sorted) + { +- const char *sect_name = (*addrs_sorted)->name; ++ const char *sect_name = addr_section_name ((*addrs_sorted)->name); + + while (*abfd_addrs_sorted +- && strcmp ((*abfd_addrs_sorted)->name, sect_name) < 0) ++ && strcmp (addr_section_name ((*abfd_addrs_sorted)->name), ++ sect_name) < 0) + abfd_addrs_sorted++; + + if (*abfd_addrs_sorted +- && strcmp ((*abfd_addrs_sorted)->name, sect_name) == 0) ++ && strcmp (addr_section_name ((*abfd_addrs_sorted)->name), ++ sect_name) == 0) + { + int index_in_addrs; + +@@ -676,7 +695,6 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) + + for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) + { +- const char *sect_name = addrs->other[i].name; + struct other_sections *sect = addrs_to_abfd_addrs[i]; + + if (sect) +@@ -694,6 +712,9 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) + } + else + { ++ /* addr_section_name transformation is not used for SECT_NAME. */ ++ const char *sect_name = addrs->other[i].name; ++ + /* This section does not exist in ABFD, which is normally + unexpected and we want to issue a warning. + +@@ -704,12 +725,20 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) + a warning. Shared libraries contain just the section + ".gnu.liblist" but it is not marked as loadable there. There is + no other way to identify them than by their name as the sections +- created by prelink have no special flags. */ ++ created by prelink have no special flags. ++ ++ For the sections `.bss' and `.sbss' see addr_section_name. */ + + if (!(strcmp (sect_name, ".gnu.liblist") == 0 + || strcmp (sect_name, ".gnu.conflict") == 0 +- || strcmp (sect_name, ".dynbss") == 0 +- || strcmp (sect_name, ".sdynbss") == 0)) ++ || (strcmp (sect_name, ".bss") == 0 ++ && i > 0 ++ && strcmp (addrs->other[i - 1].name, ".dynbss") == 0 ++ && addrs_to_abfd_addrs[i - 1] != NULL) ++ || (strcmp (sect_name, ".sbss") == 0 ++ && i > 0 ++ && strcmp (addrs->other[i - 1].name, ".sdynbss") == 0 ++ && addrs_to_abfd_addrs[i - 1] != NULL))) + warning (_("section %s not found in %s"), sect_name, + bfd_get_filename (abfd)); + +--- a/gdb/testsuite/gdb.base/prelink-lib.c ++++ b/gdb/testsuite/gdb.base/prelink-lib.c +@@ -16,6 +16,8 @@ + along with this program. If not, see . + */ + ++int copyreloc = 1; ++ + int + g (void (*p)(void)) + { +--- a/gdb/testsuite/gdb.base/prelink.c ++++ b/gdb/testsuite/gdb.base/prelink.c +@@ -18,6 +18,11 @@ + + #include + ++extern int copyreloc; ++ ++/* Test GDB itself finds `&bssvar' right. */ ++static int bssvar, *bssvarp = &bssvar; ++ + extern void (*h (void)) (void (*)(void)); + + int +@@ -25,5 +30,6 @@ main (void) + { + void (*f) (void (*)(void)) = h (); + printf ("%p\n", f); ++ printf ("%d\n", copyreloc); + f (0); + } +--- a/gdb/testsuite/gdb.base/prelink.exp ++++ b/gdb/testsuite/gdb.base/prelink.exp +@@ -57,6 +57,13 @@ if {$prelink_args == ""} { + return -1 + } + ++set test "split debug of executable" ++if [gdb_gnu_strip_debug $binfile] { ++ fail $test ++} else { ++ pass $test ++} ++ + if ![prelink_yes $prelink_args] { + # Maybe we don't have prelink. + return -1 +@@ -105,3 +112,5 @@ clean_restart $executable + gdb_test_no_output "set verbose on" + + gdb_test "core-file $objdir/$subdir/prelink.core" "Using PIC \\(Position Independent Code\\) prelink displacement 0x\[^0\]\[0-9a-f\]* for \[^\r\n\]*[file tail ${libfile}].*" "seen displacement message" ++ ++gdb_test "p &bssvar == bssvarp" " = 1" ".dynbss vs. .bss address shift" + diff --git a/gdb.spec b/gdb.spec index d60c8fd..89d7143 100644 --- a/gdb.spec +++ b/gdb.spec @@ -36,7 +36,7 @@ Version: 7.1.90.20100721 # 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 @@ -414,6 +414,9 @@ Patch475: gdb-bz601887-dwarf4-rh-test.patch Patch486: gdb-bz562763-pretty-print-2d-vectors.patch Patch487: gdb-bz562763-pretty-print-2d-vectors-libstdcxx.patch +# Fix prelinked executables with sepdebug and copy relocations (BZ 614659). +Patch489: gdb-bz614659-prelink-dynbss.patch + BuildRequires: ncurses-devel%{?_isa} texinfo gettext flex bison expat-devel%{?_isa} Requires: readline%{?_isa} BuildRequires: readline-devel%{?_isa} @@ -663,6 +666,7 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c # This patch should be applied to gcc-4.5+.src.rpm: #patch487 -p1 %patch415 -p1 +%patch489 -p1 %patch393 -p1 %patch335 -p1 @@ -990,6 +994,9 @@ fi %endif %changelog +* Wed Jul 21 2010 Jan Kratochvil - 7.1.90.20100721-2.fc14 +- Fix prelinked executables with sepdebug and copy relocations (BZ 614659). + * Wed Jul 21 2010 Jan Kratochvil - 7.1.90.20100721-1.fc14 - Rebase to FSF GDB 7.1.90.20100721 (which is 7.2 pre-release).