GDB (API)
/home/stan/gdb/src/gdb/inf-ptrace.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines