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