Initial import from FreeBSD RELENG_4:
[dragonfly.git] / gnu / usr.bin / binutils / gdbserver / low-fbsd.c
1 /* Low level interface to ptrace, for the remote server for GDB.
2    Copyright (C) 1995 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 <stdio.h>
26 #include <sys/param.h>
27 #include <dirent.h>
28 #include <sys/user.h>
29 #include <signal.h>
30 #include <sys/ioctl.h>
31 #include <sgtty.h>
32 #include <fcntl.h>
33 #include <string.h>
34
35 /***************Begin MY defs*********************/
36 int quit_flag = 0;
37 char registers[REGISTER_BYTES];
38
39 /* Index within `registers' of the first byte of the space for
40    register N.  */
41
42
43 char buf2[MAX_REGISTER_RAW_SIZE];
44 /***************End MY defs*********************/
45
46 #include <sys/ptrace.h>
47 #include <machine/reg.h>
48
49 extern char **environ;
50 extern int inferior_pid;
51 void quit (), perror_with_name ();
52 int query ();
53
54 /* Start an inferior process and returns its pid.
55    ALLARGS is a vector of program-name and args.
56    ENV is the environment vector to pass.  */
57
58 int
59 create_inferior (program, allargs)
60      char *program;
61      char **allargs;
62 {
63   int pid;
64
65   pid = fork ();
66   if (pid < 0)
67     perror_with_name ("fork");
68
69   if (pid == 0)
70     {
71       ptrace (PT_TRACE_ME, 0, 0, 0);
72
73       execv (program, allargs);
74
75       fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror(errno));
76       fflush (stderr);
77       _exit (0177);
78     }
79
80   return pid;
81 }
82
83 /* Kill the inferior process.  Make us have no inferior.  */
84
85 void
86 kill_inferior ()
87 {
88   if (inferior_pid == 0)
89     return;
90   ptrace (PT_KILL, inferior_pid, 0, 0);
91   wait (0);
92   /*************inferior_died ();****VK**************/
93 }
94
95 /* Return nonzero if the given thread is still alive.  */
96 int
97 mythread_alive (pid)
98      int pid;
99 {
100   return 1;
101 }
102
103 /* Wait for process, returns status */
104
105 unsigned char
106 mywait (status)
107      char *status;
108 {
109   int pid;
110   int w;
111
112   pid = wait (&w);
113   if (pid != inferior_pid)
114     perror_with_name ("wait");
115
116   if (WIFEXITED (w))
117     {
118       fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
119       *status = 'W';
120       return ((unsigned char) WEXITSTATUS (w));
121     }
122   else if (!WIFSTOPPED (w))
123     {
124       fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
125       *status = 'X';
126       return ((unsigned char) WTERMSIG (w));
127     }
128
129   fetch_inferior_registers (0);
130
131   *status = 'T';
132   return ((unsigned char) WSTOPSIG (w));
133 }
134
135 /* Resume execution of the inferior process.
136    If STEP is nonzero, single-step it.
137    If SIGNAL is nonzero, give it that signal.  */
138
139 void
140 myresume (step, signal)
141      int step;
142      int signal;
143 {
144   errno = 0;
145   ptrace (step ? PT_STEP : PT_CONTINUE, inferior_pid,
146           (PTRACE_ARG3_TYPE) 1, signal);
147   if (errno)
148     perror_with_name ("ptrace");
149 }
150
151 #if defined(__i386__)
152
153 /* this table must line up with REGISTER_NAMES in tm-i386v.h */
154 /* symbols like 'tEAX' come from <machine/reg.h> */
155 static int tregmap[] =
156 {
157   tEAX, tECX, tEDX, tEBX,
158   tESP, tEBP, tESI, tEDI,
159   tEIP, tEFLAGS, tCS, tSS,
160   tDS, tES, tFS, tGS,
161 };
162
163 static struct save87 pcb_savefpu;
164
165 void
166 fetch_inferior_registers (regno)
167      int regno;
168 {
169   struct reg inferior_registers;        /* ptrace order, not gcc/gdb order */
170   int r;
171
172   ptrace (PT_GETREGS, inferior_pid,
173           (PTRACE_ARG3_TYPE) &inferior_registers, 0);
174
175   for (r = 0; r < NUM_REGS; r++)
176     memcpy (&registers[REGISTER_BYTE (r)], ((int *)&inferior_registers) + tregmap[r], 4);
177 }
178
179 void
180 store_inferior_registers (regno)
181      int regno;
182 {
183   struct reg inferior_registers;        /* ptrace order, not gcc/gdb order */
184   int r;
185
186   ptrace (PT_GETREGS, inferior_pid,
187           (PTRACE_ARG3_TYPE) &inferior_registers, 0);
188
189   for (r = 0; r < NUM_REGS; r++)
190     memcpy (((int *)&inferior_registers) + tregmap[r], &registers[REGISTER_BYTE (r)], 4);
191
192   ptrace (PT_SETREGS, inferior_pid,
193           (PTRACE_ARG3_TYPE) &inferior_registers, 0);
194 }
195
196 #elif defined(__alpha__)
197
198 void
199 fetch_inferior_registers (regno)
200      int regno;
201 {
202   struct reg regs;      /* ptrace order, not gcc/gdb order */
203   struct fpreg fpregs;
204   int r;
205
206   ptrace (PT_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &regs, 0);
207   ptrace (PT_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fpregs, 0);
208
209   for (r = 0; r < 31; r++)
210     memcpy (&registers[REGISTER_BYTE (r)],
211             &regs.r_regs[r], sizeof(u_int64_t));
212   for (r = 0; r < 32; r++)
213     memcpy (&registers[REGISTER_BYTE (r + FP0_REGNUM)],
214             &fpregs.fpr_regs[r], sizeof(u_int64_t));
215   memcpy (&registers[REGISTER_BYTE (PC_REGNUM)],
216           &regs.r_regs[31], sizeof(u_int64_t));
217
218   memset (&registers[REGISTER_BYTE (ZERO_REGNUM)], 0, sizeof(u_int64_t));
219   memset (&registers[REGISTER_BYTE (FP_REGNUM)], 0, sizeof(u_int64_t));
220 }
221
222 void
223 store_inferior_registers (regno)
224      int regno;
225 {
226   struct reg regs;      /* ptrace order, not gcc/gdb order */
227   struct fpreg fpregs;
228   int r;
229
230   for (r = 0; r < 31; r++)
231     memcpy (&regs.r_regs[r],
232             &registers[REGISTER_BYTE (r)], sizeof(u_int64_t));
233   for (r = 0; r < 32; r++)
234     memcpy (&fpregs.fpr_regs[r],
235             &registers[REGISTER_BYTE (r + FP0_REGNUM)], sizeof(u_int64_t));
236   memcpy (&regs.r_regs[31],
237           &registers[REGISTER_BYTE (PC_REGNUM)], sizeof(u_int64_t));
238
239   ptrace (PT_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &regs, 0);
240   ptrace (PT_SETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fpregs, 0);
241 }
242
243 #endif
244
245
246 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
247    in the NEW_SUN_PTRACE case.
248    It ought to be straightforward.  But it appears that writing did
249    not write the data that I specified.  I cannot understand where
250    it got the data that it actually did write.  */
251
252 /* Copy LEN bytes from inferior's memory starting at MEMADDR
253    to debugger memory starting at MYADDR.  */
254
255 read_inferior_memory (memaddr, myaddr, len)
256      CORE_ADDR memaddr;
257      char *myaddr;
258      int len;
259 {
260   register int i;
261   /* Round starting address down to longword boundary.  */
262   register CORE_ADDR addr = memaddr & -sizeof (int);
263   /* Round ending address up; get number of longwords that makes.  */
264   register int count
265   = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
266   /* Allocate buffer of that many longwords.  */
267   register int *buffer = (int *) alloca (count * sizeof (int));
268
269   /* Read all the longwords */
270   for (i = 0; i < count; i++, addr += sizeof (int))
271     {
272       buffer[i] = ptrace (PT_READ_I, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
273     }
274
275   /* Copy appropriate bytes out of the buffer.  */
276   memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
277 }
278
279 /* Copy LEN bytes of data from debugger memory at MYADDR
280    to inferior's memory at MEMADDR.
281    On failure (cannot write the inferior)
282    returns the value of errno.  */
283
284 int
285 write_inferior_memory (memaddr, myaddr, len)
286      CORE_ADDR memaddr;
287      char *myaddr;
288      int len;
289 {
290   register int i;
291   /* Round starting address down to longword boundary.  */
292   register CORE_ADDR addr = memaddr & -sizeof (int);
293   /* Round ending address up; get number of longwords that makes.  */
294   register int count
295   = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
296   /* Allocate buffer of that many longwords.  */
297   register int *buffer = (int *) alloca (count * sizeof (int));
298   extern int errno;
299
300   /* Fill start and end extra bytes of buffer with existing memory data.  */
301
302   buffer[0] = ptrace (PT_READ_I, inferior_pid,
303                       (PTRACE_ARG3_TYPE) addr, 0);
304
305   if (count > 1)
306     {
307       buffer[count - 1]
308         = ptrace (PT_READ_I, inferior_pid,
309                   (PTRACE_ARG3_TYPE) addr + (count - 1) * sizeof (int), 0);
310     }
311
312   /* Copy data to be written over corresponding part of buffer */
313
314   memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
315
316   /* Write the entire buffer.  */
317
318   for (i = 0; i < count; i++, addr += sizeof (int))
319     {
320       errno = 0;
321       ptrace (PT_WRITE_I, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
322       if (errno)
323         return errno;
324     }
325
326   return 0;
327 }
328 \f
329 void
330 initialize ()
331 {
332   inferior_pid = 0;
333 }
334
335 int
336 have_inferior_p ()
337 {
338   return inferior_pid != 0;
339 }