* breakpoint.c (print_it_typical) <bp_access_watchpoint> [UI_OUT]:
[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
193 if (inferior_pid)
194 {
195 char buf[10];
196 unsigned short status;
197
c5aa993b 198 ptrace (PT_READ_FPR, inferior_pid, buf, offsetof (struct env387, status));
c906108c
SS
199 memcpy (&status, buf, sizeof (status));
200 fpsaved = status;
201 }
202 else
203 {
204 if ((fpsaved = core_env387.status) != 0)
c5aa993b 205 memcpy (&fps, &core_env387, sizeof (fps));
c906108c 206 }
c5aa993b
JM
207
208 if (fpsaved == 0)
c906108c
SS
209 {
210 printf_unfiltered ("no floating point status saved\n");
211 return;
212 }
213
214 if (inferior_pid)
215 {
216 int offset;
c5aa993b 217 for (offset = 0; offset < sizeof (fps); offset += 10)
c906108c
SS
218 {
219 char buf[10];
220 ptrace (PT_READ_FPR, inferior_pid, buf, offset);
c5aa993b
JM
221 memcpy ((char *) &fps.control + offset, buf,
222 MIN (10, sizeof (fps) - offset));
c906108c 223 }
c5aa993b 224 }
c906108c
SS
225 fps_fixed = fps;
226 for (i = 0; i < 8; ++i)
227 memcpy (fps_fixed.regs[i], fps.regs[7 - i], 10);
228 print_387_status (0, &fps_fixed);
229}
230
231/* Fetch one register. */
232static void
fba45db2 233fetch_register (int regno)
c906108c
SS
234{
235 char buf[MAX_REGISTER_RAW_SIZE];
236 if (regno < FP0_REGNUM)
c5aa993b
JM
237 *(int *) buf = ptrace (PT_READ_GPR, inferior_pid,
238 PT_REG (regmap[regno]), 0, 0);
c906108c
SS
239 else
240 ptrace (PT_READ_FPR, inferior_pid, buf,
c5aa993b 241 (regno - FP0_REGNUM) * 10 + offsetof (struct env387, regs));
c906108c
SS
242 supply_register (regno, buf);
243}
244
245void
fba45db2 246fetch_inferior_registers (int regno)
c906108c
SS
247{
248 if (regno < 0)
249 for (regno = 0; regno < NUM_REGS; regno++)
250 fetch_register (regno);
251 else
252 fetch_register (regno);
253}
254
255/* store one register */
256static void
fba45db2 257store_register (int regno)
c906108c
SS
258{
259 char buf[80];
c906108c
SS
260 errno = 0;
261 if (regno < FP0_REGNUM)
c5aa993b 262 ptrace (PT_WRITE_GPR, inferior_pid, PT_REG (regmap[regno]),
c906108c
SS
263 *(int *) &registers[REGISTER_BYTE (regno)], 0);
264 else
265 ptrace (PT_WRITE_FPR, inferior_pid, &registers[REGISTER_BYTE (regno)],
c5aa993b 266 (regno - FP0_REGNUM) * 10 + offsetof (struct env387, regs));
c906108c
SS
267
268 if (errno != 0)
269 {
270 sprintf (buf, "writing register number %d", regno);
271 perror_with_name (buf);
272 }
273}
274
275/* Store our register values back into the inferior.
276 If REGNO is -1, do this for all registers.
277 Otherwise, REGNO specifies which register (so we can save time). */
278void
fba45db2 279store_inferior_registers (int regno)
c906108c
SS
280{
281 if (regno < 0)
282 for (regno = 0; regno < NUM_REGS; regno++)
283 store_register (regno);
284 else
285 store_register (regno);
286}
287
288#ifndef CD_AX /* defined in sys/i386/coredump.h */
c5aa993b
JM
289#define CD_AX 0
290#define CD_BX 1
291#define CD_CX 2
292#define CD_DX 3
293#define CD_SI 4
294#define CD_DI 5
295#define CD_BP 6
296#define CD_SP 7
297#define CD_FL 8
298#define CD_IP 9
299#define CD_CS 10
300#define CD_DS 11
301#define CD_ES 12
302#define CD_FS 13
303#define CD_GS 14
304#define CD_SS 15
c906108c
SS
305#endif
306
307/*
308 * The order here in core_regmap[] has to be the same as in
309 * regmap[] above.
310 */
c5aa993b 311static int core_regmap[] =
c906108c
SS
312{
313 CD_AX, CD_CX, CD_DX, CD_BX,
314 CD_SP, CD_BP, CD_SI, CD_DI,
315 CD_IP, CD_FL, CD_CS, CD_SS,
316 CD_DS, CD_ES, CD_FS, CD_GS,
317};
318
165a58fe
KB
319/* Provide registers to GDB from a core file.
320
321 CORE_REG_SECT points to an array of bytes, which were obtained from
322 a core file which BFD thinks might contain register contents.
323 CORE_REG_SIZE is its size.
324
325 WHICH says which register set corelow suspects this is:
326 0 --- the general-purpose register set
327 2 --- the floating-point register set
328
329 REG_ADDR isn't used. */
330
c906108c 331static void
165a58fe
KB
332fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
333 int which, CORE_ADDR reg_addr)
c906108c
SS
334{
335
336 if (which == 0)
337 {
338 /* Integer registers */
339
340#define cd_regs(n) ((int *)core_reg_sect)[n]
341#define regs(n) *((int *) &registers[REGISTER_BYTE (n)])
342
343 int i;
344 for (i = 0; i < FP0_REGNUM; i++)
c5aa993b 345 regs (i) = cd_regs (core_regmap[i]);
c906108c
SS
346 }
347 else if (which == 2)
348 {
349 /* Floating point registers */
350
351 if (core_reg_size >= sizeof (core_env387))
352 memcpy (&core_env387, core_reg_sect, core_reg_size);
353 else
354 fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n");
355 }
356}
c906108c 357\f
c5aa993b 358
c906108c
SS
359/* Register that we are able to handle i386aix core file formats.
360 FIXME: is this really bfd_target_unknown_flavour? */
361
362static struct core_fns i386aix_core_fns =
363{
2acceee2
JM
364 bfd_target_unknown_flavour, /* core_flavour */
365 default_check_format, /* check_format */
366 default_core_sniffer, /* core_sniffer */
367 fetch_core_registers, /* core_read_registers */
368 NULL /* next */
c906108c
SS
369};
370
371void
fba45db2 372_initialize_core_i386aix (void)
c906108c
SS
373{
374 add_core_fns (&i386aix_core_fns);
375}
This page took 0.100788 seconds and 4 git commands to generate.