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