summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-12-27 07:14:58 +0000
committerpeter <peter@FreeBSD.org>1999-12-27 07:14:58 +0000
commit047fa82dd05146cf34e7c0f9fe16e2f4a5fa741f (patch)
treebf612c2f85cc36d2b54233162227b2975c37fd0a
parent04cead132ddb264f917bbce4fd71d663b16aa645 (diff)
downloadFreeBSD-src-047fa82dd05146cf34e7c0f9fe16e2f4a5fa741f.zip
FreeBSD-src-047fa82dd05146cf34e7c0f9fe16e2f4a5fa741f.tar.gz
Use kldsym(2) to lookup symbol values. This avoids the kvm_mkdb juggling
and is module aware. Yes, this means that kvm_nlist(3) will find symbols in loaded modules. The emulation of the nlist struct is pretty crude but seems to work well enough for all the users in the tree that I found.
-rw-r--r--lib/libkvm/kvm.c135
-rw-r--r--lib/libkvm/kvm_alpha.c1
-rw-r--r--lib/libkvm/kvm_amd64.c6
-rw-r--r--lib/libkvm/kvm_file.c5
-rw-r--r--lib/libkvm/kvm_getloadavg.c6
-rw-r--r--lib/libkvm/kvm_getswapinfo.c1
-rw-r--r--lib/libkvm/kvm_i386.c6
-rw-r--r--lib/libkvm/kvm_nlist.314
-rw-r--r--lib/libkvm/kvm_private.h2
-rw-r--r--lib/libkvm/kvm_proc.c7
-rw-r--r--lib/libkvm/kvm_sparc.c6
11 files changed, 60 insertions, 129 deletions
diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c
index b35eceb..55c33f8 100644
--- a/lib/libkvm/kvm.c
+++ b/lib/libkvm/kvm.c
@@ -40,7 +40,7 @@
static char sccsid[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94";
#else
static const char rcsid[] =
- "$FreeBSD$";
+ "$FreeBSD$";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -50,6 +50,7 @@ static const char rcsid[] =
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
+#include <sys/linker.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -58,7 +59,6 @@ static const char rcsid[] =
#include <machine/vmparam.h>
#include <ctype.h>
-#include <db.h>
#include <fcntl.h>
#include <kvm.h>
#include <limits.h>
@@ -71,8 +71,6 @@ static const char rcsid[] =
#include "kvm_private.h"
-static int kvm_dbopen __P((kvm_t *, const char *));
-
char *
kvm_geterr(kd)
kvm_t *kd;
@@ -180,7 +178,6 @@ _kvm_open(kd, uf, mf, flag, errout)
kd->pmfd = -1;
kd->nlfd = -1;
kd->vmst = 0;
- kd->db = 0;
kd->procbase = 0;
kd->argspc = 0;
kd->argv = 0;
@@ -225,19 +222,6 @@ _kvm_open(kd, uf, mf, flag, errout)
goto failed;
}
}
- /*
- * Open kvm nlist database. We go ahead and do this
- * here so that we don't have to hold on to the kernel
- * path name. Since a kvm application will surely do
- * a kvm_nlist(), this probably won't be a wasted effort.
- * If the database cannot be opened, open the namelist
- * argument so we revert to slow nlist() calls.
- */
- if (kvm_dbopen(kd, uf) < 0 &&
- (kd->nlfd = open(uf, O_RDONLY, 0)) < 0) {
- _kvm_syserr(kd, kd->program, "%s", uf);
- goto failed;
- }
} else {
/*
* This is a crash dump.
@@ -314,8 +298,6 @@ kvm_close(kd)
error |= close(kd->vmfd);
if (kd->nlfd >= 0)
error |= close(kd->nlfd);
- if (kd->db != 0)
- error |= (kd->db->close)(kd->db);
if (kd->vmst)
_kvm_freevtop(kd);
if (kd->procbase != 0)
@@ -327,72 +309,6 @@ kvm_close(kd)
return (0);
}
-/*
- * Set up state necessary to do queries on the kernel namelist
- * data base. If the data base is out-of-data/incompatible with
- * given executable, set up things so we revert to standard nlist call.
- * Only called for live kernels. Return 0 on success, -1 on failure.
- */
-static int
-kvm_dbopen(kd, uf)
- kvm_t *kd;
- const char *uf;
-{
- char *cp;
- DBT rec;
- int dbversionlen;
- struct nlist nitem;
- char dbversion[_POSIX2_LINE_MAX];
- char kversion[_POSIX2_LINE_MAX];
- char dbname[MAXPATHLEN];
-
- if ((cp = rindex(uf, '/')) != 0)
- uf = cp + 1;
-
- (void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf);
- kd->db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL);
- if (kd->db == 0)
- return (-1);
- /*
- * read version out of database
- */
- rec.data = VRS_KEY;
- rec.size = sizeof(VRS_KEY) - 1;
- if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
- goto close;
- if (rec.data == 0 || rec.size > sizeof(dbversion))
- goto close;
-
- bcopy(rec.data, dbversion, rec.size);
- dbversionlen = rec.size;
- /*
- * Read version string from kernel memory.
- * Since we are dealing with a live kernel, we can call kvm_read()
- * at this point.
- */
- rec.data = VRS_SYM;
- rec.size = sizeof(VRS_SYM) - 1;
- if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
- goto close;
- if (rec.data == 0 || rec.size != sizeof(struct nlist))
- goto close;
- bcopy((char *)rec.data, (char *)&nitem, sizeof(nitem));
- if (kvm_read(kd, (u_long)nitem.n_value, kversion, dbversionlen) !=
- dbversionlen)
- goto close;
- /*
- * If they match, we win - otherwise clear out kd->db so
- * we revert to slow nlist().
- */
- if (bcmp(dbversion, kversion, dbversionlen) == 0)
- return (0);
-close:
- (void)(kd->db->close)(kd->db);
- kd->db = 0;
-
- return (-1);
-}
-
int
kvm_nlist(kd, nl)
kvm_t *kd;
@@ -400,44 +316,37 @@ kvm_nlist(kd, nl)
{
register struct nlist *p;
register int nvalid;
+ struct kld_sym_lookup lookup;
/*
- * If we can't use the data base, revert to the
+ * If we can't use the kld symbol lookup, revert to the
* slow library call.
*/
- if (kd->db == 0)
+ if (!ISALIVE(kd))
return (__fdnlist(kd->nlfd, nl));
/*
- * We can use the kvm data base. Go through each nlist entry
- * and look it up with a db query.
+ * We can use the kld lookup syscall. Go through each nlist entry
+ * and look it up with a kldsym(2) syscall.
*/
nvalid = 0;
for (p = nl; p->n_name && p->n_name[0]; ++p) {
- register int len;
- DBT rec;
-
- if ((len = strlen(p->n_name)) > 4096) {
- /* sanity */
- _kvm_err(kd, kd->program, "symbol too large");
- return (-1);
+ lookup.version = sizeof(lookup);
+ lookup.symname = p->n_name;
+ lookup.symvalue = 0;
+ lookup.symsize = 0;
+
+ if (lookup.symname[0] == '_')
+ lookup.symname++;
+
+ if (kldsym(0, KLDSYM_LOOKUP, &lookup) != -1) {
+ p->n_type = N_TEXT;
+ p->n_other = 0;
+ p->n_desc = 0;
+ p->n_value = lookup.symvalue;
+ ++nvalid;
+ /* lookup.symsize */
}
- rec.data = p->n_name;
- rec.size = len;
- if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
- continue;
- if (rec.data == 0 || rec.size != sizeof(struct nlist))
- continue;
- ++nvalid;
- /*
- * Avoid alignment issues.
- */
- bcopy((char *)&((struct nlist *)rec.data)->n_type,
- (char *)&p->n_type,
- sizeof(p->n_type));
- bcopy((char *)&((struct nlist *)rec.data)->n_value,
- (char *)&p->n_value,
- sizeof(p->n_value));
}
/*
* Return the number of entries that weren't found.
diff --git a/lib/libkvm/kvm_alpha.c b/lib/libkvm/kvm_alpha.c
index 391a955..98417a0 100644
--- a/lib/libkvm/kvm_alpha.c
+++ b/lib/libkvm/kvm_alpha.c
@@ -42,7 +42,6 @@
#include <vm/vm_param.h>
#include <limits.h>
-#include <db.h>
#include <stdlib.h>
#include <machine/pmap.h>
#include "kvm_private.h"
diff --git a/lib/libkvm/kvm_amd64.c b/lib/libkvm/kvm_amd64.c
index d36b922..0b727fd 100644
--- a/lib/libkvm/kvm_amd64.c
+++ b/lib/libkvm/kvm_amd64.c
@@ -36,7 +36,12 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
#endif /* LIBC_SCCS and not lint */
/*
@@ -57,7 +62,6 @@ static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93";
#include <vm/vm_param.h>
#include <limits.h>
-#include <db.h>
#include "kvm_private.h"
diff --git a/lib/libkvm/kvm_file.c b/lib/libkvm/kvm_file.c
index 4af6b71..a80ba8e 100644
--- a/lib/libkvm/kvm_file.c
+++ b/lib/libkvm/kvm_file.c
@@ -32,7 +32,12 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
static char sccsid[] = "@(#)kvm_file.c 8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
#endif /* LIBC_SCCS and not lint */
/*
diff --git a/lib/libkvm/kvm_getloadavg.c b/lib/libkvm/kvm_getloadavg.c
index 3368e63..7963831 100644
--- a/lib/libkvm/kvm_getloadavg.c
+++ b/lib/libkvm/kvm_getloadavg.c
@@ -32,7 +32,12 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
static char sccsid[] = "@(#)kvm_getloadavg.c 8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -43,7 +48,6 @@ static char sccsid[] = "@(#)kvm_getloadavg.c 8.1 (Berkeley) 6/4/93";
#include <vm/vm_param.h>
#include <stdlib.h>
-#include <db.h>
#include <fcntl.h>
#include <limits.h>
#include <nlist.h>
diff --git a/lib/libkvm/kvm_getswapinfo.c b/lib/libkvm/kvm_getswapinfo.c
index 05aeedf..4c85e82 100644
--- a/lib/libkvm/kvm_getswapinfo.c
+++ b/lib/libkvm/kvm_getswapinfo.c
@@ -28,7 +28,6 @@ static const char rcsid[] =
#include <err.h>
#include <fcntl.h>
#include <kvm.h>
-#include <limits.h>
#include <nlist.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/lib/libkvm/kvm_i386.c b/lib/libkvm/kvm_i386.c
index d36b922..0b727fd 100644
--- a/lib/libkvm/kvm_i386.c
+++ b/lib/libkvm/kvm_i386.c
@@ -36,7 +36,12 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
#endif /* LIBC_SCCS and not lint */
/*
@@ -57,7 +62,6 @@ static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93";
#include <vm/vm_param.h>
#include <limits.h>
-#include <db.h>
#include "kvm_private.h"
diff --git a/lib/libkvm/kvm_nlist.3 b/lib/libkvm/kvm_nlist.3
index f5611b3..b01930b 100644
--- a/lib/libkvm/kvm_nlist.3
+++ b/lib/libkvm/kvm_nlist.3
@@ -60,12 +60,10 @@ Each symbol is looked up using the n_name field, and if found, the
corresponding n_type and n_value fields are filled in. These fields are set
to 0 if the symbol is not found.
.Pp
-The program
-.Xr kvm_mkdb 8
-builds a database from the running kernel's namelist.
-If the database matches the opened kernel,
-.Fn kvm_nlist
-uses it to speed lookups.
+.Xr kldsym 2
+is used to locate the symbol. This is a less than perfect emulation
+of the nlist values but has the advantage of being aware of kernel modules
+and is reasonably fast.
.Sh RETURN VALUES
The
.Fn kvm_nlist
@@ -76,6 +74,7 @@ If the kernel symbol table was unreadable, -1 is returned.
.It Pa /var/db/kvm_kernel.db
.El
.Sh SEE ALSO
+.Xr kldsym 2 ,
.Xr kvm 3 ,
.Xr kvm_close 3 ,
.Xr kvm_getargv 3 ,
@@ -85,5 +84,4 @@ If the kernel symbol table was unreadable, -1 is returned.
.Xr kvm_open 3 ,
.Xr kvm_openfiles 3 ,
.Xr kvm_read 3 ,
-.Xr kvm_write 3 ,
-.Xr kvm_mkdb 8
+.Xr kvm_write 3
diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h
index 2d6d07f..402b9ee 100644
--- a/lib/libkvm/kvm_private.h
+++ b/lib/libkvm/kvm_private.h
@@ -35,6 +35,7 @@
* SUCH DAMAGE.
*
* @(#)kvm_private.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD$
*/
struct __kvm {
@@ -46,7 +47,6 @@ struct __kvm {
const char *program;
char *errp; /* XXX this can probably go away */
char errbuf[_POSIX2_LINE_MAX];
- DB *db;
#define ISALIVE(kd) ((kd)->vmfd >= 0)
int pmfd; /* physical memory file (or crashdump) */
int vmfd; /* virtual memory file (-1 if crashdump) */
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index feba974..3490bd4 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -70,7 +70,6 @@ static char sccsid[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93";
#include <limits.h>
#include <memory.h>
-#include <db.h>
#include <paths.h>
#include "kvm_private.h"
@@ -675,6 +674,12 @@ kvm_getargv(kd, kp, nchr)
static char **bufp;
static int argc;
+ if (!ISALIVE(kd)) {
+ _kvm_err(kd, kd->program,
+ "cannot read user space from dead kernel");
+ return (0);
+ }
+
if (!buflen) {
l = sizeof(buflen);
i = sysctlbyname("kern.ps_arg_cache_limit",
diff --git a/lib/libkvm/kvm_sparc.c b/lib/libkvm/kvm_sparc.c
index a7b9594..7a538d8 100644
--- a/lib/libkvm/kvm_sparc.c
+++ b/lib/libkvm/kvm_sparc.c
@@ -36,7 +36,12 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
static char sccsid[] = "@(#)kvm_sparc.c 8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif
#endif /* LIBC_SCCS and not lint */
/*
@@ -56,7 +61,6 @@ static char sccsid[] = "@(#)kvm_sparc.c 8.1 (Berkeley) 6/4/93";
#include <vm/vm_param.h>
#include <limits.h>
-#include <db.h>
#include "kvm_private.h"
OpenPOWER on IntegriCloud