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