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