aboutsummaryrefslogtreecommitdiff
path: root/lib/libkvm
diff options
context:
space:
mode:
authorLeandro Lupori <luporl@FreeBSD.org>2020-02-06 13:21:59 +0000
committerLeandro Lupori <luporl@FreeBSD.org>2020-02-06 13:21:59 +0000
commit38cf2a4334fbc5b90761b1fd0199ac93ea83630f (patch)
tree5074546fc07397127d184948ea43915e3e91fa55 /lib/libkvm
parent210176ad76ee0f1d1ac9ca8d6d63dc5f5fc66427 (diff)
downloadsrc-38cf2a4334fbc5b90761b1fd0199ac93ea83630f.tar.gz
src-38cf2a4334fbc5b90761b1fd0199ac93ea83630f.zip
Notes
Diffstat (limited to 'lib/libkvm')
-rw-r--r--lib/libkvm/Makefile4
-rw-r--r--lib/libkvm/kvm.36
-rw-r--r--lib/libkvm/kvm.c30
-rw-r--r--lib/libkvm/kvm.h1
-rw-r--r--lib/libkvm/kvm_kerndisp.357
-rw-r--r--lib/libkvm/kvm_minidump_powerpc64.c7
-rw-r--r--lib/libkvm/kvm_private.h1
7 files changed, 102 insertions, 4 deletions
diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile
index 9fce7b9d467d..cd4872bd5b03 100644
--- a/lib/libkvm/Makefile
+++ b/lib/libkvm/Makefile
@@ -25,8 +25,8 @@ INCS= kvm.h
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 \
diff --git a/lib/libkvm/kvm.3 b/lib/libkvm/kvm.3
index 7fd5373eec7a..fbddcd475cc8 100644
--- a/lib/libkvm/kvm.3
+++ b/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 @@ respectively.
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 @@ and
.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 ,
diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c
index 2f35f26df1ca..c22f84ed64fa 100644
--- a/lib/libkvm/kvm.c
+++ b/lib/libkvm/kvm.c
@@ -46,6 +46,7 @@ __SCCSID("@(#)kvm.c 8.2 (Berkeley) 2/13/94");
#include <sys/linker.h>
#include <sys/pcpu.h>
#include <sys/stat.h>
+#include <sys/sysctl.h>
#include <sys/mman.h>
#include <net/vnet.h>
@@ -499,3 +500,32 @@ kvm_walk_pages(kvm_t *kd, kvm_walk_pages_cb_t *cb, void *closure)
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));
+}
diff --git a/lib/libkvm/kvm.h b/lib/libkvm/kvm.h
index d568a27e6963..e6dd767c9193 100644
--- a/lib/libkvm/kvm.h
+++ b/lib/libkvm/kvm.h
@@ -124,6 +124,7 @@ ssize_t kvm_read(kvm_t *, unsigned long, void *, size_t);
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 *);
diff --git a/lib/libkvm/kvm_kerndisp.3 b/lib/libkvm/kvm_kerndisp.3
new file mode 100644
index 000000000000..a1d53a4ecb2f
--- /dev/null
+++ b/lib/libkvm/kvm_kerndisp.3
@@ -0,0 +1,57 @@
+.\"
+.\" Copyright (c) 2020 Leandro Lupori <luporl@FreeBSD.org>
+.\"
+.\" 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
diff --git a/lib/libkvm/kvm_minidump_powerpc64.c b/lib/libkvm/kvm_minidump_powerpc64.c
index 39c8d03fefa6..6e95b40aab2a 100644
--- a/lib/libkvm/kvm_minidump_powerpc64.c
+++ b/lib/libkvm/kvm_minidump_powerpc64.c
@@ -184,6 +184,12 @@ _powerpc64_native(kvm_t *kd __unused)
#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 @@ static struct kvm_arch kvm_powerpc64_minidump = {
.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);
diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h
index 39a743c922fc..e71dde92a2f1 100644
--- a/lib/libkvm/kvm_private.h
+++ b/lib/libkvm/kvm_private.h
@@ -47,6 +47,7 @@ struct kvm_arch {
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)