]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/inf-child.c
Change gdbarch_inner_than to return bool
[thirdparty/binutils-gdb.git] / gdb / inf-child.c
1 /* Base/prototype target for default child (native) targets.
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 /* 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
25 #include "regcache.h"
26 #include "memattr.h"
27 #include "symtab.h"
28 #include "target.h"
29 #include "inferior.h"
30 #include <sys/stat.h>
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"
36
37 #include <sys/types.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40
41 static const target_info inf_child_target_info = {
42 "native",
43 N_("Native process"),
44 N_("Native process (started by the \"run\" command).")
45 };
46
47 const target_info &
48 inf_child_target::info () const
49 {
50 return inf_child_target_info;
51 }
52
53 /* See inf-child.h. */
54
55 target_waitstatus
56 host_status_to_waitstatus (int hoststatus)
57 {
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)));
63 else
64 return target_waitstatus ().set_stopped
65 (gdb_signal_from_host (WSTOPSIG (hoststatus)));
66 }
67
68 inf_child_target::~inf_child_target ()
69 {}
70
71 void
72 inf_child_target::post_attach (int pid)
73 {
74 /* This target doesn't require a meaningful "post attach" operation
75 by a debugger. */
76 }
77
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. */
83
84 void
85 inf_child_target::prepare_to_store (struct regcache *regcache)
86 {
87 }
88
89 bool
90 inf_child_target::supports_terminal_ours ()
91 {
92 return true;
93 }
94
95 void
96 inf_child_target::terminal_init ()
97 {
98 child_terminal_init (this);
99 }
100
101 void
102 inf_child_target::terminal_inferior ()
103 {
104 child_terminal_inferior (this);
105 }
106
107 void
108 inf_child_target::terminal_save_inferior ()
109 {
110 child_terminal_save_inferior (this);
111 }
112
113 void
114 inf_child_target::terminal_ours_for_output ()
115 {
116 child_terminal_ours_for_output (this);
117 }
118
119 void
120 inf_child_target::terminal_ours ()
121 {
122 child_terminal_ours (this);
123 }
124
125 void
126 inf_child_target::interrupt ()
127 {
128 child_interrupt (this);
129 }
130
131 void
132 inf_child_target::pass_ctrlc ()
133 {
134 child_pass_ctrlc (this);
135 }
136
137 void
138 inf_child_target::terminal_info (const char *args, int from_tty)
139 {
140 child_terminal_info (this, args, from_tty);
141 }
142
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
145 gone. */
146 static int inf_child_explicitly_opened;
147
148 /* See inf-child.h. */
149
150 void
151 inf_child_open_target (const char *arg, int from_tty)
152 {
153 target_ops *target = get_native_target ();
154
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);
158
159 target_preopen (from_tty);
160 current_inferior ()->push_target (target);
161 inf_child_explicitly_opened = 1;
162 if (from_tty)
163 gdb_printf ("Done. Use the \"run\" command to start a process.\n");
164 }
165
166 /* Implement the to_disconnect target_ops method. */
167
168 void
169 inf_child_target::disconnect (const char *args, int from_tty)
170 {
171 if (args != NULL)
172 error (_("Argument given to \"disconnect\"."));
173
174 /* This offers to detach/kill current inferiors, and then pops all
175 targets. */
176 target_preopen (from_tty);
177 }
178
179 /* Implement the to_close target_ops method. */
180
181 void
182 inf_child_target::close ()
183 {
184 /* In case we were forcibly closed. */
185 inf_child_explicitly_opened = 0;
186 }
187
188 void
189 inf_child_target::mourn_inferior ()
190 {
191 generic_mourn_inferior ();
192 maybe_unpush_target ();
193 }
194
195 /* See inf-child.h. */
196
197 void
198 inf_child_target::maybe_unpush_target ()
199 {
200 if (!inf_child_explicitly_opened)
201 current_inferior ()->unpush_target (this);
202 }
203
204 bool
205 inf_child_target::can_run ()
206 {
207 return true;
208 }
209
210 bool
211 inf_child_target::can_create_inferior ()
212 {
213 return true;
214 }
215
216 bool
217 inf_child_target::can_attach ()
218 {
219 return true;
220 }
221
222 const char *
223 inf_child_target::pid_to_exec_file (int pid)
224 {
225 /* This target doesn't support translation of a process ID to the
226 filename of the executable file. */
227 return NULL;
228 }
229
230 /* Implementation of to_fileio_open. */
231
232 int
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)
236 {
237 int nat_flags;
238 mode_t nat_mode;
239 int fd;
240
241 if (fileio_to_host_openflags (flags, &nat_flags) == -1
242 || fileio_to_host_mode (mode, &nat_mode) == -1)
243 {
244 *target_errno = FILEIO_EINVAL;
245 return -1;
246 }
247
248 fd = gdb_open_cloexec (filename, nat_flags, nat_mode).release ();
249 if (fd == -1)
250 *target_errno = host_to_fileio_error (errno);
251
252 return fd;
253 }
254
255 /* Implementation of to_fileio_pwrite. */
256
257 int
258 inf_child_target::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
259 ULONGEST offset, fileio_error *target_errno)
260 {
261 int ret;
262
263 #ifdef HAVE_PWRITE
264 ret = pwrite (fd, write_buf, len, (long) offset);
265 #else
266 ret = -1;
267 #endif
268 /* If we have no pwrite or it failed for this file, use lseek/write. */
269 if (ret == -1)
270 {
271 ret = lseek (fd, (long) offset, SEEK_SET);
272 if (ret != -1)
273 ret = write (fd, write_buf, len);
274 }
275
276 if (ret == -1)
277 *target_errno = host_to_fileio_error (errno);
278
279 return ret;
280 }
281
282 /* Implementation of to_fileio_pread. */
283
284 int
285 inf_child_target::fileio_pread (int fd, gdb_byte *read_buf, int len,
286 ULONGEST offset, fileio_error *target_errno)
287 {
288 int ret;
289
290 #ifdef HAVE_PREAD
291 ret = pread (fd, read_buf, len, (long) offset);
292 #else
293 ret = -1;
294 #endif
295 /* If we have no pread or it failed for this file, use lseek/read. */
296 if (ret == -1)
297 {
298 ret = lseek (fd, (long) offset, SEEK_SET);
299 if (ret != -1)
300 ret = read (fd, read_buf, len);
301 }
302
303 if (ret == -1)
304 *target_errno = host_to_fileio_error (errno);
305
306 return ret;
307 }
308
309 /* Implementation of to_fileio_fstat. */
310
311 int
312 inf_child_target::fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno)
313 {
314 int ret;
315
316 ret = fstat (fd, sb);
317 if (ret == -1)
318 *target_errno = host_to_fileio_error (errno);
319
320 return ret;
321 }
322
323 /* Implementation of to_fileio_close. */
324
325 int
326 inf_child_target::fileio_close (int fd, fileio_error *target_errno)
327 {
328 int ret;
329
330 ret = ::close (fd);
331 if (ret == -1)
332 *target_errno = host_to_fileio_error (errno);
333
334 return ret;
335 }
336
337 /* Implementation of to_fileio_unlink. */
338
339 int
340 inf_child_target::fileio_unlink (struct inferior *inf, const char *filename,
341 fileio_error *target_errno)
342 {
343 int ret;
344
345 ret = unlink (filename);
346 if (ret == -1)
347 *target_errno = host_to_fileio_error (errno);
348
349 return ret;
350 }
351
352 /* Implementation of to_fileio_readlink. */
353
354 std::optional<std::string>
355 inf_child_target::fileio_readlink (struct inferior *inf, const char *filename,
356 fileio_error *target_errno)
357 {
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)
361 char buf[PATH_MAX];
362 int len;
363
364 len = readlink (filename, buf, sizeof buf);
365 if (len < 0)
366 {
367 *target_errno = host_to_fileio_error (errno);
368 return {};
369 }
370
371 return std::string (buf, len);
372 #else
373 *target_errno = FILEIO_ENOSYS;
374 return {};
375 #endif
376 }
377
378 bool
379 inf_child_target::use_agent (bool use)
380 {
381 if (agent_loaded_p ())
382 {
383 ::use_agent = use;
384 return true;
385 }
386 else
387 return false;
388 }
389
390 bool
391 inf_child_target::can_use_agent ()
392 {
393 return agent_loaded_p ();
394 }
395
396 void
397 inf_child_target::follow_exec (inferior *follow_inf, ptid_t ptid,
398 const char *execd_pathname)
399 {
400 inferior *orig_inf = current_inferior ();
401
402 process_stratum_target::follow_exec (follow_inf, ptid, execd_pathname);
403
404 if (orig_inf != follow_inf)
405 {
406 /* If the target was implicitly push in the original inferior, unpush
407 it. */
408 scoped_restore_current_thread restore_thread;
409 switch_to_inferior_no_thread (orig_inf);
410 maybe_unpush_target ();
411 }
412 }
413
414 /* See inf-child.h. */
415
416 void
417 add_inf_child_target (inf_child_target *target)
418 {
419 set_native_target (target);
420 add_target (inf_child_target_info, inf_child_open_target);
421 }