gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / amd64-bsd-nat.c
CommitLineData
cced5e27
MK
1/* Native-dependent code for AMD64 BSD's.
2
b811d2c2 3 Copyright (C) 2003-2020 Free Software Foundation, Inc.
cced5e27
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
cced5e27
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/>. */
cced5e27
MK
19
20#include "defs.h"
21#include "inferior.h"
22#include "regcache.h"
6a5c78a3 23#include "target.h"
cced5e27
MK
24
25/* We include <signal.h> to make sure `struct fxsave64' is defined on
26 NetBSD, since NetBSD's <machine/reg.h> needs it. */
cced5e27
MK
27#include <signal.h>
28#include <sys/types.h>
29#include <sys/ptrace.h>
30#include <machine/reg.h>
31
85be1ca6 32#include "amd64-tdep.h"
cced5e27 33#include "amd64-nat.h"
03b62bbb 34#include "x86-bsd-nat.h"
6a5c78a3 35#include "inf-ptrace.h"
9e38d619 36#include "amd64-bsd-nat.h"
cced5e27
MK
37\f
38
1ff700c2 39static PTRACE_TYPE_RET
1c0aa1fb
KR
40gdb_ptrace (PTRACE_TYPE_ARG1 request, ptid_t ptid, PTRACE_TYPE_ARG3 addr,
41 PTRACE_TYPE_ARG4 data)
42{
43#ifdef __NetBSD__
44 gdb_assert (data == 0);
45 /* Support for NetBSD threads: unlike other ptrace implementations in this
46 file, NetBSD requires that we pass both the pid and lwp. */
47 return ptrace (request, ptid.pid (), addr, ptid.lwp ());
48#else
49 pid_t pid = get_ptrace_pid (ptid);
50 return ptrace (request, pid, addr, data);
51#endif
52}
53
cced5e27
MK
54/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
55 for all registers (including the floating-point registers). */
56
f6ac5f3d
PA
57void
58amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
cced5e27 59{
ac7936df 60 struct gdbarch *gdbarch = regcache->arch ();
1c0aa1fb 61 ptid_t ptid = regcache->ptid ();
dd6876c9
JB
62#if defined(PT_GETFSBASE) || defined(PT_GETGSBASE)
63 const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
64#endif
f8028488
MD
65
66 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
67 {
68 struct reg regs;
69
1c0aa1fb 70 if (gdb_ptrace (PT_GETREGS, ptid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
edefbb7c 71 perror_with_name (_("Couldn't get registers"));
cced5e27 72
56be3814 73 amd64_supply_native_gregset (regcache, &regs, -1);
cced5e27
MK
74 if (regnum != -1)
75 return;
76 }
77
0aa37b65 78#ifdef PT_GETFSBASE
dd6876c9 79 if (regnum == -1 || regnum == tdep->fsbase_regnum)
0aa37b65
JB
80 {
81 register_t base;
82
1c0aa1fb 83 if (gdb_ptrace (PT_GETFSBASE, ptid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
0aa37b65
JB
84 perror_with_name (_("Couldn't get segment register fs_base"));
85
dd6876c9 86 regcache->raw_supply (tdep->fsbase_regnum, &base);
0aa37b65
JB
87 if (regnum != -1)
88 return;
89 }
90#endif
91#ifdef PT_GETGSBASE
dd6876c9 92 if (regnum == -1 || regnum == tdep->fsbase_regnum + 1)
0aa37b65
JB
93 {
94 register_t base;
95
1c0aa1fb 96 if (gdb_ptrace (PT_GETGSBASE, ptid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
0aa37b65
JB
97 perror_with_name (_("Couldn't get segment register gs_base"));
98
dd6876c9 99 regcache->raw_supply (tdep->fsbase_regnum + 1, &base);
0aa37b65
JB
100 if (regnum != -1)
101 return;
102 }
103#endif
104
f8028488 105 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
106 {
107 struct fpreg fpregs;
97de3545 108#ifdef PT_GETXSTATE_INFO
21002a63 109 void *xstateregs;
97de3545 110
a3405d12 111 if (x86bsd_xsave_len != 0)
97de3545 112 {
a3405d12 113 xstateregs = alloca (x86bsd_xsave_len);
1c0aa1fb 114 if (gdb_ptrace (PT_GETXSTATE, ptid, (PTRACE_TYPE_ARG3) xstateregs, 0)
49907934 115 == -1)
97de3545
JB
116 perror_with_name (_("Couldn't get extended state status"));
117
118 amd64_supply_xsave (regcache, -1, xstateregs);
119 return;
120 }
121#endif
cced5e27 122
1c0aa1fb 123 if (gdb_ptrace (PT_GETFPREGS, ptid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 124 perror_with_name (_("Couldn't get floating point status"));
cced5e27 125
56be3814 126 amd64_supply_fxsave (regcache, -1, &fpregs);
cced5e27
MK
127 }
128}
129
130/* Store register REGNUM back into the inferior. If REGNUM is -1, do
131 this for all registers (including the floating-point registers). */
132
f6ac5f3d
PA
133void
134amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum)
cced5e27 135{
ac7936df 136 struct gdbarch *gdbarch = regcache->arch ();
1c0aa1fb 137 ptid_t ptid = regcache->ptid ();
dd6876c9
JB
138#if defined(PT_SETFSBASE) || defined(PT_SETGSBASE)
139 const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
140#endif
f8028488
MD
141
142 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
143 {
144 struct reg regs;
145
1c0aa1fb 146 if (gdb_ptrace (PT_GETREGS, ptid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
edefbb7c 147 perror_with_name (_("Couldn't get registers"));
cced5e27 148
56be3814 149 amd64_collect_native_gregset (regcache, &regs, regnum);
cced5e27 150
1c0aa1fb 151 if (gdb_ptrace (PT_SETREGS, ptid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
edefbb7c 152 perror_with_name (_("Couldn't write registers"));
cced5e27
MK
153
154 if (regnum != -1)
155 return;
156 }
157
0aa37b65 158#ifdef PT_SETFSBASE
dd6876c9 159 if (regnum == -1 || regnum == tdep->fsbase_regnum)
0aa37b65
JB
160 {
161 register_t base;
162
dd6876c9
JB
163 /* Clear the full base value to support 32-bit targets. */
164 base = 0;
165 regcache->raw_collect (tdep->fsbase_regnum, &base);
0aa37b65 166
1c0aa1fb 167 if (gdb_ptrace (PT_SETFSBASE, ptid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
0aa37b65
JB
168 perror_with_name (_("Couldn't write segment register fs_base"));
169 if (regnum != -1)
170 return;
171 }
172#endif
173#ifdef PT_SETGSBASE
dd6876c9 174 if (regnum == -1 || regnum == tdep->fsbase_regnum + 1)
0aa37b65
JB
175 {
176 register_t base;
177
dd6876c9
JB
178 /* Clear the full base value to support 32-bit targets. */
179 base = 0;
180 regcache->raw_collect (tdep->fsbase_regnum + 1, &base);
0aa37b65 181
1c0aa1fb 182 if (gdb_ptrace (PT_SETGSBASE, ptid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
0aa37b65
JB
183 perror_with_name (_("Couldn't write segment register gs_base"));
184 if (regnum != -1)
185 return;
186 }
187#endif
188
f8028488 189 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
190 {
191 struct fpreg fpregs;
97de3545 192#ifdef PT_GETXSTATE_INFO
21002a63 193 void *xstateregs;
97de3545 194
a3405d12 195 if (x86bsd_xsave_len != 0)
97de3545 196 {
a3405d12 197 xstateregs = alloca (x86bsd_xsave_len);
1c0aa1fb 198 if (gdb_ptrace (PT_GETXSTATE, ptid, (PTRACE_TYPE_ARG3) xstateregs, 0)
49907934 199 == -1)
97de3545
JB
200 perror_with_name (_("Couldn't get extended state status"));
201
202 amd64_collect_xsave (regcache, regnum, xstateregs, 0);
203
1c0aa1fb
KR
204 if (gdb_ptrace (PT_SETXSTATE, ptid, (PTRACE_TYPE_ARG3) xstateregs,
205 x86bsd_xsave_len) == -1)
97de3545
JB
206 perror_with_name (_("Couldn't write extended state status"));
207 return;
208 }
209#endif
cced5e27 210
1c0aa1fb 211 if (gdb_ptrace (PT_GETFPREGS, ptid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 212 perror_with_name (_("Couldn't get floating point status"));
cced5e27 213
56be3814 214 amd64_collect_fxsave (regcache, regnum, &fpregs);
cced5e27 215
1c0aa1fb 216 if (gdb_ptrace (PT_SETFPREGS, ptid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 217 perror_with_name (_("Couldn't write floating point status"));
cced5e27
MK
218 }
219}
This page took 0.964862 seconds and 4 git commands to generate.