gdb/gdbserver:
[deliverable/binutils-gdb.git] / gdb / amd64bsd-nat.c
CommitLineData
cced5e27
MK
1/* Native-dependent code for AMD64 BSD's.
2
0b302171 3 Copyright (C) 2003-2004, 2007-2012 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. */
27#include "gdb_assert.h"
28#include <signal.h>
29#include <sys/types.h>
30#include <sys/ptrace.h>
31#include <machine/reg.h>
32
85be1ca6 33#include "amd64-tdep.h"
cced5e27 34#include "amd64-nat.h"
649c7061 35#include "amd64bsd-nat.h"
6a5c78a3 36#include "inf-ptrace.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
6a5c78a3 42static void
28439f5e
PA
43amd64bsd_fetch_inferior_registers (struct target_ops *ops,
44 struct regcache *regcache, int regnum)
cced5e27 45{
f8028488
MD
46 struct gdbarch *gdbarch = get_regcache_arch (regcache);
47
48 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
49 {
50 struct reg regs;
51
52 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
9f8e0089 53 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
edefbb7c 54 perror_with_name (_("Couldn't get registers"));
cced5e27 55
56be3814 56 amd64_supply_native_gregset (regcache, &regs, -1);
cced5e27
MK
57 if (regnum != -1)
58 return;
59 }
60
f8028488 61 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
62 {
63 struct fpreg fpregs;
64
65 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
9f8e0089 66 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 67 perror_with_name (_("Couldn't get floating point status"));
cced5e27 68
56be3814 69 amd64_supply_fxsave (regcache, -1, &fpregs);
cced5e27
MK
70 }
71}
72
73/* Store register REGNUM back into the inferior. If REGNUM is -1, do
74 this for all registers (including the floating-point registers). */
75
6a5c78a3 76static void
28439f5e
PA
77amd64bsd_store_inferior_registers (struct target_ops *ops,
78 struct regcache *regcache, int regnum)
cced5e27 79{
f8028488
MD
80 struct gdbarch *gdbarch = get_regcache_arch (regcache);
81
82 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
83 {
84 struct reg regs;
85
86 if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
9f8e0089 87 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
edefbb7c 88 perror_with_name (_("Couldn't get registers"));
cced5e27 89
56be3814 90 amd64_collect_native_gregset (regcache, &regs, regnum);
cced5e27
MK
91
92 if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
9f8e0089 93 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
edefbb7c 94 perror_with_name (_("Couldn't write registers"));
cced5e27
MK
95
96 if (regnum != -1)
97 return;
98 }
99
f8028488 100 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
cced5e27
MK
101 {
102 struct fpreg fpregs;
103
104 if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
9f8e0089 105 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 106 perror_with_name (_("Couldn't get floating point status"));
cced5e27 107
56be3814 108 amd64_collect_fxsave (regcache, regnum, &fpregs);
cced5e27
MK
109
110 if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
9f8e0089 111 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
edefbb7c 112 perror_with_name (_("Couldn't write floating point status"));
cced5e27
MK
113 }
114}
6a5c78a3
MK
115
116/* Create a prototype *BSD/amd64 target. The client can override it
117 with local methods. */
118
119struct target_ops *
120amd64bsd_target (void)
121{
122 struct target_ops *t;
123
124 t = inf_ptrace_target ();
125 t->to_fetch_registers = amd64bsd_fetch_inferior_registers;
126 t->to_store_registers = amd64bsd_store_inferior_registers;
127 return t;
128}
1916efaf
PA
129\f
130
131/* Support for debug registers. */
132
133#ifdef HAVE_PT_GETDBREGS
134
135static unsigned long
136amd64bsd_dr_get (ptid_t ptid, int regnum)
137{
138 struct dbreg dbregs;
139
140 if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
141 (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
142 perror_with_name (_("Couldn't read debug registers"));
143
144 return DBREG_DRX ((&dbregs), regnum);
145}
146
147static void
148amd64bsd_dr_set (int regnum, unsigned long value)
149{
150 struct dbreg dbregs;
151
152 if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
153 (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
154 perror_with_name (_("Couldn't get debug registers"));
155
156 /* For some mysterious reason, some of the reserved bits in the
157 debug control register get set. Mask these off, otherwise the
158 ptrace call below will fail. */
159 DBREG_DRX ((&dbregs), 7) &= ~(0xffffffff0000fc00);
160
161 DBREG_DRX ((&dbregs), regnum) = value;
162
163 if (ptrace (PT_SETDBREGS, PIDGET (inferior_ptid),
164 (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
165 perror_with_name (_("Couldn't write debug registers"));
166}
167
168void
169amd64bsd_dr_set_control (unsigned long control)
170{
171 amd64bsd_dr_set (7, control);
172}
173
174void
175amd64bsd_dr_set_addr (int regnum, CORE_ADDR addr)
176{
177 gdb_assert (regnum >= 0 && regnum <= 4);
178
179 amd64bsd_dr_set (regnum, addr);
180}
181
182CORE_ADDR
183amd64bsd_dr_get_addr (int regnum)
184{
185 return amd64bsd_dr_get (inferior_ptid, regnum);
186}
187
188unsigned long
189amd64bsd_dr_get_status (void)
190{
191 return amd64bsd_dr_get (inferior_ptid, 6);
192}
193
194unsigned long
195amd64bsd_dr_get_control (void)
196{
197 return amd64bsd_dr_get (inferior_ptid, 7);
198}
199
200#endif /* PT_GETDBREGS */
This page took 0.501342 seconds and 4 git commands to generate.