* configure.in (noconfigdirs) [*-cygwin*, *-mingw*, *-beos]: Disable
[deliverable/binutils-gdb.git] / gdb / i386b-nat.c
CommitLineData
c906108c 1/* Native-dependent code for BSD Unix running on i386's, for GDB.
b6ba6518
KB
2 Copyright 1988, 1989, 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000,
3 2001 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
24#ifdef FETCH_INFERIOR_REGISTERS
25#include <sys/types.h>
26#include <sys/ptrace.h>
27#include <machine/reg.h>
28#include <machine/frame.h>
29#include "inferior.h"
c2d11a7d 30#include "gdbcore.h" /* for registers_fetched() */
4e052eda 31#include "regcache.h"
c906108c
SS
32
33void
fba45db2 34fetch_inferior_registers (int regno)
c906108c
SS
35{
36 struct reg inferior_registers;
37
c5aa993b
JM
38 ptrace (PT_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) & inferior_registers, 0);
39 memcpy (&registers[REGISTER_BYTE (0)], &inferior_registers, 4 * NUM_REGS);
c906108c
SS
40 registers_fetched ();
41}
42
43void
fba45db2 44store_inferior_registers (int regno)
c906108c
SS
45{
46 struct reg inferior_registers;
47
c5aa993b
JM
48 memcpy (&inferior_registers, &registers[REGISTER_BYTE (0)], 4 * NUM_REGS);
49 ptrace (PT_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) & inferior_registers, 0);
c906108c
SS
50}
51
c5aa993b
JM
52struct md_core
53{
c906108c
SS
54 struct reg intreg;
55 struct fpreg freg;
56};
57
58void
fba45db2
KB
59fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
60 CORE_ADDR ignore)
c906108c 61{
c5aa993b 62 struct md_core *core_reg = (struct md_core *) core_reg_sect;
c906108c
SS
63
64 /* integer registers */
c5aa993b
JM
65 memcpy (&registers[REGISTER_BYTE (0)], &core_reg->intreg,
66 sizeof (struct reg));
c906108c
SS
67 /* floating point registers */
68 /* XXX */
69}
70
71#else
72
73#include <machine/reg.h>
74
75/* this table must line up with REGISTER_NAMES in tm-i386.h */
76/* symbols like 'tEAX' come from <machine/reg.h> */
c5aa993b 77static int tregmap[] =
c906108c
SS
78{
79 tEAX, tECX, tEDX, tEBX,
80 tESP, tEBP, tESI, tEDI,
81 tEIP, tEFLAGS, tCS, tSS
82};
83
84#ifdef sEAX
c5aa993b 85static int sregmap[] =
c906108c
SS
86{
87 sEAX, sECX, sEDX, sEBX,
88 sESP, sEBP, sESI, sEDI,
89 sEIP, sEFLAGS, sCS, sSS
90};
91#else /* No sEAX */
92
93/* FreeBSD has decided to collapse the s* and t* symbols. So if the s*
94 ones aren't around, use the t* ones for sregmap too. */
95
c5aa993b 96static int sregmap[] =
c906108c
SS
97{
98 tEAX, tECX, tEDX, tEBX,
99 tESP, tEBP, tESI, tEDI,
100 tEIP, tEFLAGS, tCS, tSS
101};
102#endif /* No sEAX */
103
104/* blockend is the value of u.u_ar0, and points to the
105 place where ES is stored. */
106
107int
fba45db2 108i386_register_u_addr (int blockend, int regnum)
c906108c
SS
109{
110 /* The following condition is a kludge to get at the proper register map
111 depending upon the state of pcb_flag.
112 The proper condition would be
113 if (u.u_pcb.pcb_flag & FM_TRAP)
114 but that would require a ptrace call here and wouldn't work
115 for corefiles. */
116
117 if (blockend < 0x1fcc)
118 return (blockend + 4 * tregmap[regnum]);
119 else
120 return (blockend + 4 * sregmap[regnum]);
121}
122
123#endif /* !FETCH_INFERIOR_REGISTERS */
124
125#ifdef FLOAT_INFO
126#include "expression.h"
c5aa993b 127#include "language.h" /* for local_hex_string */
c906108c
SS
128#include "floatformat.h"
129
130#include <sys/param.h>
131#include <sys/dir.h>
132#include <signal.h>
133#include <sys/ioctl.h>
134#include <fcntl.h>
135
136#include <a.out.h>
137
138#include <sys/time.h>
139#include <sys/resource.h>
140#include <sys/uio.h>
c5aa993b 141#define curpcb Xcurpcb /* XXX avoid leaking declaration from pcb.h */
c906108c
SS
142#include <sys/user.h>
143#undef curpcb
144#include <sys/file.h>
145#include "gdb_stat.h"
146#include <sys/ptrace.h>
147
c5aa993b 148extern void print_387_control_word (); /* i387-tdep.h */
c906108c
SS
149extern void print_387_status_word ();
150
151#define fpstate save87
152#define U_FPSTATE(u) u.u_pcb.pcb_savefpu
153
c5aa993b
JM
154struct env387
155 {
156 unsigned short control;
157 unsigned short r0;
158 unsigned short status;
159 unsigned short r1;
160 unsigned short tag;
161 unsigned short r2;
162 unsigned long eip;
163 unsigned short code_seg;
164 unsigned short opcode;
165 unsigned long operand;
166 unsigned short operand_seg;
167 unsigned short r3;
168 unsigned char regs[8][10];
169 };
c906108c
SS
170
171static void
fba45db2 172print_387_status (unsigned short status, struct env387 *ep)
c906108c
SS
173{
174 int i;
175 int bothstatus;
176 int top;
177 int fpreg;
c5aa993b 178
c906108c 179 bothstatus = ((status != 0) && (ep->status != 0));
c5aa993b 180 if (status != 0)
c906108c
SS
181 {
182 if (bothstatus)
183 printf_unfiltered ("u: ");
c5aa993b 184 print_387_status_word ((unsigned int) status);
c906108c 185 }
c5aa993b
JM
186
187 if (ep->status != 0)
c906108c
SS
188 {
189 if (bothstatus)
190 printf_unfiltered ("e: ");
c5aa993b 191 print_387_status_word ((unsigned int) ep->status);
c906108c 192 }
c5aa993b
JM
193
194 print_387_control_word ((unsigned int) ep->control);
c906108c 195 printf_unfiltered ("last exception: ");
c5aa993b
JM
196 printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode));
197 printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
198 printf_unfiltered ("%s; ", local_hex_string (ep->eip));
199 printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
200 printf_unfiltered (":%s\n", local_hex_string (ep->operand));
c906108c
SS
201
202 top = (ep->status >> 11) & 7;
c5aa993b 203
c906108c 204 printf_unfiltered ("regno tag msb lsb value\n");
c5aa993b 205 for (fpreg = 7; fpreg >= 0; fpreg--)
c906108c
SS
206 {
207 double val;
c906108c 208
c5aa993b
JM
209 printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
210
211 switch ((ep->tag >> (fpreg * 2)) & 3)
c906108c 212 {
c5aa993b
JM
213 case 0:
214 printf_unfiltered ("valid ");
215 break;
216 case 1:
217 printf_unfiltered ("zero ");
218 break;
219 case 2:
220 printf_unfiltered ("trap ");
221 break;
222 case 3:
223 printf_unfiltered ("empty ");
224 break;
c906108c
SS
225 }
226 for (i = 9; i >= 0; i--)
227 printf_unfiltered ("%02x", ep->regs[fpreg][i]);
c5aa993b
JM
228
229 floatformat_to_double (&floatformat_i387_ext, (char *) ep->regs[fpreg],
230 &val);
c906108c
SS
231 printf_unfiltered (" %g\n", val);
232 }
233}
234
fba45db2 235i386_float_info (void)
c906108c 236{
c5aa993b 237 struct user u; /* just for address computations */
c906108c
SS
238 int i;
239 /* fpstate defined in <sys/user.h> */
240 struct fpstate *fpstatep;
241 char buf[sizeof (struct fpstate) + 2 * sizeof (int)];
242 unsigned int uaddr;
243 char fpvalid;
244 unsigned int rounded_addr;
245 unsigned int rounded_size;
c5aa993b 246 /*extern int corechan; */
c906108c
SS
247 int skip;
248 extern int inferior_pid;
c5aa993b
JM
249
250 uaddr = (char *) &U_FPSTATE (u) - (char *) &u;
251 if (inferior_pid)
c906108c
SS
252 {
253 int *ip;
c5aa993b 254
c906108c
SS
255 rounded_addr = uaddr & -sizeof (int);
256 rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) +
257 sizeof (int) - 1) / sizeof (int);
258 skip = uaddr - rounded_addr;
c5aa993b
JM
259
260 ip = (int *) buf;
261 for (i = 0; i < rounded_size; i++)
c906108c 262 {
c5aa993b 263 *ip++ = ptrace (PT_READ_U, inferior_pid, (caddr_t) rounded_addr, 0);
c906108c
SS
264 rounded_addr += sizeof (int);
265 }
c5aa993b
JM
266 }
267 else
c906108c 268 {
c5aa993b 269 printf ("float info: can't do a core file (yet)\n");
c906108c
SS
270 return;
271#if 0
272 if (lseek (corechan, uaddr, 0) < 0)
273 perror_with_name ("seek on core file");
c5aa993b
JM
274 if (myread (corechan, buf, sizeof (struct fpstate)) < 0)
275 perror_with_name ("read from core file");
c906108c
SS
276 skip = 0;
277#endif
278 }
c5aa993b
JM
279
280 print_387_status (0, (struct env387 *) buf);
c906108c
SS
281}
282
283int
fba45db2 284kernel_u_size (void)
c906108c
SS
285{
286 return (sizeof (struct user));
287}
288
289#endif
This page took 0.11344 seconds and 4 git commands to generate.