2004-02-28 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / amd64-linux-nat.c
CommitLineData
a4b6fc86 1/* Native-dependent code for GNU/Linux x86-64.
0a65a603 2
af233647 3 Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
53e95fcf
JS
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"
4056d258 27#include "linux-nat.h"
c4f35dd8 28
53e95fcf 29#include "gdb_assert.h"
30d52491 30#include "gdb_string.h"
53e95fcf
JS
31#include <sys/ptrace.h>
32#include <sys/debugreg.h>
33#include <sys/syscall.h>
34#include <sys/procfs.h>
c43af07c
EZ
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>
33a0a2ac 44#include <sys/reg.h>
c43af07c 45#include "gdb_proc_service.h"
33a0a2ac 46
c4f35dd8
MK
47/* Prototypes for supply_gregset etc. */
48#include "gregset.h"
49
9c1488cb
MK
50#include "amd64-tdep.h"
51#include "amd64-linux-tdep.h"
60fac5b8
MK
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
430eaf2e 58static int amd64_linux_gregset64_reg_offset[] =
60fac5b8
MK
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 */
af233647 69 CS * 8, SS * 8, /* %cs, %ss */
60fac5b8
MK
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. */
430eaf2e 84static int amd64_linux_gregset32_reg_offset[] =
60fac5b8 85{
f5859b4d
MK
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 */
60fac5b8
MK
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,
f5859b4d 97 ORIG_RAX * 8 /* "orig_eax" */
60fac5b8 98};
53e95fcf 99
c4f35dd8
MK
100/* Which ptrace request retrieves which registers?
101 These apply to the corresponding SET requests as well. */
53e95fcf 102
53e95fcf
JS
103#define GETFPREGS_SUPPLIES(regno) \
104 (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
53e95fcf
JS
105\f
106
107/* Transfering the general-purpose registers between GDB, inferiors
108 and core files. */
109
60fac5b8 110/* Fill GDB's register cache with the general-purpose register values
53e95fcf
JS
111 in *GREGSETP. */
112
113void
c4f35dd8 114supply_gregset (elf_gregset_t *gregsetp)
53e95fcf 115{
60fac5b8 116 amd64_supply_native_gregset (current_regcache, gregsetp, -1);
53e95fcf
JS
117}
118
60fac5b8
MK
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,
53e95fcf
JS
121 do this for all registers. */
122
123void
60fac5b8 124fill_gregset (elf_gregset_t *gregsetp, int regnum)
53e95fcf 125{
60fac5b8 126 amd64_collect_native_gregset (current_regcache, gregsetp, regnum);
53e95fcf
JS
127}
128
129/* Fetch all general-purpose registers from process/thread TID and
60fac5b8 130 store their values in GDB's register cache. */
53e95fcf
JS
131
132static void
133fetch_regs (int tid)
134{
135 elf_gregset_t regs;
136
137 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
7b3fabf0 138 perror_with_name ("Couldn't get registers");
53e95fcf
JS
139
140 supply_gregset (&regs);
141}
142
60fac5b8 143/* Store all valid general-purpose registers in GDB's register cache
53e95fcf
JS
144 into the process/thread specified by TID. */
145
146static void
60fac5b8 147store_regs (int tid, int regnum)
53e95fcf
JS
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
60fac5b8 154 fill_gregset (&regs, regnum);
53e95fcf
JS
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
60fac5b8 163/* Fill GDB's register cache with the floating-point and SSE register
c4f35dd8 164 values in *FPREGSETP. */
53e95fcf
JS
165
166void
c4f35dd8 167supply_fpregset (elf_fpregset_t *fpregsetp)
53e95fcf 168{
90f90721 169 amd64_supply_fxsave (current_regcache, -1, fpregsetp);
53e95fcf
JS
170}
171
8dda9770 172/* Fill register REGNUM (if it is a floating-point or SSE register) in
60fac5b8 173 *FPREGSETP with the value in GDB's register cache. If REGNUM is
c4f35dd8 174 -1, do this for all registers. */
53e95fcf
JS
175
176void
c4f35dd8 177fill_fpregset (elf_fpregset_t *fpregsetp, int regnum)
53e95fcf 178{
90f90721 179 amd64_fill_fxsave ((char *) fpregsetp, regnum);
53e95fcf
JS
180}
181
182/* Fetch all floating-point registers from process/thread TID and store
60fac5b8 183 thier values in GDB's register cache. */
53e95fcf
JS
184
185static void
186fetch_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
60fac5b8 196/* Store all valid floating-point registers in GDB's register cache
53e95fcf
JS
197 into the process/thread specified by TID. */
198
199static void
60fac5b8 200store_fpregs (int tid, int regnum)
53e95fcf
JS
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
60fac5b8 207 fill_fpregset (&fpregs, regnum);
53e95fcf
JS
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
60fac5b8 216/* Fetch register REGNUM from the child process. If REGNUM is -1, do
53e95fcf
JS
217 this for all registers (including the floating point and SSE
218 registers). */
219
220void
60fac5b8 221fetch_inferior_registers (int regnum)
53e95fcf
JS
222{
223 int tid;
224
a4b6fc86 225 /* GNU/Linux LWP ID's are process ID's. */
c4f35dd8
MK
226 tid = TIDGET (inferior_ptid);
227 if (tid == 0)
228 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
53e95fcf 229
60fac5b8 230 if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
53e95fcf
JS
231 {
232 fetch_regs (tid);
60fac5b8
MK
233 if (regnum != -1)
234 return;
53e95fcf
JS
235 }
236
60fac5b8 237 if (regnum == -1 || GETFPREGS_SUPPLIES (regnum))
53e95fcf
JS
238 {
239 fetch_fpregs (tid);
240 return;
241 }
242
243 internal_error (__FILE__, __LINE__,
60fac5b8 244 "Got request for bad register number %d.", regnum);
53e95fcf
JS
245}
246
60fac5b8
MK
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
53e95fcf 249 registers). */
c4f35dd8 250
53e95fcf 251void
60fac5b8 252store_inferior_registers (int regnum)
53e95fcf
JS
253{
254 int tid;
255
a4b6fc86 256 /* GNU/Linux LWP ID's are process ID's. */
c4f35dd8
MK
257 tid = TIDGET (inferior_ptid);
258 if (tid == 0)
259 tid = PIDGET (inferior_ptid); /* Not a threaded program. */
53e95fcf 260
60fac5b8 261 if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
53e95fcf 262 {
60fac5b8
MK
263 store_regs (tid, regnum);
264 if (regnum != -1)
265 return;
53e95fcf
JS
266 }
267
60fac5b8 268 if (regnum == -1 || GETFPREGS_SUPPLIES (regnum))
53e95fcf 269 {
60fac5b8 270 store_fpregs (tid, regnum);
53e95fcf
JS
271 return;
272 }
273
274 internal_error (__FILE__, __LINE__,
60fac5b8 275 "Got request to store bad register number %d.", regnum);
53e95fcf
JS
276}
277\f
278
c4f35dd8 279static unsigned long
430eaf2e 280amd64_linux_dr_get (int regnum)
c4f35dd8
MK
281{
282 int tid;
283 unsigned long value;
53e95fcf 284
c4f35dd8
MK
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);
53e95fcf 289
c4f35dd8
MK
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;
53e95fcf
JS
303#endif
304
c4f35dd8
MK
305 return value;
306}
53e95fcf
JS
307
308static void
430eaf2e 309amd64_linux_dr_set (int regnum, unsigned long value)
53e95fcf 310{
c4f35dd8 311 int tid;
53e95fcf 312
c4f35dd8
MK
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);
53e95fcf 317
c4f35dd8
MK
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}
53e95fcf 323
c4f35dd8 324void
430eaf2e 325amd64_linux_dr_set_control (unsigned long control)
c4f35dd8 326{
430eaf2e 327 amd64_linux_dr_set (DR_CONTROL, control);
c4f35dd8 328}
53e95fcf 329
c4f35dd8 330void
430eaf2e 331amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
b7c4cbf8 332{
c4f35dd8
MK
333 gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
334
430eaf2e 335 amd64_linux_dr_set (DR_FIRSTADDR + regnum, addr);
b7c4cbf8
AJ
336}
337
53e95fcf 338void
430eaf2e 339amd64_linux_dr_reset_addr (int regnum)
53e95fcf 340{
c4f35dd8
MK
341 gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
342
430eaf2e 343 amd64_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
53e95fcf 344}
8cfda98c 345
c4f35dd8 346unsigned long
430eaf2e 347amd64_linux_dr_get_status (void)
8cfda98c 348{
430eaf2e 349 return amd64_linux_dr_get (DR_STATUS);
8cfda98c 350}
5bca7895 351\f
c43af07c 352
394023e2
AC
353/* This function is called by libthread_db as part of its handling of
354 a request for a thread's local storage address. */
355
5bca7895 356ps_err_e
c43af07c
EZ
357ps_get_thread_area (const struct ps_prochandle *ph,
358 lwpid_t lwpid, int idx, void **base)
359{
394023e2
AC
360 switch (gdbarch_ptr_bit (current_gdbarch) == 32)
361 {
362 case bfd_mach_i386_i386:
363 case bfd_mach_i386_i386_intel_syntax:
364 {
365 /* The full structure is found in <asm-i386/ldt.h>. The
366 second integer is the LDT's base_address and that is used
367 to locate the thread's local storage. See i386-linux-nat.c
368 more info. */
369 unsigned int desc[4];
370
371 /* This code assumes that "int" is 32 bits and that
372 GET_THREAD_AREA returns no more than 4 int values. */
373 gdb_assert (sizeof (int) == 4);
374#ifndef PTRACE_GET_THREAD_AREA
375#define PTRACE_GET_THREAD_AREA 25
376#endif
377 if (ptrace (PTRACE_GET_THREAD_AREA,
378 lwpid, (void *) (long) idx, (unsigned long) &desc) < 0)
379 return PS_ERR;
380
381 /* Extend the value to 64 bits. Here it's assumed that a
382 "long" and a "void *" are the same. */
383 (*base) = (void *) (long) desc[1];
384 return PS_OK;
385 }
386
387 case bfd_mach_x86_64:
388 case bfd_mach_x86_64_intel_syntax:
389 /* This definition comes from prctl.h, but some kernels may not
390 have it. */
c43af07c
EZ
391#ifndef PTRACE_ARCH_PRCTL
392#define PTRACE_ARCH_PRCTL 30
393#endif
394023e2
AC
394 /* FIXME: ezannoni-2003-07-09 see comment above about include
395 file order. We could be getting bogus values for these two. */
396 gdb_assert (FS < ELF_NGREG);
397 gdb_assert (GS < ELF_NGREG);
398 switch (idx)
399 {
400 case FS:
401 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
402 return PS_OK;
403 break;
404 case GS:
405 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
406 return PS_OK;
407 break;
408 default: /* Should not happen. */
409 return PS_BADADDR;
410 }
411 return PS_ERR; /* ptrace failed. */
412
413 case bfd_mach_i386_i8086:
414 internal_error (__FILE__, __LINE__, "bad i8086 machine");
415 default:
416 internal_error (__FILE__, __LINE__, "bad_switch");
c43af07c 417 }
c43af07c 418}
5bca7895 419\f
c43af07c 420
4056d258
ML
421void
422child_post_startup_inferior (ptid_t ptid)
423{
424 i386_cleanup_dregs ();
425 linux_child_post_startup_inferior (ptid);
426}
60fac5b8
MK
427\f
428
429/* Provide a prototype to silence -Wmissing-prototypes. */
430eaf2e 430void _initialize_amd64_linux_nat (void);
60fac5b8
MK
431
432void
430eaf2e 433_initialize_amd64_linux_nat (void)
60fac5b8 434{
430eaf2e 435 amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
60fac5b8 436 amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
430eaf2e 437 amd64_native_gregset64_reg_offset = amd64_linux_gregset64_reg_offset;
60fac5b8 438
430eaf2e 439 gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
60fac5b8 440 == amd64_native_gregset32_num_regs);
430eaf2e 441 gdb_assert (ARRAY_SIZE (amd64_linux_gregset64_reg_offset)
60fac5b8
MK
442 == amd64_native_gregset64_num_regs);
443}
This page took 0.50887 seconds and 4 git commands to generate.