* Rename files for 14-character limits:
[deliverable/binutils-gdb.git] / gdb / gdbserver / low-lynx.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 "server.h"
21 #include "frame.h"
22 #include "inferior.h"
23
24 #include <stdio.h>
25 #include <sys/param.h>
26 #include <sys/dir.h>
27 #define LYNXOS
28 #include <sys/mem.h>
29 #include <sys/signal.h>
30 #include <sys/file.h>
31 #include <sys/kernel.h>
32 #include <sys/itimer.h>
33 #include <sys/time.h>
34 #include <sys/resource.h>
35 #include <sys/proc.h>
36 #include <signal.h>
37 #include <sys/ioctl.h>
38 #include <sgtty.h>
39 #include <fcntl.h>
40 #include "/usr/include/wait.h"
41
42 char registers[REGISTER_BYTES];
43
44 #include <sys/ptrace.h>
45
46 /* Start an inferior process and returns its pid.
47 ALLARGS is a vector of program-name and args. */
48
49 int
50 create_inferior (program, allargs)
51 char *program;
52 char **allargs;
53 {
54 int pid;
55
56 pid = fork ();
57 if (pid < 0)
58 perror_with_name ("fork");
59
60 if (pid == 0)
61 {
62 int pgrp;
63
64 /* Switch child to it's own process group so that signals won't
65 directly affect gdbserver. */
66
67 pgrp = getpid();
68 setpgrp(0, pgrp);
69 ioctl (0, TIOCSPGRP, &pgrp);
70
71 ptrace (PTRACE_TRACEME);
72
73 execv (program, allargs);
74
75 fprintf (stderr, "GDBserver (process %d): Cannot exec %s: %s.\n",
76 getpid(), program,
77 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
78 fflush (stderr);
79 _exit (0177);
80 }
81
82 return pid;
83 }
84
85 /* Kill the inferior process. Make us have no inferior. */
86
87 void
88 kill_inferior ()
89 {
90 if (inferior_pid == 0)
91 return;
92 ptrace (PTRACE_KILL, inferior_pid, 0, 0);
93 wait (0);
94
95 inferior_pid = 0;
96 }
97
98 /* Wait for process, returns status */
99
100 unsigned char
101 mywait (status)
102 char *status;
103 {
104 int pid;
105 union wait w;
106
107 enable_async_io();
108
109 pid = wait (&w);
110
111 disable_async_io();
112
113 if (pid != PIDGET(inferior_pid))
114 perror_with_name ("wait");
115
116 inferior_pid = BUILDPID (inferior_pid, w.w_tid);
117
118 if (WIFEXITED (w))
119 {
120 fprintf (stderr, "\nChild exited with status %d\n", WEXITSTATUS (w));
121 fprintf (stderr, "GDBserver exiting\n");
122 exit (0);
123 }
124 else if (!WIFSTOPPED (w))
125 {
126 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
127 *status = 'T';
128 return ((unsigned char) WTERMSIG (w));
129 }
130
131 fetch_inferior_registers (0);
132
133 *status = 'S';
134 return ((unsigned char) WSTOPSIG (w));
135 }
136
137 /* Resume execution of the inferior process.
138 If STEP is nonzero, single-step it.
139 If SIGNAL is nonzero, give it that signal. */
140
141 void
142 myresume (step, signal)
143 int step;
144 int signal;
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 #undef offsetof
153 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
154
155 static struct econtext *
156 lynx_registers_addr()
157 {
158 st_t *stblock;
159 int ecpoff = offsetof(st_t, ecp);
160 CORE_ADDR ecp;
161
162 errno = 0;
163 stblock = (st_t *) ptrace (PTRACE_THREADUSER, inferior_pid,
164 (PTRACE_ARG3_TYPE)0, 0);
165 if (errno)
166 perror_with_name ("PTRACE_THREADUSER");
167
168 ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, inferior_pid,
169 (PTRACE_ARG3_TYPE)ecpoff, 0);
170 ecp -= (CORE_ADDR)stblock;
171 if (errno)
172 perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
173
174 return (struct econtext *)ecp;
175 }
176
177 static struct econtext *ecp;
178
179 /* Mapping between GDB register #s and offsets into econtext. Must be
180 consistent with REGISTER_NAMES macro in tm-i386v.h. */
181
182 #define X(ENTRY)(offsetof(struct econtext, ENTRY) / 4)
183 static int regmap[] = {
184 X(eax),
185 X(ecx),
186 X(edx),
187 X(ebx),
188 X(esp),
189 X(ebp),
190 X(esi),
191 X(edi),
192 X(eip),
193 X(flags), /* ps */
194 X(cs),
195 X(ss),
196 X(ds),
197 X(es),
198 X(ecode), /* Lynx doesn't give us either fs or gs, so */
199 X(fault) /* we just substitute these two in the hopes
200 that they are useful. */
201 };
202
203 /* Fetch one or more registers from the inferior. REGNO == -1 to get
204 them all. We actually fetch more than requested, when convenient,
205 marking them as valid so we won't fetch them again. */
206
207 void
208 fetch_inferior_registers (ignored)
209 int ignored;
210 {
211 int regno;
212 unsigned long reg;
213 struct econtext *ecp;
214
215 ecp = lynx_registers_addr();
216
217 for (regno = 0; regno < NUM_REGS; regno++)
218 {
219 errno = 0;
220 reg = ptrace (PTRACE_PEEKTHREAD, inferior_pid,
221 (PTRACE_ARG3_TYPE) (&ecp->fault + regmap[regno]), 0);
222 if (errno)
223 perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
224
225 *(unsigned long *)&registers[REGISTER_BYTE (regno)] = reg;
226 }
227 }
228
229 /* Store our register values back into the inferior.
230 If REGNO is -1, do this for all registers.
231 Otherwise, REGNO specifies which register (so we can save time). */
232
233 void
234 store_inferior_registers (ignored)
235 int ignored;
236 {
237 int regno;
238 unsigned long reg;
239 struct econtext *ecp;
240
241 ecp = lynx_registers_addr();
242
243 for (regno = 0; regno < NUM_REGS; regno++)
244 {
245 reg = *(unsigned long *)&registers[REGISTER_BYTE (regno)];
246
247 errno = 0;
248 ptrace (PTRACE_POKEUSER, inferior_pid,
249 (PTRACE_ARG3_TYPE) (&ecp->fault + regmap[regno]), reg);
250 if (errno)
251 perror_with_name ("PTRACE_POKEUSER");
252 }
253 }
254
255 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
256 in the NEW_SUN_PTRACE case.
257 It ought to be straightforward. But it appears that writing did
258 not write the data that I specified. I cannot understand where
259 it got the data that it actually did write. */
260
261 /* Copy LEN bytes from inferior's memory starting at MEMADDR
262 to debugger memory starting at MYADDR. */
263
264 void
265 read_inferior_memory (memaddr, myaddr, len)
266 CORE_ADDR memaddr;
267 char *myaddr;
268 int len;
269 {
270 register int i;
271 /* Round starting address down to longword boundary. */
272 register CORE_ADDR addr = memaddr & -sizeof (int);
273 /* Round ending address up; get number of longwords that makes. */
274 register int count
275 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
276 /* Allocate buffer of that many longwords. */
277 register int *buffer = (int *) alloca (count * sizeof (int));
278
279 /* Read all the longwords */
280 for (i = 0; i < count; i++, addr += sizeof (int))
281 {
282 buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
283 }
284
285 /* Copy appropriate bytes out of the buffer. */
286 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
287 }
288
289 /* Copy LEN bytes of data from debugger memory at MYADDR
290 to inferior's memory at MEMADDR.
291 On failure (cannot write the inferior)
292 returns the value of errno. */
293
294 int
295 write_inferior_memory (memaddr, myaddr, len)
296 CORE_ADDR memaddr;
297 char *myaddr;
298 int len;
299 {
300 register int i;
301 /* Round starting address down to longword boundary. */
302 register CORE_ADDR addr = memaddr & -sizeof (int);
303 /* Round ending address up; get number of longwords that makes. */
304 register int count
305 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
306 /* Allocate buffer of that many longwords. */
307 register int *buffer = (int *) alloca (count * sizeof (int));
308 extern int errno;
309
310 /* Fill start and end extra bytes of buffer with existing memory data. */
311
312 buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
313
314 if (count > 1)
315 {
316 buffer[count - 1]
317 = ptrace (PTRACE_PEEKTEXT, inferior_pid,
318 addr + (count - 1) * sizeof (int), 0);
319 }
320
321 /* Copy data to be written over corresponding part of buffer */
322
323 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
324
325 /* Write the entire buffer. */
326
327 for (i = 0; i < count; i++, addr += sizeof (int))
328 {
329 while (1)
330 {
331 errno = 0;
332 ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]);
333 if (errno)
334 {
335 fprintf(stderr, "ptrace (PTRACE_POKETEXT): errno=%d, inferior_pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n", errno, inferior_pid, addr, buffer[i]);
336 fprintf(stderr, "Sleeping for 1 second\n");
337 sleep(1);
338 }
339 else
340 break;
341 }
342 }
343
344 return 0;
345 }
This page took 0.035659 seconds and 4 git commands to generate.