1 /* Native-dependent code for FreeBSD/amd64.
3 Copyright 2003, 2004 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
26 #include "gdb_assert.h"
29 #include <sys/types.h>
30 #include <sys/ptrace.h>
31 #include <sys/sysctl.h>
33 #include <machine/reg.h>
35 #ifdef HAVE_SYS_PROCFS_H
36 #include <sys/procfs.h>
39 #ifndef HAVE_GREGSET_T
40 typedef struct reg gregset_t;
43 #ifndef HAVE_FPREGSET_T
44 typedef struct fpreg fpregset_t;
48 #include "amd64-tdep.h"
49 #include "amd64-nat.h"
52 /* Offset to the gregset_t location where REG is stored. */
53 #define REG_OFFSET(reg) offsetof (gregset_t, reg)
55 /* At reg_offset[REGNUM] you'll find the offset to the gregset_t
56 location where the GDB register REGNUM is stored. Unsupported
57 registers are marked with `-1'. */
58 static int reg_offset[] =
77 REG_OFFSET (r_rflags),
87 /* Mapping between the general-purpose registers in FreeBSD/amd64
88 `struct reg' format and GDB's register cache layout for
91 Note that most FreeBSD/amd64 registers are 64-bit, while the
92 FreeBSD/i386 registers are all 32-bit, but since we're
93 little-endian we get away with that. */
95 /* From <machine/reg.h>. */
96 static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] =
98 14 * 8, 13 * 8, /* %eax, %ecx */
99 12 * 8, 11 * 8, /* %edx, %ebx */
100 20 * 8, 10 * 8, /* %esp, %ebp */
101 9 * 8, 8 * 8, /* %esi, %edi */
102 17 * 8, 19 * 8, /* %eip, %eflags */
103 18 * 8, 21 * 8, /* %cs, %ss */
104 -1, -1, -1, -1 /* %ds, %es, %fs, %gs */
108 /* Transfering the registers between GDB, inferiors and core files. */
110 /* Fill GDB's register array with the general-purpose register values
114 supply_gregset (gregset_t *gregsetp)
116 amd64_supply_native_gregset (current_regcache, gregsetp, -1);
119 /* Fill register REGNUM (if it is a general-purpose register) in
120 *GREGSETPS with the value in GDB's register array. If REGNUM is -1,
121 do this for all registers. */
124 fill_gregset (gregset_t *gregsetp, int regnum)
126 amd64_collect_native_gregset (current_regcache, gregsetp, regnum);
129 /* Fill GDB's register array with the floating-point register values
133 supply_fpregset (fpregset_t *fpregsetp)
135 amd64_supply_fxsave (current_regcache, -1, fpregsetp);
138 /* Fill register REGNUM (if it is a floating-point register) in
139 *FPREGSETP with the value in GDB's register array. If REGNUM is -1,
140 do this for all registers. */
143 fill_fpregset (fpregset_t *fpregsetp, int regnum)
145 amd64_fill_fxsave ((char *) fpregsetp, regnum);
149 /* Provide a prototype to silence -Wmissing-prototypes. */
150 void _initialize_amd64fbsd_nat (void);
153 _initialize_amd64fbsd_nat (void)
157 amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset;
158 amd64_native_gregset64_reg_offset = reg_offset;
160 /* To support the recognition of signal handlers, i386bsd-tdep.c
161 hardcodes some constants. Inclusion of this file means that we
162 are compiling a native debugger, which means that we can use the
163 system header files and sysctl(3) to get at the relevant
166 #define SC_REG_OFFSET amd64fbsd_sc_reg_offset
168 /* We only check the program counter, stack pointer and frame
169 pointer since these members of `struct sigcontext' are essential
170 for providing backtraces. */
172 #define SC_RIP_OFFSET SC_REG_OFFSET[AMD64_RIP_REGNUM]
173 #define SC_RSP_OFFSET SC_REG_OFFSET[AMD64_RSP_REGNUM]
174 #define SC_RBP_OFFSET SC_REG_OFFSET[AMD64_RBP_REGNUM]
176 /* Override the default value for the offset of the program counter
177 in the sigcontext structure. */
178 offset = offsetof (struct sigcontext, sc_rip);
180 if (SC_RIP_OFFSET != offset)
183 offsetof (struct sigcontext, sc_rip) yields %d instead of %d.\n\
184 Please report this to <bug-gdb@gnu.org>.",
185 offset, SC_RIP_OFFSET);
188 SC_RIP_OFFSET = offset;
190 /* Likewise for the stack pointer. */
191 offset = offsetof (struct sigcontext, sc_rsp);
193 if (SC_RSP_OFFSET != offset)
196 offsetof (struct sigcontext, sc_rsp) yields %d instead of %d.\n\
197 Please report this to <bug-gdb@gnu.org>.",
198 offset, SC_RSP_OFFSET);
201 SC_RSP_OFFSET = offset;
203 /* And the frame pointer. */
204 offset = offsetof (struct sigcontext, sc_rbp);
206 if (SC_RBP_OFFSET != offset)
209 offsetof (struct sigcontext, sc_rbp) yields %d instead of %d.\n\
210 Please report this to <bug-gdb@gnu.org>.",
211 offset, SC_RBP_OFFSET);
214 SC_RBP_OFFSET = offset;
216 /* FreeBSD provides a kern.proc.sigtramp sysctl that we can use to
217 locate the sigtramp. That way we can still recognize a sigtramp
218 if its location is changed in a new kernel. */
221 struct kinfo_sigtramp kst;
226 mib[2] = KERN_PROC_SIGTRAMP;
229 if (sysctl (mib, sizeof(mib) / sizeof(mib[0]), &kst, &len, NULL, 0) == 0)
231 amd64fbsd_sigtramp_start_addr = kst.ksigtramp_start;
232 amd64fbsd_sigtramp_end_addr = kst.ksigtramp_end;