Tue Mar 3 15:11:52 1992 Michael Tiemann (tiemann@cygnus.com)
[binutils-gdb.git] / gdb / ultra3-xdep.c
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
5 This file is part of GDB.
6
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.
11
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.
16
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #define DEBUG
22 #include "defs.h"
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
55 extern int errno;
56 struct 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 */
63 static void
64 fetch_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;
75 val = ptrace (PT_READ_U, inferior_pid, (int*)register_addr(regno,0), 0);
76 if (errno != 0) {
77 sprintf(buf,"reading register %s (#%d)",reg_names[regno],regno);
78 perror_with_name (buf);
79 } else {
80 supply_register (regno, &val);
81 }
82 }
83 }
84
85 /* Get all available registers from the inferior. Registers that are
86 * defined in REGISTER_NAMES, but not available to the user/gdb are
87 * supplied as -1. This may include gr64-gr95 and the protected special
88 * purpose registers.
89 */
90
91 void
92 fetch_inferior_registers (regno)
93 int regno;
94 {
95 register int i,j,ret_val=0;
96 char buf[128];
97
98 if (regno != -1) {
99 fetch_register (regno);
100 return;
101 }
102
103 /* Global Registers */
104 #ifdef ULTRA3
105 errno = 0;
106 ptrace (PT_READ_STRUCT, inferior_pid, (int*)register_addr(GR96_REGNUM,0),
107 (int)&pt_struct.pt_gr[0], 32*4);
108 if (errno != 0) {
109 perror_with_name ("reading global registers");
110 ret_val = -1;
111 } else for (regno=GR96_REGNUM, j=0 ; j<32 ; regno++, j++) {
112 supply_register (regno, &pt_struct.pt_gr[j]);
113 }
114 #else
115 for (regno=GR96_REGNUM ; !ret_val && regno < GR96_REGNUM+32 ; regno++)
116 fetch_register(regno);
117 #endif
118
119 /* Local Registers */
120 #ifdef ULTRA3
121 errno = 0;
122 ptrace (PT_READ_STRUCT, inferior_pid, (int*)register_addr(LR0_REGNUM,0),
123 (int)&pt_struct.pt_lr[0], 128*4);
124 if (errno != 0) {
125 perror_with_name ("reading local registers");
126 ret_val = -1;
127 } else for (regno=LR0_REGNUM, j=0 ; j<128 ; regno++, j++) {
128 supply_register (regno, &pt_struct.pt_lr[j]);
129 }
130 #else
131 for (regno=LR0_REGNUM ; !ret_val && regno < LR0_REGNUM+128 ; regno++)
132 fetch_register(regno);
133 #endif
134
135 /* Special Registers */
136 fetch_register(GR1_REGNUM);
137 fetch_register(CPS_REGNUM);
138 fetch_register(PC_REGNUM);
139 fetch_register(NPC_REGNUM);
140 fetch_register(PC2_REGNUM);
141 fetch_register(IPC_REGNUM);
142 fetch_register(IPA_REGNUM);
143 fetch_register(IPB_REGNUM);
144 fetch_register(Q_REGNUM);
145 fetch_register(BP_REGNUM);
146 fetch_register(FC_REGNUM);
147
148 /* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
149 registers_fetched();
150 }
151
152 /* Store our register values back into the inferior.
153 * If REGNO is -1, do this for all registers.
154 * Otherwise, REGNO specifies which register (so we can save time).
155 * NOTE: Assumes AMD's binary compatibility standard.
156 */
157
158 void
159 store_inferior_registers (regno)
160 int regno;
161 {
162 register unsigned int regaddr;
163 char buf[80];
164
165 if (regno >= 0)
166 {
167 if (CANNOT_STORE_REGISTER(regno))
168 return;
169 regaddr = register_addr (regno, 0);
170 errno = 0;
171 ptrace (PT_WRITE_U, inferior_pid,(int*)regaddr,read_register(regno));
172 if (errno != 0)
173 {
174 sprintf (buf, "writing register %s (#%d)", reg_names[regno],regno);
175 perror_with_name (buf);
176 }
177 }
178 else
179 {
180 #ifdef ULTRA3
181 pt_struct.pt_gr1 = read_register(GR1_REGNUM);
182 for (regno = GR96_REGNUM; regno < GR96_REGNUM+32; regno++)
183 pt_struct.pt_gr[regno] = read_register(regno);
184 for (regno = LR0_REGNUM; regno < LR0_REGNUM+128; regno++)
185 pt_struct.pt_gr[regno] = read_register(regno);
186 errno = 0;
187 ptrace (PT_WRITE_STRUCT, inferior_pid, (int*)register_addr(GR1_REGNUM,0),
188 (int)&pt_struct.pt_gr1,(1*32*128)*4);
189 if (errno != 0)
190 {
191 sprintf (buf, "writing all local/global registers");
192 perror_with_name (buf);
193 }
194 pt_struct.pt_psr = read_register(CPS_REGNUM);
195 pt_struct.pt_pc0 = read_register(NPC_REGNUM);
196 pt_struct.pt_pc1 = read_register(PC_REGNUM);
197 pt_struct.pt_pc2 = read_register(PC2_REGNUM);
198 pt_struct.pt_ipc = read_register(IPC_REGNUM);
199 pt_struct.pt_ipa = read_register(IPA_REGNUM);
200 pt_struct.pt_ipb = read_register(IPB_REGNUM);
201 pt_struct.pt_q = read_register(Q_REGNUM);
202 pt_struct.pt_bp = read_register(BP_REGNUM);
203 pt_struct.pt_fc = read_register(FC_REGNUM);
204 errno = 0;
205 ptrace (PT_WRITE_STRUCT, inferior_pid, (int*)register_addr(CPS_REGNUM,0),
206 (int)&pt_struct.pt_psr,(10)*4);
207 if (errno != 0)
208 {
209 sprintf (buf, "writing all special registers");
210 perror_with_name (buf);
211 return;
212 }
213 #else
214 store_inferior_registers(GR1_REGNUM);
215 for (regno=GR96_REGNUM ; regno<GR96_REGNUM+32 ; regno++)
216 store_inferior_registers(regno);
217 for (regno=LR0_REGNUM ; regno<LR0_REGNUM+128 ; regno++)
218 store_inferior_registers(regno);
219 store_inferior_registers(CPS_REGNUM);
220 store_inferior_registers(PC_REGNUM);
221 store_inferior_registers(NPC_REGNUM);
222 store_inferior_registers(PC2_REGNUM);
223 store_inferior_registers(IPC_REGNUM);
224 store_inferior_registers(IPA_REGNUM);
225 store_inferior_registers(IPB_REGNUM);
226 store_inferior_registers(Q_REGNUM);
227 store_inferior_registers(BP_REGNUM);
228 store_inferior_registers(FC_REGNUM);
229 #endif /* ULTRA3 */
230 }
231 }
232
233 /*
234 * Read AMD's Binary Compatibilty Standard conforming core file.
235 * struct ptrace_user is the first thing in the core file
236 */
237
238 void
239 fetch_core_registers ()
240 {
241 register int regno;
242 int val;
243 char buf[4];
244
245 for (regno = 0 ; regno < NUM_REGS; regno++) {
246 if (!CANNOT_FETCH_REGISTER(regno)) {
247 val = bfd_seek (core_bfd, register_addr (regno, 0), 0);
248 if (val < 0 || (val = bfd_read (buf, sizeof buf, 1, core_bfd)) < 0) {
249 char * buffer = (char *) alloca (strlen (reg_names[regno]) + 35);
250 strcpy (buffer, "Reading core register ");
251 strcat (buffer, reg_names[regno]);
252 perror_with_name (buffer);
253 }
254 supply_register (regno, buf);
255 }
256 }
257
258 /* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
259 registers_fetched();
260 }
261
262
263 /*
264 * Takes a register number as defined in tm.h via REGISTER_NAMES, and maps
265 * it to an offset in a struct ptrace_user defined by AMD's BCS.
266 * That is, it defines the mapping between gdb register numbers and items in
267 * a struct ptrace_user.
268 * A register protection scheme is set up here. If a register not
269 * available to the user is specified in 'regno', then an address that
270 * will cause ptrace() to fail is returned.
271 */
272 unsigned int
273 register_addr (regno,blockend)
274 unsigned int regno;
275 char *blockend;
276 {
277 if ((regno >= LR0_REGNUM) && (regno < LR0_REGNUM + 128)) {
278 return(offsetof(struct ptrace_user,pt_lr[regno-LR0_REGNUM]));
279 } else if ((regno >= GR96_REGNUM) && (regno < GR96_REGNUM + 32)) {
280 return(offsetof(struct ptrace_user,pt_gr[regno-GR96_REGNUM]));
281 } else {
282 switch (regno) {
283 case GR1_REGNUM: return(offsetof(struct ptrace_user,pt_gr1));
284 case CPS_REGNUM: return(offsetof(struct ptrace_user,pt_psr));
285 case NPC_REGNUM: return(offsetof(struct ptrace_user,pt_pc0));
286 case PC_REGNUM: return(offsetof(struct ptrace_user,pt_pc1));
287 case PC2_REGNUM: return(offsetof(struct ptrace_user,pt_pc2));
288 case IPC_REGNUM: return(offsetof(struct ptrace_user,pt_ipc));
289 case IPA_REGNUM: return(offsetof(struct ptrace_user,pt_ipa));
290 case IPB_REGNUM: return(offsetof(struct ptrace_user,pt_ipb));
291 case Q_REGNUM: return(offsetof(struct ptrace_user,pt_q));
292 case BP_REGNUM: return(offsetof(struct ptrace_user,pt_bp));
293 case FC_REGNUM: return(offsetof(struct ptrace_user,pt_fc));
294 default:
295 fprintf_filtered(stderr,"register_addr():Bad register %s (%d)\n",
296 reg_names[regno],regno);
297 return(0xffffffff); /* Should make ptrace() fail */
298 }
299 }
300 }
301
302
303 /* Assorted operating system circumventions */
304
305 #ifdef SYM1
306
307 /* FIXME: Kludge this for now. It really should be system call. */
308 int
309 getpagesize()
310 { return(8192); }
311
312 /* FIXME: Fake out the fcntl() call, which we don't have. */
313 fcntl(fd, cmd, arg)
314 int fd, cmd, arg;
315 {
316
317 switch (cmd) {
318 case F_GETFL: return(O_RDONLY); break;
319 default:
320 printf("Ultra3's fcntl() failing, cmd = %d.\n",cmd);
321 return(-1);
322 }
323 }
324
325
326 /*
327 * 4.2 Signal support, requires linking with libjobs.
328 */
329 static int _SigMask;
330 #define sigbit(s) (1L << ((s)-1))
331
332 init_SigMask()
333 {
334 /* Taken from the sym1 kernel in machdep.c:startup() */
335 _SigMask = sigbit (SIGTSTP) | sigbit (SIGTTOU) | sigbit (SIGTTIN) |
336 sigbit (SIGCHLD) | sigbit (SIGTINT);
337 }
338
339 sigmask(signo)
340 int signo;
341 {
342 return (1 << (signo-1));
343 }
344
345 sigsetmask(sigmask)
346 unsigned int sigmask;
347 {
348 int i, mask = 1;
349 int lastmask = _SigMask;
350
351 for (i=0 ; i<NSIG ; i++) {
352 if (sigmask & mask) {
353 if (!(_SigMask & mask)) {
354 sighold(i+1);
355 _SigMask |= mask;
356 }
357 } else if (_SigMask & mask) {
358 sigrelse(i+1);
359 _SigMask &= ~mask;
360 }
361 mask <<= 1;
362 }
363 return (lastmask);
364 }
365
366 sigblock(sigmask)
367 unsigned int sigmask;
368 {
369 int i, mask = 1;
370 int lastmask = _SigMask;
371
372 for (i=0 ; i<NSIG ; i++) {
373 if ((sigmask & mask) && !(_SigMask & mask)) {
374 sighold(i+1);
375 _SigMask |= mask;
376 }
377 mask <<= 1;
378 }
379 return (lastmask);
380 }
381 #endif /* SYM1 */
382
383
384 /* Initialization code for this module. */
385
386 _initialize_ultra3 ()
387 {
388 #ifdef SYM1
389 init_SigMask();
390 #endif
391 }