]> Git Repo - binutils.git/blob - gdb/sparcly-nat.c
* stabsread.c (define_symbol): Only combine a p/r pair into a
[binutils.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.044387 seconds and 4 git commands to generate.