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