1 /* BSD Kernel Data Access Library (libkvm) interface.
3 Copyright (C) 2004-2020 Free Software Foundation, Inc.
5 This file is part of GDB.
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
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 #include "cli/cli-cmds.h"
27 #include "process-stratum-target.h"
30 #include "inferior.h" /* for get_exec_file */
31 #include "gdbthread.h"
32 #include "gdbsupport/pathstuff.h"
40 #include "readline/readline.h"
41 #include <sys/param.h>
43 #ifdef HAVE_SYS_USER_H
49 /* Kernel memory device file. */
50 static const char *bsd_kvm_corefile
;
52 /* Kernel memory interface descriptor. */
53 static kvm_t
*core_kd
;
55 /* Address of process control block. */
56 static struct pcb
*bsd_kvm_paddr
;
58 /* Pointer to architecture-specific function that reconstructs the
59 register state from PCB and supplies it to REGCACHE. */
60 static int (*bsd_kvm_supply_pcb
)(struct regcache
*regcache
, struct pcb
*pcb
);
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. */
65 static ptid_t bsd_kvm_ptid
;
67 /* The libkvm target. */
69 static const target_info bsd_kvm_target_info
= {
71 N_("Kernel memory interface"),
72 N_("Use a kernel virtual memory image as a target.\n\
73 Optionally specify the filename of a core dump.")
76 class bsd_kvm_target final
: public process_stratum_target
79 bsd_kvm_target () = default;
81 const target_info
&info () const override
82 { return bsd_kvm_target_info
; }
84 void close () override
;
86 void fetch_registers (struct regcache
*, int) override
;
87 enum target_xfer_status
xfer_partial (enum target_object object
,
90 const gdb_byte
*writebuf
,
91 ULONGEST offset
, ULONGEST len
,
92 ULONGEST
*xfered_len
) override
;
94 void files_info () override
;
95 bool thread_alive (ptid_t ptid
) override
;
96 std::string
pid_to_str (ptid_t
) override
;
98 bool has_memory () override
{ return true; }
99 bool has_stack () override
{ return true; }
100 bool has_registers () override
{ return true; }
103 /* Target ops for libkvm interface. */
104 static bsd_kvm_target bsd_kvm_ops
;
107 bsd_kvm_target_open (const char *arg
, int from_tty
)
109 char errbuf
[_POSIX2_LINE_MAX
];
110 const char *execfile
= NULL
;
112 char *filename
= NULL
;
114 target_preopen (from_tty
);
118 filename
= tilde_expand (arg
);
119 if (filename
[0] != '/')
121 gdb::unique_xmalloc_ptr
<char> temp (gdb_abspath (filename
));
124 filename
= temp
.release ();
128 execfile
= get_exec_file (0);
129 temp_kd
= kvm_openfiles (execfile
, filename
, NULL
,
130 write_files
? O_RDWR
: O_RDONLY
, errbuf
);
132 error (("%s"), errbuf
);
134 bsd_kvm_corefile
= filename
;
135 unpush_target (&bsd_kvm_ops
);
137 push_target (&bsd_kvm_ops
);
139 add_thread_silent (bsd_kvm_ptid
);
140 inferior_ptid
= bsd_kvm_ptid
;
142 target_fetch_registers (get_current_regcache (), -1);
144 reinit_frame_cache ();
145 print_stack_frame (get_selected_frame (NULL
), 0, SRC_AND_LOC
, 1);
149 bsd_kvm_target::close ()
153 if (kvm_close (core_kd
) == -1)
154 warning (("%s"), kvm_geterr(core_kd
));
158 inferior_ptid
= null_ptid
;
159 discard_all_inferiors ();
163 bsd_kvm_xfer_memory (CORE_ADDR addr
, ULONGEST len
,
164 gdb_byte
*readbuf
, const gdb_byte
*writebuf
)
166 ssize_t nbytes
= len
;
169 nbytes
= kvm_read (core_kd
, addr
, readbuf
, nbytes
);
170 if (writebuf
&& nbytes
> 0)
171 nbytes
= kvm_write (core_kd
, addr
, writebuf
, nbytes
);
175 enum target_xfer_status
176 bsd_kvm_target::xfer_partial (enum target_object object
,
177 const char *annex
, gdb_byte
*readbuf
,
178 const gdb_byte
*writebuf
,
179 ULONGEST offset
, ULONGEST len
, ULONGEST
*xfered_len
)
183 case TARGET_OBJECT_MEMORY
:
185 LONGEST ret
= bsd_kvm_xfer_memory (offset
, len
, readbuf
, writebuf
);
188 return TARGET_XFER_E_IO
;
190 return TARGET_XFER_EOF
;
193 *xfered_len
= (ULONGEST
) ret
;
194 return TARGET_XFER_OK
;
199 return TARGET_XFER_E_IO
;
204 bsd_kvm_target::files_info ()
206 if (bsd_kvm_corefile
&& strcmp (bsd_kvm_corefile
, _PATH_MEM
) != 0)
207 printf_filtered (_("\tUsing the kernel crash dump %s.\n"),
210 printf_filtered (_("\tUsing the currently running kernel.\n"));
213 /* Fetch process control block at address PADDR. */
216 bsd_kvm_fetch_pcb (struct regcache
*regcache
, struct pcb
*paddr
)
220 if (kvm_read (core_kd
, (unsigned long) paddr
, &pcb
, sizeof pcb
) == -1)
221 error (("%s"), kvm_geterr (core_kd
));
223 gdb_assert (bsd_kvm_supply_pcb
);
224 return bsd_kvm_supply_pcb (regcache
, &pcb
);
228 bsd_kvm_target::fetch_registers (struct regcache
*regcache
, int regnum
)
234 bsd_kvm_fetch_pcb (regcache
, bsd_kvm_paddr
);
238 /* On dumping core, BSD kernels store the faulting context (PCB)
239 in the variable "dumppcb". */
240 memset (nl
, 0, sizeof nl
);
241 nl
[0].n_name
= "_dumppcb";
243 if (kvm_nlist (core_kd
, nl
) == -1)
244 error (("%s"), kvm_geterr (core_kd
));
246 if (nl
[0].n_value
!= 0)
248 /* Found dumppcb. If it contains a valid context, return
250 if (bsd_kvm_fetch_pcb (regcache
, (struct pcb
*) nl
[0].n_value
))
254 /* Traditional BSD kernels have a process proc0 that should always
255 be present. The address of proc0's PCB is stored in the variable
258 memset (nl
, 0, sizeof nl
);
259 nl
[0].n_name
= "_proc0paddr";
261 if (kvm_nlist (core_kd
, nl
) == -1)
262 error (("%s"), kvm_geterr (core_kd
));
264 if (nl
[0].n_value
!= 0)
268 /* Found proc0paddr. */
269 if (kvm_read (core_kd
, nl
[0].n_value
, &paddr
, sizeof paddr
) == -1)
270 error (("%s"), kvm_geterr (core_kd
));
272 bsd_kvm_fetch_pcb (regcache
, paddr
);
276 #ifdef HAVE_STRUCT_THREAD_TD_PCB
277 /* In FreeBSD kernels for 5.0-RELEASE and later, the PCB no longer
278 lives in `struct proc' but in `struct thread'. The `struct
279 thread' for the initial thread for proc0 can be found in the
280 variable "thread0". */
282 memset (nl
, 0, sizeof nl
);
283 nl
[0].n_name
= "_thread0";
285 if (kvm_nlist (core_kd
, nl
) == -1)
286 error (("%s"), kvm_geterr (core_kd
));
288 if (nl
[0].n_value
!= 0)
293 nl
[0].n_value
+= offsetof (struct thread
, td_pcb
);
294 if (kvm_read (core_kd
, nl
[0].n_value
, &paddr
, sizeof paddr
) == -1)
295 error (("%s"), kvm_geterr (core_kd
));
297 bsd_kvm_fetch_pcb (regcache
, paddr
);
302 /* i18n: PCB == "Process Control Block". */
303 error (_("Cannot find a valid PCB"));
307 /* Kernel memory interface commands. */
308 struct cmd_list_element
*bsd_kvm_cmdlist
;
311 bsd_kvm_cmd (const char *arg
, int fromtty
)
313 /* ??? Should this become an alias for "target kvm"? */
316 #ifndef HAVE_STRUCT_THREAD_TD_PCB
319 bsd_kvm_proc_cmd (const char *arg
, int fromtty
)
324 error_no_arg (_("proc address"));
327 error (_("No kernel memory image."));
329 addr
= parse_and_eval_address (arg
);
330 #ifdef HAVE_STRUCT_LWP
331 addr
+= offsetof (struct lwp
, l_addr
);
333 addr
+= offsetof (struct proc
, p_addr
);
336 if (kvm_read (core_kd
, addr
, &bsd_kvm_paddr
, sizeof bsd_kvm_paddr
) == -1)
337 error (("%s"), kvm_geterr (core_kd
));
339 target_fetch_registers (get_current_regcache (), -1);
341 reinit_frame_cache ();
342 print_stack_frame (get_selected_frame (NULL
), 0, SRC_AND_LOC
, 1);
348 bsd_kvm_pcb_cmd (const char *arg
, int fromtty
)
351 /* i18n: PCB == "Process Control Block". */
352 error_no_arg (_("pcb address"));
355 error (_("No kernel memory image."));
357 bsd_kvm_paddr
= (struct pcb
*)(u_long
) parse_and_eval_address (arg
);
359 target_fetch_registers (get_current_regcache (), -1);
361 reinit_frame_cache ();
362 print_stack_frame (get_selected_frame (NULL
), 0, SRC_AND_LOC
, 1);
366 bsd_kvm_target::thread_alive (ptid_t ptid
)
372 bsd_kvm_target::pid_to_str (ptid_t ptid
)
377 /* Add the libkvm interface to the list of all possible targets and
378 register CUPPLY_PCB as the architecture-specific process control
379 block interpreter. */
382 bsd_kvm_add_target (int (*supply_pcb
)(struct regcache
*, struct pcb
*))
384 gdb_assert (bsd_kvm_supply_pcb
== NULL
);
385 bsd_kvm_supply_pcb
= supply_pcb
;
387 add_target (bsd_kvm_target_info
, bsd_kvm_target_open
);
389 add_prefix_cmd ("kvm", class_obscure
, bsd_kvm_cmd
, _("\
390 Generic command for manipulating the kernel memory interface."),
391 &bsd_kvm_cmdlist
, "kvm ", 0, &cmdlist
);
393 #ifndef HAVE_STRUCT_THREAD_TD_PCB
394 add_cmd ("proc", class_obscure
, bsd_kvm_proc_cmd
,
395 _("Set current context from proc address"), &bsd_kvm_cmdlist
);
397 add_cmd ("pcb", class_obscure
, bsd_kvm_pcb_cmd
,
398 /* i18n: PCB == "Process Control Block". */
399 _("Set current context from pcb address"), &bsd_kvm_cmdlist
);
401 /* Some notes on the ptid usage on this target.
403 The pid field represents the kvm inferior instance. Currently,
404 we don't support multiple kvm inferiors, but we start at 1
405 anyway. The lwp field is set to != 0, in case the core wants to
406 refer to the whole kvm inferior with ptid(1,0,0).
408 If kvm is made to export running processes as gdb threads,
409 the following form can be used:
410 ptid (1, 1, 0) -> kvm inferior 1, in kernel
411 ptid (1, 1, 1) -> kvm inferior 1, process 1
412 ptid (1, 1, 2) -> kvm inferior 1, process 2
413 ptid (1, 1, n) -> kvm inferior 1, process n */
415 bsd_kvm_ptid
= ptid_t (1, 1, 0);