xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/amd64-linux-nat.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Native-dependent code for GNU/Linux x86-64.
2 
3    Copyright (C) 2001-2023 Free Software Foundation, Inc.
4    Contributed by Jiri Smid, SuSE Labs.
5 
6    This file is part of GDB.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 #include "defs.h"
22 #include "inferior.h"
23 #include "regcache.h"
24 #include "elf/common.h"
25 #include <sys/uio.h>
26 #include "nat/gdb_ptrace.h"
27 #include <asm/prctl.h>
28 #include <sys/reg.h>
29 #include "gregset.h"
30 #include "gdb_proc_service.h"
31 
32 #include "amd64-nat.h"
33 #include "amd64-tdep.h"
34 #include "amd64-linux-tdep.h"
35 #include "i386-linux-tdep.h"
36 #include "gdbsupport/x86-xstate.h"
37 
38 #include "x86-linux-nat.h"
39 #include "nat/linux-ptrace.h"
40 #include "nat/amd64-linux-siginfo.h"
41 
42 /* This definition comes from prctl.h.  Kernels older than 2.5.64
43    do not have it.  */
44 #ifndef PTRACE_ARCH_PRCTL
45 #define PTRACE_ARCH_PRCTL      30
46 #endif
47 
48 struct amd64_linux_nat_target final : public x86_linux_nat_target
49 {
50   /* Add our register access methods.  */
51   void fetch_registers (struct regcache *, int) override;
52   void store_registers (struct regcache *, int) override;
53 
54   bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
55     override;
56 };
57 
58 static amd64_linux_nat_target the_amd64_linux_nat_target;
59 
60 /* Mapping between the general-purpose registers in GNU/Linux x86-64
61    `struct user' format and GDB's register cache layout for GNU/Linux
62    i386.
63 
64    Note that most GNU/Linux x86-64 registers are 64-bit, while the
65    GNU/Linux i386 registers are all 32-bit, but since we're
66    little-endian we get away with that.  */
67 
68 /* From <sys/reg.h> on GNU/Linux i386.  */
69 static int amd64_linux_gregset32_reg_offset[] =
70 {
71   RAX * 8, RCX * 8,		/* %eax, %ecx */
72   RDX * 8, RBX * 8,		/* %edx, %ebx */
73   RSP * 8, RBP * 8,		/* %esp, %ebp */
74   RSI * 8, RDI * 8,		/* %esi, %edi */
75   RIP * 8, EFLAGS * 8,		/* %eip, %eflags */
76   CS * 8, SS * 8,		/* %cs, %ss */
77   DS * 8, ES * 8,		/* %ds, %es */
78   FS * 8, GS * 8,		/* %fs, %gs */
79   -1, -1, -1, -1, -1, -1, -1, -1,
80   -1, -1, -1, -1, -1, -1, -1, -1,
81   -1, -1, -1, -1, -1, -1, -1, -1, -1,
82   -1, -1, -1, -1, -1, -1, -1, -1,
83   -1, -1, -1, -1,		  /* MPX registers BND0 ... BND3.  */
84   -1, -1,			  /* MPX registers BNDCFGU, BNDSTATUS.  */
85   -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512)  */
86   -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512)  */
87   -1,				  /* PKEYS register PKRU  */
88   ORIG_RAX * 8			  /* "orig_eax"  */
89 };
90 
91 
92 /* Transfering the general-purpose registers between GDB, inferiors
93    and core files.  */
94 
95 /* See amd64_collect_native_gregset.  This linux specific version handles
96    issues with negative EAX values not being restored correctly upon syscall
97    return when debugging 32-bit targets.  It has no effect on 64-bit
98    targets.  */
99 
100 static void
101 amd64_linux_collect_native_gregset (const struct regcache *regcache,
102 				    void *gregs, int regnum)
103 {
104   amd64_collect_native_gregset (regcache, gregs, regnum);
105 
106   struct gdbarch *gdbarch = regcache->arch ();
107   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
108     {
109       /* Sign extend EAX value to avoid potential syscall restart
110 	 problems.
111 
112 	 On Linux, when a syscall is interrupted by a signal, the
113 	 (kernel function implementing the) syscall may return
114 	 -ERESTARTSYS when a signal occurs.  Doing so indicates that
115 	 the syscall is restartable.  Then, depending on settings
116 	 associated with the signal handler, and after the signal
117 	 handler is called, the kernel can then either return -EINTR
118 	 or it can cause the syscall to be restarted.  We are
119 	 concerned with the latter case here.
120 
121 	 On (32-bit) i386, the status (-ERESTARTSYS) is placed in the
122 	 EAX register.  When debugging a 32-bit process from a 64-bit
123 	 (amd64) GDB, the debugger fetches 64-bit registers even
124 	 though the process being debugged is only 32-bit.  The
125 	 register cache is only 32 bits wide though; GDB discards the
126 	 high 32 bits when placing 64-bit values in the 32-bit
127 	 regcache.  Normally, this is not a problem since the 32-bit
128 	 process should only care about the lower 32-bit portions of
129 	 these registers.  That said, it can happen that the 64-bit
130 	 value being restored will be different from the 64-bit value
131 	 that was originally retrieved from the kernel.  The one place
132 	 (that we know of) where it does matter is in the kernel's
133 	 syscall restart code.  The kernel's code for restarting a
134 	 syscall after a signal expects to see a negative value
135 	 (specifically -ERESTARTSYS) in the 64-bit RAX register in
136 	 order to correctly cause a syscall to be restarted.
137 
138 	 The call to amd64_collect_native_gregset, above, is setting
139 	 the high 32 bits of RAX (and other registers too) to 0.  For
140 	 syscall restart, we need to sign extend EAX so that RAX will
141 	 appear as a negative value when EAX is set to -ERESTARTSYS.
142 	 This in turn will cause the signal handling code in the
143 	 kernel to recognize -ERESTARTSYS which will in turn cause the
144 	 syscall to be restarted.
145 
146 	 The test case gdb.base/interrupt.exp tests for this problem.
147 	 Without this sign extension code in place, it'll show
148 	 a number of failures when testing against unix/-m32.  */
149 
150       if (regnum == -1 || regnum == I386_EAX_REGNUM)
151 	{
152 	  void *ptr = ((gdb_byte *) gregs
153 		       + amd64_linux_gregset32_reg_offset[I386_EAX_REGNUM]);
154 
155 	  *(int64_t *) ptr = *(int32_t *) ptr;
156 	}
157     }
158 }
159 
160 /* Fill GDB's register cache with the general-purpose register values
161    in *GREGSETP.  */
162 
163 void
164 supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
165 {
166   amd64_supply_native_gregset (regcache, gregsetp, -1);
167 }
168 
169 /* Fill register REGNUM (if it is a general-purpose register) in
170    *GREGSETP with the value in GDB's register cache.  If REGNUM is -1,
171    do this for all registers.  */
172 
173 void
174 fill_gregset (const struct regcache *regcache,
175 	      elf_gregset_t *gregsetp, int regnum)
176 {
177   amd64_linux_collect_native_gregset (regcache, gregsetp, regnum);
178 }
179 
180 /* Transfering floating-point registers between GDB, inferiors and cores.  */
181 
182 /* Fill GDB's register cache with the floating-point and SSE register
183    values in *FPREGSETP.  */
184 
185 void
186 supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
187 {
188   amd64_supply_fxsave (regcache, -1, fpregsetp);
189 }
190 
191 /* Fill register REGNUM (if it is a floating-point or SSE register) in
192    *FPREGSETP with the value in GDB's register cache.  If REGNUM is
193    -1, do this for all registers.  */
194 
195 void
196 fill_fpregset (const struct regcache *regcache,
197 	       elf_fpregset_t *fpregsetp, int regnum)
198 {
199   amd64_collect_fxsave (regcache, regnum, fpregsetp);
200 }
201 
202 
203 /* Transferring arbitrary registers between GDB and inferior.  */
204 
205 /* Fetch register REGNUM from the child process.  If REGNUM is -1, do
206    this for all registers (including the floating point and SSE
207    registers).  */
208 
209 void
210 amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
211 {
212   struct gdbarch *gdbarch = regcache->arch ();
213   int tid;
214 
215   /* GNU/Linux LWP ID's are process ID's.  */
216   tid = regcache->ptid ().lwp ();
217   if (tid == 0)
218     tid = regcache->ptid ().pid (); /* Not a threaded program.  */
219 
220   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
221     {
222       elf_gregset_t regs;
223 
224       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
225 	perror_with_name (_("Couldn't get registers"));
226 
227       amd64_supply_native_gregset (regcache, &regs, -1);
228       if (regnum != -1)
229 	return;
230     }
231 
232   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
233     {
234       elf_fpregset_t fpregs;
235 
236       if (have_ptrace_getregset == TRIBOOL_TRUE)
237 	{
238 	  char xstateregs[X86_XSTATE_MAX_SIZE];
239 	  struct iovec iov;
240 
241 	  /* Pre-4.14 kernels have a bug (fixed by commit 0852b374173b
242 	     "x86/fpu: Add FPU state copying quirk to handle XRSTOR failure on
243 	     Intel Skylake CPUs") that sometimes causes the mxcsr location in
244 	     xstateregs not to be copied by PTRACE_GETREGSET.  Make sure that
245 	     the location is at least initialized with a defined value.  */
246 	  memset (xstateregs, 0, sizeof (xstateregs));
247 	  iov.iov_base = xstateregs;
248 	  iov.iov_len = sizeof (xstateregs);
249 	  if (ptrace (PTRACE_GETREGSET, tid,
250 		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
251 	    perror_with_name (_("Couldn't get extended state status"));
252 
253 	  amd64_supply_xsave (regcache, -1, xstateregs);
254 	}
255       else
256 	{
257 	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
258 	    perror_with_name (_("Couldn't get floating point status"));
259 
260 	  amd64_supply_fxsave (regcache, -1, &fpregs);
261 	}
262     }
263 }
264 
265 /* Store register REGNUM back into the child process.  If REGNUM is
266    -1, do this for all registers (including the floating-point and SSE
267    registers).  */
268 
269 void
270 amd64_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
271 {
272   struct gdbarch *gdbarch = regcache->arch ();
273   int tid;
274 
275   /* GNU/Linux LWP ID's are process ID's.  */
276   tid = regcache->ptid ().lwp ();
277   if (tid == 0)
278     tid = regcache->ptid ().pid (); /* Not a threaded program.  */
279 
280   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
281     {
282       elf_gregset_t regs;
283 
284       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
285 	perror_with_name (_("Couldn't get registers"));
286 
287       amd64_linux_collect_native_gregset (regcache, &regs, regnum);
288 
289       if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
290 	perror_with_name (_("Couldn't write registers"));
291 
292       if (regnum != -1)
293 	return;
294     }
295 
296   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
297     {
298       elf_fpregset_t fpregs;
299 
300       if (have_ptrace_getregset == TRIBOOL_TRUE)
301 	{
302 	  char xstateregs[X86_XSTATE_MAX_SIZE];
303 	  struct iovec iov;
304 
305 	  iov.iov_base = xstateregs;
306 	  iov.iov_len = sizeof (xstateregs);
307 	  if (ptrace (PTRACE_GETREGSET, tid,
308 		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
309 	    perror_with_name (_("Couldn't get extended state status"));
310 
311 	  amd64_collect_xsave (regcache, regnum, xstateregs, 0);
312 
313 	  if (ptrace (PTRACE_SETREGSET, tid,
314 		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
315 	    perror_with_name (_("Couldn't write extended state status"));
316 	}
317       else
318 	{
319 	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
320 	    perror_with_name (_("Couldn't get floating point status"));
321 
322 	  amd64_collect_fxsave (regcache, regnum, &fpregs);
323 
324 	  if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
325 	    perror_with_name (_("Couldn't write floating point status"));
326 	}
327     }
328 }
329 
330 
331 /* This function is called by libthread_db as part of its handling of
332    a request for a thread's local storage address.  */
333 
334 ps_err_e
335 ps_get_thread_area (struct ps_prochandle *ph,
336 		    lwpid_t lwpid, int idx, void **base)
337 {
338   if (gdbarch_bfd_arch_info (ph->thread->inf->gdbarch)->bits_per_word == 32)
339     {
340       unsigned int base_addr;
341       ps_err_e result;
342 
343       result = x86_linux_get_thread_area (lwpid, (void *) (long) idx,
344 					  &base_addr);
345       if (result == PS_OK)
346 	{
347 	  /* Extend the value to 64 bits.  Here it's assumed that
348 	     a "long" and a "void *" are the same.  */
349 	  (*base) = (void *) (long) base_addr;
350 	}
351       return result;
352     }
353   else
354     {
355 
356       /* FIXME: ezannoni-2003-07-09 see comment above about include
357 	 file order.  We could be getting bogus values for these two.  */
358       gdb_assert (FS < ELF_NGREG);
359       gdb_assert (GS < ELF_NGREG);
360       switch (idx)
361 	{
362 	case FS:
363 	    {
364 	      unsigned long fs;
365 	      errno = 0;
366 	      fs = ptrace (PTRACE_PEEKUSER, lwpid,
367 			   offsetof (struct user_regs_struct, fs_base), 0);
368 	      if (errno == 0)
369 		{
370 		  *base = (void *) fs;
371 		  return PS_OK;
372 		}
373 	    }
374 
375 	  break;
376 
377 	case GS:
378 	    {
379 	      unsigned long gs;
380 	      errno = 0;
381 	      gs = ptrace (PTRACE_PEEKUSER, lwpid,
382 			   offsetof (struct user_regs_struct, gs_base), 0);
383 	      if (errno == 0)
384 		{
385 		  *base = (void *) gs;
386 		  return PS_OK;
387 		}
388 	    }
389 	  break;
390 
391 	default:                   /* Should not happen.  */
392 	  return PS_BADADDR;
393 	}
394     }
395   return PS_ERR;               /* ptrace failed.  */
396 }
397 
398 
399 /* Convert a ptrace/host siginfo object, into/from the siginfo in the
400    layout of the inferiors' architecture.  Returns true if any
401    conversion was done; false otherwise.  If DIRECTION is 1, then copy
402    from INF to PTRACE.  If DIRECTION is 0, copy from PTRACE to
403    INF.  */
404 
405 bool
406 amd64_linux_nat_target::low_siginfo_fixup (siginfo_t *ptrace,
407 					   gdb_byte *inf,
408 					   int direction)
409 {
410   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
411 
412   /* Is the inferior 32-bit?  If so, then do fixup the siginfo
413      object.  */
414   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
415     return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
416 					     FIXUP_32);
417   /* No fixup for native x32 GDB.  */
418   else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
419     return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
420 					     FIXUP_X32);
421   else
422     return false;
423 }
424 
425 void _initialize_amd64_linux_nat ();
426 void
427 _initialize_amd64_linux_nat ()
428 {
429   amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
430   amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
431   amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset;
432   amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS;
433 
434   gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
435 	      == amd64_native_gregset32_num_regs);
436 
437   linux_target = &the_amd64_linux_nat_target;
438 
439   /* Add the target.  */
440   add_inf_child_target (linux_target);
441 }
442