summaryrefslogtreecommitdiff
path: root/usr.sbin/crunch
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>2013-02-08 16:10:16 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>2013-02-08 16:10:16 +0000
commitd9a447559bc04121f7c6682e64abe67efa154864 (patch)
treeb2f038222ff8a70f687652441df00d2b564c8abe /usr.sbin/crunch
parent3cbf5f97aafc2b249c509ee1162c47c9b28e591e (diff)
parentfbda3d5daeeb730a49d025b614b35a32f0319718 (diff)
downloadsrc-test2-d9a447559bc04121f7c6682e64abe67efa154864.tar.gz
src-test2-d9a447559bc04121f7c6682e64abe67efa154864.zip
Notes
Diffstat (limited to 'usr.sbin/crunch')
-rw-r--r--usr.sbin/crunch/crunchgen/crunchgen.c36
-rw-r--r--usr.sbin/crunch/crunchide/exec_elf32.c230
-rw-r--r--usr.sbin/crunch/examples/really-big.conf2
3 files changed, 186 insertions, 82 deletions
diff --git a/usr.sbin/crunch/crunchgen/crunchgen.c b/usr.sbin/crunch/crunchgen/crunchgen.c
index 48d6f33cb25c..e25c1accef44 100644
--- a/usr.sbin/crunch/crunchgen/crunchgen.c
+++ b/usr.sbin/crunch/crunchgen/crunchgen.c
@@ -105,11 +105,11 @@ int list_mode;
/* general library routines */
-void status(char *str);
+void status(const char *str);
void out_of_memory(void);
void add_string(strlst_t **listp, char *str);
-int is_dir(char *pathname);
-int is_nonempty_file(char *pathname);
+int is_dir(const char *pathname);
+int is_nonempty_file(const char *pathname);
int subtract_strlst(strlst_t **lista, strlst_t **listb);
int in_list(strlst_t **listp, char *str);
@@ -119,6 +119,8 @@ void usage(void);
void parse_conf_file(void);
void gen_outputs(void);
+extern char *crunched_skel[];
+
int
main(int argc, char **argv)
@@ -245,7 +247,7 @@ usage(void)
/* helper routines for parse_conf_file */
void parse_one_file(char *filename);
-void parse_line(char *line, int *fc, char **fv, int nf);
+void parse_line(char *pline, int *fc, char **fv, int nf);
void add_srcdirs(int argc, char **argv);
void add_progs(int argc, char **argv);
void add_link(int argc, char **argv);
@@ -340,15 +342,15 @@ parse_one_file(char *filename)
void
-parse_line(char *line, int *fc, char **fv, int nf)
+parse_line(char *pline, int *fc, char **fv, int nf)
{
char *p;
- p = line;
+ p = pline;
*fc = 0;
while (1) {
- while (isspace(*p))
+ while (isspace((unsigned char)*p))
p++;
if (*p == '\0' || *p == '#')
@@ -357,7 +359,7 @@ parse_line(char *line, int *fc, char **fv, int nf)
if (*fc < nf)
fv[(*fc)++] = p;
- while (*p && !isspace(*p) && *p != '#')
+ while (*p && !isspace((unsigned char)*p) && *p != '#')
p++;
if (*p == '\0' || *p == '#')
@@ -767,17 +769,17 @@ fillin_program_objs(prog_t *p, char *path)
}
cp = line + 6;
- while (isspace(*cp))
+ while (isspace((unsigned char)*cp))
cp++;
while(*cp) {
obj = cp;
- while (*cp && !isspace(*cp))
+ while (*cp && !isspace((unsigned char)*cp))
cp++;
if (*cp)
*cp++ = '\0';
add_string(&p->objs, obj);
- while (isspace(*cp))
+ while (isspace((unsigned char)*cp))
cp++;
}
}
@@ -887,7 +889,6 @@ gen_output_makefile(void)
void
gen_output_cfile(void)
{
- extern char *crunched_skel[];
char **cp;
FILE *outcf;
prog_t *p;
@@ -945,7 +946,7 @@ char *genident(char *str)
for (d = s = n; *s != '\0'; s++) {
if (*s == '-')
*d++ = '_';
- else if (*s == '_' || isalnum(*s))
+ else if (*s == '_' || isalnum((unsigned char)*s))
*d++ = *s;
}
*d = '\0';
@@ -978,6 +979,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 +1109,7 @@ prog_makefile_rules(FILE *outmk, prog_t *p)
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);
@@ -1135,7 +1137,7 @@ output_strlst(FILE *outf, strlst_t *lst)
*/
void
-status(char *str)
+status(const char *str)
{
static int lastlen = 0;
int len, spaces;
@@ -1211,7 +1213,7 @@ in_list(strlst_t **listp, char *str)
}
int
-is_dir(char *pathname)
+is_dir(const char *pathname)
{
struct stat buf;
@@ -1222,7 +1224,7 @@ is_dir(char *pathname)
}
int
-is_nonempty_file(char *pathname)
+is_nonempty_file(const char *pathname)
{
struct stat buf;
diff --git a/usr.sbin/crunch/crunchide/exec_elf32.c b/usr.sbin/crunch/crunchide/exec_elf32.c
index d01fe7e17852..752007f45f26 100644
--- a/usr.sbin/crunch/crunchide/exec_elf32.c
+++ b/usr.sbin/crunch/crunchide/exec_elf32.c
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
#if 0
-__RCSID("$NetBSD: exec_elf32.c,v 1.4 1997/08/12 06:07:24 mikel Exp $");
+__RCSID("$NetBSD: exec_elf32.c,v 1.6 1999/09/20 04:12:16 christos Exp $");
#endif
#endif
__FBSDID("$FreeBSD$");
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <errno.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -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
@@ -98,7 +97,7 @@ xreadatoff(int fd, void *buf, off_t off, size_t size, const char *fn)
perror(fn);
return -1;
}
- if ((rv = read(fd, buf, size)) != size) {
+ if ((size_t)(rv = read(fd, buf, size)) != size) {
fprintf(stderr, "%s: read error: %s\n", fn,
rv == -1 ? strerror(errno) : "short read");
return -1;
@@ -115,7 +114,7 @@ xwriteatoff(int fd, void *buf, off_t off, size_t size, const char *fn)
perror(fn);
return -1;
}
- if ((rv = write(fd, buf, size)) != size) {
+ if ((size_t)(rv = write(fd, buf, size)) != size) {
fprintf(stderr, "%s: write error: %s\n", fn,
rv == -1 ? strerror(errno) : "short write");
return -1;
@@ -162,7 +161,7 @@ ELFNAMEEND(check)(int fd, const char *fn)
*/
if (fstat(fd, &sb) == -1)
return 0;
- if (sb.st_size < sizeof eh)
+ if (sb.st_size < (off_t)(sizeof eh))
return 0;
if (read(fd, &eh, sizeof eh) != sizeof eh)
return 0;
@@ -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)
+ /* load section string table for debug use */
+ if ((shstrtabp = xmalloc(xewtoh(shstrtabshdr->sh_size), fn,
+ "section string table")) == NULL)
goto bad;
- if (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 (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,26 +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 (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 (layoutp != NULL) {
+ for (i = 0; i < shnum; i++) {
+ if (layoutp[i].bufp != NULL)
+ free(layoutp[i].bufp);
+ }
+ free(layoutp);
+ }
+ free(nstrtabp);
return (rv);
bad:
diff --git a/usr.sbin/crunch/examples/really-big.conf b/usr.sbin/crunch/examples/really-big.conf
index fbd7f03f9a3e..922078a83820 100644
--- a/usr.sbin/crunch/examples/really-big.conf
+++ b/usr.sbin/crunch/examples/really-big.conf
@@ -72,7 +72,7 @@ progs dev_mkdb diskpart edquota flcopy gettable grfinfo hilinfo htable inetd
progs iostat iteconfig kvm_mkdb mtree named portmap pppd
progs pstat pwd_mkdb quot quotaon rarpd rbootd repquota rmt rpc.bootparamd
progs rwhod sa spray sysctl syslogd tcpdump
-progs traceroute trpt trsp update vipw vnconfig ypbind yppoll ypset
+progs traceroute trpt update vipw vnconfig ypbind yppoll ypset
special amd srcdir /usr/src/usr.sbin/amd/amd
special amd objs vers.amd.o afs_ops.o am_ops.o clock.o util.o xutil.o efs_ops.o mapc.o info_file.o info_hes.o info_ndbm.o info_passwd.o info_nis.o info_union.o map.o srvr_afs.o srvr_nfs.o mntfs.o misc_rpc.o mount_fs.o mtab.o mtab_bsd.o nfs_ops.o nfs_prot_svc.o nfs_start.o nfs_subr.o opts.o pfs_ops.o rpc_fwd.o sched.o sfs_ops.o amq_svc.o amq_subr.o umount_fs.o host_ops.o nfsx_ops.o ufs_ops.o ifs_ops.o amd.o get_args.o restart.o wire.o