bsd-kvm.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /* BSD Kernel Data Access Library (libkvm) interface.
  2. Copyright (C) 2004-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. #define _KMEMUSER
  15. #include "defs.h"
  16. #include "cli/cli-cmds.h"
  17. #include "command.h"
  18. #include "frame.h"
  19. #include "regcache.h"
  20. #include "target.h"
  21. #include "process-stratum-target.h"
  22. #include "value.h"
  23. #include "gdbcore.h"
  24. #include "inferior.h" /* for get_exec_file */
  25. #include "gdbthread.h"
  26. #include "gdbsupport/pathstuff.h"
  27. #include <fcntl.h>
  28. #include <kvm.h>
  29. #ifdef HAVE_NLIST_H
  30. #include <nlist.h>
  31. #endif
  32. #include <paths.h>
  33. #include "readline/readline.h"
  34. #include <sys/param.h>
  35. #include <sys/proc.h>
  36. #ifdef HAVE_SYS_USER_H
  37. #include <sys/user.h>
  38. #endif
  39. #include "bsd-kvm.h"
  40. /* Kernel memory device file. */
  41. static const char *bsd_kvm_corefile;
  42. /* Kernel memory interface descriptor. */
  43. static kvm_t *core_kd;
  44. /* Address of process control block. */
  45. static struct pcb *bsd_kvm_paddr;
  46. /* Pointer to architecture-specific function that reconstructs the
  47. register state from PCB and supplies it to REGCACHE. */
  48. static int (*bsd_kvm_supply_pcb)(struct regcache *regcache, struct pcb *pcb);
  49. /* This is the ptid we use while we're connected to kvm. The kvm
  50. target currently doesn't export any view of the running processes,
  51. so this represents the kernel task. */
  52. static ptid_t bsd_kvm_ptid;
  53. /* The libkvm target. */
  54. static const target_info bsd_kvm_target_info = {
  55. "kvm",
  56. N_("Kernel memory interface"),
  57. N_("Use a kernel virtual memory image as a target.\n\
  58. Optionally specify the filename of a core dump.")
  59. };
  60. class bsd_kvm_target final : public process_stratum_target
  61. {
  62. public:
  63. bsd_kvm_target () = default;
  64. const target_info &info () const override
  65. { return bsd_kvm_target_info; }
  66. void close () override;
  67. void fetch_registers (struct regcache *, int) override;
  68. enum target_xfer_status xfer_partial (enum target_object object,
  69. const char *annex,
  70. gdb_byte *readbuf,
  71. const gdb_byte *writebuf,
  72. ULONGEST offset, ULONGEST len,
  73. ULONGEST *xfered_len) override;
  74. void files_info () override;
  75. bool thread_alive (ptid_t ptid) override;
  76. std::string pid_to_str (ptid_t) override;
  77. bool has_memory () override { return true; }
  78. bool has_stack () override { return true; }
  79. bool has_registers () override { return true; }
  80. };
  81. /* Target ops for libkvm interface. */
  82. static bsd_kvm_target bsd_kvm_ops;
  83. static void
  84. bsd_kvm_target_open (const char *arg, int from_tty)
  85. {
  86. char errbuf[_POSIX2_LINE_MAX];
  87. const char *execfile = NULL;
  88. kvm_t *temp_kd;
  89. char *filename = NULL;
  90. target_preopen (from_tty);
  91. if (arg)
  92. {
  93. filename = tilde_expand (arg);
  94. if (filename[0] != '/')
  95. {
  96. gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (filename));
  97. xfree (filename);
  98. filename = temp.release ();
  99. }
  100. }
  101. execfile = get_exec_file (0);
  102. temp_kd = kvm_openfiles (execfile, filename, NULL,
  103. write_files ? O_RDWR : O_RDONLY, errbuf);
  104. if (temp_kd == NULL)
  105. error (("%s"), errbuf);
  106. bsd_kvm_corefile = filename;
  107. current_inferior ()->unpush_target (&bsd_kvm_ops);
  108. core_kd = temp_kd;
  109. current_inferior ()->push_target (&bsd_kvm_ops);
  110. thread_info *thr = add_thread_silent (&bsd_kvm_ops, bsd_kvm_ptid);
  111. switch_to_thread (thr);
  112. target_fetch_registers (get_current_regcache (), -1);
  113. reinit_frame_cache ();
  114. print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
  115. }
  116. void
  117. bsd_kvm_target::close ()
  118. {
  119. if (core_kd)
  120. {
  121. if (kvm_close (core_kd) == -1)
  122. warning (("%s"), kvm_geterr(core_kd));
  123. core_kd = NULL;
  124. }
  125. switch_to_no_thread ();
  126. exit_inferior_silent (current_inferior ());
  127. }
  128. static LONGEST
  129. bsd_kvm_xfer_memory (CORE_ADDR addr, ULONGEST len,
  130. gdb_byte *readbuf, const gdb_byte *writebuf)
  131. {
  132. ssize_t nbytes = len;
  133. if (readbuf)
  134. nbytes = kvm_read (core_kd, addr, readbuf, nbytes);
  135. if (writebuf && nbytes > 0)
  136. nbytes = kvm_write (core_kd, addr, writebuf, nbytes);
  137. return nbytes;
  138. }
  139. enum target_xfer_status
  140. bsd_kvm_target::xfer_partial (enum target_object object,
  141. const char *annex, gdb_byte *readbuf,
  142. const gdb_byte *writebuf,
  143. ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
  144. {
  145. switch (object)
  146. {
  147. case TARGET_OBJECT_MEMORY:
  148. {
  149. LONGEST ret = bsd_kvm_xfer_memory (offset, len, readbuf, writebuf);
  150. if (ret < 0)
  151. return TARGET_XFER_E_IO;
  152. else if (ret == 0)
  153. return TARGET_XFER_EOF;
  154. else
  155. {
  156. *xfered_len = (ULONGEST) ret;
  157. return TARGET_XFER_OK;
  158. }
  159. }
  160. default:
  161. return TARGET_XFER_E_IO;
  162. }
  163. }
  164. void
  165. bsd_kvm_target::files_info ()
  166. {
  167. if (bsd_kvm_corefile && strcmp (bsd_kvm_corefile, _PATH_MEM) != 0)
  168. gdb_printf (_("\tUsing the kernel crash dump %s.\n"),
  169. bsd_kvm_corefile);
  170. else
  171. gdb_printf (_("\tUsing the currently running kernel.\n"));
  172. }
  173. /* Fetch process control block at address PADDR. */
  174. static int
  175. bsd_kvm_fetch_pcb (struct regcache *regcache, struct pcb *paddr)
  176. {
  177. struct pcb pcb;
  178. if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
  179. error (("%s"), kvm_geterr (core_kd));
  180. gdb_assert (bsd_kvm_supply_pcb);
  181. return bsd_kvm_supply_pcb (regcache, &pcb);
  182. }
  183. void
  184. bsd_kvm_target::fetch_registers (struct regcache *regcache, int regnum)
  185. {
  186. struct nlist nl[2];
  187. if (bsd_kvm_paddr)
  188. {
  189. bsd_kvm_fetch_pcb (regcache, bsd_kvm_paddr);
  190. return;
  191. }
  192. /* On dumping core, BSD kernels store the faulting context (PCB)
  193. in the variable "dumppcb". */
  194. memset (nl, 0, sizeof nl);
  195. nl[0].n_name = (char *) "_dumppcb";
  196. if (kvm_nlist (core_kd, nl) == -1)
  197. error (("%s"), kvm_geterr (core_kd));
  198. if (nl[0].n_value != 0)
  199. {
  200. /* Found dumppcb. If it contains a valid context, return
  201. immediately. */
  202. if (bsd_kvm_fetch_pcb (regcache, (struct pcb *) nl[0].n_value))
  203. return;
  204. }
  205. /* Traditional BSD kernels have a process proc0 that should always
  206. be present. The address of proc0's PCB is stored in the variable
  207. "proc0paddr". */
  208. memset (nl, 0, sizeof nl);
  209. nl[0].n_name = (char *) "_proc0paddr";
  210. if (kvm_nlist (core_kd, nl) == -1)
  211. error (("%s"), kvm_geterr (core_kd));
  212. if (nl[0].n_value != 0)
  213. {
  214. struct pcb *paddr;
  215. /* Found proc0paddr. */
  216. if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
  217. error (("%s"), kvm_geterr (core_kd));
  218. bsd_kvm_fetch_pcb (regcache, paddr);
  219. return;
  220. }
  221. #ifdef HAVE_STRUCT_THREAD_TD_PCB
  222. /* In FreeBSD kernels for 5.0-RELEASE and later, the PCB no longer
  223. lives in `struct proc' but in `struct thread'. The `struct
  224. thread' for the initial thread for proc0 can be found in the
  225. variable "thread0". */
  226. memset (nl, 0, sizeof nl);
  227. nl[0].n_name = (char *) "_thread0";
  228. if (kvm_nlist (core_kd, nl) == -1)
  229. error (("%s"), kvm_geterr (core_kd));
  230. if (nl[0].n_value != 0)
  231. {
  232. struct pcb *paddr;
  233. /* Found thread0. */
  234. nl[0].n_value += offsetof (struct thread, td_pcb);
  235. if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
  236. error (("%s"), kvm_geterr (core_kd));
  237. bsd_kvm_fetch_pcb (regcache, paddr);
  238. return;
  239. }
  240. #endif
  241. /* i18n: PCB == "Process Control Block". */
  242. error (_("Cannot find a valid PCB"));
  243. }
  244. /* Kernel memory interface commands. */
  245. struct cmd_list_element *bsd_kvm_cmdlist;
  246. static void
  247. bsd_kvm_cmd (const char *arg, int fromtty)
  248. {
  249. /* ??? Should this become an alias for "target kvm"? */
  250. }
  251. #ifndef HAVE_STRUCT_THREAD_TD_PCB
  252. static void
  253. bsd_kvm_proc_cmd (const char *arg, int fromtty)
  254. {
  255. CORE_ADDR addr;
  256. if (arg == NULL)
  257. error_no_arg (_("proc address"));
  258. if (core_kd == NULL)
  259. error (_("No kernel memory image."));
  260. addr = parse_and_eval_address (arg);
  261. #ifdef HAVE_STRUCT_LWP
  262. addr += offsetof (struct lwp, l_addr);
  263. #else
  264. addr += offsetof (struct proc, p_addr);
  265. #endif
  266. if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
  267. error (("%s"), kvm_geterr (core_kd));
  268. target_fetch_registers (get_current_regcache (), -1);
  269. reinit_frame_cache ();
  270. print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
  271. }
  272. #endif
  273. static void
  274. bsd_kvm_pcb_cmd (const char *arg, int fromtty)
  275. {
  276. if (arg == NULL)
  277. /* i18n: PCB == "Process Control Block". */
  278. error_no_arg (_("pcb address"));
  279. if (core_kd == NULL)
  280. error (_("No kernel memory image."));
  281. bsd_kvm_paddr = (struct pcb *)(u_long) parse_and_eval_address (arg);
  282. target_fetch_registers (get_current_regcache (), -1);
  283. reinit_frame_cache ();
  284. print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
  285. }
  286. bool
  287. bsd_kvm_target::thread_alive (ptid_t ptid)
  288. {
  289. return true;
  290. }
  291. std::string
  292. bsd_kvm_target::pid_to_str (ptid_t ptid)
  293. {
  294. return "<kvm>";
  295. }
  296. /* Add the libkvm interface to the list of all possible targets and
  297. register CUPPLY_PCB as the architecture-specific process control
  298. block interpreter. */
  299. void
  300. bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
  301. {
  302. gdb_assert (bsd_kvm_supply_pcb == NULL);
  303. bsd_kvm_supply_pcb = supply_pcb;
  304. add_target (bsd_kvm_target_info, bsd_kvm_target_open);
  305. add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, _("\
  306. Generic command for manipulating the kernel memory interface."),
  307. &bsd_kvm_cmdlist, 0, &cmdlist);
  308. #ifndef HAVE_STRUCT_THREAD_TD_PCB
  309. add_cmd ("proc", class_obscure, bsd_kvm_proc_cmd,
  310. _("Set current context from proc address"), &bsd_kvm_cmdlist);
  311. #endif
  312. add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
  313. /* i18n: PCB == "Process Control Block". */
  314. _("Set current context from pcb address"), &bsd_kvm_cmdlist);
  315. /* Some notes on the ptid usage on this target.
  316. The pid field represents the kvm inferior instance. Currently,
  317. we don't support multiple kvm inferiors, but we start at 1
  318. anyway. The lwp field is set to != 0, in case the core wants to
  319. refer to the whole kvm inferior with ptid(1,0,0).
  320. If kvm is made to export running processes as gdb threads,
  321. the following form can be used:
  322. ptid (1, 1, 0) -> kvm inferior 1, in kernel
  323. ptid (1, 1, 1) -> kvm inferior 1, process 1
  324. ptid (1, 1, 2) -> kvm inferior 1, process 2
  325. ptid (1, 1, n) -> kvm inferior 1, process n */
  326. bsd_kvm_ptid = ptid_t (1, 1, 0);
  327. }