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