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