diff options
author | jhb <jhb@FreeBSD.org> | 2015-11-27 18:58:26 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2015-11-27 18:58:26 +0000 |
commit | ab35544b83d7494b58b4327d7a9e6d66da7ab579 (patch) | |
tree | 0b881610c55721cfde72c0eaeb1df3d9d654fd26 /gnu | |
parent | fd20cedd093bc1221cdc050bac05276a1b9a36ba (diff) | |
download | FreeBSD-src-ab35544b83d7494b58b4327d7a9e6d66da7ab579.zip FreeBSD-src-ab35544b83d7494b58b4327d7a9e6d66da7ab579.tar.gz |
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
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/gdb/kgdb/Makefile | 6 | ||||
-rw-r--r-- | gnu/usr.bin/gdb/kgdb/main.c | 21 | ||||
-rw-r--r-- | gnu/usr.bin/gdb/kgdb/trgt.c | 19 |
3 files changed, 17 insertions, 29 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/Makefile b/gnu/usr.bin/gdb/kgdb/Makefile index 8af2e18..39f4cd5 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 <bsd.prog.mk> diff --git a/gnu/usr.bin/gdb/kgdb/main.c b/gnu/usr.bin/gdb/kgdb/main.c index 19246c0..aa062a2 100644 --- a/gnu/usr.bin/gdb/kgdb/main.c +++ b/gnu/usr.bin/gdb/kgdb/main.c @@ -41,9 +41,6 @@ __FBSDID("$FreeBSD$"); #include <kvm.h> #include <limits.h> #include <paths.h> -#ifdef CROSS_DEBUGGER -#include <proc_service.h> -#endif #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -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 c75edf0..0e29b7a 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)); } |