Update/correct copyright notices.
[deliverable/binutils-gdb.git] / gdb / gdbserver / low-sun3.c
CommitLineData
c906108c 1/* Low level interface to ptrace, for the remote server for GDB.
b6ba6518
KB
2 Copyright 1986, 1987, 1993, 1994, 1995, 1999, 2000, 2001
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
75/* Kill the inferior process. Make us have no inferior. */
76
77void
fba45db2 78kill_inferior (void)
c906108c
SS
79{
80 if (inferior_pid == 0)
81 return;
82 ptrace (8, inferior_pid, 0, 0);
83 wait (0);
c5aa993b 84/*************inferior_died ();****VK**************/
c906108c
SS
85}
86
87/* Return nonzero if the given thread is still alive. */
88int
fba45db2 89mythread_alive (int pid)
c906108c
SS
90{
91 return 1;
92}
93
94/* Wait for process, returns status */
95
96unsigned char
fba45db2 97mywait (char *status)
c906108c
SS
98{
99 int pid;
100 union wait w;
101
102 pid = wait (&w);
103 if (pid != inferior_pid)
104 perror_with_name ("wait");
105
106 if (WIFEXITED (w))
107 {
108 fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
109 *status = 'W';
110 return ((unsigned char) WEXITSTATUS (w));
111 }
112 else if (!WIFSTOPPED (w))
113 {
114 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
115 *status = 'X';
116 return ((unsigned char) WTERMSIG (w));
117 }
118
119 fetch_inferior_registers (0);
120
121 *status = 'T';
122 return ((unsigned char) WSTOPSIG (w));
123}
124
125/* Resume execution of the inferior process.
126 If STEP is nonzero, single-step it.
127 If SIGNAL is nonzero, give it that signal. */
128
129void
fba45db2 130myresume (int step, int signal)
c906108c
SS
131{
132 errno = 0;
133 ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
134 if (errno)
135 perror_with_name ("ptrace");
136}
137
138/* Fetch one or more registers from the inferior. REGNO == -1 to get
139 them all. We actually fetch more than requested, when convenient,
140 marking them as valid so we won't fetch them again. */
141
142void
fba45db2 143fetch_inferior_registers (int ignored)
c906108c
SS
144{
145 struct regs inferior_registers;
146 struct fp_status inferior_fp_registers;
147
148 ptrace (PTRACE_GETREGS, inferior_pid,
c5aa993b 149 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c
SS
150#ifdef FP0_REGNUM
151 ptrace (PTRACE_GETFPREGS, inferior_pid,
c5aa993b
JM
152 (PTRACE_ARG3_TYPE) & inferior_fp_registers);
153#endif
154
c906108c
SS
155 memcpy (registers, &inferior_registers, 16 * 4);
156#ifdef FP0_REGNUM
157 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
158 sizeof inferior_fp_registers.fps_regs);
c5aa993b
JM
159#endif
160 *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
161 *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
c906108c
SS
162#ifdef FP0_REGNUM
163 memcpy
164 (&registers[REGISTER_BYTE (FPC_REGNUM)],
165 &inferior_fp_registers.fps_control,
166 sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
c5aa993b 167#endif
c906108c
SS
168}
169
170/* Store our register values back into the inferior.
171 If REGNO is -1, do this for all registers.
172 Otherwise, REGNO specifies which register (so we can save time). */
173
174void
fba45db2 175store_inferior_registers (int ignored)
c906108c
SS
176{
177 struct regs inferior_registers;
178 struct fp_status inferior_fp_registers;
179
180 memcpy (&inferior_registers, registers, 16 * 4);
181#ifdef FP0_REGNUM
182 memcpy (&inferior_fp_registers,
183 &registers[REGISTER_BYTE (FP0_REGNUM)],
184 sizeof inferior_fp_registers.fps_regs);
185#endif
c5aa993b
JM
186 inferior_registers.r_ps = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
187 inferior_registers.r_pc = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
c906108c
SS
188
189#ifdef FP0_REGNUM
190 memcpy (&inferior_fp_registers.fps_control,
191 &registers[REGISTER_BYTE (FPC_REGNUM)],
192 (sizeof inferior_fp_registers
193 - sizeof inferior_fp_registers.fps_regs));
194#endif
195
196 ptrace (PTRACE_SETREGS, inferior_pid,
c5aa993b 197 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c
SS
198#if FP0_REGNUM
199 ptrace (PTRACE_SETFPREGS, inferior_pid,
c5aa993b 200 (PTRACE_ARG3_TYPE) & inferior_fp_registers);
c906108c
SS
201#endif
202}
203
204/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
205 in the NEW_SUN_PTRACE case.
206 It ought to be straightforward. But it appears that writing did
207 not write the data that I specified. I cannot understand where
208 it got the data that it actually did write. */
209
210/* Copy LEN bytes from inferior's memory starting at MEMADDR
211 to debugger memory starting at MYADDR. */
212
fba45db2 213read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
214{
215 register int i;
216 /* Round starting address down to longword boundary. */
217 register CORE_ADDR addr = memaddr & -sizeof (int);
218 /* Round ending address up; get number of longwords that makes. */
219 register int count
220 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
221 /* Allocate buffer of that many longwords. */
222 register int *buffer = (int *) alloca (count * sizeof (int));
223
224 /* Read all the longwords */
225 for (i = 0; i < count; i++, addr += sizeof (int))
226 {
227 buffer[i] = ptrace (1, inferior_pid, addr, 0);
228 }
229
230 /* Copy appropriate bytes out of the buffer. */
231 memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
232}
233
234/* Copy LEN bytes of data from debugger memory at MYADDR
235 to inferior's memory at MEMADDR.
236 On failure (cannot write the inferior)
237 returns the value of errno. */
238
239int
fba45db2 240write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
241{
242 register int i;
243 /* Round starting address down to longword boundary. */
244 register CORE_ADDR addr = memaddr & -sizeof (int);
245 /* Round ending address up; get number of longwords that makes. */
246 register int count
247 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
248 /* Allocate buffer of that many longwords. */
249 register int *buffer = (int *) alloca (count * sizeof (int));
250 extern int errno;
251
252 /* Fill start and end extra bytes of buffer with existing memory data. */
253
254 buffer[0] = ptrace (1, inferior_pid, addr, 0);
255
256 if (count > 1)
257 {
258 buffer[count - 1]
259 = ptrace (1, inferior_pid,
260 addr + (count - 1) * sizeof (int), 0);
261 }
262
263 /* Copy data to be written over corresponding part of buffer */
264
265 memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
266
267 /* Write the entire buffer. */
268
269 for (i = 0; i < count; i++, addr += sizeof (int))
270 {
271 errno = 0;
272 ptrace (4, inferior_pid, addr, buffer[i]);
273 if (errno)
274 return errno;
275 }
276
277 return 0;
278}
279\f
280void
fba45db2 281initialize_low (void)
c906108c 282{
c906108c 283}
This page took 0.242389 seconds and 4 git commands to generate.