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