From 8f22c5cbd3997141cbc953f2a3266a71f700a4ff Mon Sep 17 00:00:00 2001 From: Kevin Buettner Date: Jun 14 2021 21:51:25 +0000 Subject: Backport "Exclude debuginfo files from 'outside ELF segments' warning". (Keith Seitz, RH BZ 1898252) Backport "Fix crash when expanding partial symtab..." (Tom Tromey. gdb/27743) Backport "[gdb/server] Don't overwrite fs/gs_base with -m32" (Tom de Vries) --- diff --git a/_gdb.spec.Patch.include b/_gdb.spec.Patch.include index 5a3e4e4..9f233e0 100644 --- a/_gdb.spec.Patch.include +++ b/_gdb.spec.Patch.include @@ -372,3 +372,15 @@ Patch089: gdb-rhbz1964167-fortran-array-slices-at-prompt.patch # problem in gdb/f-lang.c. Patch090: gdb-rhbz1964167-fortran-fix-type-format-mismatch-in-f-lang.c.patch +# Backport of "Exclude debuginfo files from 'outside of ELF segments' +# warning" (Keith Seitz) +Patch091: gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch + +# Backport "Fix crash when expanding partial symtabs with DW_TAG_imported_unit" +# (Tom Tromey, gdb/27743) +Patch092: gdb-gdb27743-psymtab-imported-unit.patch + +# Backport "[gdb/server] Don't overwrite fs/gs_base with -m32" +# (Tom de Vries) +Patch093: gdb-dont-overwrite-fsgsbase-m32.patch + diff --git a/_gdb.spec.patch.include b/_gdb.spec.patch.include index 3f40bb5..32f5b04 100644 --- a/_gdb.spec.patch.include +++ b/_gdb.spec.patch.include @@ -88,3 +88,6 @@ %patch088 -p1 %patch089 -p1 %patch090 -p1 +%patch091 -p1 +%patch092 -p1 +%patch093 -p1 diff --git a/_patch_order b/_patch_order index 7b81df5..562074d 100644 --- a/_patch_order +++ b/_patch_order @@ -88,3 +88,6 @@ gdb-rhbz1964167-fortran-range_type-to-range_flag.patch gdb-rhbz1964167-fortran-array-strides-in-expressions.patch gdb-rhbz1964167-fortran-array-slices-at-prompt.patch gdb-rhbz1964167-fortran-fix-type-format-mismatch-in-f-lang.c.patch +gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch +gdb-gdb27743-psymtab-imported-unit.patch +gdb-dont-overwrite-fsgsbase-m32.patch diff --git a/gdb-dont-overwrite-fsgsbase-m32.patch b/gdb-dont-overwrite-fsgsbase-m32.patch new file mode 100644 index 0000000..ee9ad49 --- /dev/null +++ b/gdb-dont-overwrite-fsgsbase-m32.patch @@ -0,0 +1,139 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 1 Jun 2021 10:14:31 -0700 +Subject: gdb-dont-overwrite-fsgsbase-m32.patch + +;; Backport "[gdb/server] Don't overwrite fs/gs_base with -m32" +;; (Tom de Vries) + +Consider a minimal test-case test.c: +... +int main (void) { return 0; } +... +compiled with -m32: +... +$ gcc test.c -m32 +... + +When running the exec using gdbserver on openSUSE Factory (currently running a +linux kernel version 5.10.5): +... +$ gdbserver localhost:12345 a.out +... +to which we connect in a gdb session, we run into a segfault in the inferior: +... +$ gdb -batch -q -ex "target remote localhost:12345" -ex continue +Program received signal SIGSEGV, Segmentation fault. +0xf7dd8bd2 in init_cacheinfo () at ../sysdeps/x86/cacheinfo.c:761 +... + +The segfault is caused by gdbserver overwriting $gs_base with 0 using +PTRACE_SETREGS. After it is overwritten, the next use of $gs in the inferior +will trigger the segfault. + +Before linux kernel version 5.9, the value used by PTRACE_SETREGS for $gs_base +was ignored, but starting version 5.9, the linux kernel has support for +intel architecture extension FSGSBASE, which allows users to modify $gs_base, +and consequently PTRACE_SETREGS can no longer ignore the $gs_base value. + +The overwrite of $gs_base with 0 is done by a memset in x86_fill_gregset, +which was added in commit 9e0aa64f551 "Fix gdbserver qGetTLSAddr for +x86_64 -m32". The memset intends to zero-extend 32-bit registers that are +tracked in the regcache to 64-bit when writing them into the PTRACE_SETREGS +data argument. But in addition, it overwrites other registers that are +not tracked in the regcache, such as $gs_base. + +Fix the segfault by redoing the fix from commit 9e0aa64f551 in minimal form. + +Tested on x86_64-linux: +- openSUSE Leap 15.2 (using kernel version 5.3.18): + - native + - gdbserver -m32 + - -m32 +- openSUSE Factory (using kernel version 5.10.5): + - native + - m32 + +gdbserver/ChangeLog: + +2021-01-20 Tom de Vries + + * linux-x86-low.cc (collect_register_i386): New function. + (x86_fill_gregset): Remove memset. Use collect_register_i386. + +diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc +--- a/gdbserver/linux-x86-low.cc ++++ b/gdbserver/linux-x86-low.cc +@@ -397,6 +397,35 @@ x86_target::low_cannot_fetch_register (int regno) + return regno >= I386_NUM_REGS; + } + ++static void ++collect_register_i386 (struct regcache *regcache, int regno, void *buf) ++{ ++ collect_register (regcache, regno, buf); ++ ++#ifdef __x86_64__ ++ /* In case of x86_64 -m32, collect_register only writes 4 bytes, but the ++ space reserved in buf for the register is 8 bytes. Make sure the entire ++ reserved space is initialized. */ ++ ++ gdb_assert (register_size (regcache->tdesc, regno) == 4); ++ ++ if (regno == RAX) ++ { ++ /* Sign extend EAX value to avoid potential syscall restart ++ problems. ++ ++ See amd64_linux_collect_native_gregset() in ++ gdb/amd64-linux-nat.c for a detailed explanation. */ ++ *(int64_t *) buf = *(int32_t *) buf; ++ } ++ else ++ { ++ /* Zero-extend. */ ++ *(uint64_t *) buf = *(uint32_t *) buf; ++ } ++#endif ++} ++ + static void + x86_fill_gregset (struct regcache *regcache, void *buf) + { +@@ -411,32 +440,14 @@ x86_fill_gregset (struct regcache *regcache, void *buf) + + return; + } +- +- /* 32-bit inferior registers need to be zero-extended. +- Callers would read uninitialized memory otherwise. */ +- memset (buf, 0x00, X86_64_USER_REGS * 8); + #endif + + for (i = 0; i < I386_NUM_REGS; i++) +- collect_register (regcache, i, ((char *) buf) + i386_regmap[i]); +- +- collect_register_by_name (regcache, "orig_eax", +- ((char *) buf) + ORIG_EAX * REGSIZE); ++ collect_register_i386 (regcache, i, ((char *) buf) + i386_regmap[i]); + +-#ifdef __x86_64__ +- /* Sign extend EAX value to avoid potential syscall restart +- problems. +- +- See amd64_linux_collect_native_gregset() in gdb/amd64-linux-nat.c +- for a detailed explanation. */ +- if (register_size (regcache->tdesc, 0) == 4) +- { +- void *ptr = ((gdb_byte *) buf +- + i386_regmap[find_regno (regcache->tdesc, "eax")]); +- +- *(int64_t *) ptr = *(int32_t *) ptr; +- } +-#endif ++ /* Handle ORIG_EAX, which is not in i386_regmap. */ ++ collect_register_i386 (regcache, find_regno (regcache->tdesc, "orig_eax"), ++ ((char *) buf) + ORIG_EAX * REGSIZE); + } + + static void diff --git a/gdb-gdb27743-psymtab-imported-unit.patch b/gdb-gdb27743-psymtab-imported-unit.patch new file mode 100644 index 0000000..c129b6d --- /dev/null +++ b/gdb-gdb27743-psymtab-imported-unit.patch @@ -0,0 +1,281 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Tom Tromey +Date: Fri, 23 Apr 2021 11:28:48 -0600 +Subject: gdb-gdb27743-psymtab-imported-unit.patch + +;; Backport "Fix crash when expanding partial symtabs with DW_TAG_imported_unit" +;; (Tom Tromey, gdb/27743) + + From e7d77ce0c408e7019f9885b8be64c9cdb46dd312 Mon Sep 17 00:00:00 2001 + Subject: [PATCH] Fix crash when expanding partial symtabs with + DW_TAG_imported_unit + +PR gdb/27743 points out a gdb crash when expanding partial symtabs, +where one of the compilation units uses DW_TAG_imported_unit. + +The bug is that partial_map_expand_apply expects only to be called for +the outermost psymtab. However, filename searching doesn't (and +probably shouldn't) guarantee this. The fix is to walk upward to find +the outermost CU. + +A new test case is included. It is mostly copied from other test +cases, which really sped up the effort. + +This bug does not occur on trunk. There, +psym_map_symtabs_matching_filename is gone, replaced by +psymbol_functions::expand_symtabs_matching. When this find a match, +it calls psymtab_to_symtab, which does this same upward walk. + +Tested on x86-64 Fedora 32. + +I propose checking in this patch on the gdb-10 branch, and just the +new test case on trunk. + +gdb/ChangeLog +2021-04-23 Tom Tromey + + PR gdb/27743: + * psymtab.c (partial_map_expand_apply): Expand outermost psymtab. + +gdb/testsuite/ChangeLog +2021-04-23 Tom Tromey + + PR gdb/27743: + * gdb.dwarf2/imported-unit-bp.exp: New file. + * gdb.dwarf2/imported-unit-bp-main.c: New file. + * gdb.dwarf2/imported-unit-bp-alt.c: New file. + +diff --git a/gdb/psymtab.c b/gdb/psymtab.c +--- a/gdb/psymtab.c ++++ b/gdb/psymtab.c +@@ -127,9 +127,10 @@ partial_map_expand_apply (struct objfile *objfile, + { + struct compunit_symtab *last_made = objfile->compunit_symtabs; + +- /* Shared psymtabs should never be seen here. Instead they should +- be handled properly by the caller. */ +- gdb_assert (pst->user == NULL); ++ /* We may see a shared psymtab here, but we want to expand the ++ outermost symtab. */ ++ while (pst->user != nullptr) ++ pst = pst->user; + + /* Don't visit already-expanded psymtabs. */ + if (pst->readin_p (objfile)) +diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-bp-alt.c b/gdb/testsuite/gdb.dwarf2/imported-unit-bp-alt.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/imported-unit-bp-alt.c +@@ -0,0 +1,50 @@ ++/* Copyright 2020-2021 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 . */ ++ ++/* Used to insert labels with which we can build a fake line table. */ ++#define LL(N) asm ("line_label_" #N ": .globl line_label_" #N) ++ ++volatile int var; ++volatile int bar; ++ ++/* Generate some code to take up some space. */ ++#define FILLER do { \ ++ var = 99; \ ++} while (0) ++ ++int ++func (void) ++{ /* func prologue */ ++ asm ("func_label: .globl func_label"); ++ LL (1); // F1, Ln 16 ++ FILLER; ++ LL (2); // F1, Ln 17 ++ FILLER; ++ LL (3); // F2, Ln 21 ++ FILLER; ++ LL (4); // F2, Ln 22 // F1, Ln 18, !S ++ FILLER; ++ LL (5); // F1, Ln 19 !S ++ FILLER; ++ LL (6); // F1, Ln 20 ++ FILLER; ++ LL (7); ++ FILLER; ++ return 0; /* func end */ ++} ++ ++#ifdef WITHMAIN ++int main () { return 0; } ++#endif +diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-bp-main.c b/gdb/testsuite/gdb.dwarf2/imported-unit-bp-main.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/imported-unit-bp-main.c +@@ -0,0 +1,24 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2004-2021 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 . */ ++ ++extern int func (void); ++ ++int ++main() ++{ ++ return func (); ++} +diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp b/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp +@@ -0,0 +1,128 @@ ++# Copyright 2020-2021 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 . ++ ++# Test that "break /absolute/file:line" works ok with imported CUs. ++ ++load_lib dwarf.exp ++ ++# This test can only be run on targets which support DWARF-2 and use gas. ++if {![dwarf2_support]} { ++ return 0 ++} ++ ++# The .c files use __attribute__. ++if [get_compiler_info] { ++ return -1 ++} ++if !$gcc_compiled { ++ return 0 ++} ++ ++standard_testfile imported-unit-bp-alt.c .S imported-unit-bp-main.c ++ ++set build_options {nodebug optimize=-O1} ++ ++set asm_file [standard_output_file $srcfile2] ++Dwarf::assemble $asm_file { ++ global srcdir subdir srcfile srcfile ++ global build_options ++ declare_labels lines_label callee_subprog_label cu_label ++ ++ get_func_info func "$build_options additional_flags=-DWITHMAIN" ++ ++ cu {} { ++ compile_unit { ++ {language @DW_LANG_C} ++ {name ""} ++ } { ++ imported_unit { ++ {import %$cu_label} ++ } ++ } ++ } ++ ++ cu {} { ++ cu_label: compile_unit { ++ {producer "gcc"} ++ {language @DW_LANG_C} ++ {name ${srcfile}} ++ {comp_dir "/tmp"} ++ {low_pc 0 addr} ++ {stmt_list ${lines_label} DW_FORM_sec_offset} ++ } { ++ callee_subprog_label: subprogram { ++ {external 1 flag} ++ {name callee} ++ {inline 3 data1} ++ } ++ subprogram { ++ {external 1 flag} ++ {name func} ++ {low_pc $func_start addr} ++ {high_pc "$func_start + $func_len" addr} ++ } { ++ } ++ } ++ } ++ ++ lines {version 2 default_is_stmt 1} lines_label { ++ include_dir "/tmp" ++ file_name "$srcfile" 1 ++ ++ program { ++ {DW_LNE_set_address line_label_1} ++ {DW_LNS_advance_line 15} ++ {DW_LNS_copy} ++ ++ {DW_LNE_set_address line_label_2} ++ {DW_LNS_advance_line 1} ++ {DW_LNS_copy} ++ ++ {DW_LNE_set_address line_label_3} ++ {DW_LNS_advance_line 4} ++ {DW_LNS_copy} ++ ++ {DW_LNE_set_address line_label_4} ++ {DW_LNS_advance_line 1} ++ {DW_LNS_copy} ++ ++ {DW_LNS_advance_line -4} ++ {DW_LNS_negate_stmt} ++ {DW_LNS_copy} ++ ++ {DW_LNE_set_address line_label_5} ++ {DW_LNS_advance_line 1} ++ {DW_LNS_copy} ++ ++ {DW_LNE_set_address line_label_6} ++ {DW_LNS_advance_line 1} ++ {DW_LNS_negate_stmt} ++ {DW_LNS_copy} ++ ++ {DW_LNE_set_address line_label_7} ++ {DW_LNE_end_sequence} ++ } ++ } ++} ++ ++if { [prepare_for_testing "failed to prepare" ${testfile} \ ++ [list $srcfile $asm_file $srcfile3] $build_options] } { ++ return -1 ++} ++ ++gdb_reinitialize_dir /tmp ++ ++# Using an absolute path is important to see the bug. ++gdb_test "break /tmp/${srcfile}:19" "Breakpoint .* file $srcfile, line .*" diff --git a/gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch b/gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch new file mode 100644 index 0000000..1419455 --- /dev/null +++ b/gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch @@ -0,0 +1,67 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 16 Nov 2020 12:42:09 -0500 +Subject: gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch + +;; Backport of "Exclude debuginfo files from 'outside of ELF segments' +;; warning" (Keith Seitz) + + Exclude debuginfo files from "outside of ELF segments" warning + + When GDB loads an ELF file, it will warn when a section is not located + in an ELF segment: + + $ ./gdb -q -iex "set build-id-verbose 0" --ex "b systemctl_main" -ex "r" -batch --args systemctl kexec + Breakpoint 1 at 0xc24d: file ../src/systemctl/systemctl.c, line 8752. + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libgcc_s.so.1 + [Thread debugging using libthread_db enabled] + Using host libthread_db library "/lib64/libthread_db.so.1". + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libcap.so.2 + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libacl.so.1 + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libcryptsetup.so.12 + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libgcrypt.so.20 + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libip4tc.so.2 + [snip] + This has feature has also been reported by various users, most notably + the Fedora-EOL'd bug 1553086. + + Mark Wielaard explains the issue quite nicely in + + https://sourceware.org/bugzilla/show_bug.cgi?id=24717#c2 + + The short of it is, the ELF program headers for debuginfo files are + not suited to this particular use case. Consequently, the warning + generated above really is useless and should be ignored. + + This patch follows the same heuristic that BFD itself uses. + + gdb/ChangeLog + 2020-11-13 Keith Seitz + + https://bugzilla.redhat.com/show_bug.cgi?id=1553086 + * elfread.c (elf_symfile_segments): Omit "Loadable section ... + outside of ELF segments" warning for debugin + +diff --git a/gdb/elfread.c b/gdb/elfread.c +--- a/gdb/elfread.c ++++ b/gdb/elfread.c +@@ -147,7 +147,12 @@ elf_symfile_segments (bfd *abfd) + RealView) use SHT_NOBITS for uninitialized data. Since it is + uninitialized, it doesn't need a program header. Such + binaries are not relocatable. */ +- if (bfd_section_size (sect) > 0 && j == num_segments ++ ++ /* Exclude debuginfo files from this warning, too, since those ++ are often not strictly compliant with the standard. See, e.g., ++ ld/24717 for more discussion. */ ++ if (!is_debuginfo_file (abfd) ++ && bfd_section_size (sect) > 0 && j == num_segments + && (bfd_section_flags (sect) & SEC_LOAD) != 0) + warning (_("Loadable section \"%s\" outside of ELF segments"), + bfd_section_name (sect)); diff --git a/gdb.spec b/gdb.spec index a66d989..c369a35 100644 --- a/gdb.spec +++ b/gdb.spec @@ -37,7 +37,7 @@ Version: 10.2 # 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: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL # Do not provide URL for snapshots as the file lasts there only for 2 days. @@ -1154,6 +1154,14 @@ fi %endif %changelog +* Fri Jun 11 2021 Keith Seitz - 10.2-3 +- Backport "Exclude debuginfo files from 'outside ELF segments' warning". + (Keith Seitz, RH BZ 1898252) +- Backport "Fix crash when expanding partial symtab..." + (Tom Tromey. gdb/27743) +- Backport "[gdb/server] Don't overwrite fs/gs_base with -m32" +- (Tom de Vries) + * Sun Jun 06 2021 Python Maint - Rebuilt for Python 3.10