amd64-linux-nat.c revision 1.7
1/* Native-dependent code for GNU/Linux x86-64.
2
3   Copyright (C) 2001-2017 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 "linux-nat.h"
34#include "amd64-tdep.h"
35#include "amd64-linux-tdep.h"
36#include "i386-linux-tdep.h"
37#include "x86-xstate.h"
38
39#include "x86-linux-nat.h"
40#include "nat/linux-ptrace.h"
41#include "nat/amd64-linux-siginfo.h"
42
43/* This definition comes from prctl.h.  Kernels older than 2.5.64
44   do not have it.  */
45#ifndef PTRACE_ARCH_PRCTL
46#define PTRACE_ARCH_PRCTL      30
47#endif
48
49/* Mapping between the general-purpose registers in GNU/Linux x86-64
50   `struct user' format and GDB's register cache layout for GNU/Linux
51   i386.
52
53   Note that most GNU/Linux x86-64 registers are 64-bit, while the
54   GNU/Linux i386 registers are all 32-bit, but since we're
55   little-endian we get away with that.  */
56
57/* From <sys/reg.h> on GNU/Linux i386.  */
58static int amd64_linux_gregset32_reg_offset[] =
59{
60  RAX * 8, RCX * 8,		/* %eax, %ecx */
61  RDX * 8, RBX * 8,		/* %edx, %ebx */
62  RSP * 8, RBP * 8,		/* %esp, %ebp */
63  RSI * 8, RDI * 8,		/* %esi, %edi */
64  RIP * 8, EFLAGS * 8,		/* %eip, %eflags */
65  CS * 8, SS * 8,		/* %cs, %ss */
66  DS * 8, ES * 8,		/* %ds, %es */
67  FS * 8, GS * 8,		/* %fs, %gs */
68  -1, -1, -1, -1, -1, -1, -1, -1,
69  -1, -1, -1, -1, -1, -1, -1, -1,
70  -1, -1, -1, -1, -1, -1, -1, -1, -1,
71  -1, -1, -1, -1, -1, -1, -1, -1,
72  -1, -1, -1, -1,		  /* MPX registers BND0 ... BND3.  */
73  -1, -1,			  /* MPX registers BNDCFGU, BNDSTATUS.  */
74  -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512)  */
75  -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512)  */
76  -1,				  /* PKEYS register PKRU  */
77  ORIG_RAX * 8			  /* "orig_eax"  */
78};
79
80
81/* Transfering the general-purpose registers between GDB, inferiors
82   and core files.  */
83
84/* Fill GDB's register cache with the general-purpose register values
85   in *GREGSETP.  */
86
87void
88supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
89{
90  amd64_supply_native_gregset (regcache, gregsetp, -1);
91}
92
93/* Fill register REGNUM (if it is a general-purpose register) in
94   *GREGSETP with the value in GDB's register cache.  If REGNUM is -1,
95   do this for all registers.  */
96
97void
98fill_gregset (const struct regcache *regcache,
99	      elf_gregset_t *gregsetp, int regnum)
100{
101  amd64_collect_native_gregset (regcache, gregsetp, regnum);
102}
103
104/* Transfering floating-point registers between GDB, inferiors and cores.  */
105
106/* Fill GDB's register cache with the floating-point and SSE register
107   values in *FPREGSETP.  */
108
109void
110supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
111{
112  amd64_supply_fxsave (regcache, -1, fpregsetp);
113}
114
115/* Fill register REGNUM (if it is a floating-point or SSE register) in
116   *FPREGSETP with the value in GDB's register cache.  If REGNUM is
117   -1, do this for all registers.  */
118
119void
120fill_fpregset (const struct regcache *regcache,
121	       elf_fpregset_t *fpregsetp, int regnum)
122{
123  amd64_collect_fxsave (regcache, regnum, fpregsetp);
124}
125
126
127/* Transferring arbitrary registers between GDB and inferior.  */
128
129/* Fetch register REGNUM from the child process.  If REGNUM is -1, do
130   this for all registers (including the floating point and SSE
131   registers).  */
132
133static void
134amd64_linux_fetch_inferior_registers (struct target_ops *ops,
135				      struct regcache *regcache, int regnum)
136{
137  struct gdbarch *gdbarch = get_regcache_arch (regcache);
138  int tid;
139
140  /* GNU/Linux LWP ID's are process ID's.  */
141  tid = ptid_get_lwp (regcache_get_ptid (regcache));
142  if (tid == 0)
143    tid = ptid_get_pid (regcache_get_ptid (regcache)); /* Not a threaded program.  */
144
145  if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
146    {
147      elf_gregset_t regs;
148
149      if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
150	perror_with_name (_("Couldn't get registers"));
151
152      amd64_supply_native_gregset (regcache, &regs, -1);
153      if (regnum != -1)
154	return;
155    }
156
157  if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
158    {
159      elf_fpregset_t fpregs;
160
161      if (have_ptrace_getregset == TRIBOOL_TRUE)
162	{
163	  char xstateregs[X86_XSTATE_MAX_SIZE];
164	  struct iovec iov;
165
166	  iov.iov_base = xstateregs;
167	  iov.iov_len = sizeof (xstateregs);
168	  if (ptrace (PTRACE_GETREGSET, tid,
169		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
170	    perror_with_name (_("Couldn't get extended state status"));
171
172	  amd64_supply_xsave (regcache, -1, xstateregs);
173	}
174      else
175	{
176	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
177	    perror_with_name (_("Couldn't get floating point status"));
178
179	  amd64_supply_fxsave (regcache, -1, &fpregs);
180	}
181#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
182      {
183	/* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
184	   fs_base and gs_base fields of user_regs_struct can be
185	   used directly.  */
186	unsigned long base;
187
188	if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
189	  {
190	    if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_FS) < 0)
191	      perror_with_name (_("Couldn't get segment register fs_base"));
192
193	    regcache_raw_supply (regcache, AMD64_FSBASE_REGNUM, &base);
194	  }
195
196	if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
197	  {
198	    if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_GS) < 0)
199	      perror_with_name (_("Couldn't get segment register gs_base"));
200
201	    regcache_raw_supply (regcache, AMD64_GSBASE_REGNUM, &base);
202	  }
203      }
204#endif
205    }
206}
207
208/* Store register REGNUM back into the child process.  If REGNUM is
209   -1, do this for all registers (including the floating-point and SSE
210   registers).  */
211
212static void
213amd64_linux_store_inferior_registers (struct target_ops *ops,
214				      struct regcache *regcache, int regnum)
215{
216  struct gdbarch *gdbarch = get_regcache_arch (regcache);
217  int tid;
218
219  /* GNU/Linux LWP ID's are process ID's.  */
220  tid = ptid_get_lwp (regcache_get_ptid (regcache));
221  if (tid == 0)
222    tid = ptid_get_pid (regcache_get_ptid (regcache)); /* Not a threaded program.  */
223
224  if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
225    {
226      elf_gregset_t regs;
227
228      if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
229	perror_with_name (_("Couldn't get registers"));
230
231      amd64_collect_native_gregset (regcache, &regs, regnum);
232
233      if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
234	perror_with_name (_("Couldn't write registers"));
235
236      if (regnum != -1)
237	return;
238    }
239
240  if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
241    {
242      elf_fpregset_t fpregs;
243
244      if (have_ptrace_getregset == TRIBOOL_TRUE)
245	{
246	  char xstateregs[X86_XSTATE_MAX_SIZE];
247	  struct iovec iov;
248
249	  iov.iov_base = xstateregs;
250	  iov.iov_len = sizeof (xstateregs);
251	  if (ptrace (PTRACE_GETREGSET, tid,
252		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
253	    perror_with_name (_("Couldn't get extended state status"));
254
255	  amd64_collect_xsave (regcache, regnum, xstateregs, 0);
256
257	  if (ptrace (PTRACE_SETREGSET, tid,
258		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
259	    perror_with_name (_("Couldn't write extended state status"));
260	}
261      else
262	{
263	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
264	    perror_with_name (_("Couldn't get floating point status"));
265
266	  amd64_collect_fxsave (regcache, regnum, &fpregs);
267
268	  if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
269	    perror_with_name (_("Couldn't write floating point status"));
270	}
271
272#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
273      {
274	/* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
275	   fs_base and gs_base fields of user_regs_struct can be
276	   used directly.  */
277	void *base;
278
279	if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM)
280	  {
281	    regcache_raw_collect (regcache, AMD64_FSBASE_REGNUM, &base);
282
283	    if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_FS) < 0)
284	      perror_with_name (_("Couldn't write segment register fs_base"));
285	  }
286	if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM)
287	  {
288
289	    regcache_raw_collect (regcache, AMD64_GSBASE_REGNUM, &base);
290	    if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_GS) < 0)
291	      perror_with_name (_("Couldn't write segment register gs_base"));
292	  }
293      }
294#endif
295    }
296}
297
298
299/* This function is called by libthread_db as part of its handling of
300   a request for a thread's local storage address.  */
301
302ps_err_e
303ps_get_thread_area (struct ps_prochandle *ph,
304                    lwpid_t lwpid, int idx, void **base)
305{
306  if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
307    {
308      unsigned int base_addr;
309      ps_err_e result;
310
311      result = x86_linux_get_thread_area (lwpid, (void *) (long) idx,
312					  &base_addr);
313      if (result == PS_OK)
314	{
315	  /* Extend the value to 64 bits.  Here it's assumed that
316	     a "long" and a "void *" are the same.  */
317	  (*base) = (void *) (long) base_addr;
318	}
319      return result;
320    }
321  else
322    {
323
324      /* FIXME: ezannoni-2003-07-09 see comment above about include
325	 file order.  We could be getting bogus values for these two.  */
326      gdb_assert (FS < ELF_NGREG);
327      gdb_assert (GS < ELF_NGREG);
328      switch (idx)
329	{
330	case FS:
331#ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
332	    {
333	      /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
334		 fs_base and gs_base fields of user_regs_struct can be
335		 used directly.  */
336	      unsigned long fs;
337	      errno = 0;
338	      fs = ptrace (PTRACE_PEEKUSER, lwpid,
339			   offsetof (struct user_regs_struct, fs_base), 0);
340	      if (errno == 0)
341		{
342		  *base = (void *) fs;
343		  return PS_OK;
344		}
345	    }
346#endif
347	  if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
348	    return PS_OK;
349	  break;
350	case GS:
351#ifdef HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE
352	    {
353	      unsigned long gs;
354	      errno = 0;
355	      gs = ptrace (PTRACE_PEEKUSER, lwpid,
356			   offsetof (struct user_regs_struct, gs_base), 0);
357	      if (errno == 0)
358		{
359		  *base = (void *) gs;
360		  return PS_OK;
361		}
362	    }
363#endif
364	  if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
365	    return PS_OK;
366	  break;
367	default:                   /* Should not happen.  */
368	  return PS_BADADDR;
369	}
370    }
371  return PS_ERR;               /* ptrace failed.  */
372}
373
374
375/* Convert a ptrace/host siginfo object, into/from the siginfo in the
376   layout of the inferiors' architecture.  Returns true if any
377   conversion was done; false otherwise.  If DIRECTION is 1, then copy
378   from INF to PTRACE.  If DIRECTION is 0, copy from PTRACE to
379   INF.  */
380
381static int
382amd64_linux_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
383{
384  struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
385
386  /* Is the inferior 32-bit?  If so, then do fixup the siginfo
387     object.  */
388  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
389      return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
390					       FIXUP_32);
391  /* No fixup for native x32 GDB.  */
392  else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
393      return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
394					       FIXUP_X32);
395  else
396    return 0;
397}
398
399/* Provide a prototype to silence -Wmissing-prototypes.  */
400void _initialize_amd64_linux_nat (void);
401
402void
403_initialize_amd64_linux_nat (void)
404{
405  struct target_ops *t;
406
407  amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
408  amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
409  amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset;
410  amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS;
411
412  gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
413	      == amd64_native_gregset32_num_regs);
414
415  /* Create a generic x86 GNU/Linux target.  */
416  t = x86_linux_create_target ();
417
418  /* Add our register access methods.  */
419  t->to_fetch_registers = amd64_linux_fetch_inferior_registers;
420  t->to_store_registers = amd64_linux_store_inferior_registers;
421
422  /* Add the target.  */
423  x86_linux_add_target (t);
424
425  /* Add our siginfo layout converter.  */
426  linux_nat_set_siginfo_fixup (t, amd64_linux_siginfo_fixup);
427}
428