]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/bsd-kvm.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / bsd-kvm.c
CommitLineData
2e0c3539
MK
1/* BSD Kernel Data Access Library (libkvm) interface.
2
1d506c26 3 Copyright (C) 2004-2024 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
2e0c3539 21#include "defs.h"
963c4174
MK
22#include "cli/cli-cmds.h"
23#include "command.h"
c62dced2 24#include "filenames.h"
2e0c3539
MK
25#include "frame.h"
26#include "regcache.h"
27#include "target.h"
3b3dac9b 28#include "process-stratum-target.h"
963c4174 29#include "value.h"
08036331 30#include "gdbcore.h"
ef0f16cc 31#include "inferior.h"
6c613132 32#include "gdbthread.h"
e3169fe0 33#include "gdbsupport/pathstuff.h"
c62dced2 34#include "gdbsupport/gdb_tilde_expand.h"
2e0c3539 35
2e0c3539
MK
36#include <fcntl.h>
37#include <kvm.h>
ac5754fa 38#ifdef HAVE_NLIST_H
2e0c3539 39#include <nlist.h>
ac5754fa 40#endif
2e5a5020 41#include <paths.h>
2e0c3539 42#include "readline/readline.h"
af09351e 43#include <sys/param.h>
963c4174 44#include <sys/proc.h>
f7efc967 45#ifdef HAVE_SYS_USER_H
2e0c3539 46#include <sys/user.h>
f7efc967 47#endif
2e0c3539
MK
48
49#include "bsd-kvm.h"
50
2e5a5020 51/* Kernel memory device file. */
c62dced2 52static std::string bsd_kvm_corefile;
2e5a5020 53
2e0c3539 54/* Kernel memory interface descriptor. */
2e5a5020 55static kvm_t *core_kd;
2e0c3539
MK
56
57/* Address of process control block. */
2e5a5020 58static struct pcb *bsd_kvm_paddr;
2e0c3539
MK
59
60/* Pointer to architecture-specific function that reconstructs the
61 register state from PCB and supplies it to REGCACHE. */
2e5a5020 62static int (*bsd_kvm_supply_pcb)(struct regcache *regcache, struct pcb *pcb);
2e0c3539 63
6c613132
PA
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
f6ac5f3d
PA
69/* The libkvm target. */
70
d9f719f1
PA
71static const target_info bsd_kvm_target_info = {
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
3b3dac9b 78class bsd_kvm_target final : public process_stratum_target
f6ac5f3d
PA
79{
80public:
3b3dac9b 81 bsd_kvm_target () = default;
f6ac5f3d 82
d9f719f1
PA
83 const target_info &info () const override
84 { return bsd_kvm_target_info; }
f6ac5f3d 85
f6ac5f3d
PA
86 void close () override;
87
88 void fetch_registers (struct regcache *, int) override;
89 enum target_xfer_status xfer_partial (enum target_object object,
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;
57810aa7 97 bool thread_alive (ptid_t ptid) override;
a068643d 98 std::string pid_to_str (ptid_t) override;
f6ac5f3d 99
57810aa7
PA
100 bool has_memory () override { return true; }
101 bool has_stack () override { return true; }
102 bool has_registers () override { return true; }
f6ac5f3d
PA
103};
104
105/* Target ops for libkvm interface. */
106static bsd_kvm_target bsd_kvm_ops;
107
2e0c3539 108static void
d9f719f1 109bsd_kvm_target_open (const char *arg, int from_tty)
2e0c3539
MK
110{
111 char errbuf[_POSIX2_LINE_MAX];
d9fa87f4 112 const char *execfile = NULL;
2e0c3539 113 kvm_t *temp_kd;
c62dced2 114 std::string filename;
2e0c3539
MK
115
116 target_preopen (from_tty);
117
014f9477 118 if (arg)
2e0c3539 119 {
c62dced2
JB
120 filename = gdb_tilde_expand (arg);
121 if (!IS_ABSOLUTE_PATH (filename))
122 filename = gdb_abspath (filename.c_str ());
2e0c3539
MK
123 }
124
7f245d65 125 execfile = get_exec_file (0);
c62dced2 126 temp_kd = kvm_openfiles (execfile, filename.c_str (), NULL,
4a35b02a 127 write_files ? O_RDWR : O_RDONLY, errbuf);
2e0c3539 128 if (temp_kd == NULL)
8a3fe4f8 129 error (("%s"), errbuf);
2e0c3539 130
2e5a5020 131 bsd_kvm_corefile = filename;
fadf6add 132 current_inferior ()->unpush_target (&bsd_kvm_ops);
2e0c3539 133 core_kd = temp_kd;
02980c56 134 current_inferior ()->push_target (&bsd_kvm_ops);
2e0c3539 135
5d971d48
PA
136 thread_info *thr = add_thread_silent (&bsd_kvm_ops, bsd_kvm_ptid);
137 switch_to_thread (thr);
6c613132 138
9c742269 139 target_fetch_registers (get_thread_regcache (thr), -1);
2e0c3539 140
35f196d9 141 reinit_frame_cache ();
08d72866 142 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
2e0c3539
MK
143}
144
f6ac5f3d
PA
145void
146bsd_kvm_target::close ()
2e0c3539
MK
147{
148 if (core_kd)
149 {
150 if (kvm_close (core_kd) == -1)
8a3fe4f8 151 warning (("%s"), kvm_geterr(core_kd));
2e0c3539
MK
152 core_kd = NULL;
153 }
6c613132 154
c62dced2 155 bsd_kvm_corefile.clear ();
f2e1c129 156 switch_to_no_thread ();
9324bfea 157 exit_inferior (current_inferior ());
2e0c3539
MK
158}
159
961cb7b5
MK
160static LONGEST
161bsd_kvm_xfer_memory (CORE_ADDR addr, ULONGEST len,
162 gdb_byte *readbuf, const gdb_byte *writebuf)
2e0c3539 163{
961cb7b5
MK
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}
2e0c3539 172
f6ac5f3d
PA
173enum target_xfer_status
174bsd_kvm_target::xfer_partial (enum target_object object,
175 const char *annex, gdb_byte *readbuf,
176 const gdb_byte *writebuf,
177 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
961cb7b5
MK
178{
179 switch (object)
180 {
181 case TARGET_OBJECT_MEMORY:
9b409511
YQ
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 }
961cb7b5
MK
195
196 default:
2ed4b548 197 return TARGET_XFER_E_IO;
961cb7b5 198 }
2e0c3539
MK
199}
200
f6ac5f3d
PA
201void
202bsd_kvm_target::files_info ()
2e5a5020 203{
c62dced2 204 if (bsd_kvm_corefile != _PATH_MEM)
6cb06a8c 205 gdb_printf (_("\tUsing the kernel crash dump %s.\n"),
c62dced2 206 bsd_kvm_corefile.c_str ());
2e5a5020 207 else
6cb06a8c 208 gdb_printf (_("\tUsing the currently running kernel.\n"));
2e5a5020
MK
209}
210
2e0c3539
MK
211/* Fetch process control block at address PADDR. */
212
213static int
56be3814 214bsd_kvm_fetch_pcb (struct regcache *regcache, struct pcb *paddr)
2e0c3539
MK
215{
216 struct pcb pcb;
217
218 if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
8a3fe4f8 219 error (("%s"), kvm_geterr (core_kd));
2e0c3539
MK
220
221 gdb_assert (bsd_kvm_supply_pcb);
56be3814 222 return bsd_kvm_supply_pcb (regcache, &pcb);
2e0c3539
MK
223}
224
f6ac5f3d
PA
225void
226bsd_kvm_target::fetch_registers (struct regcache *regcache, int regnum)
2e0c3539
MK
227{
228 struct nlist nl[2];
229
230 if (bsd_kvm_paddr)
efe1d7b9 231 {
56be3814 232 bsd_kvm_fetch_pcb (regcache, bsd_kvm_paddr);
efe1d7b9
MK
233 return;
234 }
2e0c3539
MK
235
236 /* On dumping core, BSD kernels store the faulting context (PCB)
237 in the variable "dumppcb". */
238 memset (nl, 0, sizeof nl);
ed0dcb1f 239 nl[0].n_name = (char *) "_dumppcb";
2e0c3539
MK
240
241 if (kvm_nlist (core_kd, nl) == -1)
8a3fe4f8 242 error (("%s"), kvm_geterr (core_kd));
2e0c3539
MK
243
244 if (nl[0].n_value != 0)
245 {
4a64f543 246 /* Found dumppcb. If it contains a valid context, return
2e0c3539 247 immediately. */
56be3814 248 if (bsd_kvm_fetch_pcb (regcache, (struct pcb *) nl[0].n_value))
2e0c3539
MK
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);
ed0dcb1f 257 nl[0].n_name = (char *) "_proc0paddr";
2e0c3539
MK
258
259 if (kvm_nlist (core_kd, nl) == -1)
8a3fe4f8 260 error (("%s"), kvm_geterr (core_kd));
2e0c3539
MK
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)
8a3fe4f8 268 error (("%s"), kvm_geterr (core_kd));
2e0c3539 269
56be3814 270 bsd_kvm_fetch_pcb (regcache, paddr);
2e0c3539
MK
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);
ed0dcb1f 281 nl[0].n_name = (char *) "_thread0";
2e0c3539
MK
282
283 if (kvm_nlist (core_kd, nl) == -1)
8a3fe4f8 284 error (("%s"), kvm_geterr (core_kd));
2e0c3539
MK
285
286 if (nl[0].n_value != 0)
287 {
288 struct pcb *paddr;
289
290 /* Found thread0. */
efe1d7b9
MK
291 nl[0].n_value += offsetof (struct thread, td_pcb);
292 if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
8a3fe4f8 293 error (("%s"), kvm_geterr (core_kd));
2e0c3539 294
56be3814 295 bsd_kvm_fetch_pcb (regcache, paddr);
2e0c3539
MK
296 return;
297 }
298#endif
299
0963b4bd 300 /* i18n: PCB == "Process Control Block". */
3d263c1d 301 error (_("Cannot find a valid PCB"));
2e0c3539
MK
302}
303\f
304
963c4174 305/* Kernel memory interface commands. */
fdb1bf9d 306struct cmd_list_element *bsd_kvm_cmdlist;
963c4174
MK
307
308static void
981a3fb3 309bsd_kvm_cmd (const char *arg, int fromtty)
963c4174
MK
310{
311 /* ??? Should this become an alias for "target kvm"? */
312}
313
314#ifndef HAVE_STRUCT_THREAD_TD_PCB
315
316static void
94765011 317bsd_kvm_proc_cmd (const char *arg, int fromtty)
963c4174
MK
318{
319 CORE_ADDR addr;
320
321 if (arg == NULL)
3d263c1d 322 error_no_arg (_("proc address"));
963c4174
MK
323
324 if (core_kd == NULL)
3d263c1d 325 error (_("No kernel memory image."));
963c4174
MK
326
327 addr = parse_and_eval_address (arg);
da7d81e3
NW
328#ifdef HAVE_STRUCT_LWP
329 addr += offsetof (struct lwp, l_addr);
330#else
963c4174 331 addr += offsetof (struct proc, p_addr);
da7d81e3 332#endif
963c4174
MK
333
334 if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
8a3fe4f8 335 error (("%s"), kvm_geterr (core_kd));
963c4174 336
9c742269 337 target_fetch_registers (get_thread_regcache (inferior_thread ()), -1);
963c4174 338
35f196d9 339 reinit_frame_cache ();
08d72866 340 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
963c4174
MK
341}
342
343#endif
344
345static void
94765011 346bsd_kvm_pcb_cmd (const char *arg, int fromtty)
963c4174
MK
347{
348 if (arg == NULL)
0963b4bd 349 /* i18n: PCB == "Process Control Block". */
3d263c1d 350 error_no_arg (_("pcb address"));
963c4174
MK
351
352 if (core_kd == NULL)
3d263c1d 353 error (_("No kernel memory image."));
963c4174 354
57ac95b8 355 bsd_kvm_paddr = (struct pcb *)(u_long) parse_and_eval_address (arg);
963c4174 356
9c742269 357 target_fetch_registers (get_thread_regcache (inferior_thread ()), -1);
963c4174 358
35f196d9 359 reinit_frame_cache ();
08d72866 360 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
963c4174
MK
361}
362
57810aa7 363bool
f6ac5f3d 364bsd_kvm_target::thread_alive (ptid_t ptid)
6c613132 365{
57810aa7 366 return true;
6c613132
PA
367}
368
a068643d 369std::string
f6ac5f3d 370bsd_kvm_target::pid_to_str (ptid_t ptid)
6c613132 371{
a068643d 372 return "<kvm>";
6c613132
PA
373}
374
2e0c3539
MK
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
d9f719f1 385 add_target (bsd_kvm_target_info, bsd_kvm_target_open);
963c4174 386
3d263c1d
BI
387 add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, _("\
388Generic command for manipulating the kernel memory interface."),
2f822da5 389 &bsd_kvm_cmdlist, 0, &cmdlist);
963c4174
MK
390
391#ifndef HAVE_STRUCT_THREAD_TD_PCB
392 add_cmd ("proc", class_obscure, bsd_kvm_proc_cmd,
3d263c1d 393 _("Set current context from proc address"), &bsd_kvm_cmdlist);
963c4174
MK
394#endif
395 add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
0963b4bd 396 /* i18n: PCB == "Process Control Block". */
3d263c1d 397 _("Set current context from pcb address"), &bsd_kvm_cmdlist);
6c613132
PA
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
0963b4bd
MS
411 ptid (1, 1, n) -> kvm inferior 1, process n */
412
fd79271b 413 bsd_kvm_ptid = ptid_t (1, 1, 0);
2e0c3539 414}