Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150246463
D46538.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D46538.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D46538: libkvm: look up linker_files for symbols in vmcore
Attached
Detach File
Event Timeline
Log In to Comment