From: jsing Date: Fri, 27 Dec 2013 15:02:49 +0000 (+0000) Subject: Instead of playing #include games to get a 32-bit ELF implementation on X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=e22d318dfa82b187ccb718f58c8bff73b33f8b40;p=openbsd Instead of playing #include games to get a 32-bit ELF implementation on amd64, simply compile in our own nlist_elf32. Remove ECOFF and AOUT from the nlist implementation since we do not need it. This makes the code identical for the i386 and amd64 versions of installboot(8). --- diff --git a/usr.sbin/installboot/amd64/Makefile.inc b/usr.sbin/installboot/amd64/Makefile.inc index 337d79491be..d986984b198 100644 --- a/usr.sbin/installboot/amd64/Makefile.inc +++ b/usr.sbin/installboot/amd64/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.1 2013/12/27 14:12:56 jsing Exp $ +# $OpenBSD: Makefile.inc,v 1.2 2013/12/27 15:02:49 jsing Exp $ CPPFLAGS += -I${.CURDIR}/amd64 @@ -9,4 +9,5 @@ SRCS += softraid.c .PATH: ${.CURDIR}/i386 SRCS += i386_installboot.c +SRCS += i386_nlist.c SRCS += i386_softraid.c diff --git a/usr.sbin/installboot/i386/Makefile.inc b/usr.sbin/installboot/i386/Makefile.inc index da1acc8f7c1..11c878a74b7 100644 --- a/usr.sbin/installboot/i386/Makefile.inc +++ b/usr.sbin/installboot/i386/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.1 2013/12/27 13:52:40 jsing Exp $ +# $OpenBSD: Makefile.inc,v 1.2 2013/12/27 15:02:49 jsing Exp $ CPPFLAGS += -I${.CURDIR}/i386 CFLAGS += -DSOFTRAID @@ -7,4 +7,5 @@ SRCS += softraid.c .PATH: ${.CURDIR}/i386 SRCS += i386_installboot.c +SRCS += i386_nlist.c SRCS += i386_softraid.c diff --git a/usr.sbin/installboot/i386/i386_installboot.c b/usr.sbin/installboot/i386/i386_installboot.c index 47178c0bf79..949b34a4597 100644 --- a/usr.sbin/installboot/i386/i386_installboot.c +++ b/usr.sbin/installboot/i386/i386_installboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i386_installboot.c,v 1.3 2013/12/27 14:12:56 jsing Exp $ */ +/* $OpenBSD: i386_installboot.c,v 1.4 2013/12/27 15:02:49 jsing Exp $ */ /* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ /* @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -57,7 +56,7 @@ #include #include -#include +#include #include #include #include @@ -70,10 +69,6 @@ #include "installboot.h" #include "i386_installboot.h" -#ifdef NLIST -#include "i386_nlist.c" -#endif - char *blkstore; size_t blksize; @@ -530,9 +525,9 @@ pbr_set_symbols(char *fname, char *proto, struct sym_data *sym_list) if (nl == NULL) err(1, NULL); - nl->n_un.n_name = sym->sym_name; + nl->n_name = sym->sym_name; - if (nlist(fname, nl) != 0) + if (nlist_elf32(fname, nl) != 0) errx(1, "%s: symbol %s not found", fname, sym->sym_name); diff --git a/usr.sbin/installboot/i386/i386_installboot.h b/usr.sbin/installboot/i386/i386_installboot.h index ac61e355fb3..f42ff8f27c2 100644 --- a/usr.sbin/installboot/i386/i386_installboot.h +++ b/usr.sbin/installboot/i386/i386_installboot.h @@ -49,6 +49,9 @@ struct sym_data { extern struct sym_data pbr_symbols[]; +struct nlist; + +int nlist_elf32(const char *, struct nlist *); void pbr_set_symbols(char *, char *, struct sym_data *); void sym_set_value(struct sym_data *, char *, u_int32_t); void write_bootblocks(int, char *, struct disklabel *); diff --git a/usr.sbin/installboot/i386/i386_nlist.c b/usr.sbin/installboot/i386/i386_nlist.c index de32f4f467b..af6b1440713 100644 --- a/usr.sbin/installboot/i386/i386_nlist.c +++ b/usr.sbin/installboot/i386/i386_nlist.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i386_nlist.c,v 1.1 2013/12/27 14:12:56 jsing Exp $ */ +/* $OpenBSD: i386_nlist.c,v 1.2 2013/12/27 15:02:49 jsing Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -28,242 +28,27 @@ * SUCH DAMAGE. */ -#include +#define ELFSIZE 32 + #include +#include #include #include -#include +#include #include -#include +#include #include #include #include -#include /* pulls in nlist.h */ - -#ifdef _NLIST_DO_ELF -#include -#endif - -#ifdef _NLIST_DO_ECOFF -#include -#endif - -int __fdnlist(int, struct nlist *); -int __aout_fdnlist(int, struct nlist *); -int __ecoff_fdnlist(int, struct nlist *); -int __elf_fdnlist(int, struct nlist *); -#ifdef _NLIST_DO_ELF -int __elf_is_okay__(Elf_Ehdr *ehdr); -#endif - -#define ISLAST(p) (p->n_un.n_name == 0 || p->n_un.n_name[0] == 0) - -#ifdef _NLIST_DO_AOUT -int -__aout_fdnlist(int fd, struct nlist *list) -{ - struct nlist *p, *s; - char *strtab; - off_t symoff, stroff; - u_long symsize; - int nent, cc; - int strsize, usemalloc = 0; - struct nlist nbuf[1024]; - struct exec exec; - - if (pread(fd, &exec, sizeof(exec), (off_t)0) != sizeof(exec) || - N_BADMAG(exec) || exec.a_syms == 0) - return (-1); - - stroff = N_STROFF(exec); - symoff = N_SYMOFF(exec); - symsize = exec.a_syms; - - /* Read in the size of the string table. */ - if (pread(fd, (void *)&strsize, sizeof(strsize), stroff) != - sizeof(strsize)) - return (-1); - else - stroff += sizeof(strsize); - - /* - * Read in the string table. We try mmap, but that will fail - * for /dev/ksyms so fall back on malloc. Since OpenBSD's malloc(3) - * returns memory to the system on free this does not cause bloat. - */ - strsize -= sizeof(strsize); - strtab = mmap(NULL, (size_t)strsize, PROT_READ, MAP_SHARED|MAP_FILE, - fd, stroff); - if (strtab == MAP_FAILED) { - usemalloc = 1; - if ((strtab = (char *)malloc(strsize)) == NULL) - return (-1); - errno = EIO; - if (pread(fd, strtab, strsize, stroff) != strsize) { - nent = -1; - goto aout_done; - } - } - - /* - * 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; - } - - while (symsize > 0) { - cc = MIN(symsize, sizeof(nbuf)); - if (pread(fd, nbuf, cc, symoff) != cc) - break; - symsize -= cc; - symoff += cc; - for (s = nbuf; cc > 0; ++s, cc -= sizeof(*s)) { - char *sname = strtab + s->n_un.n_strx - sizeof(int); - - if (s->n_un.n_strx == 0 || (s->n_type & N_STAB) != 0) - continue; - for (p = list; !ISLAST(p); p++) { - char *pname = p->n_un.n_name; - - if (*sname != '_' && *pname == '_') - pname++; - if (!strcmp(sname, pname)) { - p->n_value = s->n_value; - p->n_type = s->n_type; - p->n_desc = s->n_desc; - p->n_other = s->n_other; - if (--nent <= 0) - break; - } - } - } - } -aout_done: - if (usemalloc) - free(strtab); - else - munmap(strtab, strsize); - return (nent); -} -#endif /* _NLIST_DO_AOUT */ - -#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) - -int -__ecoff_fdnlist(int fd, 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; - - rv = -3; - - if (fstat(fd, &st) < 0) - BAD; - if (st.st_size > SIZE_T_MAX) { - errno = EFBIG; - BAD; - } - mappedsize = st.st_size; - mappedfile = mmap(NULL, mappedsize, PROT_READ, MAP_SHARED|MAP_FILE, - fd, 0); - if (mappedfile == MAP_FAILED) - BAD; - if (check(0, sizeof *exechdrp)) - BADUNMAP; - exechdrp = (struct ecoff_exechdr *)&mappedfile[0]; +static int __elf_fdnlist(int, struct nlist *); +static int __elf_is_okay__(Elf_Ehdr *ehdr); - if (ECOFF_BADMAG(exechdrp)) - BADUNMAP; +int nlist_elf32(const char *, struct nlist *); - symhdroff = exechdrp->f.f_symptr; - symhdrsize = exechdrp->f.f_nsyms; +#define ISLAST(p) (p->n_name == 0 || p->n_name[0] == 0) - 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; - - /* - * 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. - * - * 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; - } - - for (i = 0; i < nesyms; i++) { - for (p = list; !ISLAST(p); p++) { - char *nlistname; - char *symtabname; - - 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; - p->n_type = N_EXT; /* XXX */ - p->n_desc = 0; /* XXX */ - p->n_other = 0; /* XXX */ - if (--nent <= 0) - break; - } - } - } - rv = nent; - -unmap: - munmap(mappedfile, mappedsize); -out: - return (rv); -} -#endif /* _NLIST_DO_ECOFF */ - -#ifdef _NLIST_DO_ELF /* * __elf_is_okay__ - Determine if ehdr really * is ELF and valid for the target platform. @@ -271,7 +56,7 @@ out: * WARNING: This is NOT a ELF ABI function and * as such its use should be restricted. */ -int +static int __elf_is_okay__(Elf_Ehdr *ehdr) { int retval = 0; @@ -302,7 +87,7 @@ __elf_is_okay__(Elf_Ehdr *ehdr) return retval; } -int +static int __elf_fdnlist(int fd, struct nlist *list) { struct nlist *p; @@ -334,7 +119,8 @@ __elf_fdnlist(int fd, struct nlist *list) if ((shdr = malloc(shdr_size)) == NULL) return (-1); - if (pread(fd, shdr, shdr_size, (off_t)ehdr.e_shoff) != shdr_size) { + if (pread(fd, shdr, shdr_size, (off_t)ehdr.e_shoff) != + shdr_size) { free(shdr); return (-1); } @@ -371,7 +157,8 @@ __elf_fdnlist(int fd, struct nlist *list) if (usemalloc) { if ((strtab = malloc(symstrsize)) == NULL) return (-1); - if (pread(fd, strtab, symstrsize, (off_t)symstroff) != symstrsize) { + if (pread(fd, strtab, symstrsize, (off_t)symstroff) != + symstrsize) { free(strtab); return (-1); } @@ -429,7 +216,7 @@ __elf_fdnlist(int fd, struct nlist *list) * for both 'foo' and '_foo' in the * table and 'foo' is first? */ - sym = p->n_un.n_name; + sym = p->n_name; if (strcmp(&strtab[soff], sym) != 0 && (sym[0] != '_' || strcmp(&strtab[soff], sym + 1) != 0)) @@ -483,46 +270,17 @@ elf_done: munmap(strtab, symstrsize); return (nent); } -#endif /* _NLIST_DO_ELF */ - - -static struct nlist_handlers { - int (*fn)(int fd, struct nlist *list); -} nlist_fn[] = { -#ifdef _NLIST_DO_AOUT - { __aout_fdnlist }, -#endif -#ifdef _NLIST_DO_ELF - { __elf_fdnlist }, -#endif -#ifdef _NLIST_DO_ECOFF - { __ecoff_fdnlist }, -#endif -}; - -int -__fdnlist(int fd, struct nlist *list) -{ - int n = -1, i; - - for (i = 0; i < (int)(sizeof(nlist_fn)/sizeof(nlist_fn[0])); i++) { - n = (nlist_fn[i].fn)(fd, list); - if (n != -1) - break; - } - return (n); -} - int -nlist(const char *name, struct nlist *list) +nlist_elf32(const char *name, struct nlist *list) { int fd, n; fd = open(name, O_RDONLY, 0); if (fd < 0) return (-1); - n = __fdnlist(fd, list); - (void)close(fd); + n = __elf_fdnlist(fd, list); + close(fd); + return (n); }