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