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

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