From owner-svn-src-stable@FreeBSD.ORG Sun Feb 17 03:33:14 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 9AD56B60; Sun, 17 Feb 2013 03:33:14 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 8C1D481E; Sun, 17 Feb 2013 03:33:14 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r1H3XEZt056889; Sun, 17 Feb 2013 03:33:14 GMT (envelope-from pfg@svn.freebsd.org) Received: (from pfg@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r1H3XDlx056887; Sun, 17 Feb 2013 03:33:13 GMT (envelope-from pfg@svn.freebsd.org) Message-Id: <201302170333.r1H3XDlx056887@svn.freebsd.org> From: "Pedro F. Giffuni" Date: Sun, 17 Feb 2013 03:33:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r246895 - in stable/9/usr.sbin/crunch: crunchgen crunchide X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Feb 2013 03:33:14 -0000 Author: pfg Date: Sun Feb 17 03:33:13 2013 New Revision: 246895 URL: http://svnweb.freebsd.org/changeset/base/246895 Log: MFC r246296, r246298, r246346; crunchide: support non-custom elf object layout. crunchgen: Permit use of alternative linkers. crunchide: Put e_shnum into a local variable. [1] Submitted by: Pete Chou Reviewed by: Christoph Mallon [1] Modified: stable/9/usr.sbin/crunch/crunchgen/crunchgen.c stable/9/usr.sbin/crunch/crunchide/exec_elf32.c Directory Properties: stable/9/usr.sbin/ (props changed) stable/9/usr.sbin/crunch/ (props changed) Modified: stable/9/usr.sbin/crunch/crunchgen/crunchgen.c ============================================================================== --- stable/9/usr.sbin/crunch/crunchgen/crunchgen.c Sun Feb 17 02:52:42 2013 (r246894) +++ stable/9/usr.sbin/crunch/crunchgen/crunchgen.c Sun Feb 17 03:33:13 2013 (r246895) @@ -978,6 +978,7 @@ top_makefile_rules(FILE *outmk) { prog_t *p; + fprintf(outmk, "LD?= ld\n"); if ( subtract_strlst(&libs, &libs_so) ) fprintf(outmk, "# NOTE: Some LIBS declarations below overridden by LIBS_SO\n"); @@ -1107,7 +1108,7 @@ prog_makefile_rules(FILE *outmk, prog_t fprintf(outmk, " $(%s_LIBS)", p->ident); fprintf(outmk, "\n"); - fprintf(outmk, "\tld -dc -r -o %s.lo %s_stub.o $(%s_OBJPATHS)", + fprintf(outmk, "\t$(LD) -dc -r -o %s.lo %s_stub.o $(%s_OBJPATHS)", p->name, p->name, p->ident); if (p->libs) fprintf(outmk, " $(%s_LIBS)", p->ident); Modified: stable/9/usr.sbin/crunch/crunchide/exec_elf32.c ============================================================================== --- stable/9/usr.sbin/crunch/crunchide/exec_elf32.c Sun Feb 17 02:52:42 2013 (r246894) +++ stable/9/usr.sbin/crunch/crunchide/exec_elf32.c Sun Feb 17 03:33:13 2013 (r246895) @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -82,11 +83,9 @@ __FBSDID("$FreeBSD$"); #define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) #define htoxe32(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) -struct listelem { - struct listelem *next; - void *mem; - off_t file; - size_t size; +struct shlayout { + Elf_Shdr *shdr; + void *bufp; }; static ssize_t @@ -235,87 +234,154 @@ int ELFNAMEEND(hide)(int fd, const char *fn) { Elf_Ehdr ehdr; - Elf_Shdr *shdrp = NULL, *symtabshdr, *strtabshdr; + struct shlayout *layoutp = NULL; + Elf_Shdr *shdrp = NULL, *symtabshdr, *strtabshdr, *shstrtabshdr; + Elf_Shdr shdrshdr; Elf_Sym *symtabp = NULL; - char *strtabp = NULL; - Elf_Size nsyms, ewi; + char *shstrtabp = NULL, *strtabp = NULL; + Elf_Size nsyms, ewi; + Elf_Off off; ssize_t shdrsize; - int rv, i, weird; - size_t nstrtab_size, nstrtab_nextoff, fn_size; + int rv, i, weird, l, m, r, strtabidx; + size_t nstrtab_size, nstrtab_nextoff, fn_size, size; char *nstrtabp = NULL; unsigned char data; - Elf_Off maxoff, stroff; const char *weirdreason = NULL; + void *buf; + Elf_Half shnum; rv = 0; if (xreadatoff(fd, &ehdr, 0, sizeof ehdr, fn) != sizeof ehdr) goto bad; data = ehdr.e_ident[EI_DATA]; + shnum = xe16toh(ehdr.e_shnum); - shdrsize = xe16toh(ehdr.e_shnum) * xe16toh(ehdr.e_shentsize); + shdrsize = shnum * xe16toh(ehdr.e_shentsize); if ((shdrp = xmalloc(shdrsize, fn, "section header table")) == NULL) goto bad; if (xreadatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) != shdrsize) goto bad; - symtabshdr = strtabshdr = NULL; + symtabshdr = strtabshdr = shstrtabshdr = NULL; weird = 0; - maxoff = stroff = 0; - for (i = 0; i < xe16toh(ehdr.e_shnum); i++) { - if (xewtoh(shdrp[i].sh_offset) > maxoff) - maxoff = xewtoh(shdrp[i].sh_offset); + for (i = 0; i < shnum; i++) { switch (xe32toh(shdrp[i].sh_type)) { case SHT_SYMTAB: - if (symtabshdr != NULL) + if (symtabshdr != NULL) { weird = 1; + weirdreason = "multiple symbol tables"; + } symtabshdr = &shdrp[i]; strtabshdr = &shdrp[xe32toh(shdrp[i].sh_link)]; - - /* Check whether the string table is the last section */ - stroff = xewtoh(shdrp[xe32toh(shdrp[i].sh_link)].sh_offset); - if (!weird && xe32toh(shdrp[i].sh_link) != (xe16toh(ehdr.e_shnum) - 1)) { - weird = 1; - weirdreason = "string table not last section"; - } + break; + case SHT_STRTAB: + if (i == xe16toh(ehdr.e_shstrndx)) + shstrtabshdr = &shdrp[i]; break; } } - if (! weirdreason) - weirdreason = "unsupported"; if (symtabshdr == NULL) goto out; - if (strtabshdr == NULL) + if (strtabshdr == NULL) { weird = 1; - if (!weird && stroff != maxoff) { + weirdreason = "string table does not exist"; + } + if (shstrtabshdr == NULL) { weird = 1; - weirdreason = "string table section not last in file"; - } + weirdreason = "section header string table does not exist"; + } + if (weirdreason == NULL) + weirdreason = "unsupported"; if (weird) { fprintf(stderr, "%s: weird executable (%s)\n", fn, weirdreason); goto bad; } /* + * sort section layout table by offset + */ + layoutp = xmalloc((shnum + 1) * sizeof(struct shlayout), + fn, "layout table"); + if (layoutp == NULL) + goto bad; + + /* add a pseudo entry to represent the section header table */ + shdrshdr.sh_offset = ehdr.e_shoff; + shdrshdr.sh_size = htoxew(shdrsize); + shdrshdr.sh_addralign = htoxew(ELFSIZE / 8); + layoutp[shnum].shdr = &shdrshdr; + + /* insert and sort normal section headers */ + for (i = shnum; i-- != 0;) { + l = i + 1; + r = shnum; + while (l <= r) { + m = ( l + r) / 2; + if (xewtoh(shdrp[i].sh_offset) > + xewtoh(layoutp[m].shdr->sh_offset)) + l = m + 1; + else + r = m - 1; + } + + if (r != i) { + memmove(&layoutp[i], &layoutp[i + 1], + sizeof(struct shlayout) * (r - i)); + } + + layoutp[r].shdr = &shdrp[i]; + layoutp[r].bufp = NULL; + } + ++shnum; + + /* * load up everything we need */ - /* symbol table */ - if ((symtabp = xmalloc(xewtoh(symtabshdr->sh_size), fn, "symbol table")) - == NULL) - goto bad; - if ((size_t)xreadatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset), - xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size)) + /* load section string table for debug use */ + if ((shstrtabp = xmalloc(xewtoh(shstrtabshdr->sh_size), fn, + "section string table")) == NULL) + goto bad; + if ((size_t)xreadatoff(fd, shstrtabp, xewtoh(shstrtabshdr->sh_offset), + xewtoh(shstrtabshdr->sh_size), fn) != xewtoh(shstrtabshdr->sh_size)) goto bad; - /* string table */ - if ((strtabp = xmalloc(xewtoh(strtabshdr->sh_size), fn, "string table")) - == NULL) - goto bad; - if ((size_t)xreadatoff(fd, strtabp, xewtoh(strtabshdr->sh_offset), - xewtoh(strtabshdr->sh_size), fn) != xewtoh(strtabshdr->sh_size)) - goto bad; + /* we need symtab, strtab, and everything behind strtab */ + strtabidx = INT_MAX; + for (i = 0; i < shnum; i++) { + if (layoutp[i].shdr == &shdrshdr) { + /* not load section header again */ + layoutp[i].bufp = shdrp; + continue; + } + if (layoutp[i].shdr == shstrtabshdr) { + /* not load section string table again */ + layoutp[i].bufp = shstrtabp; + continue; + } + + if (layoutp[i].shdr == strtabshdr) + strtabidx = i; + if (layoutp[i].shdr == symtabshdr || i >= strtabidx) { + off = xewtoh(layoutp[i].shdr->sh_offset); + size = xewtoh(layoutp[i].shdr->sh_size); + layoutp[i].bufp = xmalloc(size, fn, + shstrtabp + xewtoh(layoutp[i].shdr->sh_name)); + if (layoutp[i].bufp == NULL) + goto bad; + if ((size_t)xreadatoff(fd, layoutp[i].bufp, off, size, fn) != + size) + goto bad; + + /* set symbol table and string table */ + if (layoutp[i].shdr == symtabshdr) + symtabp = layoutp[i].bufp; + else if (layoutp[i].shdr == strtabshdr) + strtabp = layoutp[i].bufp; + } + } nstrtab_size = 256; nstrtabp = xmalloc(nstrtab_size, fn, "new string table"); @@ -365,28 +431,62 @@ ELFNAMEEND(hide)(int fd, const char *fn) strtabshdr->sh_size = htoxew(nstrtab_nextoff); /* - * write new tables to the file + * update section header table in ascending order of offset */ - if (xwriteatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) != - shdrsize) - goto bad; - if ((size_t)xwriteatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset), - xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size)) - goto bad; - /* write new symbol table strings */ - if ((size_t)xwriteatoff(fd, nstrtabp, xewtoh(strtabshdr->sh_offset), - xewtoh(strtabshdr->sh_size), fn) != xewtoh(strtabshdr->sh_size)) - goto bad; + for (i = strtabidx + 1; i < shnum; i++) { + Elf_Off off, align; + off = xewtoh(layoutp[i - 1].shdr->sh_offset) + + xewtoh(layoutp[i - 1].shdr->sh_size); + align = xewtoh(layoutp[i].shdr->sh_addralign); + off = (off + (align - 1)) & ~(align - 1); + layoutp[i].shdr->sh_offset = htoxew(off); + } + + /* + * write data to the file in descending order of offset + */ + for (i = shnum; i-- != 0;) { + if (layoutp[i].shdr == strtabshdr) { + /* new string table */ + buf = nstrtabp; + } else + buf = layoutp[i].bufp; + + if (layoutp[i].shdr == &shdrshdr || + layoutp[i].shdr == symtabshdr || i >= strtabidx) { + if (buf == NULL) + goto bad; + + /* + * update the offset of section header table in elf + * header if needed. + */ + if (layoutp[i].shdr == &shdrshdr && + ehdr.e_shoff != shdrshdr.sh_offset) { + ehdr.e_shoff = shdrshdr.sh_offset; + off = (ELFSIZE == 32) ? 32 : 44; + size = sizeof(Elf_Off); + if ((size_t)xwriteatoff(fd, &ehdr.e_shoff, off, size, + fn) != size) + goto bad; + } + + off = xewtoh(layoutp[i].shdr->sh_offset); + size = xewtoh(layoutp[i].shdr->sh_size); + if ((size_t)xwriteatoff(fd, buf, off, size, fn) != size) + goto bad; + } + } out: - if (shdrp != NULL) - free(shdrp); - if (symtabp != NULL) - free(symtabp); - if (strtabp != NULL) - free(strtabp); - if (nstrtabp != NULL) - free(nstrtabp); + if (layoutp != NULL) { + for (i = 0; i < shnum; i++) { + if (layoutp[i].bufp != NULL) + free(layoutp[i].bufp); + } + free(layoutp); + } + free(nstrtabp); return (rv); bad: