]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/inf-child.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / inf-child.c
CommitLineData
f1aea813 1/* Base/prototype target for default child (native) targets.
5bf970f9 2
1d506c26 3 Copyright (C) 1988-2024 Free Software Foundation, Inc.
5bf970f9
AC
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
5bf970f9
AC
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
5bf970f9 19
f1aea813
PA
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
23 necessary. */
24
5bf970f9
AC
25#include "defs.h"
26#include "regcache.h"
27#include "memattr.h"
28#include "symtab.h"
29#include "target.h"
30#include "inferior.h"
53ce3c39 31#include <sys/stat.h>
2c0b251b 32#include "inf-child.h"
268a13a5
TT
33#include "gdbsupport/fileio.h"
34#include "gdbsupport/agent.h"
35#include "gdbsupport/gdb_wait.h"
36#include "gdbsupport/filestuff.h"
7313baad
UW
37
38#include <sys/types.h>
7313baad
UW
39#include <fcntl.h>
40#include <unistd.h>
5bf970f9 41
d9f719f1
PA
42static const target_info inf_child_target_info = {
43 "native",
44 N_("Native process"),
45 N_("Native process (started by the \"run\" command).")
46};
47
48const target_info &
49inf_child_target::info () const
50{
51 return inf_child_target_info;
52}
53
7509b829
SM
54/* See inf-child.h. */
55
56target_waitstatus
57host_status_to_waitstatus (int hoststatus)
dab06dbe
PA
58{
59 if (WIFEXITED (hoststatus))
7509b829 60 return target_waitstatus ().set_exited (WEXITSTATUS (hoststatus));
dab06dbe 61 else if (!WIFSTOPPED (hoststatus))
7509b829
SM
62 return target_waitstatus ().set_signalled
63 (gdb_signal_from_host (WTERMSIG (hoststatus)));
dab06dbe 64 else
7509b829
SM
65 return target_waitstatus ().set_stopped
66 (gdb_signal_from_host (WSTOPSIG (hoststatus)));
dab06dbe
PA
67}
68
f6ac5f3d
PA
69inf_child_target::~inf_child_target ()
70{}
5bf970f9 71
f6ac5f3d
PA
72void
73inf_child_target::post_attach (int pid)
5bf970f9 74{
f1aea813
PA
75 /* This target doesn't require a meaningful "post attach" operation
76 by a debugger. */
5bf970f9
AC
77}
78
79/* Get ready to modify the registers array. On machines which store
80 individual registers, this doesn't need to do anything. On
81 machines which store all the registers in one fell swoop, this
82 makes sure that registers contains all the registers from the
83 program being debugged. */
84
f6ac5f3d
PA
85void
86inf_child_target::prepare_to_store (struct regcache *regcache)
5bf970f9
AC
87{
88}
89
f6ac5f3d
PA
90bool
91inf_child_target::supports_terminal_ours ()
92{
93 return true;
94}
95
96void
97inf_child_target::terminal_init ()
98{
99 child_terminal_init (this);
100}
101
102void
103inf_child_target::terminal_inferior ()
104{
105 child_terminal_inferior (this);
106}
107
ae739fe7
SM
108void
109inf_child_target::terminal_save_inferior ()
110{
111 child_terminal_save_inferior (this);
112}
113
f6ac5f3d
PA
114void
115inf_child_target::terminal_ours_for_output ()
116{
117 child_terminal_ours_for_output (this);
118}
119
120void
121inf_child_target::terminal_ours ()
122{
123 child_terminal_ours (this);
124}
125
126void
127inf_child_target::interrupt ()
128{
129 child_interrupt (this);
130}
131
132void
133inf_child_target::pass_ctrlc ()
134{
135 child_pass_ctrlc (this);
136}
137
138void
139inf_child_target::terminal_info (const char *args, int from_tty)
140{
141 child_terminal_info (this, args, from_tty);
142}
143
6a3cb8e8
PA
144/* True if the user did "target native". In that case, we won't
145 unpush the child target automatically when the last inferior is
146 gone. */
147static int inf_child_explicitly_opened;
148
149/* See inf-child.h. */
150
151void
d9f719f1 152inf_child_open_target (const char *arg, int from_tty)
6a3cb8e8 153{
d9f719f1
PA
154 target_ops *target = get_native_target ();
155
156 /* There's always only ever one native target, and if we get here,
157 it better be an inf-child target. */
158 gdb_assert (dynamic_cast<inf_child_target *> (target) != NULL);
159
6a3cb8e8 160 target_preopen (from_tty);
02980c56 161 current_inferior ()->push_target (target);
6a3cb8e8
PA
162 inf_child_explicitly_opened = 1;
163 if (from_tty)
6cb06a8c 164 gdb_printf ("Done. Use the \"run\" command to start a process.\n");
6a3cb8e8
PA
165}
166
6a3cb8e8
PA
167/* Implement the to_disconnect target_ops method. */
168
f6ac5f3d
PA
169void
170inf_child_target::disconnect (const char *args, int from_tty)
6a3cb8e8
PA
171{
172 if (args != NULL)
173 error (_("Argument given to \"disconnect\"."));
174
175 /* This offers to detach/kill current inferiors, and then pops all
176 targets. */
177 target_preopen (from_tty);
178}
179
180/* Implement the to_close target_ops method. */
181
f6ac5f3d
PA
182void
183inf_child_target::close ()
6a3cb8e8
PA
184{
185 /* In case we were forcibly closed. */
186 inf_child_explicitly_opened = 0;
187}
188
c1ee2fb3 189void
f6ac5f3d 190inf_child_target::mourn_inferior ()
c1ee2fb3
PA
191{
192 generic_mourn_inferior ();
f6ac5f3d 193 maybe_unpush_target ();
c1ee2fb3
PA
194}
195
6a3cb8e8
PA
196/* See inf-child.h. */
197
198void
f6ac5f3d 199inf_child_target::maybe_unpush_target ()
6a3cb8e8 200{
5b6d1e4f 201 if (!inf_child_explicitly_opened)
fadf6add 202 current_inferior ()->unpush_target (this);
5bf970f9
AC
203}
204
57810aa7 205bool
f6ac5f3d 206inf_child_target::can_run ()
5bf970f9 207{
57810aa7 208 return true;
5bf970f9
AC
209}
210
f6ac5f3d
PA
211bool
212inf_child_target::can_create_inferior ()
5bf970f9 213{
f6ac5f3d
PA
214 return true;
215}
216
217bool
218inf_child_target::can_attach ()
219{
220 return true;
5bf970f9
AC
221}
222
0e90c441 223const char *
f6ac5f3d 224inf_child_target::pid_to_exec_file (int pid)
5bf970f9 225{
f1aea813
PA
226 /* This target doesn't support translation of a process ID to the
227 filename of the executable file. */
5bf970f9
AC
228 return NULL;
229}
230
12e2a5fd
GB
231/* Implementation of to_fileio_open. */
232
f6ac5f3d
PA
233int
234inf_child_target::fileio_open (struct inferior *inf, const char *filename,
235 int flags, int mode, int warn_if_slow,
b872057a 236 fileio_error *target_errno)
7313baad
UW
237{
238 int nat_flags;
3ac2e371 239 mode_t nat_mode;
7313baad
UW
240 int fd;
241
3ac2e371
GB
242 if (fileio_to_host_openflags (flags, &nat_flags) == -1
243 || fileio_to_host_mode (mode, &nat_mode) == -1)
7313baad
UW
244 {
245 *target_errno = FILEIO_EINVAL;
246 return -1;
247 }
248
13084383 249 fd = gdb_open_cloexec (filename, nat_flags, nat_mode).release ();
7313baad 250 if (fd == -1)
7823a941 251 *target_errno = host_to_fileio_error (errno);
7313baad
UW
252
253 return fd;
254}
255
12e2a5fd
GB
256/* Implementation of to_fileio_pwrite. */
257
f6ac5f3d
PA
258int
259inf_child_target::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
b872057a 260 ULONGEST offset, fileio_error *target_errno)
7313baad
UW
261{
262 int ret;
263
264#ifdef HAVE_PWRITE
265 ret = pwrite (fd, write_buf, len, (long) offset);
266#else
7c3270ae 267 ret = -1;
7313baad 268#endif
7c3270ae
UW
269 /* If we have no pwrite or it failed for this file, use lseek/write. */
270 if (ret == -1)
271 {
272 ret = lseek (fd, (long) offset, SEEK_SET);
273 if (ret != -1)
274 ret = write (fd, write_buf, len);
275 }
7313baad
UW
276
277 if (ret == -1)
7823a941 278 *target_errno = host_to_fileio_error (errno);
7313baad
UW
279
280 return ret;
281}
282
12e2a5fd
GB
283/* Implementation of to_fileio_pread. */
284
f6ac5f3d
PA
285int
286inf_child_target::fileio_pread (int fd, gdb_byte *read_buf, int len,
b872057a 287 ULONGEST offset, fileio_error *target_errno)
7313baad
UW
288{
289 int ret;
290
291#ifdef HAVE_PREAD
292 ret = pread (fd, read_buf, len, (long) offset);
293#else
7c3270ae 294 ret = -1;
7313baad 295#endif
7c3270ae
UW
296 /* If we have no pread or it failed for this file, use lseek/read. */
297 if (ret == -1)
298 {
299 ret = lseek (fd, (long) offset, SEEK_SET);
300 if (ret != -1)
301 ret = read (fd, read_buf, len);
302 }
7313baad
UW
303
304 if (ret == -1)
7823a941 305 *target_errno = host_to_fileio_error (errno);
7313baad
UW
306
307 return ret;
308}
309
9b15c1f0 310/* Implementation of to_fileio_fstat. */
12e2a5fd 311
f6ac5f3d 312int
b872057a 313inf_child_target::fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno)
9b15c1f0
GB
314{
315 int ret;
316
317 ret = fstat (fd, sb);
318 if (ret == -1)
7823a941 319 *target_errno = host_to_fileio_error (errno);
9b15c1f0
GB
320
321 return ret;
322}
323
12e2a5fd
GB
324/* Implementation of to_fileio_close. */
325
f6ac5f3d 326int
b872057a 327inf_child_target::fileio_close (int fd, fileio_error *target_errno)
7313baad
UW
328{
329 int ret;
330
f6ac5f3d 331 ret = ::close (fd);
7313baad 332 if (ret == -1)
7823a941 333 *target_errno = host_to_fileio_error (errno);
7313baad
UW
334
335 return ret;
336}
337
12e2a5fd
GB
338/* Implementation of to_fileio_unlink. */
339
f6ac5f3d
PA
340int
341inf_child_target::fileio_unlink (struct inferior *inf, const char *filename,
b872057a 342 fileio_error *target_errno)
7313baad
UW
343{
344 int ret;
345
346 ret = unlink (filename);
347 if (ret == -1)
7823a941 348 *target_errno = host_to_fileio_error (errno);
7313baad
UW
349
350 return ret;
351}
352
12e2a5fd
GB
353/* Implementation of to_fileio_readlink. */
354
6b09f134 355std::optional<std::string>
f6ac5f3d 356inf_child_target::fileio_readlink (struct inferior *inf, const char *filename,
b872057a 357 fileio_error *target_errno)
b9e7b9c3
UW
358{
359 /* We support readlink only on systems that also provide a compile-time
d8d2a3ee 360 maximum path length (PATH_MAX), at least for now. */
bdca27a2 361#if defined (PATH_MAX)
d8d2a3ee 362 char buf[PATH_MAX];
b9e7b9c3 363 int len;
b9e7b9c3
UW
364
365 len = readlink (filename, buf, sizeof buf);
366 if (len < 0)
367 {
7823a941 368 *target_errno = host_to_fileio_error (errno);
e0d3522b 369 return {};
b9e7b9c3
UW
370 }
371
e0d3522b 372 return std::string (buf, len);
b9e7b9c3
UW
373#else
374 *target_errno = FILEIO_ENOSYS;
e0d3522b 375 return {};
b9e7b9c3
UW
376#endif
377}
378
57810aa7
PA
379bool
380inf_child_target::use_agent (bool use)
5808517f
YQ
381{
382 if (agent_loaded_p ())
383 {
f6ac5f3d 384 ::use_agent = use;
57810aa7 385 return true;
5808517f
YQ
386 }
387 else
57810aa7 388 return false;
5808517f
YQ
389}
390
57810aa7 391bool
f6ac5f3d 392inf_child_target::can_use_agent ()
5808517f
YQ
393{
394 return agent_loaded_p ();
395}
7313baad 396
737358ba
SM
397void
398inf_child_target::follow_exec (inferior *follow_inf, ptid_t ptid,
399 const char *execd_pathname)
400{
401 inferior *orig_inf = current_inferior ();
402
403 process_stratum_target::follow_exec (follow_inf, ptid, execd_pathname);
404
405 if (orig_inf != follow_inf)
406 {
407 /* If the target was implicitly push in the original inferior, unpush
287de656 408 it. */
737358ba
SM
409 scoped_restore_current_thread restore_thread;
410 switch_to_inferior_no_thread (orig_inf);
411 maybe_unpush_target ();
412 }
413}
414
d9f719f1
PA
415/* See inf-child.h. */
416
417void
418add_inf_child_target (inf_child_target *target)
419{
420 set_native_target (target);
421 add_target (inf_child_target_info, inf_child_open_target);
422}