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