Initial import from FreeBSD RELENG_4:
[dragonfly.git] / gnu / usr.bin / binutils / gdb / alpha / 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 /* $FreeBSD: src/gnu/usr.bin/binutils/gdb/alpha/kvm-fbsd.c,v 1.1.2.1 2000/12/11 01:03:18 obrien Exp $ */
23
24 /*
25  * This works like "remote" but, you use it like this:
26  *     target kcore /dev/mem
27  * or
28  *     target kcore /var/crash/host/core.0
29  *
30  * This way makes it easy to short-circut the whole bfd monster,
31  * and direct the inferior stuff to our libkvm implementation.
32  */
33
34 #include <sys/param.h>
35 #include <sys/time.h>
36 #include <sys/proc.h>
37 #include <sys/user.h>
38 #include <errno.h>
39 #include <signal.h>
40 #include <fcntl.h>
41 #include <kvm.h>
42 #include <paths.h>
43
44 #include "defs.h"
45 #include "gdb_string.h"
46 #include "frame.h"  /* required by inferior.h */
47 #include "inferior.h"
48 #include "symtab.h"
49 #include "command.h"
50 #include "bfd.h"
51 #include "target.h"
52 #include "gdbcore.h"
53
54 static void
55 kcore_files_info PARAMS ((struct target_ops *));
56
57 static void
58 kcore_close PARAMS ((int));
59
60 static void
61 get_kcore_registers PARAMS ((int));
62
63 static int
64 xfer_mem PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
65
66 static int
67 xfer_umem PARAMS ((CORE_ADDR, char *, int, int));
68
69 static char             *core_file;
70 static kvm_t            *core_kd;
71 static struct pcb       cur_pcb;
72
73 static struct target_ops kcore_ops;
74 int kernel_writablecore;
75
76 /*
77  * Read the "thing" at kernel address 'addr' into the space pointed to
78  * by point.  The length of the "thing" is determined by the type of p.
79  * Result is non-zero if transfer fails.
80  */
81 #define kvread(addr, p) \
82 (target_read_memory((CORE_ADDR)(addr), (char *)(p), sizeof(*(p))))
83
84
85 CORE_ADDR
86 ksym_lookup(name)
87   const char *name;
88 {
89   struct minimal_symbol *sym;
90
91   sym = lookup_minimal_symbol(name, NULL, NULL);
92   if (sym == NULL)
93     error("kernel symbol `%s' not found.", name);
94
95   return SYMBOL_VALUE_ADDRESS(sym);
96 }
97
98 /*
99  * Provide the address of an initial PCB to use.
100  * If this is a crash dump, try for "dumppcb".
101  * If no "dumppcb" or it's /dev/mem, use proc0.
102  * Return the core address of the PCB we found.
103  */
104 static CORE_ADDR
105 initial_pcb()
106 {
107   struct minimal_symbol *sym;
108   CORE_ADDR addr;
109   void *val;
110
111   /* Make sure things are open... */
112   if (!core_kd || !core_file)
113     return (0);
114
115   /* If this is NOT /dev/mem try for dumppcb. */
116   if (strncmp(core_file, _PATH_DEV, sizeof _PATH_DEV - 1)) {
117     sym = lookup_minimal_symbol("dumppcb", NULL, NULL);
118     if (sym != NULL) {
119       addr = SYMBOL_VALUE_ADDRESS(sym);
120       return (addr);
121     }
122   }
123
124   /*
125    * OK, just use proc0pcb.  Note that curproc might
126    * not exist, and if it does, it will point to gdb.
127    * Therefore, just use proc0 and let the user set
128    * some other context if they care about it.
129    */
130   addr = ksym_lookup("proc0paddr");
131   if (kvread(addr, &val)) {
132     error("cannot read proc0paddr pointer at %x\n", addr);
133     val = 0;
134   }
135
136   return ((CORE_ADDR)val);
137 }
138
139 /*
140  * Set the current context to that of the PCB struct
141  * at the system address passed.
142  */
143 static int
144 set_context(addr)
145   CORE_ADDR addr;
146 {
147
148   if (kvread(addr, &cur_pcb))
149     error("cannot read pcb at %#x", addr);
150
151   /* Fetch all registers from core file */
152   target_fetch_registers (-1);
153
154   /* Now, set up the frame cache, and print the top of stack */
155   flush_cached_frames();
156   set_current_frame (create_new_frame (read_fp (), read_pc ()));
157   select_frame (get_current_frame (), 0);
158   return (0);
159 }
160
161 /* Discard all vestiges of any previous core file and mark data and stack
162    spaces as empty.  */
163
164 /* ARGSUSED */
165 static void
166 kcore_close (quitting)
167      int quitting;
168 {
169
170   inferior_pid = 0;             /* Avoid confusion from thread stuff */
171
172   if (core_kd) {
173     kvm_close(core_kd);
174     free(core_file);
175     core_file = NULL;
176     core_kd = NULL;
177   }
178 }
179
180 /* This routine opens and sets up the core file bfd.  */
181
182 static void
183 kcore_open (filename, from_tty)
184      char *filename;    /* the core file */
185      int from_tty;
186 {
187   kvm_t         *kd;
188   const char *p;
189   struct cleanup *old_chain;
190   char buf[256], *cp;
191   int ontop;
192   CORE_ADDR addr;
193
194   target_preopen (from_tty);
195
196   /* The exec file is required for symbols. */
197   if (exec_bfd == NULL)
198     error("No kernel exec file specified");
199
200   if (core_kd) {
201     error ("No core file specified."
202            "  (Use `detach' to stop debugging a core file.)");
203     return;
204   }
205
206   if (!filename) {
207     error ("No core file specified.");
208     return;
209   }
210
211   filename = tilde_expand (filename);
212   if (filename[0] != '/') {
213     cp = concat (current_directory, "/", filename, NULL);
214     free (filename);
215     filename = cp;
216   }
217
218   old_chain = make_cleanup (free, filename);
219
220   kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL,
221                  kernel_writablecore ? O_RDWR: O_RDONLY, 0);
222   if (kd == NULL) {
223     perror_with_name (filename);
224     return;
225   }
226
227   /* Looks semi-reasonable.  Toss the old core file and work on the new.  */
228
229   discard_cleanups (old_chain);         /* Don't free filename any more */
230   core_file = filename;
231   unpush_target (&kcore_ops);
232   ontop = !push_target (&kcore_ops);
233
234   /* Note unpush_target (above) calls kcore_close. */
235   core_kd = kd;
236
237   /* print out the panic string if there is one */
238   if (kvread(ksym_lookup("panicstr"), &addr) == 0 &&
239       addr != 0 && 
240       target_read_memory(addr, buf, sizeof(buf)) == 0) {
241
242     for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)
243       if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp)))
244         *cp = '?';
245     *cp = '\0';
246     if (buf[0] != '\0')
247       printf_filtered("panic: %s\n", buf);
248   }
249
250   if (!ontop) {
251     warning (
252 "you won't be able to access this core file until you terminate\n\
253 your %s; do ``info files''", target_longname);
254     return;
255   }
256
257   /* Now, set up process context, and print the top of stack */
258   (void)set_context(initial_pcb());
259   print_stack_frame (selected_frame, selected_frame_level, 1);
260 }
261
262 static void
263 kcore_detach (args, from_tty)
264      char *args;
265      int from_tty;
266 {
267   if (args)
268     error ("Too many arguments");
269   unpush_target (&kcore_ops);
270   reinit_frame_cache ();
271   if (from_tty)
272     printf_filtered ("No kernel core file now.\n");
273 }
274
275 /* Get the registers out of a core file.  This is the machine-
276    independent part.  Fetch_core_registers is the machine-dependent
277    part, typically implemented in the xm-file for each architecture.  */
278
279 /* We just get all the registers, so we don't use regno.  */
280
281 /* ARGSUSED */
282 static void
283 get_kcore_registers (regno)
284      int regno;
285 {
286
287   /*
288    * XXX - Only read the pcb when set_context() is called.
289    * When looking at a live kernel this may be a problem,
290    * but the user can do another "proc" or "pcb" command to
291    * grab a new copy of the pcb...
292    */
293
294   /*
295    * Zero out register set then fill in the ones we know about.
296    */
297   fetch_kcore_registers (&cur_pcb);
298 }
299
300 static void
301 kcore_files_info (t)
302   struct target_ops *t;
303 {
304   printf_filtered ("\t`%s'\n", core_file);
305 }
306 \f
307 /* If mourn is being called in all the right places, this could be say
308    `gdb internal error' (since generic_mourn calls breakpoint_init_inferior).  */
309
310 static int
311 ignore (addr, contents)
312      CORE_ADDR addr;
313      char *contents;
314 {
315   return 0;
316 }
317
318 static int
319 xfer_kmem (memaddr, myaddr, len, write, target)
320   CORE_ADDR memaddr;
321   char *myaddr;
322   int len;
323   int write;
324   struct target_ops *target;
325 {
326   int n;
327
328 #if 0   /* XXX */
329   if (it is a user address)
330     return xfer_umem(memaddr, myaddr, len, write);
331 #endif
332
333   if (core_kd == NULL)
334     return 0;
335
336   if (write)
337     n = kvm_write(core_kd, memaddr, myaddr, len);
338   else
339     n = kvm_read (core_kd, memaddr, myaddr, len) ;
340   if (n < 0) {
341     fprintf_unfiltered (gdb_stderr, "can not access 0x%x, %s\n",
342                         memaddr, kvm_geterr(core_kd));
343     n = 0;
344   }
345
346   return n;
347 }
348
349 #if 0   /* XXX */
350 static int
351 xfer_umem (memaddr, myaddr, len, write)
352   CORE_ADDR memaddr;
353   char *myaddr;
354   int len;
355   int write; /* ignored */
356 {
357   int n;
358   struct proc proc;
359
360   if (kvread(cur_proc, &proc))
361     error("cannot read proc at %#x", cur_proc);
362   n = kvm_uread(core_kd, &proc, memaddr, myaddr, len) ;
363
364   if (n < 0)
365     return 0;
366   return n;
367 }
368 #endif
369
370 static void
371 set_proc_cmd(arg)
372   char *arg;
373 {
374   CORE_ADDR addr;
375   void *val;
376
377   if (!arg)
378     error_no_arg("proc address for the new context");
379
380   if (core_kd == NULL)
381     error("no kernel core file");
382
383   addr = (CORE_ADDR)parse_and_eval_address(arg);
384
385   /* Read the PCB address in proc structure. */
386   addr += (int) &((struct proc *)0)->p_addr;
387   if (kvread(addr, &val))
388     error("cannot read u area ptr");
389
390   if (set_context((CORE_ADDR)val))
391     error("invalid proc address");
392 }
393
394 static void
395 set_pcb_cmd(arg)
396   char *arg;
397 {
398   CORE_ADDR addr;
399   void *val;
400
401   if (!arg)
402     error_no_arg("pcb address for the new context");
403
404   if (core_kd == NULL)
405     error("no kernel core file");
406
407   addr = (CORE_ADDR)parse_and_eval_address(arg);
408
409   if (set_context(addr))
410     error("invalid pcb address");
411 }
412
413
414
415 void
416 _initialize_kcorelow()
417 {
418   kcore_ops.to_shortname = "kcore";
419   kcore_ops.to_longname = "Kernel core dump file";
420   kcore_ops.to_doc =
421     "Use a core file as a target.  Specify the filename of the core file.";
422   kcore_ops.to_open = kcore_open;
423   kcore_ops.to_close = kcore_close;
424   kcore_ops.to_attach = find_default_attach;
425   kcore_ops.to_detach = kcore_detach;
426   kcore_ops.to_fetch_registers = get_kcore_registers;
427   kcore_ops.to_xfer_memory = xfer_kmem;
428   kcore_ops.to_files_info = kcore_files_info;
429   kcore_ops.to_create_inferior = find_default_create_inferior;
430   kcore_ops.to_stratum = kcore_stratum;
431   kcore_ops.to_has_memory = 1;
432   kcore_ops.to_has_stack = 1;
433   kcore_ops.to_has_registers = 1;
434   kcore_ops.to_magic = OPS_MAGIC;
435
436   add_target (&kcore_ops);
437   add_com ("proc", class_obscure, set_proc_cmd, "Set current process context");
438 }