1 /* Low level interface to ptrace, for the remote server for GDB.
2 Copyright (C) 1986, 1987, 1993 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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. */
25 #include <sys/param.h>
29 #include <sys/signal.h>
31 #include <sys/kernel.h>
32 #include <sys/itimer.h>
34 #include <sys/resource.h>
37 #include <sys/ioctl.h>
40 #include "/usr/include/wait.h"
42 char registers
[REGISTER_BYTES
];
44 #include <sys/ptrace.h>
46 /* Start an inferior process and returns its pid.
47 ALLARGS is a vector of program-name and args. */
50 create_inferior (program
, allargs
)
58 perror_with_name ("fork");
64 /* Switch child to it's own process group so that signals won't
65 directly affect gdbserver. */
69 ioctl (0, TIOCSPGRP
, &pgrp
);
71 ptrace (PTRACE_TRACEME
);
73 execv (program
, allargs
);
75 fprintf (stderr
, "GDBserver (process %d): Cannot exec %s: %s.\n",
77 errno
< sys_nerr
? sys_errlist
[errno
] : "unknown error");
85 /* Kill the inferior process. Make us have no inferior. */
90 if (inferior_pid
== 0)
92 ptrace (PTRACE_KILL
, inferior_pid
, 0, 0);
98 /* Wait for process, returns status */
113 if (pid
!= PIDGET(inferior_pid
))
114 perror_with_name ("wait");
116 inferior_pid
= BUILDPID (inferior_pid
, w
.w_tid
);
120 fprintf (stderr
, "\nChild exited with status %d\n", WEXITSTATUS (w
));
121 fprintf (stderr
, "GDBserver exiting\n");
124 else if (!WIFSTOPPED (w
))
126 fprintf (stderr
, "\nChild terminated with signal = %x \n", WTERMSIG (w
));
128 return ((unsigned char) WTERMSIG (w
));
131 fetch_inferior_registers (0);
134 return ((unsigned char) WSTOPSIG (w
));
137 /* Resume execution of the inferior process.
138 If STEP is nonzero, single-step it.
139 If SIGNAL is nonzero, give it that signal. */
142 myresume (step
, signal
)
147 ptrace (step
? PTRACE_SINGLESTEP
: PTRACE_CONT
, inferior_pid
, 1, signal
);
149 perror_with_name ("ptrace");
153 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
155 static struct econtext
*
156 lynx_registers_addr()
159 int ecpoff
= offsetof(st_t
, ecp
);
163 stblock
= (st_t
*) ptrace (PTRACE_THREADUSER
, inferior_pid
,
164 (PTRACE_ARG3_TYPE
)0, 0);
166 perror_with_name ("PTRACE_THREADUSER");
168 ecp
= (CORE_ADDR
) ptrace (PTRACE_PEEKTHREAD
, inferior_pid
,
169 (PTRACE_ARG3_TYPE
)ecpoff
, 0);
170 ecp
-= (CORE_ADDR
)stblock
;
172 perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
174 return (struct econtext
*)ecp
;
177 static struct econtext
*ecp
;
179 /* Mapping between GDB register #s and offsets into econtext. Must be
180 consistent with REGISTER_NAMES macro in tm-i386v.h. */
182 #define X(ENTRY)(offsetof(struct econtext, ENTRY) / 4)
183 static int regmap
[] = {
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. */
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. */
208 fetch_inferior_registers (ignored
)
213 struct econtext
*ecp
;
215 ecp
= lynx_registers_addr();
217 for (regno
= 0; regno
< NUM_REGS
; regno
++)
220 reg
= ptrace (PTRACE_PEEKTHREAD
, inferior_pid
,
221 (PTRACE_ARG3_TYPE
) (&ecp
->fault
+ regmap
[regno
]), 0);
223 perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
225 *(unsigned long *)®isters
[REGISTER_BYTE (regno
)] = reg
;
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). */
234 store_inferior_registers (ignored
)
239 struct econtext
*ecp
;
241 ecp
= lynx_registers_addr();
243 for (regno
= 0; regno
< NUM_REGS
; regno
++)
245 reg
= *(unsigned long *)®isters
[REGISTER_BYTE (regno
)];
248 ptrace (PTRACE_POKEUSER
, inferior_pid
,
249 (PTRACE_ARG3_TYPE
) (&ecp
->fault
+ regmap
[regno
]), reg
);
251 perror_with_name ("PTRACE_POKEUSER");
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. */
261 /* Copy LEN bytes from inferior's memory starting at MEMADDR
262 to debugger memory starting at MYADDR. */
265 read_inferior_memory (memaddr
, myaddr
, len
)
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. */
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));
279 /* Read all the longwords */
280 for (i
= 0; i
< count
; i
++, addr
+= sizeof (int))
282 buffer
[i
] = ptrace (PTRACE_PEEKTEXT
, inferior_pid
, addr
, 0);
285 /* Copy appropriate bytes out of the buffer. */
286 bcopy ((char *) buffer
+ (memaddr
& (sizeof (int) - 1)), myaddr
, len
);
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. */
295 write_inferior_memory (memaddr
, myaddr
, len
)
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. */
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));
310 /* Fill start and end extra bytes of buffer with existing memory data. */
312 buffer
[0] = ptrace (PTRACE_PEEKTEXT
, inferior_pid
, addr
, 0);
317 = ptrace (PTRACE_PEEKTEXT
, inferior_pid
,
318 addr
+ (count
- 1) * sizeof (int), 0);
321 /* Copy data to be written over corresponding part of buffer */
323 bcopy (myaddr
, (char *) buffer
+ (memaddr
& (sizeof (int) - 1)), len
);
325 /* Write the entire buffer. */
327 for (i
= 0; i
< count
; i
++, addr
+= sizeof (int))
332 ptrace (PTRACE_POKETEXT
, inferior_pid
, addr
, buffer
[i
]);
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");
This page took 0.035464 seconds and 4 git commands to generate.