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