btrace: remove leftover comment
[deliverable/binutils-gdb.git] / gdb / amd64-linux-nat.c
CommitLineData
a4b6fc86 1/* Native-dependent code for GNU/Linux x86-64.
0a65a603 2
618f726f 3 Copyright (C) 2001-2016 Free Software Foundation, Inc.
53e95fcf
JS
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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
53e95fcf
JS
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
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
53e95fcf
JS
20
21#include "defs.h"
22#include "inferior.h"
53e95fcf 23#include "regcache.h"
a055a187 24#include "elf/common.h"
35782f14 25#include <sys/uio.h>
5826e159 26#include "nat/gdb_ptrace.h"
c43af07c 27#include <asm/prctl.h>
33a0a2ac 28#include <sys/reg.h>
c4f35dd8 29#include "gregset.h"
3116063b 30#include "gdb_proc_service.h"
c4f35dd8 31
3116063b
GB
32#include "amd64-nat.h"
33#include "linux-nat.h"
9c1488cb 34#include "amd64-tdep.h"
3116063b 35#include "amd64-linux-tdep.h"
60fac5b8 36#include "i386-linux-tdep.h"
df7e5265 37#include "x86-xstate.h"
a055a187 38
040baaf6 39#include "x86-linux-nat.h"
ca9b78ce 40#include "nat/linux-ptrace.h"
93813b37 41#include "nat/amd64-linux-siginfo.h"
60fac5b8 42
60fac5b8
MK
43/* Mapping between the general-purpose registers in GNU/Linux x86-64
44 `struct user' format and GDB's register cache layout for GNU/Linux
45 i386.
46
47 Note that most GNU/Linux x86-64 registers are 64-bit, while the
48 GNU/Linux i386 registers are all 32-bit, but since we're
49 little-endian we get away with that. */
50
51/* From <sys/reg.h> on GNU/Linux i386. */
430eaf2e 52static int amd64_linux_gregset32_reg_offset[] =
60fac5b8 53{
f5859b4d
MK
54 RAX * 8, RCX * 8, /* %eax, %ecx */
55 RDX * 8, RBX * 8, /* %edx, %ebx */
56 RSP * 8, RBP * 8, /* %esp, %ebp */
57 RSI * 8, RDI * 8, /* %esi, %edi */
58 RIP * 8, EFLAGS * 8, /* %eip, %eflags */
59 CS * 8, SS * 8, /* %cs, %ss */
60 DS * 8, ES * 8, /* %ds, %es */
61 FS * 8, GS * 8, /* %fs, %gs */
60fac5b8
MK
62 -1, -1, -1, -1, -1, -1, -1, -1,
63 -1, -1, -1, -1, -1, -1, -1, -1,
64 -1, -1, -1, -1, -1, -1, -1, -1, -1,
a055a187 65 -1, -1, -1, -1, -1, -1, -1, -1,
01f9f808
MS
66 -1, -1, -1, -1, /* MPX registers BND0 ... BND3. */
67 -1, -1, /* MPX registers BNDCFGU, BNDSTATUS. */
68 -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512) */
69 -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512) */
70 ORIG_RAX * 8 /* "orig_eax" */
60fac5b8 71};
53e95fcf
JS
72\f
73
74/* Transfering the general-purpose registers between GDB, inferiors
75 and core files. */
76
60fac5b8 77/* Fill GDB's register cache with the general-purpose register values
53e95fcf
JS
78 in *GREGSETP. */
79
80void
7f7fe91e 81supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
53e95fcf 82{
7f7fe91e 83 amd64_supply_native_gregset (regcache, gregsetp, -1);
53e95fcf
JS
84}
85
60fac5b8
MK
86/* Fill register REGNUM (if it is a general-purpose register) in
87 *GREGSETP with the value in GDB's register cache. If REGNUM is -1,
53e95fcf
JS
88 do this for all registers. */
89
90void
7f7fe91e
UW
91fill_gregset (const struct regcache *regcache,
92 elf_gregset_t *gregsetp, int regnum)
53e95fcf 93{
7f7fe91e 94 amd64_collect_native_gregset (regcache, gregsetp, regnum);
53e95fcf
JS
95}
96
53e95fcf
JS
97/* Transfering floating-point registers between GDB, inferiors and cores. */
98
60fac5b8 99/* Fill GDB's register cache with the floating-point and SSE register
c4f35dd8 100 values in *FPREGSETP. */
53e95fcf
JS
101
102void
7f7fe91e 103supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
53e95fcf 104{
7f7fe91e 105 amd64_supply_fxsave (regcache, -1, fpregsetp);
53e95fcf
JS
106}
107
8dda9770 108/* Fill register REGNUM (if it is a floating-point or SSE register) in
60fac5b8 109 *FPREGSETP with the value in GDB's register cache. If REGNUM is
c4f35dd8 110 -1, do this for all registers. */
53e95fcf
JS
111
112void
7f7fe91e
UW
113fill_fpregset (const struct regcache *regcache,
114 elf_fpregset_t *fpregsetp, int regnum)
53e95fcf 115{
7f7fe91e 116 amd64_collect_fxsave (regcache, regnum, fpregsetp);
53e95fcf 117}
53e95fcf
JS
118\f
119
120/* Transferring arbitrary registers between GDB and inferior. */
121
60fac5b8 122/* Fetch register REGNUM from the child process. If REGNUM is -1, do
53e95fcf
JS
123 this for all registers (including the floating point and SSE
124 registers). */
125
10d6c8cd 126static void
28439f5e
PA
127amd64_linux_fetch_inferior_registers (struct target_ops *ops,
128 struct regcache *regcache, int regnum)
53e95fcf 129{
f8028488 130 struct gdbarch *gdbarch = get_regcache_arch (regcache);
53e95fcf
JS
131 int tid;
132
a4b6fc86 133 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 134 tid = ptid_get_lwp (inferior_ptid);
c4f35dd8 135 if (tid == 0)
dfd4cc63 136 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
53e95fcf 137
f8028488 138 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 139 {
99679982
MK
140 elf_gregset_t regs;
141
142 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
edefbb7c 143 perror_with_name (_("Couldn't get registers"));
99679982 144
56be3814 145 amd64_supply_native_gregset (regcache, &regs, -1);
60fac5b8
MK
146 if (regnum != -1)
147 return;
53e95fcf
JS
148 }
149
f8028488 150 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 151 {
99679982 152 elf_fpregset_t fpregs;
53e95fcf 153
0bdb2f78 154 if (have_ptrace_getregset == TRIBOOL_TRUE)
a055a187 155 {
df7e5265 156 char xstateregs[X86_XSTATE_MAX_SIZE];
a055a187
L
157 struct iovec iov;
158
159 iov.iov_base = xstateregs;
160 iov.iov_len = sizeof (xstateregs);
161 if (ptrace (PTRACE_GETREGSET, tid,
162 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
163 perror_with_name (_("Couldn't get extended state status"));
99679982 164
a055a187
L
165 amd64_supply_xsave (regcache, -1, xstateregs);
166 }
167 else
168 {
169 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
170 perror_with_name (_("Couldn't get floating point status"));
171
172 amd64_supply_fxsave (regcache, -1, &fpregs);
173 }
99679982 174 }
53e95fcf
JS
175}
176
60fac5b8
MK
177/* Store register REGNUM back into the child process. If REGNUM is
178 -1, do this for all registers (including the floating-point and SSE
53e95fcf 179 registers). */
c4f35dd8 180
10d6c8cd 181static void
28439f5e
PA
182amd64_linux_store_inferior_registers (struct target_ops *ops,
183 struct regcache *regcache, int regnum)
53e95fcf 184{
f8028488 185 struct gdbarch *gdbarch = get_regcache_arch (regcache);
53e95fcf
JS
186 int tid;
187
a4b6fc86 188 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 189 tid = ptid_get_lwp (inferior_ptid);
c4f35dd8 190 if (tid == 0)
dfd4cc63 191 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
53e95fcf 192
f8028488 193 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 194 {
99679982
MK
195 elf_gregset_t regs;
196
197 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
edefbb7c 198 perror_with_name (_("Couldn't get registers"));
99679982 199
56be3814 200 amd64_collect_native_gregset (regcache, &regs, regnum);
99679982
MK
201
202 if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
edefbb7c 203 perror_with_name (_("Couldn't write registers"));
99679982 204
60fac5b8
MK
205 if (regnum != -1)
206 return;
53e95fcf
JS
207 }
208
f8028488 209 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 210 {
99679982
MK
211 elf_fpregset_t fpregs;
212
0bdb2f78 213 if (have_ptrace_getregset == TRIBOOL_TRUE)
a055a187 214 {
df7e5265 215 char xstateregs[X86_XSTATE_MAX_SIZE];
a055a187
L
216 struct iovec iov;
217
218 iov.iov_base = xstateregs;
219 iov.iov_len = sizeof (xstateregs);
220 if (ptrace (PTRACE_GETREGSET, tid,
221 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
222 perror_with_name (_("Couldn't get extended state status"));
99679982 223
a055a187
L
224 amd64_collect_xsave (regcache, regnum, xstateregs, 0);
225
226 if (ptrace (PTRACE_SETREGSET, tid,
227 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
228 perror_with_name (_("Couldn't write extended state status"));
229 }
230 else
231 {
232 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
233 perror_with_name (_("Couldn't get floating point status"));
99679982 234
a055a187 235 amd64_collect_fxsave (regcache, regnum, &fpregs);
99679982 236
a055a187
L
237 if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
238 perror_with_name (_("Couldn't write floating point status"));
239 }
53e95fcf 240 }
53e95fcf
JS
241}
242\f
1aa7e42c 243
50d71875
AC
244/* This function is called by libthread_db as part of its handling of
245 a request for a thread's local storage address. */
246
5bca7895 247ps_err_e
754653a7 248ps_get_thread_area (struct ps_prochandle *ph,
c43af07c
EZ
249 lwpid_t lwpid, int idx, void **base)
250{
f5656ead 251 if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
50d71875 252 {
8c420b8d
GB
253 unsigned int base_addr;
254 ps_err_e result;
255
256 result = x86_linux_get_thread_area (lwpid, (void *) (long) idx,
257 &base_addr);
258 if (result == PS_OK)
259 {
260 /* Extend the value to 64 bits. Here it's assumed that
261 a "long" and a "void *" are the same. */
262 (*base) = (void *) (long) base_addr;
263 }
264 return result;
50d71875
AC
265 }
266 else
267 {
268 /* This definition comes from prctl.h, but some kernels may not
269 have it. */
c43af07c
EZ
270#ifndef PTRACE_ARCH_PRCTL
271#define PTRACE_ARCH_PRCTL 30
272#endif
50d71875
AC
273 /* FIXME: ezannoni-2003-07-09 see comment above about include
274 file order. We could be getting bogus values for these two. */
275 gdb_assert (FS < ELF_NGREG);
276 gdb_assert (GS < ELF_NGREG);
277 switch (idx)
278 {
279 case FS:
6fea9e18
L
280#ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
281 {
282 /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
283 fs_base and gs_base fields of user_regs_struct can be
284 used directly. */
285 unsigned long fs;
286 errno = 0;
287 fs = ptrace (PTRACE_PEEKUSER, lwpid,
288 offsetof (struct user_regs_struct, fs_base), 0);
289 if (errno == 0)
290 {
291 *base = (void *) fs;
292 return PS_OK;
293 }
294 }
295#endif
50d71875
AC
296 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
297 return PS_OK;
298 break;
299 case GS:
6fea9e18
L
300#ifdef HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE
301 {
302 unsigned long gs;
303 errno = 0;
304 gs = ptrace (PTRACE_PEEKUSER, lwpid,
305 offsetof (struct user_regs_struct, gs_base), 0);
306 if (errno == 0)
307 {
308 *base = (void *) gs;
309 return PS_OK;
310 }
311 }
312#endif
50d71875
AC
313 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
314 return PS_OK;
315 break;
316 default: /* Should not happen. */
317 return PS_BADADDR;
318 }
c43af07c 319 }
b6d42148 320 return PS_ERR; /* ptrace failed. */
c43af07c 321}
5bca7895 322\f
c43af07c 323
9cf12d57 324/* Convert a ptrace/host siginfo object, into/from the siginfo in the
5b009018
PA
325 layout of the inferiors' architecture. Returns true if any
326 conversion was done; false otherwise. If DIRECTION is 1, then copy
9cf12d57 327 from INF to PTRACE. If DIRECTION is 0, copy from PTRACE to
5b009018
PA
328 INF. */
329
330static int
9cf12d57 331amd64_linux_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
5b009018 332{
ba224c70
L
333 struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
334
5b009018
PA
335 /* Is the inferior 32-bit? If so, then do fixup the siginfo
336 object. */
ba224c70 337 if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
9cf12d57 338 return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
93813b37 339 FIXUP_32);
ba224c70
L
340 /* No fixup for native x32 GDB. */
341 else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
9cf12d57 342 return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
93813b37 343 FIXUP_X32);
5b009018
PA
344 else
345 return 0;
346}
c1e246a0
GB
347
348/* Provide a prototype to silence -Wmissing-prototypes. */
349void _initialize_amd64_linux_nat (void);
350
351void
352_initialize_amd64_linux_nat (void)
353{
354 struct target_ops *t;
355
356 amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
357 amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
358 amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset;
359 amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS;
360
361 gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
362 == amd64_native_gregset32_num_regs);
363
364 /* Create a generic x86 GNU/Linux target. */
365 t = x86_linux_create_target ();
366
367 /* Add our register access methods. */
368 t->to_fetch_registers = amd64_linux_fetch_inferior_registers;
369 t->to_store_registers = amd64_linux_store_inferior_registers;
370
371 /* Add the target. */
372 x86_linux_add_target (t);
373
374 /* Add our siginfo layout converter. */
375 linux_nat_set_siginfo_fixup (t, amd64_linux_siginfo_fixup);
376}
This page took 1.08863 seconds and 4 git commands to generate.