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