OSDN Git Service

Phase 1 of the ptid_t changes.
[pf3gnuchains/sourceware.git] / gdb / i386gnu-nat.c
1 /* Low level interface to i386 running the GNU Hurd.
2    Copyright 1992, 1995, 1996, 1998, 2000, 2001
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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.  */
21
22 #include "defs.h"
23 #include "inferior.h"
24 #include "floatformat.h"
25 #include "regcache.h"
26
27 #include "gdb_assert.h"
28 #include <stdio.h>
29 #include <errno.h>
30
31 #include <mach.h>
32 #include <mach_error.h>
33 #include <mach/message.h>
34 #include <mach/exception.h>
35
36 #include "gnu-nat.h"
37
38 /* The FPU hardware state.  */
39 struct env387
40 {
41   unsigned short control;
42   unsigned short r0;
43   unsigned short status;
44   unsigned short r1;
45   unsigned short tag;
46   unsigned short r2;
47   unsigned long eip;
48   unsigned short code_seg;
49   unsigned short opcode;
50   unsigned long operand;
51   unsigned short operand_seg;
52   unsigned short r3;
53   unsigned char regs[8][10];
54 };
55
56 \f
57 /* Offset to the thread_state_t location where REG is stored.  */
58 #define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
59
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[] =
63 {
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)
68 };
69
70 #define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
71
72 \f
73 /* Get the whole floating-point state of THREAD and record the
74    values of the corresponding (pseudo) registers.  */
75 static void
76 fetch_fpregs (struct proc *thread)
77 {
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;
81   error_t err;
82   int i;
83
84   err = thread_get_state (thread->port, i386_FLOAT_STATE,
85                           (thread_state_t) &state, &count);
86   if (err)
87     {
88       warning ("Couldn't fetch floating-point state from %s",
89                proc_string (thread));
90       return;
91     }
92
93   if (! state.initialized)
94     /* The floating-point state isn't initialized.  */
95     {
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);
100
101       return;
102     }
103
104   /* Supply the floating-point registers.  */
105   for (i = 0; i < 8; i++)
106     supply_register (FP0_REGNUM + i, ep->regs[i]);
107
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);
114
115   /* Store the code segment and opcode pseudo registers.  */
116   {
117     long l;
118
119     l = ep->code_seg;
120     supply_register (FCS_REGNUM, (char *) &l);
121     l = ep->opcode & ((1 << 11) - 1);
122     supply_register (FOP_REGNUM, (char *) &l);
123   }
124 }
125
126 /* Fetch register REGNO, or all regs if REGNO is -1.  */
127 void
128 gnu_fetch_registers (int regno)
129 {
130   struct proc *thread;
131
132   /* Make sure we know about new threads.  */
133   inf_update_procs (current_inferior);
134
135   thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
136   if (!thread)
137     error ("Can't fetch registers from thread %d: No such thread",
138            PIDGET (inferior_ptid));
139
140   if (regno < NUM_GREGS || regno == -1)
141     {
142       thread_state_t state;
143       
144       /* This does the dirty work for us.  */
145       state = proc_get_state (thread, 0);
146       if (!state)
147         {
148           warning ("Couldn't fetch registers from %s",
149                    proc_string (thread));
150           return;
151         }
152
153       if (regno == -1)
154         {
155           int i;
156           
157           proc_debug (thread, "fetching all register");
158           
159           for (i = 0; i < NUM_GREGS; i++)
160             supply_register (i, REG_ADDR (state, i));
161           thread->fetched_regs = ~0;
162         }
163       else
164         {
165           proc_debug (thread, "fetching register %s", REGISTER_NAME (regno));
166           
167           supply_register (regno, REG_ADDR (state, regno));
168           thread->fetched_regs |= (1 << regno);
169         }
170     }
171
172   if (regno >= NUM_GREGS || regno == -1)
173     {
174       proc_debug (thread, "fetching floating-point registers");
175       
176       fetch_fpregs (thread);
177     }
178 }
179
180 \f
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.  */
185 static void
186 convert_to_env387 (struct env387 *ep, char *regs, signed char *valid)
187 {
188   int i;
189
190   /* Fill in the floating-point registers.  */
191   for (i = 0; i < 8; i++)
192     if (!valid || valid[i])
193       memcpy (ep->regs[i], &regs[REGISTER_BYTE (FP0_REGNUM + i)],
194               REGISTER_RAW_SIZE (FP0_REGNUM + i));
195
196 #define fill(member, regno)                                              \
197   if (!valid || valid[(regno)])                                          \
198     memcpy (&ep->member, &regs[REGISTER_BYTE (regno)],                   \
199             sizeof (ep->member));
200
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);
207
208 #undef fill
209
210   if (!valid || valid[FCS_REGNUM])
211     ep->code_seg =
212       (* (int *) &registers[REGISTER_BYTE (FCS_REGNUM)] & 0xffff);
213   
214   if (!valid || valid[FOP_REGNUM])
215     ep->opcode =
216       ((* (int *) &registers[REGISTER_BYTE (FOP_REGNUM)] & ((1 << 11) - 1)));
217 }
218
219 /* Store the whole floating-point state into THREAD using information
220    from the corresponding (pseudo) registers.  */
221 static void
222 store_fpregs (struct proc *thread)
223 {
224   mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
225   struct i386_float_state state;
226   error_t err;
227
228   err = thread_get_state (thread->port, i386_FLOAT_STATE,
229                           (thread_state_t) &state, &count);
230   if (err)
231     {
232       warning ("Couldn't fetch floating-point state from %s",
233                proc_string (thread));
234       return;
235     }
236
237   convert_to_env387 ((struct env387 *) state.hw_state,
238                      registers, register_valid);
239     
240   err = thread_set_state (thread->port, i386_FLOAT_STATE,
241                           (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
242   if (err)
243     {
244       warning ("Couldn't store floating-point state into %s",
245                proc_string (thread));
246       return;
247     }
248 }
249
250 /* Store at least register REGNO, or all regs if REGNO == -1.  */
251 void
252 gnu_store_registers (int regno)
253 {
254   struct proc *thread;
255
256   /* Make sure we know about new threads.  */
257   inf_update_procs (current_inferior);
258
259   thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
260   if (!thread)
261     error ("Couldn't store registers into thread %d: No such thread",
262            PIDGET (inferior_ptid));
263
264   if (regno < NUM_GREGS || regno == -1)
265     {
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;
270       int trace;
271
272       if (!was_aborted && was_valid)
273         memcpy (&old_state, &thread->state, sizeof (old_state));
274
275       state = proc_get_state (thread, 1);
276       if (!state)
277         {
278           warning ("Couldn't store registers into %s", proc_string (thread));
279           return;
280         }
281
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;
285
286       if (!was_aborted && was_valid)
287         /* See which registers have changed after aborting the thread.  */
288         {
289           int check_regno;
290
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!  */
297               {
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));
303                 else
304                   warning ("... also writing this register!  Suspicious...");
305               }
306         }
307
308 #define fill(state, regno)                                               \
309   memcpy (REG_ADDR(state, regno), &registers[REGISTER_BYTE (regno)],     \
310           REGISTER_RAW_SIZE (regno))
311
312       if (regno == -1)
313         {
314           int i;
315           
316           proc_debug (thread, "storing all registers");
317
318           for (i = 0; i < NUM_GREGS; i++)
319             if (register_valid[i])
320               fill (state, i);
321         }
322       else
323         {
324           proc_debug (thread, "storing register %s", REGISTER_NAME (regno));
325
326           gdb_assert (register_valid[regno]);
327           fill (state, regno);
328         }
329
330       /* Restore the T bit.  */
331       ((struct i386_thread_state *)state)->efl &= ~0x100;
332       ((struct i386_thread_state *)state)->efl |= trace;
333     }
334
335 #undef fill
336
337   if (regno >= NUM_GREGS || regno == -1)
338     {
339       proc_debug (thread, "storing floating-point registers");
340       
341       store_fpregs (thread);
342     }
343 }