2000-12-22 Fernando Nasser <fnasser@redhat.com>
[deliverable/binutils-gdb.git] / gdb / ultra3-nat.c
CommitLineData
c906108c
SS
1/* Native-dependent code for GDB, for NYU Ultra3 running Sym1 OS.
2 Copyright (C) 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
3 Contributed by David Wood (wood@nyu.edu) at New York University.
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#define DEBUG
23#include "defs.h"
24#include "frame.h"
25#include "inferior.h"
26#include "symtab.h"
27#include "value.h"
28
29#include <sys/types.h>
30#include <sys/param.h>
31#include <signal.h>
32#include <sys/ioctl.h>
c5aa993b 33#include <fcntl.h>
c906108c
SS
34
35#include "gdbcore.h"
36
37#include <sys/file.h>
38#include "gdb_stat.h"
39
a14ed312 40static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
c906108c
SS
41
42/* Assumes support for AMD's Binary Compatibility Standard
43 for ptrace(). If you define ULTRA3, the ultra3 extensions to
44 ptrace() are used allowing the reading of more than one register
45 at a time.
46
47 This file assumes KERNEL_DEBUGGING is turned off. This means
48 that if the user/gdb tries to read gr64-gr95 or any of the
49 protected special registers we silently return -1 (see the
50 CANNOT_STORE/FETCH_REGISTER macros). */
51#define ULTRA3
52
53#if !defined (offsetof)
c5aa993b 54#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
c906108c
SS
55#endif
56
57extern int errno;
58struct ptrace_user pt_struct;
59
60/* Get all available registers from the inferior. Registers that are
61 * defined in REGISTER_NAMES, but not available to the user/gdb are
62 * supplied as -1. This may include gr64-gr95 and the protected special
63 * purpose registers.
64 */
65
66void
fba45db2 67fetch_inferior_registers (int regno)
c906108c 68{
c5aa993b 69 register int i, j, ret_val = 0;
c906108c
SS
70 char buf[128];
71
c5aa993b
JM
72 if (regno != -1)
73 {
74 fetch_register (regno);
75 return;
76 }
c906108c
SS
77
78/* Global Registers */
79#ifdef ULTRA3
80 errno = 0;
81 ptrace (PT_READ_STRUCT, inferior_pid,
c5aa993b
JM
82 (PTRACE_ARG3_TYPE) register_addr (GR96_REGNUM, 0),
83 (int) &pt_struct.pt_gr[0], 32 * 4);
84 if (errno != 0)
85 {
c906108c
SS
86 perror_with_name ("reading global registers");
87 ret_val = -1;
c5aa993b
JM
88 }
89 else
90 for (regno = GR96_REGNUM, j = 0; j < 32; regno++, j++)
91 {
92 supply_register (regno, &pt_struct.pt_gr[j]);
93 }
c906108c 94#else
c5aa993b
JM
95 for (regno = GR96_REGNUM; !ret_val && regno < GR96_REGNUM + 32; regno++)
96 fetch_register (regno);
c906108c
SS
97#endif
98
99/* Local Registers */
100#ifdef ULTRA3
101 errno = 0;
102 ptrace (PT_READ_STRUCT, inferior_pid,
c5aa993b
JM
103 (PTRACE_ARG3_TYPE) register_addr (LR0_REGNUM, 0),
104 (int) &pt_struct.pt_lr[0], 128 * 4);
105 if (errno != 0)
106 {
c906108c
SS
107 perror_with_name ("reading local registers");
108 ret_val = -1;
c5aa993b
JM
109 }
110 else
111 for (regno = LR0_REGNUM, j = 0; j < 128; regno++, j++)
112 {
113 supply_register (regno, &pt_struct.pt_lr[j]);
114 }
c906108c 115#else
c5aa993b
JM
116 for (regno = LR0_REGNUM; !ret_val && regno < LR0_REGNUM + 128; regno++)
117 fetch_register (regno);
c906108c
SS
118#endif
119
120/* Special Registers */
c5aa993b
JM
121 fetch_register (GR1_REGNUM);
122 fetch_register (CPS_REGNUM);
123 fetch_register (PC_REGNUM);
124 fetch_register (NPC_REGNUM);
125 fetch_register (PC2_REGNUM);
126 fetch_register (IPC_REGNUM);
127 fetch_register (IPA_REGNUM);
128 fetch_register (IPB_REGNUM);
129 fetch_register (Q_REGNUM);
130 fetch_register (BP_REGNUM);
131 fetch_register (FC_REGNUM);
132
133/* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
134 registers_fetched ();
c906108c
SS
135}
136
137/* Store our register values back into the inferior.
138 * If REGNO is -1, do this for all registers.
139 * Otherwise, REGNO specifies which register (so we can save time).
140 * NOTE: Assumes AMD's binary compatibility standard.
141 */
142
143void
fba45db2 144store_inferior_registers (int regno)
c906108c
SS
145{
146 register unsigned int regaddr;
147 char buf[80];
148
149 if (regno >= 0)
150 {
c5aa993b 151 if (CANNOT_STORE_REGISTER (regno))
c906108c
SS
152 return;
153 regaddr = register_addr (regno, 0);
154 errno = 0;
155 ptrace (PT_WRITE_U, inferior_pid,
c5aa993b 156 (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
c906108c
SS
157 if (errno != 0)
158 {
159 sprintf (buf, "writing register %s (#%d)", REGISTER_NAME (regno), regno);
160 perror_with_name (buf);
161 }
162 }
163 else
164 {
165#ifdef ULTRA3
c5aa993b
JM
166 pt_struct.pt_gr1 = read_register (GR1_REGNUM);
167 for (regno = GR96_REGNUM; regno < GR96_REGNUM + 32; regno++)
168 pt_struct.pt_gr[regno] = read_register (regno);
169 for (regno = LR0_REGNUM; regno < LR0_REGNUM + 128; regno++)
170 pt_struct.pt_gr[regno] = read_register (regno);
c906108c
SS
171 errno = 0;
172 ptrace (PT_WRITE_STRUCT, inferior_pid,
c5aa993b
JM
173 (PTRACE_ARG3_TYPE) register_addr (GR1_REGNUM, 0),
174 (int) &pt_struct.pt_gr1, (1 * 32 * 128) * 4);
c906108c
SS
175 if (errno != 0)
176 {
c5aa993b
JM
177 sprintf (buf, "writing all local/global registers");
178 perror_with_name (buf);
c906108c 179 }
c5aa993b
JM
180 pt_struct.pt_psr = read_register (CPS_REGNUM);
181 pt_struct.pt_pc0 = read_register (NPC_REGNUM);
182 pt_struct.pt_pc1 = read_register (PC_REGNUM);
183 pt_struct.pt_pc2 = read_register (PC2_REGNUM);
184 pt_struct.pt_ipc = read_register (IPC_REGNUM);
185 pt_struct.pt_ipa = read_register (IPA_REGNUM);
186 pt_struct.pt_ipb = read_register (IPB_REGNUM);
187 pt_struct.pt_q = read_register (Q_REGNUM);
188 pt_struct.pt_bp = read_register (BP_REGNUM);
189 pt_struct.pt_fc = read_register (FC_REGNUM);
c906108c
SS
190 errno = 0;
191 ptrace (PT_WRITE_STRUCT, inferior_pid,
c5aa993b
JM
192 (PTRACE_ARG3_TYPE) register_addr (CPS_REGNUM, 0),
193 (int) &pt_struct.pt_psr, (10) * 4);
c906108c
SS
194 if (errno != 0)
195 {
c5aa993b
JM
196 sprintf (buf, "writing all special registers");
197 perror_with_name (buf);
198 return;
c906108c
SS
199 }
200#else
c5aa993b
JM
201 store_inferior_registers (GR1_REGNUM);
202 for (regno = GR96_REGNUM; regno < GR96_REGNUM + 32; regno++)
203 store_inferior_registers (regno);
204 for (regno = LR0_REGNUM; regno < LR0_REGNUM + 128; regno++)
205 store_inferior_registers (regno);
206 store_inferior_registers (CPS_REGNUM);
207 store_inferior_registers (PC_REGNUM);
208 store_inferior_registers (NPC_REGNUM);
209 store_inferior_registers (PC2_REGNUM);
210 store_inferior_registers (IPC_REGNUM);
211 store_inferior_registers (IPA_REGNUM);
212 store_inferior_registers (IPB_REGNUM);
213 store_inferior_registers (Q_REGNUM);
214 store_inferior_registers (BP_REGNUM);
215 store_inferior_registers (FC_REGNUM);
216#endif /* ULTRA3 */
c906108c
SS
217 }
218}
219
220/*
221 * Fetch an individual register (and supply it).
222 * return 0 on success, -1 on failure.
223 * NOTE: Assumes AMD's Binary Compatibility Standard for ptrace().
224 */
225static void
fba45db2 226fetch_register (int regno)
c906108c
SS
227{
228 char buf[128];
c5aa993b
JM
229 int val;
230
231 if (CANNOT_FETCH_REGISTER (regno))
232 {
233 val = -1;
c906108c
SS
234 supply_register (regno, &val);
235 }
c5aa993b
JM
236 else
237 {
238 errno = 0;
239 val = ptrace (PT_READ_U, inferior_pid,
240 (PTRACE_ARG3_TYPE) register_addr (regno, 0), 0);
241 if (errno != 0)
242 {
243 sprintf (buf, "reading register %s (#%d)", REGISTER_NAME (regno), regno);
244 perror_with_name (buf);
245 }
246 else
247 {
248 supply_register (regno, &val);
249 }
250 }
c906108c
SS
251}
252
253
254/*
255 * Read AMD's Binary Compatibilty Standard conforming core file.
256 * struct ptrace_user is the first thing in the core file
3ed9691f
KB
257 *
258 * CORE_REG_SECT, CORE_REG_SIZE, WHICH, and REG_ADDR are all ignored.
c906108c
SS
259 */
260
261static void
3ed9691f
KB
262fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
263 int which, CORE_ADDR reg_addr)
c906108c
SS
264{
265 register int regno;
c5aa993b
JM
266 int val;
267 char buf[4];
268
269 for (regno = 0; regno < NUM_REGS; regno++)
270 {
271 if (!CANNOT_FETCH_REGISTER (regno))
272 {
273 val = bfd_seek (core_bfd, (file_ptr) register_addr (regno, 0), SEEK_SET);
274 if (val < 0 || (val = bfd_read (buf, sizeof buf, 1, core_bfd)) < 0)
275 {
276 char *buffer = (char *) alloca (strlen (REGISTER_NAME (regno)) + 35);
277 strcpy (buffer, "Reading core register ");
278 strcat (buffer, REGISTER_NAME (regno));
279 perror_with_name (buffer);
280 }
281 supply_register (regno, buf);
282 }
c906108c 283 }
c906108c 284
c5aa993b
JM
285 /* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
286 registers_fetched ();
c906108c
SS
287}
288
289
290/*
291 * Takes a register number as defined in tm.h via REGISTER_NAMES, and maps
292 * it to an offset in a struct ptrace_user defined by AMD's BCS.
293 * That is, it defines the mapping between gdb register numbers and items in
294 * a struct ptrace_user.
295 * A register protection scheme is set up here. If a register not
296 * available to the user is specified in 'regno', then an address that
297 * will cause ptrace() to fail is returned.
298 */
299CORE_ADDR
fba45db2 300register_addr (int regno, CORE_ADDR blockend)
c906108c 301{
c5aa993b
JM
302 if ((regno >= LR0_REGNUM) && (regno < LR0_REGNUM + 128))
303 {
304 return (offsetof (struct ptrace_user, pt_lr[regno - LR0_REGNUM]));
305 }
306 else if ((regno >= GR96_REGNUM) && (regno < GR96_REGNUM + 32))
307 {
308 return (offsetof (struct ptrace_user, pt_gr[regno - GR96_REGNUM]));
309 }
310 else
311 {
312 switch (regno)
313 {
314 case GR1_REGNUM:
315 return (offsetof (struct ptrace_user, pt_gr1));
316 case CPS_REGNUM:
317 return (offsetof (struct ptrace_user, pt_psr));
318 case NPC_REGNUM:
319 return (offsetof (struct ptrace_user, pt_pc0));
320 case PC_REGNUM:
321 return (offsetof (struct ptrace_user, pt_pc1));
322 case PC2_REGNUM:
323 return (offsetof (struct ptrace_user, pt_pc2));
324 case IPC_REGNUM:
325 return (offsetof (struct ptrace_user, pt_ipc));
326 case IPA_REGNUM:
327 return (offsetof (struct ptrace_user, pt_ipa));
328 case IPB_REGNUM:
329 return (offsetof (struct ptrace_user, pt_ipb));
330 case Q_REGNUM:
331 return (offsetof (struct ptrace_user, pt_q));
332 case BP_REGNUM:
333 return (offsetof (struct ptrace_user, pt_bp));
334 case FC_REGNUM:
335 return (offsetof (struct ptrace_user, pt_fc));
c906108c 336 default:
c5aa993b
JM
337 fprintf_filtered (gdb_stderr, "register_addr():Bad register %s (%d)\n",
338 REGISTER_NAME (regno), regno);
339 return (0xffffffff); /* Should make ptrace() fail */
340 }
c906108c 341 }
c906108c 342}
c906108c 343\f
c5aa993b 344
c906108c
SS
345/* Register that we are able to handle ultra3 core file formats.
346 FIXME: is this really bfd_target_unknown_flavour? */
347
348static struct core_fns ultra3_core_fns =
349{
2acceee2
JM
350 bfd_target_unknown_flavour, /* core_flavour */
351 default_check_format, /* check_format */
352 default_core_sniffer, /* core_sniffer */
353 fetch_core_registers, /* core_read_registers */
354 NULL /* next */
c906108c
SS
355};
356
357void
fba45db2 358_initialize_core_ultra3 (void)
c906108c
SS
359{
360 add_core_fns (&ultra3_core_fns);
361}
This page took 0.1032 seconds and 4 git commands to generate.