* i386gnu-nat.c: Include "i386-tdep.h".
[deliverable/binutils-gdb.git] / gdb / i386gnu-nat.c
CommitLineData
da59e081 1/* Low level interface to i386 running the GNU Hurd.
b6ba6518
KB
2 Copyright 1992, 1995, 1996, 1998, 2000, 2001
3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
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
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
c906108c 11
c5aa993b
JM
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.
c906108c 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c
SS
21
22#include "defs.h"
23#include "inferior.h"
24#include "floatformat.h"
4e052eda 25#include "regcache.h"
c906108c 26
780a49fa 27#include "gdb_assert.h"
c906108c 28#include <errno.h>
383d750b 29#include <stdio.h>
c906108c
SS
30
31#include <mach.h>
da59e081 32#include <mach_error.h>
c906108c
SS
33#include <mach/message.h>
34#include <mach/exception.h>
c906108c 35
4604bcad
MK
36#include "i386-tdep.h"
37
c906108c 38#include "gnu-nat.h"
383d750b 39#include "i387-nat.h"
c906108c 40
c906108c 41
da59e081
JM
42/* Offset to the thread_state_t location where REG is stored. */
43#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
c906108c 44
383d750b
MK
45/* At REG_OFFSET[N] is the offset to the thread_state_t location where
46 the GDB register N is stored. */
c5aa993b 47static int reg_offset[] =
c906108c 48{
c5aa993b
JM
49 REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
50 REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
51 REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
52 REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
c906108c
SS
53};
54
da59e081
JM
55#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
56
c906108c 57\f
da59e081
JM
58/* Get the whole floating-point state of THREAD and record the
59 values of the corresponding (pseudo) registers. */
60static void
61fetch_fpregs (struct proc *thread)
c906108c 62{
da59e081
JM
63 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
64 struct i386_float_state state;
da59e081 65 error_t err;
c906108c 66
da59e081
JM
67 err = thread_get_state (thread->port, i386_FLOAT_STATE,
68 (thread_state_t) &state, &count);
69 if (err)
c906108c 70 {
da59e081
JM
71 warning ("Couldn't fetch floating-point state from %s",
72 proc_string (thread));
73 return;
c906108c 74 }
da59e081 75
383d750b 76 if (!state.initialized)
da59e081 77 /* The floating-point state isn't initialized. */
c906108c 78 {
383d750b
MK
79 int i;
80
4604bcad 81 for (i = FP0_REGNUM; i <= FOP_REGNUM; i++)
da59e081
JM
82 supply_register (i, NULL);
83
84 return;
c906108c 85 }
da59e081
JM
86
87 /* Supply the floating-point registers. */
383d750b 88 i387_supply_fsave (state.hw_state);
c906108c 89}
da59e081
JM
90
91/* Fetch register REGNO, or all regs if REGNO is -1. */
c906108c 92void
da59e081 93gnu_fetch_registers (int regno)
c906108c
SS
94{
95 struct proc *thread;
c5aa993b 96
da59e081
JM
97 /* Make sure we know about new threads. */
98 inf_update_procs (current_inferior);
c906108c 99
39f77062 100 thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
c5aa993b 101 if (!thread)
da59e081 102 error ("Can't fetch registers from thread %d: No such thread",
39f77062 103 PIDGET (inferior_ptid));
c906108c 104
da59e081 105 if (regno < NUM_GREGS || regno == -1)
c906108c 106 {
da59e081 107 thread_state_t state;
383d750b 108
da59e081
JM
109 /* This does the dirty work for us. */
110 state = proc_get_state (thread, 0);
111 if (!state)
c906108c 112 {
da59e081
JM
113 warning ("Couldn't fetch registers from %s",
114 proc_string (thread));
115 return;
c906108c
SS
116 }
117
da59e081 118 if (regno == -1)
c906108c 119 {
da59e081 120 int i;
383d750b 121
da59e081 122 proc_debug (thread, "fetching all register");
383d750b 123
da59e081
JM
124 for (i = 0; i < NUM_GREGS; i++)
125 supply_register (i, REG_ADDR (state, i));
126 thread->fetched_regs = ~0;
c906108c
SS
127 }
128 else
129 {
da59e081 130 proc_debug (thread, "fetching register %s", REGISTER_NAME (regno));
383d750b 131
da59e081
JM
132 supply_register (regno, REG_ADDR (state, regno));
133 thread->fetched_regs |= (1 << regno);
c906108c
SS
134 }
135 }
da59e081
JM
136
137 if (regno >= NUM_GREGS || regno == -1)
138 {
139 proc_debug (thread, "fetching floating-point registers");
383d750b 140
da59e081
JM
141 fetch_fpregs (thread);
142 }
c906108c
SS
143}
144\f
da59e081
JM
145
146/* Store the whole floating-point state into THREAD using information
147 from the corresponding (pseudo) registers. */
148static void
383d750b 149store_fpregs (struct proc *thread, int regno)
da59e081
JM
150{
151 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
152 struct i386_float_state state;
153 error_t err;
c5aa993b 154
da59e081
JM
155 err = thread_get_state (thread->port, i386_FLOAT_STATE,
156 (thread_state_t) &state, &count);
157 if (err)
c906108c 158 {
da59e081
JM
159 warning ("Couldn't fetch floating-point state from %s",
160 proc_string (thread));
161 return;
c906108c 162 }
c5aa993b 163
383d750b
MK
164 /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
165 take into account REGISTER_VALID like the old code did? */
166 i387_fill_fsave (state.hw_state, regno);
167
da59e081
JM
168 err = thread_set_state (thread->port, i386_FLOAT_STATE,
169 (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
170 if (err)
c906108c 171 {
da59e081
JM
172 warning ("Couldn't store floating-point state into %s",
173 proc_string (thread));
174 return;
c906108c 175 }
c906108c 176}
c5aa993b 177
da59e081
JM
178/* Store at least register REGNO, or all regs if REGNO == -1. */
179void
180gnu_store_registers (int regno)
c5aa993b 181{
da59e081 182 struct proc *thread;
c906108c 183
da59e081
JM
184 /* Make sure we know about new threads. */
185 inf_update_procs (current_inferior);
c5aa993b 186
39f77062 187 thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
c906108c 188 if (!thread)
da59e081 189 error ("Couldn't store registers into thread %d: No such thread",
39f77062 190 PIDGET (inferior_ptid));
c906108c 191
da59e081 192 if (regno < NUM_GREGS || regno == -1)
c906108c 193 {
da59e081
JM
194 thread_state_t state;
195 thread_state_data_t old_state;
196 int was_aborted = thread->aborted;
197 int was_valid = thread->state_valid;
fb557744 198 int trace;
c906108c 199
da59e081
JM
200 if (!was_aborted && was_valid)
201 memcpy (&old_state, &thread->state, sizeof (old_state));
c906108c 202
da59e081
JM
203 state = proc_get_state (thread, 1);
204 if (!state)
205 {
206 warning ("Couldn't store registers into %s", proc_string (thread));
207 return;
208 }
c906108c 209
fb557744
MK
210 /* Save the T bit. We might try to restore the %eflags register
211 below, but changing the T bit would seriously confuse GDB. */
212 trace = ((struct i386_thread_state *)state)->efl & 0x100;
213
da59e081
JM
214 if (!was_aborted && was_valid)
215 /* See which registers have changed after aborting the thread. */
216 {
217 int check_regno;
218
219 for (check_regno = 0; check_regno < NUM_GREGS; check_regno++)
220 if ((thread->fetched_regs & (1 << check_regno))
221 && memcpy (REG_ADDR (&old_state, check_regno),
222 REG_ADDR (state, check_regno),
223 REGISTER_RAW_SIZE (check_regno)))
224 /* Register CHECK_REGNO has changed! Ack! */
225 {
226 warning ("Register %s changed after the thread was aborted",
227 REGISTER_NAME (check_regno));
228 if (regno >= 0 && regno != check_regno)
383d750b 229 /* Update GDB's copy of the register. */
da59e081
JM
230 supply_register (check_regno, REG_ADDR (state, check_regno));
231 else
232 warning ("... also writing this register! Suspicious...");
233 }
234 }
c906108c 235
da59e081
JM
236#define fill(state, regno) \
237 memcpy (REG_ADDR(state, regno), &registers[REGISTER_BYTE (regno)], \
238 REGISTER_RAW_SIZE (regno))
c906108c 239
da59e081
JM
240 if (regno == -1)
241 {
242 int i;
383d750b 243
da59e081 244 proc_debug (thread, "storing all registers");
c5aa993b 245
da59e081
JM
246 for (i = 0; i < NUM_GREGS; i++)
247 if (register_valid[i])
248 fill (state, i);
249 }
250 else
251 {
252 proc_debug (thread, "storing register %s", REGISTER_NAME (regno));
c906108c 253
780a49fa 254 gdb_assert (register_valid[regno]);
da59e081
JM
255 fill (state, regno);
256 }
fb557744
MK
257
258 /* Restore the T bit. */
259 ((struct i386_thread_state *)state)->efl &= ~0x100;
260 ((struct i386_thread_state *)state)->efl |= trace;
c906108c 261 }
c5aa993b 262
da59e081 263#undef fill
c906108c 264
da59e081
JM
265 if (regno >= NUM_GREGS || regno == -1)
266 {
267 proc_debug (thread, "storing floating-point registers");
383d750b
MK
268
269 store_fpregs (thread, regno);
da59e081 270 }
c906108c 271}
This page took 0.166239 seconds and 4 git commands to generate.