#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 *);
int (*ka_walk_pages)(kvm_t *, kvm_walk_pages_cb_t *, void *);
kssize_t (*ka_kerndisp)(kvm_t *);
};
#define KVM_ARCH(ka) DATA_SET(kvm_arch, ka)
struct __kvm {
struct kvm_arch *arch;
const char *program;
char *errp;
char errbuf[_POSIX2_LINE_MAX];
#define ISALIVE(kd) ((kd)->vmfd >= 0)
int pmfd;
int vmfd;
int nlfd;
GElf_Ehdr nlehdr;
int (*resolve_symbol)(const char *, kvaddr_t *);
struct kinfo_proc *procbase;
char *argspc;
int arglen;
char **argv;
int argc;
char *argbuf;
struct vmstate *vmst;
int rawdump;
int writable;
int vnet_initialized;
kvaddr_t vnet_start;
kvaddr_t vnet_stop;
kvaddr_t vnet_current;
kvaddr_t vnet_base;
int dpcpu_initialized;
kvaddr_t dpcpu_start;
kvaddr_t dpcpu_stop;
u_int dpcpu_maxcpus;
uintptr_t *dpcpu_off;
u_int dpcpu_curcpu;
kvaddr_t dpcpu_curoff;
uint64_t *pt_map;
size_t pt_map_size;
uint64_t *dump_avail;
size_t dump_avail_size;
off_t pt_sparse_off;
uint64_t pt_sparse_size;
uint32_t *pt_popcounts;
unsigned int pt_page_size;
void *page_map;
uint32_t page_map_size;
off_t page_map_off;
void *sparse_map;
};
struct kvm_bitmap {
uint8_t *map;
u_long size;
};
#define POPCOUNT_BITS 1024
#define BITS_IN(v) (sizeof(v) * NBBY)
#define POPCOUNTS_IN(v) (POPCOUNT_BITS / BITS_IN(v))
static inline uint16_t
_kvm16toh(kvm_t *kd, uint16_t val)
{
if (kd->nlehdr.e_ident[EI_DATA] == ELFDATA2LSB)
return (le16toh(val));
else
return (be16toh(val));
}
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));
}
uint64_t _kvm_pa_bit_id(kvm_t *kd, uint64_t pa, unsigned int page_size);
uint64_t _kvm_bit_id_pa(kvm_t *kd, uint64_t bit_id, unsigned int page_size);
#define _KVM_PA_INVALID ULONG_MAX
#define _KVM_BIT_ID_INVALID ULONG_MAX
int _kvm_bitmap_init(struct kvm_bitmap *, u_long, u_long *);
void _kvm_bitmap_set(struct kvm_bitmap *, u_long);
int _kvm_bitmap_next(struct kvm_bitmap *, u_long *);
void _kvm_bitmap_deinit(struct kvm_bitmap *);
void _kvm_err(kvm_t *kd, const char *program, const char *fmt, ...)
__printflike(3, 4);
void _kvm_freeprocs(kvm_t *kd);
void *_kvm_malloc(kvm_t *kd, size_t);
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_vnet_selectpid(kvm_t *, pid_t);
int _kvm_vnet_initialized(kvm_t *, int);
kvaddr_t _kvm_vnet_validaddr(kvm_t *, kvaddr_t);
int _kvm_dpcpu_initialized(kvm_t *, int);
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 **);
int _kvm_pt_init(kvm_t *, size_t, off_t, size_t, off_t, off_t, int);
off_t _kvm_pt_find(kvm_t *, uint64_t, unsigned int);
int _kvm_visit_cb(kvm_t *, kvm_walk_pages_cb_t *, void *, u_long,
u_long, u_long, vm_prot_t, size_t, unsigned int);
int _kvm_pmap_init(kvm_t *, uint32_t, off_t);
void * _kvm_pmap_get(kvm_t *, u_long, size_t);
void * _kvm_map_get(kvm_t *, u_long, unsigned int);