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