OSDN Git Service

* win32-nat.c: Remove unneeded header.
[pf3gnuchains/pf3gnuchains3x.git] / gdb / i386gnu-nat.c
1 /* Low level interface to i386 running the GNU Hurd.
2    Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
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.
10
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.
15
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.  */
20
21 #include "defs.h"
22 #include "inferior.h"
23 #include "floatformat.h"
24
25 #include <assert.h>
26 #include <stdio.h>
27 #include <errno.h>
28
29 #include <mach.h>
30 #include <mach_error.h>
31 #include <mach/message.h>
32 #include <mach/exception.h>
33
34 #include "gnu-nat.h"
35
36 /* The FPU hardware state.  */
37 struct 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 };
53
54 \f
55 /* Offset to the thread_state_t location where REG is stored.  */
56 #define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
57
58 /* At reg_offset[i] is the offset to the thread_state_t location where
59    the gdb registers[i] is stored.  */
60 static int reg_offset[] =
61 {
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)
66 };
67
68 #define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
69
70 \f
71 /* Get the whole floating-point state of THREAD and record the
72    values of the corresponding (pseudo) registers.  */
73 static void
74 fetch_fpregs (struct proc *thread)
75 {
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;
81
82   err = thread_get_state (thread->port, i386_FLOAT_STATE,
83                           (thread_state_t) &state, &count);
84   if (err)
85     {
86       warning ("Couldn't fetch floating-point state from %s",
87                proc_string (thread));
88       return;
89     }
90
91   if (! state.initialized)
92     /* The floating-point state isn't initialized.  */
93     {
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;
100     }
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   }
122 }
123
124 /* Fetch register REGNO, or all regs if REGNO is -1.  */
125 void
126 gnu_fetch_registers (int regno)
127 {
128   struct proc *thread;
129
130   /* Make sure we know about new threads.  */
131   inf_update_procs (current_inferior);
132
133   thread = inf_tid_to_thread (current_inferior, inferior_pid);
134   if (!thread)
135     error ("Can't fetch registers from thread %d: No such thread",
136            inferior_pid);
137
138   if (regno < NUM_GREGS || regno == -1)
139     {
140       thread_state_t state;
141       
142       /* This does the dirty work for us.  */
143       state = proc_get_state (thread, 0);
144       if (!state)
145         {
146           warning ("Couldn't fetch registers from %s",
147                    proc_string (thread));
148           return;
149         }
150
151       if (regno == -1)
152         {
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;
160         }
161       else
162         {
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);
167         }
168     }
169
170   if (regno >= NUM_GREGS || regno == -1)
171     {
172       proc_debug (thread, "fetching floating-point registers");
173       
174       fetch_fpregs (thread);
175     }
176 }
177
178 \f
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.  */
183 static void
184 convert_to_env387 (struct env387 *ep, char *regs, signed char *valid)
185 {
186   int i;
187
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.  */
219 static void
220 store_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;
225
226   err = thread_get_state (thread->port, i386_FLOAT_STATE,
227                           (thread_state_t) &state, &count);
228   if (err)
229     {
230       warning ("Couldn't fetch floating-point state from %s",
231                proc_string (thread));
232       return;
233     }
234
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)
241     {
242       warning ("Couldn't store floating-point state into %s",
243                proc_string (thread));
244       return;
245     }
246 }
247
248 /* Store at least register REGNO, or all regs if REGNO == -1.  */
249 void
250 gnu_store_registers (int regno)
251 {
252   struct proc *thread;
253
254   /* Make sure we know about new threads.  */
255   inf_update_procs (current_inferior);
256
257   thread = inf_tid_to_thread (current_inferior, inferior_pid);
258   if (!thread)
259     error ("Couldn't store registers into thread %d: No such thread",
260            inferior_pid);
261
262   if (regno < NUM_GREGS || regno == -1)
263     {
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;
268
269       if (!was_aborted && was_valid)
270         memcpy (&old_state, &thread->state, sizeof (old_state));
271
272       state = proc_get_state (thread, 1);
273       if (!state)
274         {
275           warning ("Couldn't store registers into %s", proc_string (thread));
276           return;
277         }
278
279       if (!was_aborted && was_valid)
280         /* See which registers have changed after aborting the thread.  */
281         {
282           int check_regno;
283
284           for (check_regno = 0; check_regno < NUM_GREGS; check_regno++)
285             if ((thread->fetched_regs & (1 << check_regno))
286                 && memcpy (REG_ADDR (&old_state, check_regno),
287                            REG_ADDR (state, check_regno),
288                            REGISTER_RAW_SIZE (check_regno)))
289               /* Register CHECK_REGNO has changed!  Ack!  */
290               {
291                 warning ("Register %s changed after the thread was aborted",
292                          REGISTER_NAME (check_regno));
293                 if (regno >= 0 && regno != check_regno)
294                   /* Update gdb's copy of the register.  */
295                   supply_register (check_regno, REG_ADDR (state, check_regno));
296                 else
297                   warning ("... also writing this register!  Suspicious...");
298               }
299         }
300
301 #define fill(state, regno)                                               \
302   memcpy (REG_ADDR(state, regno), &registers[REGISTER_BYTE (regno)],     \
303           REGISTER_RAW_SIZE (regno))
304
305       if (regno == -1)
306         {
307           int i;
308           
309           proc_debug (thread, "storing all registers");
310
311           for (i = 0; i < NUM_GREGS; i++)
312             if (register_valid[i])
313               fill (state, i);
314         }
315       else
316         {
317           proc_debug (thread, "storing register %s", REGISTER_NAME (regno));
318
319           assert (register_valid[regno]);
320           fill (state, regno);
321         }
322     }
323
324 #undef fill
325
326   if (regno >= NUM_GREGS || regno == -1)
327     {
328       proc_debug (thread, "storing floating-point registers");
329       
330       store_fpregs (thread);
331     }
332 }