Blame SOURCES/gdb-x86_64-i386-syscall-restart.patch

6240d7
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
6240d7
From: Fedora GDB patches <invalid@email.com>
6240d7
Date: Fri, 27 Oct 2017 21:07:50 +0200
6240d7
Subject: gdb-x86_64-i386-syscall-restart.patch
6240d7
6240d7
;; Fix syscall restarts for amd64->i386 biarch.
6240d7
;;=push+jan
6240d7
6240d7
http://sourceware.org/ml/gdb-patches/2009-11/msg00592.html
6240d7
Subject: [patch] Fix syscall restarts for amd64->i386 biarch
6240d7
6240d7
Hi,
6240d7
6240d7
tested only on recent Linux kernels, it should apply also on vanilla ones.
6240d7
There were various changes of the kernels behavior in the past.
6240d7
6240d7
FSF GDB HEAD state:
6240d7
kernel debugger inferior state
6240d7
x86_64 x86_64   x86_64   PASS
6240d7
x86_64 x86_64   i386     FAIL without this patch, PASS with this patch
6240d7
x86_64 i386     i386     PASS on recent kernels
6240d7
                         (FAIL: kernel-2.6.31.5-127.fc12.x86_64 - Fedora 12)
6240d7
                         (PASS: kernel-2.6.32-0.55.rc8.git1.fc13.x86_64)
6240d7
i386   i386     i386     PASS
6240d7
6240d7
Currently gdb.base/interrupt.exp fails on amd64 host running under
6240d7
--target_board unix/-m32 with:
6240d7
	continue
6240d7
	Continuing.
6240d7
	Unknown error 512
6240d7
6240d7
<linux/errno.h>:
6240d7
/*
6240d7
 * These should never be seen by user programs.  To return one of ERESTART*
6240d7
 * codes, signal_pending() MUST be set.  Note that ptrace can observe these
6240d7
 * at syscall exit tracing, but they will never be left for the debugged user
6240d7
 * process to see.
6240d7
 */
6240d7
6240d7
"Unknown error 512" printed above is printed by the inferior itself, not by GDB.
6240d7
6240d7
It is because GDB reads it as 0xfffffffffffffe00 but writes it back as
6240d7
0xfffffe00.
6240d7
+      /* Sign-extend %eax as during return from a syscall it is being checked
6240d7
+	 for -ERESTART* values -512 being above 0xfffffffffffffe00; tested by
6240d7
+	 interrupt.exp.  */
6240d7
6240d7
Quote of Roland McGrath from IRC:
6240d7
6240d7
roland: in the user_regset model, there are 64-bit user_regset flavors and
6240d7
32-bit user_regset flavors, so at the kabi level the (kernel) caller can say
6240d7
what it means: calls on the 32-bit user_regset flavor will behave as if on
6240d7
a 32-bit kernel/userland.  in ptrace, there is no way for x86_64 ptrace calls
6240d7
to say "i think of the inferior as being 32 bits, so act accordingly" (tho ppc
6240d7
and/or sparc have ptr
6240d7
roland: ace requests that do that iirc)
6240d7
roland: ergo 64-bit ptrace callers must either save/restore full 64-bits so
6240d7
the kernel's sign-extension choices are preserved, or else grok magic ways to
6240d7
expand stored 32-bit register contents to 64-bit values to stuff via 64-bit
6240d7
ptrace
6240d7
[...]
6240d7
roland: there is a "32-bit-flavored task", but it's not really true that it
6240d7
has 32-bit registers.  there is no 32-bit-only userland condition.  any task
6240d7
can always ljmp to the 64-bit code segment and run 64-bit insns including
6240d7
a 64-bit syscall
6240d7
roland: so a 64-bit debugger should see and be able to fiddle the full
6240d7
registers.  it can even change cs via ptrace to force the inferior into
6240d7
running 32 or 64 bit code.
6240d7
6240d7
Saving whole 64bits for i386 targets on x86_64 hosts does not much match the
6240d7
GDB architecture as `struct type' for these registers still should be 32bit
6240d7
etc.   Therefore provided just this exception.
6240d7
6240d7
The problem is reproducible only if one does an inferior call during the
6240d7
interruption to do full inferior save/restore from GDB regcache.
6240d7
6240d7
Regression tested on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu.
6240d7
6240d7
Thanks,
6240d7
Jan
6240d7
6240d7
gdb/
6240d7
2009-11-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
6240d7
6240d7
	* amd64-nat.c (amd64_collect_native_gregset): Do not pre-clear %eax.
6240d7
	Sign extend it afterwards.
6240d7
6240d7
diff --git a/gdb/amd64-nat.c b/gdb/amd64-nat.c
6240d7
--- a/gdb/amd64-nat.c
6240d7
+++ b/gdb/amd64-nat.c
6240d7
@@ -135,9 +135,9 @@ amd64_collect_native_gregset (const struct regcache *regcache,
6240d7
     {
6240d7
       num_regs = amd64_native_gregset32_num_regs;
6240d7
 
6240d7
-      /* Make sure %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and
6240d7
+      /* Make sure %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and
6240d7
          %eip get zero-extended to 64 bits.  */
6240d7
-      for (i = 0; i <= I386_EIP_REGNUM; i++)
6240d7
+      for (i = I386_ECX_REGNUM; i <= I386_EIP_REGNUM; i++)
6240d7
 	{
6240d7
 	  if (regnum == -1 || regnum == i)
6240d7
 	    memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8);
6240d7
@@ -163,4 +163,20 @@ amd64_collect_native_gregset (const struct regcache *regcache,
6240d7
 	    regcache->raw_collect (i, regs + offset);
6240d7
 	}
6240d7
     }
6240d7
+
6240d7
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
6240d7
+    {
6240d7
+      /* Sign-extend %eax as during return from a syscall it is being checked
6240d7
+	 for -ERESTART* values -512 being above 0xfffffffffffffe00; tested by
6240d7
+	 interrupt.exp.  */
6240d7
+
6240d7
+      int k = I386_EAX_REGNUM;
6240d7
+
6240d7
+      if (regnum == -1 || regnum == i)
6240d7
+	{
6240d7
+	  void *ptr = regs + amd64_native_gregset_reg_offset (gdbarch, k);
6240d7
+
6240d7
+	  *(int64_t *) ptr = *(int32_t *) ptr;
6240d7
+	}
6240d7
+    }
6240d7
 }