From 7f911abe54fff2adbb0dfea5a7fd8e81117d6527 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 27 Nov 2015 18:58:26 +0000 Subject: Add support to libkvm for reading vmcores from other architectures. - Add a kvaddr_type to represent kernel virtual addresses instead of unsigned long. - Add a struct kvm_nlist which is a stripped down version of struct nlist that uses kvaddr_t for n_value. - Add a kvm_native() routine that returns true if an open kvm descriptor is for a native kernel and memory image. - Add a kvm_open2() function similar to kvm_openfiles(). It drops the unused 'swapfile' argument and adds a new function pointer argument for a symbol resolving function. Native kernels still use _fdnlist() from libc to resolve symbols if a resolver function is not supplied, but cross kernels require a resolver. - Add a kvm_nlist2() function similar to kvm_nlist() except that it uses struct kvm_nlist instead of struct nlist. - Add a kvm_read2() function similar to kvm_read() except that it uses kvaddr_t instead of unsigned long for the kernel virtual address. - Add a new kvm_arch switch of routines needed by a vmcore backend. Each backend is responsible for implementing kvm_read2() for a given vmcore format. - Use libelf to read headers from ELF kernels and cores (except for powerpc cores). - Add internal helper routines for the common page offset hash table used by the minidump backends. - Port all of the existing kvm backends to implement a kvm_arch switch and to be cross-friendly by using private constants instead of ones that vary by platform (e.g. PAGE_SIZE). Static assertions are present when a given backend is compiled natively to ensure the private constants match the real ones. - Enable all of the existing vmcore backends on all platforms. This means that libkvm on any platform should be able to perform KVA translation and read data from a vmcore of any platform. Tested on: amd64, i386, sparc64 (marius) Differential Revision: https://reviews.freebsd.org/D3341 --- gnu/usr.bin/gdb/kgdb/Makefile | 6 +----- gnu/usr.bin/gdb/kgdb/main.c | 21 --------------------- gnu/usr.bin/gdb/kgdb/trgt.c | 19 ++++++++++++++++--- 3 files changed, 17 insertions(+), 29 deletions(-) (limited to 'gnu') diff --git a/gnu/usr.bin/gdb/kgdb/Makefile b/gnu/usr.bin/gdb/kgdb/Makefile index 8af2e1821edb5..39f4cd520c890 100644 --- a/gnu/usr.bin/gdb/kgdb/Makefile +++ b/gnu/usr.bin/gdb/kgdb/Makefile @@ -9,11 +9,7 @@ BULIBS= ${OBJ_BU}/libbfd/libbfd.a ${OBJ_BU}/libopcodes/libopcodes.a \ GDBLIBS= ${OBJ_GDB}/libgdb/libgdb.a DPADD= ${GDBLIBS} ${BULIBS} ${LIBKVM} -LDADD= ${GDBLIBS} ${BULIBS} -lkvm${GDB_SUFFIX} +LDADD= ${GDBLIBS} ${BULIBS} -lkvm LIBADD+= m readline ncursesw gnuregex -.if defined(GDB_CROSS_DEBUGGER) -CFLAGS+= -Wl,-export-dynamic -.endif - .include diff --git a/gnu/usr.bin/gdb/kgdb/main.c b/gnu/usr.bin/gdb/kgdb/main.c index 19246c0504661..aa062a2dd8c00 100644 --- a/gnu/usr.bin/gdb/kgdb/main.c +++ b/gnu/usr.bin/gdb/kgdb/main.c @@ -41,9 +41,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef CROSS_DEBUGGER -#include -#endif #include #include #include @@ -81,24 +78,6 @@ static struct ui_file *parse_gdberr; static void (*kgdb_new_objfile_chain)(struct objfile * objfile); -#ifdef CROSS_DEBUGGER -ps_err_e -ps_pglobal_lookup(struct ps_prochandle *ph, const char *obj, const char *name, - psaddr_t *sym_addr) -{ - struct minimal_symbol *ms; - CORE_ADDR addr; - - ms = lookup_minimal_symbol (name, NULL, NULL); - if (ms == NULL) - return PS_NOSYM; - - addr = SYMBOL_VALUE_ADDRESS (ms); - store_typed_address(sym_addr, builtin_type_void_data_ptr, addr); - return PS_OK; -} -#endif - static void usage(void) { diff --git a/gnu/usr.bin/gdb/kgdb/trgt.c b/gnu/usr.bin/gdb/kgdb/trgt.c index c75edf000dbac..0e29b7af9d676 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt.c +++ b/gnu/usr.bin/gdb/kgdb/trgt.c @@ -78,6 +78,19 @@ static char kvm_err[_POSIX2_LINE_MAX]; #define KERNOFF (kgdb_kernbase ()) #define PINKERNEL(x) ((x) >= KERNOFF) +static int +kgdb_resolve_symbol(const char *name, kvaddr_t *kva) +{ + struct minimal_symbol *ms; + + ms = lookup_minimal_symbol (name, NULL, NULL); + if (ms == NULL) + return (1); + + *kva = SYMBOL_VALUE_ADDRESS (ms); + return (0);; +} + static CORE_ADDR kgdb_kernbase (void) { @@ -120,8 +133,8 @@ kgdb_trgt_open(char *filename, int from_tty) old_chain = make_cleanup (xfree, filename); - nkvm = kvm_openfiles(bfd_get_filename(exec_bfd), filename, NULL, - write_files ? O_RDWR : O_RDONLY, kvm_err); + nkvm = kvm_open2(bfd_get_filename(exec_bfd), filename, + write_files ? O_RDWR : O_RDONLY, kvm_err, kgdb_resolve_symbol); if (nkvm == NULL) error ("Failed to open vmcore: %s", kvm_err); @@ -254,7 +267,7 @@ kgdb_trgt_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write, if (len == 0) return (0); if (!write) - return (kvm_read(kvm, memaddr, myaddr, len)); + return (kvm_read2(kvm, memaddr, myaddr, len)); else return (kvm_write(kvm, memaddr, myaddr, len)); } -- cgit v1.3