Index: head/lib/libkvm/Makefile =================================================================== --- head/lib/libkvm/Makefile +++ head/lib/libkvm/Makefile @@ -25,8 +25,8 @@ LIBADD= elf MAN= kvm.3 kvm_getcptime.3 kvm_geterr.3 kvm_getloadavg.3 \ - kvm_getpcpu.3 kvm_getprocs.3 kvm_getswapinfo.3 kvm_native.3 \ - kvm_nlist.3 kvm_open.3 kvm_read.3 + kvm_getpcpu.3 kvm_getprocs.3 kvm_getswapinfo.3 kvm_kerndisp.3 \ + kvm_native.3 kvm_nlist.3 kvm_open.3 kvm_read.3 MLINKS+=kvm_getpcpu.3 kvm_getmaxcpu.3 \ kvm_getpcpu.3 kvm_dpcpu_setcpu.3 \ Index: head/lib/libkvm/kvm.h =================================================================== --- head/lib/libkvm/kvm.h +++ head/lib/libkvm/kvm.h @@ -124,6 +124,7 @@ ssize_t kvm_read_zpcpu(kvm_t *, unsigned long, void *, size_t, int); ssize_t kvm_read2(kvm_t *, kvaddr_t, void *, size_t); ssize_t kvm_write(kvm_t *, unsigned long, const void *, size_t); +kssize_t kvm_kerndisp(kvm_t *); typedef int kvm_walk_pages_cb_t(struct kvm_page *, void *); int kvm_walk_pages(kvm_t *, kvm_walk_pages_cb_t *, void *); Index: head/lib/libkvm/kvm.3 =================================================================== --- head/lib/libkvm/kvm.3 +++ head/lib/libkvm/kvm.3 @@ -32,7 +32,7 @@ .\" @(#)kvm.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd April 30, 2016 +.Dd February 5, 2020 .Dt KVM 3 .Os .Sh NAME @@ -133,7 +133,8 @@ Finally, only a limited subset of operations are supported for non-native crash dumps: .Fn kvm_close , -.Fn kvm_geterr +.Fn kvm_geterr , +.Fn kvm_kerndisp , .Fn kvm_open2 , .Fn kvm_native , .Fn kvm_nlist2 , @@ -147,6 +148,7 @@ .Xr kvm_getloadavg 3 , .Xr kvm_getprocs 3 , .Xr kvm_getswapinfo 3 , +.Xr kvm_kerndisp 3 , .Xr kvm_native 3 , .Xr kvm_nlist 3 , .Xr kvm_nlist2 3 , Index: head/lib/libkvm/kvm.c =================================================================== --- head/lib/libkvm/kvm.c +++ head/lib/libkvm/kvm.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -498,4 +499,33 @@ return (0); return (kd->arch->ka_walk_pages(kd, cb, closure)); +} + +kssize_t +kvm_kerndisp(kvm_t *kd) +{ + unsigned long kernbase, rel_kernbase; + size_t kernbase_len = sizeof(kernbase); + size_t rel_kernbase_len = sizeof(rel_kernbase); + + if (ISALIVE(kd)) { + if (sysctlbyname("kern.base_address", &kernbase, + &kernbase_len, NULL, 0) == -1) { + _kvm_syserr(kd, kd->program, + "failed to get kernel base address"); + return (0); + } + if (sysctlbyname("kern.relbase_address", &rel_kernbase, + &rel_kernbase_len, NULL, 0) == -1) { + _kvm_syserr(kd, kd->program, + "failed to get relocated kernel base address"); + return (0); + } + return (rel_kernbase - kernbase); + } + + if (kd->arch->ka_kerndisp == NULL) + return (0); + + return (kd->arch->ka_kerndisp(kd)); } Index: head/lib/libkvm/kvm_kerndisp.3 =================================================================== --- head/lib/libkvm/kvm_kerndisp.3 +++ head/lib/libkvm/kvm_kerndisp.3 @@ -0,0 +1,57 @@ +.\" +.\" Copyright (c) 2020 Leandro Lupori +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd February 5, 2020 +.Dt KVM_KERNDISP 3 +.Os +.Sh NAME +.Nm kvm_kerndisp +.Nd get kernel displacement +.Sh LIBRARY +.Lb libkvm +.Sh SYNOPSIS +.In kvm.h +.Ft kssize_t +.Fn kvm_kerndisp "kvm_t *kd" +.Sh DESCRIPTION +.Fn kvm_kerndisp +returns the number of bytes by which the kernel referenced by +.Fa kd +is displaced. +This is the difference between the kernel's base virtual address at run time +and the kernel base virtual address specified in the kernel image file. +.Pp +Note that if the kernel is moved to a lower memory address, +the displacement will be negative. +.Sh RETURN VALUES +.Fn kvm_kerndisp +returns the number of bytes by which the kernel is displaced. +If the kernel is not displaced or if it is not possible to find the +displacement then 0 is returned. +.Sh SEE ALSO +.Xr kvm 3 , +.Xr kvm_close 3 , +.Xr kvm_open 3 Index: head/lib/libkvm/kvm_minidump_powerpc64.c =================================================================== --- head/lib/libkvm/kvm_minidump_powerpc64.c +++ head/lib/libkvm/kvm_minidump_powerpc64.c @@ -184,6 +184,12 @@ #endif } +static kssize_t +_powerpc64_kerndisp(kvm_t *kd) +{ + return (kd->vmst->hdr.startkernel - PPC64_KERNBASE); +} + static int _powerpc64_minidump_walk_pages(kvm_t *kd, kvm_walk_pages_cb_t *cb, void *arg) { @@ -197,6 +203,7 @@ .ka_kvatop = _powerpc64_minidump_kvatop, .ka_walk_pages = _powerpc64_minidump_walk_pages, .ka_native = _powerpc64_native, + .ka_kerndisp = _powerpc64_kerndisp, }; KVM_ARCH(kvm_powerpc64_minidump); Index: head/lib/libkvm/kvm_private.h =================================================================== --- head/lib/libkvm/kvm_private.h +++ head/lib/libkvm/kvm_private.h @@ -47,6 +47,7 @@ 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) Index: head/sys/sys/types.h =================================================================== --- head/sys/sys/types.h +++ head/sys/sys/types.h @@ -260,6 +260,7 @@ typedef __uint64_t kpaddr_t; typedef __uint64_t kvaddr_t; typedef __uint64_t ksize_t; +typedef __int64_t kssize_t; typedef __vm_offset_t vm_offset_t; typedef __uint64_t vm_ooffset_t;