Index: head/usr.sbin/crunch/crunchide/exec_aout.c =================================================================== --- head/usr.sbin/crunch/crunchide/exec_aout.c (revision 281654) +++ head/usr.sbin/crunch/crunchide/exec_aout.c (nonexistent) @@ -1,198 +0,0 @@ -/* $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 -#ifndef lint -__RCSID("$NetBSD: exec_aout.c,v 1.6 1997/08/02 21:30:17 perry Exp $"); -__FBSDID("$FreeBSD$"); -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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) - -/* is the relocation entry dependent on a symbol? */ -#define IS_SYMBOL_RELOC(rp) \ - ((rp)->r_extern||(rp)->r_baserel||(rp)->r_jmptable) - -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) */ Property changes on: head/usr.sbin/crunch/crunchide/exec_aout.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/usr.sbin/crunch/crunchide/Makefile =================================================================== --- head/usr.sbin/crunch/crunchide/Makefile (revision 281654) +++ head/usr.sbin/crunch/crunchide/Makefile (revision 281655) @@ -1,24 +1,19 @@ # $FreeBSD$ PROG= crunchide SRCS= crunchide.c TARGET_ARCH?= ${MACHINE_ARCH} -.if ${TARGET_ARCH} == i386 && ${MACHINE_ARCH} == i386 -CFLAGS+=-DNLIST_AOUT -SRCS+= exec_aout.c -.endif - .if ${TARGET_ARCH} == aarch64 || ${TARGET_ARCH} == amd64 || \ ${TARGET_ARCH} == powerpc64 || \ ${TARGET_ARCH} == sparc64 || ${TARGET_ARCH:Mmips64*} CFLAGS+=-DNLIST_ELF64 SRCS+= exec_elf64.c exec_elf64.o: exec_elf32.c .else CFLAGS+=-DNLIST_ELF32 SRCS+= exec_elf32.c .endif .include Index: head/usr.sbin/crunch/crunchide/crunchide.c =================================================================== --- head/usr.sbin/crunch/crunchide/crunchide.c (revision 281654) +++ head/usr.sbin/crunch/crunchide/crunchide.c (revision 281655) @@ -1,273 +1,267 @@ /* $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. * * 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 */ /* * crunchide.c - tiptoes through an a.out symbol table, hiding all defined * global symbols. Allows the user to supply a "keep list" of symbols * that are not to be hidden. This program relies on the use of the * linker's -dc flag to actually put global bss data into the file's * bss segment (rather than leaving it as undefined "common" data). * * The point of all this is to allow multiple programs to be linked * together without getting multiple-defined errors. * * For example, consider a program "foo.c". It can be linked with a * small stub routine, called "foostub.c", eg: * int foo_main(int argc, char **argv){ return main(argc, argv); } * like so: * cc -c foo.c foostub.c * ld -dc -r foo.o foostub.o -o foo.combined.o * crunchide -k _foo_main foo.combined.o * at this point, foo.combined.o can be linked with another program * and invoked with "foo_main(argc, argv)". foo's main() and any * other globals are hidden and will not conflict with other symbols. * * TODO: * - resolve the theoretical hanging reloc problem (see check_reloc() * below). I have yet to see this problem actually occur in any real * program. In what cases will gcc/gas generate code that needs a * relative reloc from a global symbol, other than PIC? The * solution is to not hide the symbol from the linker in this case, * but to generate some random name for it so that it doesn't link * with anything but holds the place for the reloc. * - arrange that all the BSS segments start at the same address, so * that the final crunched binary BSS size is the max of all the * component programs' BSS sizes, rather than their sum. */ #include #ifndef lint __RCSID("$NetBSD: crunchide.c,v 1.8 1997/11/01 06:51:45 lukem Exp $"); #endif __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include "extern.h" char *pname = "crunchide"; void usage(void); void add_to_keep_list(char *symbol); void add_file_to_keep_list(char *filename); int hide_syms(const char *filename); int verbose; int main(int, char *[]); int main(int argc, char **argv) { int ch, errors; if(argc > 0) pname = argv[0]; while ((ch = getopt(argc, argv, "k:f:v")) != -1) switch(ch) { case 'k': add_to_keep_list(optarg); break; case 'f': add_file_to_keep_list(optarg); break; case 'v': verbose = 1; break; default: usage(); } argc -= optind; argv += optind; if(argc == 0) usage(); errors = 0; while(argc) { if (hide_syms(*argv)) errors = 1; argc--, argv++; } return errors; } void usage(void) { fprintf(stderr, "usage: %s [-k ] [-f ] ...\n", pname); exit(1); } /* ---------------------------- */ struct keep { struct keep *next; char *sym; } *keep_list; 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; if(curp && cmp == 0) return; /* already in table */ newp = (struct keep *) malloc(sizeof(struct keep)); if(newp) newp->sym = strdup(symbol); if(newp == NULL || newp->sym == NULL) { fprintf(stderr, "%s: out of memory for keep list\n", pname); exit(1); } newp->next = curp; if(prevp) prevp->next = newp; else keep_list = newp; } 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; return curp && cmp == 0; } void add_file_to_keep_list(char *filename) { FILE *keepf; char symbol[1024]; int len; if((keepf = fopen(filename, "r")) == NULL) { perror(filename); usage(); } while(fgets(symbol, sizeof(symbol), keepf)) { len = strlen(symbol); if(len && symbol[len-1] == '\n') symbol[len-1] = '\0'; add_to_keep_list(symbol); } fclose(keepf); } /* ---------------------------- */ 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_elf64, hide_elf64, }, -#endif #ifdef NLIST_ELF32 { "ELF32", check_elf32, hide_elf32, }, #endif #ifdef NLIST_ELF64 { "ELF64", check_elf64, hide_elf64, }, #endif }; int hide_syms(const char *filename) { int fd, i, n, rv; fd = open(filename, O_RDWR, 0); if (fd == -1) { perror(filename); return 1; } rv = 0; 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; } if (verbose) fprintf(stderr, "%s is an %s binary\n", filename, exec_formats[i].name); if (lseek(fd, 0, SEEK_SET) != 0) { perror(filename); goto err; } rv = (*exec_formats[i].hide)(fd, filename); out: close (fd); return (rv); err: rv = 1; goto out; } Index: head/usr.sbin/crunch/crunchide/extern.h =================================================================== --- head/usr.sbin/crunch/crunchide/extern.h (revision 281654) +++ head/usr.sbin/crunch/crunchide/extern.h (revision 281655) @@ -1,51 +1,43 @@ /* $NetBSD: extern.h,v 1.5 1998/05/06 13:16:57 mycroft Exp $ */ /* $FreeBSD$ */ /* * 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 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);