Convert struct target_ops to C++
[deliverable/binutils-gdb.git] / gdb / inf-child.c
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. */
45 void
46 store_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
65 inf_child_target::~inf_child_target ()
66 {}
67
68 void
69 inf_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
81 void
82 inf_child_target::prepare_to_store (struct regcache *regcache)
83 {
84 }
85
86 bool
87 inf_child_target::supports_terminal_ours ()
88 {
89 return true;
90 }
91
92 void
93 inf_child_target::terminal_init ()
94 {
95 child_terminal_init (this);
96 }
97
98 void
99 inf_child_target::terminal_inferior ()
100 {
101 child_terminal_inferior (this);
102 }
103
104 void
105 inf_child_target::terminal_ours_for_output ()
106 {
107 child_terminal_ours_for_output (this);
108 }
109
110 void
111 inf_child_target::terminal_ours ()
112 {
113 child_terminal_ours (this);
114 }
115
116 void
117 inf_child_target::interrupt ()
118 {
119 child_interrupt (this);
120 }
121
122 void
123 inf_child_target::pass_ctrlc ()
124 {
125 child_pass_ctrlc (this);
126 }
127
128 void
129 inf_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. */
137 static int inf_child_explicitly_opened;
138
139 /* See inf-child.h. */
140
141 void
142 inf_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
152 void
153 inf_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
160 void
161 inf_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
173 void
174 inf_child_target::close ()
175 {
176 /* In case we were forcibly closed. */
177 inf_child_explicitly_opened = 0;
178 }
179
180 void
181 inf_child_target::mourn_inferior ()
182 {
183 generic_mourn_inferior ();
184 maybe_unpush_target ();
185 }
186
187 /* See inf-child.h. */
188
189 void
190 inf_child_target::maybe_unpush_target ()
191 {
192 if (!inf_child_explicitly_opened && !have_inferiors ())
193 unpush_target (this);
194 }
195
196 void
197 inf_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
203 int
204 inf_child_target::can_run ()
205 {
206 return 1;
207 }
208
209 bool
210 inf_child_target::can_create_inferior ()
211 {
212 return true;
213 }
214
215 bool
216 inf_child_target::can_attach ()
217 {
218 return true;
219 }
220
221 char *
222 inf_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
229 int
230 inf_child_target::has_all_memory ()
231 {
232 return default_child_has_all_memory ();
233 }
234
235 int
236 inf_child_target::has_memory ()
237 {
238 return default_child_has_memory ();
239 }
240
241 int
242 inf_child_target::has_stack ()
243 {
244 return default_child_has_stack ();
245 }
246
247 int
248 inf_child_target::has_registers ()
249 {
250 return default_child_has_registers ();
251 }
252
253 int
254 inf_child_target::has_execution (ptid_t ptid)
255 {
256 return default_child_has_execution (ptid);
257 }
258
259 /* Implementation of to_fileio_open. */
260
261 int
262 inf_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
286 int
287 inf_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
313 int
314 inf_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
340 int
341 inf_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
354 int
355 inf_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
368 int
369 inf_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
383 gdb::optional<std::string>
384 inf_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
407 int
408 inf_child_target::use_agent (int use)
409 {
410 if (agent_loaded_p ())
411 {
412 ::use_agent = use;
413 return 1;
414 }
415 else
416 return 0;
417 }
418
419 int
420 inf_child_target::can_use_agent ()
421 {
422 return agent_loaded_p ();
423 }
424
425 inf_child_target::inf_child_target ()
426 {
427 this->to_stratum = process_stratum;
428 }
This page took 0.038529 seconds and 4 git commands to generate.