]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ultra3-nat.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / gdb / ultra3-nat.c
CommitLineData
2268d619 1/* Native-dependent code for GDB, for NYU Ultra3 running Sym1 OS.
6bf98ac0
RP
2 Copyright (C) 1988, 1989, 1991, 1992 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
6c9638b4 19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
6bf98ac0
RP
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>
2b576293 37#include "gdb_stat.h"
6bf98ac0 38
948a9d92
FF
39static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
40
2268d619
JG
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
6bf98ac0
RP
59/* Get all available registers from the inferior. Registers that are
60 * defined in REGISTER_NAMES, but not available to the user/gdb are
61 * supplied as -1. This may include gr64-gr95 and the protected special
62 * purpose registers.
63 */
64
65void
66fetch_inferior_registers (regno)
67 int regno;
68{
69 register int i,j,ret_val=0;
70 char buf[128];
71
72 if (regno != -1) {
73 fetch_register (regno);
74 return;
75 }
76
77/* Global Registers */
78#ifdef ULTRA3
79 errno = 0;
80 ptrace (PT_READ_STRUCT, inferior_pid,
81 (PTRACE_ARG3_TYPE) register_addr(GR96_REGNUM,0),
82 (int)&pt_struct.pt_gr[0], 32*4);
83 if (errno != 0) {
84 perror_with_name ("reading global registers");
85 ret_val = -1;
86 } else for (regno=GR96_REGNUM, j=0 ; j<32 ; regno++, j++) {
87 supply_register (regno, &pt_struct.pt_gr[j]);
88 }
89#else
90 for (regno=GR96_REGNUM ; !ret_val && regno < GR96_REGNUM+32 ; regno++)
91 fetch_register(regno);
92#endif
93
94/* Local Registers */
95#ifdef ULTRA3
96 errno = 0;
97 ptrace (PT_READ_STRUCT, inferior_pid,
98 (PTRACE_ARG3_TYPE) register_addr(LR0_REGNUM,0),
99 (int)&pt_struct.pt_lr[0], 128*4);
100 if (errno != 0) {
101 perror_with_name ("reading local registers");
102 ret_val = -1;
103 } else for (regno=LR0_REGNUM, j=0 ; j<128 ; regno++, j++) {
104 supply_register (regno, &pt_struct.pt_lr[j]);
105 }
106#else
107 for (regno=LR0_REGNUM ; !ret_val && regno < LR0_REGNUM+128 ; regno++)
108 fetch_register(regno);
109#endif
110
111/* Special Registers */
112 fetch_register(GR1_REGNUM);
113 fetch_register(CPS_REGNUM);
114 fetch_register(PC_REGNUM);
115 fetch_register(NPC_REGNUM);
116 fetch_register(PC2_REGNUM);
117 fetch_register(IPC_REGNUM);
118 fetch_register(IPA_REGNUM);
119 fetch_register(IPB_REGNUM);
120 fetch_register(Q_REGNUM);
121 fetch_register(BP_REGNUM);
122 fetch_register(FC_REGNUM);
123
124/* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
125 registers_fetched();
126}
127
128/* Store our register values back into the inferior.
129 * If REGNO is -1, do this for all registers.
130 * Otherwise, REGNO specifies which register (so we can save time).
131 * NOTE: Assumes AMD's binary compatibility standard.
132 */
133
134void
135store_inferior_registers (regno)
136 int regno;
137{
138 register unsigned int regaddr;
139 char buf[80];
140
141 if (regno >= 0)
142 {
143 if (CANNOT_STORE_REGISTER(regno))
144 return;
145 regaddr = register_addr (regno, 0);
146 errno = 0;
147 ptrace (PT_WRITE_U, inferior_pid,
148 (PTRACE_ARG3_TYPE) regaddr, read_register(regno));
149 if (errno != 0)
150 {
d70a61e7 151 sprintf (buf, "writing register %s (#%d)", REGISTER_NAME (regno), regno);
6bf98ac0
RP
152 perror_with_name (buf);
153 }
154 }
155 else
156 {
157#ifdef ULTRA3
158 pt_struct.pt_gr1 = read_register(GR1_REGNUM);
159 for (regno = GR96_REGNUM; regno < GR96_REGNUM+32; regno++)
160 pt_struct.pt_gr[regno] = read_register(regno);
161 for (regno = LR0_REGNUM; regno < LR0_REGNUM+128; regno++)
162 pt_struct.pt_gr[regno] = read_register(regno);
163 errno = 0;
164 ptrace (PT_WRITE_STRUCT, inferior_pid,
165 (PTRACE_ARG3_TYPE) register_addr(GR1_REGNUM,0),
166 (int)&pt_struct.pt_gr1,(1*32*128)*4);
167 if (errno != 0)
168 {
169 sprintf (buf, "writing all local/global registers");
170 perror_with_name (buf);
171 }
172 pt_struct.pt_psr = read_register(CPS_REGNUM);
173 pt_struct.pt_pc0 = read_register(NPC_REGNUM);
174 pt_struct.pt_pc1 = read_register(PC_REGNUM);
175 pt_struct.pt_pc2 = read_register(PC2_REGNUM);
176 pt_struct.pt_ipc = read_register(IPC_REGNUM);
177 pt_struct.pt_ipa = read_register(IPA_REGNUM);
178 pt_struct.pt_ipb = read_register(IPB_REGNUM);
179 pt_struct.pt_q = read_register(Q_REGNUM);
180 pt_struct.pt_bp = read_register(BP_REGNUM);
181 pt_struct.pt_fc = read_register(FC_REGNUM);
182 errno = 0;
183 ptrace (PT_WRITE_STRUCT, inferior_pid,
184 (PTRACE_ARG3_TYPE) register_addr(CPS_REGNUM,0),
185 (int)&pt_struct.pt_psr,(10)*4);
186 if (errno != 0)
187 {
188 sprintf (buf, "writing all special registers");
189 perror_with_name (buf);
190 return;
191 }
192#else
193 store_inferior_registers(GR1_REGNUM);
194 for (regno=GR96_REGNUM ; regno<GR96_REGNUM+32 ; regno++)
195 store_inferior_registers(regno);
196 for (regno=LR0_REGNUM ; regno<LR0_REGNUM+128 ; regno++)
197 store_inferior_registers(regno);
198 store_inferior_registers(CPS_REGNUM);
199 store_inferior_registers(PC_REGNUM);
200 store_inferior_registers(NPC_REGNUM);
201 store_inferior_registers(PC2_REGNUM);
202 store_inferior_registers(IPC_REGNUM);
203 store_inferior_registers(IPA_REGNUM);
204 store_inferior_registers(IPB_REGNUM);
205 store_inferior_registers(Q_REGNUM);
206 store_inferior_registers(BP_REGNUM);
207 store_inferior_registers(FC_REGNUM);
208#endif /* ULTRA3 */
209 }
210}
211
212/*
213 * Fetch an individual register (and supply it).
214 * return 0 on success, -1 on failure.
215 * NOTE: Assumes AMD's Binary Compatibility Standard for ptrace().
216 */
217static void
218fetch_register (regno)
219 int regno;
220{
221 char buf[128];
222 int val;
223
224 if (CANNOT_FETCH_REGISTER(regno)) {
225 val = -1;
226 supply_register (regno, &val);
227 } else {
228 errno = 0;
229 val = ptrace (PT_READ_U, inferior_pid,
230 (PTRACE_ARG3_TYPE) register_addr(regno,0), 0);
231 if (errno != 0) {
d70a61e7 232 sprintf(buf,"reading register %s (#%d)",REGISTER_NAME (regno), regno);
6bf98ac0
RP
233 perror_with_name (buf);
234 } else {
235 supply_register (regno, &val);
236 }
237 }
238}
239
240
241/*
242 * Read AMD's Binary Compatibilty Standard conforming core file.
243 * struct ptrace_user is the first thing in the core file
244 */
245
a1df8e78 246static void
948a9d92
FF
247fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
248 char *core_reg_sect; /* Unused in this version */
249 unsigned core_reg_size; /* Unused in this version */
250 int which; /* Unused in this version */
251 CORE_ADDR reg_addr; /* Unused in this version */
6bf98ac0
RP
252{
253 register int regno;
254 int val;
255 char buf[4];
256
257 for (regno = 0 ; regno < NUM_REGS; regno++) {
258 if (!CANNOT_FETCH_REGISTER(regno)) {
987622b5 259 val = bfd_seek (core_bfd, (file_ptr) register_addr (regno, 0), SEEK_SET);
6bf98ac0 260 if (val < 0 || (val = bfd_read (buf, sizeof buf, 1, core_bfd)) < 0) {
d70a61e7 261 char * buffer = (char *) alloca (strlen (REGISTER_NAME (regno)) + 35);
6bf98ac0 262 strcpy (buffer, "Reading core register ");
d70a61e7 263 strcat (buffer, REGISTER_NAME (regno));
6bf98ac0
RP
264 perror_with_name (buffer);
265 }
266 supply_register (regno, buf);
267 }
268 }
269
270 /* Fake any registers that are in REGISTER_NAMES, but not available to gdb */
271 registers_fetched();
272}
273
274
2268d619
JG
275/*
276 * Takes a register number as defined in tm.h via REGISTER_NAMES, and maps
277 * it to an offset in a struct ptrace_user defined by AMD's BCS.
278 * That is, it defines the mapping between gdb register numbers and items in
279 * a struct ptrace_user.
280 * A register protection scheme is set up here. If a register not
281 * available to the user is specified in 'regno', then an address that
282 * will cause ptrace() to fail is returned.
283 */
948a9d92 284CORE_ADDR
2268d619 285register_addr (regno,blockend)
948a9d92
FF
286 int regno;
287 CORE_ADDR blockend;
2268d619
JG
288{
289 if ((regno >= LR0_REGNUM) && (regno < LR0_REGNUM + 128)) {
290 return(offsetof(struct ptrace_user,pt_lr[regno-LR0_REGNUM]));
291 } else if ((regno >= GR96_REGNUM) && (regno < GR96_REGNUM + 32)) {
292 return(offsetof(struct ptrace_user,pt_gr[regno-GR96_REGNUM]));
293 } else {
294 switch (regno) {
295 case GR1_REGNUM: return(offsetof(struct ptrace_user,pt_gr1));
296 case CPS_REGNUM: return(offsetof(struct ptrace_user,pt_psr));
297 case NPC_REGNUM: return(offsetof(struct ptrace_user,pt_pc0));
298 case PC_REGNUM: return(offsetof(struct ptrace_user,pt_pc1));
299 case PC2_REGNUM: return(offsetof(struct ptrace_user,pt_pc2));
300 case IPC_REGNUM: return(offsetof(struct ptrace_user,pt_ipc));
301 case IPA_REGNUM: return(offsetof(struct ptrace_user,pt_ipa));
302 case IPB_REGNUM: return(offsetof(struct ptrace_user,pt_ipb));
303 case Q_REGNUM: return(offsetof(struct ptrace_user,pt_q));
304 case BP_REGNUM: return(offsetof(struct ptrace_user,pt_bp));
305 case FC_REGNUM: return(offsetof(struct ptrace_user,pt_fc));
306 default:
199b2450 307 fprintf_filtered(gdb_stderr,"register_addr():Bad register %s (%d)\n",
d70a61e7 308 REGISTER_NAME (regno), regno);
2268d619
JG
309 return(0xffffffff); /* Should make ptrace() fail */
310 }
311 }
312}
313
a1df8e78
FF
314\f
315/* Register that we are able to handle ultra3 core file formats.
316 FIXME: is this really bfd_target_unknown_flavour? */
317
318static struct core_fns ultra3_core_fns =
319{
320 bfd_target_unknown_flavour,
321 fetch_core_registers,
322 NULL
323};
2268d619 324
a1df8e78
FF
325void
326_initialize_core_ultra3 ()
327{
328 add_core_fns (&ultra3_core_fns);
329}