]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - gnu/usr.bin/binutils/gdb/kvm-fbsd.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / gnu / usr.bin / binutils / gdb / kvm-fbsd.c
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.
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$");
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 <ctype.h>
39 #include <fcntl.h>
40 #include <kvm.h>
41 #include <sys/sysctl.h>
42 #include <paths.h>
43
44 #include "defs.h"
45 #include <readline/tilde.h>
46 #include "gdb_string.h"
47 #include "frame.h"  /* required by inferior.h */
48 #include "inferior.h"
49 #include "symfile.h"
50 #include "objfiles.h"
51 #include "command.h"
52 #include "bfd.h"
53 #include "gdbcore.h"
54 #include "solist.h"
55
56 #include "kvm-fbsd-machine.h"
57
58 static void
59 kcore_files_info (struct target_ops *);
60
61 static void
62 kcore_close (int);
63
64 static void
65 get_kcore_registers (int);
66
67 static int
68 xfer_umem (CORE_ADDR, char *, int, int);
69
70 #ifdef SOLIB_ADD
71 static int kcore_solib_add_stub (PTR);
72 #endif
73
74 static char             *core_file;
75 static kvm_t            *core_kd;
76 static struct pcb       cur_pcb;
77 static struct kinfo_proc *cur_proc;
78
79 static struct target_ops kcore_ops;
80
81 int kernel_debugging;
82 int kernel_writablecore;
83
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.  */
87
88 #define kvread(addr, p) \
89   (target_read_memory ((CORE_ADDR) (addr), (char *) (p), sizeof (*(p))))
90
91 static CORE_ADDR
92 ksym_kernbase (void)
93 {
94   static CORE_ADDR kernbase;
95   struct minimal_symbol *sym;
96
97   if (kernbase == 0)
98     {
99       sym = lookup_minimal_symbol ("kernbase", NULL, NULL);
100       if (sym == NULL) {
101         kernbase = KERNBASE;
102       } else {
103         kernbase = SYMBOL_VALUE_ADDRESS (sym);
104       }
105     }
106   return kernbase;
107 }
108
109 #define KERNOFF         (ksym_kernbase ())
110 #define INKERNEL(x)     ((x) >= KERNOFF)
111
112 static CORE_ADDR
113 ksym_lookup(const char *name)
114 {
115   struct minimal_symbol *sym;
116
117   sym = lookup_minimal_symbol (name, NULL, NULL);
118   if (sym == NULL)
119     error ("kernel symbol `%s' not found.", name);
120
121   return SYMBOL_VALUE_ADDRESS (sym);
122 }
123
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.  */
128
129 static CORE_ADDR
130 initial_pcb (void)
131 {
132   struct minimal_symbol *sym;
133   CORE_ADDR addr;
134   void *val;
135
136   /* Make sure things are open...  */
137   if (!core_kd || !core_file)
138     return (0);
139
140   /* If this is NOT /dev/mem try for dumppcb.  */
141   if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1))
142     {
143       sym = lookup_minimal_symbol ("dumppcb", NULL, NULL);
144       if (sym != NULL)
145         {
146           addr = SYMBOL_VALUE_ADDRESS (sym);
147           return (addr);
148         }
149   }
150
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.  */
155
156   addr = ksym_lookup ("thread0");
157   if (kvread (addr, &val))
158     {
159       error ("cannot read thread0 pointer at %x\n", addr);
160       val = 0;
161     }
162   else
163     {
164       /* Read the PCB address in thread structure.  */
165       addr += offsetof (struct thread, td_pcb);
166       if (kvread (addr, &val))
167         {
168           error ("cannot read thread0->td_pcb pointer at %x\n", addr);
169           val = 0;
170         }
171     }
172
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.  */
175   cur_proc = 0;
176
177   return ((CORE_ADDR)val);
178 }
179
180 /* Set the current context to that of the PCB struct at the system address
181    passed.  */
182
183 static int
184 set_context (CORE_ADDR addr)
185 {
186   if (kvread (addr, &cur_pcb))
187     error ("cannot read pcb at %#x", addr);
188
189   /* Fetch all registers from core file.  */
190   target_fetch_registers (-1);
191
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);
196   return (0);
197 }
198
199 /* Discard all vestiges of any previous core file and mark data and stack
200    spaces as empty.  */
201
202 /* ARGSUSED */
203 static void
204 kcore_close (int quitting)
205 {
206
207   inferior_ptid = null_ptid;    /* Avoid confusion from thread stuff.  */
208
209   /* Clear out solib state while the bfd is still open. See
210      comments in clear_solib in solib.c. */
211 #ifdef CLEAR_SOLIB
212   CLEAR_SOLIB ();
213 #endif
214
215   if (core_kd)
216     {
217       kvm_close (core_kd);
218       free (core_file);
219       core_file = NULL;
220       core_kd = NULL;
221     }
222 }
223
224 /* This routine opens and sets up the core file bfd.  */
225
226 static void
227 kcore_open (char *filename /* the core file */, int from_tty)
228 {
229   kvm_t *kd;
230   const char *p;
231   struct cleanup *old_chain;
232   char buf[256], *cp;
233   int ontop;
234   CORE_ADDR addr;
235
236   target_preopen (from_tty);
237
238   /* The exec file is required for symbols.  */
239   if (exec_bfd == NULL)
240     error ("No kernel exec file specified");
241
242   if (core_kd)
243     {
244       error ("No core file specified."
245              "  (Use `detach' to stop debugging a core file.)");
246       return;
247     }
248
249   if (!filename)
250     {
251       error ("No core file specified.");
252       return;
253     }
254
255   filename = tilde_expand (filename);
256   if (filename[0] != '/')
257     {
258       cp = concat (current_directory, "/", filename, NULL);
259       free (filename);
260       filename = cp;
261     }
262
263   old_chain = make_cleanup (free, filename);
264
265   kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL,
266                  kernel_writablecore ? O_RDWR: O_RDONLY, 0);
267   if (kd == NULL)
268     {
269       perror_with_name (filename);
270       return;
271     }
272
273   /* Looks semi-reasonable.  Toss the old core file and work on the new.  */
274
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);
279
280   /* Note unpush_target (above) calls kcore_close.  */
281   core_kd = kd;
282
283   /* Print out the panic string if there is one.  */
284   if (kvread (ksym_lookup ("panicstr"), &addr) == 0 &&
285       addr != 0 &&
286       target_read_memory (addr, buf, sizeof(buf)) == 0)
287     {
288
289       for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)
290         if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp)))
291           *cp = '?';
292       *cp = '\0';
293       if (buf[0] != '\0')
294         printf_filtered ("panic: %s\n", buf);
295     }
296
297   /* Print all the panic messages if possible.  */
298   if (symfile_objfile != NULL)
299     {
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);
306       fflush (stdout);
307       system (buf);
308       printf ("---\n");
309     }
310
311   if (ontop)
312     {
313       /* Add symbols and section mappings for any kernel modules.  */
314 #ifdef SOLIB_ADD
315       current_target_so_ops = &kgdb_so_ops;
316       catch_errors (kcore_solib_add_stub, &from_tty, (char *) 0,
317                     RETURN_MASK_ALL);
318 #endif
319     }
320   else
321     {
322       warning ("you won't be able to access this core file until you terminate\n"
323                 "your %s; do ``info files''", target_longname);
324       return;
325     }
326
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);
330 }
331
332 static void
333 kcore_detach (char *args, int from_tty)
334 {
335   if (args)
336     error ("Too many arguments");
337   unpush_target (&kcore_ops);
338   reinit_frame_cache ();
339   if (from_tty)
340     printf_filtered ("No kernel core file now.\n");
341 }
342
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.  */
346
347 /* We just get all the registers, so we don't use regno.  */
348
349 /* ARGSUSED */
350 static void
351 get_kcore_registers (int regno)
352 {
353
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...  */
358
359   /* Zero out register set then fill in the ones we know about.  */
360   fetch_kcore_registers (&cur_pcb);
361 }
362
363 static void
364 kcore_files_info (t)
365   struct target_ops *t;
366 {
367   printf_filtered ("\t`%s'\n", core_file);
368 }
369 \f
370 static int
371 xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write,
372            struct mem_attrib *attrib, struct target_ops *target)
373 {
374   int n;
375
376
377   if (!INKERNEL (memaddr))
378     return xfer_umem (memaddr, myaddr, len, write);
379
380   if (core_kd == NULL)
381     return 0;
382
383   if (write)
384     n = kvm_write (core_kd, memaddr, myaddr, len);
385   else
386     n = kvm_read (core_kd, memaddr, myaddr, len) ;
387   if (n < 0) {
388     fprintf_unfiltered (gdb_stderr, "can not access 0x%x, %s\n",
389                         (unsigned)memaddr, kvm_geterr (core_kd));
390     n = 0;
391   }
392
393   return n;
394 }
395
396
397 static int
398 xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */)
399 {
400   int n = 0;
401
402   if (cur_proc == 0)
403     {
404       error ("---Can't read userspace from dump, or kernel process---\n");
405       return 0;
406     }
407
408   if (write)
409     error ("kvm_uwrite unimplemented\n");
410   else
411     n = kvm_uread (core_kd, cur_proc, memaddr, myaddr, len) ;
412
413   if (n < 0)
414     return 0;
415
416   return n;
417 }
418
419 static void
420 set_proc_cmd (char *arg, int from_tty)
421 {
422   CORE_ADDR addr, pid_addr, first_td;
423   void *val;
424   struct kinfo_proc *kp;
425   int cnt;
426   pid_t pid;
427
428   if (!arg)
429     error_no_arg ("proc address for the new context");
430
431   if (core_kd == NULL)
432     error ("no kernel core file");
433
434   addr = (CORE_ADDR) parse_and_eval_address (arg);
435
436   if (!INKERNEL (addr))
437     {
438       kp = kvm_getprocs (core_kd, KERN_PROC_PID, addr, &cnt);
439       if (!cnt)
440         error ("invalid pid");
441       addr = (CORE_ADDR)kp->ki_paddr;
442       cur_proc = kp;
443     }
444   else
445     {
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);
451       if (!cnt)
452         error("invalid pid");
453     }
454
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");
459
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");
464
465   /* Read the PCB address in proc structure. */
466   if (set_context ((CORE_ADDR) val))
467     error ("invalid proc address");
468 }
469
470 #ifdef SOLIB_ADD
471 static int
472 kcore_solib_add_stub (PTR from_ttyp)
473 {
474   SOLIB_ADD (NULL, *(int *) from_ttyp, &current_target, auto_solib_add);
475   return 0;
476 }
477 #endif /* SOLIB_ADD */
478
479 void
480 _initialize_kcorelow (void)
481 {
482   kcore_ops.to_shortname = "kcore";
483   kcore_ops.to_longname = "Kernel core dump file";
484   kcore_ops.to_doc =
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;
499
500   add_target (&kcore_ops);
501   add_com ("proc", class_obscure, set_proc_cmd, "Set current process context");
502 }