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