* config/m68k/nm-hp300bsd.h: Correctly identify 4.3BSD vs 4.4BSD.
[deliverable/binutils-gdb.git] / gdb / sparcly-nat.c
1 /* Native-dependent code for Sparc running LynxOS.
2 Copyright (C) 1989, 1992, Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "defs.h"
21 #include "inferior.h"
22 #include "target.h"
23
24 #include <signal.h>
25 #include <sys/ptrace.h>
26 #include <sys/wait.h>
27 #if 0
28 #include <machine/reg.h>
29 #endif
30
31 /* We don't store all registers immediately when requested, since they
32 get sent over in large chunks anyway. Instead, we accumulate most
33 of the changes and send them over once. "deferred_stores" keeps
34 track of which sets of registers we have locally-changed copies of,
35 so we only need send the groups that have changed. */
36
37 #define INT_REGS 1
38 #define STACK_REGS 2
39 #define FP_REGS 4
40
41 /* Fetch one or more registers from the inferior. REGNO == -1 to get
42 them all. We actually fetch more than requested, when convenient,
43 marking them as valid so we won't fetch them again. */
44
45 void
46 fetch_inferior_registers (regno)
47 int regno;
48 {
49 #if 0
50 struct regs inferior_registers;
51 struct fp_status inferior_fp_registers;
52 int i;
53
54 /* We should never be called with deferred stores, because a prerequisite
55 for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh. */
56 if (deferred_stores) abort();
57
58 DO_DEFERRED_STORES;
59
60 /* Global and Out regs are fetched directly, as well as the control
61 registers. If we're getting one of the in or local regs,
62 and the stack pointer has not yet been fetched,
63 we have to do that first, since they're found in memory relative
64 to the stack pointer. */
65 if (regno < O7_REGNUM /* including -1 */
66 || regno >= Y_REGNUM
67 || (!register_valid[SP_REGNUM] && regno < I7_REGNUM))
68 {
69 if (0 != ptrace (PTRACE_GETREGS, inferior_pid,
70 (PTRACE_ARG3_TYPE) &inferior_registers, 0))
71 perror("ptrace_getregs");
72
73 registers[REGISTER_BYTE (0)] = 0;
74 memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
75 15 * REGISTER_RAW_SIZE (G0_REGNUM));
76 *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
77 *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
78 *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
79 *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
80
81 for (i = G0_REGNUM; i <= O7_REGNUM; i++)
82 register_valid[i] = 1;
83 register_valid[Y_REGNUM] = 1;
84 register_valid[PS_REGNUM] = 1;
85 register_valid[PC_REGNUM] = 1;
86 register_valid[NPC_REGNUM] = 1;
87 /* If we don't set these valid, read_register_bytes() rereads
88 all the regs every time it is called! FIXME. */
89 register_valid[WIM_REGNUM] = 1; /* Not true yet, FIXME */
90 register_valid[TBR_REGNUM] = 1; /* Not true yet, FIXME */
91 register_valid[FPS_REGNUM] = 1; /* Not true yet, FIXME */
92 register_valid[CPS_REGNUM] = 1; /* Not true yet, FIXME */
93 }
94
95 /* Floating point registers */
96 if (regno == -1 || (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
97 {
98 if (0 != ptrace (PTRACE_GETFPREGS, inferior_pid,
99 (PTRACE_ARG3_TYPE) &inferior_fp_registers,
100 0))
101 perror("ptrace_getfpregs");
102 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
103 sizeof inferior_fp_registers.fpu_fr);
104 /* memcpy (&registers[REGISTER_BYTE (FPS_REGNUM)],
105 &inferior_fp_registers.Fpu_fsr,
106 sizeof (FPU_FSR_TYPE)); FIXME??? -- gnu@cyg */
107 for (i = FP0_REGNUM; i <= FP0_REGNUM+31; i++)
108 register_valid[i] = 1;
109 register_valid[FPS_REGNUM] = 1;
110 }
111
112 /* These regs are saved on the stack by the kernel. Only read them
113 all (16 ptrace calls!) if we really need them. */
114 if (regno == -1)
115 {
116 target_xfer_memory (*(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)],
117 &registers[REGISTER_BYTE (L0_REGNUM)],
118 16*REGISTER_RAW_SIZE (L0_REGNUM), 0);
119 for (i = L0_REGNUM; i <= I7_REGNUM; i++)
120 register_valid[i] = 1;
121 }
122 else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
123 {
124 CORE_ADDR sp = *(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)];
125 i = REGISTER_BYTE (regno);
126 if (register_valid[regno])
127 printf("register %d valid and read\n", regno);
128 target_xfer_memory (sp + i - REGISTER_BYTE (L0_REGNUM),
129 &registers[i], REGISTER_RAW_SIZE (regno), 0);
130 register_valid[regno] = 1;
131 }
132 #endif
133 }
134
135 /* Store our register values back into the inferior.
136 If REGNO is -1, do this for all registers.
137 Otherwise, REGNO specifies which register (so we can save time). */
138
139 void
140 store_inferior_registers (regno)
141 int regno;
142 {
143 #if 0
144 struct regs inferior_registers;
145 struct fp_status inferior_fp_registers;
146 int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
147
148 /* First decide which pieces of machine-state we need to modify.
149 Default for regno == -1 case is all pieces. */
150 if (regno >= 0)
151 if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32)
152 {
153 wanna_store = FP_REGS;
154 }
155 else
156 {
157 if (regno == SP_REGNUM)
158 wanna_store = INT_REGS + STACK_REGS;
159 else if (regno < L0_REGNUM || regno > I7_REGNUM)
160 wanna_store = INT_REGS;
161 else
162 wanna_store = STACK_REGS;
163 }
164
165 /* See if we're forcing the stores to happen now, or deferring. */
166 if (regno == -2)
167 {
168 wanna_store = deferred_stores;
169 deferred_stores = 0;
170 }
171 else
172 {
173 if (wanna_store == STACK_REGS)
174 {
175 /* Fall through and just store one stack reg. If we deferred
176 it, we'd have to store them all, or remember more info. */
177 }
178 else
179 {
180 deferred_stores |= wanna_store;
181 return;
182 }
183 }
184
185 if (wanna_store & STACK_REGS)
186 {
187 CORE_ADDR sp = *(CORE_ADDR *)&registers[REGISTER_BYTE (SP_REGNUM)];
188
189 if (regno < 0 || regno == SP_REGNUM)
190 {
191 if (!register_valid[L0_REGNUM+5]) abort();
192 target_xfer_memory (sp,
193 &registers[REGISTER_BYTE (L0_REGNUM)],
194 16*REGISTER_RAW_SIZE (L0_REGNUM), 1);
195 }
196 else
197 {
198 if (!register_valid[regno]) abort();
199 target_xfer_memory (sp + REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM),
200 &registers[REGISTER_BYTE (regno)],
201 REGISTER_RAW_SIZE (regno), 1);
202 }
203
204 }
205
206 if (wanna_store & INT_REGS)
207 {
208 if (!register_valid[G1_REGNUM]) abort();
209
210 memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
211 15 * REGISTER_RAW_SIZE (G1_REGNUM));
212
213 inferior_registers.r_ps =
214 *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
215 inferior_registers.r_pc =
216 *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
217 inferior_registers.r_npc =
218 *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
219 inferior_registers.r_y =
220 *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
221
222 if (0 != ptrace (PTRACE_SETREGS, inferior_pid,
223 (PTRACE_ARG3_TYPE) &inferior_registers, 0))
224 perror("ptrace_setregs");
225 }
226
227 if (wanna_store & FP_REGS)
228 {
229 if (!register_valid[FP0_REGNUM+9]) abort();
230 /* Initialize inferior_fp_registers members that gdb doesn't set
231 by reading them from the inferior. */
232 if (0 !=
233 ptrace (PTRACE_GETFPREGS, inferior_pid,
234 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0))
235 perror("ptrace_getfpregs");
236 memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
237 sizeof inferior_fp_registers.fpu_fr);
238
239 /* memcpy (&inferior_fp_registers.Fpu_fsr,
240 &registers[REGISTER_BYTE (FPS_REGNUM)], sizeof (FPU_FSR_TYPE));
241 ****/
242 if (0 !=
243 ptrace (PTRACE_SETFPREGS, inferior_pid,
244 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0))
245 perror("ptrace_setfpregs");
246 }
247 #endif
248 }
249
250
251 void
252 fetch_core_registers (core_reg_sect, core_reg_size, which, ignore)
253 char *core_reg_sect;
254 unsigned core_reg_size;
255 int which;
256 unsigned int ignore; /* reg addr, unused in this version */
257 {
258 #if 0
259 if (which == 0) {
260
261 /* Integer registers */
262
263 #define gregs ((struct regs *)core_reg_sect)
264 /* G0 *always* holds 0. */
265 *(int *)&registers[REGISTER_BYTE (0)] = 0;
266
267 /* The globals and output registers. */
268 memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1,
269 15 * REGISTER_RAW_SIZE (G1_REGNUM));
270 *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps;
271 *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc;
272 *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc;
273 *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y;
274
275 /* My best guess at where to get the locals and input
276 registers is exactly where they usually are, right above
277 the stack pointer. If the core dump was caused by a bus error
278 from blowing away the stack pointer (as is possible) then this
279 won't work, but it's worth the try. */
280 {
281 int sp;
282
283 sp = *(int *)&registers[REGISTER_BYTE (SP_REGNUM)];
284 if (0 != target_read_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
285 16 * REGISTER_RAW_SIZE (L0_REGNUM)))
286 {
287 /* fprintf so user can still use gdb */
288 fprintf (stderr,
289 "Couldn't read input and local registers from core file\n");
290 }
291 }
292 } else if (which == 2) {
293
294 /* Floating point registers */
295
296 #define fpuregs ((struct fpu *) core_reg_sect)
297 if (core_reg_size >= sizeof (struct fpu))
298 {
299 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fpuregs->fpu_regs,
300 sizeof (fpuregs->fpu_regs));
301 memcpy (&registers[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr,
302 sizeof (FPU_FSR_TYPE));
303 }
304 else
305 fprintf (stderr, "Couldn't read float regs from core file\n");
306 }
307 #endif
308 }
309
310 /* Wait for child to do something. Return pid of child, or -1 in case
311 of error; store status through argument pointer STATUS. */
312
313 int
314 child_wait (pid, status)
315 int pid;
316 int *status;
317 {
318 int save_errno;
319 int thread;
320
321 while (1)
322 {
323 int sig;
324
325 if (attach_flag)
326 set_sigint_trap(); /* Causes SIGINT to be passed on to the
327 attached process. */
328 pid = wait (status);
329 save_errno = errno;
330
331 if (attach_flag)
332 clear_sigint_trap();
333
334 if (pid == -1)
335 {
336 if (save_errno == EINTR)
337 continue;
338 fprintf (stderr, "Child process unexpectedly missing: %s.\n",
339 safe_strerror (save_errno));
340 *status = 42; /* Claim it exited with signal 42 */
341 return -1;
342 }
343
344 if (pid != PIDGET (inferior_pid)) /* Some other process?!? */
345 continue;
346
347 /* thread = WIFTID (*status);*/
348 thread = *status >> 16;
349
350 /* Initial thread value can only be acquired via wait, so we have to
351 resort to this hack. */
352
353 if (TIDGET (inferior_pid) == 0)
354 {
355 inferior_pid = BUILDPID (inferior_pid, thread);
356 add_thread (inferior_pid);
357 }
358
359 pid = BUILDPID (pid, thread);
360
361 return pid;
362 }
363 }
This page took 0.049302 seconds and 4 git commands to generate.