]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/amd64-fbsd-nat.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gdb / amd64-fbsd-nat.c
CommitLineData
68cc0bfb 1/* Native-dependent code for FreeBSD/amd64.
2a6d284d 2
b811d2c2 3 Copyright (C) 2003-2020 Free Software Foundation, Inc.
68cc0bfb
MK
4
5 This file is part of GDB.
6
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
68cc0bfb
MK
10 (at your option) any later version.
11
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.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
68cc0bfb
MK
19
20#include "defs.h"
4de283e4
TT
21#include "inferior.h"
22#include "regcache.h"
23#include "target.h"
68cc0bfb 24
68cc0bfb 25#include <signal.h>
4de283e4 26#include <sys/types.h>
68cc0bfb
MK
27#include <sys/ptrace.h>
28#include <sys/sysctl.h>
cf424aef 29#include <sys/user.h>
4de283e4 30#include <machine/reg.h>
68cc0bfb 31
d55e5aa6 32#include "fbsd-nat.h"
4de283e4
TT
33#include "amd64-tdep.h"
34#include "amd64-nat.h"
35#include "amd64-bsd-nat.h"
d55e5aa6 36#include "x86-nat.h"
268a13a5 37#include "gdbsupport/x86-xstate.h"
68cc0bfb
MK
38\f
39
f6ac5f3d
PA
40class amd64_fbsd_nat_target final
41 : public amd64_bsd_nat_target<fbsd_nat_target>
42{
43public:
44 /* Add some extra features to the common *BSD/amd64 target. */
45 const struct target_desc *read_description () override;
46
47#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
57810aa7 48 bool supports_stopped_by_hw_breakpoint () override;
f6ac5f3d
PA
49#endif
50};
51
52static amd64_fbsd_nat_target the_amd64_fbsd_nat_target;
53
cb461069
MK
54/* Offset in `struct reg' where MEMBER is stored. */
55#define REG_OFFSET(member) offsetof (struct reg, member)
68cc0bfb 56
cb461069
MK
57/* At amd64fbsd64_r_reg_offset[REGNUM] you'll find the offset in
58 `struct reg' location where the GDB register REGNUM is stored.
59 Unsupported registers are marked with `-1'. */
60static int amd64fbsd64_r_reg_offset[] =
68cc0bfb
MK
61{
62 REG_OFFSET (r_rax),
63 REG_OFFSET (r_rbx),
64 REG_OFFSET (r_rcx),
65 REG_OFFSET (r_rdx),
66 REG_OFFSET (r_rsi),
67 REG_OFFSET (r_rdi),
68 REG_OFFSET (r_rbp),
69 REG_OFFSET (r_rsp),
70 REG_OFFSET (r_r8),
71 REG_OFFSET (r_r9),
72 REG_OFFSET (r_r10),
73 REG_OFFSET (r_r11),
74 REG_OFFSET (r_r12),
75 REG_OFFSET (r_r13),
76 REG_OFFSET (r_r14),
77 REG_OFFSET (r_r15),
78 REG_OFFSET (r_rip),
79 REG_OFFSET (r_rflags),
af233647
MK
80 REG_OFFSET (r_cs),
81 REG_OFFSET (r_ss),
68cc0bfb
MK
82 -1,
83 -1,
84 -1,
85 -1
86};
2a6d284d
MK
87\f
88
89/* Mapping between the general-purpose registers in FreeBSD/amd64
90 `struct reg' format and GDB's register cache layout for
91 FreeBSD/i386.
68cc0bfb 92
2a6d284d
MK
93 Note that most FreeBSD/amd64 registers are 64-bit, while the
94 FreeBSD/i386 registers are all 32-bit, but since we're
95 little-endian we get away with that. */
68cc0bfb 96
2a6d284d
MK
97/* From <machine/reg.h>. */
98static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] =
99{
100 14 * 8, 13 * 8, /* %eax, %ecx */
101 12 * 8, 11 * 8, /* %edx, %ebx */
102 20 * 8, 10 * 8, /* %esp, %ebp */
103 9 * 8, 8 * 8, /* %esi, %edi */
104 17 * 8, 19 * 8, /* %eip, %eflags */
105 18 * 8, 21 * 8, /* %cs, %ss */
106 -1, -1, -1, -1 /* %ds, %es, %fs, %gs */
107};
68cc0bfb
MK
108\f
109
315c4276
MK
110/* Support for debugging kernel virtual memory images. */
111
315c4276 112#include <machine/pcb.h>
1f596238 113#include <osreldate.h>
315c4276
MK
114
115#include "bsd-kvm.h"
116
117static int
118amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
119{
120 /* The following is true for FreeBSD 5.2:
121
122 The pcb contains %rip, %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15,
123 %ds, %es, %fs and %gs. This accounts for all callee-saved
124 registers specified by the psABI and then some. Here %esp
125 contains the stack pointer at the point just after the call to
126 cpu_switch(). From this information we reconstruct the register
127 state as it would like when we just returned from cpu_switch(). */
128
129 /* The stack pointer shouldn't be zero. */
130 if (pcb->pcb_rsp == 0)
131 return 0;
132
133 pcb->pcb_rsp += 8;
73e1c03f
SM
134 regcache->raw_supply (AMD64_RIP_REGNUM, &pcb->pcb_rip);
135 regcache->raw_supply (AMD64_RBX_REGNUM, &pcb->pcb_rbx);
136 regcache->raw_supply (AMD64_RSP_REGNUM, &pcb->pcb_rsp);
137 regcache->raw_supply (AMD64_RBP_REGNUM, &pcb->pcb_rbp);
138 regcache->raw_supply (12, &pcb->pcb_r12);
139 regcache->raw_supply (13, &pcb->pcb_r13);
140 regcache->raw_supply (14, &pcb->pcb_r14);
141 regcache->raw_supply (15, &pcb->pcb_r15);
c1dec97b 142#if (__FreeBSD_version < 800075) && (__FreeBSD_kernel_version < 800075)
ffeecffa
JB
143 /* struct pcb provides the pcb_ds/pcb_es/pcb_fs/pcb_gs fields only
144 up until __FreeBSD_version 800074: The removal of these fields
145 occurred on 2009-04-01 while the __FreeBSD_version number was
146 bumped to 800075 on 2009-04-06. So 800075 is the closest version
147 number where we should not try to access these fields. */
73e1c03f
SM
148 regcache->raw_supply (AMD64_DS_REGNUM, &pcb->pcb_ds);
149 regcache->raw_supply (AMD64_ES_REGNUM, &pcb->pcb_es);
150 regcache->raw_supply (AMD64_FS_REGNUM, &pcb->pcb_fs);
151 regcache->raw_supply (AMD64_GS_REGNUM, &pcb->pcb_gs);
1f596238 152#endif
315c4276
MK
153
154 return 1;
155}
156\f
157
f6ac5f3d 158/* Implement the read_description method. */
97de3545 159
f6ac5f3d
PA
160const struct target_desc *
161amd64_fbsd_nat_target::read_description ()
97de3545
JB
162{
163#ifdef PT_GETXSTATE_INFO
164 static int xsave_probed;
165 static uint64_t xcr0;
166#endif
167 struct reg regs;
168 int is64;
169
e99b03dc 170 if (ptrace (PT_GETREGS, inferior_ptid.pid (),
97de3545
JB
171 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
172 perror_with_name (_("Couldn't get registers"));
173 is64 = (regs.r_cs == GSEL (GUCODE_SEL, SEL_UPL));
174#ifdef PT_GETXSTATE_INFO
175 if (!xsave_probed)
176 {
177 struct ptrace_xstate_info info;
178
e99b03dc 179 if (ptrace (PT_GETXSTATE_INFO, inferior_ptid.pid (),
97de3545
JB
180 (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
181 {
a3405d12 182 x86bsd_xsave_len = info.xsave_len;
97de3545
JB
183 xcr0 = info.xsave_mask;
184 }
185 xsave_probed = 1;
186 }
187
a3405d12 188 if (x86bsd_xsave_len != 0)
97de3545
JB
189 {
190 if (is64)
41206e32 191 return amd64_target_description (xcr0, true);
97de3545 192 else
dd6876c9 193 return i386_target_description (xcr0, true);
97de3545
JB
194 }
195#endif
196 if (is64)
41206e32 197 return amd64_target_description (X86_XSTATE_SSE_MASK, true);
97de3545 198 else
dd6876c9 199 return i386_target_description (X86_XSTATE_SSE_MASK, true);
97de3545
JB
200}
201
f6ac5f3d
PA
202#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
203/* Implement the supports_stopped_by_hw_breakpoints method. */
204
57810aa7 205bool
f6ac5f3d
PA
206amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint ()
207{
57810aa7 208 return true;
f6ac5f3d
PA
209}
210#endif
211
6c265988 212void _initialize_amd64fbsd_nat ();
68cc0bfb 213void
6c265988 214_initialize_amd64fbsd_nat ()
68cc0bfb
MK
215{
216 int offset;
217
2a6d284d 218 amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset;
cb461069 219 amd64_native_gregset64_reg_offset = amd64fbsd64_r_reg_offset;
2a6d284d 220
d9f719f1 221 add_inf_child_target (&the_amd64_fbsd_nat_target);
6a5c78a3
MK
222
223 /* Support debugging kernel virtual memory images. */
224 bsd_kvm_add_target (amd64fbsd_supply_pcb);
225
03b62bbb 226 /* To support the recognition of signal handlers, i386-bsd-tdep.c
68cc0bfb
MK
227 hardcodes some constants. Inclusion of this file means that we
228 are compiling a native debugger, which means that we can use the
229 system header files and sysctl(3) to get at the relevant
230 information. */
231
68cc0bfb
MK
232#define SC_REG_OFFSET amd64fbsd_sc_reg_offset
233
234 /* We only check the program counter, stack pointer and frame
235 pointer since these members of `struct sigcontext' are essential
236 for providing backtraces. */
237
90f90721
MK
238#define SC_RIP_OFFSET SC_REG_OFFSET[AMD64_RIP_REGNUM]
239#define SC_RSP_OFFSET SC_REG_OFFSET[AMD64_RSP_REGNUM]
240#define SC_RBP_OFFSET SC_REG_OFFSET[AMD64_RBP_REGNUM]
68cc0bfb
MK
241
242 /* Override the default value for the offset of the program counter
243 in the sigcontext structure. */
244 offset = offsetof (struct sigcontext, sc_rip);
245
246 if (SC_RIP_OFFSET != offset)
247 {
edefbb7c 248 warning (_("\
68cc0bfb 249offsetof (struct sigcontext, sc_rip) yields %d instead of %d.\n\
edefbb7c 250Please report this to <bug-gdb@gnu.org>."),
68cc0bfb
MK
251 offset, SC_RIP_OFFSET);
252 }
253
254 SC_RIP_OFFSET = offset;
255
256 /* Likewise for the stack pointer. */
257 offset = offsetof (struct sigcontext, sc_rsp);
258
259 if (SC_RSP_OFFSET != offset)
260 {
edefbb7c 261 warning (_("\
68cc0bfb 262offsetof (struct sigcontext, sc_rsp) yields %d instead of %d.\n\
edefbb7c 263Please report this to <bug-gdb@gnu.org>."),
68cc0bfb
MK
264 offset, SC_RSP_OFFSET);
265 }
266
267 SC_RSP_OFFSET = offset;
268
269 /* And the frame pointer. */
270 offset = offsetof (struct sigcontext, sc_rbp);
271
272 if (SC_RBP_OFFSET != offset)
273 {
edefbb7c 274 warning (_("\
68cc0bfb 275offsetof (struct sigcontext, sc_rbp) yields %d instead of %d.\n\
edefbb7c 276Please report this to <bug-gdb@gnu.org>."),
68cc0bfb
MK
277 offset, SC_RBP_OFFSET);
278 }
279
280 SC_RBP_OFFSET = offset;
281
cf424aef
JB
282#ifdef KERN_PROC_SIGTRAMP
283 /* Normally signal frames are detected via amd64fbsd_sigtramp_p.
284 However, FreeBSD 9.2 through 10.1 do not include the page holding
285 the signal code in core dumps. These releases do provide a
286 kern.proc.sigtramp.<pid> sysctl that returns the location of the
287 signal trampoline for a running process. We fetch the location
288 of the current (gdb) process and use this to identify signal
289 frames in core dumps from these releases. Note that this only
290 works for core dumps of 64-bit (FreeBSD/amd64) processes and does
291 not handle core dumps of 32-bit (FreeBSD/i386) processes. */
68cc0bfb 292 {
cf424aef
JB
293 int mib[4];
294 struct kinfo_sigtramp kst;
68cc0bfb
MK
295 size_t len;
296
68cc0bfb 297 mib[0] = CTL_KERN;
cf424aef
JB
298 mib[1] = KERN_PROC;
299 mib[2] = KERN_PROC_SIGTRAMP;
300 mib[3] = getpid ();
301 len = sizeof (kst);
302 if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0)
68cc0bfb 303 {
cf424aef
JB
304 amd64fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start;
305 amd64fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end;
68cc0bfb
MK
306 }
307 }
cf424aef 308#endif
68cc0bfb 309}