summaryrefslogtreecommitdiffstats
path: root/usr.sbin/kvm_mkdb/nlist.c
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2013-10-15 05:15:12 +0000
committerderaadt <deraadt@openbsd.org>2013-10-15 05:15:12 +0000
commit40b3cc4674c76cd16be78dbb4e16ac51e5ad6ef9 (patch)
treed756619ffcc0539679e5aa2564fae923f4ce71be /usr.sbin/kvm_mkdb/nlist.c
parentThe ERL Ethernet is supported now and can be booted over NFS. Reflect that (diff)
downloadwireguard-openbsd-40b3cc4674c76cd16be78dbb4e16ac51e5ad6ef9.tar.xz
wireguard-openbsd-40b3cc4674c76cd16be78dbb4e16ac51e5ad6ef9.zip
tedu a.out support
Diffstat (limited to 'usr.sbin/kvm_mkdb/nlist.c')
-rw-r--r--usr.sbin/kvm_mkdb/nlist.c376
1 files changed, 1 insertions, 375 deletions
diff --git a/usr.sbin/kvm_mkdb/nlist.c b/usr.sbin/kvm_mkdb/nlist.c
index 8edd6f687b7..10fe07e4d8e 100644
--- a/usr.sbin/kvm_mkdb/nlist.c
+++ b/usr.sbin/kvm_mkdb/nlist.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nlist.c,v 1.42 2013/08/22 04:43:41 guenther Exp $ */
+/* $OpenBSD: nlist.c,v 1.43 2013/10/15 05:15:12 deraadt Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -55,10 +55,6 @@
#include <elf_abi.h>
#endif
-#ifdef _NLIST_DO_ECOFF
-#include <sys/exec_ecoff.h>
-#endif
-
typedef struct nlist NLIST;
#define _strx n_un.n_strx
#define _name n_un.n_name
@@ -66,229 +62,6 @@ typedef struct nlist NLIST;
static char *kfile;
static char *fmterr;
-#if defined(_NLIST_DO_AOUT)
-
-static u_long get_kerntext(char *kfn, u_int magic);
-
-int
-__aout_knlist(int fd, DB *db, int ksyms)
-{
- int nsyms;
- struct exec ebuf;
- FILE *fp;
- NLIST nbuf;
- DBT data, key;
- int nr, strsize;
- size_t len;
- u_long kerntextoff;
- size_t snamesize = 0;
- char *strtab, buf[1024], *sname, *p;
-
- /* Read in exec structure. */
- nr = read(fd, &ebuf, sizeof(struct exec));
- if (nr != sizeof(struct exec)) {
- fmterr = "no exec header";
- return (1);
- }
-
- /* Check magic number and symbol count. */
- if (N_BADMAG(ebuf)) {
- fmterr = "bad magic number";
- return (1);
- }
-
- /* Must have a symbol table. */
- if (!ebuf.a_syms) {
- fmterr = "stripped";
- return (-1);
- }
-
- /* Seek to string table. */
- if (lseek(fd, N_STROFF(ebuf), SEEK_SET) == -1) {
- fmterr = "corrupted string table";
- return (-1);
- }
-
- /* Read in the size of the string table. */
- nr = read(fd, (char *)&strsize, sizeof(strsize));
- if (nr != sizeof(strsize)) {
- fmterr = "no symbol table";
- return (-1);
- }
-
- /* Read in the string table. */
- strsize -= sizeof(strsize);
- if (!(strtab = malloc(strsize)))
- errx(1, "cannot allocate %d bytes for string table", strsize);
- if ((nr = read(fd, strtab, strsize)) != strsize) {
- fmterr = "corrupted symbol table";
- free(strtab);
- return (-1);
- }
-
- /* Seek to symbol table. */
- if (!(fp = fdopen(fd, "r")))
- err(1, "%s", kfile);
- if (fseek(fp, N_SYMOFF(ebuf), SEEK_SET) == -1) {
- free(strtab);
- warn("fseek %s", kfile);
- return (-1);
- }
-
- data.data = (u_char *)&nbuf;
- data.size = sizeof(NLIST);
-
- kerntextoff = get_kerntext(kfile, N_GETMAGIC(ebuf));
-
- /* Read each symbol and enter it into the database. */
- nsyms = ebuf.a_syms / sizeof(struct nlist);
- sname = NULL;
- while (nsyms--) {
- if (fread((char *)&nbuf, sizeof (NLIST), 1, fp) != 1) {
- if (feof(fp))
- fmterr = "corrupted symbol table";
- else
- warn("%s", kfile);
- free(strtab);
- return (-1);
- }
- if (!nbuf._strx || (nbuf.n_type & N_STAB))
- continue;
-
- /* If the symbol does not start with '_', add one */
- p = strtab + nbuf._strx - sizeof(int);
- if (*p != '_') {
- len = strlen(p) + 1;
- if (len >= snamesize) {
- char *newsname;
- int newsnamesize = len + 1024;
-
- newsname = realloc(sname, newsnamesize);
- if (newsname == NULL) {
- if (sname)
- free(sname);
- sname = NULL;
- } else {
- sname = newsname;
- snamesize = newsnamesize;
- }
- }
- if (sname == NULL)
- errx(1, "cannot allocate memory");
- *sname = '_';
- strlcpy(sname + 1, p, snamesize - 1);
- key.data = (u_char *)sname;
- key.size = len;
- } else {
- key.data = (u_char *)p;
- key.size = strlen((char *)key.data);
- }
- if (db->put(db, &key, &data, 0))
- err(1, "record enter");
-
- if (strcmp((char *)key.data, VRS_SYM) == 0) {
- long cur_off;
-
- if (!ksyms) {
- /*
- * Calculate offset relative to a normal
- * (non-kernel) a.out. Kerntextoff is where the
- * kernel is really loaded; N_TXTADDR is where
- * a normal file is loaded. From there, locate
- * file offset in text or data.
- */
- long voff;
-
- voff = nbuf.n_value-kerntextoff+N_TXTADDR(ebuf);
- if ((nbuf.n_type & N_TYPE) == N_TEXT)
- voff += N_TXTOFF(ebuf)-N_TXTADDR(ebuf);
- else
- voff += N_DATOFF(ebuf)-N_DATADDR(ebuf);
- cur_off = ftell(fp);
- if (fseek(fp, voff, SEEK_SET) == -1) {
- fmterr = "corrupted string table";
- free(strtab);
- return (-1);
- }
-
- /*
- * Read version string up to, and including
- * newline. This code assumes that a newline
- * terminates the version line.
- */
- if (fgets(buf, sizeof(buf), fp) == NULL) {
- fmterr = "corrupted string table";
- free(strtab);
- return (-1);
- }
- } else {
- /*
- * This is /dev/ksyms or a look alike.
- * Use sysctl() to get version since we
- * don't have real text or data.
- */
- int mib[2];
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_VERSION;
- len = sizeof(buf);
- if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) {
- err(1, "sysctl can't find kernel "
- "version string");
- }
- if ((p = strchr(buf, '\n')) != NULL)
- *(p+1) = '\0';
- }
- key.data = (u_char *)VRS_KEY;
- key.size = sizeof(VRS_KEY) - 1;
- data.data = (u_char *)buf;
- data.size = strlen(buf);
- if (db->put(db, &key, &data, 0))
- err(1, "record enter");
-
- /* Restore to original values. */
- data.data = (u_char *)&nbuf;
- data.size = sizeof(NLIST);
- if (!ksyms && fseek(fp, cur_off, SEEK_SET) == -1) {
- fmterr = "corrupted string table";
- free(strtab);
- return (-1);
- }
- }
- }
- (void)fclose(fp);
- return (0);
-}
-
-/*
- * XXX: Using this value from machine/param.h introduces a
- * XXX: machine dependency on this program, so /usr can not
- * XXX: be shared between (i.e.) several m68k machines.
- * Instead of compiling in KERNTEXTOFF or KERNBASE, try to
- * determine the text start address from a standard symbol.
- * For backward compatibility, use the old compiled-in way
- * when the standard symbol name is not found.
- */
-#ifndef KERNTEXTOFF
-#define KERNTEXTOFF KERNBASE
-#endif
-
-static u_long
-get_kerntext(char *name, u_int magic)
-{
- NLIST nl[2];
-
- bzero((caddr_t)nl, sizeof(nl));
- nl[0]._name = "_kernel_text";
-
- if (nlist(name, nl) != 0)
- return (KERNTEXTOFF);
-
- return (nl[0].n_value);
-}
-
-#endif /* _NLIST_DO_AOUT */
-
#ifdef _NLIST_DO_ELF
int
__elf_knlist(int fd, DB *db, int ksyms)
@@ -532,159 +305,12 @@ done:
}
#endif /* _NLIST_DO_ELF */
-#ifdef _NLIST_DO_ECOFF
-
-#define check(off, size) ((off < 0) || (off + size > mappedsize))
-#define BAD do { rv = -1; goto out; } while (0)
-#define BADUNMAP do { rv = -1; goto unmap; } while (0)
-#define ECOFF_INTXT(p, e) ((p) > (e)->a.text_start && \
- (p) < (e)->a.text_start + (e)->a.tsize)
-#define ECOFF_INDAT(p, e) ((p) > (e)->a.data_start && \
- (p) < (e)->a.data_start + (e)->a.dsize)
-
-int
-__ecoff_knlist(int fd, DB *db, int ksyms)
-{
- struct ecoff_exechdr *exechdrp;
- struct ecoff_symhdr *symhdrp;
- struct ecoff_extsym *esyms;
- struct stat st;
- char *mappedfile, *cp;
- size_t mappedsize;
- u_long symhdroff, extstroff, off;
- u_int symhdrsize;
- int rv = 0;
- long i, nesyms;
- DBT data, key;
- NLIST nbuf;
- char *sname = NULL;
- size_t len, snamesize = 0;
-
- if (fstat(fd, &st) < 0)
- err(1, "can't stat %s", kfile);
- if (st.st_size > SIZE_T_MAX) {
- fmterr = "file too large";
- BAD;
- }
-
- mappedsize = st.st_size;
- mappedfile = mmap(NULL, mappedsize, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);
- if (mappedfile == MAP_FAILED) {
- fmterr = "unable to mmap";
- BAD;
- }
-
- if (check(0, sizeof *exechdrp))
- BADUNMAP;
- exechdrp = (struct ecoff_exechdr *)&mappedfile[0];
-
- if (ECOFF_BADMAG(exechdrp))
- BADUNMAP;
-
- symhdroff = exechdrp->f.f_symptr;
- symhdrsize = exechdrp->f.f_nsyms;
- if (symhdrsize == 0) {
- fmterr = "stripped";
- return (-1);
- }
-
- if (check(symhdroff, sizeof *symhdrp) ||
- sizeof *symhdrp != symhdrsize)
- BADUNMAP;
- symhdrp = (struct ecoff_symhdr *)&mappedfile[symhdroff];
-
- nesyms = symhdrp->esymMax;
- if (check(symhdrp->cbExtOffset, nesyms * sizeof *esyms))
- BADUNMAP;
- esyms = (struct ecoff_extsym *)&mappedfile[symhdrp->cbExtOffset];
- extstroff = symhdrp->cbSsExtOffset;
-
- data.data = (u_char *)&nbuf;
- data.size = sizeof(NLIST);
-
- for (sname = NULL, i = 0; i < nesyms; i++) {
- /* Need to prepend a '_' */
- len = strlen(&mappedfile[extstroff + esyms[i].es_strindex]) + 1;
- if (len >= snamesize) {
- char *newsname;
- int newsnamesize = len + 1024;
-
- newsname = realloc(sname, newsnamesize);
- if (newsname == NULL) {
- if (sname)
- free(sname);
- sname = NULL;
- } else {
- sname = newsname;
- snamesize = newsnamesize;
- }
- }
- if (sname == NULL)
- errx(1, "cannot allocate memory");
- *sname = '_';
- strlcpy(sname+1, &mappedfile[extstroff + esyms[i].es_strindex],
- snamesize - 1);
-
- /* Fill in NLIST */
- bzero(&nbuf, sizeof(nbuf));
- nbuf.n_value = esyms[i].es_value;
- nbuf.n_type = N_EXT; /* XXX */
-
- /* Store entry in db */
- key.data = (u_char *)sname;
- key.size = strlen(sname);
- if (db->put(db, &key, &data, 0))
- err(1, "record enter");
-
- if (strcmp(sname, VRS_SYM) == 0) {
- key.data = (u_char *)VRS_KEY;
- key.size = sizeof(VRS_KEY) - 1;
-
- /* Version string may be in either text or data segs */
- if (ECOFF_INTXT(nbuf.n_value, exechdrp))
- off = nbuf.n_value - exechdrp->a.text_start +
- ECOFF_TXTOFF(exechdrp);
- else if (ECOFF_INDAT(nbuf.n_value, exechdrp))
- off = nbuf.n_value - exechdrp->a.data_start +
- ECOFF_DATOFF(exechdrp);
- else
- err(1, "unable to find version string");
-
- /* Version string should end in newline but... */
- data.data = &mappedfile[off];
- if ((cp = strchr(data.data, '\n')) != NULL)
- data.size = cp - (char *)data.data;
- else
- data.size = strlen((char *)data.data);
-
- if (db->put(db, &key, &data, 0))
- err(1, "record enter");
-
- /* Restore to original values */
- data.data = (u_char *)&nbuf;
- data.size = sizeof(nbuf);
- }
- }
-
-unmap:
- munmap(mappedfile, mappedsize);
-out:
- return (rv);
-}
-#endif /* _NLIST_DO_ECOFF */
-
static struct knlist_handlers {
int (*fn)(int fd, DB *db, int ksyms);
} nlist_fn[] = {
-#ifdef _NLIST_DO_AOUT
- { __aout_knlist },
-#endif
#ifdef _NLIST_DO_ELF
{ __elf_knlist },
#endif
-#ifdef _NLIST_DO_ECOFF
- { __ecoff_knlist },
-#endif
};
int