Move PTRACE_GETREGSET and PTRACE_SETREGSET to nat/linux-ptrace.h
[deliverable/binutils-gdb.git] / gdb / i386-linux-nat.c
CommitLineData
a4194092 1/* Native-dependent code for GNU/Linux i386.
a4b6fc86 2
32d0add0 3 Copyright (C) 1999-2015 Free Software Foundation, Inc.
d4f3574e 4
04cd15b6 5 This file is part of GDB.
d4f3574e 6
04cd15b6
MK
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
04cd15b6 10 (at your option) any later version.
d4f3574e 11
04cd15b6
MK
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
d4f3574e 16
04cd15b6 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
d4f3574e
SS
19
20#include "defs.h"
21#include "inferior.h"
22#include "gdbcore.h"
4e052eda 23#include "regcache.h"
c131fcee 24#include "elf/common.h"
d4f3574e 25#include <sys/ptrace.h>
72fde3df 26#include <sys/uio.h>
c60c0f5f 27#include "gregset.h"
3116063b 28#include "gdb_proc_service.h"
c60c0f5f 29
3116063b 30#include "i386-linux-nat.h"
e750d25e 31#include "i387-tdep.h"
c3833324 32#include "i386-tdep.h"
5179e78f 33#include "i386-linux-tdep.h"
df7e5265 34#include "x86-xstate.h"
c131fcee 35
040baaf6 36#include "x86-linux-nat.h"
ca9b78ce 37#include "nat/linux-ptrace.h"
d4f3574e 38
a4b6fc86
AC
39/* The register sets used in GNU/Linux ELF core-dumps are identical to
40 the register sets in `struct user' that is used for a.out
41 core-dumps, and is also used by `ptrace'. The corresponding types
42 are `elf_gregset_t' for the general-purpose registers (with
04cd15b6
MK
43 `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
44 for the floating-point registers.
45
46 Those types used to be available under the names `gregset_t' and
47 `fpregset_t' too, and this file used those names in the past. But
48 those names are now used for the register sets used in the
49 `mcontext_t' type, and have a different size and layout. */
50
5c44784c
JM
51/* Which ptrace request retrieves which registers?
52 These apply to the corresponding SET requests as well. */
e64a344c 53
5c44784c 54#define GETREGS_SUPPLIES(regno) \
3fb1c838 55 ((0 <= (regno) && (regno) <= 15) || (regno) == I386_LINUX_ORIG_EAX_REGNUM)
e64a344c 56
6ce2ac0b 57#define GETFPXREGS_SUPPLIES(regno) \
f6792ef4 58 (I386_ST0_REGNUM <= (regno) && (regno) < I386_SSE_NUM_REGS)
5c44784c 59
c131fcee 60#define GETXSTATEREGS_SUPPLIES(regno) \
01f9f808 61 (I386_ST0_REGNUM <= (regno) && (regno) < I386_AVX512_NUM_REGS)
c131fcee 62
f60300e7
MK
63/* Does the current host support the GETREGS request? */
64int have_ptrace_getregs =
65#ifdef HAVE_PTRACE_GETREGS
66 1
67#else
68 0
69#endif
70;
71
6ce2ac0b 72/* Does the current host support the GETFPXREGS request? The header
5c44784c
JM
73 file may or may not define it, and even if it is defined, the
74 kernel will return EIO if it's running on a pre-SSE processor.
75
76 My instinct is to attach this to some architecture- or
77 target-specific data structure, but really, a particular GDB
78 process can only run on top of one kernel at a time. So it's okay
79 for this to be a simple variable. */
6ce2ac0b
MK
80int have_ptrace_getfpxregs =
81#ifdef HAVE_PTRACE_GETFPXREGS
3a13a53b 82 -1
5c44784c
JM
83#else
84 0
85#endif
86;
f60300e7 87\f
6ce2ac0b 88
ce556f85 89/* Accessing registers through the U area, one at a time. */
f60300e7
MK
90
91/* Fetch one register. */
92
93static void
56be3814 94fetch_register (struct regcache *regcache, int regno)
f60300e7 95{
f60300e7 96 int tid;
ce556f85 97 int val;
f60300e7 98
ce556f85 99 gdb_assert (!have_ptrace_getregs);
be0d2954 100 if (i386_linux_gregset_reg_offset[regno] == -1)
f60300e7 101 {
56be3814 102 regcache_raw_supply (regcache, regno, NULL);
f60300e7
MK
103 return;
104 }
105
ce556f85 106 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 107 tid = ptid_get_lwp (inferior_ptid);
e64a344c 108 if (tid == 0)
dfd4cc63 109 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
f60300e7 110
ce556f85 111 errno = 0;
be0d2954
L
112 val = ptrace (PTRACE_PEEKUSER, tid,
113 i386_linux_gregset_reg_offset[regno], 0);
ce556f85 114 if (errno != 0)
c9f4d572 115 error (_("Couldn't read register %s (#%d): %s."),
875f8d0e 116 gdbarch_register_name (get_regcache_arch (regcache), regno),
ce556f85 117 regno, safe_strerror (errno));
f60300e7 118
56be3814 119 regcache_raw_supply (regcache, regno, &val);
f60300e7
MK
120}
121
1777feb0 122/* Store one register. */
f60300e7
MK
123
124static void
56be3814 125store_register (const struct regcache *regcache, int regno)
f60300e7 126{
f60300e7 127 int tid;
ce556f85 128 int val;
f60300e7 129
ce556f85 130 gdb_assert (!have_ptrace_getregs);
be0d2954 131 if (i386_linux_gregset_reg_offset[regno] == -1)
ce556f85 132 return;
f60300e7 133
ce556f85 134 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 135 tid = ptid_get_lwp (inferior_ptid);
e64a344c 136 if (tid == 0)
dfd4cc63 137 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
f60300e7 138
ce556f85 139 errno = 0;
56be3814 140 regcache_raw_collect (regcache, regno, &val);
be0d2954
L
141 ptrace (PTRACE_POKEUSER, tid,
142 i386_linux_gregset_reg_offset[regno], val);
ce556f85 143 if (errno != 0)
c9f4d572 144 error (_("Couldn't write register %s (#%d): %s."),
875f8d0e 145 gdbarch_register_name (get_regcache_arch (regcache), regno),
ce556f85 146 regno, safe_strerror (errno));
f60300e7 147}
5c44784c 148\f
6ce2ac0b 149
04cd15b6
MK
150/* Transfering the general-purpose registers between GDB, inferiors
151 and core files. */
152
ad2a4d09 153/* Fill GDB's register array with the general-purpose register values
04cd15b6 154 in *GREGSETP. */
5c44784c 155
d4f3574e 156void
7f7fe91e 157supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
d4f3574e 158{
be0d2954 159 const gdb_byte *regp = (const gdb_byte *) gregsetp;
6ce2ac0b 160 int i;
d4f3574e 161
98df6387 162 for (i = 0; i < I386_NUM_GREGS; i++)
be0d2954
L
163 regcache_raw_supply (regcache, i,
164 regp + i386_linux_gregset_reg_offset[i]);
3fb1c838 165
875f8d0e
UW
166 if (I386_LINUX_ORIG_EAX_REGNUM
167 < gdbarch_num_regs (get_regcache_arch (regcache)))
1777feb0
MS
168 regcache_raw_supply (regcache, I386_LINUX_ORIG_EAX_REGNUM, regp
169 + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]);
917317f4
JM
170}
171
04cd15b6
MK
172/* Fill register REGNO (if it is a general-purpose register) in
173 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
174 do this for all registers. */
6ce2ac0b 175
917317f4 176void
7f7fe91e
UW
177fill_gregset (const struct regcache *regcache,
178 elf_gregset_t *gregsetp, int regno)
917317f4 179{
be0d2954 180 gdb_byte *regp = (gdb_byte *) gregsetp;
6ce2ac0b 181 int i;
04cd15b6 182
98df6387 183 for (i = 0; i < I386_NUM_GREGS; i++)
099a9414 184 if (regno == -1 || regno == i)
be0d2954
L
185 regcache_raw_collect (regcache, i,
186 regp + i386_linux_gregset_reg_offset[i]);
3fb1c838 187
82ea117a 188 if ((regno == -1 || regno == I386_LINUX_ORIG_EAX_REGNUM)
875f8d0e
UW
189 && I386_LINUX_ORIG_EAX_REGNUM
190 < gdbarch_num_regs (get_regcache_arch (regcache)))
1777feb0
MS
191 regcache_raw_collect (regcache, I386_LINUX_ORIG_EAX_REGNUM, regp
192 + i386_linux_gregset_reg_offset[I386_LINUX_ORIG_EAX_REGNUM]);
d4f3574e
SS
193}
194
f60300e7
MK
195#ifdef HAVE_PTRACE_GETREGS
196
04cd15b6
MK
197/* Fetch all general-purpose registers from process/thread TID and
198 store their values in GDB's register array. */
d4f3574e 199
5c44784c 200static void
56be3814 201fetch_regs (struct regcache *regcache, int tid)
5c44784c 202{
04cd15b6 203 elf_gregset_t regs;
2e024c20 204 elf_gregset_t *regs_p = &regs;
5c44784c 205
6ce2ac0b 206 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
5c44784c 207 {
f60300e7
MK
208 if (errno == EIO)
209 {
210 /* The kernel we're running on doesn't support the GETREGS
211 request. Reset `have_ptrace_getregs'. */
212 have_ptrace_getregs = 0;
213 return;
214 }
215
e2e0b3e5 216 perror_with_name (_("Couldn't get registers"));
5c44784c
JM
217 }
218
2e024c20 219 supply_gregset (regcache, (const elf_gregset_t *) regs_p);
5c44784c
JM
220}
221
04cd15b6
MK
222/* Store all valid general-purpose registers in GDB's register array
223 into the process/thread specified by TID. */
5c44784c 224
5c44784c 225static void
56be3814 226store_regs (const struct regcache *regcache, int tid, int regno)
5c44784c 227{
04cd15b6 228 elf_gregset_t regs;
5c44784c 229
6ce2ac0b 230 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 231 perror_with_name (_("Couldn't get registers"));
5c44784c 232
56be3814 233 fill_gregset (regcache, &regs, regno);
6ce2ac0b
MK
234
235 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 236 perror_with_name (_("Couldn't write registers"));
5c44784c
JM
237}
238
f60300e7
MK
239#else
240
56be3814
UW
241static void fetch_regs (struct regcache *regcache, int tid) {}
242static void store_regs (const struct regcache *regcache, int tid, int regno) {}
f60300e7
MK
243
244#endif
5c44784c 245\f
5c44784c 246
6ce2ac0b 247/* Transfering floating-point registers between GDB, inferiors and cores. */
d4f3574e 248
04cd15b6 249/* Fill GDB's register array with the floating-point register values in
917317f4 250 *FPREGSETP. */
04cd15b6 251
d4f3574e 252void
7f7fe91e 253supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
d4f3574e 254{
7f7fe91e 255 i387_supply_fsave (regcache, -1, fpregsetp);
917317f4 256}
d4f3574e 257
04cd15b6
MK
258/* Fill register REGNO (if it is a floating-point register) in
259 *FPREGSETP with the value in GDB's register array. If REGNO is -1,
260 do this for all registers. */
917317f4
JM
261
262void
7f7fe91e
UW
263fill_fpregset (const struct regcache *regcache,
264 elf_fpregset_t *fpregsetp, int regno)
917317f4 265{
7f7fe91e 266 i387_collect_fsave (regcache, regno, fpregsetp);
d4f3574e
SS
267}
268
f60300e7
MK
269#ifdef HAVE_PTRACE_GETREGS
270
04cd15b6
MK
271/* Fetch all floating-point registers from process/thread TID and store
272 thier values in GDB's register array. */
917317f4 273
d4f3574e 274static void
56be3814 275fetch_fpregs (struct regcache *regcache, int tid)
d4f3574e 276{
04cd15b6 277 elf_fpregset_t fpregs;
d4f3574e 278
6ce2ac0b 279 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 280 perror_with_name (_("Couldn't get floating point status"));
d4f3574e 281
56be3814 282 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
d4f3574e
SS
283}
284
04cd15b6
MK
285/* Store all valid floating-point registers in GDB's register array
286 into the process/thread specified by TID. */
d4f3574e 287
d4f3574e 288static void
56be3814 289store_fpregs (const struct regcache *regcache, int tid, int regno)
d4f3574e 290{
04cd15b6 291 elf_fpregset_t fpregs;
d4f3574e 292
6ce2ac0b 293 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 294 perror_with_name (_("Couldn't get floating point status"));
d4f3574e 295
56be3814 296 fill_fpregset (regcache, &fpregs, regno);
d4f3574e 297
6ce2ac0b 298 if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 299 perror_with_name (_("Couldn't write floating point status"));
d4f3574e
SS
300}
301
f60300e7
MK
302#else
303
1777feb0
MS
304static void
305fetch_fpregs (struct regcache *regcache, int tid)
306{
307}
308
309static void
310store_fpregs (const struct regcache *regcache, int tid, int regno)
311{
312}
f60300e7
MK
313
314#endif
5c44784c 315\f
d4f3574e 316
6ce2ac0b 317/* Transfering floating-point and SSE registers to and from GDB. */
11cf8741 318
c131fcee
L
319/* Fetch all registers covered by the PTRACE_GETREGSET request from
320 process/thread TID and store their values in GDB's register array.
321 Return non-zero if successful, zero otherwise. */
322
323static int
324fetch_xstateregs (struct regcache *regcache, int tid)
325{
df7e5265 326 char xstateregs[X86_XSTATE_MAX_SIZE];
c131fcee
L
327 struct iovec iov;
328
329 if (!have_ptrace_getregset)
330 return 0;
331
332 iov.iov_base = xstateregs;
333 iov.iov_len = sizeof(xstateregs);
334 if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE,
335 &iov) < 0)
336 perror_with_name (_("Couldn't read extended state status"));
337
338 i387_supply_xsave (regcache, -1, xstateregs);
339 return 1;
340}
341
342/* Store all valid registers in GDB's register array covered by the
343 PTRACE_SETREGSET request into the process/thread specified by TID.
344 Return non-zero if successful, zero otherwise. */
345
346static int
347store_xstateregs (const struct regcache *regcache, int tid, int regno)
348{
df7e5265 349 char xstateregs[X86_XSTATE_MAX_SIZE];
c131fcee
L
350 struct iovec iov;
351
352 if (!have_ptrace_getregset)
353 return 0;
354
355 iov.iov_base = xstateregs;
356 iov.iov_len = sizeof(xstateregs);
357 if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE,
358 &iov) < 0)
359 perror_with_name (_("Couldn't read extended state status"));
360
361 i387_collect_xsave (regcache, regno, xstateregs, 0);
362
363 if (ptrace (PTRACE_SETREGSET, tid, (unsigned int) NT_X86_XSTATE,
364 (int) &iov) < 0)
365 perror_with_name (_("Couldn't write extended state status"));
366
367 return 1;
368}
369
6ce2ac0b 370#ifdef HAVE_PTRACE_GETFPXREGS
04cd15b6 371
6ce2ac0b 372/* Fetch all registers covered by the PTRACE_GETFPXREGS request from
04cd15b6
MK
373 process/thread TID and store their values in GDB's register array.
374 Return non-zero if successful, zero otherwise. */
5c44784c 375
5c44784c 376static int
56be3814 377fetch_fpxregs (struct regcache *regcache, int tid)
5c44784c 378{
6ce2ac0b 379 elf_fpxregset_t fpxregs;
5c44784c 380
6ce2ac0b 381 if (! have_ptrace_getfpxregs)
5c44784c
JM
382 return 0;
383
6ce2ac0b 384 if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0)
d4f3574e 385 {
5c44784c
JM
386 if (errno == EIO)
387 {
6ce2ac0b 388 have_ptrace_getfpxregs = 0;
5c44784c
JM
389 return 0;
390 }
391
e2e0b3e5 392 perror_with_name (_("Couldn't read floating-point and SSE registers"));
d4f3574e
SS
393 }
394
b7a8b4ef 395 i387_supply_fxsave (regcache, -1, (const elf_fpxregset_t *) &fpxregs);
5c44784c
JM
396 return 1;
397}
d4f3574e 398
04cd15b6 399/* Store all valid registers in GDB's register array covered by the
6ce2ac0b 400 PTRACE_SETFPXREGS request into the process/thread specified by TID.
04cd15b6 401 Return non-zero if successful, zero otherwise. */
5c44784c 402
5c44784c 403static int
56be3814 404store_fpxregs (const struct regcache *regcache, int tid, int regno)
5c44784c 405{
6ce2ac0b 406 elf_fpxregset_t fpxregs;
5c44784c 407
6ce2ac0b 408 if (! have_ptrace_getfpxregs)
5c44784c 409 return 0;
6ce2ac0b
MK
410
411 if (ptrace (PTRACE_GETFPXREGS, tid, 0, &fpxregs) == -1)
2866d305
MK
412 {
413 if (errno == EIO)
414 {
415 have_ptrace_getfpxregs = 0;
416 return 0;
417 }
418
e2e0b3e5 419 perror_with_name (_("Couldn't read floating-point and SSE registers"));
2866d305 420 }
5c44784c 421
b7a8b4ef 422 i387_collect_fxsave (regcache, regno, &fpxregs);
5c44784c 423
6ce2ac0b 424 if (ptrace (PTRACE_SETFPXREGS, tid, 0, &fpxregs) == -1)
e2e0b3e5 425 perror_with_name (_("Couldn't write floating-point and SSE registers"));
5c44784c
JM
426
427 return 1;
428}
429
5c44784c
JM
430#else
431
1777feb0
MS
432static int
433fetch_fpxregs (struct regcache *regcache, int tid)
434{
435 return 0;
436}
437
438static int
439store_fpxregs (const struct regcache *regcache, int tid, int regno)
440{
441 return 0;
442}
5c44784c 443
6ce2ac0b 444#endif /* HAVE_PTRACE_GETFPXREGS */
5c44784c 445\f
6ce2ac0b 446
5c44784c 447/* Transferring arbitrary registers between GDB and inferior. */
d4f3574e 448
04cd15b6
MK
449/* Fetch register REGNO from the child process. If REGNO is -1, do
450 this for all registers (including the floating point and SSE
451 registers). */
d4f3574e 452
10d6c8cd 453static void
28439f5e
PA
454i386_linux_fetch_inferior_registers (struct target_ops *ops,
455 struct regcache *regcache, int regno)
d4f3574e 456{
ed9a39eb
JM
457 int tid;
458
f60300e7
MK
459 /* Use the old method of peeking around in `struct user' if the
460 GETREGS request isn't available. */
ce556f85 461 if (!have_ptrace_getregs)
f60300e7 462 {
ce556f85
MK
463 int i;
464
875f8d0e 465 for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
ce556f85 466 if (regno == -1 || regno == i)
56be3814 467 fetch_register (regcache, i);
ce556f85 468
f60300e7
MK
469 return;
470 }
471
a4b6fc86 472 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 473 tid = ptid_get_lwp (inferior_ptid);
e64a344c 474 if (tid == 0)
dfd4cc63 475 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
ed9a39eb 476
6ce2ac0b 477 /* Use the PTRACE_GETFPXREGS request whenever possible, since it
04cd15b6 478 transfers more registers in one system call, and we'll cache the
6ce2ac0b 479 results. But remember that fetch_fpxregs can fail, and return
04cd15b6 480 zero. */
5c44784c
JM
481 if (regno == -1)
482 {
56be3814 483 fetch_regs (regcache, tid);
f60300e7
MK
484
485 /* The call above might reset `have_ptrace_getregs'. */
ce556f85 486 if (!have_ptrace_getregs)
f60300e7 487 {
84e473c8 488 i386_linux_fetch_inferior_registers (ops, regcache, regno);
f60300e7
MK
489 return;
490 }
491
c131fcee
L
492 if (fetch_xstateregs (regcache, tid))
493 return;
56be3814 494 if (fetch_fpxregs (regcache, tid))
5c44784c 495 return;
56be3814 496 fetch_fpregs (regcache, tid);
5c44784c
JM
497 return;
498 }
d4f3574e 499
5c44784c
JM
500 if (GETREGS_SUPPLIES (regno))
501 {
56be3814 502 fetch_regs (regcache, tid);
5c44784c
JM
503 return;
504 }
505
c131fcee
L
506 if (GETXSTATEREGS_SUPPLIES (regno))
507 {
508 if (fetch_xstateregs (regcache, tid))
509 return;
510 }
511
6ce2ac0b 512 if (GETFPXREGS_SUPPLIES (regno))
5c44784c 513 {
56be3814 514 if (fetch_fpxregs (regcache, tid))
5c44784c
JM
515 return;
516
517 /* Either our processor or our kernel doesn't support the SSE
518 registers, so read the FP registers in the traditional way,
519 and fill the SSE registers with dummy values. It would be
520 more graceful to handle differences in the register set using
521 gdbarch. Until then, this will at least make things work
522 plausibly. */
56be3814 523 fetch_fpregs (regcache, tid);
5c44784c
JM
524 return;
525 }
526
8e65ff28 527 internal_error (__FILE__, __LINE__,
e2e0b3e5 528 _("Got request for bad register number %d."), regno);
d4f3574e
SS
529}
530
04cd15b6
MK
531/* Store register REGNO back into the child process. If REGNO is -1,
532 do this for all registers (including the floating point and SSE
533 registers). */
10d6c8cd 534static void
28439f5e
PA
535i386_linux_store_inferior_registers (struct target_ops *ops,
536 struct regcache *regcache, int regno)
d4f3574e 537{
ed9a39eb
JM
538 int tid;
539
f60300e7
MK
540 /* Use the old method of poking around in `struct user' if the
541 SETREGS request isn't available. */
ce556f85 542 if (!have_ptrace_getregs)
f60300e7 543 {
ce556f85
MK
544 int i;
545
875f8d0e 546 for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
ce556f85 547 if (regno == -1 || regno == i)
56be3814 548 store_register (regcache, i);
ce556f85 549
f60300e7
MK
550 return;
551 }
552
a4b6fc86 553 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 554 tid = ptid_get_lwp (inferior_ptid);
e64a344c 555 if (tid == 0)
dfd4cc63 556 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
ed9a39eb 557
6ce2ac0b 558 /* Use the PTRACE_SETFPXREGS requests whenever possible, since it
04cd15b6 559 transfers more registers in one system call. But remember that
6ce2ac0b 560 store_fpxregs can fail, and return zero. */
5c44784c
JM
561 if (regno == -1)
562 {
56be3814 563 store_regs (regcache, tid, regno);
c131fcee
L
564 if (store_xstateregs (regcache, tid, regno))
565 return;
56be3814 566 if (store_fpxregs (regcache, tid, regno))
5c44784c 567 return;
56be3814 568 store_fpregs (regcache, tid, regno);
5c44784c
JM
569 return;
570 }
d4f3574e 571
5c44784c
JM
572 if (GETREGS_SUPPLIES (regno))
573 {
56be3814 574 store_regs (regcache, tid, regno);
5c44784c
JM
575 return;
576 }
577
c131fcee
L
578 if (GETXSTATEREGS_SUPPLIES (regno))
579 {
580 if (store_xstateregs (regcache, tid, regno))
581 return;
582 }
583
6ce2ac0b 584 if (GETFPXREGS_SUPPLIES (regno))
5c44784c 585 {
56be3814 586 if (store_fpxregs (regcache, tid, regno))
5c44784c
JM
587 return;
588
589 /* Either our processor or our kernel doesn't support the SSE
04cd15b6
MK
590 registers, so just write the FP registers in the traditional
591 way. */
56be3814 592 store_fpregs (regcache, tid, regno);
5c44784c
JM
593 return;
594 }
595
8e65ff28 596 internal_error (__FILE__, __LINE__,
e2e0b3e5 597 _("Got request to store bad register number %d."), regno);
d4f3574e 598}
de57eccd 599\f
6ce2ac0b 600
8c420b8d
GB
601/* Called by libthread_db. Returns a pointer to the thread local
602 storage (or its descriptor). */
603
604ps_err_e
605ps_get_thread_area (const struct ps_prochandle *ph,
606 lwpid_t lwpid, int idx, void **base)
607{
608 unsigned int base_addr;
609 ps_err_e result;
610
611 result = x86_linux_get_thread_area (lwpid, (void *) idx, &base_addr);
612
613 if (result == PS_OK)
614 *(int *) base = base_addr;
615
616 return result;
617}
5bca7895
MK
618\f
619
a4b6fc86 620/* The instruction for a GNU/Linux system call is:
a6abb2c0
MK
621 int $0x80
622 or 0xcd 0x80. */
623
624static const unsigned char linux_syscall[] = { 0xcd, 0x80 };
625
626#define LINUX_SYSCALL_LEN (sizeof linux_syscall)
627
628/* The system call number is stored in the %eax register. */
7532965f 629#define LINUX_SYSCALL_REGNUM I386_EAX_REGNUM
a6abb2c0
MK
630
631/* We are specifically interested in the sigreturn and rt_sigreturn
632 system calls. */
633
634#ifndef SYS_sigreturn
635#define SYS_sigreturn 0x77
636#endif
637#ifndef SYS_rt_sigreturn
638#define SYS_rt_sigreturn 0xad
639#endif
640
641/* Offset to saved processor flags, from <asm/sigcontext.h>. */
642#define LINUX_SIGCONTEXT_EFLAGS_OFFSET (64)
643
644/* Resume execution of the inferior process.
645 If STEP is nonzero, single-step it.
646 If SIGNAL is nonzero, give it that signal. */
647
10d6c8cd 648static void
28439f5e 649i386_linux_resume (struct target_ops *ops,
2ea28649 650 ptid_t ptid, int step, enum gdb_signal signal)
a6abb2c0 651{
90ad5e1d 652 int pid = ptid_get_lwp (ptid);
a96d9b2e
SDJ
653 int request;
654
655 if (catch_syscall_enabled () > 0)
656 request = PTRACE_SYSCALL;
657 else
658 request = PTRACE_CONT;
a6abb2c0 659
a6abb2c0
MK
660 if (step)
661 {
90ad5e1d 662 struct regcache *regcache = get_thread_regcache (ptid);
e17a4113
UW
663 struct gdbarch *gdbarch = get_regcache_arch (regcache);
664 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
7b86a1b8 665 ULONGEST pc;
8e70166d 666 gdb_byte buf[LINUX_SYSCALL_LEN];
a6abb2c0
MK
667
668 request = PTRACE_SINGLESTEP;
669
e17a4113
UW
670 regcache_cooked_read_unsigned (regcache,
671 gdbarch_pc_regnum (gdbarch), &pc);
7b86a1b8 672
a6abb2c0
MK
673 /* Returning from a signal trampoline is done by calling a
674 special system call (sigreturn or rt_sigreturn, see
675 i386-linux-tdep.c for more information). This system call
676 restores the registers that were saved when the signal was
677 raised, including %eflags. That means that single-stepping
678 won't work. Instead, we'll have to modify the signal context
679 that's about to be restored, and set the trace flag there. */
680
681 /* First check if PC is at a system call. */
8defab1a 682 if (target_read_memory (pc, buf, LINUX_SYSCALL_LEN) == 0
a6abb2c0
MK
683 && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0)
684 {
7b86a1b8
UW
685 ULONGEST syscall;
686 regcache_cooked_read_unsigned (regcache,
687 LINUX_SYSCALL_REGNUM, &syscall);
a6abb2c0
MK
688
689 /* Then check the system call number. */
690 if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn)
691 {
7b86a1b8 692 ULONGEST sp, addr;
a6abb2c0 693 unsigned long int eflags;
7bf0983e 694
7b86a1b8 695 regcache_cooked_read_unsigned (regcache, I386_ESP_REGNUM, &sp);
a6abb2c0 696 if (syscall == SYS_rt_sigreturn)
f3d6df6d
YQ
697 addr = read_memory_unsigned_integer (sp + 8, 4, byte_order)
698 + 20;
7b86a1b8
UW
699 else
700 addr = sp;
a6abb2c0
MK
701
702 /* Set the trace flag in the context that's about to be
703 restored. */
704 addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET;
8e70166d 705 read_memory (addr, (gdb_byte *) &eflags, 4);
a6abb2c0 706 eflags |= 0x0100;
8e70166d 707 write_memory (addr, (gdb_byte *) &eflags, 4);
a6abb2c0
MK
708 }
709 }
710 }
711
2ea28649 712 if (ptrace (request, pid, 0, gdb_signal_to_host (signal)) == -1)
e2e0b3e5 713 perror_with_name (("ptrace"));
a6abb2c0 714}
040baaf6 715\f
c1e246a0
GB
716
717/* -Wmissing-prototypes */
718extern initialize_file_ftype _initialize_i386_linux_nat;
719
720void
721_initialize_i386_linux_nat (void)
722{
723 /* Create a generic x86 GNU/Linux target. */
724 struct target_ops *t = x86_linux_create_target ();
725
726 /* Override the default ptrace resume method. */
727 t->to_resume = i386_linux_resume;
728
729 /* Add our register access methods. */
730 t->to_fetch_registers = i386_linux_fetch_inferior_registers;
731 t->to_store_registers = i386_linux_store_inferior_registers;
732
733 /* Add the target. */
734 x86_linux_add_target (t);
735}
This page took 1.202838 seconds and 4 git commands to generate.