1 /* Kernel core dump functions below target vector, for GDB.
2 Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
3 Free Software Foundation, Inc.
5 This file is part of GDB.
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 2 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <sys/cdefs.h>
23 __FBSDID("$FreeBSD$");
26 * This works like "remote" but, you use it like this:
27 * target kcore /dev/mem
29 * target kcore /var/crash/host/core.0
31 * This way makes it easy to short-circut the whole bfd monster,
32 * and direct the inferior stuff to our libkvm implementation.
36 #include <sys/param.h>
41 #include <sys/sysctl.h>
45 #include <readline/tilde.h>
46 #include "gdb_string.h"
47 #include "frame.h" /* required by inferior.h */
56 #include "kvm-fbsd-machine.h"
59 kcore_files_info (struct target_ops *);
65 get_kcore_registers (int);
68 xfer_umem (CORE_ADDR, char *, int, int);
71 static int kcore_solib_add_stub (PTR);
74 static char *core_file;
75 static kvm_t *core_kd;
76 static struct pcb cur_pcb;
77 static struct kinfo_proc *cur_proc;
79 static struct target_ops kcore_ops;
82 int kernel_writablecore;
84 /* Read the "thing" at kernel address 'addr' into the space pointed to
85 by point. The length of the "thing" is determined by the type of p.
86 Result is non-zero if transfer fails. */
88 #define kvread(addr, p) \
89 (target_read_memory ((CORE_ADDR) (addr), (char *) (p), sizeof (*(p))))
94 static CORE_ADDR kernbase;
95 struct minimal_symbol *sym;
99 sym = lookup_minimal_symbol ("kernbase", NULL, NULL);
103 kernbase = SYMBOL_VALUE_ADDRESS (sym);
109 #define KERNOFF (ksym_kernbase ())
110 #define INKERNEL(x) ((x) >= KERNOFF)
113 ksym_lookup(const char *name)
115 struct minimal_symbol *sym;
117 sym = lookup_minimal_symbol (name, NULL, NULL);
119 error ("kernel symbol `%s' not found.", name);
121 return SYMBOL_VALUE_ADDRESS (sym);
124 /* Provide the address of an initial PCB to use.
125 If this is a crash dump, try for "dumppcb".
126 If no "dumppcb" or it's /dev/mem, use proc0.
127 Return the core address of the PCB we found. */
132 struct minimal_symbol *sym;
136 /* Make sure things are open... */
137 if (!core_kd || !core_file)
140 /* If this is NOT /dev/mem try for dumppcb. */
141 if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1))
143 sym = lookup_minimal_symbol ("dumppcb", NULL, NULL);
146 addr = SYMBOL_VALUE_ADDRESS (sym);
151 /* OK, just use thread0's pcb. Note that curproc might
152 not exist, and if it does, it will point to gdb.
153 Therefore, just use proc0 and let the user set
154 some other context if they care about it. */
156 addr = ksym_lookup ("thread0");
157 if (kvread (addr, &val))
159 error ("cannot read thread0 pointer at %x\n", addr);
164 /* Read the PCB address in thread structure. */
165 addr += offsetof (struct thread, td_pcb);
166 if (kvread (addr, &val))
168 error ("cannot read thread0->td_pcb pointer at %x\n", addr);
173 /* thread0 is wholly in the kernel and cur_proc is only used for
174 reading user mem, so no point in setting this up. */
177 return ((CORE_ADDR)val);
180 /* Set the current context to that of the PCB struct at the system address
184 set_context (CORE_ADDR addr)
186 if (kvread (addr, &cur_pcb))
187 error ("cannot read pcb at %#x", addr);
189 /* Fetch all registers from core file. */
190 target_fetch_registers (-1);
192 /* Now, set up the frame cache, and print the top of stack. */
193 flush_cached_frames ();
194 set_current_frame (create_new_frame (read_fp (), read_pc ()));
195 select_frame (get_current_frame (), 0);
199 /* Discard all vestiges of any previous core file and mark data and stack
204 kcore_close (int quitting)
207 inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */
209 /* Clear out solib state while the bfd is still open. See
210 comments in clear_solib in solib.c. */
224 /* This routine opens and sets up the core file bfd. */
227 kcore_open (char *filename /* the core file */, int from_tty)
231 struct cleanup *old_chain;
236 target_preopen (from_tty);
238 /* The exec file is required for symbols. */
239 if (exec_bfd == NULL)
240 error ("No kernel exec file specified");
244 error ("No core file specified."
245 " (Use `detach' to stop debugging a core file.)");
251 error ("No core file specified.");
255 filename = tilde_expand (filename);
256 if (filename[0] != '/')
258 cp = concat (current_directory, "/", filename, NULL);
263 old_chain = make_cleanup (free, filename);
265 kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL,
266 kernel_writablecore ? O_RDWR: O_RDONLY, 0);
269 perror_with_name (filename);
273 /* Looks semi-reasonable. Toss the old core file and work on the new. */
275 discard_cleanups (old_chain); /* Don't free filename any more. */
276 core_file = filename;
277 unpush_target (&kcore_ops);
278 ontop = !push_target (&kcore_ops);
280 /* Note unpush_target (above) calls kcore_close. */
283 /* Print out the panic string if there is one. */
284 if (kvread (ksym_lookup ("panicstr"), &addr) == 0 &&
286 target_read_memory (addr, buf, sizeof(buf)) == 0)
289 for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)
290 if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp)))
294 printf_filtered ("panic: %s\n", buf);
297 /* Print all the panic messages if possible. */
298 if (symfile_objfile != NULL)
300 printf ("panic messages:\n---\n");
301 snprintf (buf, sizeof buf,
302 "/sbin/dmesg -N %s -M %s | \
303 /usr/bin/awk '/^(panic:|Fatal trap) / { printing = 1 } \
304 { if (printing) print $0 }'",
305 symfile_objfile->name, filename);
313 /* Add symbols and section mappings for any kernel modules. */
315 current_target_so_ops = &kgdb_so_ops;
316 catch_errors (kcore_solib_add_stub, &from_tty, (char *) 0,
322 warning ("you won't be able to access this core file until you terminate\n"
323 "your %s; do ``info files''", target_longname);
327 /* Now, set up process context, and print the top of stack. */
328 (void)set_context (initial_pcb());
329 print_stack_frame (selected_frame, selected_frame_level, 1);
333 kcore_detach (char *args, int from_tty)
336 error ("Too many arguments");
337 unpush_target (&kcore_ops);
338 reinit_frame_cache ();
340 printf_filtered ("No kernel core file now.\n");
343 /* Get the registers out of a core file. This is the machine-
344 independent part. Fetch_core_registers is the machine-dependent
345 part, typically implemented in the xm-file for each architecture. */
347 /* We just get all the registers, so we don't use regno. */
351 get_kcore_registers (int regno)
354 /* XXX - Only read the pcb when set_context() is called.
355 When looking at a live kernel this may be a problem,
356 but the user can do another "proc" or "pcb" command to
357 grab a new copy of the pcb... */
359 /* Zero out register set then fill in the ones we know about. */
360 fetch_kcore_registers (&cur_pcb);
365 struct target_ops *t;
367 printf_filtered ("\t`%s'\n", core_file);
371 xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write,
372 struct mem_attrib *attrib, struct target_ops *target)
377 if (!INKERNEL (memaddr))
378 return xfer_umem (memaddr, myaddr, len, write);
384 n = kvm_write (core_kd, memaddr, myaddr, len);
386 n = kvm_read (core_kd, memaddr, myaddr, len) ;
388 fprintf_unfiltered (gdb_stderr, "can not access 0x%x, %s\n",
389 (unsigned)memaddr, kvm_geterr (core_kd));
398 xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */)
404 error ("---Can't read userspace from dump, or kernel process---\n");
409 error ("kvm_uwrite unimplemented\n");
411 n = kvm_uread (core_kd, cur_proc, memaddr, myaddr, len) ;
420 set_proc_cmd (char *arg, int from_tty)
422 CORE_ADDR addr, pid_addr, first_td;
424 struct kinfo_proc *kp;
429 error_no_arg ("proc address for the new context");
432 error ("no kernel core file");
434 addr = (CORE_ADDR) parse_and_eval_address (arg);
436 if (!INKERNEL (addr))
438 kp = kvm_getprocs (core_kd, KERN_PROC_PID, addr, &cnt);
440 error ("invalid pid");
441 addr = (CORE_ADDR)kp->ki_paddr;
446 /* Update cur_proc. */
447 pid_addr = addr + offsetof (struct proc, p_pid);
448 if (kvread (pid_addr, &pid))
449 error ("cannot read pid ptr");
450 cur_proc = kvm_getprocs (core_kd, KERN_PROC_PID, pid, &cnt);
452 error("invalid pid");
455 /* Find the first thread in the process. XXXKSE */
456 addr += offsetof (struct proc, p_threads.tqh_first);
457 if (kvread (addr, &first_td))
458 error ("cannot read thread ptr");
460 /* Read the PCB address in thread structure. */
461 addr = first_td + offsetof (struct thread, td_pcb);
462 if (kvread (addr, &val))
463 error("cannot read pcb ptr");
465 /* Read the PCB address in proc structure. */
466 if (set_context ((CORE_ADDR) val))
467 error ("invalid proc address");
472 kcore_solib_add_stub (PTR from_ttyp)
474 SOLIB_ADD (NULL, *(int *) from_ttyp, ¤t_target, auto_solib_add);
477 #endif /* SOLIB_ADD */
480 _initialize_kcorelow (void)
482 kcore_ops.to_shortname = "kcore";
483 kcore_ops.to_longname = "Kernel core dump file";
485 "Use a core file as a target. Specify the filename of the core file.";
486 kcore_ops.to_open = kcore_open;
487 kcore_ops.to_close = kcore_close;
488 kcore_ops.to_attach = find_default_attach;
489 kcore_ops.to_detach = kcore_detach;
490 kcore_ops.to_fetch_registers = get_kcore_registers;
491 kcore_ops.to_xfer_memory = xfer_kmem;
492 kcore_ops.to_files_info = kcore_files_info;
493 kcore_ops.to_create_inferior = find_default_create_inferior;
494 kcore_ops.to_stratum = kcore_stratum;
495 kcore_ops.to_has_memory = 1;
496 kcore_ops.to_has_stack = 1;
497 kcore_ops.to_has_registers = 1;
498 kcore_ops.to_magic = OPS_MAGIC;
500 add_target (&kcore_ops);
501 add_com ("proc", class_obscure, set_proc_cmd, "Set current process context");