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