Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / gdb / gdb / gdbserver / low-sparc.c
1 /* Low level interface to ptrace, for the remote server for GDB.
2    Copyright (C) 1986, 1987, 1993 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "defs.h"
21 #include <sys/wait.h>
22 #include "frame.h"
23 #include "inferior.h"
24 /***************************
25 #include "initialize.h"
26 ****************************/
27
28 #include <stdio.h>
29 #include <sys/param.h>
30 #include <sys/dir.h>
31 #include <sys/user.h>
32 #include <signal.h>
33 #include <sys/ioctl.h>
34 #include <sgtty.h>
35 #include <fcntl.h>
36
37 /***************Begin MY defs*********************/
38 int quit_flag = 0;
39 char registers[REGISTER_BYTES];
40
41 /* Index within `registers' of the first byte of the space for
42    register N.  */
43
44
45 char buf2[MAX_REGISTER_RAW_SIZE];
46 /***************End MY defs*********************/
47
48 #include <sys/ptrace.h>
49 #include <sys/reg.h>
50
51 extern int sys_nerr;
52 extern char **sys_errlist;
53 extern char **environ;
54 extern int errno;
55 extern int inferior_pid;
56 void quit (), perror_with_name ();
57 int query ();
58
59 /* Start an inferior process and returns its pid.
60    ALLARGS is a vector of program-name and args.
61    ENV is the environment vector to pass.  */
62
63 int
64 create_inferior (program, allargs)
65      char *program;
66      char **allargs;
67 {
68   int pid;
69
70   pid = fork ();
71   if (pid < 0)
72     perror_with_name ("fork");
73
74   if (pid == 0)
75     {
76       ptrace (PTRACE_TRACEME);
77
78       execv (program, allargs);
79
80       fprintf (stderr, "Cannot exec %s: %s.\n", program,
81                errno < sys_nerr ? sys_errlist[errno] : "unknown error");
82       fflush (stderr);
83       _exit (0177);
84     }
85
86   return pid;
87 }
88
89 /* Kill the inferior process.  Make us have no inferior.  */
90
91 void
92 kill_inferior ()
93 {
94   if (inferior_pid == 0)
95     return;
96   ptrace (8, inferior_pid, 0, 0);
97   wait (0);
98   /*************inferior_died ();****VK**************/
99 }
100
101 /* Return nonzero if the given thread is still alive.  */
102 int
103 mythread_alive (pid)
104      int pid;
105 {
106   return 1;
107 }
108
109 /* Wait for process, returns status */
110
111 unsigned char
112 mywait (status)
113      char *status;
114 {
115   int pid;
116   union wait w;
117
118   pid = wait (&w);
119   if (pid != inferior_pid)
120     perror_with_name ("wait");
121
122   if (WIFEXITED (w))
123     {
124       fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
125       *status = 'W';
126       return ((unsigned char) WEXITSTATUS (w));
127     }
128   else if (!WIFSTOPPED (w))
129     {
130       fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
131       *status = 'X';
132       return ((unsigned char) WTERMSIG (w));
133     }
134
135   fetch_inferior_registers (0);
136
137   *status = 'T';
138   return ((unsigned char) WSTOPSIG (w));
139 }
140
141 /* Resume execution of the inferior process.
142    If STEP is nonzero, single-step it.
143    If SIGNAL is nonzero, give it that signal.  */
144
145 void
146 myresume (step, signal)
147      int step;
148      int signal;
149 {
150   errno = 0;
151   ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
152   if (errno)
153     perror_with_name ("ptrace");
154 }
155
156 /* Fetch one or more registers from the inferior.  REGNO == -1 to get
157    them all.  We actually fetch more than requested, when convenient,
158    marking them as valid so we won't fetch them again.  */
159
160 void
161 fetch_inferior_registers (ignored)
162      int ignored;
163 {
164   struct regs inferior_registers;
165   struct fp_status inferior_fp_registers;
166   int i;
167
168   /* Global and Out regs are fetched directly, as well as the control
169      registers.  If we're getting one of the in or local regs,
170      and the stack pointer has not yet been fetched,
171      we have to do that first, since they're found in memory relative
172      to the stack pointer.  */
173
174   if (ptrace (PTRACE_GETREGS, inferior_pid,
175               (PTRACE_ARG3_TYPE) &inferior_registers, 0))
176     perror("ptrace_getregs");
177       
178   registers[REGISTER_BYTE (0)] = 0;
179   memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
180           15 * REGISTER_RAW_SIZE (G0_REGNUM));
181   *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; 
182   *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
183   *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
184   *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
185
186   /* Floating point registers */
187
188   if (ptrace (PTRACE_GETFPREGS, inferior_pid,
189               (PTRACE_ARG3_TYPE) &inferior_fp_registers,
190               0))
191     perror("ptrace_getfpregs");
192   memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
193           sizeof inferior_fp_registers.fpu_fr);
194
195   /* These regs are saved on the stack by the kernel.  Only read them
196      all (16 ptrace calls!) if we really need them.  */
197
198   read_inferior_memory (*(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)],
199                         &registers[REGISTER_BYTE (L0_REGNUM)],
200                         16*REGISTER_RAW_SIZE (L0_REGNUM));
201 }
202
203 /* Store our register values back into the inferior.
204    If REGNO is -1, do this for all registers.
205    Otherwise, REGNO specifies which register (so we can save time).  */
206
207 void
208 store_inferior_registers (ignored)
209      int ignored;
210 {
211   struct regs inferior_registers;
212   struct fp_status inferior_fp_registers;
213   CORE_ADDR sp = *(CORE_ADDR *)&registers[REGISTER_BYTE (SP_REGNUM)];
214
215   write_inferior_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
216                          16*REGISTER_RAW_SIZE (L0_REGNUM));
217
218   memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
219           15 * REGISTER_RAW_SIZE (G1_REGNUM));
220
221   inferior_registers.r_ps =
222     *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
223   inferior_registers.r_pc =
224     *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
225   inferior_registers.r_npc =
226     *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
227   inferior_registers.r_y =
228     *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
229
230   if (ptrace (PTRACE_SETREGS, inferior_pid,
231               (PTRACE_ARG3_TYPE) &inferior_registers, 0))
232     perror("ptrace_setregs");
233
234   memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
235           sizeof inferior_fp_registers.fpu_fr);
236
237   if (ptrace (PTRACE_SETFPREGS, inferior_pid,
238               (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0))
239     perror("ptrace_setfpregs");
240 }
241
242 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
243    in the NEW_SUN_PTRACE case.
244    It ought to be straightforward.  But it appears that writing did
245    not write the data that I specified.  I cannot understand where
246    it got the data that it actually did write.  */
247
248 /* Copy LEN bytes from inferior's memory starting at MEMADDR
249    to debugger memory starting at MYADDR.  */
250
251 read_inferior_memory (memaddr, myaddr, len)
252      CORE_ADDR memaddr;
253      char *myaddr;
254      int len;
255 {
256   register int i;
257   /* Round starting address down to longword boundary.  */
258   register CORE_ADDR addr = memaddr & -sizeof (int);
259   /* Round ending address up; get number of longwords that makes.  */
260   register int count
261   = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
262   /* Allocate buffer of that many longwords.  */
263   register int *buffer = (int *) alloca (count * sizeof (int));
264
265   /* Read all the longwords */
266   for (i = 0; i < count; i++, addr += sizeof (int))
267     {
268       buffer[i] = ptrace (1, inferior_pid, addr, 0);
269     }
270
271   /* Copy appropriate bytes out of the buffer.  */
272   memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
273 }
274
275 /* Copy LEN bytes of data from debugger memory at MYADDR
276    to inferior's memory at MEMADDR.
277    On failure (cannot write the inferior)
278    returns the value of errno.  */
279
280 int
281 write_inferior_memory (memaddr, myaddr, len)
282      CORE_ADDR memaddr;
283      char *myaddr;
284      int len;
285 {
286   register int i;
287   /* Round starting address down to longword boundary.  */
288   register CORE_ADDR addr = memaddr & -sizeof (int);
289   /* Round ending address up; get number of longwords that makes.  */
290   register int count
291   = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
292   /* Allocate buffer of that many longwords.  */
293   register int *buffer = (int *) alloca (count * sizeof (int));
294   extern int errno;
295
296   /* Fill start and end extra bytes of buffer with existing memory data.  */
297
298   buffer[0] = ptrace (1, inferior_pid, addr, 0);
299
300   if (count > 1)
301     {
302       buffer[count - 1]
303         = ptrace (1, inferior_pid,
304                   addr + (count - 1) * sizeof (int), 0);
305     }
306
307   /* Copy data to be written over corresponding part of buffer */
308
309   bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
310
311   /* Write the entire buffer.  */
312
313   for (i = 0; i < count; i++, addr += sizeof (int))
314     {
315       errno = 0;
316       ptrace (4, inferior_pid, addr, buffer[i]);
317       if (errno)
318         return errno;
319     }
320
321   return 0;
322 }
323 \f
324 void
325 initialize ()
326 {
327   inferior_pid = 0;
328 }
329
330 int
331 have_inferior_p ()
332 {
333   return inferior_pid != 0;
334 }