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