Forced commit to add missing annotations.
[games.git] / gnu / usr.bin / gdb / gdb / kvm-fbsd.c
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 $ */
3
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.
7
8 This file is part of GDB.
9
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.
14
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.
19
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.
23 */
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 "target.h"
54 #include "gdb_string.h"
55 #include "frame.h"  /* required by inferior.h */
56 #include "inferior.h"
57 //#include "symtab.h"
58 #include "symfile.h"
59 #include "objfiles.h"
60 #include "command.h"
61 #include "bfd.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 static void
70 kcore_files_info (struct target_ops *);
71
72 static void
73 kcore_close (int);
74
75 static void
76 get_kcore_registers (int);
77
78
79         /*
80 static int
81 xfer_mem (CORE_ADDR, char *, int, int, struct mem_attrib *,
82           struct target_ops *);
83         */
84
85 static int
86 xfer_umem (CORE_ADDR, char *, int, int);
87
88 static char             *core_file;
89 static kvm_t            *core_kd;
90 static struct pcb       cur_pcb;
91 static struct kinfo_proc *cur_proc;
92
93 static struct target_ops kcore_ops;
94
95 int kernel_debugging;
96 int kernel_writablecore;
97
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.  */
101
102 #define kvread(addr, p) \
103   (target_read_memory ((CORE_ADDR) (addr), (char *) (p), sizeof (*(p))))
104
105 static CORE_ADDR
106 ksym_kernbase (void)
107 {
108   static CORE_ADDR kernbase;
109   struct minimal_symbol *sym;
110
111   if (kernbase == 0)
112     {
113       sym = lookup_minimal_symbol ("kernbase", NULL, NULL);
114       if (sym == NULL) {
115         kernbase = KERNBASE;
116       } else {
117         kernbase = SYMBOL_VALUE_ADDRESS (sym);
118       }
119     }
120   return kernbase;
121 }
122
123 #define KERNOFF         (ksym_kernbase ())
124 #define INKERNEL(x)     ((x) >= KERNOFF)
125
126 CORE_ADDR
127 ksym_lookup(const char *name)
128 {
129   struct minimal_symbol *sym;
130
131   sym = lookup_minimal_symbol (name, NULL, NULL);
132   if (sym == NULL)
133     error ("kernel symbol `%s' not found.", name);
134
135   return SYMBOL_VALUE_ADDRESS (sym);
136 }
137
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.  */
142
143 static CORE_ADDR
144 initial_pcb (void)
145 {
146   struct minimal_symbol *sym;
147   CORE_ADDR addr;
148   void *val;
149
150   /* Make sure things are open...  */
151   if (!core_kd || !core_file)
152     return (0);
153
154   /* If this is NOT /dev/mem try for dumppcb.  */
155   if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1))
156     {
157       sym = lookup_minimal_symbol ("dumppcb", NULL, NULL);
158       if (sym != NULL)
159         {
160           addr = SYMBOL_VALUE_ADDRESS (sym);
161           return (addr);
162         }
163   }
164
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.  */
169
170   addr = ksym_lookup ("thread0");
171   if (kvread (addr, &val))
172     {
173       error ("cannot read thread0 pointer at %lx\n", addr);
174       val = 0;
175     }
176   else
177     {
178       /* Read the PCB address in thread structure.  */
179       addr += offsetof (struct thread, td_pcb);
180       if (kvread (addr, &val))
181         {
182           error ("cannot read thread0->td_pcb pointer at %lx\n", addr);
183           val = 0;
184         }
185     }
186
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.  */
189   cur_proc = 0;
190
191   return ((CORE_ADDR)val);
192 }
193
194 /* Set the current context to that of the PCB struct at the system address
195    passed.  */
196
197 static int
198 set_context (CORE_ADDR addr)
199 {
200   CORE_ADDR procaddr = 0;
201
202   if (kvread (addr, &cur_pcb))
203     error ("cannot read pcb at %#lx", addr);
204
205   /* Fetch all registers from core file.  */
206   target_fetch_registers (-1);
207
208   /* Now, set up the frame cache, and print the top of stack.  */
209   flush_cached_frames ();
210 /*DEO XXX
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 ());
214 */
215   print_stack_frame (get_selected_frame (), -1, 1);
216   return (0);
217 }
218
219 /* Discard all vestiges of any previous core file and mark data and stack
220    spaces as empty.  */
221
222 /* ARGSUSED */
223 static void
224 kcore_close (int quitting)
225 {
226
227   inferior_ptid = null_ptid;    /* Avoid confusion from thread stuff.  */
228
229   if (core_kd)
230     {
231       kvm_close (core_kd);
232       free (core_file);
233       core_file = NULL;
234       core_kd = NULL;
235     }
236 }
237
238 /* This routine opens and sets up the core file bfd.  */
239
240 static void
241 kcore_open (char *filename /* the core file */, int from_tty)
242 {
243   kvm_t *kd;
244   const char *p;
245   struct cleanup *old_chain;
246   char buf[256], *cp;
247   int ontop;
248   CORE_ADDR addr;
249
250   target_preopen (from_tty);
251
252   /* The exec file is required for symbols.  */
253   if (exec_bfd == NULL)
254     error ("No kernel exec file specified");
255
256   if (core_kd)
257     {
258       error ("No core file specified."
259              "  (Use `detach' to stop debugging a core file.)");
260       return;
261     }
262
263   if (!filename)
264     {
265       error ("No core file specified.");
266       return;
267     }
268
269   filename = tilde_expand (filename);
270   if (filename[0] != '/')
271     {
272       cp = concat (current_directory, "/", filename, NULL);
273       free (filename);
274       filename = cp;
275     }
276
277   old_chain = make_cleanup (free, filename);
278
279   kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL,
280                  kernel_writablecore ? O_RDWR: O_RDONLY, 0);
281   if (kd == NULL)
282     {
283       perror_with_name (filename);
284       return;
285     }
286
287   /* Looks semi-reasonable.  Toss the old core file and work on the new.  */
288
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);
293
294   /* Note unpush_target (above) calls kcore_close.  */
295   core_kd = kd;
296
297   /* Print out the panic string if there is one.  */
298   if (kvread (ksym_lookup ("panicstr"), &addr) == 0 &&
299       addr != 0 &&
300       target_read_memory (addr, buf, sizeof(buf)) == 0)
301     {
302
303       for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)
304         if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp)))
305           *cp = '?';
306       *cp = '\0';
307       if (buf[0] != '\0')
308         printf_filtered ("panic: %s\n", buf);
309     }
310
311   /* Print all the panic messages if possible.  */
312   if (symfile_objfile != NULL)
313     {
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);
320       fflush (stdout);
321       system (buf);
322       printf ("---\n");
323     }
324
325   if (!ontop)
326     {
327       warning ("you won't be able to access this core file until you terminate\n"
328                 "your %s; do ``info files''", target_longname);
329       return;
330     }
331
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);
336 }
337
338 static void
339 kcore_detach (char *args, int from_tty)
340 {
341   if (args)
342     error ("Too many arguments");
343   unpush_target (&kcore_ops);
344   reinit_frame_cache ();
345   if (from_tty)
346     printf_filtered ("No kernel core file now.\n");
347 }
348
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.  */
352
353 /* We just get all the registers, so we don't use regno.  */
354
355 /* ARGSUSED */
356 static void
357 get_kcore_registers (int regno)
358 {
359
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...  */
364
365   /* Zero out register set then fill in the ones we know about.  */
366   fetch_kcore_registers (&cur_pcb);
367 }
368
369 static void
370 kcore_files_info (t)
371   struct target_ops *t;
372 {
373   printf_filtered ("\t`%s'\n", core_file);
374 }
375 \f
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). */
378
379         /*
380 static int
381 ignore (CORE_ADDR addr, char *contents)
382 {
383   return 0;
384 }
385         */
386
387 static int
388 xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write,
389            struct mem_attrib *attrib, struct target_ops *target)
390 {
391   int n;
392
393
394   if (!INKERNEL (memaddr))
395     return xfer_umem (memaddr, myaddr, len, write);
396
397   if (core_kd == NULL)
398     return 0;
399
400   if (write)
401     n = kvm_write (core_kd, memaddr, myaddr, len);
402   else
403     n = kvm_read (core_kd, memaddr, myaddr, len) ;
404   if (n < 0) {
405     fprintf_unfiltered (gdb_stderr, "can not access 0x%lx, %s\n",
406                         memaddr, kvm_geterr (core_kd));
407     n = 0;
408   }
409
410   return n;
411 }
412
413
414 static int
415 xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */)
416 {
417   int n = 0;
418
419   if (cur_proc == 0)
420     {
421       error ("---Can't read userspace from dump, or kernel process---\n");
422       return 0;
423     }
424
425   if (write)
426     error ("kvm_uwrite unimplemented\n");
427   else
428     n = kvm_uread (core_kd, &cur_proc->kp_proc, memaddr, myaddr, len) ;
429
430   if (n < 0)
431     return 0;
432
433   return n;
434 }
435
436 void
437 _initialize_kcorelow (void)
438 {
439   kcore_ops.to_shortname = "kcore";
440   kcore_ops.to_longname = "Kernel core dump file";
441   kcore_ops.to_doc =
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;
456
457   add_target (&kcore_ops);
458 }