A ton of changes to improve C++ debugging. See ChangeLog.
[deliverable/binutils-gdb.git] / gdb / ultra3-xdep.c
CommitLineData
7c18a68f
JG
1/* Host-dependent code for GDB, for NYU Ultra3 running Sym1 OS.
2 Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
3 Contributed by David Wood (wood@nyu.edu) at New York University.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#define DEBUG
7c18a68f 22#include "defs.h"
7c18a68f
JG
23#include "frame.h"
24#include "inferior.h"
25#include "symtab.h"
26#include "value.h"
27
28#include <sys/types.h>
29#include <sys/param.h>
30#include <signal.h>
31#include <sys/ioctl.h>
32#include <fcntl.h>
33
34#include "gdbcore.h"
35
36#include <sys/file.h>
37#include <sys/stat.h>
38#include <sys/ptrace.h>
39
40/* Assumes support for AMD's Binary Compatibility Standard
41 for ptrace(). If you define ULTRA3, the ultra3 extensions to
42 ptrace() are used allowing the reading of more than one register
43 at a time.
44
45 This file assumes KERNEL_DEBUGGING is turned off. This means
46 that if the user/gdb tries to read gr64-gr95 or any of the
47 protected special registers we silently return -1 (see the
48 CANNOT_STORE/FETCH_REGISTER macros). */
49#define ULTRA3
50
51#if !defined (offsetof)
52# define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
53#endif
54
55extern int errno;
56struct ptrace_user pt_struct;
57
58/*
59 * Fetch an individual register (and supply it).
60 * return 0 on success, -1 on failure.
61 * NOTE: Assumes AMD's Binary Compatibility Standard for ptrace().
62 */
63static void
64fetch_register (regno)
65 int regno;
66{
67 char buf[128];
68 int val;
69
70 if (CANNOT_FETCH_REGISTER(regno)) {
71 val = -1;
72 supply_register (regno, &val);
73 } else {
74 errno = 0;
e676a15f
FF
75 val = ptrace (PT_READ_U, inferior_pid,
76 (PTRACE_ARG3_TYPE) register_addr(regno,0), 0);
7c18a68f
JG
77 if (errno != 0) {
78 sprintf(buf,"reading register %s (#%d)",reg_names[regno],regno);
79 perror_with_name (buf);
80 } else {
81 supply_register (regno, &val);
82 }
83 }
84}
85
86/* Get all available registers from the inferior. Registers that are
87 * defined in REGISTER_NAMES, but not available to the user/gdb are
88 * supplied as -1. This may include gr64-gr95 and the protected special
89 * purpose registers.
90 */
91
92void
93fetch_inferior_registers (regno)
94 int regno;
95{
96 register int i,j,ret_val=0;
97 char buf[128];
98
99 if (regno != -1) {
100 fetch_register (regno);
101 return;
102 }
103
104/* Global Registers */
105#ifdef ULTRA3
106 errno = 0;
e676a15f
FF
107 ptrace (PT_READ_STRUCT, inferior_pid,
108 (PTRACE_ARG3_TYPE) register_addr(GR96_REGNUM,0),
109 (int)&pt_struct.pt_gr[0], 32*4);
7c18a68f
JG
110 if (errno != 0) {
111 perror_with_name ("reading global registers");
112 ret_val = -1;
113 } else for (regno=GR96_REGNUM, j=0 ; j<32 ; regno++, j++) {
114 supply_register (regno, &pt_struct.pt_gr[j]);
115 }
116#else
117 for (regno=GR96_REGNUM ; !ret_val && regno < GR96_REGNUM+32 ; regno++)
118 fetch_register(regno);
119#endif
120
121/* Local Registers */
122#ifdef ULTRA3
123 errno = 0;
e676a15f
FF
124 ptrace (PT_READ_STRUCT, inferior_pid,
125 (PTRACE_ARG3_TYPE) register_addr(LR0_REGNUM,0),
126 (int)&pt_struct.pt_lr[0], 128*4);
7c18a68f
JG
127 if (errno != 0) {
128 perror_with_name ("reading local registers");
129 ret_val = -1;
130 } else for (regno=LR0_REGNUM, j=0 ; j<128 ; regno++, j++) {
131 supply_register (regno, &pt_struct.pt_lr[j]);
132 }
133#else
134 for (regno=LR0_REGNUM ; !ret_val && regno < LR0_REGNUM+128 ; regno++)
135 fetch_register(regno);
136#endif
137
138/* Special Registers */
139 fetch_register(GR1_REGNUM);
140 fetch_register(CPS_REGNUM);
141 fetch_register(PC_REGNUM);
142 fetch_register(NPC_REGNUM);
143 fetch_register(PC2_REGNUM);
144 fetch_register(IPC_REGNUM);
145 fetch_register(IPA_REGNUM);
146 fetch_register(IPB_REGNUM);
147 fetch_register(Q_REGNUM);
148 fetch_register(BP_REGNUM);
149 fetch_register(FC_REGNUM);
150
151/* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
152 registers_fetched();
153}
154
155/* Store our register values back into the inferior.
156 * If REGNO is -1, do this for all registers.
157 * Otherwise, REGNO specifies which register (so we can save time).
158 * NOTE: Assumes AMD's binary compatibility standard.
159 */
160
7919c3ed 161void
7c18a68f
JG
162store_inferior_registers (regno)
163 int regno;
164{
165 register unsigned int regaddr;
166 char buf[80];
167
168 if (regno >= 0)
169 {
170 if (CANNOT_STORE_REGISTER(regno))
7919c3ed 171 return;
7c18a68f
JG
172 regaddr = register_addr (regno, 0);
173 errno = 0;
e676a15f
FF
174 ptrace (PT_WRITE_U, inferior_pid,
175 (PTRACE_ARG3_TYPE) regaddr, read_register(regno));
7c18a68f
JG
176 if (errno != 0)
177 {
178 sprintf (buf, "writing register %s (#%d)", reg_names[regno],regno);
179 perror_with_name (buf);
180 }
181 }
182 else
183 {
184#ifdef ULTRA3
185 pt_struct.pt_gr1 = read_register(GR1_REGNUM);
186 for (regno = GR96_REGNUM; regno < GR96_REGNUM+32; regno++)
187 pt_struct.pt_gr[regno] = read_register(regno);
188 for (regno = LR0_REGNUM; regno < LR0_REGNUM+128; regno++)
189 pt_struct.pt_gr[regno] = read_register(regno);
190 errno = 0;
e676a15f
FF
191 ptrace (PT_WRITE_STRUCT, inferior_pid,
192 (PTRACE_ARG3_TYPE) register_addr(GR1_REGNUM,0),
193 (int)&pt_struct.pt_gr1,(1*32*128)*4);
7c18a68f
JG
194 if (errno != 0)
195 {
196 sprintf (buf, "writing all local/global registers");
197 perror_with_name (buf);
198 }
199 pt_struct.pt_psr = read_register(CPS_REGNUM);
200 pt_struct.pt_pc0 = read_register(NPC_REGNUM);
201 pt_struct.pt_pc1 = read_register(PC_REGNUM);
202 pt_struct.pt_pc2 = read_register(PC2_REGNUM);
203 pt_struct.pt_ipc = read_register(IPC_REGNUM);
204 pt_struct.pt_ipa = read_register(IPA_REGNUM);
205 pt_struct.pt_ipb = read_register(IPB_REGNUM);
206 pt_struct.pt_q = read_register(Q_REGNUM);
207 pt_struct.pt_bp = read_register(BP_REGNUM);
208 pt_struct.pt_fc = read_register(FC_REGNUM);
209 errno = 0;
e676a15f
FF
210 ptrace (PT_WRITE_STRUCT, inferior_pid,
211 (PTRACE_ARG3_TYPE) register_addr(CPS_REGNUM,0),
212 (int)&pt_struct.pt_psr,(10)*4);
7c18a68f
JG
213 if (errno != 0)
214 {
215 sprintf (buf, "writing all special registers");
216 perror_with_name (buf);
7919c3ed 217 return;
7c18a68f
JG
218 }
219#else
220 store_inferior_registers(GR1_REGNUM);
221 for (regno=GR96_REGNUM ; regno<GR96_REGNUM+32 ; regno++)
222 store_inferior_registers(regno);
223 for (regno=LR0_REGNUM ; regno<LR0_REGNUM+128 ; regno++)
224 store_inferior_registers(regno);
225 store_inferior_registers(CPS_REGNUM);
226 store_inferior_registers(PC_REGNUM);
227 store_inferior_registers(NPC_REGNUM);
228 store_inferior_registers(PC2_REGNUM);
229 store_inferior_registers(IPC_REGNUM);
230 store_inferior_registers(IPA_REGNUM);
231 store_inferior_registers(IPB_REGNUM);
232 store_inferior_registers(Q_REGNUM);
233 store_inferior_registers(BP_REGNUM);
234 store_inferior_registers(FC_REGNUM);
235#endif /* ULTRA3 */
236 }
7c18a68f
JG
237}
238
239/*
240 * Read AMD's Binary Compatibilty Standard conforming core file.
241 * struct ptrace_user is the first thing in the core file
242 */
7919c3ed 243
7c18a68f
JG
244void
245fetch_core_registers ()
246{
247 register int regno;
248 int val;
249 char buf[4];
250
251 for (regno = 0 ; regno < NUM_REGS; regno++) {
252 if (!CANNOT_FETCH_REGISTER(regno)) {
253 val = bfd_seek (core_bfd, register_addr (regno, 0), 0);
254 if (val < 0 || (val = bfd_read (buf, sizeof buf, 1, core_bfd)) < 0) {
255 char * buffer = (char *) alloca (strlen (reg_names[regno]) + 35);
256 strcpy (buffer, "Reading core register ");
257 strcat (buffer, reg_names[regno]);
258 perror_with_name (buffer);
259 }
260 supply_register (regno, buf);
261 }
262 }
263
264 /* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
265 registers_fetched();
266}
267
268
269/*
270 * Takes a register number as defined in tm.h via REGISTER_NAMES, and maps
271 * it to an offset in a struct ptrace_user defined by AMD's BCS.
272 * That is, it defines the mapping between gdb register numbers and items in
273 * a struct ptrace_user.
274 * A register protection scheme is set up here. If a register not
275 * available to the user is specified in 'regno', then an address that
276 * will cause ptrace() to fail is returned.
277 */
278unsigned int
279register_addr (regno,blockend)
280 unsigned int regno;
281 char *blockend;
282{
283 if ((regno >= LR0_REGNUM) && (regno < LR0_REGNUM + 128)) {
284 return(offsetof(struct ptrace_user,pt_lr[regno-LR0_REGNUM]));
285 } else if ((regno >= GR96_REGNUM) && (regno < GR96_REGNUM + 32)) {
286 return(offsetof(struct ptrace_user,pt_gr[regno-GR96_REGNUM]));
287 } else {
288 switch (regno) {
289 case GR1_REGNUM: return(offsetof(struct ptrace_user,pt_gr1));
290 case CPS_REGNUM: return(offsetof(struct ptrace_user,pt_psr));
291 case NPC_REGNUM: return(offsetof(struct ptrace_user,pt_pc0));
292 case PC_REGNUM: return(offsetof(struct ptrace_user,pt_pc1));
293 case PC2_REGNUM: return(offsetof(struct ptrace_user,pt_pc2));
294 case IPC_REGNUM: return(offsetof(struct ptrace_user,pt_ipc));
295 case IPA_REGNUM: return(offsetof(struct ptrace_user,pt_ipa));
296 case IPB_REGNUM: return(offsetof(struct ptrace_user,pt_ipb));
297 case Q_REGNUM: return(offsetof(struct ptrace_user,pt_q));
298 case BP_REGNUM: return(offsetof(struct ptrace_user,pt_bp));
299 case FC_REGNUM: return(offsetof(struct ptrace_user,pt_fc));
300 default:
301 fprintf_filtered(stderr,"register_addr():Bad register %s (%d)\n",
302 reg_names[regno],regno);
303 return(0xffffffff); /* Should make ptrace() fail */
304 }
305 }
306}
307
308
309/* Assorted operating system circumventions */
310
311#ifdef SYM1
312
313/* FIXME: Kludge this for now. It really should be system call. */
314int
315getpagesize()
316{ return(8192); }
317
318/* FIXME: Fake out the fcntl() call, which we don't have. */
319fcntl(fd, cmd, arg)
320int fd, cmd, arg;
321{
322
323 switch (cmd) {
324 case F_GETFL: return(O_RDONLY); break;
325 default:
326 printf("Ultra3's fcntl() failing, cmd = %d.\n",cmd);
327 return(-1);
328 }
329}
330
331
332/*
333 * 4.2 Signal support, requires linking with libjobs.
334 */
335static int _SigMask;
336#define sigbit(s) (1L << ((s)-1))
337
338init_SigMask()
339{
340 /* Taken from the sym1 kernel in machdep.c:startup() */
341 _SigMask = sigbit (SIGTSTP) | sigbit (SIGTTOU) | sigbit (SIGTTIN) |
342 sigbit (SIGCHLD) | sigbit (SIGTINT);
343}
344
345sigmask(signo)
346 int signo;
347{
348 return (1 << (signo-1));
349}
350
351sigsetmask(sigmask)
352unsigned int sigmask;
353{
354 int i, mask = 1;
355 int lastmask = _SigMask;
356
357 for (i=0 ; i<NSIG ; i++) {
358 if (sigmask & mask) {
359 if (!(_SigMask & mask)) {
360 sighold(i+1);
361 _SigMask |= mask;
362 }
363 } else if (_SigMask & mask) {
364 sigrelse(i+1);
365 _SigMask &= ~mask;
366 }
367 mask <<= 1;
368 }
369 return (lastmask);
370}
371
372sigblock(sigmask)
373unsigned int sigmask;
374{
375 int i, mask = 1;
376 int lastmask = _SigMask;
377
378 for (i=0 ; i<NSIG ; i++) {
379 if ((sigmask & mask) && !(_SigMask & mask)) {
380 sighold(i+1);
381 _SigMask |= mask;
382 }
383 mask <<= 1;
384 }
385 return (lastmask);
386}
387#endif /* SYM1 */
388
389
390/* Initialization code for this module. */
391
392_initialize_ultra3 ()
393{
394#ifdef SYM1
395 init_SigMask();
396#endif
397}
This page took 0.073303 seconds and 4 git commands to generate.