diff options
Diffstat (limited to 'lib/libkvm/kvm_private.h')
-rw-r--r-- | lib/libkvm/kvm_private.h | 91 |
1 files changed, 69 insertions, 22 deletions
diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h index 4829046..78b4845 100644 --- a/lib/libkvm/kvm_private.h +++ b/lib/libkvm/kvm_private.h @@ -34,7 +34,22 @@ * $FreeBSD$ */ +#include <sys/endian.h> +#include <sys/linker_set.h> +#include <gelf.h> + +struct kvm_arch { + int (*ka_probe)(kvm_t *); + int (*ka_initvtop)(kvm_t *); + void (*ka_freevtop)(kvm_t *); + int (*ka_kvatop)(kvm_t *, kvaddr_t, off_t *); + int (*ka_native)(kvm_t *); +}; + +#define KVM_ARCH(ka) DATA_SET(kvm_arch, ka) + struct __kvm { + struct kvm_arch *arch; /* * a string to be prepended to error messages * provided for compatibility with sun's interface @@ -46,8 +61,9 @@ struct __kvm { #define ISALIVE(kd) ((kd)->vmfd >= 0) int pmfd; /* physical memory file (or crashdump) */ int vmfd; /* virtual memory file (-1 if crashdump) */ - int unused; /* was: swap file (e.g., /dev/drum) */ int nlfd; /* namelist file (e.g., /kernel) */ + GElf_Ehdr nlehdr; /* ELF file header for namelist file */ + int (*resolve_symbol)(const char *, kvaddr_t *); struct kinfo_proc *procbase; char *argspc; /* (dynamic) storage for argv strings */ int arglen; /* length of the above */ @@ -64,10 +80,10 @@ struct __kvm { int rawdump; /* raw dump format */ int vnet_initialized; /* vnet fields set up */ - uintptr_t vnet_start; /* start of kernel's vnet region */ - uintptr_t vnet_stop; /* stop of kernel's vnet region */ - uintptr_t vnet_current; /* vnet we're working with */ - uintptr_t vnet_base; /* vnet base of current vnet */ + kvaddr_t vnet_start; /* start of kernel's vnet region */ + kvaddr_t vnet_stop; /* stop of kernel's vnet region */ + kvaddr_t vnet_current; /* vnet we're working with */ + kvaddr_t vnet_base; /* vnet base of current vnet */ /* * Dynamic per-CPU kernel memory. We translate symbols, on-demand, @@ -75,38 +91,69 @@ struct __kvm { * kvm_dpcpu_setcpu(). */ int dpcpu_initialized; /* dpcpu fields set up */ - uintptr_t dpcpu_start; /* start of kernel's dpcpu region */ - uintptr_t dpcpu_stop; /* stop of kernel's dpcpu region */ + kvaddr_t dpcpu_start; /* start of kernel's dpcpu region */ + kvaddr_t dpcpu_stop; /* stop of kernel's dpcpu region */ u_int dpcpu_maxcpus; /* size of base array */ uintptr_t *dpcpu_off; /* base array, indexed by CPU ID */ u_int dpcpu_curcpu; /* CPU we're currently working with */ - uintptr_t dpcpu_curoff; /* dpcpu base of current CPU */ + kvaddr_t dpcpu_curoff; /* dpcpu base of current CPU */ +}; + +/* + * Page table hash used by minidump backends to map physical addresses + * to file offsets. + */ +struct hpte { + struct hpte *next; + uint64_t pa; + off_t off; +}; + +#define HPT_SIZE 1024 + +struct hpt { + struct hpte *hpt_head[HPT_SIZE]; }; /* * Functions used internally by kvm, but across kvm modules. */ +static inline uint32_t +_kvm32toh(kvm_t *kd, uint32_t val) +{ + + if (kd->nlehdr.e_ident[EI_DATA] == ELFDATA2LSB) + return (le32toh(val)); + else + return (be32toh(val)); +} + +static inline uint64_t +_kvm64toh(kvm_t *kd, uint64_t val) +{ + + if (kd->nlehdr.e_ident[EI_DATA] == ELFDATA2LSB) + return (le64toh(val)); + else + return (be64toh(val)); +} + void _kvm_err(kvm_t *kd, const char *program, const char *fmt, ...) __printflike(3, 4); void _kvm_freeprocs(kvm_t *kd); -void _kvm_freevtop(kvm_t *); -int _kvm_initvtop(kvm_t *); -int _kvm_kvatop(kvm_t *, u_long, off_t *); void *_kvm_malloc(kvm_t *kd, size_t); -int _kvm_nlist(kvm_t *, struct nlist *, int); +int _kvm_nlist(kvm_t *, struct kvm_nlist *, int); void *_kvm_realloc(kvm_t *kd, void *, size_t); void _kvm_syserr (kvm_t *kd, const char *program, const char *fmt, ...) __printflike(3, 4); -int _kvm_uvatop(kvm_t *, const struct proc *, u_long, u_long *); int _kvm_vnet_selectpid(kvm_t *, pid_t); int _kvm_vnet_initialized(kvm_t *, int); -uintptr_t _kvm_vnet_validaddr(kvm_t *, uintptr_t); +kvaddr_t _kvm_vnet_validaddr(kvm_t *, kvaddr_t); int _kvm_dpcpu_initialized(kvm_t *, int); -uintptr_t _kvm_dpcpu_validaddr(kvm_t *, uintptr_t); - -#if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \ - defined(__i386__) || defined(__mips__) -void _kvm_minidump_freevtop(kvm_t *); -int _kvm_minidump_initvtop(kvm_t *); -int _kvm_minidump_kvatop(kvm_t *, u_long, off_t *); -#endif +kvaddr_t _kvm_dpcpu_validaddr(kvm_t *, kvaddr_t); +int _kvm_probe_elf_kernel(kvm_t *, int, int); +int _kvm_is_minidump(kvm_t *); +int _kvm_read_core_phdrs(kvm_t *, size_t *, GElf_Phdr **); +void _kvm_hpt_init(kvm_t *, struct hpt *, void *, size_t, off_t, int, int); +off_t _kvm_hpt_find(struct hpt *, uint64_t); +void _kvm_hpt_free(struct hpt *); |