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