inf-child.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /* Base/prototype target for default child (native) targets.
  2. Copyright (C) 1988-2022 Free Software Foundation, Inc.
  3. This file is part of GDB.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. /* This file provides a common base class/target that all native
  15. target implementations extend, by calling inf_child_target to get a
  16. new prototype target and then overriding target methods as
  17. necessary. */
  18. #include "defs.h"
  19. #include "regcache.h"
  20. #include "memattr.h"
  21. #include "symtab.h"
  22. #include "target.h"
  23. #include "inferior.h"
  24. #include <sys/stat.h>
  25. #include "inf-child.h"
  26. #include "gdbsupport/fileio.h"
  27. #include "gdbsupport/agent.h"
  28. #include "gdbsupport/gdb_wait.h"
  29. #include "gdbsupport/filestuff.h"
  30. #include <sys/types.h>
  31. #include <fcntl.h>
  32. #include <unistd.h>
  33. static const target_info inf_child_target_info = {
  34. "native",
  35. N_("Native process"),
  36. N_("Native process (started by the \"run\" command).")
  37. };
  38. const target_info &
  39. inf_child_target::info () const
  40. {
  41. return inf_child_target_info;
  42. }
  43. /* See inf-child.h. */
  44. target_waitstatus
  45. host_status_to_waitstatus (int hoststatus)
  46. {
  47. if (WIFEXITED (hoststatus))
  48. return target_waitstatus ().set_exited (WEXITSTATUS (hoststatus));
  49. else if (!WIFSTOPPED (hoststatus))
  50. return target_waitstatus ().set_signalled
  51. (gdb_signal_from_host (WTERMSIG (hoststatus)));
  52. else
  53. return target_waitstatus ().set_stopped
  54. (gdb_signal_from_host (WSTOPSIG (hoststatus)));
  55. }
  56. inf_child_target::~inf_child_target ()
  57. {}
  58. void
  59. inf_child_target::post_attach (int pid)
  60. {
  61. /* This target doesn't require a meaningful "post attach" operation
  62. by a debugger. */
  63. }
  64. /* Get ready to modify the registers array. On machines which store
  65. individual registers, this doesn't need to do anything. On
  66. machines which store all the registers in one fell swoop, this
  67. makes sure that registers contains all the registers from the
  68. program being debugged. */
  69. void
  70. inf_child_target::prepare_to_store (struct regcache *regcache)
  71. {
  72. }
  73. bool
  74. inf_child_target::supports_terminal_ours ()
  75. {
  76. return true;
  77. }
  78. void
  79. inf_child_target::terminal_init ()
  80. {
  81. child_terminal_init (this);
  82. }
  83. void
  84. inf_child_target::terminal_inferior ()
  85. {
  86. child_terminal_inferior (this);
  87. }
  88. void
  89. inf_child_target::terminal_save_inferior ()
  90. {
  91. child_terminal_save_inferior (this);
  92. }
  93. void
  94. inf_child_target::terminal_ours_for_output ()
  95. {
  96. child_terminal_ours_for_output (this);
  97. }
  98. void
  99. inf_child_target::terminal_ours ()
  100. {
  101. child_terminal_ours (this);
  102. }
  103. void
  104. inf_child_target::interrupt ()
  105. {
  106. child_interrupt (this);
  107. }
  108. void
  109. inf_child_target::pass_ctrlc ()
  110. {
  111. child_pass_ctrlc (this);
  112. }
  113. void
  114. inf_child_target::terminal_info (const char *args, int from_tty)
  115. {
  116. child_terminal_info (this, args, from_tty);
  117. }
  118. /* True if the user did "target native". In that case, we won't
  119. unpush the child target automatically when the last inferior is
  120. gone. */
  121. static int inf_child_explicitly_opened;
  122. /* See inf-child.h. */
  123. void
  124. inf_child_open_target (const char *arg, int from_tty)
  125. {
  126. target_ops *target = get_native_target ();
  127. /* There's always only ever one native target, and if we get here,
  128. it better be an inf-child target. */
  129. gdb_assert (dynamic_cast<inf_child_target *> (target) != NULL);
  130. target_preopen (from_tty);
  131. current_inferior ()->push_target (target);
  132. inf_child_explicitly_opened = 1;
  133. if (from_tty)
  134. gdb_printf ("Done. Use the \"run\" command to start a process.\n");
  135. }
  136. /* Implement the to_disconnect target_ops method. */
  137. void
  138. inf_child_target::disconnect (const char *args, int from_tty)
  139. {
  140. if (args != NULL)
  141. error (_("Argument given to \"disconnect\"."));
  142. /* This offers to detach/kill current inferiors, and then pops all
  143. targets. */
  144. target_preopen (from_tty);
  145. }
  146. /* Implement the to_close target_ops method. */
  147. void
  148. inf_child_target::close ()
  149. {
  150. /* In case we were forcibly closed. */
  151. inf_child_explicitly_opened = 0;
  152. }
  153. void
  154. inf_child_target::mourn_inferior ()
  155. {
  156. generic_mourn_inferior ();
  157. maybe_unpush_target ();
  158. }
  159. /* See inf-child.h. */
  160. void
  161. inf_child_target::maybe_unpush_target ()
  162. {
  163. if (!inf_child_explicitly_opened)
  164. current_inferior ()->unpush_target (this);
  165. }
  166. bool
  167. inf_child_target::can_run ()
  168. {
  169. return true;
  170. }
  171. bool
  172. inf_child_target::can_create_inferior ()
  173. {
  174. return true;
  175. }
  176. bool
  177. inf_child_target::can_attach ()
  178. {
  179. return true;
  180. }
  181. char *
  182. inf_child_target::pid_to_exec_file (int pid)
  183. {
  184. /* This target doesn't support translation of a process ID to the
  185. filename of the executable file. */
  186. return NULL;
  187. }
  188. /* Implementation of to_fileio_open. */
  189. int
  190. inf_child_target::fileio_open (struct inferior *inf, const char *filename,
  191. int flags, int mode, int warn_if_slow,
  192. int *target_errno)
  193. {
  194. int nat_flags;
  195. mode_t nat_mode;
  196. int fd;
  197. if (fileio_to_host_openflags (flags, &nat_flags) == -1
  198. || fileio_to_host_mode (mode, &nat_mode) == -1)
  199. {
  200. *target_errno = FILEIO_EINVAL;
  201. return -1;
  202. }
  203. fd = gdb_open_cloexec (filename, nat_flags, nat_mode).release ();
  204. if (fd == -1)
  205. *target_errno = host_to_fileio_error (errno);
  206. return fd;
  207. }
  208. /* Implementation of to_fileio_pwrite. */
  209. int
  210. inf_child_target::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
  211. ULONGEST offset, int *target_errno)
  212. {
  213. int ret;
  214. #ifdef HAVE_PWRITE
  215. ret = pwrite (fd, write_buf, len, (long) offset);
  216. #else
  217. ret = -1;
  218. #endif
  219. /* If we have no pwrite or it failed for this file, use lseek/write. */
  220. if (ret == -1)
  221. {
  222. ret = lseek (fd, (long) offset, SEEK_SET);
  223. if (ret != -1)
  224. ret = write (fd, write_buf, len);
  225. }
  226. if (ret == -1)
  227. *target_errno = host_to_fileio_error (errno);
  228. return ret;
  229. }
  230. /* Implementation of to_fileio_pread. */
  231. int
  232. inf_child_target::fileio_pread (int fd, gdb_byte *read_buf, int len,
  233. ULONGEST offset, int *target_errno)
  234. {
  235. int ret;
  236. #ifdef HAVE_PREAD
  237. ret = pread (fd, read_buf, len, (long) offset);
  238. #else
  239. ret = -1;
  240. #endif
  241. /* If we have no pread or it failed for this file, use lseek/read. */
  242. if (ret == -1)
  243. {
  244. ret = lseek (fd, (long) offset, SEEK_SET);
  245. if (ret != -1)
  246. ret = read (fd, read_buf, len);
  247. }
  248. if (ret == -1)
  249. *target_errno = host_to_fileio_error (errno);
  250. return ret;
  251. }
  252. /* Implementation of to_fileio_fstat. */
  253. int
  254. inf_child_target::fileio_fstat (int fd, struct stat *sb, int *target_errno)
  255. {
  256. int ret;
  257. ret = fstat (fd, sb);
  258. if (ret == -1)
  259. *target_errno = host_to_fileio_error (errno);
  260. return ret;
  261. }
  262. /* Implementation of to_fileio_close. */
  263. int
  264. inf_child_target::fileio_close (int fd, int *target_errno)
  265. {
  266. int ret;
  267. ret = ::close (fd);
  268. if (ret == -1)
  269. *target_errno = host_to_fileio_error (errno);
  270. return ret;
  271. }
  272. /* Implementation of to_fileio_unlink. */
  273. int
  274. inf_child_target::fileio_unlink (struct inferior *inf, const char *filename,
  275. int *target_errno)
  276. {
  277. int ret;
  278. ret = unlink (filename);
  279. if (ret == -1)
  280. *target_errno = host_to_fileio_error (errno);
  281. return ret;
  282. }
  283. /* Implementation of to_fileio_readlink. */
  284. gdb::optional<std::string>
  285. inf_child_target::fileio_readlink (struct inferior *inf, const char *filename,
  286. int *target_errno)
  287. {
  288. /* We support readlink only on systems that also provide a compile-time
  289. maximum path length (PATH_MAX), at least for now. */
  290. #if defined (PATH_MAX)
  291. char buf[PATH_MAX];
  292. int len;
  293. len = readlink (filename, buf, sizeof buf);
  294. if (len < 0)
  295. {
  296. *target_errno = host_to_fileio_error (errno);
  297. return {};
  298. }
  299. return std::string (buf, len);
  300. #else
  301. *target_errno = FILEIO_ENOSYS;
  302. return {};
  303. #endif
  304. }
  305. bool
  306. inf_child_target::use_agent (bool use)
  307. {
  308. if (agent_loaded_p ())
  309. {
  310. ::use_agent = use;
  311. return true;
  312. }
  313. else
  314. return false;
  315. }
  316. bool
  317. inf_child_target::can_use_agent ()
  318. {
  319. return agent_loaded_p ();
  320. }
  321. void
  322. inf_child_target::follow_exec (inferior *follow_inf, ptid_t ptid,
  323. const char *execd_pathname)
  324. {
  325. inferior *orig_inf = current_inferior ();
  326. process_stratum_target::follow_exec (follow_inf, ptid, execd_pathname);
  327. if (orig_inf != follow_inf)
  328. {
  329. /* If the target was implicitly push in the original inferior, unpush
  330. it. */
  331. scoped_restore_current_thread restore_thread;
  332. switch_to_inferior_no_thread (orig_inf);
  333. maybe_unpush_target ();
  334. }
  335. }
  336. /* See inf-child.h. */
  337. void
  338. add_inf_child_target (inf_child_target *target)
  339. {
  340. set_native_target (target);
  341. add_target (inf_child_target_info, inf_child_open_target);
  342. }