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