Remove regcache_cooked_write_part
[deliverable/binutils-gdb.git] / gdb / amd64-linux-nat.c
CommitLineData
a4b6fc86 1/* Native-dependent code for GNU/Linux x86-64.
0a65a603 2
e2882c85 3 Copyright (C) 2001-2018 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 32#include "amd64-nat.h"
9c1488cb 33#include "amd64-tdep.h"
3116063b 34#include "amd64-linux-tdep.h"
60fac5b8 35#include "i386-linux-tdep.h"
df7e5265 36#include "x86-xstate.h"
a055a187 37
040baaf6 38#include "x86-linux-nat.h"
ca9b78ce 39#include "nat/linux-ptrace.h"
93813b37 40#include "nat/amd64-linux-siginfo.h"
60fac5b8 41
2735833d
WT
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
f6ac5f3d
PA
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;
135340af
PA
53
54 bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
55 override;
f6ac5f3d
PA
56};
57
58static amd64_linux_nat_target the_amd64_linux_nat_target;
59
60fac5b8
MK
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. */
430eaf2e 69static int amd64_linux_gregset32_reg_offset[] =
60fac5b8 70{
f5859b4d
MK
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 */
60fac5b8
MK
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,
a055a187 82 -1, -1, -1, -1, -1, -1, -1, -1,
01f9f808
MS
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) */
51547df6 87 -1, /* PKEYS register PKRU */
01f9f808 88 ORIG_RAX * 8 /* "orig_eax" */
60fac5b8 89};
53e95fcf
JS
90\f
91
92/* Transfering the general-purpose registers between GDB, inferiors
93 and core files. */
94
60fac5b8 95/* Fill GDB's register cache with the general-purpose register values
53e95fcf
JS
96 in *GREGSETP. */
97
98void
7f7fe91e 99supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
53e95fcf 100{
7f7fe91e 101 amd64_supply_native_gregset (regcache, gregsetp, -1);
53e95fcf
JS
102}
103
60fac5b8
MK
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,
53e95fcf
JS
106 do this for all registers. */
107
108void
7f7fe91e
UW
109fill_gregset (const struct regcache *regcache,
110 elf_gregset_t *gregsetp, int regnum)
53e95fcf 111{
7f7fe91e 112 amd64_collect_native_gregset (regcache, gregsetp, regnum);
53e95fcf
JS
113}
114
53e95fcf
JS
115/* Transfering floating-point registers between GDB, inferiors and cores. */
116
60fac5b8 117/* Fill GDB's register cache with the floating-point and SSE register
c4f35dd8 118 values in *FPREGSETP. */
53e95fcf
JS
119
120void
7f7fe91e 121supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
53e95fcf 122{
7f7fe91e 123 amd64_supply_fxsave (regcache, -1, fpregsetp);
53e95fcf
JS
124}
125
8dda9770 126/* Fill register REGNUM (if it is a floating-point or SSE register) in
60fac5b8 127 *FPREGSETP with the value in GDB's register cache. If REGNUM is
c4f35dd8 128 -1, do this for all registers. */
53e95fcf
JS
129
130void
7f7fe91e
UW
131fill_fpregset (const struct regcache *regcache,
132 elf_fpregset_t *fpregsetp, int regnum)
53e95fcf 133{
7f7fe91e 134 amd64_collect_fxsave (regcache, regnum, fpregsetp);
53e95fcf 135}
53e95fcf
JS
136\f
137
138/* Transferring arbitrary registers between GDB and inferior. */
139
60fac5b8 140/* Fetch register REGNUM from the child process. If REGNUM is -1, do
53e95fcf
JS
141 this for all registers (including the floating point and SSE
142 registers). */
143
f6ac5f3d
PA
144void
145amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
53e95fcf 146{
ac7936df 147 struct gdbarch *gdbarch = regcache->arch ();
53e95fcf
JS
148 int tid;
149
a4b6fc86 150 /* GNU/Linux LWP ID's are process ID's. */
222312d3 151 tid = ptid_get_lwp (regcache->ptid ());
c4f35dd8 152 if (tid == 0)
222312d3 153 tid = ptid_get_pid (regcache->ptid ()); /* Not a threaded program. */
53e95fcf 154
f8028488 155 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 156 {
99679982
MK
157 elf_gregset_t regs;
158
159 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
edefbb7c 160 perror_with_name (_("Couldn't get registers"));
99679982 161
56be3814 162 amd64_supply_native_gregset (regcache, &regs, -1);
60fac5b8
MK
163 if (regnum != -1)
164 return;
53e95fcf
JS
165 }
166
f8028488 167 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 168 {
99679982 169 elf_fpregset_t fpregs;
53e95fcf 170
0bdb2f78 171 if (have_ptrace_getregset == TRIBOOL_TRUE)
a055a187 172 {
df7e5265 173 char xstateregs[X86_XSTATE_MAX_SIZE];
a055a187
L
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"));
99679982 181
a055a187
L
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 }
2735833d
WT
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 (regcache, 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 (regcache, AMD64_GSBASE_REGNUM, &base);
212 }
213 }
214#endif
99679982 215 }
53e95fcf
JS
216}
217
60fac5b8
MK
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
53e95fcf 220 registers). */
c4f35dd8 221
f6ac5f3d
PA
222void
223amd64_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
53e95fcf 224{
ac7936df 225 struct gdbarch *gdbarch = regcache->arch ();
53e95fcf
JS
226 int tid;
227
a4b6fc86 228 /* GNU/Linux LWP ID's are process ID's. */
222312d3 229 tid = ptid_get_lwp (regcache->ptid ());
c4f35dd8 230 if (tid == 0)
222312d3 231 tid = ptid_get_pid (regcache->ptid ()); /* Not a threaded program. */
53e95fcf 232
f8028488 233 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 234 {
99679982
MK
235 elf_gregset_t regs;
236
237 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
edefbb7c 238 perror_with_name (_("Couldn't get registers"));
99679982 239
56be3814 240 amd64_collect_native_gregset (regcache, &regs, regnum);
99679982
MK
241
242 if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
edefbb7c 243 perror_with_name (_("Couldn't write registers"));
99679982 244
60fac5b8
MK
245 if (regnum != -1)
246 return;
53e95fcf
JS
247 }
248
f8028488 249 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 250 {
99679982
MK
251 elf_fpregset_t fpregs;
252
0bdb2f78 253 if (have_ptrace_getregset == TRIBOOL_TRUE)
a055a187 254 {
df7e5265 255 char xstateregs[X86_XSTATE_MAX_SIZE];
a055a187
L
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"));
99679982 263
a055a187
L
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"));
99679982 274
a055a187 275 amd64_collect_fxsave (regcache, regnum, &fpregs);
99679982 276
a055a187
L
277 if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
278 perror_with_name (_("Couldn't write floating point status"));
279 }
2735833d
WT
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 (regcache, 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 (regcache, 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
53e95fcf 304 }
53e95fcf
JS
305}
306\f
1aa7e42c 307
50d71875
AC
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
5bca7895 311ps_err_e
754653a7 312ps_get_thread_area (struct ps_prochandle *ph,
c43af07c
EZ
313 lwpid_t lwpid, int idx, void **base)
314{
f5656ead 315 if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
50d71875 316 {
8c420b8d
GB
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;
50d71875
AC
329 }
330 else
331 {
2735833d 332
50d71875
AC
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:
6fea9e18
L
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
50d71875
AC
356 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
357 return PS_OK;
358 break;
359 case GS:
6fea9e18
L
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
50d71875
AC
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 }
c43af07c 379 }
b6d42148 380 return PS_ERR; /* ptrace failed. */
c43af07c 381}
5bca7895 382\f
c43af07c 383
9cf12d57 384/* Convert a ptrace/host siginfo object, into/from the siginfo in the
5b009018
PA
385 layout of the inferiors' architecture. Returns true if any
386 conversion was done; false otherwise. If DIRECTION is 1, then copy
9cf12d57 387 from INF to PTRACE. If DIRECTION is 0, copy from PTRACE to
5b009018
PA
388 INF. */
389
135340af
PA
390bool
391amd64_linux_nat_target::low_siginfo_fixup (siginfo_t *ptrace,
392 gdb_byte *inf,
393 int direction)
5b009018 394{
ba224c70
L
395 struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
396
5b009018
PA
397 /* Is the inferior 32-bit? If so, then do fixup the siginfo
398 object. */
ba224c70 399 if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
135340af
PA
400 return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
401 FIXUP_32);
ba224c70
L
402 /* No fixup for native x32 GDB. */
403 else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
135340af
PA
404 return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
405 FIXUP_X32);
5b009018 406 else
135340af 407 return false;
5b009018 408}
c1e246a0 409
c1e246a0
GB
410void
411_initialize_amd64_linux_nat (void)
412{
c1e246a0
GB
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
f6ac5f3d 421 linux_target = &the_amd64_linux_nat_target;
c1e246a0
GB
422
423 /* Add the target. */
d9f719f1 424 add_inf_child_target (linux_target);
c1e246a0 425}
This page took 1.181424 seconds and 4 git commands to generate.