1 /* $FreeBSD: ports/devel/gdb6/files/kvm-fbsd.c,v 1.2 2004/06/20 22:22:02 obrien Exp $ */
2 /* $DragonFly: src/gnu/usr.bin/gdb/gdb/Attic/kvm-fbsd.c,v 1.2 2004/10/24 18:05:10 joerg Exp $ */
4 /* Kernel core dump functions below target vector, for GDB.
5 Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
6 Free Software Foundation, Inc.
8 This file is part of GDB.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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>
38 #include <machine/frame.h>
39 //#include <sys/proc.h>
40 //#include <sys/sysctl.h>
41 //#include <sys/time.h>
42 //#include <sys/user.h>
49 #include <sys/sysctl.h>
54 #include "gdb_string.h"
55 #include "frame.h" /* required by inferior.h */
65 #include <readline/tilde.h>
70 kcore_files_info (struct target_ops *);
76 get_kcore_registers (int);
81 xfer_mem (CORE_ADDR, char *, int, int, struct mem_attrib *,
86 xfer_umem (CORE_ADDR, char *, int, int);
88 static char *core_file;
89 static kvm_t *core_kd;
90 static struct pcb cur_pcb;
91 static struct kinfo_proc *cur_proc;
93 static struct target_ops kcore_ops;
96 int kernel_writablecore;
98 /* Read the "thing" at kernel address 'addr' into the space pointed to
99 by point. The length of the "thing" is determined by the type of p.
100 Result is non-zero if transfer fails. */
102 #define kvread(addr, p) \
103 (target_read_memory ((CORE_ADDR) (addr), (char *) (p), sizeof (*(p))))
108 static CORE_ADDR kernbase;
109 struct minimal_symbol *sym;
113 sym = lookup_minimal_symbol ("kernbase", NULL, NULL);
117 kernbase = SYMBOL_VALUE_ADDRESS (sym);
123 #define KERNOFF (ksym_kernbase ())
124 #define INKERNEL(x) ((x) >= KERNOFF)
127 ksym_lookup(const char *name)
129 struct minimal_symbol *sym;
131 sym = lookup_minimal_symbol (name, NULL, NULL);
133 error ("kernel symbol `%s' not found.", name);
135 return SYMBOL_VALUE_ADDRESS (sym);
138 /* Provide the address of an initial PCB to use.
139 If this is a crash dump, try for "dumppcb".
140 If no "dumppcb" or it's /dev/mem, use proc0.
141 Return the core address of the PCB we found. */
146 struct minimal_symbol *sym;
150 /* Make sure things are open... */
151 if (!core_kd || !core_file)
154 /* If this is NOT /dev/mem try for dumppcb. */
155 if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1))
157 sym = lookup_minimal_symbol ("dumppcb", NULL, NULL);
160 addr = SYMBOL_VALUE_ADDRESS (sym);
165 /* OK, just use thread0's pcb. Note that curproc might
166 not exist, and if it does, it will point to gdb.
167 Therefore, just use proc0 and let the user set
168 some other context if they care about it. */
170 addr = ksym_lookup ("thread0");
171 if (kvread (addr, &val))
173 error ("cannot read thread0 pointer at %lx\n", addr);
178 /* Read the PCB address in thread structure. */
179 addr += offsetof (struct thread, td_pcb);
180 if (kvread (addr, &val))
182 error ("cannot read thread0->td_pcb pointer at %lx\n", addr);
187 /* thread0 is wholly in the kernel and cur_proc is only used for
188 reading user mem, so no point in setting this up. */
191 return ((CORE_ADDR)val);
194 /* Set the current context to that of the PCB struct at the system address
198 set_context (CORE_ADDR addr)
200 CORE_ADDR procaddr = 0;
202 if (kvread (addr, &cur_pcb))
203 error ("cannot read pcb at %#lx", addr);
205 /* Fetch all registers from core file. */
206 target_fetch_registers (-1);
208 /* Now, set up the frame cache, and print the top of stack. */
209 flush_cached_frames ();
211 set_current_frame (create_new_frame (read_fp (), read_pc ()));
212 set_current_frame (create_new_frame (deprecated_read_fp (), read_pc ()));
213 select_frame (get_current_frame ());
215 print_stack_frame (get_selected_frame (), -1, 1);
219 /* Discard all vestiges of any previous core file and mark data and stack
224 kcore_close (int quitting)
227 inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */
238 /* This routine opens and sets up the core file bfd. */
241 kcore_open (char *filename /* the core file */, int from_tty)
245 struct cleanup *old_chain;
250 target_preopen (from_tty);
252 /* The exec file is required for symbols. */
253 if (exec_bfd == NULL)
254 error ("No kernel exec file specified");
258 error ("No core file specified."
259 " (Use `detach' to stop debugging a core file.)");
265 error ("No core file specified.");
269 filename = tilde_expand (filename);
270 if (filename[0] != '/')
272 cp = concat (current_directory, "/", filename, NULL);
277 old_chain = make_cleanup (free, filename);
279 kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL,
280 kernel_writablecore ? O_RDWR: O_RDONLY, 0);
283 perror_with_name (filename);
287 /* Looks semi-reasonable. Toss the old core file and work on the new. */
289 discard_cleanups (old_chain); /* Don't free filename any more. */
290 core_file = filename;
291 unpush_target (&kcore_ops);
292 ontop = !push_target (&kcore_ops);
294 /* Note unpush_target (above) calls kcore_close. */
297 /* Print out the panic string if there is one. */
298 if (kvread (ksym_lookup ("panicstr"), &addr) == 0 &&
300 target_read_memory (addr, buf, sizeof(buf)) == 0)
303 for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)
304 if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp)))
308 printf_filtered ("panic: %s\n", buf);
311 /* Print all the panic messages if possible. */
312 if (symfile_objfile != NULL)
314 printf ("panic messages:\n---\n");
315 snprintf (buf, sizeof buf,
316 "/sbin/dmesg -N %s -M %s | \
317 /usr/bin/awk '/^(panic:|Fatal trap) / { printing = 1 } \
318 { if (printing) print $0 }'",
319 symfile_objfile->name, filename);
327 warning ("you won't be able to access this core file until you terminate\n"
328 "your %s; do ``info files''", target_longname);
332 /* Now, set up process context, and print the top of stack. */
333 (void)set_context (initial_pcb());
334 print_stack_frame (get_selected_frame (),
335 frame_relative_level (get_selected_frame ()), 1);
339 kcore_detach (char *args, int from_tty)
342 error ("Too many arguments");
343 unpush_target (&kcore_ops);
344 reinit_frame_cache ();
346 printf_filtered ("No kernel core file now.\n");
349 /* Get the registers out of a core file. This is the machine-
350 independent part. Fetch_core_registers is the machine-dependent
351 part, typically implemented in the xm-file for each architecture. */
353 /* We just get all the registers, so we don't use regno. */
357 get_kcore_registers (int regno)
360 /* XXX - Only read the pcb when set_context() is called.
361 When looking at a live kernel this may be a problem,
362 but the user can do another "proc" or "pcb" command to
363 grab a new copy of the pcb... */
365 /* Zero out register set then fill in the ones we know about. */
366 fetch_kcore_registers (&cur_pcb);
371 struct target_ops *t;
373 printf_filtered ("\t`%s'\n", core_file);
376 /* If mourn is being called in all the right places, this could be say
377 `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */
381 ignore (CORE_ADDR addr, char *contents)
388 xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write,
389 struct mem_attrib *attrib, struct target_ops *target)
394 if (!INKERNEL (memaddr))
395 return xfer_umem (memaddr, myaddr, len, write);
401 n = kvm_write (core_kd, memaddr, myaddr, len);
403 n = kvm_read (core_kd, memaddr, myaddr, len) ;
405 fprintf_unfiltered (gdb_stderr, "can not access 0x%lx, %s\n",
406 memaddr, kvm_geterr (core_kd));
415 xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */)
421 error ("---Can't read userspace from dump, or kernel process---\n");
426 error ("kvm_uwrite unimplemented\n");
428 n = kvm_uread (core_kd, &cur_proc->kp_proc, memaddr, myaddr, len) ;
437 _initialize_kcorelow (void)
439 kcore_ops.to_shortname = "kcore";
440 kcore_ops.to_longname = "Kernel core dump file";
442 "Use a core file as a target. Specify the filename of the core file.";
443 kcore_ops.to_open = kcore_open;
444 kcore_ops.to_close = kcore_close;
445 kcore_ops.to_attach = find_default_attach;
446 kcore_ops.to_detach = kcore_detach;
447 kcore_ops.to_fetch_registers = get_kcore_registers;
448 kcore_ops.to_xfer_memory = xfer_kmem;
449 kcore_ops.to_files_info = kcore_files_info;
450 kcore_ops.to_create_inferior = find_default_create_inferior;
451 kcore_ops.to_stratum = kcore_stratum;
452 kcore_ops.to_has_memory = 1;
453 kcore_ops.to_has_stack = 1;
454 kcore_ops.to_has_registers = 1;
455 kcore_ops.to_magic = OPS_MAGIC;
457 add_target (&kcore_ops);