1 /* Low-level child interface to ptrace.
2 
3    Copyright (C) 1988-2024 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "command.h"
21 #include "inferior.h"
22 #include "terminal.h"
23 #include "gdbcore.h"
24 #include "regcache.h"
25 #include "nat/gdb_ptrace.h"
26 #include "gdbsupport/gdb_wait.h"
27 #include <signal.h>
28 
29 #include "inf-ptrace.h"
30 #include "inf-child.h"
31 #include "gdbthread.h"
32 #include "nat/fork-inferior.h"
33 #include "utils.h"
34 #include "gdbarch.h"
35 
36 
37 
38 static PTRACE_TYPE_RET
gdb_ptrace(PTRACE_TYPE_ARG1 request,ptid_t ptid,PTRACE_TYPE_ARG3 addr,PTRACE_TYPE_ARG4 data)39 gdb_ptrace (PTRACE_TYPE_ARG1 request, ptid_t ptid, PTRACE_TYPE_ARG3 addr,
40               PTRACE_TYPE_ARG4 data)
41 {
42 #ifdef __NetBSD__
43   /*
44    * On NetBSD the data field of PT_STEP contains the thread
45    * to be stepped; all other threads are continued if this value is > 0
46    */
47   if (request == PT_STEP)
48      data = ptid.lwp ();
49   return ptrace (request, ptid.pid (), addr, data);
50 #else
51   pid_t pid = get_ptrace_pid (ptid);
52   return ptrace (request, pid, addr, data);
53 #endif
54 }
55 
56 /* The event pipe registered as a waitable file in the event loop.  */
57 event_pipe inf_ptrace_target::m_event_pipe;
58 
~inf_ptrace_target()59 inf_ptrace_target::~inf_ptrace_target ()
60 {}
61 
62 
63 
64 /* Prepare to be traced.  */
65 
66 static void
inf_ptrace_me(void)67 inf_ptrace_me (void)
68 {
69   /* "Trace me, Dr. Memory!"  */
70   if (ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3) 0, 0) < 0)
71     trace_start_error_with_name ("ptrace");
72 }
73 
74 /* Start a new inferior Unix child process.  EXEC_FILE is the file to
75    run, ALLARGS is a string containing the arguments to the program.
76    ENV is the environment vector to pass.  If FROM_TTY is non-zero, be
77    chatty about it.  */
78 
79 void
create_inferior(const char * exec_file,const std::string & allargs,char ** env,int from_tty)80 inf_ptrace_target::create_inferior (const char *exec_file,
81                                             const std::string &allargs,
82                                             char **env, int from_tty)
83 {
84   inferior *inf = current_inferior ();
85 
86   /* Do not change either targets above or the same target if already present.
87      The reason is the target stack is shared across multiple inferiors.  */
88   int ops_already_pushed = inf->target_is_pushed (this);
89 
90   target_unpush_up unpusher;
91   if (! ops_already_pushed)
92     {
93       /* Clear possible core file with its process_stratum.  */
94       inf->push_target (this);
95       unpusher.reset (this);
96     }
97 
98   pid_t pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
99                                    NULL, NULL, NULL);
100 
101   ptid_t ptid (pid);
102   /* We have something that executes now.  We'll be running through
103      the shell at this point (if startup-with-shell is true), but the
104      pid shouldn't change.  */
105   thread_info *thr = add_thread_silent (this, ptid);
106   switch_to_thread (thr);
107 
108   unpusher.release ();
109 
110   gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED);
111 
112   /* On some targets, there must be some explicit actions taken after
113      the inferior has been started up.  */
114   post_startup_inferior (ptid);
115 }
116 
117 /* Clean up a rotting corpse of an inferior after it died.  */
118 
119 void
mourn_inferior()120 inf_ptrace_target::mourn_inferior ()
121 {
122   int status;
123 
124   /* Wait just one more time to collect the inferior's exit status.
125      Do not check whether this succeeds though, since we may be
126      dealing with a process that we attached to.  Such a process will
127      only report its exit status to its original parent.  */
128   waitpid (inferior_ptid.pid (), &status, 0);
129 
130   inf_child_target::mourn_inferior ();
131 }
132 
133 /* Attach to the process specified by ARGS.  If FROM_TTY is non-zero,
134    be chatty about it.  */
135 
136 void
attach(const char * args,int from_tty)137 inf_ptrace_target::attach (const char *args, int from_tty)
138 {
139   inferior *inf = current_inferior ();
140 
141   /* Do not change either targets above or the same target if already present.
142      The reason is the target stack is shared across multiple inferiors.  */
143   int ops_already_pushed = inf->target_is_pushed (this);
144 
145   pid_t pid = parse_pid_to_attach (args);
146 
147   if (pid == getpid ())                 /* Trying to masturbate?  */
148     error (_("I refuse to debug myself!"));
149 
150   target_unpush_up unpusher;
151   if (! ops_already_pushed)
152     {
153       /* target_pid_to_str already uses the target.  Also clear possible core
154            file with its process_stratum.  */
155       inf->push_target (this);
156       unpusher.reset (this);
157     }
158 
159   target_announce_attach (from_tty, pid);
160 
161 #ifdef PT_ATTACH
162   errno = 0;
163   ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
164   if (errno != 0)
165     perror_with_name (("ptrace"));
166 #else
167   error (_("This system does not support attaching to a process"));
168 #endif
169 
170   inferior_appeared (inf, pid);
171   inf->attach_flag = true;
172 
173   /* Always add a main thread.  If some target extends the ptrace
174      target, it should decorate the ptid later with more info.  */
175   thread_info *thr = add_thread_silent (this, ptid_t (pid));
176   switch_to_thread (thr);
177 
178   /* Don't consider the thread stopped until we've processed its
179      initial SIGSTOP stop.  */
180   set_executing (this, thr->ptid, true);
181 
182   unpusher.release ();
183 }
184 
185 /* Detach from the inferior.  If FROM_TTY is non-zero, be chatty about it.  */
186 
187 void
detach(inferior * inf,int from_tty)188 inf_ptrace_target::detach (inferior *inf, int from_tty)
189 {
190   pid_t pid = inferior_ptid.pid ();
191 
192   target_announce_detach (from_tty);
193 
194 #ifdef PT_DETACH
195   /* We'd better not have left any breakpoints in the program or it'll
196      die when it hits one.  Also note that this may only work if we
197      previously attached to the inferior.  It *might* work if we
198      started the process ourselves.  */
199   errno = 0;
200   ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, 0);
201   if (errno != 0)
202     perror_with_name (("ptrace"));
203 #else
204   error (_("This system does not support detaching from a process"));
205 #endif
206 
207   detach_success (inf);
208 }
209 
210 /* See inf-ptrace.h.  */
211 
212 void
detach_success(inferior * inf)213 inf_ptrace_target::detach_success (inferior *inf)
214 {
215   switch_to_no_thread ();
216   detach_inferior (inf);
217 
218   maybe_unpush_target ();
219 }
220 
221 /* Kill the inferior.  */
222 
223 void
kill()224 inf_ptrace_target::kill ()
225 {
226   pid_t pid = inferior_ptid.pid ();
227   int status;
228 
229   if (pid == 0)
230     return;
231 
232   ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0);
233   waitpid (pid, &status, 0);
234 
235   target_mourn_inferior (inferior_ptid);
236 }
237 
238 #ifndef __NetBSD__
239 
240 /* See inf-ptrace.h.  */
241 
242 pid_t
get_ptrace_pid(ptid_t ptid)243 get_ptrace_pid (ptid_t ptid)
244 {
245   pid_t pid;
246 
247   /* If we have an LWPID to work with, use it.  Otherwise, we're
248      dealing with a non-threaded program/target.  */
249   pid = ptid.lwp ();
250   if (pid == 0)
251     pid = ptid.pid ();
252   return pid;
253 }
254 #endif
255 
256 /* Resume execution of thread PTID, or all threads if PTID is -1.  If
257    STEP is nonzero, single-step it.  If SIGNAL is nonzero, give it
258    that signal.  */
259 
260 void
resume(ptid_t ptid,int step,enum gdb_signal signal)261 inf_ptrace_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
262 {
263   PTRACE_TYPE_ARG1 request;
264 
265   if (minus_one_ptid == ptid)
266     /* Resume all threads.  Traditionally ptrace() only supports
267        single-threaded processes, so simply resume the inferior.  */
268     ptid = ptid_t (inferior_ptid.pid ());
269 
270   if (catch_syscall_enabled ())
271     request = PT_SYSCALL;
272   else
273     request = PT_CONTINUE;
274 
275   if (step)
276     {
277       /* If this system does not support PT_STEP, a higher level
278            function will have called the appropriate functions to transmute the
279            step request into a continue request (by setting breakpoints on
280            all possible successor instructions), so we don't have to
281            worry about that here.  */
282       request = PT_STEP;
283     }
284 
285   /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
286      where it was.  If GDB wanted it to start some other way, we have
287      already written a new program counter value to the child.  */
288   errno = 0;
289   gdb_ptrace (request, ptid, (PTRACE_TYPE_ARG3)1, gdb_signal_to_host (signal));
290   if (errno != 0)
291     perror_with_name (("ptrace"));
292 }
293 
294 /* Wait for the child specified by PTID to do something.  Return the
295    process ID of the child, or MINUS_ONE_PTID in case of error; store
296    the status in *OURSTATUS.  */
297 
298 ptid_t
wait(ptid_t ptid,struct target_waitstatus * ourstatus,target_wait_flags target_options)299 inf_ptrace_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
300                                target_wait_flags target_options)
301 {
302   pid_t pid;
303   int options, status, save_errno;
304 
305   options = 0;
306   if (target_options & TARGET_WNOHANG)
307     options |= WNOHANG;
308 
309   do
310     {
311       set_sigint_trap ();
312 
313       do
314           {
315             pid = waitpid (ptid.pid (), &status, options);
316             save_errno = errno;
317           }
318       while (pid == -1 && errno == EINTR);
319 
320       clear_sigint_trap ();
321 
322       if (pid == 0)
323           {
324             gdb_assert (target_options & TARGET_WNOHANG);
325             ourstatus->set_ignore ();
326             return minus_one_ptid;
327           }
328 
329       if (pid == -1)
330           {
331             /* In async mode the SIGCHLD might have raced and triggered
332                a check for an event that had already been reported.  If
333                the event was the exit of the only remaining child,
334                waitpid() will fail with ECHILD.  */
335             if (ptid == minus_one_ptid && save_errno == ECHILD)
336               {
337                 ourstatus->set_no_resumed ();
338                 return minus_one_ptid;
339               }
340 
341             gdb_printf (gdb_stderr,
342                           _("Child process unexpectedly missing: %s.\n"),
343                           safe_strerror (save_errno));
344 
345             ourstatus->set_ignore ();
346             return minus_one_ptid;
347           }
348 
349       /* Ignore terminated detached child processes.  */
350       if (!WIFSTOPPED (status) && find_inferior_pid (this, pid) == nullptr)
351           pid = -1;
352     }
353   while (pid == -1);
354 
355   *ourstatus = host_status_to_waitstatus (status);
356 
357   return ptid_t (pid);
358 }
359 
360 /* Transfer data via ptrace into process PID's memory from WRITEBUF, or
361    from process PID's memory into READBUF.  Start at target address ADDR
362    and transfer up to LEN bytes.  Exactly one of READBUF and WRITEBUF must
363    be non-null.  Return the number of transferred bytes.  */
364 
365 static ULONGEST
inf_ptrace_peek_poke(ptid_t ptid,gdb_byte * readbuf,const gdb_byte * writebuf,ULONGEST addr,ULONGEST len)366 inf_ptrace_peek_poke (ptid_t ptid, gdb_byte *readbuf,
367                           const gdb_byte *writebuf,
368                           ULONGEST addr, ULONGEST len)
369 {
370   ULONGEST n;
371   unsigned int chunk;
372 
373   /* We transfer aligned words.  Thus align ADDR down to a word
374      boundary and determine how many bytes to skip at the
375      beginning.  */
376   ULONGEST skip = addr & (sizeof (PTRACE_TYPE_RET) - 1);
377   addr -= skip;
378 
379   for (n = 0;
380        n < len;
381        n += chunk, addr += sizeof (PTRACE_TYPE_RET), skip = 0)
382     {
383       /* Restrict to a chunk that fits in the current word.  */
384       chunk = std::min (sizeof (PTRACE_TYPE_RET) - skip, len - n);
385 
386       /* Use a union for type punning.  */
387       union
388       {
389           PTRACE_TYPE_RET word;
390           gdb_byte byte[sizeof (PTRACE_TYPE_RET)];
391       } buf;
392 
393       /* Read the word, also when doing a partial word write.  */
394       if (readbuf != NULL || chunk < sizeof (PTRACE_TYPE_RET))
395           {
396             errno = 0;
397             buf.word = gdb_ptrace (PT_READ_I, ptid,
398                                          (PTRACE_TYPE_ARG3)(uintptr_t) addr, 0);
399             if (errno != 0)
400               break;
401             if (readbuf != NULL)
402               memcpy (readbuf + n, buf.byte + skip, chunk);
403           }
404       if (writebuf != NULL)
405           {
406             memcpy (buf.byte + skip, writebuf + n, chunk);
407             errno = 0;
408             gdb_ptrace (PT_WRITE_D, ptid, (PTRACE_TYPE_ARG3)(uintptr_t) addr,
409                       buf.word);
410             if (errno != 0)
411               {
412                 /* Using the appropriate one (I or D) is necessary for
413                      Gould NP1, at least.  */
414                 errno = 0;
415                 gdb_ptrace (PT_WRITE_I, ptid, (PTRACE_TYPE_ARG3)(uintptr_t) addr,
416                                 buf.word);
417                 if (errno != 0)
418                     break;
419               }
420           }
421     }
422 
423   return n;
424 }
425 
426 /* Implement the to_xfer_partial target_ops method.  */
427 
428 enum target_xfer_status
xfer_partial(enum target_object object,const char * annex,gdb_byte * readbuf,const gdb_byte * writebuf,ULONGEST offset,ULONGEST len,ULONGEST * xfered_len)429 inf_ptrace_target::xfer_partial (enum target_object object,
430                                          const char *annex, gdb_byte *readbuf,
431                                          const gdb_byte *writebuf,
432                                          ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
433 {
434   ptid_t ptid = inferior_ptid;
435 
436   switch (object)
437     {
438     case TARGET_OBJECT_MEMORY:
439 #ifdef PT_IO
440       /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO
441            request that promises to be much more efficient in reading
442            and writing data in the traced process's address space.  */
443       {
444           struct ptrace_io_desc piod;
445 
446           /* NOTE: We assume that there are no distinct address spaces
447              for instruction and data.  However, on OpenBSD 3.9 and
448              later, PIOD_WRITE_D doesn't allow changing memory that's
449              mapped read-only.  Since most code segments will be
450              read-only, using PIOD_WRITE_D will prevent us from
451              inserting breakpoints, so we use PIOD_WRITE_I instead.  */
452           piod.piod_op = writebuf ? PIOD_WRITE_I : PIOD_READ_D;
453           piod.piod_addr = writebuf ? (void *) writebuf : readbuf;
454           piod.piod_offs = (void *) (long) offset;
455           piod.piod_len = len;
456 
457           errno = 0;
458           if (gdb_ptrace (PT_IO, ptid, (caddr_t)&piod, 0) == 0)
459             {
460               /* Return the actual number of bytes read or written.  */
461               *xfered_len = piod.piod_len;
462               return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
463             }
464           /* If the PT_IO request is somehow not supported, fallback on
465              using PT_WRITE_D/PT_READ_D.  Otherwise we will return zero
466              to indicate failure.  */
467           if (errno != EINVAL)
468             return TARGET_XFER_EOF;
469       }
470 #endif
471       *xfered_len = inf_ptrace_peek_poke (ptid, readbuf, writebuf,
472                                                     offset, len);
473       return *xfered_len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
474 
475     case TARGET_OBJECT_UNWIND_TABLE:
476       return TARGET_XFER_E_IO;
477 
478     case TARGET_OBJECT_AUXV:
479 #if defined (PT_IO) && defined (PIOD_READ_AUXV)
480       /* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO
481            request that allows us to read the auxilliary vector.  Other
482            BSD's may follow if they feel the need to support PIE.  */
483       {
484           struct ptrace_io_desc piod;
485 
486           if (writebuf)
487             return TARGET_XFER_E_IO;
488           piod.piod_op = PIOD_READ_AUXV;
489           piod.piod_addr = readbuf;
490           piod.piod_offs = (void *) (long) offset;
491           piod.piod_len = len;
492 
493           errno = 0;
494           if (gdb_ptrace (PT_IO, ptid, (caddr_t)&piod, 0) == 0)
495             {
496               /* Return the actual number of bytes read or written.  */
497               *xfered_len = piod.piod_len;
498               return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
499             }
500       }
501 #endif
502       return TARGET_XFER_E_IO;
503 
504     case TARGET_OBJECT_WCOOKIE:
505       return TARGET_XFER_E_IO;
506 
507     default:
508       return TARGET_XFER_E_IO;
509     }
510 }
511 
512 /* Return non-zero if the thread specified by PTID is alive.  */
513 
514 bool
thread_alive(ptid_t ptid)515 inf_ptrace_target::thread_alive (ptid_t ptid)
516 {
517   /* ??? Is kill the right way to do this?  */
518   return (::kill (ptid.pid (), 0) != -1);
519 }
520 
521 /* Print status information about what we're accessing.  */
522 
523 void
files_info()524 inf_ptrace_target::files_info ()
525 {
526   struct inferior *inf = current_inferior ();
527 
528   gdb_printf (_("\tUsing the running image of %s %s.\n"),
529                 inf->attach_flag ? "attached" : "child",
530                 target_pid_to_str (ptid_t (inf->pid)).c_str ());
531 }
532 
533 std::string
pid_to_str(ptid_t ptid)534 inf_ptrace_target::pid_to_str (ptid_t ptid)
535 {
536   return normal_pid_to_str (ptid);
537 }
538 
539 /* Implement the "close" target method.  */
540 
541 void
close()542 inf_ptrace_target::close ()
543 {
544   /* Unregister from the event loop.  */
545   if (is_async_p ())
546     async (false);
547 
548   inf_child_target::close ();
549 }
550