]> Git Repo - binutils.git/blob - gdb/bsd-kvm.c
Automatic date update in version.in
[binutils.git] / gdb / bsd-kvm.c
1 /* BSD Kernel Data Access Library (libkvm) interface.
2
3    Copyright (C) 2004-2022 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 "filenames.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 "gdbthread.h"
33 #include "gdbsupport/pathstuff.h"
34 #include "gdbsupport/gdb_tilde_expand.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 std::string 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   std::string filename;
115
116   target_preopen (from_tty);
117
118   if (arg)
119     {
120       filename = gdb_tilde_expand (arg);
121       if (!IS_ABSOLUTE_PATH (filename))
122         filename = gdb_abspath (filename.c_str ());
123     }
124
125   execfile = get_exec_file (0);
126   temp_kd = kvm_openfiles (execfile, filename.c_str (), NULL,
127                            write_files ? O_RDWR : O_RDONLY, errbuf);
128   if (temp_kd == NULL)
129     error (("%s"), errbuf);
130
131   bsd_kvm_corefile = filename;
132   current_inferior ()->unpush_target (&bsd_kvm_ops);
133   core_kd = temp_kd;
134   current_inferior ()->push_target (&bsd_kvm_ops);
135
136   thread_info *thr = add_thread_silent (&bsd_kvm_ops, bsd_kvm_ptid);
137   switch_to_thread (thr);
138
139   target_fetch_registers (get_current_regcache (), -1);
140
141   reinit_frame_cache ();
142   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
143 }
144
145 void
146 bsd_kvm_target::close ()
147 {
148   if (core_kd)
149     {
150       if (kvm_close (core_kd) == -1)
151         warning (("%s"), kvm_geterr(core_kd));
152       core_kd = NULL;
153     }
154
155   bsd_kvm_corefile.clear ();
156   switch_to_no_thread ();
157   exit_inferior_silent (current_inferior ());
158 }
159
160 static LONGEST
161 bsd_kvm_xfer_memory (CORE_ADDR addr, ULONGEST len,
162                      gdb_byte *readbuf, const gdb_byte *writebuf)
163 {
164   ssize_t nbytes = len;
165
166   if (readbuf)
167     nbytes = kvm_read (core_kd, addr, readbuf, nbytes);
168   if (writebuf && nbytes > 0)
169     nbytes = kvm_write (core_kd, addr, writebuf, nbytes);
170   return nbytes;
171 }
172
173 enum target_xfer_status
174 bsd_kvm_target::xfer_partial (enum target_object object,
175                               const char *annex, gdb_byte *readbuf,
176                               const gdb_byte *writebuf,
177                               ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
178 {
179   switch (object)
180     {
181     case TARGET_OBJECT_MEMORY:
182       {
183         LONGEST ret = bsd_kvm_xfer_memory (offset, len, readbuf, writebuf);
184
185         if (ret < 0)
186           return TARGET_XFER_E_IO;
187         else if (ret == 0)
188           return TARGET_XFER_EOF;
189         else
190           {
191             *xfered_len = (ULONGEST) ret;
192             return TARGET_XFER_OK;
193           }
194       }
195
196     default:
197       return TARGET_XFER_E_IO;
198     }
199 }
200
201 void
202 bsd_kvm_target::files_info ()
203 {
204   if (bsd_kvm_corefile != _PATH_MEM)
205     gdb_printf (_("\tUsing the kernel crash dump %s.\n"),
206                 bsd_kvm_corefile.c_str ());
207   else
208     gdb_printf (_("\tUsing the currently running kernel.\n"));
209 }
210
211 /* Fetch process control block at address PADDR.  */
212
213 static int
214 bsd_kvm_fetch_pcb (struct regcache *regcache, struct pcb *paddr)
215 {
216   struct pcb pcb;
217
218   if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
219     error (("%s"), kvm_geterr (core_kd));
220
221   gdb_assert (bsd_kvm_supply_pcb);
222   return bsd_kvm_supply_pcb (regcache, &pcb);
223 }
224
225 void
226 bsd_kvm_target::fetch_registers (struct regcache *regcache, int regnum)
227 {
228   struct nlist nl[2];
229
230   if (bsd_kvm_paddr)
231     {
232       bsd_kvm_fetch_pcb (regcache, bsd_kvm_paddr);
233       return;
234     }
235
236   /* On dumping core, BSD kernels store the faulting context (PCB)
237      in the variable "dumppcb".  */
238   memset (nl, 0, sizeof nl);
239   nl[0].n_name = (char *) "_dumppcb";
240
241   if (kvm_nlist (core_kd, nl) == -1)
242     error (("%s"), kvm_geterr (core_kd));
243
244   if (nl[0].n_value != 0)
245     {
246       /* Found dumppcb.  If it contains a valid context, return
247          immediately.  */
248       if (bsd_kvm_fetch_pcb (regcache, (struct pcb *) nl[0].n_value))
249         return;
250     }
251
252   /* Traditional BSD kernels have a process proc0 that should always
253      be present.  The address of proc0's PCB is stored in the variable
254      "proc0paddr".  */
255
256   memset (nl, 0, sizeof nl);
257   nl[0].n_name = (char *) "_proc0paddr";
258
259   if (kvm_nlist (core_kd, nl) == -1)
260     error (("%s"), kvm_geterr (core_kd));
261
262   if (nl[0].n_value != 0)
263     {
264       struct pcb *paddr;
265
266       /* Found proc0paddr.  */
267       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
268         error (("%s"), kvm_geterr (core_kd));
269
270       bsd_kvm_fetch_pcb (regcache, paddr);
271       return;
272     }
273
274 #ifdef HAVE_STRUCT_THREAD_TD_PCB
275   /* In FreeBSD kernels for 5.0-RELEASE and later, the PCB no longer
276      lives in `struct proc' but in `struct thread'.  The `struct
277      thread' for the initial thread for proc0 can be found in the
278      variable "thread0".  */
279
280   memset (nl, 0, sizeof nl);
281   nl[0].n_name = (char *) "_thread0";
282
283   if (kvm_nlist (core_kd, nl) == -1)
284     error (("%s"), kvm_geterr (core_kd));
285
286   if (nl[0].n_value != 0)
287     {
288       struct pcb *paddr;
289
290       /* Found thread0.  */
291       nl[0].n_value += offsetof (struct thread, td_pcb);
292       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
293         error (("%s"), kvm_geterr (core_kd));
294
295       bsd_kvm_fetch_pcb (regcache, paddr);
296       return;
297     }
298 #endif
299
300   /* i18n: PCB == "Process Control Block".  */
301   error (_("Cannot find a valid PCB"));
302 }
303 \f
304
305 /* Kernel memory interface commands.  */
306 struct cmd_list_element *bsd_kvm_cmdlist;
307
308 static void
309 bsd_kvm_cmd (const char *arg, int fromtty)
310 {
311   /* ??? Should this become an alias for "target kvm"?  */
312 }
313
314 #ifndef HAVE_STRUCT_THREAD_TD_PCB
315
316 static void
317 bsd_kvm_proc_cmd (const char *arg, int fromtty)
318 {
319   CORE_ADDR addr;
320
321   if (arg == NULL)
322     error_no_arg (_("proc address"));
323
324   if (core_kd == NULL)
325     error (_("No kernel memory image."));
326
327   addr = parse_and_eval_address (arg);
328 #ifdef HAVE_STRUCT_LWP
329   addr += offsetof (struct lwp, l_addr);
330 #else
331   addr += offsetof (struct proc, p_addr);
332 #endif
333
334   if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
335     error (("%s"), kvm_geterr (core_kd));
336
337   target_fetch_registers (get_current_regcache (), -1);
338
339   reinit_frame_cache ();
340   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
341 }
342
343 #endif
344
345 static void
346 bsd_kvm_pcb_cmd (const char *arg, int fromtty)
347 {
348   if (arg == NULL)
349     /* i18n: PCB == "Process Control Block".  */
350     error_no_arg (_("pcb address"));
351
352   if (core_kd == NULL)
353     error (_("No kernel memory image."));
354
355   bsd_kvm_paddr = (struct pcb *)(u_long) parse_and_eval_address (arg);
356
357   target_fetch_registers (get_current_regcache (), -1);
358
359   reinit_frame_cache ();
360   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
361 }
362
363 bool
364 bsd_kvm_target::thread_alive (ptid_t ptid)
365 {
366   return true;
367 }
368
369 std::string
370 bsd_kvm_target::pid_to_str (ptid_t ptid)
371 {
372   return "<kvm>";
373 }
374
375 /* Add the libkvm interface to the list of all possible targets and
376    register CUPPLY_PCB as the architecture-specific process control
377    block interpreter.  */
378
379 void
380 bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
381 {
382   gdb_assert (bsd_kvm_supply_pcb == NULL);
383   bsd_kvm_supply_pcb = supply_pcb;
384
385   add_target (bsd_kvm_target_info, bsd_kvm_target_open);
386   
387   add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, _("\
388 Generic command for manipulating the kernel memory interface."),
389                   &bsd_kvm_cmdlist, 0, &cmdlist);
390
391 #ifndef HAVE_STRUCT_THREAD_TD_PCB
392   add_cmd ("proc", class_obscure, bsd_kvm_proc_cmd,
393            _("Set current context from proc address"), &bsd_kvm_cmdlist);
394 #endif
395   add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
396            /* i18n: PCB == "Process Control Block".  */
397            _("Set current context from pcb address"), &bsd_kvm_cmdlist);
398
399   /* Some notes on the ptid usage on this target.
400
401      The pid field represents the kvm inferior instance.  Currently,
402      we don't support multiple kvm inferiors, but we start at 1
403      anyway.  The lwp field is set to != 0, in case the core wants to
404      refer to the whole kvm inferior with ptid(1,0,0).
405
406      If kvm is made to export running processes as gdb threads,
407      the following form can be used:
408      ptid (1, 1, 0) -> kvm inferior 1, in kernel
409      ptid (1, 1, 1) -> kvm inferior 1, process 1
410      ptid (1, 1, 2) -> kvm inferior 1, process 2
411      ptid (1, 1, n) -> kvm inferior 1, process n  */
412
413   bsd_kvm_ptid = ptid_t (1, 1, 0);
414 }
This page took 0.073433 seconds and 4 git commands to generate.