* gregset.h (struct regcache): Add forward declaration.
[deliverable/binutils-gdb.git] / gdb / i386gnu-nat.c
CommitLineData
da59e081 1/* Low level interface to i386 running the GNU Hurd.
f6052080 2
6aba47ca 3 Copyright (C) 1992, 1995, 1996, 1998, 2000, 2001, 2004, 2007
b6ba6518 4 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
197e01b6
EZ
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
c906108c
SS
22
23#include "defs.h"
24#include "inferior.h"
25#include "floatformat.h"
4e052eda 26#include "regcache.h"
c906108c 27
780a49fa 28#include "gdb_assert.h"
c906108c 29#include <errno.h>
383d750b 30#include <stdio.h>
3303a276 31#include "gdb_string.h"
c906108c
SS
32
33#include <mach.h>
da59e081 34#include <mach_error.h>
c906108c
SS
35#include <mach/message.h>
36#include <mach/exception.h>
c906108c 37
4604bcad
MK
38#include "i386-tdep.h"
39
c906108c 40#include "gnu-nat.h"
e750d25e 41#include "i387-tdep.h"
c906108c 42
57e76fac
MS
43#ifdef HAVE_SYS_PROCFS_H
44# include <sys/procfs.h>
45# include "gregset.h"
46#endif
c906108c 47
da59e081
JM
48/* Offset to the thread_state_t location where REG is stored. */
49#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
c906108c 50
383d750b
MK
51/* At REG_OFFSET[N] is the offset to the thread_state_t location where
52 the GDB register N is stored. */
c5aa993b 53static int reg_offset[] =
c906108c 54{
c5aa993b
JM
55 REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
56 REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
57 REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
58 REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
c906108c
SS
59};
60
da59e081 61#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
7f7fe91e 62#define CREG_ADDR(state, regnum) ((const char *)(state) + reg_offset[regnum])
da59e081 63
c906108c 64\f
3303a276
MK
65/* Get the whole floating-point state of THREAD and record the values
66 of the corresponding (pseudo) registers. */
67
da59e081
JM
68static void
69fetch_fpregs (struct proc *thread)
c906108c 70{
da59e081
JM
71 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
72 struct i386_float_state state;
da59e081 73 error_t err;
c906108c 74
da59e081
JM
75 err = thread_get_state (thread->port, i386_FLOAT_STATE,
76 (thread_state_t) &state, &count);
77 if (err)
c906108c 78 {
8a3fe4f8 79 warning (_("Couldn't fetch floating-point state from %s"),
da59e081
JM
80 proc_string (thread));
81 return;
c906108c 82 }
da59e081 83
383d750b 84 if (!state.initialized)
c906108c 85 {
3303a276
MK
86 /* The floating-point state isn't initialized. */
87 i387_supply_fsave (current_regcache, -1, NULL);
88 }
89 else
90 {
91 /* Supply the floating-point registers. */
92 i387_supply_fsave (current_regcache, -1, state.hw_state);
c906108c
SS
93 }
94}
da59e081 95
57e76fac
MS
96#ifdef HAVE_SYS_PROCFS_H
97/* These two calls are used by the core-regset.c code for
98 reading ELF core files. */
99void
7f7fe91e 100supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregs)
57e76fac
MS
101{
102 int i;
65e78234 103 for (i = 0; i < I386_NUM_GREGS; i++)
7f7fe91e 104 regcache_raw_supply (regcache, i, CREG_ADDR (gregs, i));
57e76fac
MS
105}
106
107void
7f7fe91e 108supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
57e76fac 109{
7f7fe91e 110 i387_supply_fsave (regcache, -1, fpregs);
57e76fac
MS
111}
112#endif
113
da59e081 114/* Fetch register REGNO, or all regs if REGNO is -1. */
c906108c 115void
da59e081 116gnu_fetch_registers (int regno)
c906108c
SS
117{
118 struct proc *thread;
c5aa993b 119
da59e081
JM
120 /* Make sure we know about new threads. */
121 inf_update_procs (current_inferior);
c906108c 122
39f77062 123 thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
c5aa993b 124 if (!thread)
8a3fe4f8 125 error (_("Can't fetch registers from thread %d: No such thread"),
39f77062 126 PIDGET (inferior_ptid));
c906108c 127
65e78234 128 if (regno < I386_NUM_GREGS || regno == -1)
c906108c 129 {
da59e081 130 thread_state_t state;
383d750b 131
da59e081
JM
132 /* This does the dirty work for us. */
133 state = proc_get_state (thread, 0);
134 if (!state)
c906108c 135 {
8a3fe4f8 136 warning (_("Couldn't fetch registers from %s"),
da59e081
JM
137 proc_string (thread));
138 return;
c906108c
SS
139 }
140
da59e081 141 if (regno == -1)
c906108c 142 {
da59e081 143 int i;
383d750b 144
da59e081 145 proc_debug (thread, "fetching all register");
383d750b 146
65e78234 147 for (i = 0; i < I386_NUM_GREGS; i++)
23a6d369 148 regcache_raw_supply (current_regcache, i, REG_ADDR (state, i));
da59e081 149 thread->fetched_regs = ~0;
c906108c
SS
150 }
151 else
152 {
da59e081 153 proc_debug (thread, "fetching register %s", REGISTER_NAME (regno));
383d750b 154
23a6d369
AC
155 regcache_raw_supply (current_regcache, regno,
156 REG_ADDR (state, regno));
da59e081 157 thread->fetched_regs |= (1 << regno);
c906108c
SS
158 }
159 }
da59e081 160
65e78234 161 if (regno >= I386_NUM_GREGS || regno == -1)
da59e081
JM
162 {
163 proc_debug (thread, "fetching floating-point registers");
383d750b 164
da59e081
JM
165 fetch_fpregs (thread);
166 }
c906108c
SS
167}
168\f
da59e081
JM
169
170/* Store the whole floating-point state into THREAD using information
171 from the corresponding (pseudo) registers. */
172static void
383d750b 173store_fpregs (struct proc *thread, int regno)
da59e081
JM
174{
175 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
176 struct i386_float_state state;
177 error_t err;
c5aa993b 178
da59e081
JM
179 err = thread_get_state (thread->port, i386_FLOAT_STATE,
180 (thread_state_t) &state, &count);
181 if (err)
c906108c 182 {
8a3fe4f8 183 warning (_("Couldn't fetch floating-point state from %s"),
da59e081
JM
184 proc_string (thread));
185 return;
c906108c 186 }
c5aa993b 187
383d750b 188 /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
8262ee23 189 take into account DEPRECATED_REGISTER_VALID like the old code did? */
26144df5 190 i387_collect_fsave (current_regcache, regno, state.hw_state);
383d750b 191
da59e081
JM
192 err = thread_set_state (thread->port, i386_FLOAT_STATE,
193 (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
194 if (err)
c906108c 195 {
8a3fe4f8 196 warning (_("Couldn't store floating-point state into %s"),
da59e081
JM
197 proc_string (thread));
198 return;
c906108c 199 }
c906108c 200}
c5aa993b 201
da59e081
JM
202/* Store at least register REGNO, or all regs if REGNO == -1. */
203void
204gnu_store_registers (int regno)
c5aa993b 205{
f6052080 206 struct regcache *regcache = current_regcache;
da59e081 207 struct proc *thread;
c906108c 208
da59e081
JM
209 /* Make sure we know about new threads. */
210 inf_update_procs (current_inferior);
c5aa993b 211
39f77062 212 thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
c906108c 213 if (!thread)
8a3fe4f8 214 error (_("Couldn't store registers into thread %d: No such thread"),
39f77062 215 PIDGET (inferior_ptid));
c906108c 216
65e78234 217 if (regno < I386_NUM_GREGS || regno == -1)
c906108c 218 {
da59e081
JM
219 thread_state_t state;
220 thread_state_data_t old_state;
221 int was_aborted = thread->aborted;
222 int was_valid = thread->state_valid;
fb557744 223 int trace;
c906108c 224
da59e081
JM
225 if (!was_aborted && was_valid)
226 memcpy (&old_state, &thread->state, sizeof (old_state));
c906108c 227
da59e081
JM
228 state = proc_get_state (thread, 1);
229 if (!state)
230 {
8a3fe4f8 231 warning (_("Couldn't store registers into %s"), proc_string (thread));
da59e081
JM
232 return;
233 }
c906108c 234
fb557744
MK
235 /* Save the T bit. We might try to restore the %eflags register
236 below, but changing the T bit would seriously confuse GDB. */
237 trace = ((struct i386_thread_state *)state)->efl & 0x100;
238
da59e081
JM
239 if (!was_aborted && was_valid)
240 /* See which registers have changed after aborting the thread. */
241 {
242 int check_regno;
243
65e78234 244 for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
da59e081
JM
245 if ((thread->fetched_regs & (1 << check_regno))
246 && memcpy (REG_ADDR (&old_state, check_regno),
247 REG_ADDR (state, check_regno),
3acba339 248 register_size (current_gdbarch, check_regno)))
da59e081
JM
249 /* Register CHECK_REGNO has changed! Ack! */
250 {
8a3fe4f8 251 warning (_("Register %s changed after the thread was aborted"),
da59e081
JM
252 REGISTER_NAME (check_regno));
253 if (regno >= 0 && regno != check_regno)
383d750b 254 /* Update GDB's copy of the register. */
f6052080 255 regcache_raw_supply (regcache, check_regno,
23a6d369 256 REG_ADDR (state, check_regno));
da59e081 257 else
8a3fe4f8 258 warning (_("... also writing this register! Suspicious..."));
da59e081
JM
259 }
260 }
c906108c 261
da59e081
JM
262 if (regno == -1)
263 {
264 int i;
383d750b 265
da59e081 266 proc_debug (thread, "storing all registers");
c5aa993b 267
65e78234 268 for (i = 0; i < I386_NUM_GREGS; i++)
f6052080 269 if (regcache_valid_p (regcache, i))
9b8607ce 270 regcache_raw_collect (regcache, i, REG_ADDR (state, i));
da59e081
JM
271 }
272 else
273 {
274 proc_debug (thread, "storing register %s", REGISTER_NAME (regno));
c906108c 275
f6052080 276 gdb_assert (regcache_valid_p (regcache, regno));
ecac404d 277 regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
da59e081 278 }
fb557744
MK
279
280 /* Restore the T bit. */
281 ((struct i386_thread_state *)state)->efl &= ~0x100;
282 ((struct i386_thread_state *)state)->efl |= trace;
c906108c 283 }
c5aa993b 284
65e78234 285 if (regno >= I386_NUM_GREGS || regno == -1)
da59e081
JM
286 {
287 proc_debug (thread, "storing floating-point registers");
383d750b
MK
288
289 store_fpregs (thread, regno);
da59e081 290 }
c906108c 291}
This page took 0.635798 seconds and 4 git commands to generate.