Disambiguate info_print_options
[deliverable/binutils-gdb.git] / gdb / bsd-kvm.c
CommitLineData
2e0c3539
MK
1/* BSD Kernel Data Access Library (libkvm) interface.
2
b811d2c2 3 Copyright (C) 2004-2020 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"
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
PA
29#include "gdbcore.h"
30#include "inferior.h" /* for get_exec_file */
6c613132 31#include "gdbthread.h"
e3169fe0 32#include "gdbsupport/pathstuff.h"
2e0c3539 33
2e0c3539
MK
34#include <fcntl.h>
35#include <kvm.h>
ac5754fa 36#ifdef HAVE_NLIST_H
2e0c3539 37#include <nlist.h>
ac5754fa 38#endif
2e5a5020 39#include <paths.h>
2e0c3539 40#include "readline/readline.h"
af09351e 41#include <sys/param.h>
963c4174 42#include <sys/proc.h>
f7efc967 43#ifdef HAVE_SYS_USER_H
2e0c3539 44#include <sys/user.h>
f7efc967 45#endif
2e0c3539
MK
46
47#include "bsd-kvm.h"
48
2e5a5020
MK
49/* Kernel memory device file. */
50static const char *bsd_kvm_corefile;
51
2e0c3539 52/* Kernel memory interface descriptor. */
2e5a5020 53static kvm_t *core_kd;
2e0c3539
MK
54
55/* Address of process control block. */
2e5a5020 56static struct pcb *bsd_kvm_paddr;
2e0c3539
MK
57
58/* Pointer to architecture-specific function that reconstructs the
59 register state from PCB and supplies it to REGCACHE. */
2e5a5020 60static int (*bsd_kvm_supply_pcb)(struct regcache *regcache, struct pcb *pcb);
2e0c3539 61
6c613132
PA
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. */
65static ptid_t bsd_kvm_ptid;
66
f6ac5f3d
PA
67/* The libkvm target. */
68
d9f719f1
PA
69static 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\
73Optionally specify the filename of a core dump.")
74};
75
3b3dac9b 76class bsd_kvm_target final : public process_stratum_target
f6ac5f3d
PA
77{
78public:
3b3dac9b 79 bsd_kvm_target () = default;
f6ac5f3d 80
d9f719f1
PA
81 const target_info &info () const override
82 { return bsd_kvm_target_info; }
f6ac5f3d 83
f6ac5f3d
PA
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;
57810aa7 95 bool thread_alive (ptid_t ptid) override;
a068643d 96 std::string pid_to_str (ptid_t) override;
f6ac5f3d 97
57810aa7
PA
98 bool has_memory () override { return true; }
99 bool has_stack () override { return true; }
100 bool has_registers () override { return true; }
f6ac5f3d
PA
101};
102
103/* Target ops for libkvm interface. */
104static bsd_kvm_target bsd_kvm_ops;
105
2e0c3539 106static void
d9f719f1 107bsd_kvm_target_open (const char *arg, int from_tty)
2e0c3539
MK
108{
109 char errbuf[_POSIX2_LINE_MAX];
d9fa87f4 110 const char *execfile = NULL;
2e0c3539 111 kvm_t *temp_kd;
014f9477 112 char *filename = NULL;
2e0c3539
MK
113
114 target_preopen (from_tty);
115
014f9477 116 if (arg)
2e0c3539 117 {
014f9477 118 filename = tilde_expand (arg);
2e0c3539
MK
119 if (filename[0] != '/')
120 {
ff8577f6
SDJ
121 gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (filename));
122
2e0c3539 123 xfree (filename);
ff8577f6 124 filename = temp.release ();
2e0c3539
MK
125 }
126 }
127
7f245d65 128 execfile = get_exec_file (0);
4a35b02a
NW
129 temp_kd = kvm_openfiles (execfile, filename, NULL,
130 write_files ? O_RDWR : O_RDONLY, errbuf);
2e0c3539 131 if (temp_kd == NULL)
8a3fe4f8 132 error (("%s"), errbuf);
2e0c3539 133
2e5a5020 134 bsd_kvm_corefile = filename;
2e0c3539
MK
135 unpush_target (&bsd_kvm_ops);
136 core_kd = temp_kd;
137 push_target (&bsd_kvm_ops);
138
5b6d1e4f 139 add_thread_silent (&bsd_kvm_ops, bsd_kvm_ptid);
6c613132
PA
140 inferior_ptid = bsd_kvm_ptid;
141
594f7785 142 target_fetch_registers (get_current_regcache (), -1);
2e0c3539 143
35f196d9 144 reinit_frame_cache ();
08d72866 145 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
2e0c3539
MK
146}
147
f6ac5f3d
PA
148void
149bsd_kvm_target::close ()
2e0c3539
MK
150{
151 if (core_kd)
152 {
153 if (kvm_close (core_kd) == -1)
8a3fe4f8 154 warning (("%s"), kvm_geterr(core_kd));
2e0c3539
MK
155 core_kd = NULL;
156 }
6c613132
PA
157
158 inferior_ptid = null_ptid;
4ec89149 159 exit_inferior_silent (current_inferior ());
2e0c3539
MK
160}
161
961cb7b5
MK
162static LONGEST
163bsd_kvm_xfer_memory (CORE_ADDR addr, ULONGEST len,
164 gdb_byte *readbuf, const gdb_byte *writebuf)
2e0c3539 165{
961cb7b5
MK
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}
2e0c3539 174
f6ac5f3d
PA
175enum target_xfer_status
176bsd_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)
961cb7b5
MK
180{
181 switch (object)
182 {
183 case TARGET_OBJECT_MEMORY:
9b409511
YQ
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 }
961cb7b5
MK
197
198 default:
2ed4b548 199 return TARGET_XFER_E_IO;
961cb7b5 200 }
2e0c3539
MK
201}
202
f6ac5f3d
PA
203void
204bsd_kvm_target::files_info ()
2e5a5020
MK
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
2e0c3539
MK
213/* Fetch process control block at address PADDR. */
214
215static int
56be3814 216bsd_kvm_fetch_pcb (struct regcache *regcache, struct pcb *paddr)
2e0c3539
MK
217{
218 struct pcb pcb;
219
220 if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
8a3fe4f8 221 error (("%s"), kvm_geterr (core_kd));
2e0c3539
MK
222
223 gdb_assert (bsd_kvm_supply_pcb);
56be3814 224 return bsd_kvm_supply_pcb (regcache, &pcb);
2e0c3539
MK
225}
226
f6ac5f3d
PA
227void
228bsd_kvm_target::fetch_registers (struct regcache *regcache, int regnum)
2e0c3539
MK
229{
230 struct nlist nl[2];
231
232 if (bsd_kvm_paddr)
efe1d7b9 233 {
56be3814 234 bsd_kvm_fetch_pcb (regcache, bsd_kvm_paddr);
efe1d7b9
MK
235 return;
236 }
2e0c3539
MK
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)
8a3fe4f8 244 error (("%s"), kvm_geterr (core_kd));
2e0c3539
MK
245
246 if (nl[0].n_value != 0)
247 {
4a64f543 248 /* Found dumppcb. If it contains a valid context, return
2e0c3539 249 immediately. */
56be3814 250 if (bsd_kvm_fetch_pcb (regcache, (struct pcb *) nl[0].n_value))
2e0c3539
MK
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)
8a3fe4f8 262 error (("%s"), kvm_geterr (core_kd));
2e0c3539
MK
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)
8a3fe4f8 270 error (("%s"), kvm_geterr (core_kd));
2e0c3539 271
56be3814 272 bsd_kvm_fetch_pcb (regcache, paddr);
2e0c3539
MK
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)
8a3fe4f8 286 error (("%s"), kvm_geterr (core_kd));
2e0c3539
MK
287
288 if (nl[0].n_value != 0)
289 {
290 struct pcb *paddr;
291
292 /* Found thread0. */
efe1d7b9
MK
293 nl[0].n_value += offsetof (struct thread, td_pcb);
294 if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
8a3fe4f8 295 error (("%s"), kvm_geterr (core_kd));
2e0c3539 296
56be3814 297 bsd_kvm_fetch_pcb (regcache, paddr);
2e0c3539
MK
298 return;
299 }
300#endif
301
0963b4bd 302 /* i18n: PCB == "Process Control Block". */
3d263c1d 303 error (_("Cannot find a valid PCB"));
2e0c3539
MK
304}
305\f
306
963c4174 307/* Kernel memory interface commands. */
fdb1bf9d 308struct cmd_list_element *bsd_kvm_cmdlist;
963c4174
MK
309
310static void
981a3fb3 311bsd_kvm_cmd (const char *arg, int fromtty)
963c4174
MK
312{
313 /* ??? Should this become an alias for "target kvm"? */
314}
315
316#ifndef HAVE_STRUCT_THREAD_TD_PCB
317
318static void
94765011 319bsd_kvm_proc_cmd (const char *arg, int fromtty)
963c4174
MK
320{
321 CORE_ADDR addr;
322
323 if (arg == NULL)
3d263c1d 324 error_no_arg (_("proc address"));
963c4174
MK
325
326 if (core_kd == NULL)
3d263c1d 327 error (_("No kernel memory image."));
963c4174
MK
328
329 addr = parse_and_eval_address (arg);
da7d81e3
NW
330#ifdef HAVE_STRUCT_LWP
331 addr += offsetof (struct lwp, l_addr);
332#else
963c4174 333 addr += offsetof (struct proc, p_addr);
da7d81e3 334#endif
963c4174
MK
335
336 if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
8a3fe4f8 337 error (("%s"), kvm_geterr (core_kd));
963c4174 338
594f7785 339 target_fetch_registers (get_current_regcache (), -1);
963c4174 340
35f196d9 341 reinit_frame_cache ();
08d72866 342 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
963c4174
MK
343}
344
345#endif
346
347static void
94765011 348bsd_kvm_pcb_cmd (const char *arg, int fromtty)
963c4174
MK
349{
350 if (arg == NULL)
0963b4bd 351 /* i18n: PCB == "Process Control Block". */
3d263c1d 352 error_no_arg (_("pcb address"));
963c4174
MK
353
354 if (core_kd == NULL)
3d263c1d 355 error (_("No kernel memory image."));
963c4174 356
57ac95b8 357 bsd_kvm_paddr = (struct pcb *)(u_long) parse_and_eval_address (arg);
963c4174 358
594f7785 359 target_fetch_registers (get_current_regcache (), -1);
963c4174 360
35f196d9 361 reinit_frame_cache ();
08d72866 362 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
963c4174
MK
363}
364
57810aa7 365bool
f6ac5f3d 366bsd_kvm_target::thread_alive (ptid_t ptid)
6c613132 367{
57810aa7 368 return true;
6c613132
PA
369}
370
a068643d 371std::string
f6ac5f3d 372bsd_kvm_target::pid_to_str (ptid_t ptid)
6c613132 373{
a068643d 374 return "<kvm>";
6c613132
PA
375}
376
2e0c3539
MK
377/* Add the libkvm interface to the list of all possible targets and
378 register CUPPLY_PCB as the architecture-specific process control
379 block interpreter. */
380
381void
382bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
383{
384 gdb_assert (bsd_kvm_supply_pcb == NULL);
385 bsd_kvm_supply_pcb = supply_pcb;
386
d9f719f1 387 add_target (bsd_kvm_target_info, bsd_kvm_target_open);
963c4174 388
3d263c1d
BI
389 add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, _("\
390Generic command for manipulating the kernel memory interface."),
963c4174
MK
391 &bsd_kvm_cmdlist, "kvm ", 0, &cmdlist);
392
393#ifndef HAVE_STRUCT_THREAD_TD_PCB
394 add_cmd ("proc", class_obscure, bsd_kvm_proc_cmd,
3d263c1d 395 _("Set current context from proc address"), &bsd_kvm_cmdlist);
963c4174
MK
396#endif
397 add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
0963b4bd 398 /* i18n: PCB == "Process Control Block". */
3d263c1d 399 _("Set current context from pcb address"), &bsd_kvm_cmdlist);
6c613132
PA
400
401 /* Some notes on the ptid usage on this target.
402
403 The pid field represents the kvm inferior instance. Currently,
404 we don't support multiple kvm inferiors, but we start at 1
405 anyway. The lwp field is set to != 0, in case the core wants to
406 refer to the whole kvm inferior with ptid(1,0,0).
407
408 If kvm is made to export running processes as gdb threads,
409 the following form can be used:
410 ptid (1, 1, 0) -> kvm inferior 1, in kernel
411 ptid (1, 1, 1) -> kvm inferior 1, process 1
412 ptid (1, 1, 2) -> kvm inferior 1, process 2
0963b4bd
MS
413 ptid (1, 1, n) -> kvm inferior 1, process n */
414
fd79271b 415 bsd_kvm_ptid = ptid_t (1, 1, 0);
2e0c3539 416}
This page took 0.984923 seconds and 4 git commands to generate.