1 /* Base/prototype target for default child (native) targets.
3 Copyright (C) 1988-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 /* This file provides a common base class/target that all native
21 target implementations extend, by calling inf_child_target to get a
22 new prototype target and then overriding target methods as
31 #include "inf-child.h"
32 #include "gdbsupport/fileio.h"
33 #include "gdbsupport/agent.h"
34 #include "gdbsupport/gdb_wait.h"
35 #include "gdbsupport/filestuff.h"
37 #include <sys/types.h>
41 static const target_info inf_child_target_info
= {
44 N_("Native process (started by the \"run\" command).")
48 inf_child_target::info () const
50 return inf_child_target_info
;
53 /* See inf-child.h. */
56 host_status_to_waitstatus (int hoststatus
)
58 if (WIFEXITED (hoststatus
))
59 return target_waitstatus ().set_exited (WEXITSTATUS (hoststatus
));
60 else if (!WIFSTOPPED (hoststatus
))
61 return target_waitstatus ().set_signalled
62 (gdb_signal_from_host (WTERMSIG (hoststatus
)));
64 return target_waitstatus ().set_stopped
65 (gdb_signal_from_host (WSTOPSIG (hoststatus
)));
68 inf_child_target::~inf_child_target ()
72 inf_child_target::post_attach (int pid
)
74 /* This target doesn't require a meaningful "post attach" operation
78 /* Get ready to modify the registers array. On machines which store
79 individual registers, this doesn't need to do anything. On
80 machines which store all the registers in one fell swoop, this
81 makes sure that registers contains all the registers from the
82 program being debugged. */
85 inf_child_target::prepare_to_store (struct regcache
*regcache
)
90 inf_child_target::supports_terminal_ours ()
96 inf_child_target::terminal_init ()
98 child_terminal_init (this);
102 inf_child_target::terminal_inferior ()
104 child_terminal_inferior (this);
108 inf_child_target::terminal_save_inferior ()
110 child_terminal_save_inferior (this);
114 inf_child_target::terminal_ours_for_output ()
116 child_terminal_ours_for_output (this);
120 inf_child_target::terminal_ours ()
122 child_terminal_ours (this);
126 inf_child_target::interrupt ()
128 child_interrupt (this);
132 inf_child_target::pass_ctrlc ()
134 child_pass_ctrlc (this);
138 inf_child_target::terminal_info (const char *args
, int from_tty
)
140 child_terminal_info (this, args
, from_tty
);
143 /* True if the user did "target native". In that case, we won't
144 unpush the child target automatically when the last inferior is
146 static int inf_child_explicitly_opened
;
148 /* See inf-child.h. */
151 inf_child_open_target (const char *arg
, int from_tty
)
153 target_ops
*target
= get_native_target ();
155 /* There's always only ever one native target, and if we get here,
156 it better be an inf-child target. */
157 gdb_assert (dynamic_cast<inf_child_target
*> (target
) != NULL
);
159 target_preopen (from_tty
);
160 current_inferior ()->push_target (target
);
161 inf_child_explicitly_opened
= 1;
163 gdb_printf ("Done. Use the \"run\" command to start a process.\n");
166 /* Implement the to_disconnect target_ops method. */
169 inf_child_target::disconnect (const char *args
, int from_tty
)
172 error (_("Argument given to \"disconnect\"."));
174 /* This offers to detach/kill current inferiors, and then pops all
176 target_preopen (from_tty
);
179 /* Implement the to_close target_ops method. */
182 inf_child_target::close ()
184 /* In case we were forcibly closed. */
185 inf_child_explicitly_opened
= 0;
189 inf_child_target::mourn_inferior ()
191 generic_mourn_inferior ();
192 maybe_unpush_target ();
195 /* See inf-child.h. */
198 inf_child_target::maybe_unpush_target ()
200 if (!inf_child_explicitly_opened
)
201 current_inferior ()->unpush_target (this);
205 inf_child_target::can_run ()
211 inf_child_target::can_create_inferior ()
217 inf_child_target::can_attach ()
223 inf_child_target::pid_to_exec_file (int pid
)
225 /* This target doesn't support translation of a process ID to the
226 filename of the executable file. */
230 /* Implementation of to_fileio_open. */
233 inf_child_target::fileio_open (struct inferior
*inf
, const char *filename
,
234 int flags
, int mode
, int warn_if_slow
,
235 fileio_error
*target_errno
)
241 if (fileio_to_host_openflags (flags
, &nat_flags
) == -1
242 || fileio_to_host_mode (mode
, &nat_mode
) == -1)
244 *target_errno
= FILEIO_EINVAL
;
248 fd
= gdb_open_cloexec (filename
, nat_flags
, nat_mode
).release ();
250 *target_errno
= host_to_fileio_error (errno
);
255 /* Implementation of to_fileio_pwrite. */
258 inf_child_target::fileio_pwrite (int fd
, const gdb_byte
*write_buf
, int len
,
259 ULONGEST offset
, fileio_error
*target_errno
)
264 ret
= pwrite (fd
, write_buf
, len
, (long) offset
);
268 /* If we have no pwrite or it failed for this file, use lseek/write. */
271 ret
= lseek (fd
, (long) offset
, SEEK_SET
);
273 ret
= write (fd
, write_buf
, len
);
277 *target_errno
= host_to_fileio_error (errno
);
282 /* Implementation of to_fileio_pread. */
285 inf_child_target::fileio_pread (int fd
, gdb_byte
*read_buf
, int len
,
286 ULONGEST offset
, fileio_error
*target_errno
)
291 ret
= pread (fd
, read_buf
, len
, (long) offset
);
295 /* If we have no pread or it failed for this file, use lseek/read. */
298 ret
= lseek (fd
, (long) offset
, SEEK_SET
);
300 ret
= read (fd
, read_buf
, len
);
304 *target_errno
= host_to_fileio_error (errno
);
309 /* Implementation of to_fileio_fstat. */
312 inf_child_target::fileio_fstat (int fd
, struct stat
*sb
, fileio_error
*target_errno
)
316 ret
= fstat (fd
, sb
);
318 *target_errno
= host_to_fileio_error (errno
);
323 /* Implementation of to_fileio_close. */
326 inf_child_target::fileio_close (int fd
, fileio_error
*target_errno
)
332 *target_errno
= host_to_fileio_error (errno
);
337 /* Implementation of to_fileio_unlink. */
340 inf_child_target::fileio_unlink (struct inferior
*inf
, const char *filename
,
341 fileio_error
*target_errno
)
345 ret
= unlink (filename
);
347 *target_errno
= host_to_fileio_error (errno
);
352 /* Implementation of to_fileio_readlink. */
354 std::optional
<std::string
>
355 inf_child_target::fileio_readlink (struct inferior
*inf
, const char *filename
,
356 fileio_error
*target_errno
)
358 /* We support readlink only on systems that also provide a compile-time
359 maximum path length (PATH_MAX), at least for now. */
360 #if defined (PATH_MAX)
364 len
= readlink (filename
, buf
, sizeof buf
);
367 *target_errno
= host_to_fileio_error (errno
);
371 return std::string (buf
, len
);
373 *target_errno
= FILEIO_ENOSYS
;
379 inf_child_target::use_agent (bool use
)
381 if (agent_loaded_p ())
391 inf_child_target::can_use_agent ()
393 return agent_loaded_p ();
397 inf_child_target::follow_exec (inferior
*follow_inf
, ptid_t ptid
,
398 const char *execd_pathname
)
400 inferior
*orig_inf
= current_inferior ();
402 process_stratum_target::follow_exec (follow_inf
, ptid
, execd_pathname
);
404 if (orig_inf
!= follow_inf
)
406 /* If the target was implicitly push in the original inferior, unpush
408 scoped_restore_current_thread restore_thread
;
409 switch_to_inferior_no_thread (orig_inf
);
410 maybe_unpush_target ();
414 /* See inf-child.h. */
417 add_inf_child_target (inf_child_target
*target
)
419 set_native_target (target
);
420 add_target (inf_child_target_info
, inf_child_open_target
);