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