* win32-nat.c (psapi_module_handle): Remove static.
[deliverable/binutils-gdb.git] / gdb / inf-ptrace.c
CommitLineData
2c4a536d 1/* Low-level child interface to ptrace.
5bf970f9 2
6aba47ca
DJ
3 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
4 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
8785ced0 5 Free Software Foundation, Inc.
5bf970f9
AC
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
5bf970f9
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
5bf970f9
AC
21
22#include "defs.h"
5bf970f9 23#include "command.h"
2c4a536d
MK
24#include "inferior.h"
25#include "inflow.h"
5bf970f9 26#include "gdbcore.h"
8785ced0 27#include "regcache.h"
5bf970f9 28
f7dd0ed7 29#include "gdb_stdint.h"
8785ced0 30#include "gdb_assert.h"
2c4a536d
MK
31#include "gdb_string.h"
32#include "gdb_ptrace.h"
34a17005 33#include "gdb_wait.h"
5bf970f9
AC
34#include <signal.h>
35
2c4a536d
MK
36#include "inf-child.h"
37
38/* HACK: Save the ptrace ops returned by inf_ptrace_target. */
5bf970f9 39static struct target_ops *ptrace_ops_hack;
c7c14b96
MK
40\f
41
735f54b4
MK
42#ifdef PT_GET_PROCESS_STATE
43
44static int
ee057212 45inf_ptrace_follow_fork (struct target_ops *ops, int follow_child)
735f54b4
MK
46{
47 pid_t pid, fpid;
48 ptrace_state_t pe;
49
50 /* FIXME: kettenis/20050720: This stuff should really be passed as
51 an argument by our caller. */
52 {
53 ptid_t ptid;
54 struct target_waitstatus status;
55
56 get_last_target_status (&ptid, &status);
57 gdb_assert (status.kind == TARGET_WAITKIND_FORKED);
58
59 pid = ptid_get_pid (ptid);
60 }
61
62 if (ptrace (PT_GET_PROCESS_STATE, pid,
63 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
64 perror_with_name (("ptrace"));
65
66 gdb_assert (pe.pe_report_event == PTRACE_FORK);
67 fpid = pe.pe_other_pid;
68
69 if (follow_child)
70 {
71 inferior_ptid = pid_to_ptid (fpid);
72 detach_breakpoints (pid);
73
74 /* Reset breakpoints in the child as appropriate. */
75 follow_inferior_reset_breakpoints ();
76
77 if (ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
78 perror_with_name (("ptrace"));
79 }
80 else
81 {
82 inferior_ptid = pid_to_ptid (pid);
83 detach_breakpoints (fpid);
84
85 if (ptrace (PT_DETACH, fpid, (PTRACE_TYPE_ARG3)1, 0) == -1)
86 perror_with_name (("ptrace"));
87 }
88
89 return 0;
90}
91
92#endif /* PT_GET_PROCESS_STATE */
93\f
94
4b8a1a28 95/* Prepare to be traced. */
5bf970f9
AC
96
97static void
c7c14b96 98inf_ptrace_me (void)
5bf970f9 99{
c7c14b96 100 /* "Trace me, Dr. Memory!" */
4b8a1a28 101 ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3)0, 0);
5bf970f9
AC
102}
103
4b8a1a28 104/* Start tracing PID. */
5bf970f9
AC
105
106static void
c7c14b96 107inf_ptrace_him (int pid)
5bf970f9 108{
c7c14b96 109 push_target (ptrace_ops_hack);
5bf970f9 110
c7c14b96
MK
111 /* On some targets, there must be some explicit synchronization
112 between the parent and child processes after the debugger
113 forks, and before the child execs the debuggee program. This
114 call basically gives permission for the child to exec. */
5bf970f9 115
c7c14b96 116 target_acknowledge_created_inferior (pid);
5bf970f9 117
c7c14b96
MK
118 /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
119 be 1 or 2 depending on whether we're starting without or with a
120 shell. */
121 startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
122
123 /* On some targets, there must be some explicit actions taken after
124 the inferior has been started up. */
125 target_post_startup_inferior (pid_to_ptid (pid));
5bf970f9
AC
126}
127
4b8a1a28
MK
128/* Start a new inferior Unix child process. EXEC_FILE is the file to
129 run, ALLARGS is a string containing the arguments to the program.
130 ENV is the environment vector to pass. If FROM_TTY is non-zero, be
131 chatty about it. */
5bf970f9 132
c7c14b96
MK
133static void
134inf_ptrace_create_inferior (char *exec_file, char *allargs, char **env,
135 int from_tty)
5bf970f9 136{
c7c14b96
MK
137 fork_inferior (exec_file, allargs, env, inf_ptrace_me, inf_ptrace_him,
138 NULL, NULL);
5bf970f9
AC
139}
140
e4ef629d
MK
141#ifdef PT_GET_PROCESS_STATE
142
143static void
144inf_ptrace_post_startup_inferior (ptid_t pid)
145{
146 ptrace_event_t pe;
147
148 /* Set the initial event mask. */
149 memset (&pe, 0, sizeof pe);
150 pe.pe_set_event |= PTRACE_FORK;
151 if (ptrace (PT_SET_EVENT_MASK, ptid_get_pid (pid),
152 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
153 perror_with_name (("ptrace"));
154}
155
156#endif
157
4b8a1a28
MK
158/* Clean up a rotting corpse of an inferior after it died. */
159
c7c14b96
MK
160static void
161inf_ptrace_mourn_inferior (void)
5bf970f9 162{
4b8a1a28
MK
163 int status;
164
165 /* Wait just one more time to collect the inferior's exit status.
f010475d 166 Do not check whether this succeeds though, since we may be
4b8a1a28 167 dealing with a process that we attached to. Such a process will
3d450bdd 168 only report its exit status to its original parent. */
4b8a1a28
MK
169 waitpid (ptid_get_pid (inferior_ptid), &status, 0);
170
c7c14b96
MK
171 unpush_target (ptrace_ops_hack);
172 generic_mourn_inferior ();
5bf970f9
AC
173}
174
4b8a1a28
MK
175/* Attach to the process specified by ARGS. If FROM_TTY is non-zero,
176 be chatty about it. */
5bf970f9
AC
177
178static void
179inf_ptrace_attach (char *args, int from_tty)
180{
181 char *exec_file;
4b8a1a28 182 pid_t pid;
5bf970f9
AC
183 char *dummy;
184
185 if (!args)
e2e0b3e5 186 error_no_arg (_("process-id to attach"));
5bf970f9
AC
187
188 dummy = args;
189 pid = strtol (args, &dummy, 0);
f6ffd89b 190 /* Some targets don't set errno on errors, grrr! */
6e1e94ea 191 if (pid == 0 && args == dummy)
8a3fe4f8 192 error (_("Illegal process-id: %s."), args);
5bf970f9 193
f6ffd89b 194 if (pid == getpid ()) /* Trying to masturbate? */
8a3fe4f8 195 error (_("I refuse to debug myself!"));
5bf970f9
AC
196
197 if (from_tty)
198 {
4b8a1a28 199 exec_file = get_exec_file (0);
5bf970f9
AC
200
201 if (exec_file)
a3f17187 202 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
5bf970f9
AC
203 target_pid_to_str (pid_to_ptid (pid)));
204 else
a3f17187 205 printf_unfiltered (_("Attaching to %s\n"),
5bf970f9
AC
206 target_pid_to_str (pid_to_ptid (pid)));
207
208 gdb_flush (gdb_stdout);
209 }
210
6e1e94ea
MK
211#ifdef PT_ATTACH
212 errno = 0;
4b8a1a28 213 ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
6e1e94ea 214 if (errno != 0)
e2e0b3e5 215 perror_with_name (("ptrace"));
6e1e94ea
MK
216 attach_flag = 1;
217#else
8a3fe4f8 218 error (_("This system does not support attaching to a process"));
6e1e94ea 219#endif
5bf970f9
AC
220
221 inferior_ptid = pid_to_ptid (pid);
222 push_target (ptrace_ops_hack);
223}
224
e4ef629d
MK
225#ifdef PT_GET_PROCESS_STATE
226
227void
228inf_ptrace_post_attach (int pid)
229{
230 ptrace_event_t pe;
231
232 /* Set the initial event mask. */
233 memset (&pe, 0, sizeof pe);
234 pe.pe_set_event |= PTRACE_FORK;
235 if (ptrace (PT_SET_EVENT_MASK, pid,
236 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
237 perror_with_name (("ptrace"));
238}
239
240#endif
241
4b8a1a28 242/* Detach from the inferior, optionally passing it the signal
f010475d 243 specified by ARGS. If FROM_TTY is non-zero, be chatty about it. */
5bf970f9
AC
244
245static void
246inf_ptrace_detach (char *args, int from_tty)
247{
4b8a1a28 248 pid_t pid = ptid_get_pid (inferior_ptid);
6e1e94ea 249 int sig = 0;
5bf970f9
AC
250
251 if (from_tty)
252 {
253 char *exec_file = get_exec_file (0);
254 if (exec_file == 0)
255 exec_file = "";
a3f17187 256 printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
5bf970f9
AC
257 target_pid_to_str (pid_to_ptid (pid)));
258 gdb_flush (gdb_stdout);
259 }
260 if (args)
6e1e94ea 261 sig = atoi (args);
5bf970f9 262
6e1e94ea 263#ifdef PT_DETACH
4b8a1a28 264 /* We'd better not have left any breakpoints in the program or it'll
f010475d 265 die when it hits one. Also note that this may only work if we
4b8a1a28
MK
266 previously attached to the inferior. It *might* work if we
267 started the process ourselves. */
6e1e94ea 268 errno = 0;
4b8a1a28 269 ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, sig);
6e1e94ea 270 if (errno != 0)
e2e0b3e5 271 perror_with_name (("ptrace"));
6e1e94ea
MK
272 attach_flag = 0;
273#else
8a3fe4f8 274 error (_("This system does not support detaching from a process"));
6e1e94ea 275#endif
5bf970f9
AC
276
277 inferior_ptid = null_ptid;
278 unpush_target (ptrace_ops_hack);
279}
280
4b8a1a28
MK
281/* Kill the inferior. */
282
5bf970f9 283static void
4b8a1a28 284inf_ptrace_kill (void)
5bf970f9 285{
4b8a1a28 286 pid_t pid = ptid_get_pid (inferior_ptid);
c7c14b96 287 int status;
c7c14b96
MK
288
289 if (pid == 0)
290 return;
291
4b8a1a28
MK
292 ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0);
293 waitpid (pid, &status, 0);
294
c7c14b96 295 target_mourn_inferior ();
5bf970f9
AC
296}
297
4b8a1a28 298/* Stop the inferior. */
c7c14b96 299
5bf970f9 300static void
c7c14b96 301inf_ptrace_stop (void)
5bf970f9 302{
4b8a1a28
MK
303 /* Send a SIGINT to the process group. This acts just like the user
304 typed a ^C on the controlling terminal. Note that using a
305 negative process number in kill() is a System V-ism. The proper
306 BSD interface is killpg(). However, all modern BSDs support the
307 System V interface too. */
c7c14b96 308 kill (-inferior_process_group, SIGINT);
5bf970f9
AC
309}
310
4b8a1a28
MK
311/* Resume execution of thread PTID, or all threads if PTID is -1. If
312 STEP is nonzero, single-step it. If SIGNAL is nonzero, give it
313 that signal. */
5bf970f9
AC
314
315static void
c7c14b96 316inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
5bf970f9 317{
4b8a1a28 318 pid_t pid = ptid_get_pid (ptid);
c7c14b96 319 int request = PT_CONTINUE;
c7c14b96
MK
320
321 if (pid == -1)
4b8a1a28
MK
322 /* Resume all threads. Traditionally ptrace() only supports
323 single-threaded processes, so simply resume the inferior. */
324 pid = ptid_get_pid (inferior_ptid);
c7c14b96
MK
325
326 if (step)
327 {
328 /* If this system does not support PT_STEP, a higher level
329 function will have called single_step() to transmute the step
330 request into a continue request (by setting breakpoints on
331 all possible successor instructions), so we don't have to
332 worry about that here. */
333 request = PT_STEP;
334 }
335
336 /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
337 where it was. If GDB wanted it to start some other way, we have
4b8a1a28 338 already written a new program counter value to the child. */
c7c14b96 339 errno = 0;
4b8a1a28 340 ptrace (request, pid, (PTRACE_TYPE_ARG3)1, target_signal_to_host (signal));
c7c14b96
MK
341 if (errno != 0)
342 perror_with_name (("ptrace"));
5bf970f9
AC
343}
344
4b8a1a28
MK
345/* Wait for the child specified by PTID to do something. Return the
346 process ID of the child, or MINUS_ONE_PTID in case of error; store
347 the status in *OURSTATUS. */
5bf970f9 348
c7c14b96
MK
349static ptid_t
350inf_ptrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
5bf970f9 351{
4b8a1a28
MK
352 pid_t pid;
353 int status, save_errno;
5bf970f9 354
c7c14b96
MK
355 do
356 {
4b8a1a28 357 set_sigint_trap ();
c7c14b96 358 set_sigio_trap ();
5bf970f9 359
4b8a1a28
MK
360 do
361 {
362 pid = waitpid (ptid_get_pid (ptid), &status, 0);
363 save_errno = errno;
364 }
365 while (pid == -1 && errno == EINTR);
5bf970f9 366
c7c14b96 367 clear_sigio_trap ();
c7c14b96 368 clear_sigint_trap ();
5bf970f9 369
c7c14b96
MK
370 if (pid == -1)
371 {
c7c14b96 372 fprintf_unfiltered (gdb_stderr,
4b8a1a28 373 _("Child process unexpectedly missing: %s.\n"),
c7c14b96
MK
374 safe_strerror (save_errno));
375
376 /* Claim it exited with unknown signal. */
377 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
378 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
4b8a1a28 379 return minus_one_ptid;
c7c14b96
MK
380 }
381
4b8a1a28
MK
382 /* Ignore terminated detached child processes. */
383 if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid))
384 pid = -1;
c7c14b96 385 }
4b8a1a28 386 while (pid == -1);
c7c14b96 387
735f54b4
MK
388#ifdef PT_GET_PROCESS_STATE
389 if (WIFSTOPPED (status))
390 {
391 ptrace_state_t pe;
392 pid_t fpid;
393
394 if (ptrace (PT_GET_PROCESS_STATE, pid,
395 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
396 perror_with_name (("ptrace"));
397
398 switch (pe.pe_report_event)
399 {
400 case PTRACE_FORK:
401 ourstatus->kind = TARGET_WAITKIND_FORKED;
402 ourstatus->value.related_pid = pe.pe_other_pid;
403
404 /* Make sure the other end of the fork is stopped too. */
405 fpid = waitpid (pe.pe_other_pid, &status, 0);
406 if (fpid == -1)
407 perror_with_name (("waitpid"));
408
409 if (ptrace (PT_GET_PROCESS_STATE, fpid,
410 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
411 perror_with_name (("ptrace"));
412
413 gdb_assert (pe.pe_report_event == PTRACE_FORK);
414 gdb_assert (pe.pe_other_pid == pid);
415 if (fpid == ptid_get_pid (inferior_ptid))
416 {
417 ourstatus->value.related_pid = pe.pe_other_pid;
418 return pid_to_ptid (fpid);
419 }
420
421 return pid_to_ptid (pid);
422 }
423 }
424#endif
425
c7c14b96
MK
426 store_waitstatus (ourstatus, status);
427 return pid_to_ptid (pid);
5bf970f9
AC
428}
429
4b8a1a28
MK
430/* Attempt a transfer all LEN bytes starting at OFFSET between the
431 inferior's OBJECT:ANNEX space and GDB's READBUF/WRITEBUF buffer.
432 Return the number of bytes actually transferred. */
5bf970f9
AC
433
434static LONGEST
435inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
961cb7b5
MK
436 const char *annex, gdb_byte *readbuf,
437 const gdb_byte *writebuf,
438 ULONGEST offset, LONGEST len)
5bf970f9 439{
4b8a1a28
MK
440 pid_t pid = ptid_get_pid (inferior_ptid);
441
5bf970f9
AC
442 switch (object)
443 {
444 case TARGET_OBJECT_MEMORY:
f929a579
AC
445#ifdef PT_IO
446 /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO
447 request that promises to be much more efficient in reading
448 and writing data in the traced process's address space. */
449 {
450 struct ptrace_io_desc piod;
4b8a1a28 451
f929a579 452 /* NOTE: We assume that there are no distinct address spaces
b457b3dd
MK
453 for instruction and data. However, on OpenBSD 3.9 and
454 later, PIOD_WRITE_D doesn't allow changing memory that's
455 mapped read-only. Since most code segments will be
456 read-only, using PIOD_WRITE_D will prevent us from
457 inserting breakpoints, so we use PIOD_WRITE_I instead. */
458 piod.piod_op = writebuf ? PIOD_WRITE_I : PIOD_READ_D;
f929a579
AC
459 piod.piod_addr = writebuf ? (void *) writebuf : readbuf;
460 piod.piod_offs = (void *) (long) offset;
461 piod.piod_len = len;
462
463 errno = 0;
4b8a1a28 464 if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0)
f929a579
AC
465 /* Return the actual number of bytes read or written. */
466 return piod.piod_len;
467 /* If the PT_IO request is somehow not supported, fallback on
468 using PT_WRITE_D/PT_READ_D. Otherwise we will return zero
469 to indicate failure. */
470 if (errno != EINVAL)
471 return 0;
472 }
473#endif
474 {
475 union
476 {
477 PTRACE_TYPE_RET word;
4b8a1a28 478 gdb_byte byte[sizeof (PTRACE_TYPE_RET)];
f929a579
AC
479 } buffer;
480 ULONGEST rounded_offset;
481 LONGEST partial_len;
4b8a1a28 482
cb85a953
AC
483 /* Round the start offset down to the next long word
484 boundary. */
f929a579 485 rounded_offset = offset & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
4b8a1a28 486
cb85a953
AC
487 /* Since ptrace will transfer a single word starting at that
488 rounded_offset the partial_len needs to be adjusted down to
489 that (remember this function only does a single transfer).
490 Should the required length be even less, adjust it down
491 again. */
492 partial_len = (rounded_offset + sizeof (PTRACE_TYPE_RET)) - offset;
493 if (partial_len > len)
f929a579 494 partial_len = len;
4b8a1a28 495
f929a579
AC
496 if (writebuf)
497 {
cb85a953
AC
498 /* If OFFSET:PARTIAL_LEN is smaller than
499 ROUNDED_OFFSET:WORDSIZE then a read/modify write will
500 be needed. Read in the entire word. */
f929a579 501 if (rounded_offset < offset
cb85a953
AC
502 || (offset + partial_len
503 < rounded_offset + sizeof (PTRACE_TYPE_RET)))
f929a579 504 /* Need part of initial word -- fetch it. */
4b8a1a28 505 buffer.word = ptrace (PT_READ_I, pid,
f7dd0ed7
UW
506 (PTRACE_TYPE_ARG3)(uintptr_t)
507 rounded_offset, 0);
4b8a1a28 508
f929a579
AC
509 /* Copy data to be written over corresponding part of
510 buffer. */
f6ffd89b
MK
511 memcpy (buffer.byte + (offset - rounded_offset),
512 writebuf, partial_len);
4b8a1a28 513
f929a579 514 errno = 0;
4b8a1a28 515 ptrace (PT_WRITE_D, pid,
f7dd0ed7
UW
516 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
517 buffer.word);
f929a579
AC
518 if (errno)
519 {
520 /* Using the appropriate one (I or D) is necessary for
521 Gould NP1, at least. */
522 errno = 0;
4b8a1a28 523 ptrace (PT_WRITE_I, pid,
f7dd0ed7
UW
524 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
525 buffer.word);
f929a579
AC
526 if (errno)
527 return 0;
528 }
529 }
4b8a1a28 530
f929a579
AC
531 if (readbuf)
532 {
533 errno = 0;
4b8a1a28 534 buffer.word = ptrace (PT_READ_I, pid,
f7dd0ed7
UW
535 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
536 0);
f929a579
AC
537 if (errno)
538 return 0;
539 /* Copy appropriate bytes out of the buffer. */
540 memcpy (readbuf, buffer.byte + (offset - rounded_offset),
541 partial_len);
542 }
4b8a1a28 543
f929a579
AC
544 return partial_len;
545 }
5bf970f9
AC
546
547 case TARGET_OBJECT_UNWIND_TABLE:
548 return -1;
549
550 case TARGET_OBJECT_AUXV:
551 return -1;
552
553 case TARGET_OBJECT_WCOOKIE:
554 return -1;
555
556 default:
557 return -1;
558 }
559}
560
4b8a1a28 561/* Return non-zero if the thread specified by PTID is alive. */
c7c14b96
MK
562
563static int
564inf_ptrace_thread_alive (ptid_t ptid)
565{
4b8a1a28
MK
566 /* ??? Is kill the right way to do this? */
567 return (kill (ptid_get_pid (ptid), 0) != -1);
c7c14b96
MK
568}
569
570/* Print status information about what we're accessing. */
571
572static void
573inf_ptrace_files_info (struct target_ops *ignore)
574{
4b8a1a28
MK
575 printf_filtered (_("\tUsing the running image of %s %s.\n"),
576 attach_flag ? "attached" : "child",
577 target_pid_to_str (inferior_ptid));
5bf970f9
AC
578}
579
8785ced0
MK
580/* Create a prototype ptrace target. The client can override it with
581 local methods. */
582
5bf970f9
AC
583struct target_ops *
584inf_ptrace_target (void)
585{
586 struct target_ops *t = inf_child_target ();
8785ced0 587
5bf970f9 588 t->to_attach = inf_ptrace_attach;
5bf970f9
AC
589 t->to_detach = inf_ptrace_detach;
590 t->to_resume = inf_ptrace_resume;
591 t->to_wait = inf_ptrace_wait;
5bf970f9 592 t->to_files_info = inf_ptrace_files_info;
4b8a1a28 593 t->to_kill = inf_ptrace_kill;
5bf970f9 594 t->to_create_inferior = inf_ptrace_create_inferior;
735f54b4
MK
595#ifdef PT_GET_PROCESS_STATE
596 t->to_follow_fork = inf_ptrace_follow_fork;
e4ef629d
MK
597 t->to_post_startup_inferior = inf_ptrace_post_startup_inferior;
598 t->to_post_attach = inf_ptrace_post_attach;
735f54b4 599#endif
5bf970f9 600 t->to_mourn_inferior = inf_ptrace_mourn_inferior;
5bf970f9 601 t->to_thread_alive = inf_ptrace_thread_alive;
4b8a1a28 602 t->to_pid_to_str = normal_pid_to_str;
5bf970f9 603 t->to_stop = inf_ptrace_stop;
c7c14b96 604 t->to_xfer_partial = inf_ptrace_xfer_partial;
8785ced0 605
c7c14b96 606 ptrace_ops_hack = t;
8785ced0
MK
607 return t;
608}
609\f
610
4b8a1a28 611/* Pointer to a function that returns the offset within the user area
8785ced0 612 where a particular register is stored. */
7714d83a 613static CORE_ADDR (*inf_ptrace_register_u_offset)(struct gdbarch *, int, int);
8785ced0
MK
614
615/* Fetch register REGNUM from the inferior. */
616
617static void
56be3814 618inf_ptrace_fetch_register (struct regcache *regcache, int regnum)
8785ced0 619{
3b3b1423 620 struct gdbarch *gdbarch = get_regcache_arch (regcache);
8785ced0
MK
621 CORE_ADDR addr;
622 size_t size;
623 PTRACE_TYPE_RET *buf;
624 int pid, i;
625
7714d83a 626 /* This isn't really an address, but ptrace thinks of it as one. */
3b3b1423 627 addr = inf_ptrace_register_u_offset (gdbarch, regnum, 0);
8d4c1ba3 628 if (addr == (CORE_ADDR)-1
3b3b1423 629 || gdbarch_cannot_fetch_register (gdbarch, regnum))
10d6c8cd 630 {
56be3814 631 regcache_raw_supply (regcache, regnum, NULL);
10d6c8cd
DJ
632 return;
633 }
634
8785ced0 635 /* Cater for systems like GNU/Linux, that implement threads as
10d6c8cd 636 separate processes. */
8785ced0
MK
637 pid = ptid_get_lwp (inferior_ptid);
638 if (pid == 0)
639 pid = ptid_get_pid (inferior_ptid);
640
3b3b1423 641 size = register_size (gdbarch, regnum);
8785ced0
MK
642 gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
643 buf = alloca (size);
644
10d6c8cd 645 /* Read the register contents from the inferior a chunk at a time. */
8785ced0
MK
646 for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
647 {
648 errno = 0;
f7dd0ed7 649 buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, 0);
8785ced0 650 if (errno != 0)
4b8a1a28 651 error (_("Couldn't read register %s (#%d): %s."),
3b3b1423 652 gdbarch_register_name (gdbarch, regnum),
c9f4d572 653 regnum, safe_strerror (errno));
8785ced0
MK
654
655 addr += sizeof (PTRACE_TYPE_RET);
656 }
56be3814 657 regcache_raw_supply (regcache, regnum, buf);
8785ced0
MK
658}
659
660/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
661 for all registers. */
662
663static void
56be3814 664inf_ptrace_fetch_registers (struct regcache *regcache, int regnum)
8785ced0
MK
665{
666 if (regnum == -1)
3b3b1423
UW
667 for (regnum = 0;
668 regnum < gdbarch_num_regs (get_regcache_arch (regcache));
669 regnum++)
56be3814 670 inf_ptrace_fetch_register (regcache, regnum);
8785ced0 671 else
56be3814 672 inf_ptrace_fetch_register (regcache, regnum);
8785ced0
MK
673}
674
675/* Store register REGNUM into the inferior. */
676
677static void
56be3814 678inf_ptrace_store_register (const struct regcache *regcache, int regnum)
8785ced0 679{
3b3b1423 680 struct gdbarch *gdbarch = get_regcache_arch (regcache);
8785ced0
MK
681 CORE_ADDR addr;
682 size_t size;
683 PTRACE_TYPE_RET *buf;
684 int pid, i;
685
7714d83a 686 /* This isn't really an address, but ptrace thinks of it as one. */
3b3b1423 687 addr = inf_ptrace_register_u_offset (gdbarch, regnum, 1);
8d4c1ba3 688 if (addr == (CORE_ADDR)-1
3b3b1423 689 || gdbarch_cannot_store_register (gdbarch, regnum))
10d6c8cd
DJ
690 return;
691
8785ced0 692 /* Cater for systems like GNU/Linux, that implement threads as
10d6c8cd 693 separate processes. */
8785ced0
MK
694 pid = ptid_get_lwp (inferior_ptid);
695 if (pid == 0)
696 pid = ptid_get_pid (inferior_ptid);
697
3b3b1423 698 size = register_size (gdbarch, regnum);
8785ced0
MK
699 gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
700 buf = alloca (size);
701
10d6c8cd 702 /* Write the register contents into the inferior a chunk at a time. */
56be3814 703 regcache_raw_collect (regcache, regnum, buf);
8785ced0
MK
704 for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
705 {
706 errno = 0;
f7dd0ed7 707 ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, buf[i]);
8785ced0 708 if (errno != 0)
4b8a1a28 709 error (_("Couldn't write register %s (#%d): %s."),
3b3b1423 710 gdbarch_register_name (gdbarch, regnum),
c9f4d572 711 regnum, safe_strerror (errno));
8785ced0
MK
712
713 addr += sizeof (PTRACE_TYPE_RET);
714 }
715}
716
717/* Store register REGNUM back into the inferior. If REGNUM is -1, do
718 this for all registers. */
719
720void
56be3814 721inf_ptrace_store_registers (struct regcache *regcache, int regnum)
8785ced0
MK
722{
723 if (regnum == -1)
3b3b1423
UW
724 for (regnum = 0;
725 regnum < gdbarch_num_regs (get_regcache_arch (regcache));
726 regnum++)
56be3814 727 inf_ptrace_store_register (regcache, regnum);
8785ced0 728 else
56be3814 729 inf_ptrace_store_register (regcache, regnum);
8785ced0
MK
730}
731
732/* Create a "traditional" ptrace target. REGISTER_U_OFFSET should be
733 a function returning the offset within the user area where a
734 particular register is stored. */
735
736struct target_ops *
7714d83a
UW
737inf_ptrace_trad_target (CORE_ADDR (*register_u_offset)
738 (struct gdbarch *, int, int))
8785ced0
MK
739{
740 struct target_ops *t = inf_ptrace_target();
741
742 gdb_assert (register_u_offset);
743 inf_ptrace_register_u_offset = register_u_offset;
744 t->to_fetch_registers = inf_ptrace_fetch_registers;
745 t->to_store_registers = inf_ptrace_store_registers;
746
5bf970f9
AC
747 return t;
748}
This page took 0.327215 seconds and 4 git commands to generate.