From 2001-07-23 Andreas Schwab <schwab@suse.de>:
[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
af471f3c 213void
fba45db2 214read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
215{
216 register int i;
217 /* Round starting address down to longword boundary. */
9f30d7f5 218 register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
c906108c
SS
219 /* Round ending address up; get number of longwords that makes. */
220 register int count
221 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
222 /* Allocate buffer of that many longwords. */
223 register int *buffer = (int *) alloca (count * sizeof (int));
224
225 /* Read all the longwords */
226 for (i = 0; i < count; i++, addr += sizeof (int))
227 {
228 buffer[i] = ptrace (1, inferior_pid, addr, 0);
229 }
230
231 /* Copy appropriate bytes out of the buffer. */
232 memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
233}
234
235/* Copy LEN bytes of data from debugger memory at MYADDR
236 to inferior's memory at MEMADDR.
237 On failure (cannot write the inferior)
238 returns the value of errno. */
239
240int
fba45db2 241write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
242{
243 register int i;
244 /* Round starting address down to longword boundary. */
9f30d7f5 245 register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
c906108c
SS
246 /* Round ending address up; get number of longwords that makes. */
247 register int count
248 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
249 /* Allocate buffer of that many longwords. */
250 register int *buffer = (int *) alloca (count * sizeof (int));
251 extern int errno;
252
253 /* Fill start and end extra bytes of buffer with existing memory data. */
254
255 buffer[0] = ptrace (1, inferior_pid, addr, 0);
256
257 if (count > 1)
258 {
259 buffer[count - 1]
260 = ptrace (1, inferior_pid,
261 addr + (count - 1) * sizeof (int), 0);
262 }
263
264 /* Copy data to be written over corresponding part of buffer */
265
266 memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
267
268 /* Write the entire buffer. */
269
270 for (i = 0; i < count; i++, addr += sizeof (int))
271 {
272 errno = 0;
273 ptrace (4, inferior_pid, addr, buffer[i]);
274 if (errno)
275 return errno;
276 }
277
278 return 0;
279}
280\f
281void
fba45db2 282initialize_low (void)
c906108c 283{
c906108c 284}
This page took 0.11291 seconds and 4 git commands to generate.