* configure.ac: Switch license to GPLv3.
[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 68static void
56be3814 69fetch_fpregs (struct regcache *regcache, 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 86 /* The floating-point state isn't initialized. */
56be3814 87 i387_supply_fsave (regcache, -1, NULL);
3303a276
MK
88 }
89 else
90 {
91 /* Supply the floating-point registers. */
56be3814 92 i387_supply_fsave (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
56be3814 116gnu_fetch_registers (struct regcache *regcache, 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++)
56be3814 148 regcache_raw_supply (regcache, i, REG_ADDR (state, i));
da59e081 149 thread->fetched_regs = ~0;
c906108c
SS
150 }
151 else
152 {
c9f4d572
UW
153 proc_debug (thread, "fetching register %s",
154 gdbarch_register_name (current_gdbarch, regno));
383d750b 155
56be3814 156 regcache_raw_supply (regcache, regno,
23a6d369 157 REG_ADDR (state, regno));
da59e081 158 thread->fetched_regs |= (1 << regno);
c906108c
SS
159 }
160 }
da59e081 161
65e78234 162 if (regno >= I386_NUM_GREGS || regno == -1)
da59e081
JM
163 {
164 proc_debug (thread, "fetching floating-point registers");
383d750b 165
56be3814 166 fetch_fpregs (regcache, thread);
da59e081 167 }
c906108c
SS
168}
169\f
da59e081
JM
170
171/* Store the whole floating-point state into THREAD using information
172 from the corresponding (pseudo) registers. */
173static void
56be3814 174store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
da59e081
JM
175{
176 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
177 struct i386_float_state state;
178 error_t err;
c5aa993b 179
da59e081
JM
180 err = thread_get_state (thread->port, i386_FLOAT_STATE,
181 (thread_state_t) &state, &count);
182 if (err)
c906108c 183 {
8a3fe4f8 184 warning (_("Couldn't fetch floating-point state from %s"),
da59e081
JM
185 proc_string (thread));
186 return;
c906108c 187 }
c5aa993b 188
383d750b 189 /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
8262ee23 190 take into account DEPRECATED_REGISTER_VALID like the old code did? */
56be3814 191 i387_collect_fsave (regcache, regno, state.hw_state);
383d750b 192
da59e081
JM
193 err = thread_set_state (thread->port, i386_FLOAT_STATE,
194 (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
195 if (err)
c906108c 196 {
8a3fe4f8 197 warning (_("Couldn't store floating-point state into %s"),
da59e081
JM
198 proc_string (thread));
199 return;
c906108c 200 }
c906108c 201}
c5aa993b 202
da59e081
JM
203/* Store at least register REGNO, or all regs if REGNO == -1. */
204void
56be3814 205gnu_store_registers (struct regcache *regcache, int regno)
c5aa993b 206{
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"),
c9f4d572 252 gdbarch_register_name (current_gdbarch, check_regno));
da59e081 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 {
c9f4d572
UW
274 proc_debug (thread, "storing register %s",
275 gdbarch_register_name (current_gdbarch, regno));
c906108c 276
f6052080 277 gdb_assert (regcache_valid_p (regcache, regno));
ecac404d 278 regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
da59e081 279 }
fb557744
MK
280
281 /* Restore the T bit. */
282 ((struct i386_thread_state *)state)->efl &= ~0x100;
283 ((struct i386_thread_state *)state)->efl |= trace;
c906108c 284 }
c5aa993b 285
65e78234 286 if (regno >= I386_NUM_GREGS || regno == -1)
da59e081
JM
287 {
288 proc_debug (thread, "storing floating-point registers");
383d750b 289
56be3814 290 store_fpregs (regcache, thread, regno);
da59e081 291 }
c906108c 292}
This page took 0.755146 seconds and 4 git commands to generate.