* tm-sparc.h, tm-sysv4.h, solib.h: Move shared lib definitions
[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
22#include <stdio.h>
23#include "defs.h"
7c18a68f
JG
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>
33#include <fcntl.h>
34
35#include "gdbcore.h"
36
37#include <sys/file.h>
38#include <sys/stat.h>
39#include <sys/ptrace.h>
40
41/* Assumes support for AMD's Binary Compatibility Standard
42 for ptrace(). If you define ULTRA3, the ultra3 extensions to
43 ptrace() are used allowing the reading of more than one register
44 at a time.
45
46 This file assumes KERNEL_DEBUGGING is turned off. This means
47 that if the user/gdb tries to read gr64-gr95 or any of the
48 protected special registers we silently return -1 (see the
49 CANNOT_STORE/FETCH_REGISTER macros). */
50#define ULTRA3
51
52#if !defined (offsetof)
53# define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
54#endif
55
56extern int errno;
57struct ptrace_user pt_struct;
58
59/*
60 * Fetch an individual register (and supply it).
61 * return 0 on success, -1 on failure.
62 * NOTE: Assumes AMD's Binary Compatibility Standard for ptrace().
63 */
64static void
65fetch_register (regno)
66 int regno;
67{
68 char buf[128];
69 int val;
70
71 if (CANNOT_FETCH_REGISTER(regno)) {
72 val = -1;
73 supply_register (regno, &val);
74 } else {
75 errno = 0;
76 val = ptrace (PT_READ_U, inferior_pid, (int*)register_addr(regno,0), 0);
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;
107 ptrace (PT_READ_STRUCT, inferior_pid, (int*)register_addr(GR96_REGNUM,0),
108 (int)&pt_struct.pt_gr[0], 32*4);
109 if (errno != 0) {
110 perror_with_name ("reading global registers");
111 ret_val = -1;
112 } else for (regno=GR96_REGNUM, j=0 ; j<32 ; regno++, j++) {
113 supply_register (regno, &pt_struct.pt_gr[j]);
114 }
115#else
116 for (regno=GR96_REGNUM ; !ret_val && regno < GR96_REGNUM+32 ; regno++)
117 fetch_register(regno);
118#endif
119
120/* Local Registers */
121#ifdef ULTRA3
122 errno = 0;
123 ptrace (PT_READ_STRUCT, inferior_pid, (int*)register_addr(LR0_REGNUM,0),
124 (int)&pt_struct.pt_lr[0], 128*4);
125 if (errno != 0) {
126 perror_with_name ("reading local registers");
127 ret_val = -1;
128 } else for (regno=LR0_REGNUM, j=0 ; j<128 ; regno++, j++) {
129 supply_register (regno, &pt_struct.pt_lr[j]);
130 }
131#else
132 for (regno=LR0_REGNUM ; !ret_val && regno < LR0_REGNUM+128 ; regno++)
133 fetch_register(regno);
134#endif
135
136/* Special Registers */
137 fetch_register(GR1_REGNUM);
138 fetch_register(CPS_REGNUM);
139 fetch_register(PC_REGNUM);
140 fetch_register(NPC_REGNUM);
141 fetch_register(PC2_REGNUM);
142 fetch_register(IPC_REGNUM);
143 fetch_register(IPA_REGNUM);
144 fetch_register(IPB_REGNUM);
145 fetch_register(Q_REGNUM);
146 fetch_register(BP_REGNUM);
147 fetch_register(FC_REGNUM);
148
149/* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
150 registers_fetched();
151}
152
153/* Store our register values back into the inferior.
154 * If REGNO is -1, do this for all registers.
155 * Otherwise, REGNO specifies which register (so we can save time).
156 * NOTE: Assumes AMD's binary compatibility standard.
157 */
158
7919c3ed 159void
7c18a68f
JG
160store_inferior_registers (regno)
161 int regno;
162{
163 register unsigned int regaddr;
164 char buf[80];
165
166 if (regno >= 0)
167 {
168 if (CANNOT_STORE_REGISTER(regno))
7919c3ed 169 return;
7c18a68f
JG
170 regaddr = register_addr (regno, 0);
171 errno = 0;
172 ptrace (PT_WRITE_U, inferior_pid,(int*)regaddr,read_register(regno));
173 if (errno != 0)
174 {
175 sprintf (buf, "writing register %s (#%d)", reg_names[regno],regno);
176 perror_with_name (buf);
177 }
178 }
179 else
180 {
181#ifdef ULTRA3
182 pt_struct.pt_gr1 = read_register(GR1_REGNUM);
183 for (regno = GR96_REGNUM; regno < GR96_REGNUM+32; regno++)
184 pt_struct.pt_gr[regno] = read_register(regno);
185 for (regno = LR0_REGNUM; regno < LR0_REGNUM+128; regno++)
186 pt_struct.pt_gr[regno] = read_register(regno);
187 errno = 0;
188 ptrace (PT_WRITE_STRUCT, inferior_pid, (int*)register_addr(GR1_REGNUM,0),
189 (int)&pt_struct.pt_gr1,(1*32*128)*4);
190 if (errno != 0)
191 {
192 sprintf (buf, "writing all local/global registers");
193 perror_with_name (buf);
194 }
195 pt_struct.pt_psr = read_register(CPS_REGNUM);
196 pt_struct.pt_pc0 = read_register(NPC_REGNUM);
197 pt_struct.pt_pc1 = read_register(PC_REGNUM);
198 pt_struct.pt_pc2 = read_register(PC2_REGNUM);
199 pt_struct.pt_ipc = read_register(IPC_REGNUM);
200 pt_struct.pt_ipa = read_register(IPA_REGNUM);
201 pt_struct.pt_ipb = read_register(IPB_REGNUM);
202 pt_struct.pt_q = read_register(Q_REGNUM);
203 pt_struct.pt_bp = read_register(BP_REGNUM);
204 pt_struct.pt_fc = read_register(FC_REGNUM);
205 errno = 0;
206 ptrace (PT_WRITE_STRUCT, inferior_pid, (int*)register_addr(CPS_REGNUM,0),
207 (int)&pt_struct.pt_psr,(10)*4);
208 if (errno != 0)
209 {
210 sprintf (buf, "writing all special registers");
211 perror_with_name (buf);
7919c3ed 212 return;
7c18a68f
JG
213 }
214#else
215 store_inferior_registers(GR1_REGNUM);
216 for (regno=GR96_REGNUM ; regno<GR96_REGNUM+32 ; regno++)
217 store_inferior_registers(regno);
218 for (regno=LR0_REGNUM ; regno<LR0_REGNUM+128 ; regno++)
219 store_inferior_registers(regno);
220 store_inferior_registers(CPS_REGNUM);
221 store_inferior_registers(PC_REGNUM);
222 store_inferior_registers(NPC_REGNUM);
223 store_inferior_registers(PC2_REGNUM);
224 store_inferior_registers(IPC_REGNUM);
225 store_inferior_registers(IPA_REGNUM);
226 store_inferior_registers(IPB_REGNUM);
227 store_inferior_registers(Q_REGNUM);
228 store_inferior_registers(BP_REGNUM);
229 store_inferior_registers(FC_REGNUM);
230#endif /* ULTRA3 */
231 }
7c18a68f
JG
232}
233
234/*
235 * Read AMD's Binary Compatibilty Standard conforming core file.
236 * struct ptrace_user is the first thing in the core file
237 */
7919c3ed 238
7c18a68f
JG
239void
240fetch_core_registers ()
241{
242 register int regno;
243 int val;
244 char buf[4];
245
246 for (regno = 0 ; regno < NUM_REGS; regno++) {
247 if (!CANNOT_FETCH_REGISTER(regno)) {
248 val = bfd_seek (core_bfd, register_addr (regno, 0), 0);
249 if (val < 0 || (val = bfd_read (buf, sizeof buf, 1, core_bfd)) < 0) {
250 char * buffer = (char *) alloca (strlen (reg_names[regno]) + 35);
251 strcpy (buffer, "Reading core register ");
252 strcat (buffer, reg_names[regno]);
253 perror_with_name (buffer);
254 }
255 supply_register (regno, buf);
256 }
257 }
258
259 /* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
260 registers_fetched();
261}
262
263
264/*
265 * Takes a register number as defined in tm.h via REGISTER_NAMES, and maps
266 * it to an offset in a struct ptrace_user defined by AMD's BCS.
267 * That is, it defines the mapping between gdb register numbers and items in
268 * a struct ptrace_user.
269 * A register protection scheme is set up here. If a register not
270 * available to the user is specified in 'regno', then an address that
271 * will cause ptrace() to fail is returned.
272 */
273unsigned int
274register_addr (regno,blockend)
275 unsigned int regno;
276 char *blockend;
277{
278 if ((regno >= LR0_REGNUM) && (regno < LR0_REGNUM + 128)) {
279 return(offsetof(struct ptrace_user,pt_lr[regno-LR0_REGNUM]));
280 } else if ((regno >= GR96_REGNUM) && (regno < GR96_REGNUM + 32)) {
281 return(offsetof(struct ptrace_user,pt_gr[regno-GR96_REGNUM]));
282 } else {
283 switch (regno) {
284 case GR1_REGNUM: return(offsetof(struct ptrace_user,pt_gr1));
285 case CPS_REGNUM: return(offsetof(struct ptrace_user,pt_psr));
286 case NPC_REGNUM: return(offsetof(struct ptrace_user,pt_pc0));
287 case PC_REGNUM: return(offsetof(struct ptrace_user,pt_pc1));
288 case PC2_REGNUM: return(offsetof(struct ptrace_user,pt_pc2));
289 case IPC_REGNUM: return(offsetof(struct ptrace_user,pt_ipc));
290 case IPA_REGNUM: return(offsetof(struct ptrace_user,pt_ipa));
291 case IPB_REGNUM: return(offsetof(struct ptrace_user,pt_ipb));
292 case Q_REGNUM: return(offsetof(struct ptrace_user,pt_q));
293 case BP_REGNUM: return(offsetof(struct ptrace_user,pt_bp));
294 case FC_REGNUM: return(offsetof(struct ptrace_user,pt_fc));
295 default:
296 fprintf_filtered(stderr,"register_addr():Bad register %s (%d)\n",
297 reg_names[regno],regno);
298 return(0xffffffff); /* Should make ptrace() fail */
299 }
300 }
301}
302
303
304/* Assorted operating system circumventions */
305
306#ifdef SYM1
307
308/* FIXME: Kludge this for now. It really should be system call. */
309int
310getpagesize()
311{ return(8192); }
312
313/* FIXME: Fake out the fcntl() call, which we don't have. */
314fcntl(fd, cmd, arg)
315int fd, cmd, arg;
316{
317
318 switch (cmd) {
319 case F_GETFL: return(O_RDONLY); break;
320 default:
321 printf("Ultra3's fcntl() failing, cmd = %d.\n",cmd);
322 return(-1);
323 }
324}
325
326
327/*
328 * 4.2 Signal support, requires linking with libjobs.
329 */
330static int _SigMask;
331#define sigbit(s) (1L << ((s)-1))
332
333init_SigMask()
334{
335 /* Taken from the sym1 kernel in machdep.c:startup() */
336 _SigMask = sigbit (SIGTSTP) | sigbit (SIGTTOU) | sigbit (SIGTTIN) |
337 sigbit (SIGCHLD) | sigbit (SIGTINT);
338}
339
340sigmask(signo)
341 int signo;
342{
343 return (1 << (signo-1));
344}
345
346sigsetmask(sigmask)
347unsigned int sigmask;
348{
349 int i, mask = 1;
350 int lastmask = _SigMask;
351
352 for (i=0 ; i<NSIG ; i++) {
353 if (sigmask & mask) {
354 if (!(_SigMask & mask)) {
355 sighold(i+1);
356 _SigMask |= mask;
357 }
358 } else if (_SigMask & mask) {
359 sigrelse(i+1);
360 _SigMask &= ~mask;
361 }
362 mask <<= 1;
363 }
364 return (lastmask);
365}
366
367sigblock(sigmask)
368unsigned int sigmask;
369{
370 int i, mask = 1;
371 int lastmask = _SigMask;
372
373 for (i=0 ; i<NSIG ; i++) {
374 if ((sigmask & mask) && !(_SigMask & mask)) {
375 sighold(i+1);
376 _SigMask |= mask;
377 }
378 mask <<= 1;
379 }
380 return (lastmask);
381}
382#endif /* SYM1 */
383
384
385/* Initialization code for this module. */
386
387_initialize_ultra3 ()
388{
389#ifdef SYM1
390 init_SigMask();
391#endif
392}
This page took 0.055491 seconds and 4 git commands to generate.