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