diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2013-10-15 05:15:13 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2013-10-15 05:15:13 +0000 |
commit | 769b3a9e45b7bbe19b99d9bf46d7bb1ca5c0947e (patch) | |
tree | 2aeac8e9379369c39158c2e3c9aedd3ad705a26e /usr.sbin | |
parent | f230580b33d3152292ec5232d8d21cee41d16c99 (diff) |
tedu a.out support
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/kvm_mkdb/nlist.c | 376 |
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 |