summaryrefslogtreecommitdiffstats
path: root/usr.sbin/crunch/crunchide
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1998-09-14 11:35:32 +0000
committerjkh <jkh@FreeBSD.org>1998-09-14 11:35:32 +0000
commita4969a17ca93b529c57b07fb44668d7563024d3f (patch)
tree593ab577b803f64ca18aad0944f5c5ca1b308269 /usr.sbin/crunch/crunchide
parente7f0dcd13762c2e1e086d5e60434578e55b0d1a6 (diff)
downloadFreeBSD-src-a4969a17ca93b529c57b07fb44668d7563024d3f.zip
FreeBSD-src-a4969a17ca93b529c57b07fb44668d7563024d3f.tar.gz
Teach crunch about an elf/a.out world.
Submitted by: jhay
Diffstat (limited to 'usr.sbin/crunch/crunchide')
-rw-r--r--usr.sbin/crunch/crunchide/Makefile2
-rw-r--r--usr.sbin/crunch/crunchide/crunchide.c233
-rw-r--r--usr.sbin/crunch/crunchide/exec_aout.c203
-rw-r--r--usr.sbin/crunch/crunchide/exec_elf32.c389
-rw-r--r--usr.sbin/crunch/crunchide/exec_elf64.c40
-rw-r--r--usr.sbin/crunch/crunchide/extern.h68
6 files changed, 795 insertions, 140 deletions
diff --git a/usr.sbin/crunch/crunchide/Makefile b/usr.sbin/crunch/crunchide/Makefile
index f6e1a8a..d7abd44 100644
--- a/usr.sbin/crunch/crunchide/Makefile
+++ b/usr.sbin/crunch/crunchide/Makefile
@@ -1,4 +1,6 @@
PROG= crunchide
+SRCS= crunchide.c exec_aout.c exec_elf32.c exec_elf64.c
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/crunch/crunchide/crunchide.c b/usr.sbin/crunch/crunchide/crunchide.c
index 2edc082..04bec03 100644
--- a/usr.sbin/crunch/crunchide/crunchide.c
+++ b/usr.sbin/crunch/crunchide/crunchide.c
@@ -1,4 +1,6 @@
+/* $NetBSD: crunchide.c,v 1.8 1997/11/01 06:51:45 lukem Exp $ */
/*
+ * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
* Copyright (c) 1994 University of Maryland
* All Rights Reserved.
*
@@ -56,32 +58,45 @@
* that the final crunched binary BSS size is the max of all the
* component programs' BSS sizes, rather than their sum.
*/
-#include <a.out.h>
-#include <err.h>
-#include <fcntl.h>
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: crunchide.c,v 1.8 1997/11/01 06:51:45 lukem Exp $");
+#endif
+
+#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
+#include <fcntl.h>
+#include <a.out.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
+#include "extern.h"
+
+char *pname = "crunchide";
+
void usage(void);
void add_to_keep_list(char *symbol);
void add_file_to_keep_list(char *filename);
-void hide_syms(char *filename);
+int hide_syms(const char *filename);
+
+int verbose;
+int main __P((int, char *[]));
int main(argc, argv)
int argc;
char **argv;
{
- int ch;
+ int ch, errors;
+
+ if(argc > 0) pname = argv[0];
- while ((ch = getopt(argc, argv, "k:f:")) != -1)
+ while ((ch = getopt(argc, argv, "k:f:v")) != -1)
switch(ch) {
case 'k':
add_to_keep_list(optarg);
@@ -89,6 +104,9 @@ char **argv;
case 'f':
add_file_to_keep_list(optarg);
break;
+ case 'v':
+ verbose = 1;
+ break;
default:
usage();
}
@@ -98,18 +116,21 @@ char **argv;
if(argc == 0) usage();
+ errors = 0;
while(argc) {
- hide_syms(*argv);
+ if (hide_syms(*argv))
+ errors = 1;
argc--, argv++;
}
- return 0;
+ return errors;
}
void usage(void)
{
fprintf(stderr,
- "usage: crunchide [-k <symbol-name>] [-f <keep-list-file>] <files> ...\n");
+ "Usage: %s [-k <symbol-name>] [-f <keep-list-file>] <files> ...\n",
+ pname);
exit(1);
}
@@ -125,6 +146,8 @@ void add_to_keep_list(char *symbol)
struct keep *newp, *prevp, *curp;
int cmp;
+ cmp = 0;
+
for(curp = keep_list, prevp = NULL; curp; prevp = curp, curp = curp->next)
if((cmp = strcmp(symbol, curp->sym)) <= 0) break;
@@ -134,7 +157,8 @@ void add_to_keep_list(char *symbol)
newp = (struct keep *) malloc(sizeof(struct keep));
if(newp) newp->sym = strdup(symbol);
if(newp == NULL || newp->sym == NULL) {
- errx(1, "out of memory for keep list");
+ fprintf(stderr, "%s: out of memory for keep list\n", pname);
+ exit(1);
}
newp->next = curp;
@@ -142,11 +166,13 @@ void add_to_keep_list(char *symbol)
else keep_list = newp;
}
-int in_keep_list(char *symbol)
+int in_keep_list(const char *symbol)
{
struct keep *curp;
int cmp;
+ cmp = 0;
+
for(curp = keep_list; curp; curp = curp->next)
if((cmp = strcmp(symbol, curp->sym)) <= 0) break;
@@ -160,7 +186,7 @@ void add_file_to_keep_list(char *filename)
int len;
if((keepf = fopen(filename, "r")) == NULL) {
- warn("%s", filename);
+ perror(filename);
usage();
}
@@ -174,141 +200,68 @@ void add_file_to_keep_list(char *filename)
fclose(keepf);
}
-/* ---------------------- */
-
-int nsyms, ntextrel, ndatarel;
-struct exec *hdrp;
-char *aoutdata, *strbase;
-struct relocation_info *textrel, *datarel;
-struct nlist *symbase;
-
-
-#define SYMSTR(sp) &strbase[(sp)->n_un.n_strx]
-
-/* is the symbol a global symbol defined in the current file? */
-#define IS_GLOBAL_DEFINED(sp) \
- (((sp)->n_type & N_EXT) && ((sp)->n_type & N_TYPE) != N_UNDF)
-
-/* is the relocation entry dependent on a symbol? */
-#define IS_SYMBOL_RELOC(rp) \
- ((rp)->r_extern||(rp)->r_baserel||(rp)->r_jmptable)
+/* ---------------------------- */
-void check_reloc(char *filename, struct relocation_info *relp);
+struct {
+ const char *name;
+ int (*check)(int, const char *); /* 1 if match, zero if not */
+ int (*hide)(int, const char *); /* non-zero if error */
+} exec_formats[] = {
+#ifdef NLIST_AOUT
+ { "a.out", check_aout, hide_aout, },
+#endif
+#ifdef NLIST_ECOFF
+ { "ECOFF", check_ecoff, hide_ecoff, },
+#endif
+#ifdef NLIST_ELF32
+ { "ELF32", check_elf32, hide_elf32, },
+#endif
+#ifdef NLIST_ELF64
+ { "ELF64", check_elf64, hide_elf64, },
+#endif
+};
-void hide_syms(char *filename)
+int hide_syms(const char *filename)
{
- int inf, rc;
- struct stat infstat;
- struct relocation_info *relp;
- struct nlist *symp;
-
- /*
- * Open the file and do some error checking.
- */
-
- if((inf = open(filename, O_RDWR)) == -1) {
- warn("%s", filename);
- return;
- }
-
- if(fstat(inf, &infstat) == -1) {
- warn("%s", filename);
- close(inf);
- return;
- }
-
- if(infstat.st_size < sizeof(struct exec)) {
- warnx("%s: short file", filename);
- close(inf);
- return;
- }
-
- /*
- * Read the entire file into memory. XXX - Really, we only need to
- * read the header and from TRELOFF to the end of the file.
- */
-
- if((aoutdata = (char *) malloc(infstat.st_size)) == NULL) {
- warnx("%s: too big to read into memory", filename);
- close(inf);
- return;
- }
-
- if((rc = read(inf, aoutdata, infstat.st_size)) < infstat.st_size) {
- warnx("%s: read error: %s", filename,
- rc == -1? strerror(errno) : "short read");
- close(inf);
- return;
- }
+ int fd, i, n, rv;
- /*
- * Check the header and calculate offsets and sizes from it.
- */
+ fd = open(filename, O_RDWR, 0);
+ if (fd == -1) {
+ perror(filename);
+ return 1;
+ }
- hdrp = (struct exec *) aoutdata;
+ rv = 0;
- if(N_BADMAG(*hdrp)) {
- warnx("%s: bad magic: not an a.out file", filename);
- close(inf);
- return;
- }
+ n = sizeof exec_formats / sizeof exec_formats[0];
+ for (i = 0; i < n; i++) {
+ if (lseek(fd, 0, SEEK_SET) != 0) {
+ perror(filename);
+ goto err;
+ }
+ if ((*exec_formats[i].check)(fd, filename) != 0)
+ break;
+ }
+ if (i == n) {
+ fprintf(stderr, "%s: unknown executable format\n", filename);
+ goto err;
+ }
-#ifdef __FreeBSD__
- textrel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp));
- datarel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp) +
- hdrp->a_trsize);
-#else
- textrel = (struct relocation_info *) (aoutdata + N_TRELOFF(*hdrp));
- datarel = (struct relocation_info *) (aoutdata + N_DRELOFF(*hdrp));
-#endif
- symbase = (struct nlist *) (aoutdata + N_SYMOFF(*hdrp));
- strbase = (char *) (aoutdata + N_STROFF(*hdrp));
-
- ntextrel = hdrp->a_trsize / sizeof(struct relocation_info);
- ndatarel = hdrp->a_drsize / sizeof(struct relocation_info);
- nsyms = hdrp->a_syms / sizeof(struct nlist);
-
- /*
- * Zap the type field of all globally-defined symbols. The linker will
- * subsequently ignore these entries. Don't zap any symbols in the
- * keep list.
- */
-
- for(symp = symbase; symp < symbase + nsyms; symp++)
- if(IS_GLOBAL_DEFINED(symp) && !in_keep_list(SYMSTR(symp)))
- symp->n_type = 0;
-
- /*
- * Check whether the relocation entries reference any symbols that we
- * just zapped. I don't know whether ld can handle this case, but I
- * haven't encountered it yet. These checks are here so that the program
- * doesn't fail silently should such symbols be encountered.
- */
-
- for(relp = textrel; relp < textrel + ntextrel; relp++)
- check_reloc(filename, relp);
- for(relp = datarel; relp < datarel + ndatarel; relp++)
- check_reloc(filename, relp);
-
- /*
- * Write the .o file back out to disk. XXX - Really, we only need to
- * write the symbol table entries back out.
- */
- lseek(inf, 0, SEEK_SET);
- if((rc = write(inf, aoutdata, infstat.st_size)) < infstat.st_size) {
- warnx("%s: write error: %s", filename,
- rc == -1? strerror(errno) : "short write");
- }
+ if (verbose)
+ fprintf(stderr, "%s is an %s binary\n", filename,
+ exec_formats[i].name);
- close(inf);
-}
+ if (lseek(fd, 0, SEEK_SET) != 0) {
+ perror(filename);
+ goto err;
+ }
+ rv = (*exec_formats[i].hide)(fd, filename);
+out:
+ close (fd);
+ return (rv);
-void check_reloc(char *filename, struct relocation_info *relp)
-{
- /* bail out if we zapped a symbol that is needed */
- if(IS_SYMBOL_RELOC(relp) && symbase[relp->r_symbolnum].n_type == 0) {
- errx(1, "%s: oops, have hanging relocation for %s: bailing out!",
- filename, SYMSTR(&symbase[relp->r_symbolnum]));
- }
+err:
+ rv = 1;
+ goto out;
}
diff --git a/usr.sbin/crunch/crunchide/exec_aout.c b/usr.sbin/crunch/crunchide/exec_aout.c
new file mode 100644
index 0000000..9f68115
--- /dev/null
+++ b/usr.sbin/crunch/crunchide/exec_aout.c
@@ -0,0 +1,203 @@
+/* $NetBSD: exec_aout.c,v 1.6 1997/08/02 21:30:17 perry Exp $ */
+/*
+ * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
+ * Copyright (c) 1994 University of Maryland
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: exec_aout.c,v 1.6 1997/08/02 21:30:17 perry Exp $");
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <a.out.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+
+#include "extern.h"
+
+#if defined(NLIST_AOUT)
+
+int nsyms, ntextrel, ndatarel;
+struct exec *hdrp;
+char *aoutdata, *strbase;
+struct relocation_info *textrel, *datarel;
+struct nlist *symbase;
+
+
+#define SYMSTR(sp) (&strbase[(sp)->n_un.n_strx])
+
+/* is the symbol a global symbol defined in the current file? */
+#define IS_GLOBAL_DEFINED(sp) \
+ (((sp)->n_type & N_EXT) && ((sp)->n_type & N_TYPE) != N_UNDF)
+
+#ifdef __sparc
+/* is the relocation entry dependent on a symbol? */
+#define IS_SYMBOL_RELOC(rp) \
+ ((rp)->r_extern || \
+ ((rp)->r_type >= RELOC_BASE10 && (rp)->r_type <= RELOC_BASE22) || \
+ (rp)->r_type == RELOC_JMP_TBL)
+#else
+/* is the relocation entry dependent on a symbol? */
+#define IS_SYMBOL_RELOC(rp) \
+ ((rp)->r_extern||(rp)->r_baserel||(rp)->r_jmptable)
+#endif
+
+static void check_reloc(const char *filename, struct relocation_info *relp);
+
+int check_aout(int inf, const char *filename)
+{
+ struct stat infstat;
+ struct exec eh;
+
+ /*
+ * check the header to make sure it's an a.out-format file.
+ */
+
+ if(fstat(inf, &infstat) == -1)
+ return 0;
+ if(infstat.st_size < sizeof eh)
+ return 0;
+ if(read(inf, &eh, sizeof eh) != sizeof eh)
+ return 0;
+
+ if(N_BADMAG(eh))
+ return 0;
+
+ return 1;
+}
+
+int hide_aout(int inf, const char *filename)
+{
+ struct stat infstat;
+ struct relocation_info *relp;
+ struct nlist *symp;
+ int rc;
+
+ /*
+ * do some error checking.
+ */
+
+ if(fstat(inf, &infstat) == -1) {
+ perror(filename);
+ return 1;
+ }
+
+ /*
+ * Read the entire file into memory. XXX - Really, we only need to
+ * read the header and from TRELOFF to the end of the file.
+ */
+
+ if((aoutdata = (char *) malloc(infstat.st_size)) == NULL) {
+ fprintf(stderr, "%s: too big to read into memory\n", filename);
+ return 1;
+ }
+
+ if((rc = read(inf, aoutdata, infstat.st_size)) < infstat.st_size) {
+ fprintf(stderr, "%s: read error: %s\n", filename,
+ rc == -1? strerror(errno) : "short read");
+ return 1;
+ }
+
+ /*
+ * Calculate offsets and sizes from the header.
+ */
+
+ hdrp = (struct exec *) aoutdata;
+
+#ifdef __FreeBSD__
+ textrel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp));
+ datarel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp) +
+ hdrp->a_trsize);
+#else
+ textrel = (struct relocation_info *) (aoutdata + N_TRELOFF(*hdrp));
+ datarel = (struct relocation_info *) (aoutdata + N_DRELOFF(*hdrp));
+#endif
+ symbase = (struct nlist *) (aoutdata + N_SYMOFF(*hdrp));
+ strbase = (char *) (aoutdata + N_STROFF(*hdrp));
+
+ ntextrel = hdrp->a_trsize / sizeof(struct relocation_info);
+ ndatarel = hdrp->a_drsize / sizeof(struct relocation_info);
+ nsyms = hdrp->a_syms / sizeof(struct nlist);
+
+ /*
+ * Zap the type field of all globally-defined symbols. The linker will
+ * subsequently ignore these entries. Don't zap any symbols in the
+ * keep list.
+ */
+
+ for(symp = symbase; symp < symbase + nsyms; symp++) {
+ if(!IS_GLOBAL_DEFINED(symp)) /* keep undefined syms */
+ continue;
+
+ /* keep (C) symbols which are on the keep list */
+ if(SYMSTR(symp)[0] == '_' && in_keep_list(SYMSTR(symp) + 1))
+ continue;
+
+ symp->n_type = 0;
+ }
+
+ /*
+ * Check whether the relocation entries reference any symbols that we
+ * just zapped. I don't know whether ld can handle this case, but I
+ * haven't encountered it yet. These checks are here so that the program
+ * doesn't fail silently should such symbols be encountered.
+ */
+
+ for(relp = textrel; relp < textrel + ntextrel; relp++)
+ check_reloc(filename, relp);
+ for(relp = datarel; relp < datarel + ndatarel; relp++)
+ check_reloc(filename, relp);
+
+ /*
+ * Write the .o file back out to disk. XXX - Really, we only need to
+ * write the symbol table entries back out.
+ */
+ lseek(inf, 0, SEEK_SET);
+ if((rc = write(inf, aoutdata, infstat.st_size)) < infstat.st_size) {
+ fprintf(stderr, "%s: write error: %s\n", filename,
+ rc == -1? strerror(errno) : "short write");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static void check_reloc(const char *filename, struct relocation_info *relp)
+{
+ /* bail out if we zapped a symbol that is needed */
+ if(IS_SYMBOL_RELOC(relp) && symbase[relp->r_symbolnum].n_type == 0) {
+ fprintf(stderr,
+ "%s: oops, have hanging relocation for %s: bailing out!\n",
+ filename, SYMSTR(&symbase[relp->r_symbolnum]));
+ exit(1);
+ }
+}
+
+#endif /* defined(NLIST_AOUT) */
diff --git a/usr.sbin/crunch/crunchide/exec_elf32.c b/usr.sbin/crunch/crunchide/exec_elf32.c
new file mode 100644
index 0000000..45883f4
--- /dev/null
+++ b/usr.sbin/crunch/crunchide/exec_elf32.c
@@ -0,0 +1,389 @@
+/* $NetBSD: exec_elf32.c,v 1.4 1997/08/12 06:07:24 mikel Exp $ */
+
+/*
+ * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: exec_elf32.c,v 1.4 1997/08/12 06:07:24 mikel Exp $");
+#endif
+
+#ifndef ELFSIZE
+#define ELFSIZE 32
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "extern.h"
+
+#if (defined(NLIST_ELF32) && (ELFSIZE == 32)) || \
+ (defined(NLIST_ELF64) && (ELFSIZE == 64))
+
+#include <elf.h>
+
+#define CONCAT(x,y) __CONCAT(x,y)
+#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
+#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y))))
+#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE))
+#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
+
+struct listelem {
+ struct listelem *next;
+ void *mem;
+ off_t file;
+ size_t size;
+};
+
+static ssize_t
+xreadatoff(int fd, void *buf, off_t off, size_t size, const char *fn)
+{
+ ssize_t rv;
+
+ if (lseek(fd, off, SEEK_SET) != off) {
+ perror(fn);
+ return -1;
+ }
+ if ((rv = read(fd, buf, size)) != size) {
+ fprintf(stderr, "%s: read error: %s\n", fn,
+ rv == -1 ? strerror(errno) : "short read");
+ return -1;
+ }
+ return size;
+}
+
+static ssize_t
+xwriteatoff(int fd, void *buf, off_t off, size_t size, const char *fn)
+{
+ ssize_t rv;
+
+ if (lseek(fd, off, SEEK_SET) != off) {
+ perror(fn);
+ return -1;
+ }
+ if ((rv = write(fd, buf, size)) != size) {
+ fprintf(stderr, "%s: write error: %s\n", fn,
+ rv == -1 ? strerror(errno) : "short write");
+ return -1;
+ }
+ return size;
+}
+
+static void *
+xmalloc(size_t size, const char *fn, const char *use)
+{
+ void *rv;
+
+ rv = malloc(size);
+ if (rv == NULL)
+ fprintf(stderr, "%s: out of memory (allocating for %s)\n",
+ fn, use);
+ return (rv);
+}
+
+int
+ELFNAMEEND(check)(int fd, const char *fn)
+{
+ Elf_Ehdr eh;
+ struct stat sb;
+
+ /*
+ * Check the header to maek sure it's an ELF file (of the
+ * appropriate size).
+ */
+ if (fstat(fd, &sb) == -1)
+ return 0;
+ if (sb.st_size < sizeof eh)
+ return 0;
+ if (read(fd, &eh, sizeof eh) != sizeof eh)
+ return 0;
+
+ if (IS_ELF(eh) == 0)
+ return 0;
+
+ switch (eh.e_machine) {
+ case EM_386: break;
+ case EM_ALPHA: break;
+/* ELFDEFNNAME(MACHDEP_ID_CASES) */
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+int
+ELFNAMEEND(hide)(int fd, const char *fn)
+{
+ Elf_Ehdr ehdr;
+ Elf_Shdr *shdrp = NULL, *symtabshdr, *strtabshdr;
+ Elf_Sym *symtabp = NULL;
+ char *strtabp = NULL;
+ Elf_Word *symfwmap = NULL, *symrvmap = NULL, nsyms, nlocalsyms, ewi;
+ struct listelem *relalist = NULL, *rellist = NULL, *tmpl;
+ ssize_t shdrsize;
+ int rv, i, weird;
+
+ rv = 0;
+ if (xreadatoff(fd, &ehdr, 0, sizeof ehdr, fn) != sizeof ehdr)
+ goto bad;
+
+ shdrsize = ehdr.e_shnum * ehdr.e_shentsize;
+ if ((shdrp = xmalloc(shdrsize, fn, "section header table")) == NULL)
+ goto bad;
+ if (xreadatoff(fd, shdrp, ehdr.e_shoff, shdrsize, fn) != shdrsize)
+ goto bad;
+
+ symtabshdr = strtabshdr = NULL;
+ weird = 0;
+ for (i = 0; i < ehdr.e_shnum; i++) {
+ switch (shdrp[i].sh_type) {
+ case SHT_SYMTAB:
+ if (symtabshdr != NULL)
+ weird = 1;
+ symtabshdr = &shdrp[i];
+ strtabshdr = &shdrp[shdrp[i].sh_link];
+ break;
+ case SHT_RELA:
+ tmpl = xmalloc(sizeof *tmpl, fn, "rela list element");
+ if (tmpl == NULL)
+ goto bad;
+ tmpl->mem = NULL;
+ tmpl->file = shdrp[i].sh_offset;
+ tmpl->size = shdrp[i].sh_size;
+ tmpl->next = relalist;
+ relalist = tmpl;
+ break;
+ case SHT_REL:
+ tmpl = xmalloc(sizeof *tmpl, fn, "rel list element");
+ if (tmpl == NULL)
+ goto bad;
+ tmpl->mem = NULL;
+ tmpl->file = shdrp[i].sh_offset;
+ tmpl->size = shdrp[i].sh_size;
+ tmpl->next = rellist;
+ rellist = tmpl;
+ break;
+ }
+ }
+ if (symtabshdr == NULL)
+ goto out;
+ if (strtabshdr == NULL)
+ weird = 1;
+ if (weird) {
+ fprintf(stderr, "%s: weird executable (unsupported)\n", fn);
+ goto bad;
+ }
+
+ /*
+ * load up everything we need
+ */
+
+ /* symbol table */
+ if ((symtabp = xmalloc(symtabshdr->sh_size, fn, "symbol table"))
+ == NULL)
+ goto bad;
+ if (xreadatoff(fd, symtabp, symtabshdr->sh_offset, symtabshdr->sh_size,
+ fn) != symtabshdr->sh_size)
+ goto bad;
+
+ /* string table */
+ if ((strtabp = xmalloc(strtabshdr->sh_size, fn, "string table"))
+ == NULL)
+ goto bad;
+ if (xreadatoff(fd, strtabp, strtabshdr->sh_offset, strtabshdr->sh_size,
+ fn) != strtabshdr->sh_size)
+ goto bad;
+
+ /* any rela tables */
+ for (tmpl = relalist; tmpl != NULL; tmpl = tmpl->next) {
+ if ((tmpl->mem = xmalloc(tmpl->size, fn, "rela table"))
+ == NULL)
+ goto bad;
+ if (xreadatoff(fd, tmpl->mem, tmpl->file, tmpl->size, fn) !=
+ tmpl->size)
+ goto bad;
+ }
+
+ /* any rel tables */
+ for (tmpl = rellist; tmpl != NULL; tmpl = tmpl->next) {
+ if ((tmpl->mem = xmalloc(tmpl->size, fn, "rel table"))
+ == NULL)
+ goto bad;
+ if (xreadatoff(fd, tmpl->mem, tmpl->file, tmpl->size, fn) !=
+ tmpl->size)
+ goto bad;
+ }
+
+ /* Prepare data structures for symbol movement. */
+ nsyms = symtabshdr->sh_size / symtabshdr->sh_entsize;
+ nlocalsyms = symtabshdr->sh_info;
+ if ((symfwmap = xmalloc(nsyms * sizeof (Elf_Word), fn,
+ "symbol forward mapping table")) == NULL)
+ goto bad;
+ if ((symrvmap = xmalloc(nsyms * sizeof (Elf_Word), fn,
+ "symbol reverse mapping table")) == NULL)
+ goto bad;
+
+ /* init location -> symbol # table */
+ for (ewi = 0; ewi < nsyms; ewi++)
+ symrvmap[ewi] = ewi;
+
+ /* move symbols, making them local */
+ for (ewi = nlocalsyms; ewi < nsyms; ewi++) {
+ Elf_Sym *sp, symswap;
+ Elf_Word mapswap;
+
+ sp = &symtabp[ewi];
+
+ /* if it's on our keep list, don't move it */
+ if (in_keep_list(strtabp + sp->st_name))
+ continue;
+
+ /* if it's an undefined symbol, keep it */
+ if (sp->st_shndx == SHN_UNDEF)
+ continue;
+
+ /* adjust the symbol so that it's local */
+ sp->st_info =
+ ELF_ST_INFO(STB_LOCAL, sp->st_info);
+/* (STB_LOCAL << 4) | ELF_SYM_TYPE(sp->st_info); *//* XXX */
+
+ /*
+ * move the symbol to its new location
+ */
+
+ /* note that symbols in those locations have been swapped */
+ mapswap = symrvmap[ewi];
+ symrvmap[ewi] = symrvmap[nlocalsyms];
+ symrvmap[nlocalsyms] = mapswap;
+
+ /* and swap the symbols */
+ symswap = *sp;
+ *sp = symtabp[nlocalsyms];
+ symtabp[nlocalsyms] = symswap;
+
+ nlocalsyms++; /* note new local sym */
+ }
+ symtabshdr->sh_info = nlocalsyms;
+
+ /* set up symbol # -> location mapping table */
+ for (ewi = 0; ewi < nsyms; ewi++)
+ symfwmap[symrvmap[ewi]] = ewi;
+
+ /* any rela tables */
+ for (tmpl = relalist; tmpl != NULL; tmpl = tmpl->next) {
+ Elf_Rela *relap = tmpl->mem;
+
+ for (ewi = 0; ewi < tmpl->size / sizeof(*relap); ewi++) {
+ relap[ewi].r_info =
+#if (ELFSIZE == 32) /* XXX */
+ symfwmap[ELF_R_SYM(relap[ewi].r_info)] << 8 |
+ ELF_R_TYPE(relap[ewi].r_info);
+#elif (ELFSIZE == 64) /* XXX */
+ symfwmap[ELF_R_SYM(relap[ewi].r_info)] << 32 |
+ ELF_R_TYPE(relap[ewi].r_info);
+#endif /* XXX */
+ }
+ }
+
+ /* any rel tables */
+ for (tmpl = rellist; tmpl != NULL; tmpl = tmpl->next) {
+ Elf_Rel *relp = tmpl->mem;
+
+ for (ewi = 0; ewi < tmpl->size / sizeof *relp; ewi++) {
+ relp[ewi].r_info =
+#if (ELFSIZE == 32) /* XXX */
+ symfwmap[ELF_R_SYM(relp[ewi].r_info)] << 8 |
+ ELF_R_TYPE(relp[ewi].r_info);
+#elif (ELFSIZE == 64) /* XXX */
+ symfwmap[ELF_R_SYM(relp[ewi].r_info)] << 32 |
+ ELF_R_TYPE(relp[ewi].r_info);
+#endif /* XXX */
+ }
+ }
+
+ /*
+ * write new tables to the file
+ */
+ if (xwriteatoff(fd, shdrp, ehdr.e_shoff, shdrsize, fn) != shdrsize)
+ goto bad;
+ if (xwriteatoff(fd, symtabp, symtabshdr->sh_offset,
+ symtabshdr->sh_size, fn) != symtabshdr->sh_size)
+ goto bad;
+ for (tmpl = relalist; tmpl != NULL; tmpl = tmpl->next) {
+ if (xwriteatoff(fd, tmpl->mem, tmpl->file, tmpl->size, fn) !=
+ tmpl->size)
+ goto bad;
+ }
+ for (tmpl = rellist; tmpl != NULL; tmpl = tmpl->next) {
+ if (xwriteatoff(fd, tmpl->mem, tmpl->file, tmpl->size, fn) !=
+ tmpl->size)
+ goto bad;
+ }
+
+out:
+ if (shdrp != NULL)
+ free(shdrp);
+ if (symtabp != NULL)
+ free(symtabp);
+ if (strtabp != NULL)
+ free(strtabp);
+ if (symfwmap != NULL)
+ free(symfwmap);
+ if (symrvmap != NULL)
+ free(symrvmap);
+ while ((tmpl = relalist) != NULL) {
+ relalist = tmpl->next;
+ if (tmpl->mem != NULL)
+ free(tmpl->mem);
+ free(tmpl);
+ }
+ while ((tmpl = rellist) != NULL) {
+ rellist = tmpl->next;
+ if (tmpl->mem != NULL)
+ free(tmpl->mem);
+ free(tmpl);
+ }
+ return (rv);
+
+bad:
+ rv = 1;
+ goto out;
+}
+
+#endif /* include this size of ELF */
diff --git a/usr.sbin/crunch/crunchide/exec_elf64.c b/usr.sbin/crunch/crunchide/exec_elf64.c
new file mode 100644
index 0000000..962cc07
--- /dev/null
+++ b/usr.sbin/crunch/crunchide/exec_elf64.c
@@ -0,0 +1,40 @@
+/* $NetBSD: exec_elf64.c,v 1.2 1997/08/02 21:30:19 perry Exp $ */
+
+/*
+ * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__IDSTRING(elf64rcsid, "$NetBSD: exec_elf64.c,v 1.2 1997/08/02 21:30:19 perry Exp $");
+#endif
+
+#define ELFSIZE 64
+
+#include "exec_elf32.c"
diff --git a/usr.sbin/crunch/crunchide/extern.h b/usr.sbin/crunch/crunchide/extern.h
new file mode 100644
index 0000000..a3d6586
--- /dev/null
+++ b/usr.sbin/crunch/crunchide/extern.h
@@ -0,0 +1,68 @@
+/* $NetBSD: extern.h,v 1.5 1998/05/06 13:16:57 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef __alpha__
+#define NLIST_ECOFF
+#define NLIST_ELF64
+#else
+#ifdef __mips__
+#define NLIST_ELF32
+#else
+#ifdef __powerpc__
+#define NLIST_ELF32
+#else
+#define NLIST_AOUT
+/* #define NLIST_ECOFF */
+#define NLIST_ELF32
+/* #define NLIST_ELF64 */
+#endif
+#endif
+#endif
+
+#ifdef NLIST_AOUT
+int check_aout(int, const char *);
+int hide_aout(int, const char *);
+#endif
+#ifdef NLIST_ECOFF
+int check_ecoff(int, const char *);
+int hide_ecoff(int, const char *);
+#endif
+#ifdef NLIST_ELF32
+int check_elf32(int, const char *);
+int hide_elf32(int, const char *);
+#endif
+#ifdef NLIST_ELF64
+int check_elf64(int, const char *);
+int hide_elf64(int, const char *);
+#endif
+
+int in_keep_list(const char *symbol);
OpenPOWER on IntegriCloud