This commit was generated by cvs2svn to track changes on a CVS vendor
[deliverable/binutils-gdb.git] / gdb / gdbserver / low-nbsd.c
CommitLineData
d6e9fb05
JK
1/* Low level interface to ptrace, for the remote server for GDB.
2 Copyright (C) 1986, 1987, 1993, 2000 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20#include "defs.h"
21#include <sys/types.h>
22#include <sys/wait.h>
23#include "frame.h"
24#include "inferior.h"
25
26#include <stdio.h>
27#include <errno.h>
28
29/***************Begin MY defs*********************/
30int quit_flag = 0;
31static char my_registers[REGISTER_BYTES];
32char *registers = my_registers;
33
34/* Index within `registers' of the first byte of the space for
35 register N. */
36
37char buf2[MAX_REGISTER_RAW_SIZE];
38/***************End MY defs*********************/
39
40#include <sys/ptrace.h>
41#include <machine/reg.h>
42
43extern int sys_nerr;
44// extern char **sys_errlist;
45extern char **environ;
46extern int inferior_pid;
47void quit (), perror_with_name ();
48
49#ifdef TM_I386_H
50/* i386_register_raw_size[i] is the number of bytes of storage in the
51 actual machine representation for register i. */
52int i386_register_raw_size[MAX_NUM_REGS] = {
53 4, 4, 4, 4,
54 4, 4, 4, 4,
55 4, 4, 4, 4,
56 4, 4, 4, 4,
57 10, 10, 10, 10,
58 10, 10, 10, 10,
59 4, 4, 4, 4,
60 4, 4, 4, 4,
61 16, 16, 16, 16,
62 16, 16, 16, 16,
63 4
64};
65
66int i386_register_byte[MAX_NUM_REGS];
67
68static void
69initialize_arch()
70{
71 /* Initialize the table saying where each register starts in the
72 register file. */
73 {
74 int i, offset;
75
76 offset = 0;
77 for (i = 0; i < MAX_NUM_REGS; i++)
78 {
79 i386_register_byte[i] = offset;
80 offset += i386_register_raw_size[i];
81 }
82 }
83}
84
85#endif
86
87
88/* Start an inferior process and returns its pid.
89 ALLARGS is a vector of program-name and args.
90 ENV is the environment vector to pass. */
91
92int
93create_inferior (program, allargs)
94 char *program;
95 char **allargs;
96{
97 int pid;
98
99 pid = fork ();
100 if (pid < 0)
101 perror_with_name ("fork");
102
103 if (pid == 0)
104 {
105 ptrace (PT_TRACE_ME, 0, 0, 0);
106
107 execv (program, allargs);
108
109 fprintf (stderr, "Cannot exec %s: %s.\n", program,
110 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
111 fflush (stderr);
112 _exit (0177);
113 }
114
115 return pid;
116}
117
118/* Kill the inferior process. Make us have no inferior. */
119
120void
121kill_inferior ()
122{
123 if (inferior_pid == 0)
124 return;
125 ptrace (PT_KILL, inferior_pid, 0, 0);
126 wait (0);
127 /*************inferior_died ();****VK**************/
128}
129
130/* Return nonzero if the given thread is still alive. */
131int
132mythread_alive (pid)
133 int pid;
134{
135 return 1;
136}
137
138/* Wait for process, returns status */
139
140unsigned char
141mywait (status)
142 char *status;
143{
144 int pid;
145 int w;
146
147 pid = wait (&w);
148 if (pid != inferior_pid)
149 perror_with_name ("wait");
150
151 if (WIFEXITED (w))
152 {
153 fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
154 *status = 'W';
155 return ((unsigned char) WEXITSTATUS (w));
156 }
157 else if (!WIFSTOPPED (w))
158 {
159 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
160 *status = 'X';
161 return ((unsigned char) WTERMSIG (w));
162 }
163
164 fetch_inferior_registers (0);
165
166 *status = 'T';
167 return ((unsigned char) WSTOPSIG (w));
168}
169
170/* Resume execution of the inferior process.
171 If STEP is nonzero, single-step it.
172 If SIGNAL is nonzero, give it that signal. */
173
174void
175myresume (step, signal)
176 int step;
177 int signal;
178{
179 errno = 0;
180 ptrace (step ? PT_STEP : PT_CONTINUE, inferior_pid,
181 (PTRACE_ARG3_TYPE) 1, signal);
182 if (errno)
183 perror_with_name ("ptrace");
184}
185
186/* Fetch one or more registers from the inferior. REGNO == -1 to get
187 them all. We actually fetch more than requested, when convenient,
188 marking them as valid so we won't fetch them again. */
189
190void
191fetch_inferior_registers (ignored)
192 int ignored;
193{
194 struct reg inferior_registers;
195 struct fpreg inferior_fp_registers;
196
197 ptrace (PT_GETREGS, inferior_pid,
198 (PTRACE_ARG3_TYPE) &inferior_registers, 0);
199 memcpy (&registers[REGISTER_BYTE(0)], &inferior_registers,
200 sizeof(inferior_registers));
201
202#if 0 /* def FP0_REGNUM */
203 ptrace (PT_GETFPREGS, inferior_pid,
204 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
205 memcpy (&registers[REGISTER_BYTE(FP0_REGNUM)], &inferior_fp_registers,
206 sizeof(inferior_fp_registers));
207#endif
208}
209
210/* Store our register values back into the inferior.
211 If REGNO is -1, do this for all registers.
212 Otherwise, REGNO specifies which register (so we can save time). */
213
214void
215store_inferior_registers (ignored)
216 int ignored;
217{
218 struct reg inferior_registers;
219 struct fpreg inferior_fp_registers;
220
221 memcpy (&inferior_registers, &registers[REGISTER_BYTE(0)],
222 sizeof(inferior_registers));
223 ptrace (PT_SETREGS, inferior_pid,
224 (PTRACE_ARG3_TYPE) &inferior_registers, 0);
225
226#if 0 /* def FP0_REGNUM */
227 memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
228 sizeof (inferior_fp_registers));
229 ptrace (PT_SETFPREGS, inferior_pid,
230 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
231#endif
232}
233
234/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
235 in the NEW_SUN_PTRACE case.
236 It ought to be straightforward. But it appears that writing did
237 not write the data that I specified. I cannot understand where
238 it got the data that it actually did write. */
239
240/* Copy LEN bytes from inferior's memory starting at MEMADDR
241 to debugger memory starting at MYADDR. */
242
243read_inferior_memory (memaddr, myaddr, len)
244 CORE_ADDR memaddr;
245 char *myaddr;
246 int len;
247{
248 register int i;
249 /* Round starting address down to longword boundary. */
250 register CORE_ADDR addr = memaddr & -sizeof (int);
251 /* Round ending address up; get number of longwords that makes. */
252 register int count
253 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
254 /* Allocate buffer of that many longwords. */
255 register int *buffer = (int *) alloca (count * sizeof (int));
256
257 /* Read all the longwords */
258 for (i = 0; i < count; i++, addr += sizeof (int))
259 {
260 buffer[i] = ptrace (PT_READ_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
261 }
262
263 /* Copy appropriate bytes out of the buffer. */
264 memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
265}
266
267/* Copy LEN bytes of data from debugger memory at MYADDR
268 to inferior's memory at MEMADDR.
269 On failure (cannot write the inferior)
270 returns the value of errno. */
271
272int
273write_inferior_memory (memaddr, myaddr, len)
274 CORE_ADDR memaddr;
275 char *myaddr;
276 int len;
277{
278 register int i;
279 /* Round starting address down to longword boundary. */
280 register CORE_ADDR addr = memaddr & -sizeof (int);
281 /* Round ending address up; get number of longwords that makes. */
282 register int count
283 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
284 /* Allocate buffer of that many longwords. */
285 register int *buffer = (int *) alloca (count * sizeof (int));
286 extern int errno;
287
288 /* Fill start and end extra bytes of buffer with existing memory data. */
289
290 buffer[0] = ptrace (PT_READ_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
291
292 if (count > 1)
293 {
294 buffer[count - 1]
295 = ptrace (PT_READ_D, inferior_pid,
296 (PTRACE_ARG3_TYPE) addr + (count - 1) * sizeof (int), 0);
297 }
298
299 /* Copy data to be written over corresponding part of buffer */
300
301 memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
302
303 /* Write the entire buffer. */
304
305 for (i = 0; i < count; i++, addr += sizeof (int))
306 {
307 errno = 0;
308 ptrace (PT_WRITE_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
309 if (errno)
310 return errno;
311 }
312
313 return 0;
314}
315\f
316void
317initialize_low ()
318{
319 initialize_arch ();
320}
This page took 0.034152 seconds and 4 git commands to generate.