]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/ultra3-nat.c
Update FSF address.
[thirdparty/binutils-gdb.git] / gdb / ultra3-nat.c
1 /* Native-dependent code for GDB, for NYU Ultra3 running Sym1 OS.
2 Copyright (C) 1988, 1989, 1991, 1992 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "gdb_stat.h"
38
39 /* Assumes support for AMD's Binary Compatibility Standard
40 for ptrace(). If you define ULTRA3, the ultra3 extensions to
41 ptrace() are used allowing the reading of more than one register
42 at a time.
43
44 This file assumes KERNEL_DEBUGGING is turned off. This means
45 that if the user/gdb tries to read gr64-gr95 or any of the
46 protected special registers we silently return -1 (see the
47 CANNOT_STORE/FETCH_REGISTER macros). */
48 #define ULTRA3
49
50 #if !defined (offsetof)
51 # define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
52 #endif
53
54 extern int errno;
55 struct ptrace_user pt_struct;
56
57 /* Get all available registers from the inferior. Registers that are
58 * defined in REGISTER_NAMES, but not available to the user/gdb are
59 * supplied as -1. This may include gr64-gr95 and the protected special
60 * purpose registers.
61 */
62
63 void
64 fetch_inferior_registers (regno)
65 int regno;
66 {
67 register int i,j,ret_val=0;
68 char buf[128];
69
70 if (regno != -1) {
71 fetch_register (regno);
72 return;
73 }
74
75 /* Global Registers */
76 #ifdef ULTRA3
77 errno = 0;
78 ptrace (PT_READ_STRUCT, inferior_pid,
79 (PTRACE_ARG3_TYPE) register_addr(GR96_REGNUM,0),
80 (int)&pt_struct.pt_gr[0], 32*4);
81 if (errno != 0) {
82 perror_with_name ("reading global registers");
83 ret_val = -1;
84 } else for (regno=GR96_REGNUM, j=0 ; j<32 ; regno++, j++) {
85 supply_register (regno, &pt_struct.pt_gr[j]);
86 }
87 #else
88 for (regno=GR96_REGNUM ; !ret_val && regno < GR96_REGNUM+32 ; regno++)
89 fetch_register(regno);
90 #endif
91
92 /* Local Registers */
93 #ifdef ULTRA3
94 errno = 0;
95 ptrace (PT_READ_STRUCT, inferior_pid,
96 (PTRACE_ARG3_TYPE) register_addr(LR0_REGNUM,0),
97 (int)&pt_struct.pt_lr[0], 128*4);
98 if (errno != 0) {
99 perror_with_name ("reading local registers");
100 ret_val = -1;
101 } else for (regno=LR0_REGNUM, j=0 ; j<128 ; regno++, j++) {
102 supply_register (regno, &pt_struct.pt_lr[j]);
103 }
104 #else
105 for (regno=LR0_REGNUM ; !ret_val && regno < LR0_REGNUM+128 ; regno++)
106 fetch_register(regno);
107 #endif
108
109 /* Special Registers */
110 fetch_register(GR1_REGNUM);
111 fetch_register(CPS_REGNUM);
112 fetch_register(PC_REGNUM);
113 fetch_register(NPC_REGNUM);
114 fetch_register(PC2_REGNUM);
115 fetch_register(IPC_REGNUM);
116 fetch_register(IPA_REGNUM);
117 fetch_register(IPB_REGNUM);
118 fetch_register(Q_REGNUM);
119 fetch_register(BP_REGNUM);
120 fetch_register(FC_REGNUM);
121
122 /* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
123 registers_fetched();
124 }
125
126 /* Store our register values back into the inferior.
127 * If REGNO is -1, do this for all registers.
128 * Otherwise, REGNO specifies which register (so we can save time).
129 * NOTE: Assumes AMD's binary compatibility standard.
130 */
131
132 void
133 store_inferior_registers (regno)
134 int regno;
135 {
136 register unsigned int regaddr;
137 char buf[80];
138
139 if (regno >= 0)
140 {
141 if (CANNOT_STORE_REGISTER(regno))
142 return;
143 regaddr = register_addr (regno, 0);
144 errno = 0;
145 ptrace (PT_WRITE_U, inferior_pid,
146 (PTRACE_ARG3_TYPE) regaddr, read_register(regno));
147 if (errno != 0)
148 {
149 sprintf (buf, "writing register %s (#%d)", reg_names[regno],regno);
150 perror_with_name (buf);
151 }
152 }
153 else
154 {
155 #ifdef ULTRA3
156 pt_struct.pt_gr1 = read_register(GR1_REGNUM);
157 for (regno = GR96_REGNUM; regno < GR96_REGNUM+32; regno++)
158 pt_struct.pt_gr[regno] = read_register(regno);
159 for (regno = LR0_REGNUM; regno < LR0_REGNUM+128; regno++)
160 pt_struct.pt_gr[regno] = read_register(regno);
161 errno = 0;
162 ptrace (PT_WRITE_STRUCT, inferior_pid,
163 (PTRACE_ARG3_TYPE) register_addr(GR1_REGNUM,0),
164 (int)&pt_struct.pt_gr1,(1*32*128)*4);
165 if (errno != 0)
166 {
167 sprintf (buf, "writing all local/global registers");
168 perror_with_name (buf);
169 }
170 pt_struct.pt_psr = read_register(CPS_REGNUM);
171 pt_struct.pt_pc0 = read_register(NPC_REGNUM);
172 pt_struct.pt_pc1 = read_register(PC_REGNUM);
173 pt_struct.pt_pc2 = read_register(PC2_REGNUM);
174 pt_struct.pt_ipc = read_register(IPC_REGNUM);
175 pt_struct.pt_ipa = read_register(IPA_REGNUM);
176 pt_struct.pt_ipb = read_register(IPB_REGNUM);
177 pt_struct.pt_q = read_register(Q_REGNUM);
178 pt_struct.pt_bp = read_register(BP_REGNUM);
179 pt_struct.pt_fc = read_register(FC_REGNUM);
180 errno = 0;
181 ptrace (PT_WRITE_STRUCT, inferior_pid,
182 (PTRACE_ARG3_TYPE) register_addr(CPS_REGNUM,0),
183 (int)&pt_struct.pt_psr,(10)*4);
184 if (errno != 0)
185 {
186 sprintf (buf, "writing all special registers");
187 perror_with_name (buf);
188 return;
189 }
190 #else
191 store_inferior_registers(GR1_REGNUM);
192 for (regno=GR96_REGNUM ; regno<GR96_REGNUM+32 ; regno++)
193 store_inferior_registers(regno);
194 for (regno=LR0_REGNUM ; regno<LR0_REGNUM+128 ; regno++)
195 store_inferior_registers(regno);
196 store_inferior_registers(CPS_REGNUM);
197 store_inferior_registers(PC_REGNUM);
198 store_inferior_registers(NPC_REGNUM);
199 store_inferior_registers(PC2_REGNUM);
200 store_inferior_registers(IPC_REGNUM);
201 store_inferior_registers(IPA_REGNUM);
202 store_inferior_registers(IPB_REGNUM);
203 store_inferior_registers(Q_REGNUM);
204 store_inferior_registers(BP_REGNUM);
205 store_inferior_registers(FC_REGNUM);
206 #endif /* ULTRA3 */
207 }
208 }
209
210 /*
211 * Fetch an individual register (and supply it).
212 * return 0 on success, -1 on failure.
213 * NOTE: Assumes AMD's Binary Compatibility Standard for ptrace().
214 */
215 static void
216 fetch_register (regno)
217 int regno;
218 {
219 char buf[128];
220 int val;
221
222 if (CANNOT_FETCH_REGISTER(regno)) {
223 val = -1;
224 supply_register (regno, &val);
225 } else {
226 errno = 0;
227 val = ptrace (PT_READ_U, inferior_pid,
228 (PTRACE_ARG3_TYPE) register_addr(regno,0), 0);
229 if (errno != 0) {
230 sprintf(buf,"reading register %s (#%d)",reg_names[regno],regno);
231 perror_with_name (buf);
232 } else {
233 supply_register (regno, &val);
234 }
235 }
236 }
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 */
243
244 void
245 fetch_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, (file_ptr) register_addr (regno, 0), L_SET);
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 */
278 unsigned int
279 register_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(gdb_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