amd64-linux-nat.c revision 1.8
1/* Native-dependent code for GNU/Linux x86-64.
2
3   Copyright (C) 2001-2019 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 "common/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
48struct 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
58static 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.  */
69static 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/* Fill GDB's register cache with the general-purpose register values
96   in *GREGSETP.  */
97
98void
99supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
100{
101  amd64_supply_native_gregset (regcache, gregsetp, -1);
102}
103
104/* Fill register REGNUM (if it is a general-purpose register) in
105   *GREGSETP with the value in GDB's register cache.  If REGNUM is -1,
106   do this for all registers.  */
107
108void
109fill_gregset (const struct regcache *regcache,
110	      elf_gregset_t *gregsetp, int regnum)
111{
112  amd64_collect_native_gregset (regcache, gregsetp, regnum);
113}
114
115/* Transfering floating-point registers between GDB, inferiors and cores.  */
116
117/* Fill GDB's register cache with the floating-point and SSE register
118   values in *FPREGSETP.  */
119
120void
121supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
122{
123  amd64_supply_fxsave (regcache, -1, fpregsetp);
124}
125
126/* Fill register REGNUM (if it is a floating-point or SSE register) in
127   *FPREGSETP with the value in GDB's register cache.  If REGNUM is
128   -1, do this for all registers.  */
129
130void
131fill_fpregset (const struct regcache *regcache,
132	       elf_fpregset_t *fpregsetp, int regnum)
133{
134  amd64_collect_fxsave (regcache, regnum, fpregsetp);
135}
136
137
138/* Transferring arbitrary registers between GDB and inferior.  */
139
140/* Fetch register REGNUM from the child process.  If REGNUM is -1, do
141   this for all registers (including the floating point and SSE
142   registers).  */
143
144void
145amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
146{
147  struct gdbarch *gdbarch = regcache->arch ();
148  int tid;
149
150  /* GNU/Linux LWP ID's are process ID's.  */
151  tid = regcache->ptid ().lwp ();
152  if (tid == 0)
153    tid = regcache->ptid ().pid (); /* Not a threaded program.  */
154
155  if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
156    {
157      elf_gregset_t regs;
158
159      if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
160	perror_with_name (_("Couldn't get registers"));
161
162      amd64_supply_native_gregset (regcache, &regs, -1);
163      if (regnum != -1)
164	return;
165    }
166
167  if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
168    {
169      elf_fpregset_t fpregs;
170
171      if (have_ptrace_getregset == TRIBOOL_TRUE)
172	{
173	  char xstateregs[X86_XSTATE_MAX_SIZE];
174	  struct iovec iov;
175
176	  iov.iov_base = xstateregs;
177	  iov.iov_len = sizeof (xstateregs);
178	  if (ptrace (PTRACE_GETREGSET, tid,
179		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
180	    perror_with_name (_("Couldn't get extended state status"));
181
182	  amd64_supply_xsave (regcache, -1, xstateregs);
183	}
184      else
185	{
186	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
187	    perror_with_name (_("Couldn't get floating point status"));
188
189	  amd64_supply_fxsave (regcache, -1, &fpregs);
190	}
191#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
192      {
193	/* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
194	   fs_base and gs_base fields of user_regs_struct can be
195	   used directly.  */
196	unsigned long base;
197
198	if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
199	  {
200	    if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_FS) < 0)
201	      perror_with_name (_("Couldn't get segment register fs_base"));
202
203	    regcache->raw_supply (AMD64_FSBASE_REGNUM, &base);
204	  }
205
206	if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
207	  {
208	    if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_GS) < 0)
209	      perror_with_name (_("Couldn't get segment register gs_base"));
210
211	    regcache->raw_supply (AMD64_GSBASE_REGNUM, &base);
212	  }
213      }
214#endif
215    }
216}
217
218/* Store register REGNUM back into the child process.  If REGNUM is
219   -1, do this for all registers (including the floating-point and SSE
220   registers).  */
221
222void
223amd64_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
224{
225  struct gdbarch *gdbarch = regcache->arch ();
226  int tid;
227
228  /* GNU/Linux LWP ID's are process ID's.  */
229  tid = regcache->ptid ().lwp ();
230  if (tid == 0)
231    tid = regcache->ptid ().pid (); /* Not a threaded program.  */
232
233  if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
234    {
235      elf_gregset_t regs;
236
237      if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
238	perror_with_name (_("Couldn't get registers"));
239
240      amd64_collect_native_gregset (regcache, &regs, regnum);
241
242      if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
243	perror_with_name (_("Couldn't write registers"));
244
245      if (regnum != -1)
246	return;
247    }
248
249  if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
250    {
251      elf_fpregset_t fpregs;
252
253      if (have_ptrace_getregset == TRIBOOL_TRUE)
254	{
255	  char xstateregs[X86_XSTATE_MAX_SIZE];
256	  struct iovec iov;
257
258	  iov.iov_base = xstateregs;
259	  iov.iov_len = sizeof (xstateregs);
260	  if (ptrace (PTRACE_GETREGSET, tid,
261		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
262	    perror_with_name (_("Couldn't get extended state status"));
263
264	  amd64_collect_xsave (regcache, regnum, xstateregs, 0);
265
266	  if (ptrace (PTRACE_SETREGSET, tid,
267		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
268	    perror_with_name (_("Couldn't write extended state status"));
269	}
270      else
271	{
272	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
273	    perror_with_name (_("Couldn't get floating point status"));
274
275	  amd64_collect_fxsave (regcache, regnum, &fpregs);
276
277	  if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
278	    perror_with_name (_("Couldn't write floating point status"));
279	}
280
281#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
282      {
283	/* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
284	   fs_base and gs_base fields of user_regs_struct can be
285	   used directly.  */
286	void *base;
287
288	if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
289	  {
290	    regcache->raw_collect (AMD64_FSBASE_REGNUM, &base);
291
292	    if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_FS) < 0)
293	      perror_with_name (_("Couldn't write segment register fs_base"));
294	  }
295	if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
296	  {
297
298	    regcache->raw_collect (AMD64_GSBASE_REGNUM, &base);
299	    if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_GS) < 0)
300	      perror_with_name (_("Couldn't write segment register gs_base"));
301	  }
302      }
303#endif
304    }
305}
306
307
308/* This function is called by libthread_db as part of its handling of
309   a request for a thread's local storage address.  */
310
311ps_err_e
312ps_get_thread_area (struct ps_prochandle *ph,
313                    lwpid_t lwpid, int idx, void **base)
314{
315  if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
316    {
317      unsigned int base_addr;
318      ps_err_e result;
319
320      result = x86_linux_get_thread_area (lwpid, (void *) (long) idx,
321					  &base_addr);
322      if (result == PS_OK)
323	{
324	  /* Extend the value to 64 bits.  Here it's assumed that
325	     a "long" and a "void *" are the same.  */
326	  (*base) = (void *) (long) base_addr;
327	}
328      return result;
329    }
330  else
331    {
332
333      /* FIXME: ezannoni-2003-07-09 see comment above about include
334	 file order.  We could be getting bogus values for these two.  */
335      gdb_assert (FS < ELF_NGREG);
336      gdb_assert (GS < ELF_NGREG);
337      switch (idx)
338	{
339	case FS:
340#ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
341	    {
342	      /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
343		 fs_base and gs_base fields of user_regs_struct can be
344		 used directly.  */
345	      unsigned long fs;
346	      errno = 0;
347	      fs = ptrace (PTRACE_PEEKUSER, lwpid,
348			   offsetof (struct user_regs_struct, fs_base), 0);
349	      if (errno == 0)
350		{
351		  *base = (void *) fs;
352		  return PS_OK;
353		}
354	    }
355#endif
356	  if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
357	    return PS_OK;
358	  break;
359	case GS:
360#ifdef HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE
361	    {
362	      unsigned long gs;
363	      errno = 0;
364	      gs = ptrace (PTRACE_PEEKUSER, lwpid,
365			   offsetof (struct user_regs_struct, gs_base), 0);
366	      if (errno == 0)
367		{
368		  *base = (void *) gs;
369		  return PS_OK;
370		}
371	    }
372#endif
373	  if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
374	    return PS_OK;
375	  break;
376	default:                   /* Should not happen.  */
377	  return PS_BADADDR;
378	}
379    }
380  return PS_ERR;               /* ptrace failed.  */
381}
382
383
384/* Convert a ptrace/host siginfo object, into/from the siginfo in the
385   layout of the inferiors' architecture.  Returns true if any
386   conversion was done; false otherwise.  If DIRECTION is 1, then copy
387   from INF to PTRACE.  If DIRECTION is 0, copy from PTRACE to
388   INF.  */
389
390bool
391amd64_linux_nat_target::low_siginfo_fixup (siginfo_t *ptrace,
392					   gdb_byte *inf,
393					   int direction)
394{
395  struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
396
397  /* Is the inferior 32-bit?  If so, then do fixup the siginfo
398     object.  */
399  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
400    return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
401					     FIXUP_32);
402  /* No fixup for native x32 GDB.  */
403  else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
404    return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
405					     FIXUP_X32);
406  else
407    return false;
408}
409
410void
411_initialize_amd64_linux_nat (void)
412{
413  amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
414  amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
415  amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset;
416  amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS;
417
418  gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
419	      == amd64_native_gregset32_num_regs);
420
421  linux_target = &the_amd64_linux_nat_target;
422
423  /* Add the target.  */
424  add_inf_child_target (linux_target);
425}
426