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