Add README.
[deliverable/binutils-gdb.git] / gdb / gdbserver / remote-inflow-sparc.c
CommitLineData
38dc5e12
SG
1/* Low level interface to ptrace, for the remote server for GDB.
2 Copyright (C) 1986, 1987, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
799d5b6a
SG
19
20#include "defs.h"
38dc5e12 21#include "/usr/include/sys/wait.h"
799d5b6a
SG
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*********************/
38int quit_flag = 0;
39char registers[REGISTER_BYTES];
40
41/* Index within `registers' of the first byte of the space for
42 register N. */
43
44
45char buf2[MAX_REGISTER_RAW_SIZE];
46/***************End MY defs*********************/
47
48#include <sys/ptrace.h>
49#include <machine/reg.h>
50
51extern char **environ;
52extern int errno;
53extern int inferior_pid;
54void error (), quit (), perror_with_name ();
55int query ();
799d5b6a
SG
56
57/* Start an inferior process and returns its pid.
58 ALLARGS is a vector of program-name and args.
59 ENV is the environment vector to pass. */
60
61int
62create_inferior (allargs, env)
63 char **allargs;
64 char **env;
65{
66 int pid;
67 extern int sys_nerr;
68 extern char *sys_errlist[];
69 extern int errno;
70 char status;
71 char execbuf[1024];
72
73 /* exec is said to fail if the executable is open. */
74 /****************close_exec_file ();*****************/
75
76 sprintf (execbuf, "exec %s", allargs);
77
78 pid = vfork ();
79 if (pid < 0)
80 perror_with_name ("vfork");
81
82 if (pid == 0)
83 {
84 /* Run inferior in a separate process group. */
85 setpgrp (getpid (), getpid ());
86
87 errno = 0;
88 ptrace (PTRACE_TRACEME);
89
90 execle ("/bin/sh", "sh", "-c", execbuf, 0, env);
91
92 fprintf (stderr, "Cannot exec /bin/sh: %s.\n",
93 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
94 fflush (stderr);
95 _exit (0177);
96 }
97
98 return pid;
99}
100
101/* Kill the inferior process. Make us have no inferior. */
102
103void
104kill_inferior ()
105{
106 if (inferior_pid == 0)
107 return;
108 ptrace (8, inferior_pid, 0, 0);
109 wait (0);
110 /*************inferior_died ();****VK**************/
111}
112
38dc5e12 113/* Wait for process, returns status */
799d5b6a
SG
114
115unsigned char
38dc5e12 116mywait (status)
799d5b6a
SG
117 char *status;
118{
119 int pid;
38dc5e12 120 union wait w;
799d5b6a 121
799d5b6a
SG
122 pid = wait (&w);
123 if (pid != inferior_pid)
124 perror_with_name ("wait");
125
799d5b6a
SG
126 if (WIFEXITED (w))
127 {
38dc5e12 128 fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
799d5b6a
SG
129 *status = 'E';
130 return ((unsigned char) WEXITSTATUS (w));
131 }
132 else if (!WIFSTOPPED (w))
133 {
38dc5e12 134 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
799d5b6a
SG
135 *status = 'T';
136 return ((unsigned char) WTERMSIG (w));
137 }
38dc5e12
SG
138
139 fetch_inferior_registers (0);
140
141 *status = 'S';
142 return ((unsigned char) WSTOPSIG (w));
799d5b6a
SG
143}
144
38dc5e12
SG
145/* Resume execution of the inferior process.
146 If STEP is nonzero, single-step it.
147 If SIGNAL is nonzero, give it that signal. */
148
149void
150myresume (step, signal)
151 int step;
152 int signal;
153{
154 errno = 0;
155 ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
156 if (errno)
157 perror_with_name ("ptrace");
158}
799d5b6a
SG
159
160/* Fetch one or more registers from the inferior. REGNO == -1 to get
161 them all. We actually fetch more than requested, when convenient,
162 marking them as valid so we won't fetch them again. */
163
164void
165fetch_inferior_registers (ignored)
166 int ignored;
167{
168 struct regs inferior_registers;
169 struct fp_status inferior_fp_registers;
170 int i;
171
172 /* Global and Out regs are fetched directly, as well as the control
173 registers. If we're getting one of the in or local regs,
174 and the stack pointer has not yet been fetched,
175 we have to do that first, since they're found in memory relative
176 to the stack pointer. */
177
178 if (ptrace (PTRACE_GETREGS, inferior_pid,
179 (PTRACE_ARG3_TYPE) &inferior_registers, 0))
180 perror("ptrace_getregs");
181
182 registers[REGISTER_BYTE (0)] = 0;
183 memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
184 15 * REGISTER_RAW_SIZE (G0_REGNUM));
185 *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
186 *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
187 *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
188 *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
189
190 /* Floating point registers */
191
192 if (ptrace (PTRACE_GETFPREGS, inferior_pid,
193 (PTRACE_ARG3_TYPE) &inferior_fp_registers,
194 0))
195 perror("ptrace_getfpregs");
196 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
197 sizeof inferior_fp_registers.fpu_fr);
198
199 /* These regs are saved on the stack by the kernel. Only read them
200 all (16 ptrace calls!) if we really need them. */
201
202 read_inferior_memory (*(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)],
203 &registers[REGISTER_BYTE (L0_REGNUM)],
204 16*REGISTER_RAW_SIZE (L0_REGNUM));
205}
206
207/* Store our register values back into the inferior.
208 If REGNO is -1, do this for all registers.
209 Otherwise, REGNO specifies which register (so we can save time). */
210
211void
212store_inferior_registers (ignored)
213 int ignored;
214{
215 struct regs inferior_registers;
216 struct fp_status inferior_fp_registers;
217 CORE_ADDR sp = *(CORE_ADDR *)&registers[REGISTER_BYTE (SP_REGNUM)];
218
219 write_inferior_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
220 16*REGISTER_RAW_SIZE (L0_REGNUM));
221
222 memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
223 15 * REGISTER_RAW_SIZE (G1_REGNUM));
224
225 inferior_registers.r_ps =
226 *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
227 inferior_registers.r_pc =
228 *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
229 inferior_registers.r_npc =
230 *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
231 inferior_registers.r_y =
232 *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
233
234 if (ptrace (PTRACE_SETREGS, inferior_pid,
235 (PTRACE_ARG3_TYPE) &inferior_registers, 0))
236 perror("ptrace_setregs");
237
238 memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
239 sizeof inferior_fp_registers.fpu_fr);
240
241 if (ptrace (PTRACE_SETFPREGS, inferior_pid,
242 (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0))
243 perror("ptrace_setfpregs");
244}
245
799d5b6a
SG
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
255read_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 (1, inferior_pid, addr, 0);
273 }
274
275 /* Copy appropriate bytes out of the buffer. */
276 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, 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
284int
285write_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 (1, inferior_pid, addr, 0);
303
304 if (count > 1)
305 {
306 buffer[count - 1]
307 = ptrace (1, inferior_pid,
308 addr + (count - 1) * sizeof (int), 0);
309 }
310
311 /* Copy data to be written over corresponding part of buffer */
312
313 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
314
315 /* Write the entire buffer. */
316
317 for (i = 0; i < count; i++, addr += sizeof (int))
318 {
319 errno = 0;
320 ptrace (4, inferior_pid, addr, buffer[i]);
321 if (errno)
322 return errno;
323 }
324
325 return 0;
326}
327\f
799d5b6a
SG
328void
329initialize ()
330{
799d5b6a 331 inferior_pid = 0;
799d5b6a
SG
332}
333
799d5b6a
SG
334int
335have_inferior_p ()
336{
337 return inferior_pid != 0;
338}
This page took 0.035516 seconds and 4 git commands to generate.