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