Page MenuHomeFreeBSD

D46538.diff
No OneTemporary

D46538.diff

diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile
--- a/lib/libkvm/Makefile
+++ b/lib/libkvm/Makefile
@@ -7,6 +7,7 @@
SRCS= kvm.c kvm_cptime.c kvm_getloadavg.c \
kvm_getswapinfo.c kvm_pcpu.c kvm_private.c kvm_proc.c kvm_vnet.c \
+ kvm_minidump_helpers.c \
kvm_minidump_aarch64.c \
kvm_amd64.c kvm_minidump_amd64.c \
kvm_arm.c kvm_minidump_arm.c \
@@ -20,7 +21,7 @@
MAN= kvm.3 kvm_getcptime.3 kvm_geterr.3 kvm_getloadavg.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
+ kvm_lookup_symbol.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.h b/lib/libkvm/kvm.h
--- a/lib/libkvm/kvm.h
+++ b/lib/libkvm/kvm.h
@@ -124,6 +124,9 @@
typedef int kvm_walk_pages_cb_t(struct kvm_page *, void *);
int kvm_walk_pages(kvm_t *, kvm_walk_pages_cb_t *, void *);
+
+int kvm_lookup_symbol(kvm_t *, int, struct kvm_nlist *);
+int kvm_lookup_kld(kvm_t *, const char *);
__END_DECLS
#endif /* !_KVM_H_ */
diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c
--- a/lib/libkvm/kvm.c
+++ b/lib/libkvm/kvm.c
@@ -211,6 +211,19 @@
*/
if (kd->arch->ka_initvtop(kd) < 0)
goto failed;
+
+ TAILQ_INIT(&kd->linker_files_list);
+ if (kd->arch->ka_walk_linker_files != NULL) {
+ /*
+ * Walk the linker_files list so that kvm_nlist works properly
+ * against loaded kernel modules.
+ */
+ if (kd->arch->ka_walk_linker_files(kd) != 0) {
+ _kvm_err(kd, kd->program,
+ "failed to walk linker_files list");
+ goto failed;
+ }
+ }
return (kd);
failed:
/*
@@ -273,11 +286,16 @@
kvm_close(kvm_t *kd)
{
int error = 0;
+ struct kvm_linker_file *lf;
if (kd == NULL) {
errno = EINVAL;
return (-1);
}
+ while ((lf = TAILQ_FIRST(&kd->linker_files_list)) != NULL) {
+ TAILQ_REMOVE(&kd->linker_files_list, lf, link);
+ _kvm_linker_file_free(lf);
+ }
if (kd->vmst != NULL)
kd->arch->ka_freevtop(kd);
if (kd->pmfd >= 0)
@@ -534,3 +552,59 @@
return (kd->arch->ka_kerndisp(kd));
}
+
+int
+kvm_lookup_symbol(kvm_t *kd, int fileid, struct kvm_nlist *nl)
+{
+ struct kvm_linker_file *p;
+ int error, nfail = 0;
+ int i;
+
+ if (kd->arch->ka_lookup_symbol == NULL) {
+ _kvm_err(kd, kd->program, "unsupported architecture");
+ return (-1);
+ }
+
+ for (i = 0; nl[i].n_name != NULL && nl[i].n_name[0] != '\0'; i++) {
+ bool found = false;
+
+ TAILQ_FOREACH(p, &kd->linker_files_list, link) {
+ /* For fileid == 0 go through all the images */
+ if (fileid != 0 && p->id != fileid)
+ continue;
+ if (kd->arch->ka_lookup_symbol(kd, p, &nl[i]) == 0) {
+ found = true;
+ break;
+ }
+ if (fileid != 0) {
+ /*
+ * For exact match fileid, just bail out if the
+ * request symbol is not found. It is
+ * meaningless to go through the rest of the
+ * image list.
+ */
+ break;
+ }
+ }
+ if (!found)
+ nfail++;
+ }
+ return (nfail);
+}
+
+int
+kvm_lookup_kld(kvm_t *kd, const char *filename)
+{
+ struct kvm_linker_file *p;
+ int id = -1;
+
+ TAILQ_FOREACH(p, &kd->linker_files_list, link) {
+ if (strcmp(p->filename, filename) == 0) {
+ id = p->id;
+ break;
+ }
+ }
+ if (id == -1)
+ _kvm_err(kd, kd->program, "KLD not found");
+ return (id);
+}
diff --git a/lib/libkvm/kvm_lookup_kld.3 b/lib/libkvm/kvm_lookup_kld.3
new file mode 100644
--- /dev/null
+++ b/lib/libkvm/kvm_lookup_kld.3
@@ -0,0 +1,51 @@
+.\"
+.\" Copyright (c) 2024 Juniper Networks, Inc.
+.\"
+.\" 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.
+.\"
+.Dd August 30, 2024
+.Dt KVM_LOOKUP_KLD 3
+.Os
+.Sh NAME
+.Nm kvm_lookup_kld
+.Nd look up the file id of a kld file
+.Sh LIBRARY
+.Lb libkvm
+.Sh SYNOPSIS
+.In kvm.h
+.Ft int
+.Fn kvm_lookup_kld "kvm_t *kd" "const char *filename"
+.Sh DESCRIPTION
+The
+.Fn kvm_lookup_kld
+function looks up the corresponding file id of a kld file.
+The
+.Fa filename
+argument points to a memory location storing the kld image's file name.
+.Sh RETURN VALUES
+The
+.Fn kvm_lookup_kld
+function returns a positive value indicating the file id of the loaded kld.
+If the kld specified by the file name does not exist, the function returns -1.
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_open2 3
diff --git a/lib/libkvm/kvm_lookup_symbol.3 b/lib/libkvm/kvm_lookup_symbol.3
new file mode 100644
--- /dev/null
+++ b/lib/libkvm/kvm_lookup_symbol.3
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 2024 Juniper Networks, Inc.
+.\"
+.\" This code is derived from software developed by the Computer Systems
+.\" Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+.\" BG 91-66 and contributed to Berkeley.
+.\"
+.\" 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.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+.\"
+.Dd August 30, 2024
+.Dt KVM_LOOKUP_SYMBOL 3
+.Os
+.Sh NAME
+.Nm kvm_lookup_symbol
+.Nd retrieve symbol table names from a kernel image
+.Sh LIBRARY
+.Lb libkvm
+.Sh SYNOPSIS
+.In kvm.h
+.Ft int
+.Fn kvm_lookup_symbol "kvm_t *kd" "int fileid" "struct kvm_nlist *nl"
+.Sh DESCRIPTION
+The
+.Fn kvm_lookup_symbol
+function retrieves the symbol table entries from the image specified by the
+.Fa fileid
+argument, and indicated by the name list argument
+.Fa nl .
+The
+.Fa nl
+argument points to an array of
+.Vt "struct kvm_nlist"
+structures,
+terminated by an entry whose
+.Fa n_name
+field is
+.Dv NULL
+These structures are similar to the nlist structures used by
+.Fn kvm_nlist
+except that the
+.Fa n_value
+field uses a different type
+.Pq Vt kvaddr_t
+to avoid truncation when examining non-native kernel images.
+If the value of 0 is passed to the
+.Fa fileid
+argument,
+the
+.Fn kvm_lookup_symbol
+function will look through all the loaded images.
+.Sh RETURN VALUES
+The
+.Fn kvm_lookup_symbol
+function return the number of invalid entries found.
+If the symbol table of the specified image was unreadable, -1 is returned.
+.Sh SEE ALSO
+.Xr kldsym 2 ,
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_native 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
+.Sh HISTORY
+The
+.Fn kvm_lookup_symbol
+function first appeared in
+.Fx 15.0 .
diff --git a/lib/libkvm/kvm_minidump_aarch64.c b/lib/libkvm/kvm_minidump_aarch64.c
--- a/lib/libkvm/kvm_minidump_aarch64.c
+++ b/lib/libkvm/kvm_minidump_aarch64.c
@@ -31,6 +31,12 @@
*/
#include <sys/param.h>
+#define _WANT_LINKER
+#include <sys/queue.h>
+#include <sys/linker.h>
+#undef _WANT_LINKER
+#include <vm/vm.h>
+#include <vm/vm_object.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -44,6 +50,7 @@
#include "kvm_private.h"
#include "kvm_aarch64.h"
+#include "kvm_minidump_helpers.h"
#define aarch64_round_page(x, size) roundup2((kvaddr_t)(x), size)
#define aarch64_trunc_page(x, size) rounddown2((kvaddr_t)(x), size)
@@ -311,6 +318,20 @@
return (ret);
}
+static int
+_aarch64_minidump_walk_linker_files(kvm_t *kd)
+{
+ return (_kvm_minidump_walk_linker_files(kd));
+}
+
+static int
+_aarch64_minidump_lookup_symbol(kvm_t *kd, struct kvm_linker_file *lf,
+ struct kvm_nlist *nl)
+{
+ return (_kvm_minidump_lookup_symbol(kd, lf, nl));
+}
+
+
static struct kvm_arch kvm_aarch64_minidump = {
.ka_probe = _aarch64_minidump_probe,
.ka_initvtop = _aarch64_minidump_initvtop,
@@ -318,6 +339,8 @@
.ka_kvatop = _aarch64_minidump_kvatop,
.ka_native = _aarch64_native,
.ka_walk_pages = _aarch64_minidump_walk_pages,
+ .ka_walk_linker_files = _aarch64_minidump_walk_linker_files,
+ .ka_lookup_symbol = _aarch64_minidump_lookup_symbol,
};
KVM_ARCH(kvm_aarch64_minidump);
diff --git a/lib/libkvm/kvm_minidump_amd64.c b/lib/libkvm/kvm_minidump_amd64.c
--- a/lib/libkvm/kvm_minidump_amd64.c
+++ b/lib/libkvm/kvm_minidump_amd64.c
@@ -32,11 +32,18 @@
#include <sys/param.h>
#include <sys/endian.h>
+#define _WANT_LINKER
+#include <sys/queue.h>
+#include <sys/linker.h>
+#undef _WANT_LINKER
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <assert.h>
+#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <vm/vm.h>
#include <kvm.h>
#include "../../sys/amd64/include/minidump.h"
@@ -45,6 +52,7 @@
#include "kvm_private.h"
#include "kvm_amd64.h"
+#include "kvm_minidump_helpers.h"
#define amd64_round_page(x) roundup2((kvaddr_t)(x), AMD64_PAGE_SIZE)
#define VM_IS_V1(vm) (vm->hdr.version == 1)
@@ -428,6 +436,19 @@
return (ret);
}
+static int
+_amd64_minidump_walk_linker_files(kvm_t *kd)
+{
+ return (_kvm_minidump_walk_linker_files(kd));
+}
+
+static int
+_amd64_minidump_lookup_symbol(kvm_t *kd, struct kvm_linker_file *lf,
+ struct kvm_nlist *nl)
+{
+ return (_kvm_minidump_lookup_symbol(kd, lf, nl));
+}
+
static struct kvm_arch kvm_amd64_minidump = {
.ka_probe = _amd64_minidump_probe,
.ka_initvtop = _amd64_minidump_initvtop,
@@ -435,6 +456,8 @@
.ka_kvatop = _amd64_minidump_kvatop,
.ka_native = _amd64_native,
.ka_walk_pages = _amd64_minidump_walk_pages,
+ .ka_walk_linker_files = _amd64_minidump_walk_linker_files,
+ .ka_lookup_symbol = _amd64_minidump_lookup_symbol,
};
KVM_ARCH(kvm_amd64_minidump);
diff --git a/lib/libkvm/kvm_minidump_helpers.h b/lib/libkvm/kvm_minidump_helpers.h
new file mode 100644
--- /dev/null
+++ b/lib/libkvm/kvm_minidump_helpers.h
@@ -0,0 +1,35 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Juniper Networks, Inc.
+ *
+ * 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.
+ */
+
+#ifndef _KVM_MINIDUMP_HELPERS_H_
+#define _KVM_MINIDUMP_HELPERS_H_
+
+int _kvm_minidump_walk_linker_files(kvm_t *);
+int _kvm_minidump_lookup_symbol(kvm_t *, struct kvm_linker_file *,
+ struct kvm_nlist *);
+
+#endif /* _KVM_MINIDUMP_HELPERS_H_ */
diff --git a/lib/libkvm/kvm_minidump_helpers.c b/lib/libkvm/kvm_minidump_helpers.c
new file mode 100644
--- /dev/null
+++ b/lib/libkvm/kvm_minidump_helpers.c
@@ -0,0 +1,170 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Juniper Networks, Inc.
+ *
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#define _WANT_LINKER
+#include <sys/queue.h>
+#include <sys/linker.h>
+#include <sys/_linker_elf_file.h>
+#undef _WANT_LINKER
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <kvm.h>
+
+#include "kvm_private.h"
+#include "kvm_minidump_helpers.h"
+
+/* from src/lib/libc/gen/nlist.c */
+int __fdnlist(int, struct nlist *);
+
+static int
+_elf_file_parse(kvm_t *kd, kvaddr_t lfkva, const struct elf_file_base *buf,
+ struct kvm_linker_file *klf)
+{
+ ssize_t nbytes;
+ size_t i;
+
+ klf->address = (uintptr_t)buf->address;
+ klf->ddbsymcnt = buf->ddbsymcnt;
+ klf->ddbstrcnt = buf->ddbstrcnt;
+ klf->ddbsymtab = calloc(buf->ddbsymcnt, sizeof(*klf->ddbsymtab));
+ klf->ddbstrtab = malloc(buf->ddbstrcnt);
+ if (klf->ddbsymtab == NULL || klf->ddbstrtab == NULL)
+ return (-1);
+
+ nbytes = kvm_read2(kd, (kvaddr_t)buf->ddbsymtab, klf->ddbsymtab,
+ buf->ddbsymcnt * sizeof(*klf->ddbsymtab));
+ if (nbytes != buf->ddbsymcnt * sizeof(*klf->ddbsymtab))
+ return (-1);
+ nbytes = kvm_read2(kd, (kvaddr_t)buf->ddbstrtab, klf->ddbstrtab,
+ buf->ddbstrcnt);
+ if (nbytes != buf->ddbstrcnt)
+ return (-1);
+
+ if (!buf->is_obj) {
+ for (i = 0; i < klf->ddbsymcnt; i++)
+ klf->ddbsymtab[i].st_value += (uintptr_t)buf->address;
+ }
+
+ return (0);
+}
+
+int
+_kvm_minidump_walk_linker_files(kvm_t *kd)
+{
+ int nfail;
+ ssize_t nbytes;
+ kvaddr_t ptr;
+ struct kvm_linker_file *p = NULL;
+ struct elf_file_base efb;
+ struct nlist nl[2] = {
+ { .n_name = "linker_files" },
+ { .n_name = NULL },
+ };
+
+ assert(!ISALIVE(kd));
+
+ /* We are here without knowing other modules. So nlist is the only
+ * way to move forward. */
+ nfail = __fdnlist(kd->nlfd, nl);
+ if (nfail != 0)
+ return (-1);
+
+ nbytes = kvm_read2(kd,
+ nl[0].n_value + offsetof(linker_file_list_t, tqh_first), &ptr,
+ sizeof(ptr));
+ if (nbytes != sizeof(ptr))
+ return (-1);
+
+ while (ptr != 0) {
+ nbytes = kvm_read2(kd, ptr, &efb, sizeof(efb));
+ if (nbytes != sizeof(efb) ||
+ efb.version != ELF_FILE_BASE_VERSION)
+ goto errout;
+
+ p = malloc(sizeof(struct kvm_linker_file));
+ if (p == NULL)
+ goto errout;
+ p->id = efb.lf.id;
+ p->size = efb.lf.size;
+ p->filename = malloc(MAXPATHLEN);
+ p->pathname = malloc(MAXPATHLEN);
+ if (p->filename == NULL || p->pathname == NULL)
+ goto errout;
+ nbytes = kvm_read2(kd, (kvaddr_t)efb.lf.filename, p->filename,
+ MAXPATHLEN);
+ if (nbytes != MAXPATHLEN)
+ goto errout;
+ nbytes = kvm_read2(kd, (kvaddr_t)efb.lf.pathname, p->pathname,
+ MAXPATHLEN);
+ if (nbytes != MAXPATHLEN)
+ goto errout;
+ if (_elf_file_parse(kd, ptr, &efb, p) != 0)
+ goto errout;
+
+ TAILQ_INSERT_TAIL(&kd->linker_files_list, p, link);
+ ptr = (kvaddr_t)efb.lf.link.tqe_next;
+ }
+
+ return (0);
+errout:
+ _kvm_linker_file_free(p);
+ return (-1);
+}
+
+int
+_kvm_minidump_lookup_symbol(kvm_t *kd, struct kvm_linker_file *lf,
+ struct kvm_nlist *nl)
+{
+ const char *name;
+ Elf_Sym *sym;
+ size_t i;
+
+ for (i = 0; i < lf->ddbsymcnt; ++i) {
+ sym = &lf->ddbsymtab[i];
+ name = lf->ddbstrtab + sym->st_name;
+ if (((nl->n_name[0] == '_' &&
+ strcmp(name, nl->n_name + 1) == 0) ||
+ strcmp(name, nl->n_name) == 0) && sym->st_value != 0) {
+ /*
+ * For now, just set n_type up like what has been done in
+ * the kldsym(2) calling.
+ */
+ nl->n_type = N_TEXT;
+ nl->n_value = sym->st_value;
+ return (0);
+ }
+ }
+ return (-1);
+}
diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h
--- a/lib/libkvm/kvm_private.h
+++ b/lib/libkvm/kvm_private.h
@@ -35,8 +35,23 @@
#include <sys/endian.h>
#include <sys/linker_set.h>
+#include <sys/queue.h>
+#include <sys/elf.h>
#include <gelf.h>
+struct kvm_linker_file {
+ TAILQ_ENTRY(kvm_linker_file) link;
+ char *filename;
+ char *pathname;
+ int id;
+ uintptr_t address;
+ size_t size;
+ size_t ddbsymcnt;
+ size_t ddbstrcnt;
+ Elf_Sym *ddbsymtab;
+ char *ddbstrtab;
+};
+
struct kvm_arch {
int (*ka_probe)(kvm_t *);
int (*ka_initvtop)(kvm_t *);
@@ -45,6 +60,9 @@
int (*ka_native)(kvm_t *);
int (*ka_walk_pages)(kvm_t *, kvm_walk_pages_cb_t *, void *);
kssize_t (*ka_kerndisp)(kvm_t *);
+ int (*ka_walk_linker_files)(kvm_t *);
+ int (*ka_lookup_symbol)(kvm_t *, struct kvm_linker_file *,
+ struct kvm_nlist *);
};
#define KVM_ARCH(ka) DATA_SET(kvm_arch, ka)
@@ -115,6 +133,9 @@
uint32_t page_map_size;
off_t page_map_off;
void *sparse_map;
+
+ /* List of loaded klds known */
+ TAILQ_HEAD(, kvm_linker_file) linker_files_list;
};
struct kvm_bitmap {
@@ -193,3 +214,5 @@
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);
+
+void _kvm_linker_file_free(struct kvm_linker_file *);
diff --git a/lib/libkvm/kvm_private.c b/lib/libkvm/kvm_private.c
--- a/lib/libkvm/kvm_private.c
+++ b/lib/libkvm/kvm_private.c
@@ -822,3 +822,15 @@
return cb(&p, arg);
}
+
+void
+_kvm_linker_file_free(struct kvm_linker_file *lf)
+{
+ if (lf == NULL)
+ return;
+ free(lf->filename);
+ free(lf->pathname);
+ free(lf->ddbsymtab);
+ free(lf->ddbstrtab);
+ free(lf);
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 31, 2:33 PM (19 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30638677
Default Alt Text
D46538.diff (20 KB)

Event Timeline