xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/bsd-kvm.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /* BSD Kernel Data Access Library (libkvm) interface.
2 
3    Copyright (C) 2004-2019 Free Software Foundation, Inc.
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
9    the Free Software Foundation; either version 3 of the License, or
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
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #define _KMEMUSER
21 #include "defs.h"
22 #include "cli/cli-cmds.h"
23 #include "command.h"
24 #include "frame.h"
25 #include "regcache.h"
26 #include "target.h"
27 #include "process-stratum-target.h"
28 #include "value.h"
29 #include "gdbcore.h"
30 #include "inferior.h"          /* for get_exec_file */
31 #include "symfile.h"
32 #include "gdbthread.h"
33 #include "arch-utils.h"
34 
35 #include <fcntl.h>
36 #include <kvm.h>
37 #ifdef HAVE_NLIST_H
38 #include <nlist.h>
39 #endif
40 #include <paths.h>
41 #include "readline/readline.h"
42 #include <sys/param.h>
43 #include <sys/proc.h>
44 #ifdef HAVE_SYS_USER_H
45 #include <sys/user.h>
46 #endif
47 
48 #include "bsd-kvm.h"
49 
50 /* Kernel memory device file.  */
51 static const char *bsd_kvm_corefile;
52 
53 /* Kernel memory interface descriptor.  */
54 static kvm_t *core_kd;
55 
56 /* Address of process control block.  */
57 static struct pcb *bsd_kvm_paddr;
58 
59 /* Pointer to architecture-specific function that reconstructs the
60    register state from PCB and supplies it to REGCACHE.  */
61 static int (*bsd_kvm_supply_pcb)(struct regcache *regcache, struct pcb *pcb);
62 
63 /* This is the ptid we use while we're connected to kvm.  The kvm
64    target currently doesn't export any view of the running processes,
65    so this represents the kernel task.  */
66 static ptid_t bsd_kvm_ptid;
67 
68 /* The libkvm target.  */
69 
70 static const target_info bsd_kvm_target_info = {
71   "kvm",
72   N_("Kernel memory interface"),
73   N_("Use a kernel virtual memory image as a target.\n\
74 Optionally specify the filename of a core dump.")
75 };
76 
77 class bsd_kvm_target final : public process_stratum_target
78 {
79 public:
80   bsd_kvm_target () = default;
81 
82   const target_info &info () const override
83   { return bsd_kvm_target_info; }
84 
85   void close () override;
86 
87   void fetch_registers (struct regcache *, int) override;
88   enum target_xfer_status xfer_partial (enum target_object object,
89 					const char *annex,
90 					gdb_byte *readbuf,
91 					const gdb_byte *writebuf,
92 					ULONGEST offset, ULONGEST len,
93 					ULONGEST *xfered_len) override;
94 
95   void files_info () override;
96   bool thread_alive (ptid_t ptid) override;
97   const char *pid_to_str (ptid_t) override;
98 
99   bool has_memory () override { return true; }
100   bool has_stack () override { return true; }
101   bool has_registers () override { return true; }
102 };
103 
104 /* Target ops for libkvm interface.  */
105 static bsd_kvm_target bsd_kvm_ops;
106 
107 static void
108 bsd_kvm_target_open (const char *arg, int from_tty)
109 {
110   char errbuf[_POSIX2_LINE_MAX];
111   char *execfile = NULL;
112   kvm_t *temp_kd;
113   struct inferior *inf;
114   char *filename = NULL;
115 
116   target_preopen (from_tty);
117 
118   if (arg)
119     {
120       char *temp;
121 
122       filename = tilde_expand (arg);
123       if (filename[0] != '/')
124 	{
125 	  temp = concat (current_directory, "/", filename, (char *)NULL);
126 	  xfree (filename);
127 	  filename = temp;
128 	}
129     }
130 
131   execfile = get_exec_file (0);
132   temp_kd = kvm_openfiles (execfile, filename, NULL,
133 			   write_files ? O_RDWR : O_RDONLY, errbuf);
134   if (temp_kd == NULL)
135     error (("%s"), errbuf);
136 
137   bsd_kvm_corefile = filename;
138   unpush_target (&bsd_kvm_ops);
139   core_kd = temp_kd;
140   push_target (&bsd_kvm_ops);
141 
142   inf = add_inferior_silent (bsd_kvm_ptid.pid ());
143   inf->aspace = maybe_new_address_space ();
144   inf->pspace = new program_space (inf->aspace);
145 
146   inf->gdbarch = get_current_arch ();
147 
148   thread_info *tp = add_thread_silent (bsd_kvm_ptid);
149   switch_to_thread(tp);
150   inferior_ptid = bsd_kvm_ptid;
151 
152   symbol_file_add_main(execfile, 0);
153 
154   target_fetch_registers (get_current_regcache (), -1);
155 
156   reinit_frame_cache ();
157   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
158 }
159 
160 void
161 bsd_kvm_target::close ()
162 {
163   if (core_kd)
164     {
165       if (kvm_close (core_kd) == -1)
166 	warning (("%s"), kvm_geterr(core_kd));
167       core_kd = NULL;
168     }
169 
170   inferior_ptid = null_ptid;
171   discard_all_inferiors ();
172 }
173 
174 static LONGEST
175 bsd_kvm_xfer_memory (CORE_ADDR addr, ULONGEST len,
176 		     gdb_byte *readbuf, const gdb_byte *writebuf)
177 {
178   ssize_t nbytes = len;
179 
180   if (readbuf)
181     nbytes = kvm_read (core_kd, addr, readbuf, nbytes);
182   if (writebuf && nbytes > 0)
183     nbytes = kvm_write (core_kd, addr, writebuf, nbytes);
184   return nbytes;
185 }
186 
187 enum target_xfer_status
188 bsd_kvm_target::xfer_partial (enum target_object object,
189 			      const char *annex, gdb_byte *readbuf,
190 			      const gdb_byte *writebuf,
191 			      ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
192 {
193   switch (object)
194     {
195     case TARGET_OBJECT_MEMORY:
196       {
197 	LONGEST ret = bsd_kvm_xfer_memory (offset, len, readbuf, writebuf);
198 
199 	if (ret < 0)
200 	  return TARGET_XFER_E_IO;
201 	else if (ret == 0)
202 	  return TARGET_XFER_EOF;
203 	else
204 	  {
205 	    *xfered_len = (ULONGEST) ret;
206 	    return TARGET_XFER_OK;
207 	  }
208       }
209 
210     default:
211       return TARGET_XFER_E_IO;
212     }
213 }
214 
215 void
216 bsd_kvm_target::files_info ()
217 {
218   if (bsd_kvm_corefile && strcmp (bsd_kvm_corefile, _PATH_MEM) != 0)
219     printf_filtered (_("\tUsing the kernel crash dump %s.\n"),
220 		     bsd_kvm_corefile);
221   else
222     printf_filtered (_("\tUsing the currently running kernel.\n"));
223 }
224 
225 /* Fetch process control block at address PADDR.  */
226 
227 static int
228 bsd_kvm_fetch_pcb (struct regcache *regcache, struct pcb *paddr)
229 {
230   struct pcb pcb;
231 
232   if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
233     error (("%s"), kvm_geterr (core_kd));
234 
235   gdb_assert (bsd_kvm_supply_pcb);
236   return bsd_kvm_supply_pcb (regcache, &pcb);
237 }
238 
239 void
240 bsd_kvm_target::fetch_registers (struct regcache *regcache, int regnum)
241 {
242   struct nlist nl[2];
243 
244   if (bsd_kvm_paddr)
245     {
246       bsd_kvm_fetch_pcb (regcache, bsd_kvm_paddr);
247       return;
248     }
249 
250   /* On dumping core, BSD kernels store the faulting context (PCB)
251      in the variable "dumppcb".  */
252   memset (nl, 0, sizeof nl);
253   nl[0].n_name = "_dumppcb";
254 
255   if (kvm_nlist (core_kd, nl) == -1)
256     error (("%s"), kvm_geterr (core_kd));
257 
258   if (nl[0].n_value != 0)
259     {
260       /* Found dumppcb.  If it contains a valid context, return
261 	 immediately.  */
262       if (bsd_kvm_fetch_pcb (regcache, (struct pcb *) nl[0].n_value))
263 	return;
264     }
265 
266   /* Traditional BSD kernels have a process proc0 that should always
267      be present.  The address of proc0's PCB is stored in the variable
268      "proc0paddr".  */
269 
270   memset (nl, 0, sizeof nl);
271   nl[0].n_name = "_proc0paddr";
272 
273   if (kvm_nlist (core_kd, nl) == -1)
274     error (("%s"), kvm_geterr (core_kd));
275 
276   if (nl[0].n_value != 0)
277     {
278       struct pcb *paddr;
279 
280       /* Found proc0paddr.  */
281       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
282 	error (("%s"), kvm_geterr (core_kd));
283 
284       bsd_kvm_fetch_pcb (regcache, paddr);
285       return;
286     }
287 
288 #if 1 /* TODO: HAVE_STRUCT_LWP_L_ADDR */
289   memset (nl, 0, sizeof nl);
290   nl[0].n_name = "_lwp0";
291 
292   if (kvm_nlist (core_kd, nl) == -1)
293     error (("%s"), kvm_geterr (core_kd));
294 
295   if (nl[0].n_value != 0)
296     {
297       struct pcb *paddr;
298 
299       /* Found lwp0.  */
300       nl[0].n_value += offsetof (struct lwp, l_addr);
301       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
302 	error (("%s"), kvm_geterr (core_kd));
303 
304       bsd_kvm_fetch_pcb (regcache, paddr);
305       return;
306     }
307 #endif
308 
309 #ifdef HAVE_STRUCT_THREAD_TD_PCB
310   /* In FreeBSD kernels for 5.0-RELEASE and later, the PCB no longer
311      lives in `struct proc' but in `struct thread'.  The `struct
312      thread' for the initial thread for proc0 can be found in the
313      variable "thread0".  */
314 
315   memset (nl, 0, sizeof nl);
316   nl[0].n_name = "_thread0";
317 
318   if (kvm_nlist (core_kd, nl) == -1)
319     error (("%s"), kvm_geterr (core_kd));
320 
321   if (nl[0].n_value != 0)
322     {
323       struct pcb *paddr;
324 
325       /* Found thread0.  */
326       nl[0].n_value += offsetof (struct thread, td_pcb);
327       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
328 	error (("%s"), kvm_geterr (core_kd));
329 
330       bsd_kvm_fetch_pcb (regcache, paddr);
331       return;
332     }
333 #endif
334 
335   /* i18n: PCB == "Process Control Block".  */
336   error (_("Cannot find a valid PCB"));
337 }
338 
339 
340 /* Kernel memory interface commands.  */
341 struct cmd_list_element *bsd_kvm_cmdlist;
342 
343 static void
344 bsd_kvm_cmd (const char *arg, int fromtty)
345 {
346   /* ??? Should this become an alias for "target kvm"?  */
347 }
348 
349 #ifndef HAVE_STRUCT_THREAD_TD_PCB
350 
351 static void
352 bsd_kvm_proc_cmd (const char *arg, int fromtty)
353 {
354   CORE_ADDR addr;
355 
356   if (arg == NULL)
357     error_no_arg (_("proc address"));
358 
359   if (core_kd == NULL)
360     error (_("No kernel memory image."));
361 
362   addr = parse_and_eval_address (arg);
363 #ifdef HAVE_STRUCT_LWP
364   addr += offsetof (struct lwp, l_addr);
365 #else
366   addr += offsetof (struct proc, p_addr);
367 #endif
368 
369   if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
370     error (("%s"), kvm_geterr (core_kd));
371 
372   target_fetch_registers (get_current_regcache (), -1);
373 
374   reinit_frame_cache ();
375   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
376 }
377 
378 #endif
379 
380 static void
381 bsd_kvm_pcb_cmd (const char *arg, int fromtty)
382 {
383   if (arg == NULL)
384     /* i18n: PCB == "Process Control Block".  */
385     error_no_arg (_("pcb address"));
386 
387   if (core_kd == NULL)
388     error (_("No kernel memory image."));
389 
390   bsd_kvm_paddr = (struct pcb *)(u_long) parse_and_eval_address (arg);
391 
392   target_fetch_registers (get_current_regcache (), -1);
393 
394   reinit_frame_cache ();
395   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
396 }
397 
398 bool
399 bsd_kvm_target::thread_alive (ptid_t ptid)
400 {
401   return true;
402 }
403 
404 const char *
405 bsd_kvm_target::pid_to_str (ptid_t ptid)
406 {
407   static char buf[64];
408   xsnprintf (buf, sizeof buf, "<kvm>");
409   return buf;
410 }
411 
412 /* Add the libkvm interface to the list of all possible targets and
413    register CUPPLY_PCB as the architecture-specific process control
414    block interpreter.  */
415 
416 void
417 bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
418 {
419   gdb_assert (bsd_kvm_supply_pcb == NULL);
420   bsd_kvm_supply_pcb = supply_pcb;
421 
422   add_target (bsd_kvm_target_info, bsd_kvm_target_open);
423 
424   add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, _("\
425 Generic command for manipulating the kernel memory interface."),
426 		  &bsd_kvm_cmdlist, "kvm ", 0, &cmdlist);
427 
428 #ifndef HAVE_STRUCT_THREAD_TD_PCB
429   add_cmd ("proc", class_obscure, bsd_kvm_proc_cmd,
430 	   _("Set current context from proc address"), &bsd_kvm_cmdlist);
431 #endif
432   add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
433 	   /* i18n: PCB == "Process Control Block".  */
434 	   _("Set current context from pcb address"), &bsd_kvm_cmdlist);
435 
436   /* Some notes on the ptid usage on this target.
437 
438      The pid field represents the kvm inferior instance.  Currently,
439      we don't support multiple kvm inferiors, but we start at 1
440      anyway.  The lwp field is set to != 0, in case the core wants to
441      refer to the whole kvm inferior with ptid(1,0,0).
442 
443      If kvm is made to export running processes as gdb threads,
444      the following form can be used:
445      ptid (1, 1, 0) -> kvm inferior 1, in kernel
446      ptid (1, 1, 1) -> kvm inferior 1, process 1
447      ptid (1, 1, 2) -> kvm inferior 1, process 2
448      ptid (1, 1, n) -> kvm inferior 1, process n  */
449 
450   bsd_kvm_ptid = ptid_t (1, 1, 0);
451 }
452