Page MenuHomeFreeBSD

D21946.diff
No OneTemporary

D21946.diff

Index: devel/gdb/files/kgdb/kgdb-main.c
===================================================================
--- devel/gdb/files/kgdb/kgdb-main.c
+++ devel/gdb/files/kgdb/kgdb-main.c
@@ -383,6 +383,38 @@
add_arg(&args, "-iex");
add_arg(&args, "set osabi FreeBSD/kernel");
+ /*
+ * PowerPC kernels are fully relocatable and may be loaded
+ * at any memory address. In order to resolve symbols properly,
+ * GDB must load the kernel symbol file relative to the base
+ * offset where the it was loaded in memory.
+ */
+#ifdef __powerpc__
+ {
+ unsigned long long offs;
+
+ unsigned long long ppcfbsd_get_startkernel(
+ const char *, const char *);
+
+ offs = ppcfbsd_get_startkernel(kernel, vmcore);
+
+ /* Set executable file but don't load it yet. */
+ add_arg(&args, "-e");
+ add_arg(&args, kernel);
+
+ add_arg(&args, "-ex");
+ add_arg(&args, "set confirm off");
+
+ /* Load symbols at proper offsets. */
+ add_arg(&args, "-ex");
+ asprintf(&s, "symbol-file -o 0x%llx %s", offs, kernel);
+ add_arg(&args, s);
+
+ add_arg(&args, "-ex");
+ add_arg(&args, "set confirm on");
+ }
+#endif
+
/* Open the vmcore if requested. */
if (vmcore != NULL) {
add_arg(&args, "-ex");
@@ -400,7 +432,10 @@
add_arg(&args, s);
}
+ /* Avoid loading symbols twice on PowerPC. */
+#ifndef __powerpc__
add_arg(&args, kernel);
+#endif
/* The libgdb code uses optind too. Reset it... */
optind = 0;
Index: devel/gdb/files/kgdb/ppcfbsd-kern.c
===================================================================
--- devel/gdb/files/kgdb/ppcfbsd-kern.c
+++ devel/gdb/files/kgdb/ppcfbsd-kern.c
@@ -39,8 +39,13 @@
#include "ppc64-tdep.h"
#ifdef __powerpc__
+#include <err.h>
+#include <kvm.h>
+#include <paths.h>
+
#include <machine/pcb.h>
#include <machine/frame.h>
+#include <machine/minidump.h>
#endif
#include "kgdb.h"
@@ -246,3 +251,68 @@
gdbarch_register_osabi (bfd_arch_rs6000, 0,
GDB_OSABI_FREEBSD_KERNEL, ppcfbsd_kernel_init_abi);
}
+
+#ifdef __powerpc__
+
+#define KERNBASE 0x100100ULL
+
+/*
+ * Find kernel start address in memory.
+ */
+unsigned long long
+ppcfbsd_get_startkernel(const char *kernel, const char *vmcore)
+{
+ struct minidumphdr hdr;
+ struct nlist nl[2];
+ int fd = -1;
+ kvm_t *kd = NULL;
+ const char *errmsg = NULL;
+
+ /* Look for startkernel in minidump file. */
+ if (vmcore && strcmp(vmcore, _PATH_MEM) != 0) {
+ if ((fd = open(vmcore, O_RDONLY)) == -1) {
+ errmsg = "Failed to open core file";
+ goto failed;
+ }
+
+ if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+ errmsg = "Failed to read core file";
+ goto failed;
+ }
+
+ if (strcmp(hdr.magic, MINIDUMP_MAGIC) != 0) {
+ errmsg = "Wrong minudump magic";
+ goto failed;
+ }
+
+ close(fd);
+ return hdr.startkernel - KERNBASE;
+ /* For live kernels, use kvm to get kernel start address. */
+ } else {
+ if ((kd = kvm_open(kernel, NULL, NULL, O_RDONLY, "kgdb")) ==
+ NULL) {
+ errmsg = "kvm_open failed";
+ goto failed;
+ }
+
+ nl[0].n_name = "btext";
+ nl[1].n_name = NULL;
+ if (kvm_nlist(kd, nl) != 0) {
+ errmsg = "Failed to locate kernel start symbol";
+ goto failed;
+ }
+
+ kvm_close(kd);
+ return nl[0].n_value - KERNBASE;
+ }
+
+failed:
+ if (fd != -1)
+ close(fd);
+ if (kd != NULL)
+ kvm_close(kd);
+ warnx("warning: %s", errmsg);
+ warnx("warning: Symbol resolution may not work\n");
+ return 0;
+}
+#endif

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 3:30 AM (2 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30701626
Default Alt Text
D21946.diff (3 KB)

Event Timeline