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