[AArch64] Removing unused functions.
[deliverable/binutils-gdb.git] / gdb / inf-ptrace.c
CommitLineData
2c4a536d 1/* Low-level child interface to ptrace.
5bf970f9 2
32d0add0 3 Copyright (C) 1988-2015 Free Software Foundation, Inc.
5bf970f9
AC
4
5 This file is part of GDB.
6
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
5bf970f9
AC
10 (at your option) any later version.
11
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.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
5bf970f9
AC
19
20#include "defs.h"
5bf970f9 21#include "command.h"
2c4a536d
MK
22#include "inferior.h"
23#include "inflow.h"
191c4426 24#include "terminal.h"
5bf970f9 25#include "gdbcore.h"
8785ced0 26#include "regcache.h"
2c4a536d 27#include "gdb_ptrace.h"
34a17005 28#include "gdb_wait.h"
5bf970f9
AC
29#include <signal.h>
30
2c0b251b 31#include "inf-ptrace.h"
2c4a536d 32#include "inf-child.h"
af990527 33#include "gdbthread.h"
2c4a536d 34
c7c14b96
MK
35\f
36
735f54b4
MK
37#ifdef PT_GET_PROCESS_STATE
38
d83ad864
DB
39/* Target hook for follow_fork. On entry and at return inferior_ptid is
40 the ptid of the followed inferior. */
41
735f54b4 42static int
07107ca6
LM
43inf_ptrace_follow_fork (struct target_ops *ops, int follow_child,
44 int detach_fork)
735f54b4 45{
d83ad864 46 if (!follow_child)
735f54b4 47 {
ebf3aa72
MK
48 struct thread_info *tp = inferior_thread ();
49 pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid);
191c4426 50
b242c3c2
PA
51 /* Breakpoints have already been detached from the child by
52 infrun.c. */
735f54b4 53
d83ad864 54 if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
735f54b4
MK
55 perror_with_name (("ptrace"));
56 }
57
58 return 0;
59}
60
61#endif /* PT_GET_PROCESS_STATE */
62\f
63
4b8a1a28 64/* Prepare to be traced. */
5bf970f9
AC
65
66static void
c7c14b96 67inf_ptrace_me (void)
5bf970f9 68{
c7c14b96 69 /* "Trace me, Dr. Memory!" */
4b8a1a28 70 ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3)0, 0);
5bf970f9
AC
71}
72
136d6dae
VP
73/* Start a new inferior Unix child process. EXEC_FILE is the file to
74 run, ALLARGS is a string containing the arguments to the program.
75 ENV is the environment vector to pass. If FROM_TTY is non-zero, be
76 chatty about it. */
5bf970f9
AC
77
78static void
136d6dae
VP
79inf_ptrace_create_inferior (struct target_ops *ops,
80 char *exec_file, char *allargs, char **env,
81 int from_tty)
5bf970f9 82{
136d6dae
VP
83 int pid;
84
c0edd9ed
JK
85 /* Do not change either targets above or the same target if already present.
86 The reason is the target stack is shared across multiple inferiors. */
87 int ops_already_pushed = target_is_pushed (ops);
25f43500 88 struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
c0edd9ed
JK
89
90 if (! ops_already_pushed)
91 {
92 /* Clear possible core file with its process_stratum. */
93 push_target (ops);
25f43500 94 make_cleanup_unpush_target (ops);
c0edd9ed
JK
95 }
96
136d6dae 97 pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
e69860f1 98 NULL, NULL, NULL);
136d6dae 99
25f43500 100 discard_cleanups (back_to);
5bf970f9 101
c7c14b96
MK
102 startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
103
104 /* On some targets, there must be some explicit actions taken after
105 the inferior has been started up. */
106 target_post_startup_inferior (pid_to_ptid (pid));
5bf970f9
AC
107}
108
e4ef629d
MK
109#ifdef PT_GET_PROCESS_STATE
110
111static void
2e97a79e 112inf_ptrace_post_startup_inferior (struct target_ops *self, ptid_t pid)
e4ef629d
MK
113{
114 ptrace_event_t pe;
115
116 /* Set the initial event mask. */
117 memset (&pe, 0, sizeof pe);
118 pe.pe_set_event |= PTRACE_FORK;
119 if (ptrace (PT_SET_EVENT_MASK, ptid_get_pid (pid),
120 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
121 perror_with_name (("ptrace"));
122}
123
124#endif
125
4b8a1a28
MK
126/* Clean up a rotting corpse of an inferior after it died. */
127
c7c14b96 128static void
136d6dae 129inf_ptrace_mourn_inferior (struct target_ops *ops)
5bf970f9 130{
4b8a1a28
MK
131 int status;
132
133 /* Wait just one more time to collect the inferior's exit status.
f010475d 134 Do not check whether this succeeds though, since we may be
4b8a1a28 135 dealing with a process that we attached to. Such a process will
3d450bdd 136 only report its exit status to its original parent. */
4b8a1a28
MK
137 waitpid (ptid_get_pid (inferior_ptid), &status, 0);
138
c1ee2fb3 139 inf_child_mourn_inferior (ops);
5bf970f9
AC
140}
141
4b8a1a28
MK
142/* Attach to the process specified by ARGS. If FROM_TTY is non-zero,
143 be chatty about it. */
5bf970f9
AC
144
145static void
c0939df1 146inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty)
5bf970f9
AC
147{
148 char *exec_file;
4b8a1a28 149 pid_t pid;
181e7f93 150 struct inferior *inf;
5bf970f9 151
c0edd9ed
JK
152 /* Do not change either targets above or the same target if already present.
153 The reason is the target stack is shared across multiple inferiors. */
154 int ops_already_pushed = target_is_pushed (ops);
25f43500 155 struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
c0edd9ed 156
74164c56 157 pid = parse_pid_to_attach (args);
5bf970f9 158
f6ffd89b 159 if (pid == getpid ()) /* Trying to masturbate? */
8a3fe4f8 160 error (_("I refuse to debug myself!"));
5bf970f9 161
c0edd9ed
JK
162 if (! ops_already_pushed)
163 {
164 /* target_pid_to_str already uses the target. Also clear possible core
165 file with its process_stratum. */
166 push_target (ops);
25f43500 167 make_cleanup_unpush_target (ops);
c0edd9ed
JK
168 }
169
5bf970f9
AC
170 if (from_tty)
171 {
4b8a1a28 172 exec_file = get_exec_file (0);
5bf970f9
AC
173
174 if (exec_file)
a3f17187 175 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
5bf970f9
AC
176 target_pid_to_str (pid_to_ptid (pid)));
177 else
a3f17187 178 printf_unfiltered (_("Attaching to %s\n"),
5bf970f9
AC
179 target_pid_to_str (pid_to_ptid (pid)));
180
181 gdb_flush (gdb_stdout);
182 }
183
6e1e94ea
MK
184#ifdef PT_ATTACH
185 errno = 0;
4b8a1a28 186 ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
6e1e94ea 187 if (errno != 0)
e2e0b3e5 188 perror_with_name (("ptrace"));
6e1e94ea 189#else
8a3fe4f8 190 error (_("This system does not support attaching to a process"));
6e1e94ea 191#endif
5bf970f9 192
6c95b8df
PA
193 inf = current_inferior ();
194 inferior_appeared (inf, pid);
181e7f93 195 inf->attach_flag = 1;
6c95b8df 196 inferior_ptid = pid_to_ptid (pid);
7f9f62ba 197
af990527
PA
198 /* Always add a main thread. If some target extends the ptrace
199 target, it should decorate the ptid later with more info. */
200 add_thread_silent (inferior_ptid);
201
25f43500 202 discard_cleanups (back_to);
5bf970f9
AC
203}
204
e4ef629d
MK
205#ifdef PT_GET_PROCESS_STATE
206
460fac3c 207static void
f045800c 208inf_ptrace_post_attach (struct target_ops *self, int pid)
e4ef629d
MK
209{
210 ptrace_event_t pe;
211
212 /* Set the initial event mask. */
213 memset (&pe, 0, sizeof pe);
214 pe.pe_set_event |= PTRACE_FORK;
215 if (ptrace (PT_SET_EVENT_MASK, pid,
216 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
217 perror_with_name (("ptrace"));
218}
219
220#endif
221
4b8a1a28 222/* Detach from the inferior, optionally passing it the signal
f010475d 223 specified by ARGS. If FROM_TTY is non-zero, be chatty about it. */
5bf970f9
AC
224
225static void
52554a0e 226inf_ptrace_detach (struct target_ops *ops, const char *args, int from_tty)
5bf970f9 227{
4b8a1a28 228 pid_t pid = ptid_get_pid (inferior_ptid);
6e1e94ea 229 int sig = 0;
5bf970f9
AC
230
231 if (from_tty)
232 {
233 char *exec_file = get_exec_file (0);
234 if (exec_file == 0)
235 exec_file = "";
a3f17187 236 printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
5bf970f9
AC
237 target_pid_to_str (pid_to_ptid (pid)));
238 gdb_flush (gdb_stdout);
239 }
240 if (args)
6e1e94ea 241 sig = atoi (args);
5bf970f9 242
6e1e94ea 243#ifdef PT_DETACH
4b8a1a28 244 /* We'd better not have left any breakpoints in the program or it'll
f010475d 245 die when it hits one. Also note that this may only work if we
4b8a1a28
MK
246 previously attached to the inferior. It *might* work if we
247 started the process ourselves. */
6e1e94ea 248 errno = 0;
4b8a1a28 249 ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, sig);
6e1e94ea 250 if (errno != 0)
e2e0b3e5 251 perror_with_name (("ptrace"));
6e1e94ea 252#else
8a3fe4f8 253 error (_("This system does not support detaching from a process"));
6e1e94ea 254#endif
5bf970f9
AC
255
256 inferior_ptid = null_ptid;
7f9f62ba 257 detach_inferior (pid);
7a7d3353 258
6a3cb8e8 259 inf_child_maybe_unpush_target (ops);
5bf970f9
AC
260}
261
4b8a1a28
MK
262/* Kill the inferior. */
263
5bf970f9 264static void
7d85a9c0 265inf_ptrace_kill (struct target_ops *ops)
5bf970f9 266{
4b8a1a28 267 pid_t pid = ptid_get_pid (inferior_ptid);
c7c14b96 268 int status;
c7c14b96
MK
269
270 if (pid == 0)
271 return;
272
4b8a1a28
MK
273 ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0);
274 waitpid (pid, &status, 0);
275
c7c14b96 276 target_mourn_inferior ();
5bf970f9
AC
277}
278
4b8a1a28 279/* Stop the inferior. */
c7c14b96 280
5bf970f9 281static void
1eab8a48 282inf_ptrace_stop (struct target_ops *self, ptid_t ptid)
5bf970f9 283{
4b8a1a28
MK
284 /* Send a SIGINT to the process group. This acts just like the user
285 typed a ^C on the controlling terminal. Note that using a
286 negative process number in kill() is a System V-ism. The proper
287 BSD interface is killpg(). However, all modern BSDs support the
288 System V interface too. */
7e1789f5 289 kill (-inferior_process_group (), SIGINT);
5bf970f9
AC
290}
291
90ad5e1d
PA
292/* Return which PID to pass to ptrace in order to observe/control the
293 tracee identified by PTID. */
294
295static pid_t
296get_ptrace_pid (ptid_t ptid)
297{
298 pid_t pid;
299
300 /* If we have an LWPID to work with, use it. Otherwise, we're
301 dealing with a non-threaded program/target. */
302 pid = ptid_get_lwp (ptid);
303 if (pid == 0)
304 pid = ptid_get_pid (ptid);
305 return pid;
306}
307
4b8a1a28
MK
308/* Resume execution of thread PTID, or all threads if PTID is -1. If
309 STEP is nonzero, single-step it. If SIGNAL is nonzero, give it
310 that signal. */
5bf970f9
AC
311
312static void
28439f5e 313inf_ptrace_resume (struct target_ops *ops,
2ea28649 314 ptid_t ptid, int step, enum gdb_signal signal)
5bf970f9 315{
90ad5e1d 316 pid_t pid;
a96d9b2e 317 int request;
c7c14b96 318
90ad5e1d 319 if (ptid_equal (minus_one_ptid, ptid))
4b8a1a28
MK
320 /* Resume all threads. Traditionally ptrace() only supports
321 single-threaded processes, so simply resume the inferior. */
c1593e4f 322 pid = ptid_get_pid (inferior_ptid);
90ad5e1d
PA
323 else
324 pid = get_ptrace_pid (ptid);
c7c14b96 325
a96d9b2e
SDJ
326 if (catch_syscall_enabled () > 0)
327 request = PT_SYSCALL;
328 else
329 request = PT_CONTINUE;
330
c7c14b96
MK
331 if (step)
332 {
333 /* If this system does not support PT_STEP, a higher level
334 function will have called single_step() to transmute the step
335 request into a continue request (by setting breakpoints on
336 all possible successor instructions), so we don't have to
337 worry about that here. */
338 request = PT_STEP;
339 }
340
341 /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
342 where it was. If GDB wanted it to start some other way, we have
4b8a1a28 343 already written a new program counter value to the child. */
c7c14b96 344 errno = 0;
2ea28649 345 ptrace (request, pid, (PTRACE_TYPE_ARG3)1, gdb_signal_to_host (signal));
c7c14b96
MK
346 if (errno != 0)
347 perror_with_name (("ptrace"));
5bf970f9
AC
348}
349
4b8a1a28
MK
350/* Wait for the child specified by PTID to do something. Return the
351 process ID of the child, or MINUS_ONE_PTID in case of error; store
352 the status in *OURSTATUS. */
5bf970f9 353
c7c14b96 354static ptid_t
117de6a9 355inf_ptrace_wait (struct target_ops *ops,
47608cb1 356 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
5bf970f9 357{
4b8a1a28
MK
358 pid_t pid;
359 int status, save_errno;
5bf970f9 360
c7c14b96
MK
361 do
362 {
4b8a1a28 363 set_sigint_trap ();
5bf970f9 364
4b8a1a28
MK
365 do
366 {
367 pid = waitpid (ptid_get_pid (ptid), &status, 0);
368 save_errno = errno;
369 }
370 while (pid == -1 && errno == EINTR);
5bf970f9 371
c7c14b96 372 clear_sigint_trap ();
5bf970f9 373
c7c14b96
MK
374 if (pid == -1)
375 {
c7c14b96 376 fprintf_unfiltered (gdb_stderr,
4b8a1a28 377 _("Child process unexpectedly missing: %s.\n"),
c7c14b96
MK
378 safe_strerror (save_errno));
379
380 /* Claim it exited with unknown signal. */
381 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
a493e3e2 382 ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
fb66883a 383 return inferior_ptid;
c7c14b96
MK
384 }
385
4b8a1a28
MK
386 /* Ignore terminated detached child processes. */
387 if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid))
388 pid = -1;
c7c14b96 389 }
4b8a1a28 390 while (pid == -1);
c7c14b96 391
735f54b4
MK
392#ifdef PT_GET_PROCESS_STATE
393 if (WIFSTOPPED (status))
394 {
395 ptrace_state_t pe;
396 pid_t fpid;
397
398 if (ptrace (PT_GET_PROCESS_STATE, pid,
399 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
400 perror_with_name (("ptrace"));
401
402 switch (pe.pe_report_event)
403 {
404 case PTRACE_FORK:
405 ourstatus->kind = TARGET_WAITKIND_FORKED;
3a3e9ee3 406 ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid);
735f54b4
MK
407
408 /* Make sure the other end of the fork is stopped too. */
409 fpid = waitpid (pe.pe_other_pid, &status, 0);
410 if (fpid == -1)
411 perror_with_name (("waitpid"));
412
413 if (ptrace (PT_GET_PROCESS_STATE, fpid,
414 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
415 perror_with_name (("ptrace"));
416
417 gdb_assert (pe.pe_report_event == PTRACE_FORK);
418 gdb_assert (pe.pe_other_pid == pid);
419 if (fpid == ptid_get_pid (inferior_ptid))
420 {
3a3e9ee3 421 ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid);
735f54b4
MK
422 return pid_to_ptid (fpid);
423 }
424
425 return pid_to_ptid (pid);
426 }
427 }
428#endif
429
c7c14b96
MK
430 store_waitstatus (ourstatus, status);
431 return pid_to_ptid (pid);
5bf970f9
AC
432}
433
edcc890f 434/* Implement the to_xfer_partial target_ops method. */
5bf970f9 435
9b409511 436static enum target_xfer_status
5bf970f9 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,
9b409511 440 ULONGEST offset, ULONGEST len, ULONGEST *xfered_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)
9b409511 467 {
9b409511 468 /* Return the actual number of bytes read or written. */
493443a4
MK
469 *xfered_len = piod.piod_len;
470 return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
9b409511 471 }
f929a579
AC
472 /* If the PT_IO request is somehow not supported, fallback on
473 using PT_WRITE_D/PT_READ_D. Otherwise we will return zero
474 to indicate failure. */
475 if (errno != EINVAL)
9b409511 476 return TARGET_XFER_EOF;
f929a579
AC
477 }
478#endif
479 {
480 union
481 {
482 PTRACE_TYPE_RET word;
4b8a1a28 483 gdb_byte byte[sizeof (PTRACE_TYPE_RET)];
f929a579
AC
484 } buffer;
485 ULONGEST rounded_offset;
9b409511 486 ULONGEST partial_len;
4b8a1a28 487
cb85a953
AC
488 /* Round the start offset down to the next long word
489 boundary. */
f929a579 490 rounded_offset = offset & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
4b8a1a28 491
cb85a953
AC
492 /* Since ptrace will transfer a single word starting at that
493 rounded_offset the partial_len needs to be adjusted down to
494 that (remember this function only does a single transfer).
495 Should the required length be even less, adjust it down
496 again. */
497 partial_len = (rounded_offset + sizeof (PTRACE_TYPE_RET)) - offset;
498 if (partial_len > len)
f929a579 499 partial_len = len;
4b8a1a28 500
f929a579
AC
501 if (writebuf)
502 {
cb85a953
AC
503 /* If OFFSET:PARTIAL_LEN is smaller than
504 ROUNDED_OFFSET:WORDSIZE then a read/modify write will
505 be needed. Read in the entire word. */
f929a579 506 if (rounded_offset < offset
cb85a953
AC
507 || (offset + partial_len
508 < rounded_offset + sizeof (PTRACE_TYPE_RET)))
f929a579 509 /* Need part of initial word -- fetch it. */
4b8a1a28 510 buffer.word = ptrace (PT_READ_I, pid,
f7dd0ed7
UW
511 (PTRACE_TYPE_ARG3)(uintptr_t)
512 rounded_offset, 0);
4b8a1a28 513
f929a579
AC
514 /* Copy data to be written over corresponding part of
515 buffer. */
f6ffd89b
MK
516 memcpy (buffer.byte + (offset - rounded_offset),
517 writebuf, partial_len);
4b8a1a28 518
f929a579 519 errno = 0;
4b8a1a28 520 ptrace (PT_WRITE_D, pid,
f7dd0ed7
UW
521 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
522 buffer.word);
f929a579
AC
523 if (errno)
524 {
525 /* Using the appropriate one (I or D) is necessary for
526 Gould NP1, at least. */
527 errno = 0;
4b8a1a28 528 ptrace (PT_WRITE_I, pid,
f7dd0ed7
UW
529 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
530 buffer.word);
f929a579 531 if (errno)
9b409511 532 return TARGET_XFER_EOF;
f929a579
AC
533 }
534 }
4b8a1a28 535
f929a579
AC
536 if (readbuf)
537 {
538 errno = 0;
4b8a1a28 539 buffer.word = ptrace (PT_READ_I, pid,
f7dd0ed7
UW
540 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
541 0);
f929a579 542 if (errno)
9b409511 543 return TARGET_XFER_EOF;
f929a579
AC
544 /* Copy appropriate bytes out of the buffer. */
545 memcpy (readbuf, buffer.byte + (offset - rounded_offset),
546 partial_len);
547 }
4b8a1a28 548
9b409511
YQ
549 *xfered_len = partial_len;
550 return TARGET_XFER_OK;
f929a579 551 }
5bf970f9
AC
552
553 case TARGET_OBJECT_UNWIND_TABLE:
2ed4b548 554 return TARGET_XFER_E_IO;
5bf970f9
AC
555
556 case TARGET_OBJECT_AUXV:
e8ace1c0
MK
557#if defined (PT_IO) && defined (PIOD_READ_AUXV)
558 /* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO
559 request that allows us to read the auxilliary vector. Other
560 BSD's may follow if they feel the need to support PIE. */
561 {
562 struct ptrace_io_desc piod;
563
564 if (writebuf)
2ed4b548 565 return TARGET_XFER_E_IO;
e8ace1c0
MK
566 piod.piod_op = PIOD_READ_AUXV;
567 piod.piod_addr = readbuf;
568 piod.piod_offs = (void *) (long) offset;
569 piod.piod_len = len;
570
571 errno = 0;
572 if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0)
9b409511 573 {
9b409511 574 /* Return the actual number of bytes read or written. */
493443a4
MK
575 *xfered_len = piod.piod_len;
576 return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
9b409511 577 }
e8ace1c0
MK
578 }
579#endif
2ed4b548 580 return TARGET_XFER_E_IO;
5bf970f9
AC
581
582 case TARGET_OBJECT_WCOOKIE:
2ed4b548 583 return TARGET_XFER_E_IO;
5bf970f9
AC
584
585 default:
2ed4b548 586 return TARGET_XFER_E_IO;
5bf970f9
AC
587 }
588}
589
4b8a1a28 590/* Return non-zero if the thread specified by PTID is alive. */
c7c14b96
MK
591
592static int
28439f5e 593inf_ptrace_thread_alive (struct target_ops *ops, ptid_t ptid)
c7c14b96 594{
4b8a1a28
MK
595 /* ??? Is kill the right way to do this? */
596 return (kill (ptid_get_pid (ptid), 0) != -1);
c7c14b96
MK
597}
598
599/* Print status information about what we're accessing. */
600
601static void
602inf_ptrace_files_info (struct target_ops *ignore)
603{
181e7f93
PA
604 struct inferior *inf = current_inferior ();
605
4b8a1a28 606 printf_filtered (_("\tUsing the running image of %s %s.\n"),
181e7f93 607 inf->attach_flag ? "attached" : "child",
4b8a1a28 608 target_pid_to_str (inferior_ptid));
5bf970f9
AC
609}
610
117de6a9
PA
611static char *
612inf_ptrace_pid_to_str (struct target_ops *ops, ptid_t ptid)
613{
614 return normal_pid_to_str (ptid);
615}
616
e8ace1c0
MK
617#if defined (PT_IO) && defined (PIOD_READ_AUXV)
618
619/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
620 Return 0 if *READPTR is already at the end of the buffer.
621 Return -1 if there is insufficient buffer for a whole entry.
622 Return 1 if an entry was read into *TYPEP and *VALP. */
623
624static int
625inf_ptrace_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
626 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
627{
f5656ead
TT
628 struct type *int_type = builtin_type (target_gdbarch ())->builtin_int;
629 struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
e8ace1c0
MK
630 const int sizeof_auxv_type = TYPE_LENGTH (int_type);
631 const int sizeof_auxv_val = TYPE_LENGTH (ptr_type);
f5656ead 632 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
e8ace1c0
MK
633 gdb_byte *ptr = *readptr;
634
635 if (endptr == ptr)
636 return 0;
637
638 if (endptr - ptr < 2 * sizeof_auxv_val)
639 return -1;
640
641 *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order);
642 ptr += sizeof_auxv_val; /* Alignment. */
643 *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order);
644 ptr += sizeof_auxv_val;
645
646 *readptr = ptr;
647 return 1;
648}
649
650#endif
651
8785ced0
MK
652/* Create a prototype ptrace target. The client can override it with
653 local methods. */
654
5bf970f9
AC
655struct target_ops *
656inf_ptrace_target (void)
657{
658 struct target_ops *t = inf_child_target ();
8785ced0 659
5bf970f9 660 t->to_attach = inf_ptrace_attach;
5bf970f9
AC
661 t->to_detach = inf_ptrace_detach;
662 t->to_resume = inf_ptrace_resume;
663 t->to_wait = inf_ptrace_wait;
5bf970f9 664 t->to_files_info = inf_ptrace_files_info;
4b8a1a28 665 t->to_kill = inf_ptrace_kill;
5bf970f9 666 t->to_create_inferior = inf_ptrace_create_inferior;
735f54b4
MK
667#ifdef PT_GET_PROCESS_STATE
668 t->to_follow_fork = inf_ptrace_follow_fork;
e4ef629d
MK
669 t->to_post_startup_inferior = inf_ptrace_post_startup_inferior;
670 t->to_post_attach = inf_ptrace_post_attach;
735f54b4 671#endif
5bf970f9 672 t->to_mourn_inferior = inf_ptrace_mourn_inferior;
5bf970f9 673 t->to_thread_alive = inf_ptrace_thread_alive;
117de6a9 674 t->to_pid_to_str = inf_ptrace_pid_to_str;
5bf970f9 675 t->to_stop = inf_ptrace_stop;
c7c14b96 676 t->to_xfer_partial = inf_ptrace_xfer_partial;
e8ace1c0
MK
677#if defined (PT_IO) && defined (PIOD_READ_AUXV)
678 t->to_auxv_parse = inf_ptrace_auxv_parse;
679#endif
8785ced0
MK
680
681 return t;
682}
683\f
684
4b8a1a28 685/* Pointer to a function that returns the offset within the user area
8785ced0 686 where a particular register is stored. */
7714d83a 687static CORE_ADDR (*inf_ptrace_register_u_offset)(struct gdbarch *, int, int);
8785ced0
MK
688
689/* Fetch register REGNUM from the inferior. */
690
691static void
56be3814 692inf_ptrace_fetch_register (struct regcache *regcache, int regnum)
8785ced0 693{
3b3b1423 694 struct gdbarch *gdbarch = get_regcache_arch (regcache);
8785ced0
MK
695 CORE_ADDR addr;
696 size_t size;
697 PTRACE_TYPE_RET *buf;
698 int pid, i;
699
7714d83a 700 /* This isn't really an address, but ptrace thinks of it as one. */
3b3b1423 701 addr = inf_ptrace_register_u_offset (gdbarch, regnum, 0);
8d4c1ba3 702 if (addr == (CORE_ADDR)-1
3b3b1423 703 || gdbarch_cannot_fetch_register (gdbarch, regnum))
10d6c8cd 704 {
56be3814 705 regcache_raw_supply (regcache, regnum, NULL);
10d6c8cd
DJ
706 return;
707 }
708
8785ced0 709 /* Cater for systems like GNU/Linux, that implement threads as
10d6c8cd 710 separate processes. */
8785ced0
MK
711 pid = ptid_get_lwp (inferior_ptid);
712 if (pid == 0)
713 pid = ptid_get_pid (inferior_ptid);
714
3b3b1423 715 size = register_size (gdbarch, regnum);
8785ced0
MK
716 gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
717 buf = alloca (size);
718
10d6c8cd 719 /* Read the register contents from the inferior a chunk at a time. */
8785ced0
MK
720 for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
721 {
722 errno = 0;
f7dd0ed7 723 buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, 0);
8785ced0 724 if (errno != 0)
4b8a1a28 725 error (_("Couldn't read register %s (#%d): %s."),
3b3b1423 726 gdbarch_register_name (gdbarch, regnum),
c9f4d572 727 regnum, safe_strerror (errno));
8785ced0
MK
728
729 addr += sizeof (PTRACE_TYPE_RET);
730 }
56be3814 731 regcache_raw_supply (regcache, regnum, buf);
8785ced0
MK
732}
733
734/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
735 for all registers. */
736
737static void
28439f5e
PA
738inf_ptrace_fetch_registers (struct target_ops *ops,
739 struct regcache *regcache, int regnum)
8785ced0
MK
740{
741 if (regnum == -1)
3b3b1423
UW
742 for (regnum = 0;
743 regnum < gdbarch_num_regs (get_regcache_arch (regcache));
744 regnum++)
56be3814 745 inf_ptrace_fetch_register (regcache, regnum);
8785ced0 746 else
56be3814 747 inf_ptrace_fetch_register (regcache, regnum);
8785ced0
MK
748}
749
750/* Store register REGNUM into the inferior. */
751
752static void
56be3814 753inf_ptrace_store_register (const struct regcache *regcache, int regnum)
8785ced0 754{
3b3b1423 755 struct gdbarch *gdbarch = get_regcache_arch (regcache);
8785ced0
MK
756 CORE_ADDR addr;
757 size_t size;
758 PTRACE_TYPE_RET *buf;
759 int pid, i;
760
7714d83a 761 /* This isn't really an address, but ptrace thinks of it as one. */
3b3b1423 762 addr = inf_ptrace_register_u_offset (gdbarch, regnum, 1);
8d4c1ba3 763 if (addr == (CORE_ADDR)-1
3b3b1423 764 || gdbarch_cannot_store_register (gdbarch, regnum))
10d6c8cd
DJ
765 return;
766
8785ced0 767 /* Cater for systems like GNU/Linux, that implement threads as
10d6c8cd 768 separate processes. */
8785ced0
MK
769 pid = ptid_get_lwp (inferior_ptid);
770 if (pid == 0)
771 pid = ptid_get_pid (inferior_ptid);
772
3b3b1423 773 size = register_size (gdbarch, regnum);
8785ced0
MK
774 gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
775 buf = alloca (size);
776
10d6c8cd 777 /* Write the register contents into the inferior a chunk at a time. */
56be3814 778 regcache_raw_collect (regcache, regnum, buf);
8785ced0
MK
779 for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
780 {
781 errno = 0;
f7dd0ed7 782 ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, buf[i]);
8785ced0 783 if (errno != 0)
4b8a1a28 784 error (_("Couldn't write register %s (#%d): %s."),
3b3b1423 785 gdbarch_register_name (gdbarch, regnum),
c9f4d572 786 regnum, safe_strerror (errno));
8785ced0
MK
787
788 addr += sizeof (PTRACE_TYPE_RET);
789 }
790}
791
792/* Store register REGNUM back into the inferior. If REGNUM is -1, do
793 this for all registers. */
794
2c0b251b 795static void
28439f5e
PA
796inf_ptrace_store_registers (struct target_ops *ops,
797 struct regcache *regcache, int regnum)
8785ced0
MK
798{
799 if (regnum == -1)
3b3b1423
UW
800 for (regnum = 0;
801 regnum < gdbarch_num_regs (get_regcache_arch (regcache));
802 regnum++)
56be3814 803 inf_ptrace_store_register (regcache, regnum);
8785ced0 804 else
56be3814 805 inf_ptrace_store_register (regcache, regnum);
8785ced0
MK
806}
807
808/* Create a "traditional" ptrace target. REGISTER_U_OFFSET should be
809 a function returning the offset within the user area where a
810 particular register is stored. */
811
812struct target_ops *
7714d83a
UW
813inf_ptrace_trad_target (CORE_ADDR (*register_u_offset)
814 (struct gdbarch *, int, int))
8785ced0
MK
815{
816 struct target_ops *t = inf_ptrace_target();
817
818 gdb_assert (register_u_offset);
819 inf_ptrace_register_u_offset = register_u_offset;
820 t->to_fetch_registers = inf_ptrace_fetch_registers;
821 t->to_store_registers = inf_ptrace_store_registers;
822
5bf970f9
AC
823 return t;
824}
This page took 0.858681 seconds and 4 git commands to generate.