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