[Midnightbsd-cvs] src [8784] trunk/usr.sbin/crunch: permit use of alt linkers.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Sep 25 23:11:27 EDT 2016


Revision: 8784
          http://svnweb.midnightbsd.org/src/?rev=8784
Author:   laffer1
Date:     2016-09-25 23:11:26 -0400 (Sun, 25 Sep 2016)
Log Message:
-----------
permit use of alt linkers.

Modified Paths:
--------------
    trunk/usr.sbin/crunch/crunchgen/crunchgen.c
    trunk/usr.sbin/crunch/crunchide/exec_elf32.c

Modified: trunk/usr.sbin/crunch/crunchgen/crunchgen.c
===================================================================
--- trunk/usr.sbin/crunch/crunchgen/crunchgen.c	2016-09-26 03:10:49 UTC (rev 8783)
+++ trunk/usr.sbin/crunch/crunchgen/crunchgen.c	2016-09-26 03:11:26 UTC (rev 8784)
@@ -980,6 +980,7 @@
 {
 	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");
 
@@ -1109,7 +1110,7 @@
 		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: trunk/usr.sbin/crunch/crunchide/exec_elf32.c
===================================================================
--- trunk/usr.sbin/crunch/crunchide/exec_elf32.c	2016-09-26 03:10:49 UTC (rev 8783)
+++ trunk/usr.sbin/crunch/crunchide/exec_elf32.c	2016-09-26 03:11:26 UTC (rev 8784)
@@ -45,6 +45,7 @@
 #include <sys/stat.h>
 
 #include <errno.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -82,11 +83,9 @@
 #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,17 +234,21 @@
 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)
@@ -252,8 +255,9 @@
 		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) !=
@@ -260,38 +264,36 @@
 	    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;
@@ -298,25 +300,89 @@
 	}
 
 	/*
+	 * 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)
+	/* 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, symtabp, xewtoh(symtabshdr->sh_offset),
-	    xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size))
+	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");
 	if (nstrtabp == NULL)
@@ -365,28 +431,62 @@
 	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:



More information about the Midnightbsd-cvs mailing list