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