Include <alloca.h> conditionally
[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
39/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
40 for all registers (including the floating-point registers). */
41
f6ac5f3d
PA
42void
43amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
cced5e27 44{
ac7936df 45 struct gdbarch *gdbarch = regcache->arch ();
222312d3 46 pid_t pid = get_ptrace_pid (regcache->ptid ());
dd6876c9
JB
47#if defined(PT_GETFSBASE) || defined(PT_GETGSBASE)
48 const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
49#endif
f8028488
MD
50
51 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
52 {
53 struct reg regs;
54
49907934 55 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
edefbb7c 56 perror_with_name (_("Couldn't get registers"));
cced5e27 57
56be3814 58 amd64_supply_native_gregset (regcache, &regs, -1);
cced5e27
MK
59 if (regnum != -1)
60 return;
61 }
62
0aa37b65 63#ifdef PT_GETFSBASE
dd6876c9 64 if (regnum == -1 || regnum == tdep->fsbase_regnum)
0aa37b65
JB
65 {
66 register_t base;
67
68 if (ptrace (PT_GETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
69 perror_with_name (_("Couldn't get segment register fs_base"));
70
dd6876c9 71 regcache->raw_supply (tdep->fsbase_regnum, &base);
0aa37b65
JB
72 if (regnum != -1)
73 return;
74 }
75#endif
76#ifdef PT_GETGSBASE
dd6876c9 77 if (regnum == -1 || regnum == tdep->fsbase_regnum + 1)
0aa37b65
JB
78 {
79 register_t base;
80
81 if (ptrace (PT_GETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
82 perror_with_name (_("Couldn't get segment register gs_base"));
83
dd6876c9 84 regcache->raw_supply (tdep->fsbase_regnum + 1, &base);
0aa37b65
JB
85 if (regnum != -1)
86 return;
87 }
88#endif
89
f8028488 90 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
91 {
92 struct fpreg fpregs;
97de3545 93#ifdef PT_GETXSTATE_INFO
21002a63 94 void *xstateregs;
97de3545 95
a3405d12 96 if (x86bsd_xsave_len != 0)
97de3545 97 {
a3405d12 98 xstateregs = alloca (x86bsd_xsave_len);
49907934
JB
99 if (ptrace (PT_GETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, 0)
100 == -1)
97de3545
JB
101 perror_with_name (_("Couldn't get extended state status"));
102
103 amd64_supply_xsave (regcache, -1, xstateregs);
104 return;
105 }
106#endif
cced5e27 107
49907934 108 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 109 perror_with_name (_("Couldn't get floating point status"));
cced5e27 110
56be3814 111 amd64_supply_fxsave (regcache, -1, &fpregs);
cced5e27
MK
112 }
113}
114
115/* Store register REGNUM back into the inferior. If REGNUM is -1, do
116 this for all registers (including the floating-point registers). */
117
f6ac5f3d
PA
118void
119amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum)
cced5e27 120{
ac7936df 121 struct gdbarch *gdbarch = regcache->arch ();
222312d3 122 pid_t pid = get_ptrace_pid (regcache->ptid ());
dd6876c9
JB
123#if defined(PT_SETFSBASE) || defined(PT_SETGSBASE)
124 const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
125#endif
f8028488
MD
126
127 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
128 {
129 struct reg regs;
130
49907934 131 if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
edefbb7c 132 perror_with_name (_("Couldn't get registers"));
cced5e27 133
56be3814 134 amd64_collect_native_gregset (regcache, &regs, regnum);
cced5e27 135
49907934 136 if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
edefbb7c 137 perror_with_name (_("Couldn't write registers"));
cced5e27
MK
138
139 if (regnum != -1)
140 return;
141 }
142
0aa37b65 143#ifdef PT_SETFSBASE
dd6876c9 144 if (regnum == -1 || regnum == tdep->fsbase_regnum)
0aa37b65
JB
145 {
146 register_t base;
147
dd6876c9
JB
148 /* Clear the full base value to support 32-bit targets. */
149 base = 0;
150 regcache->raw_collect (tdep->fsbase_regnum, &base);
0aa37b65
JB
151
152 if (ptrace (PT_SETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
153 perror_with_name (_("Couldn't write segment register fs_base"));
154 if (regnum != -1)
155 return;
156 }
157#endif
158#ifdef PT_SETGSBASE
dd6876c9 159 if (regnum == -1 || regnum == tdep->fsbase_regnum + 1)
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 + 1, &base);
0aa37b65
JB
166
167 if (ptrace (PT_SETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1)
168 perror_with_name (_("Couldn't write segment register gs_base"));
169 if (regnum != -1)
170 return;
171 }
172#endif
173
f8028488 174 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
175 {
176 struct fpreg fpregs;
97de3545 177#ifdef PT_GETXSTATE_INFO
21002a63 178 void *xstateregs;
97de3545 179
a3405d12 180 if (x86bsd_xsave_len != 0)
97de3545 181 {
a3405d12 182 xstateregs = alloca (x86bsd_xsave_len);
49907934
JB
183 if (ptrace (PT_GETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, 0)
184 == -1)
97de3545
JB
185 perror_with_name (_("Couldn't get extended state status"));
186
187 amd64_collect_xsave (regcache, regnum, xstateregs, 0);
188
49907934
JB
189 if (ptrace (PT_SETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs,
190 x86bsd_xsave_len) == -1)
97de3545
JB
191 perror_with_name (_("Couldn't write extended state status"));
192 return;
193 }
194#endif
cced5e27 195
49907934 196 if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 197 perror_with_name (_("Couldn't get floating point status"));
cced5e27 198
56be3814 199 amd64_collect_fxsave (regcache, regnum, &fpregs);
cced5e27 200
49907934 201 if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 202 perror_with_name (_("Couldn't write floating point status"));
cced5e27
MK
203 }
204}
This page took 0.944385 seconds and 4 git commands to generate.