linux_nat_target: More low methods
[deliverable/binutils-gdb.git] / gdb / inf-child.c
... / ...
CommitLineData
1/* Base/prototype target for default child (native) targets.
2
3 Copyright (C) 1988-2018 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 "defs.h"
26#include "regcache.h"
27#include "memattr.h"
28#include "symtab.h"
29#include "target.h"
30#include "inferior.h"
31#include <sys/stat.h>
32#include "inf-child.h"
33#include "fileio.h"
34#include "agent.h"
35#include "gdb_wait.h"
36#include "filestuff.h"
37
38#include <sys/types.h>
39#include <fcntl.h>
40#include <unistd.h>
41
42/* Helper function for child_wait and the derivatives of child_wait.
43 HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
44 translation of that in OURSTATUS. */
45void
46store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
47{
48 if (WIFEXITED (hoststatus))
49 {
50 ourstatus->kind = TARGET_WAITKIND_EXITED;
51 ourstatus->value.integer = WEXITSTATUS (hoststatus);
52 }
53 else if (!WIFSTOPPED (hoststatus))
54 {
55 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
56 ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (hoststatus));
57 }
58 else
59 {
60 ourstatus->kind = TARGET_WAITKIND_STOPPED;
61 ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (hoststatus));
62 }
63}
64
65inf_child_target::~inf_child_target ()
66{}
67
68void
69inf_child_target::post_attach (int pid)
70{
71 /* This target doesn't require a meaningful "post attach" operation
72 by a debugger. */
73}
74
75/* Get ready to modify the registers array. On machines which store
76 individual registers, this doesn't need to do anything. On
77 machines which store all the registers in one fell swoop, this
78 makes sure that registers contains all the registers from the
79 program being debugged. */
80
81void
82inf_child_target::prepare_to_store (struct regcache *regcache)
83{
84}
85
86bool
87inf_child_target::supports_terminal_ours ()
88{
89 return true;
90}
91
92void
93inf_child_target::terminal_init ()
94{
95 child_terminal_init (this);
96}
97
98void
99inf_child_target::terminal_inferior ()
100{
101 child_terminal_inferior (this);
102}
103
104void
105inf_child_target::terminal_ours_for_output ()
106{
107 child_terminal_ours_for_output (this);
108}
109
110void
111inf_child_target::terminal_ours ()
112{
113 child_terminal_ours (this);
114}
115
116void
117inf_child_target::interrupt ()
118{
119 child_interrupt (this);
120}
121
122void
123inf_child_target::pass_ctrlc ()
124{
125 child_pass_ctrlc (this);
126}
127
128void
129inf_child_target::terminal_info (const char *args, int from_tty)
130{
131 child_terminal_info (this, args, from_tty);
132}
133
134/* True if the user did "target native". In that case, we won't
135 unpush the child target automatically when the last inferior is
136 gone. */
137static int inf_child_explicitly_opened;
138
139/* See inf-child.h. */
140
141void
142inf_child_open_target (struct target_ops *target, const char *arg,
143 int from_tty)
144{
145 target_preopen (from_tty);
146 push_target (target);
147 inf_child_explicitly_opened = 1;
148 if (from_tty)
149 printf_filtered ("Done. Use the \"run\" command to start a process.\n");
150}
151
152void
153inf_child_target::open (const char *arg, int from_tty)
154{
155 inf_child_open_target (this, arg, from_tty);
156}
157
158/* Implement the to_disconnect target_ops method. */
159
160void
161inf_child_target::disconnect (const char *args, int from_tty)
162{
163 if (args != NULL)
164 error (_("Argument given to \"disconnect\"."));
165
166 /* This offers to detach/kill current inferiors, and then pops all
167 targets. */
168 target_preopen (from_tty);
169}
170
171/* Implement the to_close target_ops method. */
172
173void
174inf_child_target::close ()
175{
176 /* In case we were forcibly closed. */
177 inf_child_explicitly_opened = 0;
178}
179
180void
181inf_child_target::mourn_inferior ()
182{
183 generic_mourn_inferior ();
184 maybe_unpush_target ();
185}
186
187/* See inf-child.h. */
188
189void
190inf_child_target::maybe_unpush_target ()
191{
192 if (!inf_child_explicitly_opened && !have_inferiors ())
193 unpush_target (this);
194}
195
196void
197inf_child_target::post_startup_inferior (ptid_t ptid)
198{
199 /* This target doesn't require a meaningful "post startup inferior"
200 operation by a debugger. */
201}
202
203bool
204inf_child_target::can_run ()
205{
206 return true;
207}
208
209bool
210inf_child_target::can_create_inferior ()
211{
212 return true;
213}
214
215bool
216inf_child_target::can_attach ()
217{
218 return true;
219}
220
221char *
222inf_child_target::pid_to_exec_file (int pid)
223{
224 /* This target doesn't support translation of a process ID to the
225 filename of the executable file. */
226 return NULL;
227}
228
229bool
230inf_child_target::has_all_memory ()
231{
232 return default_child_has_all_memory ();
233}
234
235bool
236inf_child_target::has_memory ()
237{
238 return default_child_has_memory ();
239}
240
241bool
242inf_child_target::has_stack ()
243{
244 return default_child_has_stack ();
245}
246
247bool
248inf_child_target::has_registers ()
249{
250 return default_child_has_registers ();
251}
252
253bool
254inf_child_target::has_execution (ptid_t ptid)
255{
256 return default_child_has_execution (ptid);
257}
258
259/* Implementation of to_fileio_open. */
260
261int
262inf_child_target::fileio_open (struct inferior *inf, const char *filename,
263 int flags, int mode, int warn_if_slow,
264 int *target_errno)
265{
266 int nat_flags;
267 mode_t nat_mode;
268 int fd;
269
270 if (fileio_to_host_openflags (flags, &nat_flags) == -1
271 || fileio_to_host_mode (mode, &nat_mode) == -1)
272 {
273 *target_errno = FILEIO_EINVAL;
274 return -1;
275 }
276
277 fd = gdb_open_cloexec (filename, nat_flags, nat_mode);
278 if (fd == -1)
279 *target_errno = host_to_fileio_error (errno);
280
281 return fd;
282}
283
284/* Implementation of to_fileio_pwrite. */
285
286int
287inf_child_target::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
288 ULONGEST offset, int *target_errno)
289{
290 int ret;
291
292#ifdef HAVE_PWRITE
293 ret = pwrite (fd, write_buf, len, (long) offset);
294#else
295 ret = -1;
296#endif
297 /* If we have no pwrite or it failed for this file, use lseek/write. */
298 if (ret == -1)
299 {
300 ret = lseek (fd, (long) offset, SEEK_SET);
301 if (ret != -1)
302 ret = write (fd, write_buf, len);
303 }
304
305 if (ret == -1)
306 *target_errno = host_to_fileio_error (errno);
307
308 return ret;
309}
310
311/* Implementation of to_fileio_pread. */
312
313int
314inf_child_target::fileio_pread (int fd, gdb_byte *read_buf, int len,
315 ULONGEST offset, int *target_errno)
316{
317 int ret;
318
319#ifdef HAVE_PREAD
320 ret = pread (fd, read_buf, len, (long) offset);
321#else
322 ret = -1;
323#endif
324 /* If we have no pread or it failed for this file, use lseek/read. */
325 if (ret == -1)
326 {
327 ret = lseek (fd, (long) offset, SEEK_SET);
328 if (ret != -1)
329 ret = read (fd, read_buf, len);
330 }
331
332 if (ret == -1)
333 *target_errno = host_to_fileio_error (errno);
334
335 return ret;
336}
337
338/* Implementation of to_fileio_fstat. */
339
340int
341inf_child_target::fileio_fstat (int fd, struct stat *sb, int *target_errno)
342{
343 int ret;
344
345 ret = fstat (fd, sb);
346 if (ret == -1)
347 *target_errno = host_to_fileio_error (errno);
348
349 return ret;
350}
351
352/* Implementation of to_fileio_close. */
353
354int
355inf_child_target::fileio_close (int fd, int *target_errno)
356{
357 int ret;
358
359 ret = ::close (fd);
360 if (ret == -1)
361 *target_errno = host_to_fileio_error (errno);
362
363 return ret;
364}
365
366/* Implementation of to_fileio_unlink. */
367
368int
369inf_child_target::fileio_unlink (struct inferior *inf, const char *filename,
370 int *target_errno)
371{
372 int ret;
373
374 ret = unlink (filename);
375 if (ret == -1)
376 *target_errno = host_to_fileio_error (errno);
377
378 return ret;
379}
380
381/* Implementation of to_fileio_readlink. */
382
383gdb::optional<std::string>
384inf_child_target::fileio_readlink (struct inferior *inf, const char *filename,
385 int *target_errno)
386{
387 /* We support readlink only on systems that also provide a compile-time
388 maximum path length (PATH_MAX), at least for now. */
389#if defined (PATH_MAX)
390 char buf[PATH_MAX];
391 int len;
392
393 len = readlink (filename, buf, sizeof buf);
394 if (len < 0)
395 {
396 *target_errno = host_to_fileio_error (errno);
397 return {};
398 }
399
400 return std::string (buf, len);
401#else
402 *target_errno = FILEIO_ENOSYS;
403 return {};
404#endif
405}
406
407bool
408inf_child_target::use_agent (bool use)
409{
410 if (agent_loaded_p ())
411 {
412 ::use_agent = use;
413 return true;
414 }
415 else
416 return false;
417}
418
419bool
420inf_child_target::can_use_agent ()
421{
422 return agent_loaded_p ();
423}
424
425inf_child_target::inf_child_target ()
426{
427 this->to_stratum = process_stratum;
428}
This page took 0.026242 seconds and 4 git commands to generate.