329532712d8aeb0b4be4f0f7683b2ba953aaa603
[deliverable/binutils-gdb.git] / gdb / x86-64-linux-nat.c
1 /* Native-dependent code for GNU/Linux x86-64.
2
3 Copyright 2001, 2002 Free Software Foundation, Inc.
4
5 Contributed by Jiri Smid, SuSE Labs.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
23
24 #include "defs.h"
25 #include "inferior.h"
26 #include "gdbcore.h"
27 #include "regcache.h"
28 #include "i387-nat.h"
29 #include "gdb_assert.h"
30 #include "x86-64-tdep.h"
31
32 #include <sys/ptrace.h>
33 #include <sys/debugreg.h>
34 #include <sys/syscall.h>
35 #include <sys/procfs.h>
36 #include <sys/reg.h>
37
38 /* Mapping between the general-purpose registers in `struct user'
39 format and GDB's register array layout. */
40
41 static int x86_64_regmap[] = {
42 RAX, RBX, RCX, RDX,
43 RSI, RDI, RBP, RSP,
44 R8, R9, R10, R11,
45 R12, R13, R14, R15,
46 RIP, EFLAGS,
47 DS, ES, FS, GS
48 };
49
50 static unsigned long
51 x86_64_linux_dr_get (int regnum)
52 {
53 int tid;
54 unsigned long value;
55
56 /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
57 multi-threaded processes here. For now, pretend there is just
58 one thread. */
59 tid = PIDGET (inferior_ptid);
60
61 /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
62 ptrace call fails breaks debugging remote targets. The correct
63 way to fix this is to add the hardware breakpoint and watchpoint
64 stuff to the target vectore. For now, just return zero if the
65 ptrace call fails. */
66 errno = 0;
67 value = ptrace (PT_READ_U, tid,
68 offsetof (struct user, u_debugreg[regnum]), 0);
69 if (errno != 0)
70 #if 0
71 perror_with_name ("Couldn't read debug register");
72 #else
73 return 0;
74 #endif
75
76 return value;
77 }
78
79 static void
80 x86_64_linux_dr_set (int regnum, unsigned long value)
81 {
82 int tid;
83
84 /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
85 multi-threaded processes here. For now, pretend there is just
86 one thread. */
87 tid = PIDGET (inferior_ptid);
88
89 errno = 0;
90 ptrace (PT_WRITE_U, tid, offsetof (struct user, u_debugreg[regnum]), value);
91 if (errno != 0)
92 perror_with_name ("Couldn't write debug register");
93 }
94
95 void
96 x86_64_linux_dr_set_control (unsigned long control)
97 {
98 x86_64_linux_dr_set (DR_CONTROL, control);
99 }
100
101 void
102 x86_64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
103 {
104 gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
105
106 x86_64_linux_dr_set (DR_FIRSTADDR + regnum, addr);
107 }
108
109 void
110 x86_64_linux_dr_reset_addr (int regnum)
111 {
112 gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
113
114 x86_64_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
115 }
116
117 unsigned long
118 x86_64_linux_dr_get_status (void)
119 {
120 return x86_64_linux_dr_get (DR_STATUS);
121 }
122 \f
123
124 /* The register sets used in GNU/Linux ELF core-dumps are identical to
125 the register sets used by `ptrace'. */
126
127 #define GETREGS_SUPPLIES(regno) \
128 (0 <= (regno) && (regno) < x86_64_num_gregs)
129 #define GETFPREGS_SUPPLIES(regno) \
130 (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
131 \f
132
133 /* Transfering the general-purpose registers between GDB, inferiors
134 and core files. */
135
136 /* Fill GDB's register array with the general-purpose register values
137 in *GREGSETP. */
138
139 void
140 supply_gregset (elf_gregset_t * gregsetp)
141 {
142 elf_greg_t *regp = (elf_greg_t *) gregsetp;
143 int i;
144
145 for (i = 0; i < x86_64_num_gregs; i++)
146 supply_register (i, (char *) (regp + x86_64_regmap[i]));
147 }
148
149 /* Fill register REGNO (if it is a general-purpose register) in
150 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
151 do this for all registers. */
152
153 void
154 fill_gregset (elf_gregset_t * gregsetp, int regno)
155 {
156 elf_greg_t *regp = (elf_greg_t *) gregsetp;
157 int i;
158
159 for (i = 0; i < x86_64_num_gregs; i++)
160 if ((regno == -1 || regno == i))
161 read_register_gen (i, (char *) (regp + x86_64_regmap[i]));
162 }
163
164 /* Fetch all general-purpose registers from process/thread TID and
165 store their values in GDB's register array. */
166
167 static void
168 fetch_regs (int tid)
169 {
170 elf_gregset_t regs;
171
172 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
173 perror_with_name ("Couldn't get registers");
174
175 supply_gregset (&regs);
176 }
177
178 /* Store all valid general-purpose registers in GDB's register array
179 into the process/thread specified by TID. */
180
181 static void
182 store_regs (int tid, int regno)
183 {
184 elf_gregset_t regs;
185
186 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
187 perror_with_name ("Couldn't get registers");
188
189 fill_gregset (&regs, regno);
190
191 if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
192 perror_with_name ("Couldn't write registers");
193 }
194 \f
195
196 /* Transfering floating-point registers between GDB, inferiors and cores. */
197
198 /* Fill GDB's register array with the floating-point register values in
199 *FPREGSETP. */
200
201 void
202 supply_fpregset (elf_fpregset_t * fpregsetp)
203 {
204 i387_supply_fxsave ((char *) fpregsetp);
205 }
206
207 /* Fill register REGNO (if it is a floating-point register) in
208 *FPREGSETP with the value in GDB's register array. If REGNO is -1,
209 do this for all registers. */
210
211 void
212 fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
213 {
214 i387_fill_fxsave ((char *) fpregsetp, regno);
215 }
216
217 /* Fetch all floating-point registers from process/thread TID and store
218 thier values in GDB's register array. */
219
220 static void
221 fetch_fpregs (int tid)
222 {
223 elf_fpregset_t fpregs;
224
225 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
226 perror_with_name ("Couldn't get floating point status");
227
228 supply_fpregset (&fpregs);
229 }
230
231 /* Store all valid floating-point registers in GDB's register array
232 into the process/thread specified by TID. */
233
234 static void
235 store_fpregs (int tid, int regno)
236 {
237 elf_fpregset_t fpregs;
238
239 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
240 perror_with_name ("Couldn't get floating point status");
241
242 fill_fpregset (&fpregs, regno);
243
244 if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
245 perror_with_name ("Couldn't write floating point status");
246 }
247 \f
248
249 /* Transferring arbitrary registers between GDB and inferior. */
250
251 /* Fetch register REGNO from the child process. If REGNO is -1, do
252 this for all registers (including the floating point and SSE
253 registers). */
254
255 void
256 fetch_inferior_registers (int regno)
257 {
258 int tid;
259
260 /* GNU/Linux LWP ID's are process ID's. */
261 if ((tid = TIDGET (inferior_ptid)) == 0)
262 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
263
264 if (regno == -1)
265 {
266 fetch_regs (tid);
267 fetch_fpregs (tid);
268 return;
269 }
270
271 if (GETREGS_SUPPLIES (regno))
272 {
273 fetch_regs (tid);
274 return;
275 }
276
277 if (GETFPREGS_SUPPLIES (regno))
278 {
279 fetch_fpregs (tid);
280 return;
281 }
282
283 internal_error (__FILE__, __LINE__,
284 "Got request for bad register number %d.", regno);
285 }
286
287 /* Store register REGNO back into the child process. If REGNO is -1,
288 do this for all registers (including the floating point and SSE
289 registers). */
290 void
291 store_inferior_registers (int regno)
292 {
293 int tid;
294
295 /* GNU/Linux LWP ID's are process ID's. */
296 if ((tid = TIDGET (inferior_ptid)) == 0)
297 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
298
299 if (regno == -1)
300 {
301 store_regs (tid, regno);
302 store_fpregs (tid, regno);
303 return;
304 }
305
306 if (GETREGS_SUPPLIES (regno))
307 {
308 store_regs (tid, regno);
309 return;
310 }
311
312 if (GETFPREGS_SUPPLIES (regno))
313 {
314 store_fpregs (tid, regno);
315 return;
316 }
317
318 internal_error (__FILE__, __LINE__,
319 "Got request to store bad register number %d.", regno);
320 }
321 \f
322
323 static const unsigned char linux_syscall[] = { 0x0f, 0x05 };
324
325 #define LINUX_SYSCALL_LEN (sizeof linux_syscall)
326
327 /* The system call number is stored in the %rax register. */
328 #define LINUX_SYSCALL_REGNUM 0 /* %rax */
329
330 /* We are specifically interested in the sigreturn and rt_sigreturn
331 system calls. */
332
333 #ifndef SYS_sigreturn
334 #define SYS_sigreturn __NR_sigreturn
335 #endif
336 #ifndef SYS_rt_sigreturn
337 #define SYS_rt_sigreturn __NR_rt_sigreturn
338 #endif
339
340 /* Offset to saved processor flags, from <asm/sigcontext.h>. */
341 #define LINUX_SIGCONTEXT_EFLAGS_OFFSET (152)
342 /* Offset to saved processor registers from <asm/ucontext.h> */
343 #define LINUX_UCONTEXT_SIGCONTEXT_OFFSET (36)
344
345 /* Interpreting register set info found in core files. */
346 /* Provide registers to GDB from a core file.
347
348 CORE_REG_SECT points to an array of bytes, which are the contents
349 of a `note' from a core file which BFD thinks might contain
350 register contents. CORE_REG_SIZE is its size.
351
352 WHICH says which register set corelow suspects this is:
353 0 --- the general-purpose register set, in elf_gregset_t format
354 2 --- the floating-point register set, in elf_fpregset_t format
355
356 REG_ADDR isn't used on GNU/Linux. */
357
358 static void
359 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
360 int which, CORE_ADDR reg_addr)
361 {
362 elf_gregset_t gregset;
363 elf_fpregset_t fpregset;
364 switch (which)
365 {
366 case 0:
367 if (core_reg_size != sizeof (gregset))
368 warning ("Wrong size gregset in core file.");
369 else
370 {
371 memcpy (&gregset, core_reg_sect, sizeof (gregset));
372 supply_gregset (&gregset);
373 }
374 break;
375
376 case 2:
377 if (core_reg_size != sizeof (fpregset))
378 warning ("Wrong size fpregset in core file.");
379 else
380 {
381 memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
382 supply_fpregset (&fpregset);
383 }
384 break;
385
386 default:
387 /* We've covered all the kinds of registers we know about here,
388 so this must be something we wouldn't know what to do with
389 anyway. Just ignore it. */
390 break;
391 }
392 }
393
394 /* Register that we are able to handle GNU/Linux ELF core file formats. */
395
396 static struct core_fns linux_elf_core_fns = {
397 bfd_target_elf_flavour, /* core_flavour */
398 default_check_format, /* check_format */
399 default_core_sniffer, /* core_sniffer */
400 fetch_core_registers, /* core_read_registers */
401 NULL /* next */
402 };
403 \f
404
405 #if !defined (offsetof)
406 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
407 #endif
408
409 /* Return the address of register REGNUM. BLOCKEND is the value of
410 u.u_ar0, which should point to the registers. */
411 CORE_ADDR
412 x86_64_register_u_addr (CORE_ADDR blockend, int regnum)
413 {
414 struct user u;
415 CORE_ADDR fpstate;
416 CORE_ADDR ubase;
417 ubase = blockend;
418 if (IS_FP_REGNUM (regnum))
419 {
420 fpstate = ubase + ((char *) &u.i387.st_space - (char *) &u);
421 return (fpstate + 16 * (regnum - FP0_REGNUM));
422 }
423 else if (IS_SSE_REGNUM (regnum))
424 {
425 fpstate = ubase + ((char *) &u.i387.xmm_space - (char *) &u);
426 return (fpstate + 16 * (regnum - XMM0_REGNUM));
427 }
428 else
429 return (ubase + 8 * x86_64_regmap[regnum]);
430 }
431
432 void
433 _initialize_x86_64_linux_nat (void)
434 {
435 add_core_fns (&linux_elf_core_fns);
436 }
437
438 int
439 kernel_u_size (void)
440 {
441 return (sizeof (struct user));
442 }
This page took 0.091583 seconds and 3 git commands to generate.