1 /* Low level interface to i386 running the GNU Hurd.
2 Copyright 1992, 1995, 1996, 1998, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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. */
24 #include "floatformat.h"
27 #include "gdb_assert.h"
32 #include <mach_error.h>
33 #include <mach/message.h>
34 #include <mach/exception.h>
38 /* The FPU hardware state. */
41 unsigned short control
;
43 unsigned short status
;
48 unsigned short code_seg
;
49 unsigned short opcode
;
50 unsigned long operand
;
51 unsigned short operand_seg
;
53 unsigned char regs
[8][10];
57 /* Offset to the thread_state_t location where REG is stored. */
58 #define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
60 /* At reg_offset[i] is the offset to the thread_state_t location where
61 the gdb registers[i] is stored. */
62 static int reg_offset
[] =
64 REG_OFFSET (eax
), REG_OFFSET (ecx
), REG_OFFSET (edx
), REG_OFFSET (ebx
),
65 REG_OFFSET (uesp
), REG_OFFSET (ebp
), REG_OFFSET (esi
), REG_OFFSET (edi
),
66 REG_OFFSET (eip
), REG_OFFSET (efl
), REG_OFFSET (cs
), REG_OFFSET (ss
),
67 REG_OFFSET (ds
), REG_OFFSET (es
), REG_OFFSET (fs
), REG_OFFSET (gs
)
70 #define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
73 /* Get the whole floating-point state of THREAD and record the
74 values of the corresponding (pseudo) registers. */
76 fetch_fpregs (struct proc
*thread
)
78 mach_msg_type_number_t count
= i386_FLOAT_STATE_COUNT
;
79 struct i386_float_state state
;
80 struct env387
*ep
= (struct env387
*) state
.hw_state
;
84 err
= thread_get_state (thread
->port
, i386_FLOAT_STATE
,
85 (thread_state_t
) &state
, &count
);
88 warning ("Couldn't fetch floating-point state from %s",
89 proc_string (thread
));
93 if (! state
.initialized
)
94 /* The floating-point state isn't initialized. */
96 for (i
= FP0_REGNUM
; i
<= FP7_REGNUM
; i
++)
97 supply_register (i
, NULL
);
98 for (i
= FIRST_FPU_CTRL_REGNUM
; i
<= LAST_FPU_CTRL_REGNUM
; i
++)
99 supply_register (i
, NULL
);
104 /* Supply the floating-point registers. */
105 for (i
= 0; i
< 8; i
++)
106 supply_register (FP0_REGNUM
+ i
, ep
->regs
[i
]);
108 supply_register (FCTRL_REGNUM
, (char *) &ep
->control
);
109 supply_register (FSTAT_REGNUM
, (char *) &ep
->status
);
110 supply_register (FTAG_REGNUM
, (char *) &ep
->tag
);
111 supply_register (FCOFF_REGNUM
, (char *) &ep
->eip
);
112 supply_register (FDS_REGNUM
, (char *) &ep
->operand_seg
);
113 supply_register (FDOFF_REGNUM
, (char *) &ep
->operand
);
115 /* Store the code segment and opcode pseudo registers. */
120 supply_register (FCS_REGNUM
, (char *) &l
);
121 l
= ep
->opcode
& ((1 << 11) - 1);
122 supply_register (FOP_REGNUM
, (char *) &l
);
126 /* Fetch register REGNO, or all regs if REGNO is -1. */
128 gnu_fetch_registers (int regno
)
132 /* Make sure we know about new threads. */
133 inf_update_procs (current_inferior
);
135 thread
= inf_tid_to_thread (current_inferior
, inferior_pid
);
137 error ("Can't fetch registers from thread %d: No such thread",
140 if (regno
< NUM_GREGS
|| regno
== -1)
142 thread_state_t state
;
144 /* This does the dirty work for us. */
145 state
= proc_get_state (thread
, 0);
148 warning ("Couldn't fetch registers from %s",
149 proc_string (thread
));
157 proc_debug (thread
, "fetching all register");
159 for (i
= 0; i
< NUM_GREGS
; i
++)
160 supply_register (i
, REG_ADDR (state
, i
));
161 thread
->fetched_regs
= ~0;
165 proc_debug (thread
, "fetching register %s", REGISTER_NAME (regno
));
167 supply_register (regno
, REG_ADDR (state
, regno
));
168 thread
->fetched_regs
|= (1 << regno
);
172 if (regno
>= NUM_GREGS
|| regno
== -1)
174 proc_debug (thread
, "fetching floating-point registers");
176 fetch_fpregs (thread
);
181 /* Fill the i387 hardware state EP with selected data from the set of
182 (pseudo) registers specified by REGS and VALID. VALID is an array
183 indicating which registers in REGS are valid. If VALID is zero,
184 all registers are assumed to be valid. */
186 convert_to_env387 (struct env387
*ep
, char *regs
, signed char *valid
)
190 /* Fill in the floating-point registers. */
191 for (i
= 0; i
< 8; i
++)
192 if (!valid
|| valid
[i
])
193 memcpy (ep
->regs
[i
], ®s
[REGISTER_BYTE (FP0_REGNUM
+ i
)],
194 REGISTER_RAW_SIZE (FP0_REGNUM
+ i
));
196 #define fill(member, regno) \
197 if (!valid || valid[(regno)]) \
198 memcpy (&ep->member, ®s[REGISTER_BYTE (regno)], \
199 sizeof (ep->member));
201 fill (control
, FCTRL_REGNUM
);
202 fill (status
, FSTAT_REGNUM
);
203 fill (tag
, FTAG_REGNUM
);
204 fill (eip
, FCOFF_REGNUM
);
205 fill (operand
, FDOFF_REGNUM
);
206 fill (operand_seg
, FDS_REGNUM
);
210 if (!valid
|| valid
[FCS_REGNUM
])
212 (* (int *) ®isters
[REGISTER_BYTE (FCS_REGNUM
)] & 0xffff);
214 if (!valid
|| valid
[FOP_REGNUM
])
216 ((* (int *) ®isters
[REGISTER_BYTE (FOP_REGNUM
)] & ((1 << 11) - 1)));
219 /* Store the whole floating-point state into THREAD using information
220 from the corresponding (pseudo) registers. */
222 store_fpregs (struct proc
*thread
)
224 mach_msg_type_number_t count
= i386_FLOAT_STATE_COUNT
;
225 struct i386_float_state state
;
228 err
= thread_get_state (thread
->port
, i386_FLOAT_STATE
,
229 (thread_state_t
) &state
, &count
);
232 warning ("Couldn't fetch floating-point state from %s",
233 proc_string (thread
));
237 convert_to_env387 ((struct env387
*) state
.hw_state
,
238 registers
, register_valid
);
240 err
= thread_set_state (thread
->port
, i386_FLOAT_STATE
,
241 (thread_state_t
) &state
, i386_FLOAT_STATE_COUNT
);
244 warning ("Couldn't store floating-point state into %s",
245 proc_string (thread
));
250 /* Store at least register REGNO, or all regs if REGNO == -1. */
252 gnu_store_registers (int regno
)
256 /* Make sure we know about new threads. */
257 inf_update_procs (current_inferior
);
259 thread
= inf_tid_to_thread (current_inferior
, inferior_pid
);
261 error ("Couldn't store registers into thread %d: No such thread",
264 if (regno
< NUM_GREGS
|| regno
== -1)
266 thread_state_t state
;
267 thread_state_data_t old_state
;
268 int was_aborted
= thread
->aborted
;
269 int was_valid
= thread
->state_valid
;
272 if (!was_aborted
&& was_valid
)
273 memcpy (&old_state
, &thread
->state
, sizeof (old_state
));
275 state
= proc_get_state (thread
, 1);
278 warning ("Couldn't store registers into %s", proc_string (thread
));
282 /* Save the T bit. We might try to restore the %eflags register
283 below, but changing the T bit would seriously confuse GDB. */
284 trace
= ((struct i386_thread_state
*)state
)->efl
& 0x100;
286 if (!was_aborted
&& was_valid
)
287 /* See which registers have changed after aborting the thread. */
291 for (check_regno
= 0; check_regno
< NUM_GREGS
; check_regno
++)
292 if ((thread
->fetched_regs
& (1 << check_regno
))
293 && memcpy (REG_ADDR (&old_state
, check_regno
),
294 REG_ADDR (state
, check_regno
),
295 REGISTER_RAW_SIZE (check_regno
)))
296 /* Register CHECK_REGNO has changed! Ack! */
298 warning ("Register %s changed after the thread was aborted",
299 REGISTER_NAME (check_regno
));
300 if (regno
>= 0 && regno
!= check_regno
)
301 /* Update gdb's copy of the register. */
302 supply_register (check_regno
, REG_ADDR (state
, check_regno
));
304 warning ("... also writing this register! Suspicious...");
308 #define fill(state, regno) \
309 memcpy (REG_ADDR(state, regno), ®isters[REGISTER_BYTE (regno)], \
310 REGISTER_RAW_SIZE (regno))
316 proc_debug (thread
, "storing all registers");
318 for (i
= 0; i
< NUM_GREGS
; i
++)
319 if (register_valid
[i
])
324 proc_debug (thread
, "storing register %s", REGISTER_NAME (regno
));
326 gdb_assert (register_valid
[regno
]);
330 /* Restore the T bit. */
331 ((struct i386_thread_state
*)state
)->efl
&= ~0x100;
332 ((struct i386_thread_state
*)state
)->efl
|= trace
;
337 if (regno
>= NUM_GREGS
|| regno
== -1)
339 proc_debug (thread
, "storing floating-point registers");
341 store_fpregs (thread
);