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