1 /* BSD Kernel Data Access Library (libkvm) interface.
2 
3    Copyright (C) 2004-2021 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 "gdbthread.h"
32 #include "gdbsupport/pathstuff.h"
33 
34 #include <fcntl.h>
35 #include <kvm.h>
36 #ifdef HAVE_NLIST_H
37 #include <nlist.h>
38 #endif
39 #include <paths.h>
40 #include "readline/readline.h"
41 #include <sys/param.h>
42 #ifdef HAVE_SYS_USER_H
43 #include <sys/user.h>
44 #endif
45 #include <sys/proc.h>
46 
47 #include "bsd-kvm.h"
48 
49 /* Kernel memory device file.  */
50 static const char *bsd_kvm_corefile;
51 
52 /* Kernel memory interface descriptor.  */
53 static kvm_t *core_kd;
54 
55 /* Address of process control block.  */
56 static struct pcb *bsd_kvm_paddr;
57 
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);
61 
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;
66 
67 /* The libkvm target.  */
68 
69 static const target_info bsd_kvm_target_info = {
70   "kvm",
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.")
74 };
75 
76 class bsd_kvm_target final : public process_stratum_target
77 {
78 public:
79   bsd_kvm_target () = default;
80 
info()81   const target_info &info () const override
82   { return bsd_kvm_target_info; }
83 
84   void close () override;
85 
86   void fetch_registers (struct regcache *, int) override;
87   enum target_xfer_status xfer_partial (enum target_object object,
88 					const char *annex,
89 					gdb_byte *readbuf,
90 					const gdb_byte *writebuf,
91 					ULONGEST offset, ULONGEST len,
92 					ULONGEST *xfered_len) override;
93 
94   void files_info () override;
95   bool thread_alive (ptid_t ptid) override;
96   std::string pid_to_str (ptid_t) override;
97 
has_memory()98   bool has_memory () override { return true; }
has_stack()99   bool has_stack () override { return true; }
has_registers()100   bool has_registers () override { return true; }
101 };
102 
103 /* Target ops for libkvm interface.  */
104 static bsd_kvm_target bsd_kvm_ops;
105 
106 static void
bsd_kvm_target_open(const char * arg,int from_tty)107 bsd_kvm_target_open (const char *arg, int from_tty)
108 {
109   char errbuf[_POSIX2_LINE_MAX];
110   const char *execfile = NULL;
111   kvm_t *temp_kd;
112   char *filename = NULL;
113 
114   target_preopen (from_tty);
115 
116   if (arg)
117     {
118       filename = tilde_expand (arg);
119       if (filename[0] != '/')
120 	{
121 	  gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (filename));
122 
123 	  xfree (filename);
124 	  filename = temp.release ();
125 	}
126     }
127 
128   execfile = get_exec_file (0);
129   temp_kd = kvm_openfiles (execfile, filename, NULL,
130 			   write_files ? O_RDWR : O_RDONLY, errbuf);
131   if (temp_kd == NULL)
132     error (("%s"), errbuf);
133 
134   bsd_kvm_corefile = filename;
135   current_inferior ()->unpush_target (&bsd_kvm_ops);
136   core_kd = temp_kd;
137   current_inferior ()->push_target (&bsd_kvm_ops);
138 
139   thread_info *thr = add_thread_silent (&bsd_kvm_ops, bsd_kvm_ptid);
140   switch_to_thread (thr);
141 
142   target_fetch_registers (get_current_regcache (), -1);
143 
144   reinit_frame_cache ();
145   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
146 }
147 
148 void
close()149 bsd_kvm_target::close ()
150 {
151   if (core_kd)
152     {
153       if (kvm_close (core_kd) == -1)
154 	warning (("%s"), kvm_geterr(core_kd));
155       core_kd = NULL;
156     }
157 
158   switch_to_no_thread ();
159   exit_inferior_silent (current_inferior ());
160 }
161 
162 static LONGEST
bsd_kvm_xfer_memory(CORE_ADDR addr,ULONGEST len,gdb_byte * readbuf,const gdb_byte * writebuf)163 bsd_kvm_xfer_memory (CORE_ADDR addr, ULONGEST len,
164 		     gdb_byte *readbuf, const gdb_byte *writebuf)
165 {
166   ssize_t nbytes = len;
167 
168   if (readbuf)
169     nbytes = kvm_read (core_kd, addr, readbuf, nbytes);
170   if (writebuf && nbytes > 0)
171     nbytes = kvm_write (core_kd, addr, writebuf, nbytes);
172   return nbytes;
173 }
174 
175 enum target_xfer_status
xfer_partial(enum target_object object,const char * annex,gdb_byte * readbuf,const gdb_byte * writebuf,ULONGEST offset,ULONGEST len,ULONGEST * xfered_len)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)
180 {
181   switch (object)
182     {
183     case TARGET_OBJECT_MEMORY:
184       {
185 	LONGEST ret = bsd_kvm_xfer_memory (offset, len, readbuf, writebuf);
186 
187 	if (ret < 0)
188 	  return TARGET_XFER_E_IO;
189 	else if (ret == 0)
190 	  return TARGET_XFER_EOF;
191 	else
192 	  {
193 	    *xfered_len = (ULONGEST) ret;
194 	    return TARGET_XFER_OK;
195 	  }
196       }
197 
198     default:
199       return TARGET_XFER_E_IO;
200     }
201 }
202 
203 void
files_info()204 bsd_kvm_target::files_info ()
205 {
206   if (bsd_kvm_corefile && strcmp (bsd_kvm_corefile, _PATH_MEM) != 0)
207     printf_filtered (_("\tUsing the kernel crash dump %s.\n"),
208 		     bsd_kvm_corefile);
209   else
210     printf_filtered (_("\tUsing the currently running kernel.\n"));
211 }
212 
213 /* Fetch process control block at address PADDR.  */
214 
215 static int
bsd_kvm_fetch_pcb(struct regcache * regcache,struct pcb * paddr)216 bsd_kvm_fetch_pcb (struct regcache *regcache, struct pcb *paddr)
217 {
218   struct pcb pcb;
219 
220   if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
221     error (("%s"), kvm_geterr (core_kd));
222 
223   gdb_assert (bsd_kvm_supply_pcb);
224   return bsd_kvm_supply_pcb (regcache, &pcb);
225 }
226 
227 void
fetch_registers(struct regcache * regcache,int regnum)228 bsd_kvm_target::fetch_registers (struct regcache *regcache, int regnum)
229 {
230   struct nlist nl[2];
231 
232   if (bsd_kvm_paddr)
233     {
234       bsd_kvm_fetch_pcb (regcache, bsd_kvm_paddr);
235       return;
236     }
237 
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";
242 
243   if (kvm_nlist (core_kd, nl) == -1)
244     error (("%s"), kvm_geterr (core_kd));
245 
246   if (nl[0].n_value != 0)
247     {
248       /* Found dumppcb.  If it contains a valid context, return
249 	 immediately.  */
250       if (bsd_kvm_fetch_pcb (regcache, (struct pcb *) nl[0].n_value))
251 	return;
252     }
253 
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
256      "proc0paddr".  */
257 
258   memset (nl, 0, sizeof nl);
259   nl[0].n_name = "_proc0paddr";
260 
261   if (kvm_nlist (core_kd, nl) == -1)
262     error (("%s"), kvm_geterr (core_kd));
263 
264   if (nl[0].n_value != 0)
265     {
266       struct pcb *paddr;
267 
268       /* Found proc0paddr.  */
269       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
270 	error (("%s"), kvm_geterr (core_kd));
271 
272       bsd_kvm_fetch_pcb (regcache, paddr);
273       return;
274     }
275 
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".  */
281 
282   memset (nl, 0, sizeof nl);
283   nl[0].n_name = "_thread0";
284 
285   if (kvm_nlist (core_kd, nl) == -1)
286     error (("%s"), kvm_geterr (core_kd));
287 
288   if (nl[0].n_value != 0)
289     {
290       struct pcb *paddr;
291 
292       /* Found thread0.  */
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));
296 
297       bsd_kvm_fetch_pcb (regcache, paddr);
298       return;
299     }
300 #endif
301 
302   /* i18n: PCB == "Process Control Block".  */
303   error (_("Cannot find a valid PCB"));
304 }
305 
306 
307 /* Kernel memory interface commands.  */
308 struct cmd_list_element *bsd_kvm_cmdlist;
309 
310 static void
bsd_kvm_cmd(const char * arg,int fromtty)311 bsd_kvm_cmd (const char *arg, int fromtty)
312 {
313   /* ??? Should this become an alias for "target kvm"?  */
314 }
315 
316 #ifndef HAVE_STRUCT_THREAD_TD_PCB
317 
318 static void
bsd_kvm_proc_cmd(const char * arg,int fromtty)319 bsd_kvm_proc_cmd (const char *arg, int fromtty)
320 {
321   CORE_ADDR addr;
322 
323   if (arg == NULL)
324     error_no_arg (_("proc address"));
325 
326   if (core_kd == NULL)
327     error (_("No kernel memory image."));
328 
329   addr = parse_and_eval_address (arg);
330 #ifdef HAVE_STRUCT_LWP
331   addr += offsetof (struct lwp, l_addr);
332 #else
333 #ifndef __DragonFly__  /* XXX FIXME */
334   addr += offsetof (struct proc, p_addr);
335 #endif
336 #endif
337 
338   if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
339     error (("%s"), kvm_geterr (core_kd));
340 
341   target_fetch_registers (get_current_regcache (), -1);
342 
343   reinit_frame_cache ();
344   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
345 }
346 
347 #endif
348 
349 static void
bsd_kvm_pcb_cmd(const char * arg,int fromtty)350 bsd_kvm_pcb_cmd (const char *arg, int fromtty)
351 {
352   if (arg == NULL)
353     /* i18n: PCB == "Process Control Block".  */
354     error_no_arg (_("pcb address"));
355 
356   if (core_kd == NULL)
357     error (_("No kernel memory image."));
358 
359   bsd_kvm_paddr = (struct pcb *)(u_long) parse_and_eval_address (arg);
360 
361   target_fetch_registers (get_current_regcache (), -1);
362 
363   reinit_frame_cache ();
364   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
365 }
366 
367 bool
thread_alive(ptid_t ptid)368 bsd_kvm_target::thread_alive (ptid_t ptid)
369 {
370   return true;
371 }
372 
373 std::string
pid_to_str(ptid_t ptid)374 bsd_kvm_target::pid_to_str (ptid_t ptid)
375 {
376   return "<kvm>";
377 }
378 
379 /* Add the libkvm interface to the list of all possible targets and
380    register CUPPLY_PCB as the architecture-specific process control
381    block interpreter.  */
382 
383 void
bsd_kvm_add_target(int (* supply_pcb)(struct regcache *,struct pcb *))384 bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
385 {
386   gdb_assert (bsd_kvm_supply_pcb == NULL);
387   bsd_kvm_supply_pcb = supply_pcb;
388 
389   add_target (bsd_kvm_target_info, bsd_kvm_target_open);
390 
391   add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, _("\
392 Generic command for manipulating the kernel memory interface."),
393 		  &bsd_kvm_cmdlist, 0, &cmdlist);
394 
395 #ifndef HAVE_STRUCT_THREAD_TD_PCB
396   add_cmd ("proc", class_obscure, bsd_kvm_proc_cmd,
397 	   _("Set current context from proc address"), &bsd_kvm_cmdlist);
398 #endif
399   add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
400 	   /* i18n: PCB == "Process Control Block".  */
401 	   _("Set current context from pcb address"), &bsd_kvm_cmdlist);
402 
403   /* Some notes on the ptid usage on this target.
404 
405      The pid field represents the kvm inferior instance.  Currently,
406      we don't support multiple kvm inferiors, but we start at 1
407      anyway.  The lwp field is set to != 0, in case the core wants to
408      refer to the whole kvm inferior with ptid(1,0,0).
409 
410      If kvm is made to export running processes as gdb threads,
411      the following form can be used:
412      ptid (1, 1, 0) -> kvm inferior 1, in kernel
413      ptid (1, 1, 1) -> kvm inferior 1, process 1
414      ptid (1, 1, 2) -> kvm inferior 1, process 2
415      ptid (1, 1, n) -> kvm inferior 1, process n  */
416 
417   bsd_kvm_ptid = ptid_t (1, 1, 0);
418 }
419