summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authormillert <millert@openbsd.org>1998-09-05 16:30:07 +0000
committermillert <millert@openbsd.org>1998-09-05 16:30:07 +0000
commitf6868ab6e6459510a3a01ca1a0744a7b05905d7c (patch)
treee04a17cc428f67a7f3bfda1d69dd3be59165a1c2 /lib/libc
parentmissed these too. sigh (diff)
downloadwireguard-openbsd-f6868ab6e6459510a3a01ca1a0744a7b05905d7c.tar.xz
wireguard-openbsd-f6868ab6e6459510a3a01ca1a0744a7b05905d7c.zip
Add support for nlisting against a gzipped kernel, #ifdef'd out since
it requires linking with -lz. savecore will use this to operate on gzipped kernels.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gen/nlist.c266
1 files changed, 135 insertions, 131 deletions
diff --git a/lib/libc/gen/nlist.c b/lib/libc/gen/nlist.c
index 5ae1b965591..86ae940c45d 100644
--- a/lib/libc/gen/nlist.c
+++ b/lib/libc/gen/nlist.c
@@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: nlist.c,v 1.27 1998/08/23 17:48:02 millert Exp $";
+static char rcsid[] = "$OpenBSD: nlist.c,v 1.28 1998/09/05 16:30:07 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -57,12 +57,23 @@ static char rcsid[] = "$OpenBSD: nlist.c,v 1.27 1998/08/23 17:48:02 millert Exp
#include <sys/exec_ecoff.h>
#endif
+#ifdef _NLIST_DO_GZIP
+#include <zlib.h>
+#define Read gzread
+#define Seek gzseek
+typedef gzFile File;
+#else
+#define Read read
+#define Seek lseek
+typedef int File;
+#endif /* _NLIST_DO_GZIP */
+
#define ISLAST(p) (p->n_un.n_name == 0 || p->n_un.n_name[0] == 0)
#ifdef _NLIST_DO_AOUT
int
__aout_fdnlist(fd, list)
- register int fd;
+ register File fd;
register struct nlist *list;
{
register struct nlist *p, *s;
@@ -74,8 +85,8 @@ __aout_fdnlist(fd, list)
struct nlist nbuf[1024];
struct exec exec;
- if (lseek(fd, (off_t)0, SEEK_SET) == -1 ||
- read(fd, &exec, sizeof(exec)) != sizeof(exec) ||
+ if (Seek(fd, 0, SEEK_SET) == -1 ||
+ Read(fd, &exec, sizeof(exec)) != sizeof(exec) ||
N_BADMAG(exec) || exec.a_syms == NULL)
return (-1);
@@ -84,9 +95,9 @@ __aout_fdnlist(fd, list)
stroff = symoff + symsize;
/* Read in the size of the string table. */
- if (lseek(fd, N_STROFF(exec), SEEK_SET) == -1)
+ if (Seek(fd, N_STROFF(exec), SEEK_SET) == -1)
return (-1);
- if (read(fd, (char *)&strsize, sizeof(strsize)) != sizeof(strsize))
+ if (Read(fd, (char *)&strsize, sizeof(strsize)) != sizeof(strsize))
return (-1);
/*
@@ -96,7 +107,7 @@ __aout_fdnlist(fd, list)
strsize -= sizeof(strsize);
if ((strtab = (char *)malloc(strsize)) == NULL)
return (-1);
- if (read(fd, strtab, strsize) != strsize)
+ if (Read(fd, strtab, strsize) != strsize)
return (-1);
/*
@@ -117,12 +128,12 @@ __aout_fdnlist(fd, list)
p->n_value = 0;
++nent;
}
- if (lseek(fd, symoff, SEEK_SET) == -1)
+ if (Seek(fd, symoff, SEEK_SET) == -1)
return (-1);
while (symsize > 0) {
cc = MIN(symsize, sizeof(nbuf));
- if (read(fd, nbuf, cc) != cc)
+ if (Read(fd, nbuf, cc) != cc)
break;
symsize -= cc;
for (s = nbuf; cc > 0; ++s, cc -= sizeof(*s)) {
@@ -154,59 +165,51 @@ __aout_fdnlist(fd, list)
#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 BADFREE do { rv = -1; goto freestr; } while (0)
int
__ecoff_fdnlist(fd, list)
- register int fd;
+ register File fd;
register struct nlist *list;
{
struct nlist *p;
- struct ecoff_exechdr *exechdrp;
- struct ecoff_symhdr *symhdrp;
- struct ecoff_extsym *esyms;
- struct stat st;
- char *mappedfile;
- size_t mappedsize;
- u_long symhdroff, extstroff;
- u_int symhdrsize;
- int rv, nent;
- long i, nesyms;
+ struct ecoff_exechdr exechdr;
+ struct ecoff_symhdr symhdr;
+ struct ecoff_extsym esym;
+ char *strtab, *nlistname, *symtabname;
+ int rv, nent, strsize, nesyms;
rv = -3;
- if (fstat(fd, &st) < 0)
+ if (Seek(fd, 0, SEEK_SET) == -1)
BAD;
- if (st.st_size > SIZE_T_MAX) {
- errno = EFBIG;
+
+ /* Read in exec header and check magic nummber. */
+ if (Read(fd, &exechdr, sizeof(exechdr)) != sizeof(exechdr))
BAD;
- }
- mappedsize = st.st_size;
- mappedfile = mmap(NULL, mappedsize, PROT_READ, MAP_COPY|MAP_FILE,
- fd, 0);
- if (mappedfile == MAP_FAILED)
+ if (ECOFF_BADMAG(&exechdr))
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;
+ /* Can't operate on stripped executables. *.
+ if (exechdr.f.f_nsyms == 0)
+ BAD;
- if (check(symhdroff, sizeof *symhdrp) ||
- sizeof *symhdrp != symhdrsize)
- BADUNMAP;
- symhdrp = (struct ecoff_symhdr *)&mappedfile[symhdroff];
+ /* Read in symbol table header and check magic nummber. */
+ if (Seek(fd, exechdr.f.f_symptr, SEEK_SET) == -1)
+ BAD;
+ if (Read(fd, &symhdr, sizeof(symhdr)) != sizeof(symhdr))
+ BAD;
+ if (ECOFF_BADMAG(&exechdr))
+ BAD;
- nesyms = symhdrp->esymMax;
- if (check(symhdrp->cbExtOffset, nesyms * sizeof *esyms))
- BADUNMAP;
- esyms = (struct ecoff_extsym *)&mappedfile[symhdrp->cbExtOffset];
- extstroff = symhdrp->cbSsExtOffset;
+ /* Read in the string table. */
+ if (Seek(fd, symhdr.cbSsExtOffset, SEEK_SET) == -1)
+ BAD;
+ strsize = symhdr.estrMax;
+ if (!(strtab = (char *)malloc(strsize)))
+ BAD;
+ if (Read(fd, strtab, strsize) != strsize)
+ BADFREE;
/*
* clean out any left-over information for all valid entries.
@@ -225,22 +228,24 @@ __ecoff_fdnlist(fd, list)
++nent;
}
- for (i = 0; i < nesyms; i++) {
- for (p = list; !ISLAST(p); p++) {
- char *nlistname;
- char *symtabname;
+ /* Seek to symbol table. */
+ if (Seek(fd, symhdr.cbExtOffset, SEEK_SET) == -1)
+ BADFREE;
+ /* Check each symbol against the list */
+ nesyms = symhdr.esymMax;
+ while (nesyms--) {
+ if (Read(fd, &esym, sizeof (esym)) != sizeof (esym))
+ BADFREE;
+ symtabname = strtab + esym.es_strindex;
+ for (p = list; !ISLAST(p); p++) {
nlistname = p->n_un.n_name;
if (*nlistname == '_')
nlistname++;
- symtabname =
- &mappedfile[extstroff + esyms[i].es_strindex];
- if (!strcmp(symtabname, nlistname)) {
- p->n_value = esyms[i].es_value;
+ if (strcmp(symtabname, nlistname) == 0) {
+ p->n_value = esym.es_value;
p->n_type = N_EXT; /* XXX */
- p->n_desc = 0; /* XXX */
- p->n_other = 0; /* XXX */
if (--nent <= 0)
break;
}
@@ -248,8 +253,8 @@ __ecoff_fdnlist(fd, list)
}
rv = nent;
-unmap:
- munmap(mappedfile, mappedsize);
+freestr:
+ free(strtab);
out:
return (rv);
}
@@ -289,11 +294,11 @@ __elf_is_okay__(ehdr)
int
__elf_fdnlist(fd, list)
- register int fd;
+ register File fd;
register struct nlist *list;
{
register struct nlist *p;
- register caddr_t strtab;
+ register char *strtab = NULL;
register Elf32_Off symoff = 0, symstroff = 0;
register Elf32_Word symsize = 0, symstrsize = 0;
register Elf32_Sword nent, cc, i;
@@ -302,29 +307,42 @@ __elf_fdnlist(fd, list)
Elf32_Ehdr ehdr;
Elf32_Shdr *shdr = NULL;
Elf32_Word shdr_size;
+ int serrno;
struct stat st;
/* Make sure obj is OK */
- if (lseek(fd, (off_t)0, SEEK_SET) == -1 ||
- read(fd, &ehdr, sizeof(Elf32_Ehdr)) != sizeof(Elf32_Ehdr) ||
- !__elf_is_okay__(&ehdr) ||
- fstat(fd, &st) < 0)
+ if (Seek(fd, 0, SEEK_SET) == -1 ||
+ Read(fd, &ehdr, sizeof(Elf32_Ehdr)) != sizeof(Elf32_Ehdr) ||
+ !__elf_is_okay__(&ehdr))
return (-1);
- /* calculate section header table size */
- shdr_size = ehdr.e_shentsize * ehdr.e_shnum;
-
- /* Make sure it's not too big to mmap */
- if (shdr_size > SIZE_T_MAX) {
- errno = EFBIG;
- return (-1);
+ /*
+ * Clean out any left-over information for all valid entries.
+ * Type and value defined to be 0 if not found; historical
+ * versions cleared other and desc as well. Also figure out
+ * the largest string length so don't read any more of the
+ * string table than we have to.
+ *
+ * XXX clearing anything other than n_type and n_value violates
+ * the semantics given in the man page.
+ */
+ nent = 0;
+ for (p = list; !ISLAST(p); ++p) {
+ p->n_type = 0;
+ p->n_other = 0;
+ p->n_desc = 0;
+ p->n_value = 0;
+ ++nent;
}
- /* mmap section header table */
- shdr = (Elf32_Shdr *)mmap(NULL, (size_t)shdr_size, PROT_READ,
- MAP_COPY|MAP_FILE, fd, (off_t) ehdr.e_shoff);
- if (shdr == (Elf32_Shdr *)-1)
- return (-1);
+ /* Calculate section header table size */
+ shdr_size = ehdr.e_shentsize * ehdr.e_shnum;
+
+ /* Alloc and read section header table */
+ shdr = (Elf32_Shdr *)malloc((size_t)shdr_size);
+ if (shdr == NULL || Seek(fd, ehdr.e_shoff, SEEK_SET) == -1 ||
+ Read(fd, shdr, shdr_size) != shdr_size)
+ goto done;
/*
* Find the symbol table entry and it's corresponding
@@ -342,57 +360,22 @@ __elf_fdnlist(fd, list)
}
}
- /* Flush the section header table */
- munmap((caddr_t)shdr, shdr_size);
+ /* Alloc and read in string table */
+ strtab = (char *)malloc(symstrsize);
+ if (strtab == NULL || Seek(fd, symstroff, SEEK_SET) == -1 ||
+ Read(fd, strtab, symstrsize) != symstrsize)
+ goto done;
- /* Check for files too large to mmap. */
- /* XXX is this really possible? */
- if (symstrsize > SIZE_T_MAX) {
- errno = EFBIG;
- return (-1);
- }
/*
- * Map string table into our address space. This gives us
- * an easy way to randomly access all the strings, without
- * making the memory allocation permanent as with malloc/free
- * (i.e., munmap will return it to the system).
+ * Don't process any further if object is stripped.
+ * ELFism -- dunno if stripped by looking at header
*/
- strtab = mmap(NULL, (size_t)symstrsize, PROT_READ, MAP_COPY|MAP_FILE,
- fd, (off_t) symstroff);
- if (strtab == (char *)-1)
- return (-1);
- /*
- * clean out any left-over information for all valid entries.
- * Type and value defined to be 0 if not found; historical
- * versions cleared other and desc as well. Also figure out
- * the largest string length so don't read any more of the
- * string table than we have to.
- *
- * XXX clearing anything other than n_type and n_value violates
- * the semantics given in the man page.
- */
- nent = 0;
- for (p = list; !ISLAST(p); ++p) {
- p->n_type = 0;
- p->n_other = 0;
- p->n_desc = 0;
- p->n_value = 0;
- ++nent;
- }
-
- /* Don't process any further if object is stripped. */
- /* ELFism - dunno if stripped by looking at header */
- if (symoff == 0)
- goto done;
-
- if (lseek(fd, (off_t) symoff, SEEK_SET) == -1) {
- nent = -1;
+ if (symoff == 0 || Seek(fd, symoff, SEEK_SET) == -1)
goto done;
- }
while (symsize > 0) {
cc = MIN(symsize, sizeof(sbuf));
- if (read(fd, sbuf, cc) != cc)
+ if (Read(fd, sbuf, cc) != cc)
break;
symsize -= cc;
for (s = sbuf; cc > 0; ++s, cc -= sizeof(*s)) {
@@ -432,8 +415,6 @@ __elf_fdnlist(fd, list)
if (ELF32_ST_BIND(s->st_info) ==
STB_LOCAL)
p->n_type = N_EXT;
- p->n_desc = 0;
- p->n_other = 0;
if (--nent <= 0)
break;
}
@@ -441,14 +422,19 @@ __elf_fdnlist(fd, list)
}
}
done:
- munmap(strtab, symstrsize);
+ serrno = errno;
+ if (shdr)
+ free(shdr);
+ if (strtab)
+ free(strtab);
+ errno = serrno;
return (nent);
}
#endif /* _NLIST_DO_ELF */
static struct nlist_handlers {
- int (*fn) __P((int fd, struct nlist *list));
+ int (*fn) __P((File fd, struct nlist *list));
} nlist_fn[] = {
#ifdef _NLIST_DO_AOUT
{ __aout_fdnlist },
@@ -466,26 +452,44 @@ __fdnlist(fd, list)
register int fd;
register struct nlist *list;
{
- int n = -1, i;
+ int n = -1, i, serrno;
+ File f;
+#ifdef _NLIST_DO_GZIP
+ int nfd;
+
+ if ((nfd = dup(fd)) == -1)
+ return (-1);
+
+ if ((f = gzdopen(nfd, "r")) == NULL)
+ return (-1);
+#else
+ f = fd;
+#endif /* _NLIST_DO_GZIP */
for (i = 0; i < sizeof(nlist_fn)/sizeof(nlist_fn[0]); i++) {
- n = (nlist_fn[i].fn)(fd, list);
+ n = (nlist_fn[i].fn)(f, list);
+ serrno = errno;
if (n != -1)
break;
}
+
+#ifdef _NLIST_DO_GZIP
+ (void)gzclose(f);
+#endif /* _NLIST_DO_GZIP */
+
+ errno = serrno;
return (n);
}
-
int
nlist(name, list)
const char *name;
struct nlist *list;
{
- int fd, n;
+ int n, fd;
- fd = open(name, O_RDONLY, 0);
- if (fd < 0)
+ fd = open(name, O_RDONLY);
+ if (fd == -1)
return (-1);
n = __fdnlist(fd, list);
(void)close(fd);