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

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