Phase 1 of the ptid_t changes.
[deliverable/binutils-gdb.git] / gdb / i386aix-nat.c
CommitLineData
c906108c 1/* Intel 386 native support.
b6ba6518
KB
2 Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
3 2000, 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#include "frame.h"
24#include "inferior.h"
25#include "language.h"
26#include "gdbcore.h"
4e052eda 27#include "regcache.h"
c906108c
SS
28
29#ifdef USG
30#include <sys/types.h>
31#endif
32
33#include <sys/param.h>
34#include <sys/dir.h>
35#include <signal.h>
36#include <sys/user.h>
37#include <sys/ioctl.h>
38#include <fcntl.h>
39
40#include <sys/file.h>
41#include "gdb_stat.h"
42
43#include <stddef.h>
44#include <sys/ptrace.h>
45
46/* Does AIX define this in <errno.h>? */
47extern int errno;
48
49#ifdef HAVE_SYS_REG_H
50#include <sys/reg.h>
51#endif
52
53#include "floatformat.h"
54
55#include "target.h"
56
a14ed312 57static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
c906108c 58\f
c5aa993b 59
c906108c
SS
60/* this table must line up with REGISTER_NAMES in tm-i386v.h */
61/* symbols like 'EAX' come from <sys/reg.h> */
c5aa993b 62static int regmap[] =
c906108c
SS
63{
64 EAX, ECX, EDX, EBX,
65 USP, EBP, ESI, EDI,
66 EIP, EFL, CS, SS,
67 DS, ES, FS, GS,
68};
69
70/* blockend is the value of u.u_ar0, and points to the
71 * place where GS is stored
72 */
73
74int
fba45db2 75i386_register_u_addr (int blockend, int regnum)
c906108c
SS
76{
77#if 0
78 /* this will be needed if fp registers are reinstated */
79 /* for now, you can look at them with 'info float'
80 * sys5 wont let you change them with ptrace anyway
81 */
c5aa993b 82 if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM)
c906108c
SS
83 {
84 int ubase, fpstate;
85 struct user u;
86 ubase = blockend + 4 * (SS + 1) - KSTKSZ;
c5aa993b 87 fpstate = ubase + ((char *) &u.u_fpstate - (char *) &u);
c906108c 88 return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
c5aa993b 89 }
c906108c
SS
90 else
91#endif
92 return (blockend + 4 * regmap[regnum]);
c5aa993b 93
c906108c
SS
94}
95
96/* The code below only work on the aix ps/2 (i386-ibm-aix) -
97 * mtranle@paris - Sat Apr 11 10:34:12 1992
98 */
99
c5aa993b 100struct env387
c906108c
SS
101{
102 unsigned short control;
103 unsigned short r0;
104 unsigned short status;
105 unsigned short r1;
106 unsigned short tag;
107 unsigned short r2;
108 unsigned long eip;
109 unsigned short code_seg;
110 unsigned short opcode;
111 unsigned long operand;
112 unsigned short operand_seg;
113 unsigned short r3;
114 unsigned char regs[8][10];
115};
116
117static
fba45db2 118print_387_status (unsigned short status, struct env387 *ep)
c906108c
SS
119{
120 int i;
121 int bothstatus;
122 int top;
123 int fpreg;
124 unsigned char *p;
c5aa993b 125
c906108c 126 bothstatus = ((status != 0) && (ep->status != 0));
c5aa993b 127 if (status != 0)
c906108c
SS
128 {
129 if (bothstatus)
130 printf_unfiltered ("u: ");
131 print_387_status_word (status);
132 }
c5aa993b
JM
133
134 if (ep->status != 0)
c906108c
SS
135 {
136 if (bothstatus)
137 printf_unfiltered ("e: ");
138 print_387_status_word (ep->status);
139 }
c5aa993b 140
c906108c
SS
141 print_387_control_word (ep->control);
142 printf_unfiltered ("last exception: ");
c5aa993b
JM
143 printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode));
144 printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
145 printf_unfiltered ("%s; ", local_hex_string (ep->eip));
146 printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
147 printf_unfiltered (":%s\n", local_hex_string (ep->operand));
c906108c
SS
148
149 top = ((ep->status >> 11) & 7);
150
151 printf_unfiltered ("regno tag msb lsb value\n");
c5aa993b 152 for (fpreg = 7; fpreg >= 0; fpreg--)
c906108c
SS
153 {
154 double val;
155
156 printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
157
c5aa993b 158 switch ((ep->tag >> ((7 - fpreg) * 2)) & 3)
c906108c 159 {
c5aa993b
JM
160 case 0:
161 printf_unfiltered ("valid ");
162 break;
163 case 1:
164 printf_unfiltered ("zero ");
165 break;
166 case 2:
167 printf_unfiltered ("trap ");
168 break;
169 case 3:
170 printf_unfiltered ("empty ");
171 break;
c906108c
SS
172 }
173 for (i = 9; i >= 0; i--)
174 printf_unfiltered ("%02x", ep->regs[fpreg][i]);
c5aa993b
JM
175
176 i387_to_double ((char *) ep->regs[fpreg], (char *) &val);
c906108c
SS
177 printf_unfiltered (" %#g\n", val);
178 }
179}
180
181static struct env387 core_env387;
182
183void
fba45db2 184i386_float_info (void)
c906108c
SS
185{
186 struct env387 fps;
187 int fpsaved = 0;
188 /* We need to reverse the order of the registers. Apparently AIX stores
189 the highest-numbered ones first. */
190 struct env387 fps_fixed;
191 int i;
192
39f77062 193 if (! ptid_equal (inferior_ptid, null_ptid))
c906108c
SS
194 {
195 char buf[10];
196 unsigned short status;
197
39f77062
KB
198 ptrace (PT_READ_FPR, PIDGET (inferior_ptid), buf,
199 offsetof (struct env387, status));
c906108c
SS
200 memcpy (&status, buf, sizeof (status));
201 fpsaved = status;
202 }
203 else
204 {
205 if ((fpsaved = core_env387.status) != 0)
c5aa993b 206 memcpy (&fps, &core_env387, sizeof (fps));
c906108c 207 }
c5aa993b
JM
208
209 if (fpsaved == 0)
c906108c
SS
210 {
211 printf_unfiltered ("no floating point status saved\n");
212 return;
213 }
214
39f77062 215 if (! ptid_equal (inferior_ptid, null_ptid))
c906108c
SS
216 {
217 int offset;
c5aa993b 218 for (offset = 0; offset < sizeof (fps); offset += 10)
c906108c
SS
219 {
220 char buf[10];
39f77062 221 ptrace (PT_READ_FPR, PIDGET (inferior_ptid), buf, offset);
c5aa993b
JM
222 memcpy ((char *) &fps.control + offset, buf,
223 MIN (10, sizeof (fps) - offset));
c906108c 224 }
c5aa993b 225 }
c906108c
SS
226 fps_fixed = fps;
227 for (i = 0; i < 8; ++i)
228 memcpy (fps_fixed.regs[i], fps.regs[7 - i], 10);
229 print_387_status (0, &fps_fixed);
230}
231
232/* Fetch one register. */
233static void
fba45db2 234fetch_register (int regno)
c906108c
SS
235{
236 char buf[MAX_REGISTER_RAW_SIZE];
237 if (regno < FP0_REGNUM)
39f77062 238 *(int *) buf = ptrace (PT_READ_GPR, PIDGET (inferior_ptid),
c5aa993b 239 PT_REG (regmap[regno]), 0, 0);
c906108c 240 else
39f77062 241 ptrace (PT_READ_FPR, PIDGET (inferior_ptid), buf,
c5aa993b 242 (regno - FP0_REGNUM) * 10 + offsetof (struct env387, regs));
c906108c
SS
243 supply_register (regno, buf);
244}
245
246void
fba45db2 247fetch_inferior_registers (int regno)
c906108c
SS
248{
249 if (regno < 0)
250 for (regno = 0; regno < NUM_REGS; regno++)
251 fetch_register (regno);
252 else
253 fetch_register (regno);
254}
255
256/* store one register */
257static void
fba45db2 258store_register (int regno)
c906108c
SS
259{
260 char buf[80];
c906108c
SS
261 errno = 0;
262 if (regno < FP0_REGNUM)
39f77062 263 ptrace (PT_WRITE_GPR, PIDGET (inferior_ptid), PT_REG (regmap[regno]),
c906108c
SS
264 *(int *) &registers[REGISTER_BYTE (regno)], 0);
265 else
39f77062
KB
266 ptrace (PT_WRITE_FPR, PIDGET (inferior_ptid),
267 &registers[REGISTER_BYTE (regno)],
c5aa993b 268 (regno - FP0_REGNUM) * 10 + offsetof (struct env387, regs));
c906108c
SS
269
270 if (errno != 0)
271 {
272 sprintf (buf, "writing register number %d", regno);
273 perror_with_name (buf);
274 }
275}
276
277/* Store our register values back into the inferior.
278 If REGNO is -1, do this for all registers.
279 Otherwise, REGNO specifies which register (so we can save time). */
280void
fba45db2 281store_inferior_registers (int regno)
c906108c
SS
282{
283 if (regno < 0)
284 for (regno = 0; regno < NUM_REGS; regno++)
285 store_register (regno);
286 else
287 store_register (regno);
288}
289
290#ifndef CD_AX /* defined in sys/i386/coredump.h */
c5aa993b
JM
291#define CD_AX 0
292#define CD_BX 1
293#define CD_CX 2
294#define CD_DX 3
295#define CD_SI 4
296#define CD_DI 5
297#define CD_BP 6
298#define CD_SP 7
299#define CD_FL 8
300#define CD_IP 9
301#define CD_CS 10
302#define CD_DS 11
303#define CD_ES 12
304#define CD_FS 13
305#define CD_GS 14
306#define CD_SS 15
c906108c
SS
307#endif
308
309/*
310 * The order here in core_regmap[] has to be the same as in
311 * regmap[] above.
312 */
c5aa993b 313static int core_regmap[] =
c906108c
SS
314{
315 CD_AX, CD_CX, CD_DX, CD_BX,
316 CD_SP, CD_BP, CD_SI, CD_DI,
317 CD_IP, CD_FL, CD_CS, CD_SS,
318 CD_DS, CD_ES, CD_FS, CD_GS,
319};
320
165a58fe
KB
321/* Provide registers to GDB from a core file.
322
323 CORE_REG_SECT points to an array of bytes, which were obtained from
324 a core file which BFD thinks might contain register contents.
325 CORE_REG_SIZE is its size.
326
327 WHICH says which register set corelow suspects this is:
328 0 --- the general-purpose register set
329 2 --- the floating-point register set
330
331 REG_ADDR isn't used. */
332
c906108c 333static void
165a58fe
KB
334fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
335 int which, CORE_ADDR reg_addr)
c906108c
SS
336{
337
338 if (which == 0)
339 {
340 /* Integer registers */
341
342#define cd_regs(n) ((int *)core_reg_sect)[n]
343#define regs(n) *((int *) &registers[REGISTER_BYTE (n)])
344
345 int i;
346 for (i = 0; i < FP0_REGNUM; i++)
c5aa993b 347 regs (i) = cd_regs (core_regmap[i]);
c906108c
SS
348 }
349 else if (which == 2)
350 {
351 /* Floating point registers */
352
353 if (core_reg_size >= sizeof (core_env387))
354 memcpy (&core_env387, core_reg_sect, core_reg_size);
355 else
356 fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n");
357 }
358}
c906108c 359\f
c5aa993b 360
c906108c
SS
361/* Register that we are able to handle i386aix core file formats.
362 FIXME: is this really bfd_target_unknown_flavour? */
363
364static struct core_fns i386aix_core_fns =
365{
2acceee2
JM
366 bfd_target_unknown_flavour, /* core_flavour */
367 default_check_format, /* check_format */
368 default_core_sniffer, /* core_sniffer */
369 fetch_core_registers, /* core_read_registers */
370 NULL /* next */
c906108c
SS
371};
372
373void
fba45db2 374_initialize_core_i386aix (void)
c906108c
SS
375{
376 add_core_fns (&i386aix_core_fns);
377}
This page took 0.108095 seconds and 4 git commands to generate.