ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/pack/freebsd/gdb6/files/kvm-fbsd.c
Revision: 2
Committed: 2007-01-31T14:59:36-08:00 (18 years, 4 months ago) by douglas
Content type: text/x-c
File size: 12876 byte(s)
Log Message:
This needs fixing...

File Contents

# User Rev Content
1 douglas 2 /* Kernel core dump functions below target vector, for GDB.
2     Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
3     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 2 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, write to the Free Software
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20     */
21    
22     #include <sys/cdefs.h>
23     __FBSDID("$FreeBSD: ports/devel/gdb6/files/kvm-fbsd.c,v 1.2 2004/06/20 22:22:02 obrien Exp $");
24    
25     /*
26     * This works like "remote" but, you use it like this:
27     * target kcore /dev/mem
28     * or
29     * target kcore /var/crash/host/core.0
30     *
31     * This way makes it easy to short-circut the whole bfd monster,
32     * and direct the inferior stuff to our libkvm implementation.
33     *
34     */
35    
36     #include <sys/param.h>
37     #include <sys/user.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>
43    
44     #include <ctype.h>
45     //#include <errno.h>
46     //#include <signal.h>
47     #include <fcntl.h>
48     #include <kvm.h>
49     #include <sys/sysctl.h>
50     #include <paths.h>
51    
52     #include "defs.h"
53     #include "gdb_string.h"
54     #include "frame.h" /* required by inferior.h */
55     #include "inferior.h"
56     //#include "symtab.h"
57     #include "symfile.h"
58     #include "objfiles.h"
59     #include "command.h"
60     #include "bfd.h"
61     //#include "target.h"
62     #include "gdbcore.h"
63     #include "solist.h"
64     #include "regcache.h"
65     #include <readline/tilde.h>
66    
67     #include "kvm-fbsd.h"
68    
69     #if __FreeBSD_version >= 500032
70     static void
71     kcore_files_info (struct target_ops *);
72    
73     static void
74     kcore_close (int);
75    
76     static void
77     get_kcore_registers (int);
78    
79    
80     /*
81     static int
82     xfer_mem (CORE_ADDR, char *, int, int, struct mem_attrib *,
83     struct target_ops *);
84     */
85    
86     static int
87     xfer_umem (CORE_ADDR, char *, int, int);
88    
89     static char *core_file;
90     static kvm_t *core_kd;
91     static struct pcb cur_pcb;
92     static struct kinfo_proc *cur_proc;
93    
94     static struct target_ops kcore_ops;
95    
96     int kernel_debugging;
97     int kernel_writablecore;
98    
99     /* Read the "thing" at kernel address 'addr' into the space pointed to
100     by point. The length of the "thing" is determined by the type of p.
101     Result is non-zero if transfer fails. */
102    
103     #define kvread(addr, p) \
104     (target_read_memory ((CORE_ADDR) (addr), (char *) (p), sizeof (*(p))))
105    
106     static CORE_ADDR
107     ksym_kernbase (void)
108     {
109     static CORE_ADDR kernbase;
110     struct minimal_symbol *sym;
111    
112     if (kernbase == 0)
113     {
114     sym = lookup_minimal_symbol ("kernbase", NULL, NULL);
115     if (sym == NULL) {
116     kernbase = KERNBASE;
117     } else {
118     kernbase = SYMBOL_VALUE_ADDRESS (sym);
119     }
120     }
121     return kernbase;
122     }
123    
124     #define KERNOFF (ksym_kernbase ())
125     #define INKERNEL(x) ((x) >= KERNOFF)
126    
127     CORE_ADDR
128     ksym_lookup(const char *name)
129     {
130     struct minimal_symbol *sym;
131    
132     sym = lookup_minimal_symbol (name, NULL, NULL);
133     if (sym == NULL)
134     error ("kernel symbol `%s' not found.", name);
135    
136     return SYMBOL_VALUE_ADDRESS (sym);
137     }
138    
139     /* Provide the address of an initial PCB to use.
140     If this is a crash dump, try for "dumppcb".
141     If no "dumppcb" or it's /dev/mem, use proc0.
142     Return the core address of the PCB we found. */
143    
144     static CORE_ADDR
145     initial_pcb (void)
146     {
147     struct minimal_symbol *sym;
148     CORE_ADDR addr;
149     void *val;
150    
151     /* Make sure things are open... */
152     if (!core_kd || !core_file)
153     return (0);
154    
155     /* If this is NOT /dev/mem try for dumppcb. */
156     if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1))
157     {
158     sym = lookup_minimal_symbol ("dumppcb", NULL, NULL);
159     if (sym != NULL)
160     {
161     addr = SYMBOL_VALUE_ADDRESS (sym);
162     return (addr);
163     }
164     }
165    
166     /* OK, just use thread0's pcb. Note that curproc might
167     not exist, and if it does, it will point to gdb.
168     Therefore, just use proc0 and let the user set
169     some other context if they care about it. */
170    
171     addr = ksym_lookup ("thread0");
172     if (kvread (addr, &val))
173     {
174     error ("cannot read thread0 pointer at %lx\n", addr);
175     val = 0;
176     }
177     else
178     {
179     /* Read the PCB address in thread structure. */
180     addr += offsetof (struct thread, td_pcb);
181     if (kvread (addr, &val))
182     {
183     error ("cannot read thread0->td_pcb pointer at %lx\n", addr);
184     val = 0;
185     }
186     }
187    
188     /* thread0 is wholly in the kernel and cur_proc is only used for
189     reading user mem, so no point in setting this up. */
190     cur_proc = 0;
191    
192     return ((CORE_ADDR)val);
193     }
194    
195     /* Set the current context to that of the PCB struct at the system address
196     passed. */
197    
198     static int
199     set_context (CORE_ADDR addr)
200     {
201     CORE_ADDR procaddr = 0;
202    
203     if (kvread (addr, &cur_pcb))
204     error ("cannot read pcb at %#lx", addr);
205    
206     /* Fetch all registers from core file. */
207     target_fetch_registers (-1);
208    
209     /* Now, set up the frame cache, and print the top of stack. */
210     flush_cached_frames ();
211     /*DEO XXX
212     set_current_frame (create_new_frame (read_fp (), read_pc ()));
213     set_current_frame (create_new_frame (deprecated_read_fp (), read_pc ()));
214     select_frame (get_current_frame ());
215     */
216     print_stack_frame (get_selected_frame (), -1, 1);
217     return (0);
218     }
219    
220     /* Discard all vestiges of any previous core file and mark data and stack
221     spaces as empty. */
222    
223     /* ARGSUSED */
224     static void
225     kcore_close (int quitting)
226     {
227    
228     inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */
229    
230     if (core_kd)
231     {
232     kvm_close (core_kd);
233     free (core_file);
234     core_file = NULL;
235     core_kd = NULL;
236     }
237     }
238    
239     /* This routine opens and sets up the core file bfd. */
240    
241     static void
242     kcore_open (char *filename /* the core file */, int from_tty)
243     {
244     kvm_t *kd;
245     const char *p;
246     struct cleanup *old_chain;
247     char buf[256], *cp;
248     int ontop;
249     CORE_ADDR addr;
250    
251     target_preopen (from_tty);
252    
253     /* The exec file is required for symbols. */
254     if (exec_bfd == NULL)
255     error ("No kernel exec file specified");
256    
257     if (core_kd)
258     {
259     error ("No core file specified."
260     " (Use `detach' to stop debugging a core file.)");
261     return;
262     }
263    
264     if (!filename)
265     {
266     error ("No core file specified.");
267     return;
268     }
269    
270     filename = tilde_expand (filename);
271     if (filename[0] != '/')
272     {
273     cp = concat (current_directory, "/", filename, NULL);
274     free (filename);
275     filename = cp;
276     }
277    
278     old_chain = make_cleanup (free, filename);
279    
280     kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL,
281     kernel_writablecore ? O_RDWR: O_RDONLY, 0);
282     if (kd == NULL)
283     {
284     perror_with_name (filename);
285     return;
286     }
287    
288     /* Looks semi-reasonable. Toss the old core file and work on the new. */
289    
290     discard_cleanups (old_chain); /* Don't free filename any more. */
291     core_file = filename;
292     unpush_target (&kcore_ops);
293     ontop = !push_target (&kcore_ops);
294    
295     /* Note unpush_target (above) calls kcore_close. */
296     core_kd = kd;
297    
298     /* Print out the panic string if there is one. */
299     if (kvread (ksym_lookup ("panicstr"), &addr) == 0 &&
300     addr != 0 &&
301     target_read_memory (addr, buf, sizeof(buf)) == 0)
302     {
303    
304     for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)
305     if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp)))
306     *cp = '?';
307     *cp = '\0';
308     if (buf[0] != '\0')
309     printf_filtered ("panic: %s\n", buf);
310     }
311    
312     /* Print all the panic messages if possible. */
313     if (symfile_objfile != NULL)
314     {
315     printf ("panic messages:\n---\n");
316     snprintf (buf, sizeof buf,
317     "/sbin/dmesg -N %s -M %s | \
318     /usr/bin/awk '/^(panic:|Fatal trap) / { printing = 1 } \
319     { if (printing) print $0 }'",
320     symfile_objfile->name, filename);
321     fflush (stdout);
322     system (buf);
323     printf ("---\n");
324     }
325    
326     if (!ontop)
327     {
328     warning ("you won't be able to access this core file until you terminate\n"
329     "your %s; do ``info files''", target_longname);
330     return;
331     }
332    
333     /* Now, set up process context, and print the top of stack. */
334     (void)set_context (initial_pcb());
335     print_stack_frame (get_selected_frame (),
336     frame_relative_level (get_selected_frame ()), 1);
337     }
338    
339     static void
340     kcore_detach (char *args, int from_tty)
341     {
342     if (args)
343     error ("Too many arguments");
344     unpush_target (&kcore_ops);
345     reinit_frame_cache ();
346     if (from_tty)
347     printf_filtered ("No kernel core file now.\n");
348     }
349    
350     /* Get the registers out of a core file. This is the machine-
351     independent part. Fetch_core_registers is the machine-dependent
352     part, typically implemented in the xm-file for each architecture. */
353    
354     /* We just get all the registers, so we don't use regno. */
355    
356     /* ARGSUSED */
357     static void
358     get_kcore_registers (int regno)
359     {
360    
361     /* XXX - Only read the pcb when set_context() is called.
362     When looking at a live kernel this may be a problem,
363     but the user can do another "proc" or "pcb" command to
364     grab a new copy of the pcb... */
365    
366     /* Zero out register set then fill in the ones we know about. */
367     fetch_kcore_registers (&cur_pcb);
368     }
369    
370     static void
371     kcore_files_info (t)
372     struct target_ops *t;
373     {
374     printf_filtered ("\t`%s'\n", core_file);
375     }
376    
377     /* If mourn is being called in all the right places, this could be say
378     `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */
379    
380     /*
381     static int
382     ignore (CORE_ADDR addr, char *contents)
383     {
384     return 0;
385     }
386     */
387    
388     static int
389     xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write,
390     struct mem_attrib *attrib, struct target_ops *target)
391     {
392     int n;
393    
394    
395     if (!INKERNEL (memaddr))
396     return xfer_umem (memaddr, myaddr, len, write);
397    
398     if (core_kd == NULL)
399     return 0;
400    
401     if (write)
402     n = kvm_write (core_kd, memaddr, myaddr, len);
403     else
404     n = kvm_read (core_kd, memaddr, myaddr, len) ;
405     if (n < 0) {
406     fprintf_unfiltered (gdb_stderr, "can not access 0x%lx, %s\n",
407     memaddr, kvm_geterr (core_kd));
408     n = 0;
409     }
410    
411     return n;
412     }
413    
414    
415     static int
416     xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */)
417     {
418     int n = 0;
419    
420     if (cur_proc == 0)
421     {
422     error ("---Can't read userspace from dump, or kernel process---\n");
423     return 0;
424     }
425    
426     if (write)
427     error ("kvm_uwrite unimplemented\n");
428     else
429     n = kvm_uread (core_kd, cur_proc, memaddr, myaddr, len) ;
430    
431     if (n < 0)
432     return 0;
433    
434     return n;
435     }
436    
437     static void
438     set_proc_cmd (char *arg, int from_tty)
439     {
440     CORE_ADDR addr, pid_addr, first_td;
441     void *val;
442     struct kinfo_proc *kp;
443     int cnt;
444     pid_t pid;
445    
446     if (!arg)
447     error_no_arg ("proc address for the new context");
448    
449     if (core_kd == NULL)
450     error ("no kernel core file");
451    
452     addr = (CORE_ADDR) parse_and_eval_address (arg);
453    
454     if (!INKERNEL (addr))
455     {
456     kp = kvm_getprocs (core_kd, KERN_PROC_PID, addr, &cnt);
457     if (!cnt)
458     error ("invalid pid");
459     addr = (CORE_ADDR)kp->ki_paddr;
460     cur_proc = kp;
461     }
462     else
463     {
464     /* Update cur_proc. */
465     pid_addr = addr + offsetof (struct proc, p_pid);
466     if (kvread (pid_addr, &pid))
467     error ("cannot read pid ptr");
468     cur_proc = kvm_getprocs (core_kd, KERN_PROC_PID, pid, &cnt);
469     if (!cnt)
470     error("invalid pid");
471     }
472    
473     /* Find the first thread in the process. XXXKSE */
474     addr += offsetof (struct proc, p_threads.tqh_first);
475     if (kvread (addr, &first_td))
476     error ("cannot read thread ptr");
477    
478     /* Read the PCB address in thread structure. */
479     addr = first_td + offsetof (struct thread, td_pcb);
480     if (kvread (addr, &val))
481     error("cannot read pcb ptr");
482    
483     /* Read the PCB address in proc structure. */
484     if (set_context ((CORE_ADDR) val))
485     error ("invalid proc address");
486     }
487     #else
488     int kernel_debugging = 0;
489     int kernel_writablecore = 0;
490    
491     CORE_ADDR
492     fbsd_kern_frame_saved_pc (struct frame_info *fi)
493     {
494     return 0;
495     }
496     #endif
497    
498     void
499     _initialize_kcorelow (void)
500     {
501     #if __FreeBSD_version >= 500032
502     kcore_ops.to_shortname = "kcore";
503     kcore_ops.to_longname = "Kernel core dump file";
504     kcore_ops.to_doc =
505     "Use a core file as a target. Specify the filename of the core file.";
506     kcore_ops.to_open = kcore_open;
507     kcore_ops.to_close = kcore_close;
508     kcore_ops.to_attach = find_default_attach;
509     kcore_ops.to_detach = kcore_detach;
510     kcore_ops.to_fetch_registers = get_kcore_registers;
511     kcore_ops.to_xfer_memory = xfer_kmem;
512     kcore_ops.to_files_info = kcore_files_info;
513     kcore_ops.to_create_inferior = find_default_create_inferior;
514     kcore_ops.to_stratum = kcore_stratum;
515     kcore_ops.to_has_memory = 1;
516     kcore_ops.to_has_stack = 1;
517     kcore_ops.to_has_registers = 1;
518     kcore_ops.to_magic = OPS_MAGIC;
519    
520     add_target (&kcore_ops);
521     add_com ("proc", class_obscure, set_proc_cmd, "Set current process context");
522     #endif
523     }