]> git.pld-linux.org Git - packages/gdb.git/blob - gdb-x86_64-i386-syscall-restart.patch
- update to gdb-7.0-7.fc12.src.rpm; but leave cactus patches as these seem newer
[packages/gdb.git] / gdb-x86_64-i386-syscall-restart.patch
1 http://sourceware.org/ml/gdb-patches/2009-11/msg00592.html
2 Subject: [patch] Fix syscall restarts for amd64->i386 biarch
3
4 Hi,
5
6 tested only on recent Linux kernels, it should apply also on vanilla ones.
7 There were various changes of the kernels behavior in the past.
8
9 FSF GDB HEAD state:
10 kernel debugger inferior state
11 x86_64 x86_64   x86_64   PASS
12 x86_64 x86_64   i386     FAIL without this patch, PASS with this patch
13 x86_64 i386     i386     PASS on recent kernels
14                          (FAIL: kernel-2.6.31.5-127.fc12.x86_64 - Fedora 12)
15                          (PASS: kernel-2.6.32-0.55.rc8.git1.fc13.x86_64)
16 i386   i386     i386     PASS
17
18
19 Currently gdb.base/interrupt.exp fails on amd64 host running under
20 --target_board unix/-m32 with:
21         continue
22         Continuing.
23         Unknown error 512
24
25 <linux/errno.h>:
26 /*
27  * These should never be seen by user programs.  To return one of ERESTART*
28  * codes, signal_pending() MUST be set.  Note that ptrace can observe these
29  * at syscall exit tracing, but they will never be left for the debugged user
30  * process to see.
31  */
32 #define ERESTARTSYS     512
33
34 "Unknown error 512" printed above is printed by the inferior itself, not by GDB.
35
36 It is because GDB reads it as 0xfffffffffffffe00 but writes it back as
37 0xfffffe00.
38 +      /* Sign-extend %eax as during return from a syscall it is being checked
39 +        for -ERESTART* values -512 being above 0xfffffffffffffe00; tested by
40 +        interrupt.exp.  */
41
42
43 Quote of Roland McGrath from IRC:
44
45 roland: in the user_regset model, there are 64-bit user_regset flavors and
46 32-bit user_regset flavors, so at the kabi level the (kernel) caller can say
47 what it means: calls on the 32-bit user_regset flavor will behave as if on
48 a 32-bit kernel/userland.  in ptrace, there is no way for x86_64 ptrace calls
49 to say "i think of the inferior as being 32 bits, so act accordingly" (tho ppc
50 and/or sparc have ptr
51 roland: ace requests that do that iirc)
52 roland: ergo 64-bit ptrace callers must either save/restore full 64-bits so
53 the kernel's sign-extension choices are preserved, or else grok magic ways to
54 expand stored 32-bit register contents to 64-bit values to stuff via 64-bit
55 ptrace
56 [...]
57 roland: there is a "32-bit-flavored task", but it's not really true that it
58 has 32-bit registers.  there is no 32-bit-only userland condition.  any task
59 can always ljmp to the 64-bit code segment and run 64-bit insns including
60 a 64-bit syscall
61 roland: so a 64-bit debugger should see and be able to fiddle the full
62 registers.  it can even change cs via ptrace to force the inferior into
63 running 32 or 64 bit code.
64
65
66 Saving whole 64bits for i386 targets on x86_64 hosts does not much match the
67 GDB architecture as `struct type' for these registers still should be 32bit
68 etc.   Therefore provided just this exception.
69
70 The problem is reproducible only if one does an inferior call during the
71 interruption to do full inferior save/restore from GDB regcache.
72
73 Regression tested on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu.
74
75
76 Thanks,
77 Jan
78
79
80 gdb/
81 2009-11-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
82
83         * amd64-nat.c (amd64_collect_native_gregset): Do not pre-clear %eax.
84         Sign extend it afterwards.
85
86 --- a/gdb/amd64-nat.c
87 +++ b/gdb/amd64-nat.c
88 @@ -131,9 +131,9 @@ amd64_collect_native_gregset (const struct regcache *regcache,
89      {
90        num_regs = amd64_native_gregset32_num_regs;
91  
92 -      /* Make sure %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and
93 +      /* Make sure %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and
94           %eip get zero-extended to 64 bits.  */
95 -      for (i = 0; i <= I386_EIP_REGNUM; i++)
96 +      for (i = I386_ECX_REGNUM; i <= I386_EIP_REGNUM; i++)
97         {
98           if (regnum == -1 || regnum == i)
99             memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8);
100 @@ -159,4 +159,20 @@ amd64_collect_native_gregset (const struct regcache *regcache,
101             regcache_raw_collect (regcache, i, regs + offset);
102         }
103      }
104 +
105 +  if (gdbarch_ptr_bit (gdbarch) == 32)
106 +    {
107 +      /* Sign-extend %eax as during return from a syscall it is being checked
108 +        for -ERESTART* values -512 being above 0xfffffffffffffe00; tested by
109 +        interrupt.exp.  */
110 +
111 +      int i = I386_EAX_REGNUM;
112 +
113 +      if (regnum == -1 || regnum == i)
114 +       {
115 +         void *ptr = regs + amd64_native_gregset_reg_offset (gdbarch, i);
116 +
117 +         *(int64_t *) ptr = *(int32_t *) ptr;
118 +       }
119 +    }
120  }
121
This page took 0.093153 seconds and 3 git commands to generate.