* amd64-tdep.h: Renamed from x86-64-tdep.h.
[external/binutils.git] / gdb / amd64-linux-nat.c
1 /* Native-dependent code for GNU/Linux x86-64.
2
3    Copyright 2001, 2002, 2003, 2004 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 "linux-nat.h"
28
29 #include "gdb_assert.h"
30 #include "gdb_string.h"
31 #include <sys/ptrace.h>
32 #include <sys/debugreg.h>
33 #include <sys/syscall.h>
34 #include <sys/procfs.h>
35 #include <asm/prctl.h>
36 /* FIXME ezannoni-2003-07-09: we need <sys/reg.h> to be included after
37    <asm/ptrace.h> because the latter redefines FS and GS for no apparent
38    reason, and those definitions don't match the ones that libpthread_db
39    uses, which come from <sys/reg.h>.  */
40 /* ezannoni-2003-07-09: I think this is fixed. The extraneous defs have
41    been removed from ptrace.h in the kernel.  However, better safe than
42    sorry.  */
43 #include <asm/ptrace.h>
44 #include <sys/reg.h>
45 #include "gdb_proc_service.h"
46
47 /* Prototypes for supply_gregset etc.  */
48 #include "gregset.h"
49
50 #include "amd64-tdep.h"
51 #include "amd64-linux-tdep.h"
52 #include "i386-linux-tdep.h"
53 #include "amd64-nat.h"
54
55 /* Mapping between the general-purpose registers in GNU/Linux x86-64
56    `struct user' format and GDB's register cache layout.  */
57
58 static int amd64_linux_gregset64_reg_offset[] =
59 {
60   RAX * 8, RBX * 8,             /* %rax, %rbx */
61   RCX * 8, RDX * 8,             /* %rcx, %rdx */
62   RSI * 8, RDI * 8,             /* %rsi, %rdi */
63   RBP * 8, RSP * 8,             /* %rbp, %rsp */
64   R8 * 8, R9 * 8,               /* %r8 ... */
65   R10 * 8, R11 * 8,
66   R12 * 8, R13 * 8,
67   R14 * 8, R15 * 8,             /* ... %r15 */
68   RIP * 8, EFLAGS * 8,          /* %rip, %eflags */
69   CS * 8, SS * 8,               /* %cs, %ss */
70   DS * 8, ES * 8,               /* %ds, %es */
71   FS * 8, GS * 8                /* %fs, %gs */
72 };
73 \f
74
75 /* Mapping between the general-purpose registers in GNU/Linux x86-64
76    `struct user' format and GDB's register cache layout for GNU/Linux
77    i386.
78
79    Note that most GNU/Linux x86-64 registers are 64-bit, while the
80    GNU/Linux i386 registers are all 32-bit, but since we're
81    little-endian we get away with that.  */
82
83 /* From <sys/reg.h> on GNU/Linux i386.  */
84 static int amd64_linux_gregset32_reg_offset[] =
85 {
86   RAX * 8, RCX * 8,             /* %eax, %ecx */
87   RDX * 8, RBX * 8,             /* %edx, %ebx */
88   RSP * 8, RBP * 8,             /* %esp, %ebp */
89   RSI * 8, RDI * 8,             /* %esi, %edi */
90   RIP * 8, EFLAGS * 8,          /* %eip, %eflags */
91   CS * 8, SS * 8,               /* %cs, %ss */
92   DS * 8, ES * 8,               /* %ds, %es */
93   FS * 8, GS * 8,               /* %fs, %gs */
94   -1, -1, -1, -1, -1, -1, -1, -1,
95   -1, -1, -1, -1, -1, -1, -1, -1,
96   -1, -1, -1, -1, -1, -1, -1, -1, -1,
97   ORIG_RAX * 8                  /* "orig_eax" */
98 };
99
100 /* Which ptrace request retrieves which registers?
101    These apply to the corresponding SET requests as well.  */
102
103 #define GETFPREGS_SUPPLIES(regno) \
104   (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
105 \f
106
107 /* Transfering the general-purpose registers between GDB, inferiors
108    and core files.  */
109
110 /* Fill GDB's register cache with the general-purpose register values
111    in *GREGSETP.  */
112
113 void
114 supply_gregset (elf_gregset_t *gregsetp)
115 {
116   amd64_supply_native_gregset (current_regcache, gregsetp, -1);
117 }
118
119 /* Fill register REGNUM (if it is a general-purpose register) in
120    *GREGSETP with the value in GDB's register cache.  If REGNUM is -1,
121    do this for all registers.  */
122
123 void
124 fill_gregset (elf_gregset_t *gregsetp, int regnum)
125 {
126   amd64_collect_native_gregset (current_regcache, gregsetp, regnum);
127 }
128
129 /* Fetch all general-purpose registers from process/thread TID and
130    store their values in GDB's register cache.  */
131
132 static void
133 fetch_regs (int tid)
134 {
135   elf_gregset_t regs;
136
137   if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
138     perror_with_name ("Couldn't get registers");
139
140   supply_gregset (&regs);
141 }
142
143 /* Store all valid general-purpose registers in GDB's register cache
144    into the process/thread specified by TID.  */
145
146 static void
147 store_regs (int tid, int regnum)
148 {
149   elf_gregset_t regs;
150
151   if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
152     perror_with_name ("Couldn't get registers");
153
154   fill_gregset (&regs, regnum);
155
156   if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
157     perror_with_name ("Couldn't write registers");
158 }
159 \f
160
161 /* Transfering floating-point registers between GDB, inferiors and cores.  */
162
163 /* Fill GDB's register cache with the floating-point and SSE register
164    values in *FPREGSETP.  */
165
166 void
167 supply_fpregset (elf_fpregset_t *fpregsetp)
168 {
169   amd64_supply_fxsave (current_regcache, -1, fpregsetp);
170 }
171
172 /* Fill register REGNUM (if it is a floating-point or SSE register) in
173    *FPREGSETP with the value in GDB's register cache.  If REGNUM is
174    -1, do this for all registers.  */
175
176 void
177 fill_fpregset (elf_fpregset_t *fpregsetp, int regnum)
178 {
179   amd64_fill_fxsave ((char *) fpregsetp, regnum);
180 }
181
182 /* Fetch all floating-point registers from process/thread TID and store
183    thier values in GDB's register cache.  */
184
185 static void
186 fetch_fpregs (int tid)
187 {
188   elf_fpregset_t fpregs;
189
190   if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
191     perror_with_name ("Couldn't get floating point status");
192
193   supply_fpregset (&fpregs);
194 }
195
196 /* Store all valid floating-point registers in GDB's register cache
197    into the process/thread specified by TID.  */
198
199 static void
200 store_fpregs (int tid, int regnum)
201 {
202   elf_fpregset_t fpregs;
203
204   if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
205     perror_with_name ("Couldn't get floating point status");
206
207   fill_fpregset (&fpregs, regnum);
208
209   if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
210     perror_with_name ("Couldn't write floating point status");
211 }
212 \f
213
214 /* Transferring arbitrary registers between GDB and inferior.  */
215
216 /* Fetch register REGNUM from the child process.  If REGNUM is -1, do
217    this for all registers (including the floating point and SSE
218    registers).  */
219
220 void
221 fetch_inferior_registers (int regnum)
222 {
223   int tid;
224
225   /* GNU/Linux LWP ID's are process ID's.  */
226   tid = TIDGET (inferior_ptid);
227   if (tid == 0)
228     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
229
230   if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
231     {
232       fetch_regs (tid);
233       if (regnum != -1)
234         return;
235     }
236
237   if (regnum == -1 || GETFPREGS_SUPPLIES (regnum))
238     {
239       fetch_fpregs (tid);
240       return;
241     }
242
243   internal_error (__FILE__, __LINE__,
244                   "Got request for bad register number %d.", regnum);
245 }
246
247 /* Store register REGNUM back into the child process.  If REGNUM is
248    -1, do this for all registers (including the floating-point and SSE
249    registers).  */
250
251 void
252 store_inferior_registers (int regnum)
253 {
254   int tid;
255
256   /* GNU/Linux LWP ID's are process ID's.  */
257   tid = TIDGET (inferior_ptid);
258   if (tid == 0)
259     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
260
261   if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
262     {
263       store_regs (tid, regnum);
264       if (regnum != -1)
265         return;
266     }
267
268   if (regnum == -1 || GETFPREGS_SUPPLIES (regnum))
269     {
270       store_fpregs (tid, regnum);
271       return;
272     }
273
274   internal_error (__FILE__, __LINE__,
275                   "Got request to store bad register number %d.", regnum);
276 }
277 \f
278
279 static unsigned long
280 amd64_linux_dr_get (int regnum)
281 {
282   int tid;
283   unsigned long value;
284
285   /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
286      multi-threaded processes here.  For now, pretend there is just
287      one thread.  */
288   tid = PIDGET (inferior_ptid);
289
290   /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
291      ptrace call fails breaks debugging remote targets.  The correct
292      way to fix this is to add the hardware breakpoint and watchpoint
293      stuff to the target vectore.  For now, just return zero if the
294      ptrace call fails.  */
295   errno = 0;
296   value = ptrace (PT_READ_U, tid,
297                   offsetof (struct user, u_debugreg[regnum]), 0);
298   if (errno != 0)
299 #if 0
300     perror_with_name ("Couldn't read debug register");
301 #else
302     return 0;
303 #endif
304
305   return value;
306 }
307
308 static void
309 amd64_linux_dr_set (int regnum, unsigned long value)
310 {
311   int tid;
312
313   /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
314      multi-threaded processes here.  For now, pretend there is just
315      one thread.  */
316   tid = PIDGET (inferior_ptid);
317
318   errno = 0;
319   ptrace (PT_WRITE_U, tid, offsetof (struct user, u_debugreg[regnum]), value);
320   if (errno != 0)
321     perror_with_name ("Couldn't write debug register");
322 }
323
324 void
325 amd64_linux_dr_set_control (unsigned long control)
326 {
327   amd64_linux_dr_set (DR_CONTROL, control);
328 }
329
330 void
331 amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
332 {
333   gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
334
335   amd64_linux_dr_set (DR_FIRSTADDR + regnum, addr);
336 }
337
338 void
339 amd64_linux_dr_reset_addr (int regnum)
340 {
341   gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
342
343   amd64_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
344 }
345
346 unsigned long
347 amd64_linux_dr_get_status (void)
348 {
349   return amd64_linux_dr_get (DR_STATUS);
350 }
351 \f
352
353 ps_err_e
354 ps_get_thread_area (const struct ps_prochandle *ph,
355                     lwpid_t lwpid, int idx, void **base)
356 {
357 /* This definition comes from prctl.h, but some kernels may not have it.  */
358 #ifndef PTRACE_ARCH_PRCTL
359 #define PTRACE_ARCH_PRCTL      30
360 #endif
361
362   /* FIXME: ezannoni-2003-07-09 see comment above about include file order.
363      We could be getting bogus values for these two.  */
364   gdb_assert (FS < ELF_NGREG);
365   gdb_assert (GS < ELF_NGREG);
366   switch (idx)
367     {
368     case FS:
369       if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
370         return PS_OK;
371       break;
372     case GS:
373       if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
374         return PS_OK;
375       break;
376     default:                   /* Should not happen.  */
377       return PS_BADADDR;
378     }
379   return PS_ERR;               /* ptrace failed.  */
380 }
381 \f
382
383 void
384 child_post_startup_inferior (ptid_t ptid)
385 {
386   i386_cleanup_dregs ();
387   linux_child_post_startup_inferior (ptid);
388 }
389 \f
390
391 /* Provide a prototype to silence -Wmissing-prototypes.  */
392 void _initialize_amd64_linux_nat (void);
393
394 void
395 _initialize_amd64_linux_nat (void)
396 {
397   amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
398   amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
399   amd64_native_gregset64_reg_offset = amd64_linux_gregset64_reg_offset;
400
401   gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
402               == amd64_native_gregset32_num_regs);
403   gdb_assert (ARRAY_SIZE (amd64_linux_gregset64_reg_offset)
404               == amd64_native_gregset64_num_regs);
405 }