Merge from vendor branch GCC:
[dragonfly.git] / gnu / usr.bin / gdb / kgdb / kgdb.c
1 /*
2  * Copyright (c) 2004 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * $FreeBSD: src/gnu/usr.bin/gdb/kgdb/main.c,v 1.11 2006/01/04 23:17:52 kan Exp $
27  * $DragonFly: src/gnu/usr.bin/gdb/kgdb/kgdb.c,v 1.3 2008/01/14 21:36:38 corecode Exp $
28  */
29
30 #include <sys/cdefs.h>
31
32 #include <sys/param.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <sys/ioctl.h>
36 #include <sys/resource.h>
37 #include <sys/select.h>
38 #include <sys/time.h>
39 #include <sys/wait.h>
40 #include <sys/msgbuf.h>
41 #include <errno.h>
42 #include <err.h>
43 #include <fcntl.h>
44 #include <inttypes.h>
45 #include <kvm.h>
46 #include <limits.h>
47 #include <paths.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <unistd.h>
52 #include <linker_set.h>
53
54 /* libgdb stuff. */
55 #include <defs.h>
56 #include <frame.h>
57 #include <frame-unwind.h>
58 #include <inferior.h>
59 #include <interps.h>
60 #include <cli-out.h>
61 #include <main.h>
62 #include <target.h>
63 #include <top.h>
64 #include <bfd.h>
65 #include <gdbcore.h>
66 #include <target.h>
67
68 extern void symbol_file_add_main (char *args, int from_tty);
69
70 #include "kgdb.h"
71
72 kvm_t *kvm;
73 static char kvm_err[_POSIX2_LINE_MAX];
74
75 static int dumpnr;
76 static int verbose;
77
78 static char crashdir[PATH_MAX];
79 static char *kernel;
80 static char *remote;
81 static char *vmcore;
82
83 static void (*kgdb_new_objfile_chain)(struct objfile * objfile);
84
85 uintptr_t
86 lookup(const char *sym)
87 {
88         struct nlist nl[2];
89
90         nl[0].n_name = (char *)(uintptr_t)sym;
91         nl[1].n_name = NULL;
92         if (kvm_nlist(kvm, nl) != 0) {
93                 warnx("kvm_nlist(%s): %s", sym, kvm_geterr(kvm));
94                 return (0);
95         }
96         return (nl[0].n_value);
97 }
98
99 static void
100 kgdb_atexit(void)
101 {
102         if (kvm != NULL)
103                 kvm_close(kvm);
104 }
105
106 static void
107 usage(void)
108 {
109
110         fprintf(stderr,
111             "usage: %s [-afqv] [-d crashdir] [-c core | -n dumpnr | -r device]\n"
112             "\t[kernel [core]]\n", getprogname());
113         exit(1);
114 }
115
116 static void
117 kernel_from_dumpnr(int nr)
118 {
119         char path[PATH_MAX];
120         FILE *info;
121         char *s;
122         struct stat st;
123         int l;
124
125         /*
126          * If there's a kernel image right here in the crash directory, then
127          * use it.  The kernel image is either called kernel.<nr> or is in a
128          * subdirectory kernel.<nr> and called kernel.  The latter allows us
129          * to collect the modules in the same place.
130          */
131         snprintf(path, sizeof(path), "%s/kernel.%d", crashdir, nr);
132         if (stat(path, &st) == 0) {
133                 if (S_ISREG(st.st_mode)) {
134                         kernel = strdup(path);
135                         return;
136                 }
137                 if (S_ISDIR(st.st_mode)) {
138                         snprintf(path, sizeof(path), "%s/kernel.%d/kernel",
139                             crashdir, nr);
140                         if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
141                                 kernel = strdup(path);
142                                 return;
143                         }
144                 }
145         }
146
147         /*
148          * No kernel image here.  Parse the dump header.  The kernel object
149          * directory can be found there and we probably have the kernel
150          * image still in it.  The object directory may also have a kernel
151          * with debugging info (called kernel.debug).  If we have a debug
152          * kernel, use it.
153          */
154         snprintf(path, sizeof(path), "%s/info.%d", crashdir, nr);
155         info = fopen(path, "r");
156         if (info == NULL) {
157                 warn(path);
158                 return;
159         }
160         while (fgets(path, sizeof(path), info) != NULL) {
161                 l = strlen(path);
162                 if (l > 0 && path[l - 1] == '\n')
163                         path[--l] = '\0';
164                 if (strncmp(path, "    ", 4) == 0) {
165                         s = strchr(path, ':');
166                         s = (s == NULL) ? path + 4 : s + 1;
167                         l = snprintf(path, sizeof(path), "%s/kernel.debug", s);
168                         if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) {
169                                 path[l - 6] = '\0';
170                                 if (stat(path, &st) == -1 ||
171                                     !S_ISREG(st.st_mode))
172                                         break;
173                         }
174                         kernel = strdup(path);
175                         break;
176                 }
177         }
178         fclose(info);
179 }
180
181 static void
182 kgdb_new_objfile(struct objfile *objfile)
183 {
184 #if 0
185         printf("XXX: %s(%p)\n", __func__, objfile);
186         if (objfile != NULL) {
187                 goto out;
188         }
189
190 out:
191 #endif
192         if (kgdb_new_objfile_chain != NULL)
193                 kgdb_new_objfile_chain(objfile);
194 }
195
196 static CORE_ADDR
197 kgdb_parse(const char *exp)
198 {
199         struct cleanup *old_chain;
200         struct expression *expr;
201         struct value *val;
202         char *s;
203         CORE_ADDR n;
204
205         s = strdup(exp);
206         old_chain = make_cleanup(free_current_contents, &expr);
207         expr = parse_expression(s);
208         val = (expr != NULL) ? evaluate_expression(expr) : NULL;
209         n = (val != NULL) ? value_as_address(val) : 0;
210         do_cleanups(old_chain);
211         free(s);
212         return (n);
213 }
214
215 #define MSGBUF_SEQ_TO_POS(size, seq)    ((seq) % (size))
216
217 static void
218 kgdb_init_target(void)
219 {
220         bfd *kern_bfd;
221         int kern_desc;
222
223         kern_desc = open(kernel, O_RDONLY);
224         if (kern_desc == -1)
225                 errx(1, "couldn't open a kernel image");
226
227         kern_bfd = bfd_fdopenr(kernel, gnutarget, kern_desc);
228         if (kern_bfd == NULL) {
229                 close(kern_desc);
230                 errx(1, "\"%s\": can't open to probe ABI: %s.", kernel,
231                         bfd_errmsg (bfd_get_error ()));
232         }
233         bfd_set_cacheable(kern_bfd, 1);
234
235         if (!bfd_check_format (kern_bfd, bfd_object)) {
236                 bfd_close(kern_bfd);
237                 errx(1, "\"%s\": not in executable format: %s", kernel,
238                         bfd_errmsg(bfd_get_error()));
239         }
240
241         set_gdbarch_from_file (kern_bfd);
242         bfd_close(kern_bfd);
243
244         frame_unwind_prepend_unwinder(current_gdbarch, &kgdb_trgt_trapframe_unwind);
245
246         symbol_file_add_main (kernel, 0);
247         if (remote)
248                 push_remote_target (remote, 0);
249         else
250                 kgdb_target();
251 }
252
253 static void
254 kgdb_display_msgbuf(void)
255 {
256         uintptr_t addr;
257         struct msgbuf *bufp, buf;
258         size_t rseq, wseq;
259         char c;
260
261         /*
262          * Display the unread portion of the message buffer. This gives the
263          * user a some initial data to work from.
264          */
265         addr = lookup("_msgbufp");
266         if (addr == 0)
267                 return;
268         read_memory((CORE_ADDR)addr, (char *)&bufp, sizeof(bufp));
269         read_memory((CORE_ADDR)bufp, (char *)&buf, sizeof(buf));
270         if (buf.msg_size == 0 || buf.msg_bufr == buf.msg_bufx)
271                 return;
272         rseq = MSGBUF_SEQ_TO_POS(buf.msg_size, buf.msg_bufr);
273         wseq = MSGBUF_SEQ_TO_POS(buf.msg_size, buf.msg_bufx);
274
275         printf("\nUnread portion of the kernel message buffer:\n");
276         while (rseq < wseq) {
277                 read_memory((CORE_ADDR)buf.msg_ptr + rseq, &c, 1);
278                 putchar(c);
279                 rseq++;
280                 if (rseq == buf.msg_size)
281                         rseq = 0;
282         }
283         if (c != '\n')
284                 putchar('\n');
285         putchar('\n');
286 }
287
288 static void
289 kgdb_init(char *argv0 __unused)
290 {
291         kgdb_init_target();
292
293         set_prompt("(kgdb) ");
294         kgdb_display_msgbuf();
295         print_stack_frame(get_selected_frame(NULL),
296             frame_relative_level(get_selected_frame(NULL)), 1);
297 }
298
299 int
300 main(int argc, char *argv[])
301 {
302         char path[PATH_MAX];
303         struct stat st;
304         struct captured_main_args args;
305         char *s;
306         int a, ch, quiet, writecore;
307
308         dumpnr = -1;
309
310         strlcpy(crashdir, "/var/crash", sizeof(crashdir));
311         s = getenv("KGDB_CRASH_DIR");
312         if (s != NULL)
313                 strlcpy(crashdir, s, sizeof(crashdir));
314
315         /* Convert long options into short options. */
316         for (a = 1; a < argc; a++) {
317                 s = argv[a];
318                 if (s[0] == '-') {
319                         s++;
320                         /* Long options take either 1 or 2 dashes. */
321                         if (s[0] == '-')
322                                 s++;
323                         if (strcmp(s, "quiet") == 0)
324                                 argv[a] = "-q";
325                         else if (strcmp(s, "fullname") == 0)
326                                 argv[a] = "-f";
327                 }
328         }
329
330         quiet = 0;
331         writecore = 0;
332
333         while ((ch = getopt(argc, argv, "ac:d:fn:qr:vw")) != -1) {
334                 switch (ch) {
335                 case 'a':
336                         annotation_level++;
337                         break;
338                 case 'c':       /* use given core file. */
339                         if (vmcore != NULL) {
340                                 warnx("option %c: can only be specified once",
341                                     optopt);
342                                 usage();
343                                 /* NOTREACHED */
344                         }
345                         vmcore = strdup(optarg);
346                         break;
347                 case 'd':       /* lookup dumps in given directory. */
348                         strlcpy(crashdir, optarg, sizeof(crashdir));
349                         break;
350                 case 'f':
351                         annotation_level = 1;
352                         break;
353                 case 'n':       /* use dump with given number. */
354                         dumpnr = strtol(optarg, &s, 0);
355                         if (dumpnr < 0 || *s != '\0') {
356                                 warnx("option %c: invalid kernel dump number",
357                                     optopt);
358                                 usage();
359                                 /* NOTREACHED */
360                         }
361                         break;
362                 case 'q':
363                         quiet = 1;
364                         break;
365                 case 'r':       /* use given device for remote session. */
366                         if (remote != NULL) {
367                                 warnx("option %c: can only be specified once",
368                                     optopt);
369                                 usage();
370                                 /* NOTREACHED */
371                         }
372                         remote = strdup(optarg);
373                         break;
374                 case 'v':       /* increase verbosity. */
375                         verbose++;
376                         break;
377                 case 'w':       /* core file is writeable. */
378                         writecore = 1;
379                         break;
380                 case '?':
381                 default:
382                         usage();
383                 }
384         }
385
386         if (((vmcore != NULL) ? 1 : 0) + ((dumpnr >= 0) ? 1 : 0) +
387             ((remote != NULL) ? 1 : 0) > 1) {
388                 warnx("options -c, -n and -r are mutually exclusive");
389                 usage();
390                 /* NOTREACHED */
391         }
392
393         if (verbose > 1)
394                 warnx("using %s as the crash directory", crashdir);
395
396         if (argc > optind)
397                 kernel = strdup(argv[optind++]);
398
399         if (argc > optind && (dumpnr >= 0 || remote != NULL)) {
400                 warnx("options -n and -r do not take a core file. Ignored");
401                 optind = argc;
402         }
403
404         if (dumpnr >= 0) {
405                 snprintf(path, sizeof(path), "%s/vmcore.%d", crashdir, dumpnr);
406                 if (stat(path, &st) == -1)
407                         err(1, path);
408                 if (!S_ISREG(st.st_mode))
409                         errx(1, "%s: not a regular file", path);
410                 vmcore = strdup(path);
411         } else if (remote != NULL && remote[0] != ':' && remote[0] != '|') {
412                 if (stat(remote, &st) != 0) {
413                         snprintf(path, sizeof(path), "/dev/%s", remote);
414                         if (stat(path, &st) != 0) {
415                                 err(1, "%s", remote);
416                                 /* NOTREACHED */
417                         }
418                         free(remote);
419                         remote = strdup(path);
420                 }
421                 if (!S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode)) {
422                         errx(1, "%s: not a special file, FIFO or socket",
423                             remote);
424                         /* NOTREACHED */
425                 }
426         } else if (argc > optind) {
427                 if (vmcore == NULL)
428                         vmcore = strdup(argv[optind++]);
429                 if (argc > optind)
430                         warnx("multiple core files specified. Ignored");
431         } else if (vmcore == NULL && kernel == NULL) {
432                 vmcore = strdup(_PATH_MEM);
433                 kernel = strdup(getbootfile());
434         }
435
436         if (verbose) {
437                 if (vmcore != NULL)
438                         warnx("core file: %s", vmcore);
439                 if (remote != NULL)
440                         warnx("device file: %s", remote);
441                 if (kernel != NULL)
442                         warnx("kernel image: %s", kernel);
443         }
444
445         /*
446          * At this point we must either have a core file or have a kernel
447          * with a remote target.
448          */
449         if (remote != NULL && kernel == NULL) {
450                 warnx("remote debugging requires a kernel");
451                 usage();
452                 /* NOTREACHED */
453         }
454         if (vmcore == NULL && remote == NULL) {
455                 warnx("need a core file or a device for remote debugging");
456                 usage();
457                 /* NOTREACHED */
458         }
459
460         /* If we don't have a kernel image yet, try to find one. */
461         if (kernel == NULL) {
462                 if (dumpnr >= 0)
463                         kernel_from_dumpnr(dumpnr);
464
465                 if (kernel == NULL)
466                         errx(1, "couldn't find a suitable kernel image");
467                 if (verbose)
468                         warnx("kernel image: %s", kernel);
469         }
470
471         if (remote == NULL) {
472                 kvm = kvm_openfiles(kernel, vmcore, NULL,
473                     writecore ? O_RDWR : O_RDONLY, kvm_err);
474                 if (kvm == NULL)
475                         errx(1, kvm_err);
476                 atexit(kgdb_atexit);
477                 kgdb_thr_init();
478         }
479
480         /* The libgdb code uses optind too. Reset it... */
481         optind = 0;
482
483         memset (&args, 0, sizeof args);
484         args.argv = argv;
485         args.argc = 1 + quiet;
486         if (quiet)
487                 argv[1] = "-q";
488         argv[args.argc] = NULL;
489         args.use_windows = 0;
490         args.interpreter_p = INTERP_CONSOLE;
491
492         deprecated_init_ui_hook = kgdb_init;
493
494         return (gdb_main(&args));
495 }