Commit | Line | Data |
---|---|---|
6ce2ac0b | 1 | /* Native-dependent code for Linux/x86. |
8e65ff28 | 2 | Copyright 1999, 2000, 2001 Free Software Foundation, Inc. |
d4f3574e | 3 | |
04cd15b6 | 4 | This file is part of GDB. |
d4f3574e | 5 | |
04cd15b6 MK |
6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2 of the License, or | |
9 | (at your option) any later version. | |
d4f3574e | 10 | |
04cd15b6 MK |
11 | This program is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
d4f3574e | 15 | |
04cd15b6 MK |
16 | You should have received a copy of the GNU General Public License |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, Inc., 59 Temple Place - Suite 330, | |
19 | Boston, MA 02111-1307, USA. */ | |
d4f3574e SS |
20 | |
21 | #include "defs.h" | |
22 | #include "inferior.h" | |
23 | #include "gdbcore.h" | |
4e052eda | 24 | #include "regcache.h" |
d4f3574e | 25 | |
d4f3574e SS |
26 | #include <sys/ptrace.h> |
27 | #include <sys/user.h> | |
28 | #include <sys/procfs.h> | |
29 | ||
30 | #ifdef HAVE_SYS_REG_H | |
31 | #include <sys/reg.h> | |
32 | #endif | |
33 | ||
6ce2ac0b | 34 | /* Prototypes for supply_gregset etc. */ |
c60c0f5f MS |
35 | #include "gregset.h" |
36 | ||
6ce2ac0b MK |
37 | /* Prototypes for i387_supply_fsave etc. */ |
38 | #include "i387-nat.h" | |
39 | ||
756ed206 MK |
40 | /* Prototypes for local functions. */ |
41 | static void dummy_sse_values (void); | |
42 | ||
04cd15b6 MK |
43 | /* On Linux, threads are implemented as pseudo-processes, in which |
44 | case we may be tracing more than one process at a time. In that | |
45 | case, inferior_pid will contain the main process ID and the | |
46 | individual thread (process) ID mashed together. These macros are | |
47 | used to separate them out. These definitions should be overridden | |
48 | if thread support is included. */ | |
ed9a39eb JM |
49 | |
50 | #if !defined (PIDGET) /* Default definition for PIDGET/TIDGET. */ | |
51 | #define PIDGET(PID) PID | |
52 | #define TIDGET(PID) 0 | |
53 | #endif | |
6ce2ac0b | 54 | \f |
d4f3574e | 55 | |
04cd15b6 MK |
56 | /* The register sets used in Linux ELF core-dumps are identical to the |
57 | register sets in `struct user' that is used for a.out core-dumps, | |
58 | and is also used by `ptrace'. The corresponding types are | |
59 | `elf_gregset_t' for the general-purpose registers (with | |
60 | `elf_greg_t' the type of a single GP register) and `elf_fpregset_t' | |
61 | for the floating-point registers. | |
62 | ||
63 | Those types used to be available under the names `gregset_t' and | |
64 | `fpregset_t' too, and this file used those names in the past. But | |
65 | those names are now used for the register sets used in the | |
66 | `mcontext_t' type, and have a different size and layout. */ | |
67 | ||
68 | /* Mapping between the general-purpose registers in `struct user' | |
69 | format and GDB's register array layout. */ | |
d4f3574e SS |
70 | static int regmap[] = |
71 | { | |
72 | EAX, ECX, EDX, EBX, | |
73 | UESP, EBP, ESI, EDI, | |
74 | EIP, EFL, CS, SS, | |
04cd15b6 | 75 | DS, ES, FS, GS |
d4f3574e SS |
76 | }; |
77 | ||
5c44784c JM |
78 | /* Which ptrace request retrieves which registers? |
79 | These apply to the corresponding SET requests as well. */ | |
80 | #define GETREGS_SUPPLIES(regno) \ | |
81 | (0 <= (regno) && (regno) <= 15) | |
82 | #define GETFPREGS_SUPPLIES(regno) \ | |
83 | (FP0_REGNUM <= (regno) && (regno) <= LAST_FPU_CTRL_REGNUM) | |
6ce2ac0b | 84 | #define GETFPXREGS_SUPPLIES(regno) \ |
5c44784c JM |
85 | (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM) |
86 | ||
f60300e7 MK |
87 | /* Does the current host support the GETREGS request? */ |
88 | int have_ptrace_getregs = | |
89 | #ifdef HAVE_PTRACE_GETREGS | |
90 | 1 | |
91 | #else | |
92 | 0 | |
93 | #endif | |
94 | ; | |
95 | ||
6ce2ac0b | 96 | /* Does the current host support the GETFPXREGS request? The header |
5c44784c JM |
97 | file may or may not define it, and even if it is defined, the |
98 | kernel will return EIO if it's running on a pre-SSE processor. | |
99 | ||
100 | My instinct is to attach this to some architecture- or | |
101 | target-specific data structure, but really, a particular GDB | |
102 | process can only run on top of one kernel at a time. So it's okay | |
103 | for this to be a simple variable. */ | |
6ce2ac0b MK |
104 | int have_ptrace_getfpxregs = |
105 | #ifdef HAVE_PTRACE_GETFPXREGS | |
5c44784c JM |
106 | 1 |
107 | #else | |
108 | 0 | |
109 | #endif | |
110 | ; | |
f60300e7 | 111 | \f |
6ce2ac0b | 112 | |
97780f5f JB |
113 | /* Fetching registers directly from the U area, one at a time. */ |
114 | ||
f60300e7 MK |
115 | /* FIXME: kettenis/2000-03-05: This duplicates code from `inptrace.c'. |
116 | The problem is that we define FETCH_INFERIOR_REGISTERS since we | |
117 | want to use our own versions of {fetch,store}_inferior_registers | |
118 | that use the GETREGS request. This means that the code in | |
119 | `infptrace.c' is #ifdef'd out. But we need to fall back on that | |
120 | code when GDB is running on top of a kernel that doesn't support | |
121 | the GETREGS request. I want to avoid changing `infptrace.c' right | |
122 | now. */ | |
123 | ||
318b21ef MK |
124 | #ifndef PT_READ_U |
125 | #define PT_READ_U PTRACE_PEEKUSR | |
126 | #endif | |
127 | #ifndef PT_WRITE_U | |
128 | #define PT_WRITE_U PTRACE_POKEUSR | |
129 | #endif | |
130 | ||
f60300e7 MK |
131 | /* Default the type of the ptrace transfer to int. */ |
132 | #ifndef PTRACE_XFER_TYPE | |
133 | #define PTRACE_XFER_TYPE int | |
134 | #endif | |
135 | ||
136 | /* Registers we shouldn't try to fetch. */ | |
d5d65353 | 137 | #define OLD_CANNOT_FETCH_REGISTER(regno) ((regno) >= NUM_GREGS) |
f60300e7 MK |
138 | |
139 | /* Fetch one register. */ | |
140 | ||
141 | static void | |
fba45db2 | 142 | fetch_register (int regno) |
f60300e7 MK |
143 | { |
144 | /* This isn't really an address. But ptrace thinks of it as one. */ | |
145 | CORE_ADDR regaddr; | |
146 | char mess[128]; /* For messages */ | |
147 | register int i; | |
148 | unsigned int offset; /* Offset of registers within the u area. */ | |
149 | char buf[MAX_REGISTER_RAW_SIZE]; | |
150 | int tid; | |
151 | ||
d5d65353 | 152 | if (OLD_CANNOT_FETCH_REGISTER (regno)) |
f60300e7 MK |
153 | { |
154 | memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */ | |
155 | supply_register (regno, buf); | |
156 | return; | |
157 | } | |
158 | ||
159 | /* Overload thread id onto process id */ | |
160 | if ((tid = TIDGET (inferior_pid)) == 0) | |
161 | tid = inferior_pid; /* no thread id, just use process id */ | |
162 | ||
163 | offset = U_REGS_OFFSET; | |
164 | ||
165 | regaddr = register_addr (regno, offset); | |
166 | for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) | |
167 | { | |
168 | errno = 0; | |
169 | *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid, | |
170 | (PTRACE_ARG3_TYPE) regaddr, 0); | |
171 | regaddr += sizeof (PTRACE_XFER_TYPE); | |
172 | if (errno != 0) | |
173 | { | |
174 | sprintf (mess, "reading register %s (#%d)", | |
175 | REGISTER_NAME (regno), regno); | |
176 | perror_with_name (mess); | |
177 | } | |
178 | } | |
179 | supply_register (regno, buf); | |
180 | } | |
181 | ||
182 | /* Fetch register values from the inferior. | |
183 | If REGNO is negative, do this for all registers. | |
184 | Otherwise, REGNO specifies which register (so we can save time). */ | |
185 | ||
186 | void | |
fba45db2 | 187 | old_fetch_inferior_registers (int regno) |
f60300e7 MK |
188 | { |
189 | if (regno >= 0) | |
190 | { | |
191 | fetch_register (regno); | |
192 | } | |
193 | else | |
194 | { | |
a728f042 | 195 | for (regno = 0; regno < NUM_REGS; regno++) |
f60300e7 MK |
196 | { |
197 | fetch_register (regno); | |
198 | } | |
199 | } | |
200 | } | |
201 | ||
202 | /* Registers we shouldn't try to store. */ | |
d5d65353 | 203 | #define OLD_CANNOT_STORE_REGISTER(regno) ((regno) >= NUM_GREGS) |
f60300e7 MK |
204 | |
205 | /* Store one register. */ | |
206 | ||
207 | static void | |
fba45db2 | 208 | store_register (int regno) |
f60300e7 MK |
209 | { |
210 | /* This isn't really an address. But ptrace thinks of it as one. */ | |
211 | CORE_ADDR regaddr; | |
212 | char mess[128]; /* For messages */ | |
213 | register int i; | |
214 | unsigned int offset; /* Offset of registers within the u area. */ | |
215 | int tid; | |
216 | ||
d5d65353 | 217 | if (OLD_CANNOT_STORE_REGISTER (regno)) |
f60300e7 MK |
218 | { |
219 | return; | |
220 | } | |
221 | ||
222 | /* Overload thread id onto process id */ | |
223 | if ((tid = TIDGET (inferior_pid)) == 0) | |
224 | tid = inferior_pid; /* no thread id, just use process id */ | |
225 | ||
226 | offset = U_REGS_OFFSET; | |
227 | ||
228 | regaddr = register_addr (regno, offset); | |
229 | for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) | |
230 | { | |
231 | errno = 0; | |
232 | ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr, | |
233 | *(PTRACE_XFER_TYPE *) & registers[REGISTER_BYTE (regno) + i]); | |
234 | regaddr += sizeof (PTRACE_XFER_TYPE); | |
235 | if (errno != 0) | |
236 | { | |
237 | sprintf (mess, "writing register %s (#%d)", | |
238 | REGISTER_NAME (regno), regno); | |
239 | perror_with_name (mess); | |
240 | } | |
241 | } | |
242 | } | |
243 | ||
244 | /* Store our register values back into the inferior. | |
245 | If REGNO is negative, do this for all registers. | |
246 | Otherwise, REGNO specifies which register (so we can save time). */ | |
247 | ||
248 | void | |
fba45db2 | 249 | old_store_inferior_registers (int regno) |
f60300e7 MK |
250 | { |
251 | if (regno >= 0) | |
252 | { | |
253 | store_register (regno); | |
254 | } | |
255 | else | |
256 | { | |
a728f042 | 257 | for (regno = 0; regno < NUM_REGS; regno++) |
f60300e7 MK |
258 | { |
259 | store_register (regno); | |
260 | } | |
261 | } | |
262 | } | |
5c44784c | 263 | \f |
6ce2ac0b | 264 | |
04cd15b6 MK |
265 | /* Transfering the general-purpose registers between GDB, inferiors |
266 | and core files. */ | |
267 | ||
ad2a4d09 | 268 | /* Fill GDB's register array with the general-purpose register values |
04cd15b6 | 269 | in *GREGSETP. */ |
5c44784c | 270 | |
d4f3574e | 271 | void |
04cd15b6 | 272 | supply_gregset (elf_gregset_t *gregsetp) |
d4f3574e | 273 | { |
04cd15b6 | 274 | elf_greg_t *regp = (elf_greg_t *) gregsetp; |
6ce2ac0b | 275 | int i; |
d4f3574e | 276 | |
6ce2ac0b MK |
277 | for (i = 0; i < NUM_GREGS; i++) |
278 | supply_register (i, (char *) (regp + regmap[i])); | |
917317f4 JM |
279 | } |
280 | ||
04cd15b6 MK |
281 | /* Fill register REGNO (if it is a general-purpose register) in |
282 | *GREGSETPS with the value in GDB's register array. If REGNO is -1, | |
283 | do this for all registers. */ | |
6ce2ac0b | 284 | |
917317f4 | 285 | void |
04cd15b6 | 286 | fill_gregset (elf_gregset_t *gregsetp, int regno) |
917317f4 | 287 | { |
6ce2ac0b MK |
288 | elf_greg_t *regp = (elf_greg_t *) gregsetp; |
289 | int i; | |
04cd15b6 | 290 | |
6ce2ac0b MK |
291 | for (i = 0; i < NUM_GREGS; i++) |
292 | if ((regno == -1 || regno == i)) | |
293 | *(regp + regmap[i]) = *(elf_greg_t *) ®isters[REGISTER_BYTE (i)]; | |
d4f3574e SS |
294 | } |
295 | ||
f60300e7 MK |
296 | #ifdef HAVE_PTRACE_GETREGS |
297 | ||
04cd15b6 MK |
298 | /* Fetch all general-purpose registers from process/thread TID and |
299 | store their values in GDB's register array. */ | |
d4f3574e | 300 | |
5c44784c | 301 | static void |
ed9a39eb | 302 | fetch_regs (int tid) |
5c44784c | 303 | { |
04cd15b6 | 304 | elf_gregset_t regs; |
5c44784c | 305 | |
6ce2ac0b | 306 | if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0) |
5c44784c | 307 | { |
f60300e7 MK |
308 | if (errno == EIO) |
309 | { | |
310 | /* The kernel we're running on doesn't support the GETREGS | |
311 | request. Reset `have_ptrace_getregs'. */ | |
312 | have_ptrace_getregs = 0; | |
313 | return; | |
314 | } | |
315 | ||
6ce2ac0b | 316 | perror_with_name ("Couldn't get registers"); |
5c44784c JM |
317 | } |
318 | ||
04cd15b6 | 319 | supply_gregset (®s); |
5c44784c JM |
320 | } |
321 | ||
04cd15b6 MK |
322 | /* Store all valid general-purpose registers in GDB's register array |
323 | into the process/thread specified by TID. */ | |
5c44784c | 324 | |
5c44784c | 325 | static void |
6ce2ac0b | 326 | store_regs (int tid, int regno) |
5c44784c | 327 | { |
04cd15b6 | 328 | elf_gregset_t regs; |
5c44784c | 329 | |
6ce2ac0b MK |
330 | if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0) |
331 | perror_with_name ("Couldn't get registers"); | |
5c44784c | 332 | |
6ce2ac0b MK |
333 | fill_gregset (®s, regno); |
334 | ||
335 | if (ptrace (PTRACE_SETREGS, tid, 0, (int) ®s) < 0) | |
336 | perror_with_name ("Couldn't write registers"); | |
5c44784c JM |
337 | } |
338 | ||
f60300e7 MK |
339 | #else |
340 | ||
341 | static void fetch_regs (int tid) {} | |
6ce2ac0b | 342 | static void store_regs (int tid, int regno) {} |
f60300e7 MK |
343 | |
344 | #endif | |
5c44784c | 345 | \f |
5c44784c | 346 | |
6ce2ac0b | 347 | /* Transfering floating-point registers between GDB, inferiors and cores. */ |
d4f3574e | 348 | |
04cd15b6 | 349 | /* Fill GDB's register array with the floating-point register values in |
917317f4 | 350 | *FPREGSETP. */ |
04cd15b6 | 351 | |
d4f3574e | 352 | void |
04cd15b6 | 353 | supply_fpregset (elf_fpregset_t *fpregsetp) |
d4f3574e | 354 | { |
6ce2ac0b | 355 | i387_supply_fsave ((char *) fpregsetp); |
756ed206 | 356 | dummy_sse_values (); |
917317f4 | 357 | } |
d4f3574e | 358 | |
04cd15b6 MK |
359 | /* Fill register REGNO (if it is a floating-point register) in |
360 | *FPREGSETP with the value in GDB's register array. If REGNO is -1, | |
361 | do this for all registers. */ | |
917317f4 JM |
362 | |
363 | void | |
04cd15b6 | 364 | fill_fpregset (elf_fpregset_t *fpregsetp, int regno) |
917317f4 | 365 | { |
6ce2ac0b | 366 | i387_fill_fsave ((char *) fpregsetp, regno); |
d4f3574e SS |
367 | } |
368 | ||
f60300e7 MK |
369 | #ifdef HAVE_PTRACE_GETREGS |
370 | ||
04cd15b6 MK |
371 | /* Fetch all floating-point registers from process/thread TID and store |
372 | thier values in GDB's register array. */ | |
917317f4 | 373 | |
d4f3574e | 374 | static void |
ed9a39eb | 375 | fetch_fpregs (int tid) |
d4f3574e | 376 | { |
04cd15b6 | 377 | elf_fpregset_t fpregs; |
d4f3574e | 378 | |
6ce2ac0b MK |
379 | if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0) |
380 | perror_with_name ("Couldn't get floating point status"); | |
d4f3574e | 381 | |
04cd15b6 | 382 | supply_fpregset (&fpregs); |
d4f3574e SS |
383 | } |
384 | ||
04cd15b6 MK |
385 | /* Store all valid floating-point registers in GDB's register array |
386 | into the process/thread specified by TID. */ | |
d4f3574e | 387 | |
d4f3574e | 388 | static void |
6ce2ac0b | 389 | store_fpregs (int tid, int regno) |
d4f3574e | 390 | { |
04cd15b6 | 391 | elf_fpregset_t fpregs; |
d4f3574e | 392 | |
6ce2ac0b MK |
393 | if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0) |
394 | perror_with_name ("Couldn't get floating point status"); | |
d4f3574e | 395 | |
6ce2ac0b | 396 | fill_fpregset (&fpregs, regno); |
d4f3574e | 397 | |
6ce2ac0b MK |
398 | if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0) |
399 | perror_with_name ("Couldn't write floating point status"); | |
d4f3574e SS |
400 | } |
401 | ||
f60300e7 MK |
402 | #else |
403 | ||
404 | static void fetch_fpregs (int tid) {} | |
6ce2ac0b | 405 | static void store_fpregs (int tid, int regno) {} |
f60300e7 MK |
406 | |
407 | #endif | |
5c44784c | 408 | \f |
d4f3574e | 409 | |
6ce2ac0b | 410 | /* Transfering floating-point and SSE registers to and from GDB. */ |
11cf8741 | 411 | |
6ce2ac0b | 412 | #ifdef HAVE_PTRACE_GETFPXREGS |
04cd15b6 MK |
413 | |
414 | /* Fill GDB's register array with the floating-point and SSE register | |
6ce2ac0b | 415 | values in *FPXREGSETP. */ |
04cd15b6 | 416 | |
d4f3574e | 417 | static void |
6ce2ac0b | 418 | supply_fpxregset (elf_fpxregset_t *fpxregsetp) |
d4f3574e | 419 | { |
6ce2ac0b | 420 | i387_supply_fxsave ((char *) fpxregsetp); |
d4f3574e SS |
421 | } |
422 | ||
6ce2ac0b MK |
423 | /* Fill register REGNO (if it is a floating-point or SSE register) in |
424 | *FPXREGSETP with the value in GDB's register array. If REGNO is | |
425 | -1, do this for all registers. */ | |
d4f3574e | 426 | |
d4f3574e | 427 | static void |
6ce2ac0b | 428 | fill_fpxregset (elf_fpxregset_t *fpxregsetp, int regno) |
d4f3574e | 429 | { |
6ce2ac0b | 430 | i387_fill_fxsave ((char *) fpxregsetp, regno); |
5c44784c JM |
431 | } |
432 | ||
6ce2ac0b | 433 | /* Fetch all registers covered by the PTRACE_GETFPXREGS request from |
04cd15b6 MK |
434 | process/thread TID and store their values in GDB's register array. |
435 | Return non-zero if successful, zero otherwise. */ | |
5c44784c | 436 | |
5c44784c | 437 | static int |
6ce2ac0b | 438 | fetch_fpxregs (int tid) |
5c44784c | 439 | { |
6ce2ac0b | 440 | elf_fpxregset_t fpxregs; |
5c44784c | 441 | |
6ce2ac0b | 442 | if (! have_ptrace_getfpxregs) |
5c44784c JM |
443 | return 0; |
444 | ||
6ce2ac0b | 445 | if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0) |
d4f3574e | 446 | { |
5c44784c JM |
447 | if (errno == EIO) |
448 | { | |
6ce2ac0b | 449 | have_ptrace_getfpxregs = 0; |
5c44784c JM |
450 | return 0; |
451 | } | |
452 | ||
6ce2ac0b | 453 | perror_with_name ("Couldn't read floating-point and SSE registers"); |
d4f3574e SS |
454 | } |
455 | ||
6ce2ac0b | 456 | supply_fpxregset (&fpxregs); |
5c44784c JM |
457 | return 1; |
458 | } | |
d4f3574e | 459 | |
04cd15b6 | 460 | /* Store all valid registers in GDB's register array covered by the |
6ce2ac0b | 461 | PTRACE_SETFPXREGS request into the process/thread specified by TID. |
04cd15b6 | 462 | Return non-zero if successful, zero otherwise. */ |
5c44784c | 463 | |
5c44784c | 464 | static int |
6ce2ac0b | 465 | store_fpxregs (int tid, int regno) |
5c44784c | 466 | { |
6ce2ac0b | 467 | elf_fpxregset_t fpxregs; |
5c44784c | 468 | |
6ce2ac0b | 469 | if (! have_ptrace_getfpxregs) |
5c44784c | 470 | return 0; |
6ce2ac0b MK |
471 | |
472 | if (ptrace (PTRACE_GETFPXREGS, tid, 0, &fpxregs) == -1) | |
2866d305 MK |
473 | { |
474 | if (errno == EIO) | |
475 | { | |
476 | have_ptrace_getfpxregs = 0; | |
477 | return 0; | |
478 | } | |
479 | ||
480 | perror_with_name ("Couldn't read floating-point and SSE registers"); | |
481 | } | |
5c44784c | 482 | |
6ce2ac0b | 483 | fill_fpxregset (&fpxregs, regno); |
5c44784c | 484 | |
6ce2ac0b MK |
485 | if (ptrace (PTRACE_SETFPXREGS, tid, 0, &fpxregs) == -1) |
486 | perror_with_name ("Couldn't write floating-point and SSE registers"); | |
5c44784c JM |
487 | |
488 | return 1; | |
489 | } | |
490 | ||
04cd15b6 | 491 | /* Fill the XMM registers in the register array with dummy values. For |
5c44784c JM |
492 | cases where we don't have access to the XMM registers. I think |
493 | this is cleaner than printing a warning. For a cleaner solution, | |
494 | we should gdbarchify the i386 family. */ | |
04cd15b6 | 495 | |
5c44784c | 496 | static void |
04cd15b6 | 497 | dummy_sse_values (void) |
5c44784c JM |
498 | { |
499 | /* C doesn't have a syntax for NaN's, so write it out as an array of | |
500 | longs. */ | |
501 | static long dummy[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; | |
502 | static long mxcsr = 0x1f80; | |
503 | int reg; | |
504 | ||
505 | for (reg = 0; reg < 8; reg++) | |
506 | supply_register (XMM0_REGNUM + reg, (char *) dummy); | |
507 | supply_register (MXCSR_REGNUM, (char *) &mxcsr); | |
d4f3574e SS |
508 | } |
509 | ||
5c44784c JM |
510 | #else |
511 | ||
f0373401 MK |
512 | static int fetch_fpxregs (int tid) { return 0; } |
513 | static int store_fpxregs (int tid, int regno) { return 0; } | |
04cd15b6 | 514 | static void dummy_sse_values (void) {} |
5c44784c | 515 | |
6ce2ac0b | 516 | #endif /* HAVE_PTRACE_GETFPXREGS */ |
5c44784c | 517 | \f |
6ce2ac0b | 518 | |
5c44784c | 519 | /* Transferring arbitrary registers between GDB and inferior. */ |
d4f3574e | 520 | |
d5d65353 PS |
521 | /* Check if register REGNO in the child process is accessible. |
522 | If we are accessing registers directly via the U area, only the | |
523 | general-purpose registers are available. | |
524 | All registers should be accessible if we have GETREGS support. */ | |
525 | ||
526 | int | |
527 | cannot_fetch_register (int regno) | |
528 | { | |
529 | if (! have_ptrace_getregs) | |
530 | return OLD_CANNOT_FETCH_REGISTER (regno); | |
531 | return 0; | |
532 | } | |
533 | int | |
534 | cannot_store_register (int regno) | |
535 | { | |
536 | if (! have_ptrace_getregs) | |
537 | return OLD_CANNOT_STORE_REGISTER (regno); | |
538 | return 0; | |
539 | } | |
540 | ||
04cd15b6 MK |
541 | /* Fetch register REGNO from the child process. If REGNO is -1, do |
542 | this for all registers (including the floating point and SSE | |
543 | registers). */ | |
d4f3574e SS |
544 | |
545 | void | |
917317f4 | 546 | fetch_inferior_registers (int regno) |
d4f3574e | 547 | { |
ed9a39eb JM |
548 | int tid; |
549 | ||
f60300e7 MK |
550 | /* Use the old method of peeking around in `struct user' if the |
551 | GETREGS request isn't available. */ | |
552 | if (! have_ptrace_getregs) | |
553 | { | |
554 | old_fetch_inferior_registers (regno); | |
555 | return; | |
556 | } | |
557 | ||
04cd15b6 | 558 | /* Linux LWP ID's are process ID's. */ |
ed9a39eb | 559 | if ((tid = TIDGET (inferior_pid)) == 0) |
04cd15b6 | 560 | tid = inferior_pid; /* Not a threaded program. */ |
ed9a39eb | 561 | |
6ce2ac0b | 562 | /* Use the PTRACE_GETFPXREGS request whenever possible, since it |
04cd15b6 | 563 | transfers more registers in one system call, and we'll cache the |
6ce2ac0b | 564 | results. But remember that fetch_fpxregs can fail, and return |
04cd15b6 | 565 | zero. */ |
5c44784c JM |
566 | if (regno == -1) |
567 | { | |
ed9a39eb | 568 | fetch_regs (tid); |
f60300e7 MK |
569 | |
570 | /* The call above might reset `have_ptrace_getregs'. */ | |
571 | if (! have_ptrace_getregs) | |
572 | { | |
573 | old_fetch_inferior_registers (-1); | |
574 | return; | |
575 | } | |
576 | ||
6ce2ac0b | 577 | if (fetch_fpxregs (tid)) |
5c44784c | 578 | return; |
ed9a39eb | 579 | fetch_fpregs (tid); |
5c44784c JM |
580 | return; |
581 | } | |
d4f3574e | 582 | |
5c44784c JM |
583 | if (GETREGS_SUPPLIES (regno)) |
584 | { | |
ed9a39eb | 585 | fetch_regs (tid); |
5c44784c JM |
586 | return; |
587 | } | |
588 | ||
6ce2ac0b | 589 | if (GETFPXREGS_SUPPLIES (regno)) |
5c44784c | 590 | { |
6ce2ac0b | 591 | if (fetch_fpxregs (tid)) |
5c44784c JM |
592 | return; |
593 | ||
594 | /* Either our processor or our kernel doesn't support the SSE | |
595 | registers, so read the FP registers in the traditional way, | |
596 | and fill the SSE registers with dummy values. It would be | |
597 | more graceful to handle differences in the register set using | |
598 | gdbarch. Until then, this will at least make things work | |
599 | plausibly. */ | |
ed9a39eb | 600 | fetch_fpregs (tid); |
5c44784c JM |
601 | return; |
602 | } | |
603 | ||
8e65ff28 AC |
604 | internal_error (__FILE__, __LINE__, |
605 | "Got request for bad register number %d.", regno); | |
d4f3574e SS |
606 | } |
607 | ||
04cd15b6 MK |
608 | /* Store register REGNO back into the child process. If REGNO is -1, |
609 | do this for all registers (including the floating point and SSE | |
610 | registers). */ | |
d4f3574e | 611 | void |
04cd15b6 | 612 | store_inferior_registers (int regno) |
d4f3574e | 613 | { |
ed9a39eb JM |
614 | int tid; |
615 | ||
f60300e7 MK |
616 | /* Use the old method of poking around in `struct user' if the |
617 | SETREGS request isn't available. */ | |
618 | if (! have_ptrace_getregs) | |
619 | { | |
620 | old_store_inferior_registers (regno); | |
621 | return; | |
622 | } | |
623 | ||
04cd15b6 | 624 | /* Linux LWP ID's are process ID's. */ |
ed9a39eb | 625 | if ((tid = TIDGET (inferior_pid)) == 0) |
04cd15b6 | 626 | tid = inferior_pid; /* Not a threaded program. */ |
ed9a39eb | 627 | |
6ce2ac0b | 628 | /* Use the PTRACE_SETFPXREGS requests whenever possible, since it |
04cd15b6 | 629 | transfers more registers in one system call. But remember that |
6ce2ac0b | 630 | store_fpxregs can fail, and return zero. */ |
5c44784c JM |
631 | if (regno == -1) |
632 | { | |
6ce2ac0b MK |
633 | store_regs (tid, regno); |
634 | if (store_fpxregs (tid, regno)) | |
5c44784c | 635 | return; |
6ce2ac0b | 636 | store_fpregs (tid, regno); |
5c44784c JM |
637 | return; |
638 | } | |
d4f3574e | 639 | |
5c44784c JM |
640 | if (GETREGS_SUPPLIES (regno)) |
641 | { | |
6ce2ac0b | 642 | store_regs (tid, regno); |
5c44784c JM |
643 | return; |
644 | } | |
645 | ||
6ce2ac0b | 646 | if (GETFPXREGS_SUPPLIES (regno)) |
5c44784c | 647 | { |
6ce2ac0b | 648 | if (store_fpxregs (tid, regno)) |
5c44784c JM |
649 | return; |
650 | ||
651 | /* Either our processor or our kernel doesn't support the SSE | |
04cd15b6 MK |
652 | registers, so just write the FP registers in the traditional |
653 | way. */ | |
6ce2ac0b | 654 | store_fpregs (tid, regno); |
5c44784c JM |
655 | return; |
656 | } | |
657 | ||
8e65ff28 AC |
658 | internal_error (__FILE__, __LINE__, |
659 | "Got request to store bad register number %d.", regno); | |
d4f3574e | 660 | } |
de57eccd | 661 | \f |
6ce2ac0b | 662 | |
de57eccd JM |
663 | /* Interpreting register set info found in core files. */ |
664 | ||
665 | /* Provide registers to GDB from a core file. | |
666 | ||
667 | (We can't use the generic version of this function in | |
668 | core-regset.c, because Linux has *three* different kinds of | |
669 | register set notes. core-regset.c would have to call | |
6ce2ac0b | 670 | supply_fpxregset, which most platforms don't have.) |
de57eccd JM |
671 | |
672 | CORE_REG_SECT points to an array of bytes, which are the contents | |
673 | of a `note' from a core file which BFD thinks might contain | |
674 | register contents. CORE_REG_SIZE is its size. | |
675 | ||
676 | WHICH says which register set corelow suspects this is: | |
04cd15b6 MK |
677 | 0 --- the general-purpose register set, in elf_gregset_t format |
678 | 2 --- the floating-point register set, in elf_fpregset_t format | |
6ce2ac0b | 679 | 3 --- the extended floating-point register set, in elf_fpxregset_t format |
04cd15b6 MK |
680 | |
681 | REG_ADDR isn't used on Linux. */ | |
de57eccd | 682 | |
de57eccd | 683 | static void |
04cd15b6 MK |
684 | fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, |
685 | int which, CORE_ADDR reg_addr) | |
de57eccd | 686 | { |
04cd15b6 MK |
687 | elf_gregset_t gregset; |
688 | elf_fpregset_t fpregset; | |
de57eccd JM |
689 | |
690 | switch (which) | |
691 | { | |
692 | case 0: | |
693 | if (core_reg_size != sizeof (gregset)) | |
04cd15b6 | 694 | warning ("Wrong size gregset in core file."); |
de57eccd JM |
695 | else |
696 | { | |
697 | memcpy (&gregset, core_reg_sect, sizeof (gregset)); | |
698 | supply_gregset (&gregset); | |
699 | } | |
700 | break; | |
701 | ||
702 | case 2: | |
703 | if (core_reg_size != sizeof (fpregset)) | |
04cd15b6 | 704 | warning ("Wrong size fpregset in core file."); |
de57eccd JM |
705 | else |
706 | { | |
707 | memcpy (&fpregset, core_reg_sect, sizeof (fpregset)); | |
708 | supply_fpregset (&fpregset); | |
709 | } | |
710 | break; | |
711 | ||
6ce2ac0b | 712 | #ifdef HAVE_PTRACE_GETFPXREGS |
de57eccd | 713 | { |
6ce2ac0b | 714 | elf_fpxregset_t fpxregset; |
04cd15b6 | 715 | |
de57eccd | 716 | case 3: |
6ce2ac0b MK |
717 | if (core_reg_size != sizeof (fpxregset)) |
718 | warning ("Wrong size fpxregset in core file."); | |
de57eccd JM |
719 | else |
720 | { | |
6ce2ac0b MK |
721 | memcpy (&fpxregset, core_reg_sect, sizeof (fpxregset)); |
722 | supply_fpxregset (&fpxregset); | |
de57eccd JM |
723 | } |
724 | break; | |
725 | } | |
726 | #endif | |
727 | ||
728 | default: | |
729 | /* We've covered all the kinds of registers we know about here, | |
730 | so this must be something we wouldn't know what to do with | |
731 | anyway. Just ignore it. */ | |
732 | break; | |
733 | } | |
734 | } | |
a6abb2c0 | 735 | \f |
6ce2ac0b | 736 | |
a6abb2c0 MK |
737 | /* The instruction for a Linux system call is: |
738 | int $0x80 | |
739 | or 0xcd 0x80. */ | |
740 | ||
741 | static const unsigned char linux_syscall[] = { 0xcd, 0x80 }; | |
742 | ||
743 | #define LINUX_SYSCALL_LEN (sizeof linux_syscall) | |
744 | ||
745 | /* The system call number is stored in the %eax register. */ | |
746 | #define LINUX_SYSCALL_REGNUM 0 /* %eax */ | |
747 | ||
748 | /* We are specifically interested in the sigreturn and rt_sigreturn | |
749 | system calls. */ | |
750 | ||
751 | #ifndef SYS_sigreturn | |
752 | #define SYS_sigreturn 0x77 | |
753 | #endif | |
754 | #ifndef SYS_rt_sigreturn | |
755 | #define SYS_rt_sigreturn 0xad | |
756 | #endif | |
757 | ||
758 | /* Offset to saved processor flags, from <asm/sigcontext.h>. */ | |
759 | #define LINUX_SIGCONTEXT_EFLAGS_OFFSET (64) | |
760 | ||
761 | /* Resume execution of the inferior process. | |
762 | If STEP is nonzero, single-step it. | |
763 | If SIGNAL is nonzero, give it that signal. */ | |
764 | ||
765 | void | |
766 | child_resume (int pid, int step, enum target_signal signal) | |
767 | { | |
768 | int request = PTRACE_CONT; | |
769 | ||
770 | if (pid == -1) | |
771 | /* Resume all threads. */ | |
772 | /* I think this only gets used in the non-threaded case, where "resume | |
773 | all threads" and "resume inferior_pid" are the same. */ | |
774 | pid = inferior_pid; | |
775 | ||
776 | if (step) | |
777 | { | |
778 | CORE_ADDR pc = read_pc_pid (pid); | |
779 | unsigned char buf[LINUX_SYSCALL_LEN]; | |
780 | ||
781 | request = PTRACE_SINGLESTEP; | |
782 | ||
783 | /* Returning from a signal trampoline is done by calling a | |
784 | special system call (sigreturn or rt_sigreturn, see | |
785 | i386-linux-tdep.c for more information). This system call | |
786 | restores the registers that were saved when the signal was | |
787 | raised, including %eflags. That means that single-stepping | |
788 | won't work. Instead, we'll have to modify the signal context | |
789 | that's about to be restored, and set the trace flag there. */ | |
790 | ||
791 | /* First check if PC is at a system call. */ | |
792 | if (read_memory_nobpt (pc, (char *) buf, LINUX_SYSCALL_LEN) == 0 | |
793 | && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0) | |
794 | { | |
795 | int syscall = read_register_pid (LINUX_SYSCALL_REGNUM, pid); | |
796 | ||
797 | /* Then check the system call number. */ | |
798 | if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn) | |
799 | { | |
800 | CORE_ADDR sp = read_register (SP_REGNUM); | |
801 | CORE_ADDR addr = sp; | |
802 | unsigned long int eflags; | |
803 | ||
804 | if (syscall == SYS_rt_sigreturn) | |
805 | addr = read_memory_integer (sp + 8, 4) + 20; | |
806 | ||
807 | /* Set the trace flag in the context that's about to be | |
808 | restored. */ | |
809 | addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET; | |
810 | read_memory (addr, (char *) &eflags, 4); | |
811 | eflags |= 0x0100; | |
812 | write_memory (addr, (char *) &eflags, 4); | |
813 | } | |
814 | } | |
815 | } | |
816 | ||
817 | if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1) | |
818 | perror_with_name ("ptrace"); | |
819 | } | |
5c44784c | 820 | \f |
6ce2ac0b | 821 | |
04cd15b6 MK |
822 | /* Register that we are able to handle Linux ELF core file formats. */ |
823 | ||
824 | static struct core_fns linux_elf_core_fns = | |
825 | { | |
826 | bfd_target_elf_flavour, /* core_flavour */ | |
827 | default_check_format, /* check_format */ | |
828 | default_core_sniffer, /* core_sniffer */ | |
829 | fetch_core_registers, /* core_read_registers */ | |
830 | NULL /* next */ | |
831 | }; | |
de57eccd JM |
832 | |
833 | void | |
fba45db2 | 834 | _initialize_i386_linux_nat (void) |
de57eccd | 835 | { |
04cd15b6 | 836 | add_core_fns (&linux_elf_core_fns); |
de57eccd | 837 | } |