]> Git Repo - binutils.git/blob - gdb/ultra3-xdep.c
Fix demangling of destructors, and fix a minor indentation problem.
[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 "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
56 extern int errno;
57 struct 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  */
64 static void
65 fetch_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
92 void
93 fetch_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
159 int
160 store_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)) 
169         return 0;                       /*  Pretend success */
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);
212            return -1;
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     }
232   return 0;
233 }
234
235 /* 
236  * Read AMD's Binary Compatibilty Standard conforming core file.
237  * struct ptrace_user is the first thing in the core file
238  */
239 void
240 fetch_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  */
273 unsigned int 
274 register_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. */
309 int
310 getpagesize()
311 { return(8192); }
312
313 /* FIXME: Fake out the fcntl() call, which we don't have.  */
314 fcntl(fd, cmd, arg)
315 int 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  */
330 static int      _SigMask;
331 #define sigbit(s)       (1L << ((s)-1))
332
333 init_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
340 sigmask(signo)
341         int signo;
342 {
343         return (1 << (signo-1));
344 }
345
346 sigsetmask(sigmask)
347 unsigned 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
367 sigblock(sigmask)
368 unsigned 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.047366 seconds and 4 git commands to generate.