* alpha-tdep.c (alpha_register_name): New function.
[deliverable/binutils-gdb.git] / gdb / x86-64-linux-nat.c
CommitLineData
53e95fcf
JS
1/* Native-dependent code for Linux/x86-64.
2 Copyright 2001
3 Free Software Foundation, Inc.
4 Contributed by Jiri Smid, SuSE Labs.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23#include "defs.h"
24#include "inferior.h"
25#include "gdbcore.h"
26#include "regcache.h"
27#include "i387-nat.h"
28#include "gdb_assert.h"
29#include "x86-64-tdep.h"
30
31#include <sys/ptrace.h>
32#include <sys/debugreg.h>
33#include <sys/syscall.h>
34#include <sys/procfs.h>
35
36static unsigned long
37x86_64_linux_dr_get (int regnum)
38{
39 int tid;
40 unsigned long value;
41
42 /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
43 multi-threaded processes here. For now, pretend there is just
44 one thread. */
45 tid = PIDGET (inferior_ptid);
46
47 /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
48 ptrace call fails breaks debugging remote targets. The correct
49 way to fix this is to add the hardware breakpoint and watchpoint
50 stuff to the target vectore. For now, just return zero if the
51 ptrace call fails. */
52 errno = 0;
53 value = ptrace (PT_READ_U, tid,
54 offsetof (struct user, u_debugreg[regnum]), 0);
55 if (errno != 0)
56#if 0
57 perror_with_name ("Couldn't read debug register");
58#else
59 return 0;
60#endif
61
62 return value;
63}
64
65static void
66x86_64_linux_dr_set (int regnum, unsigned long value)
67{
68 int tid;
69
70 /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
71 multi-threaded processes here. For now, pretend there is just
72 one thread. */
73 tid = PIDGET (inferior_ptid);
74
75 errno = 0;
76 ptrace (PT_WRITE_U, tid,
77 offsetof (struct user, u_debugreg[regnum]), value);
78 if (errno != 0)
79 perror_with_name ("Couldn't write debug register");
80}
81
82void
83x86_64_linux_dr_set_control (unsigned long control)
84{
85 x86_64_linux_dr_set (DR_CONTROL, control);
86}
87
88void
89x86_64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
90{
91 gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
92
93 x86_64_linux_dr_set (DR_FIRSTADDR + regnum, addr);
94}
95
96void
97x86_64_linux_dr_reset_addr (int regnum)
98{
99 gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
100
101 x86_64_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
102}
103
104unsigned long
105x86_64_linux_dr_get_status (void)
106{
107 return x86_64_linux_dr_get (DR_STATUS);
108}
109\f
110
111/* The register sets used in Linux ELF core-dumps are identical to the
112 register sets used by `ptrace'. */
113
114#define GETREGS_SUPPLIES(regno) \
115 (0 <= (regno) && (regno) <= 17)
116#define GETFPREGS_SUPPLIES(regno) \
117 (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
118
119#define PTRACE_XFER_TYPE unsigned long
120\f
121
122/* Transfering the general-purpose registers between GDB, inferiors
123 and core files. */
124
125/* Fill GDB's register array with the general-purpose register values
126 in *GREGSETP. */
127
128void
129supply_gregset (elf_gregset_t * gregsetp)
130{
131 elf_greg_t *regp = (elf_greg_t *) gregsetp;
132 int i;
133
134 for (i = 0; i < X86_64_NUM_GREGS; i++)
135 supply_register (i, (char *) (regp + x86_64_regmap[i]));
136}
137
138/* Fill register REGNO (if it is a general-purpose register) in
139 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
140 do this for all registers. */
141
142void
143fill_gregset (elf_gregset_t * gregsetp, int regno)
144{
145 elf_greg_t *regp = (elf_greg_t *) gregsetp;
146 int i;
147
148 for (i = 0; i < X86_64_NUM_GREGS; i++)
149 if ((regno == -1 || regno == i))
94cd915f 150 read_register_gen (i, regp + x86_64_regmap[i]);
53e95fcf
JS
151}
152
153/* Fetch all general-purpose registers from process/thread TID and
154 store their values in GDB's register array. */
155
156static void
157fetch_regs (int tid)
158{
159 elf_gregset_t regs;
160
161 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
162 perror_with_name ("Couldn't get registers");
163
164 supply_gregset (&regs);
165}
166
167/* Store all valid general-purpose registers in GDB's register array
168 into the process/thread specified by TID. */
169
170static void
171store_regs (int tid, int regno)
172{
173 elf_gregset_t regs;
174
175 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
176 perror_with_name ("Couldn't get registers");
177
178 fill_gregset (&regs, regno);
179
180 if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
181 perror_with_name ("Couldn't write registers");
182}
183\f
184
185/* Transfering floating-point registers between GDB, inferiors and cores. */
186
187/* Fill GDB's register array with the floating-point register values in
188 *FPREGSETP. */
189
190void
191supply_fpregset (elf_fpregset_t * fpregsetp)
192{
193 i387_supply_fxsave ((char *) fpregsetp);
194}
195
196/* Fill register REGNO (if it is a floating-point register) in
197 *FPREGSETP with the value in GDB's register array. If REGNO is -1,
198 do this for all registers. */
199
200void
201fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
202{
203 i387_fill_fxsave ((char *) fpregsetp, regno);
204}
205
206/* Fetch all floating-point registers from process/thread TID and store
207 thier values in GDB's register array. */
208
209static void
210fetch_fpregs (int tid)
211{
212 elf_fpregset_t fpregs;
213
214 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
215 perror_with_name ("Couldn't get floating point status");
216
217 supply_fpregset (&fpregs);
218}
219
220/* Store all valid floating-point registers in GDB's register array
221 into the process/thread specified by TID. */
222
223static void
224store_fpregs (int tid, int regno)
225{
226 elf_fpregset_t fpregs;
227
228 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
229 perror_with_name ("Couldn't get floating point status");
230
231 fill_fpregset (&fpregs, regno);
232
233 if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
234 perror_with_name ("Couldn't write floating point status");
235}
236\f
237
238/* Transferring arbitrary registers between GDB and inferior. */
239
240/* Fetch register REGNO from the child process. If REGNO is -1, do
241 this for all registers (including the floating point and SSE
242 registers). */
243
244void
245fetch_inferior_registers (int regno)
246{
247 int tid;
248
249 /* Linux LWP ID's are process ID's. */
250 if ((tid = TIDGET (inferior_ptid)) == 0)
251 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
252
253 if (regno == -1)
254 {
255 fetch_regs (tid);
256 fetch_fpregs (tid);
257 return;
258 }
259
260 if (GETREGS_SUPPLIES (regno))
261 {
262 fetch_regs (tid);
263 return;
264 }
265
266 if (GETFPREGS_SUPPLIES (regno))
267 {
268 fetch_fpregs (tid);
269 return;
270 }
271
272 internal_error (__FILE__, __LINE__,
273 "Got request for bad register number %d.", regno);
274}
275
276/* Store register REGNO back into the child process. If REGNO is -1,
277 do this for all registers (including the floating point and SSE
278 registers). */
279void
280store_inferior_registers (int regno)
281{
282 int tid;
283
284 /* Linux LWP ID's are process ID's. */
285 if ((tid = TIDGET (inferior_ptid)) == 0)
286 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
287
288 if (regno == -1)
289 {
290 store_regs (tid, regno);
291 store_fpregs (tid, regno);
292 return;
293 }
294
295 if (GETREGS_SUPPLIES (regno))
296 {
297 store_regs (tid, regno);
298 return;
299 }
300
301 if (GETFPREGS_SUPPLIES (regno))
302 {
303 store_fpregs (tid, regno);
304 return;
305 }
306
307 internal_error (__FILE__, __LINE__,
308 "Got request to store bad register number %d.", regno);
309}
310\f
311
312static const unsigned char linux_syscall[] = { 0x0f, 0x05 };
313
314#define LINUX_SYSCALL_LEN (sizeof linux_syscall)
315
316/* The system call number is stored in the %rax register. */
317#define LINUX_SYSCALL_REGNUM 0 /* %rax */
318
319/* We are specifically interested in the sigreturn and rt_sigreturn
320 system calls. */
321
322#ifndef SYS_sigreturn
323#define SYS_sigreturn __NR_sigreturn
324#endif
325#ifndef SYS_rt_sigreturn
326#define SYS_rt_sigreturn __NR_rt_sigreturn
327#endif
328
329/* Offset to saved processor flags, from <asm/sigcontext.h>. */
330#define LINUX_SIGCONTEXT_EFLAGS_OFFSET (152)
331/* Offset to saved processor registers from <asm/ucontext.h> */
332#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET (36)
333
334/* Resume execution of the inferior process.
335 If STEP is nonzero, single-step it.
336 If SIGNAL is nonzero, give it that signal. */
337
338void
339child_resume (ptid_t ptid, int step, enum target_signal signal)
340{
341 int pid = PIDGET (ptid);
342 int request = PTRACE_CONT;
343
344 if (pid == -1)
345 /* Resume all threads. */
346 /* I think this only gets used in the non-threaded case, where "resume
347 all threads" and "resume inferior_ptid" are the same. */
348 pid = PIDGET (inferior_ptid);
349
350 if (step)
351 {
352 CORE_ADDR pc = read_pc_pid (pid_to_ptid (pid));
353 unsigned char buf[LINUX_SYSCALL_LEN];
354
355 request = PTRACE_SINGLESTEP;
356
357 /* Returning from a signal trampoline is done by calling a
358 special system call (sigreturn or rt_sigreturn, see
359 i386-linux-tdep.c for more information). This system call
360 restores the registers that were saved when the signal was
361 raised, including %eflags. That means that single-stepping
362 won't work. Instead, we'll have to modify the signal context
363 that's about to be restored, and set the trace flag there. */
364
365 /* First check if PC is at a system call. */
366 if (read_memory_nobpt (pc, (char *) buf, LINUX_SYSCALL_LEN) == 0
367 && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0)
368 {
369 int syscall =
370 read_register_pid (LINUX_SYSCALL_REGNUM, pid_to_ptid (pid));
371
372 /* Then check the system call number. */
373 if (syscall == SYS_rt_sigreturn)
374 {
375 CORE_ADDR sp = read_register (SP_REGNUM);
376 CORE_ADDR addr = sp;
377 unsigned long int eflags;
378
379 addr +=
380 sizeof (struct siginfo) + LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
381
382 /* Set the trace flag in the context that's about to be
383 restored. */
384 addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET;
385 read_memory (addr, (char *) &eflags, 8);
386 eflags |= 0x0100;
387 write_memory (addr, (char *) &eflags, 8);
388 }
389 }
390 }
391
392 if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1)
393 perror_with_name ("ptrace");
394}
395\f
396
397/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
398 to debugger memory starting at MYADDR. Copy to inferior if
399 WRITE is nonzero. TARGET is ignored.
400
401 Returns the length copied, which is either the LEN argument or zero.
402 This xfer function does not do partial moves, since child_ops
403 doesn't allow memory operations to cross below us in the target stack
404 anyway. */
405
406int
407child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
408 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
409 struct target_ops *target)
410{
411 register int i;
412 /* Round starting address down to longword boundary. */
413 register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE);
414 /* Round ending address up; get number of longwords that makes. */
415 register int count
416 = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
417 / sizeof (PTRACE_XFER_TYPE);
418 /* Allocate buffer of that many longwords. */
94cd915f
MS
419 /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
420 because it uses alloca to allocate a buffer of arbitrary size.
421 For very large xfers, this could crash GDB's stack. */
53e95fcf
JS
422 register PTRACE_XFER_TYPE *buffer
423 = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
424
425 if (write)
426 {
427 /* Fill start and end extra bytes of buffer with existing memory data. */
428 if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE))
429 {
430 /* Need part of initial word -- fetch it. */
431 ptrace (PT_READ_I, PIDGET (inferior_ptid),
432 (PTRACE_ARG3_TYPE) addr, buffer);
433 }
434
435 if (count > 1) /* FIXME, avoid if even boundary */
436 {
437 ptrace (PT_READ_I, PIDGET (inferior_ptid),
438 ((PTRACE_ARG3_TYPE)
439 (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE))),
440 buffer + count - 1);
441 }
442
443 /* Copy data to be written over corresponding part of buffer */
444
445 memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
446 myaddr, len);
447
448 /* Write the entire buffer. */
449
450 for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
451 {
452 errno = 0;
453 ptrace (PT_WRITE_D, PIDGET (inferior_ptid),
454 (PTRACE_ARG3_TYPE) addr, buffer[i]);
455 if (errno)
456 {
457 /* Using the appropriate one (I or D) is necessary for
458 Gould NP1, at least. */
459 errno = 0;
460 ptrace (PT_WRITE_I, PIDGET (inferior_ptid),
461 (PTRACE_ARG3_TYPE) addr, buffer[i]);
462 }
463 if (errno)
464 return 0;
465 }
466#ifdef CLEAR_INSN_CACHE
467 CLEAR_INSN_CACHE ();
468#endif
469 }
470 else
471 {
472 /* Read all the longwords */
473 for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
474 {
475 errno = 0;
476 ptrace (PT_READ_I, PIDGET (inferior_ptid),
477 (PTRACE_ARG3_TYPE) addr, buffer + i);
478 if (errno)
479 return 0;
480 }
481
482 /* Copy appropriate bytes out of the buffer. */
483 memcpy (myaddr,
484 (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
485 len);
486 }
487 return len;
488}
489
490/* Interpreting register set info found in core files. */
491
492/* Provide registers to GDB from a core file.
493
494 CORE_REG_SECT points to an array of bytes, which are the contents
495 of a `note' from a core file which BFD thinks might contain
496 register contents. CORE_REG_SIZE is its size.
497
498 WHICH says which register set corelow suspects this is:
499 0 --- the general-purpose register set, in elf_gregset_t format
500 2 --- the floating-point register set, in elf_fpregset_t format
501
502 REG_ADDR isn't used on Linux. */
503
504static void
505fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
506 int which, CORE_ADDR reg_addr)
507{
508 elf_gregset_t gregset;
509 elf_fpregset_t fpregset;
510 switch (which)
511 {
512 case 0:
513 if (core_reg_size != sizeof (gregset))
514 warning ("Wrong size gregset in core file.");
515 else
516 {
517 memcpy (&gregset, core_reg_sect, sizeof (gregset));
518 supply_gregset (&gregset);
519 }
520 break;
521
522 case 2:
523 if (core_reg_size != sizeof (fpregset))
524 warning ("Wrong size fpregset in core file.");
525 else
526 {
527 memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
528 supply_fpregset (&fpregset);
529 }
530 break;
531
532 default:
533 /* We've covered all the kinds of registers we know about here,
534 so this must be something we wouldn't know what to do with
535 anyway. Just ignore it. */
536 break;
537 }
538}
539
540/* Register that we are able to handle Linux ELF core file formats. */
541
542static struct core_fns linux_elf_core_fns = {
543 bfd_target_elf_flavour, /* core_flavour */
544 default_check_format, /* check_format */
545 default_core_sniffer, /* core_sniffer */
546 fetch_core_registers, /* core_read_registers */
547 NULL /* next */
548};
549\f
550
551#if !defined (offsetof)
552#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
553#endif
554
555/* Record the value of the debug control register. */
556static long debug_control_mirror;
557
558/* Record which address associates with which register. */
559static CORE_ADDR address_lookup[DR_LASTADDR - DR_FIRSTADDR + 1];
560
561void
562_initialize_x86_64_linux_nat (void)
563{
564 add_core_fns (&linux_elf_core_fns);
565}
This page took 0.079809 seconds and 4 git commands to generate.