]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ultra3-nat.c
import gdb-1999-07-07 post reformat
[thirdparty/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
40static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
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
67fetch_inferior_registers (regno)
c5aa993b 68 int regno;
c906108c 69{
c5aa993b 70 register int i, j, ret_val = 0;
c906108c
SS
71 char buf[128];
72
c5aa993b
JM
73 if (regno != -1)
74 {
75 fetch_register (regno);
76 return;
77 }
c906108c
SS
78
79/* Global Registers */
80#ifdef ULTRA3
81 errno = 0;
82 ptrace (PT_READ_STRUCT, inferior_pid,
c5aa993b
JM
83 (PTRACE_ARG3_TYPE) register_addr (GR96_REGNUM, 0),
84 (int) &pt_struct.pt_gr[0], 32 * 4);
85 if (errno != 0)
86 {
c906108c
SS
87 perror_with_name ("reading global registers");
88 ret_val = -1;
c5aa993b
JM
89 }
90 else
91 for (regno = GR96_REGNUM, j = 0; j < 32; regno++, j++)
92 {
93 supply_register (regno, &pt_struct.pt_gr[j]);
94 }
c906108c 95#else
c5aa993b
JM
96 for (regno = GR96_REGNUM; !ret_val && regno < GR96_REGNUM + 32; regno++)
97 fetch_register (regno);
c906108c
SS
98#endif
99
100/* Local Registers */
101#ifdef ULTRA3
102 errno = 0;
103 ptrace (PT_READ_STRUCT, inferior_pid,
c5aa993b
JM
104 (PTRACE_ARG3_TYPE) register_addr (LR0_REGNUM, 0),
105 (int) &pt_struct.pt_lr[0], 128 * 4);
106 if (errno != 0)
107 {
c906108c
SS
108 perror_with_name ("reading local registers");
109 ret_val = -1;
c5aa993b
JM
110 }
111 else
112 for (regno = LR0_REGNUM, j = 0; j < 128; regno++, j++)
113 {
114 supply_register (regno, &pt_struct.pt_lr[j]);
115 }
c906108c 116#else
c5aa993b
JM
117 for (regno = LR0_REGNUM; !ret_val && regno < LR0_REGNUM + 128; regno++)
118 fetch_register (regno);
c906108c
SS
119#endif
120
121/* Special Registers */
c5aa993b
JM
122 fetch_register (GR1_REGNUM);
123 fetch_register (CPS_REGNUM);
124 fetch_register (PC_REGNUM);
125 fetch_register (NPC_REGNUM);
126 fetch_register (PC2_REGNUM);
127 fetch_register (IPC_REGNUM);
128 fetch_register (IPA_REGNUM);
129 fetch_register (IPB_REGNUM);
130 fetch_register (Q_REGNUM);
131 fetch_register (BP_REGNUM);
132 fetch_register (FC_REGNUM);
133
134/* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
135 registers_fetched ();
c906108c
SS
136}
137
138/* Store our register values back into the inferior.
139 * If REGNO is -1, do this for all registers.
140 * Otherwise, REGNO specifies which register (so we can save time).
141 * NOTE: Assumes AMD's binary compatibility standard.
142 */
143
144void
145store_inferior_registers (regno)
146 int regno;
147{
148 register unsigned int regaddr;
149 char buf[80];
150
151 if (regno >= 0)
152 {
c5aa993b 153 if (CANNOT_STORE_REGISTER (regno))
c906108c
SS
154 return;
155 regaddr = register_addr (regno, 0);
156 errno = 0;
157 ptrace (PT_WRITE_U, inferior_pid,
c5aa993b 158 (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
c906108c
SS
159 if (errno != 0)
160 {
161 sprintf (buf, "writing register %s (#%d)", REGISTER_NAME (regno), regno);
162 perror_with_name (buf);
163 }
164 }
165 else
166 {
167#ifdef ULTRA3
c5aa993b
JM
168 pt_struct.pt_gr1 = read_register (GR1_REGNUM);
169 for (regno = GR96_REGNUM; regno < GR96_REGNUM + 32; regno++)
170 pt_struct.pt_gr[regno] = read_register (regno);
171 for (regno = LR0_REGNUM; regno < LR0_REGNUM + 128; regno++)
172 pt_struct.pt_gr[regno] = read_register (regno);
c906108c
SS
173 errno = 0;
174 ptrace (PT_WRITE_STRUCT, inferior_pid,
c5aa993b
JM
175 (PTRACE_ARG3_TYPE) register_addr (GR1_REGNUM, 0),
176 (int) &pt_struct.pt_gr1, (1 * 32 * 128) * 4);
c906108c
SS
177 if (errno != 0)
178 {
c5aa993b
JM
179 sprintf (buf, "writing all local/global registers");
180 perror_with_name (buf);
c906108c 181 }
c5aa993b
JM
182 pt_struct.pt_psr = read_register (CPS_REGNUM);
183 pt_struct.pt_pc0 = read_register (NPC_REGNUM);
184 pt_struct.pt_pc1 = read_register (PC_REGNUM);
185 pt_struct.pt_pc2 = read_register (PC2_REGNUM);
186 pt_struct.pt_ipc = read_register (IPC_REGNUM);
187 pt_struct.pt_ipa = read_register (IPA_REGNUM);
188 pt_struct.pt_ipb = read_register (IPB_REGNUM);
189 pt_struct.pt_q = read_register (Q_REGNUM);
190 pt_struct.pt_bp = read_register (BP_REGNUM);
191 pt_struct.pt_fc = read_register (FC_REGNUM);
c906108c
SS
192 errno = 0;
193 ptrace (PT_WRITE_STRUCT, inferior_pid,
c5aa993b
JM
194 (PTRACE_ARG3_TYPE) register_addr (CPS_REGNUM, 0),
195 (int) &pt_struct.pt_psr, (10) * 4);
c906108c
SS
196 if (errno != 0)
197 {
c5aa993b
JM
198 sprintf (buf, "writing all special registers");
199 perror_with_name (buf);
200 return;
c906108c
SS
201 }
202#else
c5aa993b
JM
203 store_inferior_registers (GR1_REGNUM);
204 for (regno = GR96_REGNUM; regno < GR96_REGNUM + 32; regno++)
205 store_inferior_registers (regno);
206 for (regno = LR0_REGNUM; regno < LR0_REGNUM + 128; regno++)
207 store_inferior_registers (regno);
208 store_inferior_registers (CPS_REGNUM);
209 store_inferior_registers (PC_REGNUM);
210 store_inferior_registers (NPC_REGNUM);
211 store_inferior_registers (PC2_REGNUM);
212 store_inferior_registers (IPC_REGNUM);
213 store_inferior_registers (IPA_REGNUM);
214 store_inferior_registers (IPB_REGNUM);
215 store_inferior_registers (Q_REGNUM);
216 store_inferior_registers (BP_REGNUM);
217 store_inferior_registers (FC_REGNUM);
218#endif /* ULTRA3 */
c906108c
SS
219 }
220}
221
222/*
223 * Fetch an individual register (and supply it).
224 * return 0 on success, -1 on failure.
225 * NOTE: Assumes AMD's Binary Compatibility Standard for ptrace().
226 */
227static void
228fetch_register (regno)
229 int regno;
230{
231 char buf[128];
c5aa993b
JM
232 int val;
233
234 if (CANNOT_FETCH_REGISTER (regno))
235 {
236 val = -1;
c906108c
SS
237 supply_register (regno, &val);
238 }
c5aa993b
JM
239 else
240 {
241 errno = 0;
242 val = ptrace (PT_READ_U, inferior_pid,
243 (PTRACE_ARG3_TYPE) register_addr (regno, 0), 0);
244 if (errno != 0)
245 {
246 sprintf (buf, "reading register %s (#%d)", REGISTER_NAME (regno), regno);
247 perror_with_name (buf);
248 }
249 else
250 {
251 supply_register (regno, &val);
252 }
253 }
c906108c
SS
254}
255
256
257/*
258 * Read AMD's Binary Compatibilty Standard conforming core file.
259 * struct ptrace_user is the first thing in the core file
260 */
261
262static void
263fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
264 char *core_reg_sect; /* Unused in this version */
265 unsigned core_reg_size; /* Unused in this version */
266 int which; /* Unused in this version */
267 CORE_ADDR reg_addr; /* Unused in this version */
268{
269 register int regno;
c5aa993b
JM
270 int val;
271 char buf[4];
272
273 for (regno = 0; regno < NUM_REGS; regno++)
274 {
275 if (!CANNOT_FETCH_REGISTER (regno))
276 {
277 val = bfd_seek (core_bfd, (file_ptr) register_addr (regno, 0), SEEK_SET);
278 if (val < 0 || (val = bfd_read (buf, sizeof buf, 1, core_bfd)) < 0)
279 {
280 char *buffer = (char *) alloca (strlen (REGISTER_NAME (regno)) + 35);
281 strcpy (buffer, "Reading core register ");
282 strcat (buffer, REGISTER_NAME (regno));
283 perror_with_name (buffer);
284 }
285 supply_register (regno, buf);
286 }
c906108c 287 }
c906108c 288
c5aa993b
JM
289 /* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
290 registers_fetched ();
c906108c
SS
291}
292
293
294/*
295 * Takes a register number as defined in tm.h via REGISTER_NAMES, and maps
296 * it to an offset in a struct ptrace_user defined by AMD's BCS.
297 * That is, it defines the mapping between gdb register numbers and items in
298 * a struct ptrace_user.
299 * A register protection scheme is set up here. If a register not
300 * available to the user is specified in 'regno', then an address that
301 * will cause ptrace() to fail is returned.
302 */
303CORE_ADDR
c5aa993b
JM
304register_addr (regno, blockend)
305 int regno;
306 CORE_ADDR blockend;
c906108c 307{
c5aa993b
JM
308 if ((regno >= LR0_REGNUM) && (regno < LR0_REGNUM + 128))
309 {
310 return (offsetof (struct ptrace_user, pt_lr[regno - LR0_REGNUM]));
311 }
312 else if ((regno >= GR96_REGNUM) && (regno < GR96_REGNUM + 32))
313 {
314 return (offsetof (struct ptrace_user, pt_gr[regno - GR96_REGNUM]));
315 }
316 else
317 {
318 switch (regno)
319 {
320 case GR1_REGNUM:
321 return (offsetof (struct ptrace_user, pt_gr1));
322 case CPS_REGNUM:
323 return (offsetof (struct ptrace_user, pt_psr));
324 case NPC_REGNUM:
325 return (offsetof (struct ptrace_user, pt_pc0));
326 case PC_REGNUM:
327 return (offsetof (struct ptrace_user, pt_pc1));
328 case PC2_REGNUM:
329 return (offsetof (struct ptrace_user, pt_pc2));
330 case IPC_REGNUM:
331 return (offsetof (struct ptrace_user, pt_ipc));
332 case IPA_REGNUM:
333 return (offsetof (struct ptrace_user, pt_ipa));
334 case IPB_REGNUM:
335 return (offsetof (struct ptrace_user, pt_ipb));
336 case Q_REGNUM:
337 return (offsetof (struct ptrace_user, pt_q));
338 case BP_REGNUM:
339 return (offsetof (struct ptrace_user, pt_bp));
340 case FC_REGNUM:
341 return (offsetof (struct ptrace_user, pt_fc));
c906108c 342 default:
c5aa993b
JM
343 fprintf_filtered (gdb_stderr, "register_addr():Bad register %s (%d)\n",
344 REGISTER_NAME (regno), regno);
345 return (0xffffffff); /* Should make ptrace() fail */
346 }
c906108c 347 }
c906108c 348}
c906108c 349\f
c5aa993b 350
c906108c
SS
351/* Register that we are able to handle ultra3 core file formats.
352 FIXME: is this really bfd_target_unknown_flavour? */
353
354static struct core_fns ultra3_core_fns =
355{
356 bfd_target_unknown_flavour,
357 fetch_core_registers,
358 NULL
359};
360
361void
362_initialize_core_ultra3 ()
363{
364 add_core_fns (&ultra3_core_fns);
365}