GDB (API)
|
00001 /* Low-level child interface to ptrace. 00002 00003 Copyright (C) 1988-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "command.h" 00022 #include "inferior.h" 00023 #include "inflow.h" 00024 #include "terminal.h" 00025 #include "gdbcore.h" 00026 #include "regcache.h" 00027 00028 #include "gdb_assert.h" 00029 #include "gdb_string.h" 00030 #include "gdb_ptrace.h" 00031 #include "gdb_wait.h" 00032 #include <signal.h> 00033 00034 #include "inf-ptrace.h" 00035 #include "inf-child.h" 00036 #include "gdbthread.h" 00037 00038 00039 00040 #ifdef PT_GET_PROCESS_STATE 00041 00042 static int 00043 inf_ptrace_follow_fork (struct target_ops *ops, int follow_child, 00044 int detach_fork) 00045 { 00046 pid_t pid, fpid; 00047 ptrace_state_t pe; 00048 00049 pid = ptid_get_pid (inferior_ptid); 00050 00051 if (ptrace (PT_GET_PROCESS_STATE, pid, 00052 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) 00053 perror_with_name (("ptrace")); 00054 00055 gdb_assert (pe.pe_report_event == PTRACE_FORK); 00056 fpid = pe.pe_other_pid; 00057 00058 if (follow_child) 00059 { 00060 struct inferior *parent_inf, *child_inf; 00061 struct thread_info *tp; 00062 00063 parent_inf = find_inferior_pid (pid); 00064 00065 /* Add the child. */ 00066 child_inf = add_inferior (fpid); 00067 child_inf->attach_flag = parent_inf->attach_flag; 00068 copy_terminal_info (child_inf, parent_inf); 00069 child_inf->pspace = parent_inf->pspace; 00070 child_inf->aspace = parent_inf->aspace; 00071 00072 /* Before detaching from the parent, remove all breakpoints from 00073 it. */ 00074 remove_breakpoints (); 00075 00076 if (ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, 0) == -1) 00077 perror_with_name (("ptrace")); 00078 00079 /* Switch inferior_ptid out of the parent's way. */ 00080 inferior_ptid = pid_to_ptid (fpid); 00081 00082 /* Delete the parent. */ 00083 detach_inferior (pid); 00084 00085 add_thread_silent (inferior_ptid); 00086 } 00087 else 00088 { 00089 /* Breakpoints have already been detached from the child by 00090 infrun.c. */ 00091 00092 if (ptrace (PT_DETACH, fpid, (PTRACE_TYPE_ARG3)1, 0) == -1) 00093 perror_with_name (("ptrace")); 00094 } 00095 00096 return 0; 00097 } 00098 00099 #endif /* PT_GET_PROCESS_STATE */ 00100 00101 00102 /* Prepare to be traced. */ 00103 00104 static void 00105 inf_ptrace_me (void) 00106 { 00107 /* "Trace me, Dr. Memory!" */ 00108 ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3)0, 0); 00109 } 00110 00111 /* Start a new inferior Unix child process. EXEC_FILE is the file to 00112 run, ALLARGS is a string containing the arguments to the program. 00113 ENV is the environment vector to pass. If FROM_TTY is non-zero, be 00114 chatty about it. */ 00115 00116 static void 00117 inf_ptrace_create_inferior (struct target_ops *ops, 00118 char *exec_file, char *allargs, char **env, 00119 int from_tty) 00120 { 00121 int pid; 00122 00123 /* Do not change either targets above or the same target if already present. 00124 The reason is the target stack is shared across multiple inferiors. */ 00125 int ops_already_pushed = target_is_pushed (ops); 00126 struct cleanup *back_to = make_cleanup (null_cleanup, NULL); 00127 00128 if (! ops_already_pushed) 00129 { 00130 /* Clear possible core file with its process_stratum. */ 00131 push_target (ops); 00132 make_cleanup_unpush_target (ops); 00133 } 00134 00135 pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL, 00136 NULL, NULL, NULL); 00137 00138 discard_cleanups (back_to); 00139 00140 /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will 00141 be 1 or 2 depending on whether we're starting without or with a 00142 shell. */ 00143 startup_inferior (START_INFERIOR_TRAPS_EXPECTED); 00144 00145 /* On some targets, there must be some explicit actions taken after 00146 the inferior has been started up. */ 00147 target_post_startup_inferior (pid_to_ptid (pid)); 00148 } 00149 00150 #ifdef PT_GET_PROCESS_STATE 00151 00152 static void 00153 inf_ptrace_post_startup_inferior (ptid_t pid) 00154 { 00155 ptrace_event_t pe; 00156 00157 /* Set the initial event mask. */ 00158 memset (&pe, 0, sizeof pe); 00159 pe.pe_set_event |= PTRACE_FORK; 00160 if (ptrace (PT_SET_EVENT_MASK, ptid_get_pid (pid), 00161 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) 00162 perror_with_name (("ptrace")); 00163 } 00164 00165 #endif 00166 00167 /* Clean up a rotting corpse of an inferior after it died. */ 00168 00169 static void 00170 inf_ptrace_mourn_inferior (struct target_ops *ops) 00171 { 00172 int status; 00173 00174 /* Wait just one more time to collect the inferior's exit status. 00175 Do not check whether this succeeds though, since we may be 00176 dealing with a process that we attached to. Such a process will 00177 only report its exit status to its original parent. */ 00178 waitpid (ptid_get_pid (inferior_ptid), &status, 0); 00179 00180 generic_mourn_inferior (); 00181 00182 if (!have_inferiors ()) 00183 unpush_target (ops); 00184 } 00185 00186 /* Attach to the process specified by ARGS. If FROM_TTY is non-zero, 00187 be chatty about it. */ 00188 00189 static void 00190 inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty) 00191 { 00192 char *exec_file; 00193 pid_t pid; 00194 struct inferior *inf; 00195 00196 /* Do not change either targets above or the same target if already present. 00197 The reason is the target stack is shared across multiple inferiors. */ 00198 int ops_already_pushed = target_is_pushed (ops); 00199 struct cleanup *back_to = make_cleanup (null_cleanup, NULL); 00200 00201 pid = parse_pid_to_attach (args); 00202 00203 if (pid == getpid ()) /* Trying to masturbate? */ 00204 error (_("I refuse to debug myself!")); 00205 00206 if (! ops_already_pushed) 00207 { 00208 /* target_pid_to_str already uses the target. Also clear possible core 00209 file with its process_stratum. */ 00210 push_target (ops); 00211 make_cleanup_unpush_target (ops); 00212 } 00213 00214 if (from_tty) 00215 { 00216 exec_file = get_exec_file (0); 00217 00218 if (exec_file) 00219 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file, 00220 target_pid_to_str (pid_to_ptid (pid))); 00221 else 00222 printf_unfiltered (_("Attaching to %s\n"), 00223 target_pid_to_str (pid_to_ptid (pid))); 00224 00225 gdb_flush (gdb_stdout); 00226 } 00227 00228 #ifdef PT_ATTACH 00229 errno = 0; 00230 ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0); 00231 if (errno != 0) 00232 perror_with_name (("ptrace")); 00233 #else 00234 error (_("This system does not support attaching to a process")); 00235 #endif 00236 00237 inf = current_inferior (); 00238 inferior_appeared (inf, pid); 00239 inf->attach_flag = 1; 00240 inferior_ptid = pid_to_ptid (pid); 00241 00242 /* Always add a main thread. If some target extends the ptrace 00243 target, it should decorate the ptid later with more info. */ 00244 add_thread_silent (inferior_ptid); 00245 00246 discard_cleanups (back_to); 00247 } 00248 00249 #ifdef PT_GET_PROCESS_STATE 00250 00251 static void 00252 inf_ptrace_post_attach (int pid) 00253 { 00254 ptrace_event_t pe; 00255 00256 /* Set the initial event mask. */ 00257 memset (&pe, 0, sizeof pe); 00258 pe.pe_set_event |= PTRACE_FORK; 00259 if (ptrace (PT_SET_EVENT_MASK, pid, 00260 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) 00261 perror_with_name (("ptrace")); 00262 } 00263 00264 #endif 00265 00266 /* Detach from the inferior, optionally passing it the signal 00267 specified by ARGS. If FROM_TTY is non-zero, be chatty about it. */ 00268 00269 static void 00270 inf_ptrace_detach (struct target_ops *ops, char *args, int from_tty) 00271 { 00272 pid_t pid = ptid_get_pid (inferior_ptid); 00273 int sig = 0; 00274 00275 if (from_tty) 00276 { 00277 char *exec_file = get_exec_file (0); 00278 if (exec_file == 0) 00279 exec_file = ""; 00280 printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file, 00281 target_pid_to_str (pid_to_ptid (pid))); 00282 gdb_flush (gdb_stdout); 00283 } 00284 if (args) 00285 sig = atoi (args); 00286 00287 #ifdef PT_DETACH 00288 /* We'd better not have left any breakpoints in the program or it'll 00289 die when it hits one. Also note that this may only work if we 00290 previously attached to the inferior. It *might* work if we 00291 started the process ourselves. */ 00292 errno = 0; 00293 ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, sig); 00294 if (errno != 0) 00295 perror_with_name (("ptrace")); 00296 #else 00297 error (_("This system does not support detaching from a process")); 00298 #endif 00299 00300 inferior_ptid = null_ptid; 00301 detach_inferior (pid); 00302 00303 if (!have_inferiors ()) 00304 unpush_target (ops); 00305 } 00306 00307 /* Kill the inferior. */ 00308 00309 static void 00310 inf_ptrace_kill (struct target_ops *ops) 00311 { 00312 pid_t pid = ptid_get_pid (inferior_ptid); 00313 int status; 00314 00315 if (pid == 0) 00316 return; 00317 00318 ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0); 00319 waitpid (pid, &status, 0); 00320 00321 target_mourn_inferior (); 00322 } 00323 00324 /* Stop the inferior. */ 00325 00326 static void 00327 inf_ptrace_stop (ptid_t ptid) 00328 { 00329 /* Send a SIGINT to the process group. This acts just like the user 00330 typed a ^C on the controlling terminal. Note that using a 00331 negative process number in kill() is a System V-ism. The proper 00332 BSD interface is killpg(). However, all modern BSDs support the 00333 System V interface too. */ 00334 kill (-inferior_process_group (), SIGINT); 00335 } 00336 00337 /* Resume execution of thread PTID, or all threads if PTID is -1. If 00338 STEP is nonzero, single-step it. If SIGNAL is nonzero, give it 00339 that signal. */ 00340 00341 static void 00342 inf_ptrace_resume (struct target_ops *ops, 00343 ptid_t ptid, int step, enum gdb_signal signal) 00344 { 00345 pid_t pid = ptid_get_pid (ptid); 00346 int request; 00347 00348 if (pid == -1) 00349 /* Resume all threads. Traditionally ptrace() only supports 00350 single-threaded processes, so simply resume the inferior. */ 00351 pid = ptid_get_pid (inferior_ptid); 00352 00353 if (catch_syscall_enabled () > 0) 00354 request = PT_SYSCALL; 00355 else 00356 request = PT_CONTINUE; 00357 00358 if (step) 00359 { 00360 /* If this system does not support PT_STEP, a higher level 00361 function will have called single_step() to transmute the step 00362 request into a continue request (by setting breakpoints on 00363 all possible successor instructions), so we don't have to 00364 worry about that here. */ 00365 request = PT_STEP; 00366 } 00367 00368 /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from 00369 where it was. If GDB wanted it to start some other way, we have 00370 already written a new program counter value to the child. */ 00371 errno = 0; 00372 ptrace (request, pid, (PTRACE_TYPE_ARG3)1, gdb_signal_to_host (signal)); 00373 if (errno != 0) 00374 perror_with_name (("ptrace")); 00375 } 00376 00377 /* Wait for the child specified by PTID to do something. Return the 00378 process ID of the child, or MINUS_ONE_PTID in case of error; store 00379 the status in *OURSTATUS. */ 00380 00381 static ptid_t 00382 inf_ptrace_wait (struct target_ops *ops, 00383 ptid_t ptid, struct target_waitstatus *ourstatus, int options) 00384 { 00385 pid_t pid; 00386 int status, save_errno; 00387 00388 do 00389 { 00390 set_sigint_trap (); 00391 00392 do 00393 { 00394 pid = waitpid (ptid_get_pid (ptid), &status, 0); 00395 save_errno = errno; 00396 } 00397 while (pid == -1 && errno == EINTR); 00398 00399 clear_sigint_trap (); 00400 00401 if (pid == -1) 00402 { 00403 fprintf_unfiltered (gdb_stderr, 00404 _("Child process unexpectedly missing: %s.\n"), 00405 safe_strerror (save_errno)); 00406 00407 /* Claim it exited with unknown signal. */ 00408 ourstatus->kind = TARGET_WAITKIND_SIGNALLED; 00409 ourstatus->value.sig = GDB_SIGNAL_UNKNOWN; 00410 return inferior_ptid; 00411 } 00412 00413 /* Ignore terminated detached child processes. */ 00414 if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid)) 00415 pid = -1; 00416 } 00417 while (pid == -1); 00418 00419 #ifdef PT_GET_PROCESS_STATE 00420 if (WIFSTOPPED (status)) 00421 { 00422 ptrace_state_t pe; 00423 pid_t fpid; 00424 00425 if (ptrace (PT_GET_PROCESS_STATE, pid, 00426 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) 00427 perror_with_name (("ptrace")); 00428 00429 switch (pe.pe_report_event) 00430 { 00431 case PTRACE_FORK: 00432 ourstatus->kind = TARGET_WAITKIND_FORKED; 00433 ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid); 00434 00435 /* Make sure the other end of the fork is stopped too. */ 00436 fpid = waitpid (pe.pe_other_pid, &status, 0); 00437 if (fpid == -1) 00438 perror_with_name (("waitpid")); 00439 00440 if (ptrace (PT_GET_PROCESS_STATE, fpid, 00441 (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1) 00442 perror_with_name (("ptrace")); 00443 00444 gdb_assert (pe.pe_report_event == PTRACE_FORK); 00445 gdb_assert (pe.pe_other_pid == pid); 00446 if (fpid == ptid_get_pid (inferior_ptid)) 00447 { 00448 ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid); 00449 return pid_to_ptid (fpid); 00450 } 00451 00452 return pid_to_ptid (pid); 00453 } 00454 } 00455 #endif 00456 00457 store_waitstatus (ourstatus, status); 00458 return pid_to_ptid (pid); 00459 } 00460 00461 /* Attempt a transfer all LEN bytes starting at OFFSET between the 00462 inferior's OBJECT:ANNEX space and GDB's READBUF/WRITEBUF buffer. 00463 Return the number of bytes actually transferred. */ 00464 00465 static LONGEST 00466 inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object, 00467 const char *annex, gdb_byte *readbuf, 00468 const gdb_byte *writebuf, 00469 ULONGEST offset, LONGEST len) 00470 { 00471 pid_t pid = ptid_get_pid (inferior_ptid); 00472 00473 switch (object) 00474 { 00475 case TARGET_OBJECT_MEMORY: 00476 #ifdef PT_IO 00477 /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO 00478 request that promises to be much more efficient in reading 00479 and writing data in the traced process's address space. */ 00480 { 00481 struct ptrace_io_desc piod; 00482 00483 /* NOTE: We assume that there are no distinct address spaces 00484 for instruction and data. However, on OpenBSD 3.9 and 00485 later, PIOD_WRITE_D doesn't allow changing memory that's 00486 mapped read-only. Since most code segments will be 00487 read-only, using PIOD_WRITE_D will prevent us from 00488 inserting breakpoints, so we use PIOD_WRITE_I instead. */ 00489 piod.piod_op = writebuf ? PIOD_WRITE_I : PIOD_READ_D; 00490 piod.piod_addr = writebuf ? (void *) writebuf : readbuf; 00491 piod.piod_offs = (void *) (long) offset; 00492 piod.piod_len = len; 00493 00494 errno = 0; 00495 if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0) 00496 /* Return the actual number of bytes read or written. */ 00497 return piod.piod_len; 00498 /* If the PT_IO request is somehow not supported, fallback on 00499 using PT_WRITE_D/PT_READ_D. Otherwise we will return zero 00500 to indicate failure. */ 00501 if (errno != EINVAL) 00502 return 0; 00503 } 00504 #endif 00505 { 00506 union 00507 { 00508 PTRACE_TYPE_RET word; 00509 gdb_byte byte[sizeof (PTRACE_TYPE_RET)]; 00510 } buffer; 00511 ULONGEST rounded_offset; 00512 LONGEST partial_len; 00513 00514 /* Round the start offset down to the next long word 00515 boundary. */ 00516 rounded_offset = offset & -(ULONGEST) sizeof (PTRACE_TYPE_RET); 00517 00518 /* Since ptrace will transfer a single word starting at that 00519 rounded_offset the partial_len needs to be adjusted down to 00520 that (remember this function only does a single transfer). 00521 Should the required length be even less, adjust it down 00522 again. */ 00523 partial_len = (rounded_offset + sizeof (PTRACE_TYPE_RET)) - offset; 00524 if (partial_len > len) 00525 partial_len = len; 00526 00527 if (writebuf) 00528 { 00529 /* If OFFSET:PARTIAL_LEN is smaller than 00530 ROUNDED_OFFSET:WORDSIZE then a read/modify write will 00531 be needed. Read in the entire word. */ 00532 if (rounded_offset < offset 00533 || (offset + partial_len 00534 < rounded_offset + sizeof (PTRACE_TYPE_RET))) 00535 /* Need part of initial word -- fetch it. */ 00536 buffer.word = ptrace (PT_READ_I, pid, 00537 (PTRACE_TYPE_ARG3)(uintptr_t) 00538 rounded_offset, 0); 00539 00540 /* Copy data to be written over corresponding part of 00541 buffer. */ 00542 memcpy (buffer.byte + (offset - rounded_offset), 00543 writebuf, partial_len); 00544 00545 errno = 0; 00546 ptrace (PT_WRITE_D, pid, 00547 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset, 00548 buffer.word); 00549 if (errno) 00550 { 00551 /* Using the appropriate one (I or D) is necessary for 00552 Gould NP1, at least. */ 00553 errno = 0; 00554 ptrace (PT_WRITE_I, pid, 00555 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset, 00556 buffer.word); 00557 if (errno) 00558 return 0; 00559 } 00560 } 00561 00562 if (readbuf) 00563 { 00564 errno = 0; 00565 buffer.word = ptrace (PT_READ_I, pid, 00566 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset, 00567 0); 00568 if (errno) 00569 return 0; 00570 /* Copy appropriate bytes out of the buffer. */ 00571 memcpy (readbuf, buffer.byte + (offset - rounded_offset), 00572 partial_len); 00573 } 00574 00575 return partial_len; 00576 } 00577 00578 case TARGET_OBJECT_UNWIND_TABLE: 00579 return -1; 00580 00581 case TARGET_OBJECT_AUXV: 00582 #if defined (PT_IO) && defined (PIOD_READ_AUXV) 00583 /* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO 00584 request that allows us to read the auxilliary vector. Other 00585 BSD's may follow if they feel the need to support PIE. */ 00586 { 00587 struct ptrace_io_desc piod; 00588 00589 if (writebuf) 00590 return -1; 00591 piod.piod_op = PIOD_READ_AUXV; 00592 piod.piod_addr = readbuf; 00593 piod.piod_offs = (void *) (long) offset; 00594 piod.piod_len = len; 00595 00596 errno = 0; 00597 if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0) 00598 /* Return the actual number of bytes read or written. */ 00599 return piod.piod_len; 00600 } 00601 #endif 00602 return -1; 00603 00604 case TARGET_OBJECT_WCOOKIE: 00605 return -1; 00606 00607 default: 00608 return -1; 00609 } 00610 } 00611 00612 /* Return non-zero if the thread specified by PTID is alive. */ 00613 00614 static int 00615 inf_ptrace_thread_alive (struct target_ops *ops, ptid_t ptid) 00616 { 00617 /* ??? Is kill the right way to do this? */ 00618 return (kill (ptid_get_pid (ptid), 0) != -1); 00619 } 00620 00621 /* Print status information about what we're accessing. */ 00622 00623 static void 00624 inf_ptrace_files_info (struct target_ops *ignore) 00625 { 00626 struct inferior *inf = current_inferior (); 00627 00628 printf_filtered (_("\tUsing the running image of %s %s.\n"), 00629 inf->attach_flag ? "attached" : "child", 00630 target_pid_to_str (inferior_ptid)); 00631 } 00632 00633 static char * 00634 inf_ptrace_pid_to_str (struct target_ops *ops, ptid_t ptid) 00635 { 00636 return normal_pid_to_str (ptid); 00637 } 00638 00639 #if defined (PT_IO) && defined (PIOD_READ_AUXV) 00640 00641 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. 00642 Return 0 if *READPTR is already at the end of the buffer. 00643 Return -1 if there is insufficient buffer for a whole entry. 00644 Return 1 if an entry was read into *TYPEP and *VALP. */ 00645 00646 static int 00647 inf_ptrace_auxv_parse (struct target_ops *ops, gdb_byte **readptr, 00648 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) 00649 { 00650 struct type *int_type = builtin_type (target_gdbarch ())->builtin_int; 00651 struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; 00652 const int sizeof_auxv_type = TYPE_LENGTH (int_type); 00653 const int sizeof_auxv_val = TYPE_LENGTH (ptr_type); 00654 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00655 gdb_byte *ptr = *readptr; 00656 00657 if (endptr == ptr) 00658 return 0; 00659 00660 if (endptr - ptr < 2 * sizeof_auxv_val) 00661 return -1; 00662 00663 *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order); 00664 ptr += sizeof_auxv_val; /* Alignment. */ 00665 *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order); 00666 ptr += sizeof_auxv_val; 00667 00668 *readptr = ptr; 00669 return 1; 00670 } 00671 00672 #endif 00673 00674 /* Create a prototype ptrace target. The client can override it with 00675 local methods. */ 00676 00677 struct target_ops * 00678 inf_ptrace_target (void) 00679 { 00680 struct target_ops *t = inf_child_target (); 00681 00682 t->to_attach = inf_ptrace_attach; 00683 t->to_detach = inf_ptrace_detach; 00684 t->to_resume = inf_ptrace_resume; 00685 t->to_wait = inf_ptrace_wait; 00686 t->to_files_info = inf_ptrace_files_info; 00687 t->to_kill = inf_ptrace_kill; 00688 t->to_create_inferior = inf_ptrace_create_inferior; 00689 #ifdef PT_GET_PROCESS_STATE 00690 t->to_follow_fork = inf_ptrace_follow_fork; 00691 t->to_post_startup_inferior = inf_ptrace_post_startup_inferior; 00692 t->to_post_attach = inf_ptrace_post_attach; 00693 #endif 00694 t->to_mourn_inferior = inf_ptrace_mourn_inferior; 00695 t->to_thread_alive = inf_ptrace_thread_alive; 00696 t->to_pid_to_str = inf_ptrace_pid_to_str; 00697 t->to_stop = inf_ptrace_stop; 00698 t->to_xfer_partial = inf_ptrace_xfer_partial; 00699 #if defined (PT_IO) && defined (PIOD_READ_AUXV) 00700 t->to_auxv_parse = inf_ptrace_auxv_parse; 00701 #endif 00702 00703 return t; 00704 } 00705 00706 00707 /* Pointer to a function that returns the offset within the user area 00708 where a particular register is stored. */ 00709 static CORE_ADDR (*inf_ptrace_register_u_offset)(struct gdbarch *, int, int); 00710 00711 /* Fetch register REGNUM from the inferior. */ 00712 00713 static void 00714 inf_ptrace_fetch_register (struct regcache *regcache, int regnum) 00715 { 00716 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00717 CORE_ADDR addr; 00718 size_t size; 00719 PTRACE_TYPE_RET *buf; 00720 int pid, i; 00721 00722 /* This isn't really an address, but ptrace thinks of it as one. */ 00723 addr = inf_ptrace_register_u_offset (gdbarch, regnum, 0); 00724 if (addr == (CORE_ADDR)-1 00725 || gdbarch_cannot_fetch_register (gdbarch, regnum)) 00726 { 00727 regcache_raw_supply (regcache, regnum, NULL); 00728 return; 00729 } 00730 00731 /* Cater for systems like GNU/Linux, that implement threads as 00732 separate processes. */ 00733 pid = ptid_get_lwp (inferior_ptid); 00734 if (pid == 0) 00735 pid = ptid_get_pid (inferior_ptid); 00736 00737 size = register_size (gdbarch, regnum); 00738 gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0); 00739 buf = alloca (size); 00740 00741 /* Read the register contents from the inferior a chunk at a time. */ 00742 for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) 00743 { 00744 errno = 0; 00745 buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, 0); 00746 if (errno != 0) 00747 error (_("Couldn't read register %s (#%d): %s."), 00748 gdbarch_register_name (gdbarch, regnum), 00749 regnum, safe_strerror (errno)); 00750 00751 addr += sizeof (PTRACE_TYPE_RET); 00752 } 00753 regcache_raw_supply (regcache, regnum, buf); 00754 } 00755 00756 /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this 00757 for all registers. */ 00758 00759 static void 00760 inf_ptrace_fetch_registers (struct target_ops *ops, 00761 struct regcache *regcache, int regnum) 00762 { 00763 if (regnum == -1) 00764 for (regnum = 0; 00765 regnum < gdbarch_num_regs (get_regcache_arch (regcache)); 00766 regnum++) 00767 inf_ptrace_fetch_register (regcache, regnum); 00768 else 00769 inf_ptrace_fetch_register (regcache, regnum); 00770 } 00771 00772 /* Store register REGNUM into the inferior. */ 00773 00774 static void 00775 inf_ptrace_store_register (const struct regcache *regcache, int regnum) 00776 { 00777 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00778 CORE_ADDR addr; 00779 size_t size; 00780 PTRACE_TYPE_RET *buf; 00781 int pid, i; 00782 00783 /* This isn't really an address, but ptrace thinks of it as one. */ 00784 addr = inf_ptrace_register_u_offset (gdbarch, regnum, 1); 00785 if (addr == (CORE_ADDR)-1 00786 || gdbarch_cannot_store_register (gdbarch, regnum)) 00787 return; 00788 00789 /* Cater for systems like GNU/Linux, that implement threads as 00790 separate processes. */ 00791 pid = ptid_get_lwp (inferior_ptid); 00792 if (pid == 0) 00793 pid = ptid_get_pid (inferior_ptid); 00794 00795 size = register_size (gdbarch, regnum); 00796 gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0); 00797 buf = alloca (size); 00798 00799 /* Write the register contents into the inferior a chunk at a time. */ 00800 regcache_raw_collect (regcache, regnum, buf); 00801 for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) 00802 { 00803 errno = 0; 00804 ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, buf[i]); 00805 if (errno != 0) 00806 error (_("Couldn't write register %s (#%d): %s."), 00807 gdbarch_register_name (gdbarch, regnum), 00808 regnum, safe_strerror (errno)); 00809 00810 addr += sizeof (PTRACE_TYPE_RET); 00811 } 00812 } 00813 00814 /* Store register REGNUM back into the inferior. If REGNUM is -1, do 00815 this for all registers. */ 00816 00817 static void 00818 inf_ptrace_store_registers (struct target_ops *ops, 00819 struct regcache *regcache, int regnum) 00820 { 00821 if (regnum == -1) 00822 for (regnum = 0; 00823 regnum < gdbarch_num_regs (get_regcache_arch (regcache)); 00824 regnum++) 00825 inf_ptrace_store_register (regcache, regnum); 00826 else 00827 inf_ptrace_store_register (regcache, regnum); 00828 } 00829 00830 /* Create a "traditional" ptrace target. REGISTER_U_OFFSET should be 00831 a function returning the offset within the user area where a 00832 particular register is stored. */ 00833 00834 struct target_ops * 00835 inf_ptrace_trad_target (CORE_ADDR (*register_u_offset) 00836 (struct gdbarch *, int, int)) 00837 { 00838 struct target_ops *t = inf_ptrace_target(); 00839 00840 gdb_assert (register_u_offset); 00841 inf_ptrace_register_u_offset = register_u_offset; 00842 t->to_fetch_registers = inf_ptrace_fetch_registers; 00843 t->to_store_registers = inf_ptrace_store_registers; 00844 00845 return t; 00846 }