Fix the year on the following lines:
[deliverable/binutils-gdb.git] / gdb / i386gnu-nat.c
CommitLineData
da59e081 1/* Low level interface to i386 running the GNU Hurd.
fb557744 2 Copyright (C) 1992, 1995, 1996, 2000 Free Software Foundation, Inc.
c906108c 3
c5aa993b 4 This file is part of GDB.
c906108c 5
c5aa993b
JM
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
c906108c 10
c5aa993b
JM
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
c906108c 15
c5aa993b
JM
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
c906108c
SS
20
21#include "defs.h"
22#include "inferior.h"
23#include "floatformat.h"
24
780a49fa 25#include "gdb_assert.h"
c906108c
SS
26#include <stdio.h>
27#include <errno.h>
28
29#include <mach.h>
da59e081 30#include <mach_error.h>
c906108c
SS
31#include <mach/message.h>
32#include <mach/exception.h>
c906108c
SS
33
34#include "gnu-nat.h"
35
da59e081
JM
36/* The FPU hardware state. */
37struct env387
38{
39 unsigned short control;
40 unsigned short r0;
41 unsigned short status;
42 unsigned short r1;
43 unsigned short tag;
44 unsigned short r2;
45 unsigned long eip;
46 unsigned short code_seg;
47 unsigned short opcode;
48 unsigned long operand;
49 unsigned short operand_seg;
50 unsigned short r3;
51 unsigned char regs[8][10];
52};
c906108c 53
c906108c 54\f
da59e081
JM
55/* Offset to the thread_state_t location where REG is stored. */
56#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
c906108c 57
da59e081
JM
58/* At reg_offset[i] is the offset to the thread_state_t location where
59 the gdb registers[i] is stored. */
c5aa993b 60static int reg_offset[] =
c906108c 61{
c5aa993b
JM
62 REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
63 REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
64 REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
65 REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
c906108c
SS
66};
67
da59e081
JM
68#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
69
c906108c 70\f
da59e081
JM
71/* Get the whole floating-point state of THREAD and record the
72 values of the corresponding (pseudo) registers. */
73static void
74fetch_fpregs (struct proc *thread)
c906108c 75{
da59e081
JM
76 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
77 struct i386_float_state state;
78 struct env387 *ep = (struct env387 *) state.hw_state;
79 error_t err;
80 int i;
c906108c 81
da59e081
JM
82 err = thread_get_state (thread->port, i386_FLOAT_STATE,
83 (thread_state_t) &state, &count);
84 if (err)
c906108c 85 {
da59e081
JM
86 warning ("Couldn't fetch floating-point state from %s",
87 proc_string (thread));
88 return;
c906108c 89 }
da59e081
JM
90
91 if (! state.initialized)
92 /* The floating-point state isn't initialized. */
c906108c 93 {
da59e081
JM
94 for (i = FP0_REGNUM; i <= FP7_REGNUM; i++)
95 supply_register (i, NULL);
96 for (i = FIRST_FPU_CTRL_REGNUM; i <= LAST_FPU_CTRL_REGNUM; i++)
97 supply_register (i, NULL);
98
99 return;
c906108c 100 }
da59e081
JM
101
102 /* Supply the floating-point registers. */
103 for (i = 0; i < 8; i++)
104 supply_register (FP0_REGNUM + i, ep->regs[i]);
105
106 supply_register (FCTRL_REGNUM, (char *) &ep->control);
107 supply_register (FSTAT_REGNUM, (char *) &ep->status);
108 supply_register (FTAG_REGNUM, (char *) &ep->tag);
109 supply_register (FCOFF_REGNUM, (char *) &ep->eip);
110 supply_register (FDS_REGNUM, (char *) &ep->operand_seg);
111 supply_register (FDOFF_REGNUM, (char *) &ep->operand);
112
113 /* Store the code segment and opcode pseudo registers. */
114 {
115 long l;
116
117 l = ep->code_seg;
118 supply_register (FCS_REGNUM, (char *) &l);
119 l = ep->opcode & ((1 << 11) - 1);
120 supply_register (FOP_REGNUM, (char *) &l);
121 }
c906108c 122}
da59e081
JM
123
124/* Fetch register REGNO, or all regs if REGNO is -1. */
c906108c 125void
da59e081 126gnu_fetch_registers (int regno)
c906108c
SS
127{
128 struct proc *thread;
c5aa993b 129
da59e081
JM
130 /* Make sure we know about new threads. */
131 inf_update_procs (current_inferior);
c906108c
SS
132
133 thread = inf_tid_to_thread (current_inferior, inferior_pid);
c5aa993b 134 if (!thread)
da59e081
JM
135 error ("Can't fetch registers from thread %d: No such thread",
136 inferior_pid);
c906108c 137
da59e081 138 if (regno < NUM_GREGS || regno == -1)
c906108c 139 {
da59e081
JM
140 thread_state_t state;
141
142 /* This does the dirty work for us. */
143 state = proc_get_state (thread, 0);
144 if (!state)
c906108c 145 {
da59e081
JM
146 warning ("Couldn't fetch registers from %s",
147 proc_string (thread));
148 return;
c906108c
SS
149 }
150
da59e081 151 if (regno == -1)
c906108c 152 {
da59e081
JM
153 int i;
154
155 proc_debug (thread, "fetching all register");
156
157 for (i = 0; i < NUM_GREGS; i++)
158 supply_register (i, REG_ADDR (state, i));
159 thread->fetched_regs = ~0;
c906108c
SS
160 }
161 else
162 {
da59e081
JM
163 proc_debug (thread, "fetching register %s", REGISTER_NAME (regno));
164
165 supply_register (regno, REG_ADDR (state, regno));
166 thread->fetched_regs |= (1 << regno);
c906108c
SS
167 }
168 }
da59e081
JM
169
170 if (regno >= NUM_GREGS || regno == -1)
171 {
172 proc_debug (thread, "fetching floating-point registers");
173
174 fetch_fpregs (thread);
175 }
c906108c 176}
da59e081 177
c906108c 178\f
da59e081
JM
179/* Fill the i387 hardware state EP with selected data from the set of
180 (pseudo) registers specified by REGS and VALID. VALID is an array
181 indicating which registers in REGS are valid. If VALID is zero,
182 all registers are assumed to be valid. */
183static void
184convert_to_env387 (struct env387 *ep, char *regs, signed char *valid)
c906108c
SS
185{
186 int i;
c5aa993b 187
da59e081
JM
188 /* Fill in the floating-point registers. */
189 for (i = 0; i < 8; i++)
190 if (!valid || valid[i])
191 memcpy (ep->regs[i], &regs[REGISTER_BYTE (FP0_REGNUM + i)],
192 REGISTER_RAW_SIZE (FP0_REGNUM + i));
193
194#define fill(member, regno) \
195 if (!valid || valid[(regno)]) \
196 memcpy (&ep->member, &regs[REGISTER_BYTE (regno)], \
197 sizeof (ep->member));
198
199 fill (control, FCTRL_REGNUM);
200 fill (status, FSTAT_REGNUM);
201 fill (tag, FTAG_REGNUM);
202 fill (eip, FCOFF_REGNUM);
203 fill (operand, FDOFF_REGNUM);
204 fill (operand_seg, FDS_REGNUM);
205
206#undef fill
207
208 if (!valid || valid[FCS_REGNUM])
209 ep->code_seg =
210 (* (int *) &registers[REGISTER_BYTE (FCS_REGNUM)] & 0xffff);
211
212 if (!valid || valid[FOP_REGNUM])
213 ep->opcode =
214 ((* (int *) &registers[REGISTER_BYTE (FOP_REGNUM)] & ((1 << 11) - 1)));
215}
216
217/* Store the whole floating-point state into THREAD using information
218 from the corresponding (pseudo) registers. */
219static void
220store_fpregs (struct proc *thread)
221{
222 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
223 struct i386_float_state state;
224 error_t err;
c5aa993b 225
da59e081
JM
226 err = thread_get_state (thread->port, i386_FLOAT_STATE,
227 (thread_state_t) &state, &count);
228 if (err)
c906108c 229 {
da59e081
JM
230 warning ("Couldn't fetch floating-point state from %s",
231 proc_string (thread));
232 return;
c906108c 233 }
c5aa993b 234
da59e081
JM
235 convert_to_env387 ((struct env387 *) state.hw_state,
236 registers, register_valid);
237
238 err = thread_set_state (thread->port, i386_FLOAT_STATE,
239 (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
240 if (err)
c906108c 241 {
da59e081
JM
242 warning ("Couldn't store floating-point state into %s",
243 proc_string (thread));
244 return;
c906108c 245 }
c906108c 246}
c5aa993b 247
da59e081
JM
248/* Store at least register REGNO, or all regs if REGNO == -1. */
249void
250gnu_store_registers (int regno)
c5aa993b 251{
da59e081 252 struct proc *thread;
c906108c 253
da59e081
JM
254 /* Make sure we know about new threads. */
255 inf_update_procs (current_inferior);
c5aa993b 256
da59e081 257 thread = inf_tid_to_thread (current_inferior, inferior_pid);
c906108c 258 if (!thread)
da59e081
JM
259 error ("Couldn't store registers into thread %d: No such thread",
260 inferior_pid);
c906108c 261
da59e081 262 if (regno < NUM_GREGS || regno == -1)
c906108c 263 {
da59e081
JM
264 thread_state_t state;
265 thread_state_data_t old_state;
266 int was_aborted = thread->aborted;
267 int was_valid = thread->state_valid;
fb557744 268 int trace;
c906108c 269
da59e081
JM
270 if (!was_aborted && was_valid)
271 memcpy (&old_state, &thread->state, sizeof (old_state));
c906108c 272
da59e081
JM
273 state = proc_get_state (thread, 1);
274 if (!state)
275 {
276 warning ("Couldn't store registers into %s", proc_string (thread));
277 return;
278 }
c906108c 279
fb557744
MK
280 /* Save the T bit. We might try to restore the %eflags register
281 below, but changing the T bit would seriously confuse GDB. */
282 trace = ((struct i386_thread_state *)state)->efl & 0x100;
283
da59e081
JM
284 if (!was_aborted && was_valid)
285 /* See which registers have changed after aborting the thread. */
286 {
287 int check_regno;
288
289 for (check_regno = 0; check_regno < NUM_GREGS; check_regno++)
290 if ((thread->fetched_regs & (1 << check_regno))
291 && memcpy (REG_ADDR (&old_state, check_regno),
292 REG_ADDR (state, check_regno),
293 REGISTER_RAW_SIZE (check_regno)))
294 /* Register CHECK_REGNO has changed! Ack! */
295 {
296 warning ("Register %s changed after the thread was aborted",
297 REGISTER_NAME (check_regno));
298 if (regno >= 0 && regno != check_regno)
299 /* Update gdb's copy of the register. */
300 supply_register (check_regno, REG_ADDR (state, check_regno));
301 else
302 warning ("... also writing this register! Suspicious...");
303 }
304 }
c906108c 305
da59e081
JM
306#define fill(state, regno) \
307 memcpy (REG_ADDR(state, regno), &registers[REGISTER_BYTE (regno)], \
308 REGISTER_RAW_SIZE (regno))
c906108c 309
da59e081
JM
310 if (regno == -1)
311 {
312 int i;
313
314 proc_debug (thread, "storing all registers");
c5aa993b 315
da59e081
JM
316 for (i = 0; i < NUM_GREGS; i++)
317 if (register_valid[i])
318 fill (state, i);
319 }
320 else
321 {
322 proc_debug (thread, "storing register %s", REGISTER_NAME (regno));
c906108c 323
780a49fa 324 gdb_assert (register_valid[regno]);
da59e081
JM
325 fill (state, regno);
326 }
fb557744
MK
327
328 /* Restore the T bit. */
329 ((struct i386_thread_state *)state)->efl &= ~0x100;
330 ((struct i386_thread_state *)state)->efl |= trace;
c906108c 331 }
c5aa993b 332
da59e081 333#undef fill
c906108c 334
da59e081
JM
335 if (regno >= NUM_GREGS || regno == -1)
336 {
337 proc_debug (thread, "storing floating-point registers");
338
339 store_fpregs (thread);
340 }
c906108c 341}
This page took 0.118669 seconds and 4 git commands to generate.