[arch-commits] Commit in gdb/repos (3 files)
Anatol Pomozov
anatolik at archlinux.org
Wed May 19 21:34:48 UTC 2021
Date: Wednesday, May 19, 2021 @ 21:34:47
Author: anatolik
Revision: 415776
archrelease: copy trunk to testing-x86_64
Added:
gdb/repos/testing-x86_64/
gdb/repos/testing-x86_64/PKGBUILD
(from rev 415775, gdb/trunk/PKGBUILD)
gdb/repos/testing-x86_64/gdb_dont_overwrite_fs-gs_base_with_-m32.patch
(from rev 415775, gdb/trunk/gdb_dont_overwrite_fs-gs_base_with_-m32.patch)
-----------------------------------------------+
PKGBUILD | 78 +++++++++++
gdb_dont_overwrite_fs-gs_base_with_-m32.patch | 163 ++++++++++++++++++++++++
2 files changed, 241 insertions(+)
Copied: gdb/repos/testing-x86_64/PKGBUILD (from rev 415775, gdb/trunk/PKGBUILD)
===================================================================
--- testing-x86_64/PKGBUILD (rev 0)
+++ testing-x86_64/PKGBUILD 2021-05-19 21:34:47 UTC (rev 415776)
@@ -0,0 +1,78 @@
+# Maintainer: Levente Polyak <anthraxx[at]archlinux[dot]org>
+# Maintainer: Anatol Pomozov <anatol.pomozov at gmail.com>
+# Contributor: Allan McRae <allan at archlinux.org>
+# Contributor: Jan de Groot <jgc at archlinux.org>
+
+pkgbase=gdb
+# gdb-common is a package that contains files common for all cross compiled versions
+# of gdb (for arm/avr/...)
+pkgname=(gdb gdb-common)
+pkgver=10.2
+pkgrel=2
+pkgdesc='The GNU Debugger'
+arch=(x86_64)
+url='https://www.gnu.org/software/gdb/'
+license=(GPL3)
+makedepends=(glibc gcc-libs texinfo python guile ncurses expat xz mpfr source-highlight
+ readline)
+source=(https://ftp.gnu.org/gnu/gdb/${pkgname}-${pkgver}.tar.xz{,.sig}
+ gdb_dont_overwrite_fs-gs_base_with_-m32.patch)
+
+sha1sums=('1056e2743a825ecce46ec9eec37f0b357831012b'
+ 'SKIP'
+ '7a78c03b563797e5c0ee85a0618a47e4c6677dc4')
+b2sums=('c5d31d80d2b454767d6f844e8471b012ad437c3872391b618fd7b14c5cf251b78e55d28c12e81382fd600f67e2f618ff5dbe3a7b737a5d5161ceb3542afbb90b'
+ 'SKIP'
+ '4337167930ecc045b9d19125b975bc98b4b16e05954c45bfa41f0e21471ed7ab5c5a8e9a8479056d7019cd127beed936c664e37d38ee3e99dbe861f8c1a67540')
+validpgpkeys=('F40ADB902B24264AA42E50BF92EDB04BFF325CF3') # Joel Brobecker
+
+prepare() {
+ cd gdb-$pkgver
+
+ patch -p1 < ../gdb_dont_overwrite_fs-gs_base_with_-m32.patch # FS#70879
+
+ # hack! - libiberty configure tests for header files using "$CPP $CPPFLAGS"
+ sed -i "/ac_cpp=/s/\$CPPFLAGS/\$CPPFLAGS -O2/" libiberty/configure
+}
+
+build() {
+ cd gdb-$pkgver
+
+ mkdir -p build && cd build
+ ../configure \
+ --prefix=/usr \
+ --disable-nls \
+ --enable-source-highlight \
+ --enable-tui \
+ --with-system-readline \
+ --with-python=/usr/bin/python \
+ --with-guile=guile-2.2 \
+ --with-system-gdbinit=/etc/gdb/gdbinit
+ make
+}
+
+package_gdb-common() {
+ depends=(python guile)
+
+ cd gdb-$pkgver/build
+ make -C gdb/data-directory DESTDIR="$pkgdir" install
+}
+
+package_gdb() {
+ depends=(glibc ncurses libncursesw.so gcc-libs expat xz mpfr source-highlight gdb-common=$pkgver
+ readline libreadline.so guile python libelf)
+ backup=(etc/gdb/gdbinit)
+
+ cd gdb-$pkgver/build
+ make -C gdb DESTDIR="$pkgdir" install
+ make -C gdbserver DESTDIR="$pkgdir" install
+
+ # install "custom" system gdbinit
+ install -dm 755 "$pkgdir/etc/gdb"
+ touch "$pkgdir/etc/gdb/gdbinit"
+
+ # comes from gdb-common
+ rm -r "$pkgdir/usr/share/gdb/"
+}
+
+# vim: ts=2 sw=2 et:
Copied: gdb/repos/testing-x86_64/gdb_dont_overwrite_fs-gs_base_with_-m32.patch (from rev 415775, gdb/trunk/gdb_dont_overwrite_fs-gs_base_with_-m32.patch)
===================================================================
--- testing-x86_64/gdb_dont_overwrite_fs-gs_base_with_-m32.patch (rev 0)
+++ testing-x86_64/gdb_dont_overwrite_fs-gs_base_with_-m32.patch 2021-05-19 21:34:47 UTC (rev 415776)
@@ -0,0 +1,163 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tom de Vries <tdevries at suse.de>
+Date: Wed, 20 Jan 2021 16:29:30 +0100
+Subject: [PATCH] [gdb/server] Don't overwrite fs/gs_base with -m32
+
+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 <tdevries at suse.de>
+
+ * linux-x86-low.cc (collect_register_i386): New function.
+ (x86_fill_gregset): Remove memset. Use collect_register_i386.
+
+(cherry picked from commit 037e8112b9794a633248e5aa5943f3be273e0a20)
+
+Conflicts:
+ gdbserver/ChangeLog
+ gdbserver/linux-x86-low.cc
+---
+ gdbserver/ChangeLog | 5 ++++
+ gdbserver/linux-x86-low.cc | 55 +++++++++++++++++++++++---------------
+ 2 files changed, 38 insertions(+), 22 deletions(-)
+
+diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog
+index 28d0f9bfccb..b87174ce4e3 100644
+--- a/gdbserver/ChangeLog
++++ b/gdbserver/ChangeLog
+@@ -1,3 +1,8 @@
++2021-01-20 Tom de Vries <tdevries at suse.de>
++
++ * linux-x86-low.cc (collect_register_i386): New function.
++ (x86_fill_gregset): Remove memset. Use collect_register_i386.
++
+ 2021-01-01 Joel Brobecker <brobecker at adacore.com>
+
+ * server.cc (gdbserver_version): Update copyright year.
+diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc
+index 79284473f14..ea95f3ea2ae 100644
+--- 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
+--
+2.29.2
+
More information about the arch-commits
mailing list