gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / i386-fbsd-nat.c
CommitLineData
25630444 1/* Native-dependent code for FreeBSD/i386.
5d93ae8c 2
b811d2c2 3 Copyright (C) 2001-2020 Free Software Foundation, Inc.
25630444
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
25630444
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/>. */
25630444
MK
19
20#include "defs.h"
21#include "inferior.h"
22#include "regcache.h"
9692934b 23#include "target.h"
25630444
MK
24
25#include <sys/types.h>
26#include <sys/ptrace.h>
27#include <sys/sysctl.h>
cf424aef 28#include <sys/user.h>
25630444 29
9692934b 30#include "fbsd-nat.h"
f0925262 31#include "i386-tdep.h"
df7e5265 32#include "x86-nat.h"
268a13a5 33#include "gdbsupport/x86-xstate.h"
03b62bbb
SM
34#include "x86-bsd-nat.h"
35#include "i386-bsd-nat.h"
f0925262 36
f6ac5f3d
PA
37class i386_fbsd_nat_target final
38 : public i386_bsd_nat_target<fbsd_nat_target>
39{
40public:
41 /* Add some extra features to the common *BSD/i386 target. */
42#ifdef PT_GETXSTATE_INFO
43 const struct target_desc *read_description () override;
44#endif
45
46 void resume (ptid_t, int, enum gdb_signal) override;
47
48#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
57810aa7 49 bool supports_stopped_by_hw_breakpoint () override;
f6ac5f3d
PA
50#endif
51};
52
53static i386_fbsd_nat_target the_i386_fbsd_nat_target;
54
9692934b
MK
55/* Resume execution of the inferior process. If STEP is nonzero,
56 single-step it. If SIGNAL is nonzero, give it that signal. */
25630444 57
f6ac5f3d
PA
58void
59i386_fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
25630444 60{
e99b03dc 61 pid_t pid = ptid.pid ();
25630444
MK
62 int request = PT_STEP;
63
64 if (pid == -1)
65 /* Resume all threads. This only gets used in the non-threaded
66 case, where "resume all threads" and "resume inferior_ptid" are
67 the same. */
e99b03dc 68 pid = inferior_ptid.pid ();
25630444
MK
69
70 if (!step)
71 {
594f7785 72 struct regcache *regcache = get_current_regcache ();
f0925262 73 ULONGEST eflags;
25630444
MK
74
75 /* Workaround for a bug in FreeBSD. Make sure that the trace
76 flag is off when doing a continue. There is a code path
77 through the kernel which leaves the flag set when it should
78 have been cleared. If a process has a signal pending (such
79 as SIGALRM) and we do a PT_STEP, the process never really has
80 a chance to run because the kernel needs to notify the
81 debugger that a signal is being sent. Therefore, the process
82 never goes through the kernel's trap() function which would
83 normally clear it. */
84
594f7785 85 regcache_cooked_read_unsigned (regcache, I386_EFLAGS_REGNUM,
f0925262 86 &eflags);
25630444 87 if (eflags & 0x0100)
594f7785 88 regcache_cooked_write_unsigned (regcache, I386_EFLAGS_REGNUM,
f0925262 89 eflags & ~0x0100);
25630444
MK
90
91 request = PT_CONTINUE;
92 }
93
94 /* An addres of (caddr_t) 1 tells ptrace to continue from where it
95 was. (If GDB wanted it to start some other way, we have already
96 written a new PC value to the child.) */
97 if (ptrace (request, pid, (caddr_t) 1,
2ea28649 98 gdb_signal_to_host (signal)) == -1)
e2e0b3e5 99 perror_with_name (("ptrace"));
25630444
MK
100}
101\f
2e0c3539
MK
102
103/* Support for debugging kernel virtual memory images. */
104
2e0c3539
MK
105#include <machine/pcb.h>
106
107#include "bsd-kvm.h"
108
109static int
110i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
111{
112 /* The following is true for FreeBSD 4.7:
113
114 The pcb contains %eip, %ebx, %esp, %ebp, %esi, %edi and %gs.
115 This accounts for all callee-saved registers specified by the
116 psABI and then some. Here %esp contains the stack pointer at the
117 point just after the call to cpu_switch(). From this information
118 we reconstruct the register state as it would look when we just
119 returned from cpu_switch(). */
120
121 /* The stack pointer shouldn't be zero. */
122 if (pcb->pcb_esp == 0)
123 return 0;
124
125 pcb->pcb_esp += 4;
73e1c03f
SM
126 regcache->raw_supply (I386_EDI_REGNUM, &pcb->pcb_edi);
127 regcache->raw_supply (I386_ESI_REGNUM, &pcb->pcb_esi);
128 regcache->raw_supply (I386_EBP_REGNUM, &pcb->pcb_ebp);
129 regcache->raw_supply (I386_ESP_REGNUM, &pcb->pcb_esp);
130 regcache->raw_supply (I386_EBX_REGNUM, &pcb->pcb_ebx);
131 regcache->raw_supply (I386_EIP_REGNUM, &pcb->pcb_eip);
132 regcache->raw_supply (I386_GS_REGNUM, &pcb->pcb_gs);
2e0c3539
MK
133
134 return 1;
135}
136\f
137
97de3545 138#ifdef PT_GETXSTATE_INFO
f6ac5f3d 139/* Implement the read_description method. */
97de3545 140
f6ac5f3d
PA
141const struct target_desc *
142i386_fbsd_nat_target::read_description ()
97de3545
JB
143{
144 static int xsave_probed;
145 static uint64_t xcr0;
146
147 if (!xsave_probed)
148 {
149 struct ptrace_xstate_info info;
150
e99b03dc 151 if (ptrace (PT_GETXSTATE_INFO, inferior_ptid.pid (),
97de3545
JB
152 (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
153 {
a3405d12 154 x86bsd_xsave_len = info.xsave_len;
97de3545
JB
155 xcr0 = info.xsave_mask;
156 }
157 xsave_probed = 1;
158 }
159
ca1fa5ee
YQ
160 if (x86bsd_xsave_len == 0)
161 xcr0 = X86_XSTATE_SSE_MASK;
162
dd6876c9 163 return i386_target_description (xcr0, true);
97de3545
JB
164}
165#endif
166
f6ac5f3d
PA
167#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
168/* Implement the supports_stopped_by_hw_breakpoints method. */
9bb9e8ad 169
57810aa7 170bool
f6ac5f3d
PA
171i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint ()
172{
57810aa7 173 return true;
f6ac5f3d 174}
97de3545 175#endif
9bb9e8ad 176
6c265988 177void _initialize_i386fbsd_nat ();
f6ac5f3d 178void
6c265988 179_initialize_i386fbsd_nat ()
f6ac5f3d 180{
d9f719f1 181 add_inf_child_target (&the_i386_fbsd_nat_target);
9692934b 182
771e236c
MK
183 /* Support debugging kernel virtual memory images. */
184 bsd_kvm_add_target (i386fbsd_supply_pcb);
185
cf424aef
JB
186#ifdef KERN_PROC_SIGTRAMP
187 /* Normally signal frames are detected via i386fbsd_sigtramp_p.
188 However, FreeBSD 9.2 through 10.1 do not include the page holding
189 the signal code in core dumps. These releases do provide a
190 kern.proc.sigtramp.<pid> sysctl that returns the location of the
191 signal trampoline for a running process. We fetch the location
192 of the current (gdb) process and use this to identify signal
193 frames in core dumps from these releases. */
25630444 194 {
cf424aef
JB
195 int mib[4];
196 struct kinfo_sigtramp kst;
25630444
MK
197 size_t len;
198
199 mib[0] = CTL_KERN;
cf424aef
JB
200 mib[1] = KERN_PROC;
201 mib[2] = KERN_PROC_SIGTRAMP;
202 mib[3] = getpid ();
203 len = sizeof (kst);
204 if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0)
25630444 205 {
cf424aef
JB
206 i386fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start;
207 i386fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end;
25630444
MK
208 }
209 }
210#endif
211}
This page took 1.561175 seconds and 4 git commands to generate.