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