From: François Tigeot Date: Sun, 30 Mar 2014 19:46:42 +0000 (+0200) Subject: Revert "Remove crunchgen(8)." X-Git-Tag: v3.9.0~241 X-Git-Url: https://gitweb.dragonflybsd.org/~tuxillo/dragonfly.git/commitdiff_plain/fc7e83fa167ace550636f25b513c873f2f3135ff Revert "Remove crunchgen(8)." This reverts commit 97c14704c37c914dbd89b22465a421ffde7fe89d. Conflicts: Makefile.inc1 Makefile_upgrade.inc sbin/ifconfig/Makefile usr.bin/vi/Makefile usr.sbin/ppp/bundle.c usr.sbin/pppd/Makefile usr.sbin/tcpdump/Makefile --- diff --git a/Makefile.inc1 b/Makefile.inc1 index 8ab74702a8..0b994bc477 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -877,7 +877,9 @@ btools-${_tool}! _btxld= usr.sbin/btxld .endif -CTOOLSDIRS= ${_btxld} ${_binutils} usr.bin/objformat ${_gcc_common_cross} \ +CTOOLSDIRS= ${_btxld} ${_binutils} \ + usr.bin/objformat usr.bin/crunch/crunchide \ + ${_gcc_common_cross} \ ${_gcc44_cross} ${_gcc47_cross} ${_custom_cross} cross-tools: cross-tools-targets diff --git a/Makefile_upgrade.inc b/Makefile_upgrade.inc index 76230b4ca0..49ccff3691 100644 --- a/Makefile_upgrade.inc +++ b/Makefile_upgrade.inc @@ -1099,12 +1099,6 @@ TO_REMOVE+=/usr/share/info/cpio.info.gz TO_REMOVE+=/usr/sbin/tcpslice TO_REMOVE+=/usr/share/man/cat1/tcpslice.1.gz TO_REMOVE+=/usr/share/man/man1/tcpslice.1.gz -TO_REMOVE+=/usr/bin/crunchgen -TO_REMOVE+=/usr/share/man/cat1/crunchgen.1.gz -TO_REMOVE+=/usr/share/man/man1/crunchgen.1.gz -TO_REMOVE+=/usr/bin/crunchide -TO_REMOVE+=/usr/share/man/cat1/crunchide.1.gz -TO_REMOVE+=/usr/share/man/man1/crunchide.1.gz TO_REMOVE+=/usr/share/man/cat9/suser.9.gz TO_REMOVE+=/usr/share/man/man9/suser.9.gz TO_REMOVE+=/usr/share/man/cat9/suser_cred.9.gz diff --git a/sbin/camcontrol/Makefile b/sbin/camcontrol/Makefile index 4308a4df82..8425e0c2f0 100644 --- a/sbin/camcontrol/Makefile +++ b/sbin/camcontrol/Makefile @@ -2,10 +2,14 @@ # $DragonFly: src/sbin/camcontrol/Makefile,v 1.7 2008/03/07 08:44:24 pavalos Exp $ PROG= camcontrol -SRCS= camcontrol.c modeedit.c util.c -MAN= camcontrol.8 - +SRCS= camcontrol.c util.c +.if !defined(RELEASE_CRUNCH) +SRCS+= modeedit.c +.else +CFLAGS+= -DMINIMALISTIC +.endif DPADD= ${LIBCAM} ${LIBSBUF} ${LIBUTIL} LDADD= -lcam -lsbuf -lutil +MAN= camcontrol.8 .include diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile index 85517ab4df..fe215e4706 100644 --- a/sbin/ifconfig/Makefile +++ b/sbin/ifconfig/Makefile @@ -28,10 +28,14 @@ SRCS+= ifcarp.c # SIOC[GS]VH support SRCS+= ifbridge.c # bridge support +.ifndef RELEASE_CRUNCH SRCS+= af_ipx.c # IPX support DPADD= ${LIBIPX} ${LIBBSDXML} ${LIBSBUF} LDADD= -lipx -lbsdxml -lsbuf +.else +CFLAGS+= -DNO_IPX +.endif MAN= ifconfig.8 diff --git a/sbin/ping/Makefile b/sbin/ping/Makefile index 7a89ecaf78..c21eba729f 100644 --- a/sbin/ping/Makefile +++ b/sbin/ping/Makefile @@ -5,9 +5,13 @@ PROG= ping MAN= ping.8 BINMODE=4555 -DPADD= ${LIBM} ${LIBIPSEC} -LDADD= -lm -lipsec +DPADD= ${LIBM} +LDADD= -lm +.if !defined(RELEASE_CRUNCH) CFLAGS+=-DIPSEC +DPADD+= ${LIBIPSEC} +LDADD+= -lipsec +.endif .include diff --git a/usr.bin/Makefile b/usr.bin/Makefile index d1a73c2d0d..e8eecb281b 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -47,6 +47,7 @@ SUBDIR= alias \ compile_et \ compress \ cpio \ + crunch \ csplit \ ctags \ cut \ diff --git a/usr.bin/crunch/COPYRIGHT b/usr.bin/crunch/COPYRIGHT new file mode 100644 index 0000000000..c7b4d2f9ae --- /dev/null +++ b/usr.bin/crunch/COPYRIGHT @@ -0,0 +1,25 @@ +/* + * 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 + */ diff --git a/usr.bin/crunch/Makefile b/usr.bin/crunch/Makefile new file mode 100644 index 0000000000..a38e0b9061 --- /dev/null +++ b/usr.bin/crunch/Makefile @@ -0,0 +1,4 @@ + +SUBDIR=crunchgen crunchide + +.include diff --git a/usr.bin/crunch/Makefile.inc b/usr.bin/crunch/Makefile.inc new file mode 100644 index 0000000000..ad6e982e6d --- /dev/null +++ b/usr.bin/crunch/Makefile.inc @@ -0,0 +1,3 @@ +WARNS?= 1 + +.include "../Makefile.inc" diff --git a/usr.bin/crunch/README b/usr.bin/crunch/README new file mode 100644 index 0000000000..27c2d0298a --- /dev/null +++ b/usr.bin/crunch/README @@ -0,0 +1,88 @@ + +CRUNCH 0.2 README 6/14/94 + +Crunch is available via anonymous ftp to ftp.cs.umd.edu in + pub/bsd/crunch-0.2.tar.gz + + +WHAT'S NEW IN 0.2 + +* The prototype awk script has been replaced by a more capable and + hopefully more robust C program. +* No fragile template makefiles or dependencies on the details of the + bsd build environment. +* You can build crunched binaries even with no sources on-line, you + just need the .o files. Crunchgen still will try to figure out as + much as possible on its own, but you can override its guessing by + specifying the list of .o files explicitly. +* Crunch itself has been bmake'd and some man pages written, so it + should be ready to install. + + +INTRODUCTION + +Crunch is a little package that helps create "crunched" binaries for use +on boot, install, and fixit floppies. A crunched binary in this case is +one where many programs have been linked together into one a.out file. +The different programs are run depending on the value of argv[0], so +hard links to the crunched binary suffice to simulate a perfectly normal +system. + +As an example, I have created an 980K crunched "fixit" binary containing +the following programs in their entirety: + + cat chmod cp date dd df echo ed expr hostname kill ln ls mkdir + mt mv pwd rcp rm rmdir sh sleep stty sync test [ badsect chown + clri disklabel dump rdump dmesg fdisk fsck halt ifconfig init + mknod mount newfs ping reboot restore rrestore swapon umount + ftp rsh sed telnet rlogin vi cpio gzip gunzip gzcat + +Note carefully: vi, cpio, gzip, ed, sed, dump/restore, some networking +utilities, and the disk management utilities, all in a binary small +enough to fit on a 1.2 MB root filesystem floppy (albeit with the kernel +on its own boot floppy). A more reasonable subset can be made to fit +easily with a kernel for a decent one-disk fixit filesystem. + +The linking together of different programs by hand is an old +space-saving technique. Crunch automates the process by building the +necessary stub files and makefile for you (via the crunchgen program), +and by doctoring the symbol tables of the component .o files to allow +them to link without "symbol multiply defined" conflicts (via the +crunchide program). + + +BUILDING CRUNCH + +Just type make, then make install. + +Crunch was written and tested under NetBSD/i386, but should work under +other PC BSD systems that use GNU ld. + +The crunchgen(1) and crunchide(1) man pages have more details on using +crunch, and the examples subdirectory contains some working .conf files +and a sample Makefile. + +CREDITS + +Thanks to the NetBSD team for a consistently high quality effort in +bringing together a solid, state of the art development environment. + +Thanks to the FreeBSD guys; Rod Grimes, Nate Williams and Jordan +Hubbard; and to Bruce Evans, for immediate and detailed feedback on +crunch 0.1, and for pressing me to make the prototype more useable. + +Crunch was written for the Maruti Hard Real-Time Operating System +project at the University of Maryland, to help make for better install +and recovery procedures for our NetBSD-based development environment. It +is copyright (c) 1994 by the University of Maryland under a UCB-style +freely- redistributable notice. See the file COPYRIGHT for details. + +Please let me know of any problems or of enhancements you make to this +package. I'm particularly interested in the details of what you found +was good to put on your fixit or install disks. Thanks! + +Share and Enjoy, +Jaime +............................................................................ +: Stand on my shoulders, : jds@cs.umd.edu : James da Silva +: not on my toes. : uunet!mimsy!jds : http://www.cs.umd.edu/users/jds diff --git a/usr.bin/crunch/crunchgen/Makefile b/usr.bin/crunch/crunchgen/Makefile new file mode 100644 index 0000000000..ecf99d9820 --- /dev/null +++ b/usr.bin/crunch/crunchgen/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD: src/usr.sbin/crunch/crunchgen/Makefile,v 1.4.8.1 2002/04/11 19:41:39 murray Exp $ +# $DragonFly: src/usr.sbin/crunch/crunchgen/Makefile,v 1.2 2003/06/17 04:29:53 dillon Exp $ + +PROG= crunchgen +SRCS= crunchgen.c crunched_skel.c +CLEANFILES+= crunched_skel.c + +crunched_skel.c: crunched_main.c + sh -e ${.CURDIR}/mkskel.sh ${.CURDIR}/crunched_main.c >crunched_skel.c + +.include diff --git a/usr.bin/crunch/crunchgen/crunched_main.c b/usr.bin/crunch/crunchgen/crunched_main.c new file mode 100644 index 0000000000..c3bfe07509 --- /dev/null +++ b/usr.bin/crunch/crunchgen/crunched_main.c @@ -0,0 +1,123 @@ +/* + * 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 + * + * $FreeBSD: src/usr.sbin/crunch/crunchgen/crunched_main.c,v 1.6.6.2 2002/08/09 02:42:02 gshapiro Exp $ + * $DragonFly: src/usr.sbin/crunch/crunchgen/crunched_main.c,v 1.3 2003/11/16 14:10:44 eirikn Exp $ + */ +/* + * crunched_main.c - main program for crunched binaries, it branches to a + * particular subprogram based on the value of argv[0]. Also included + * is a little program invoked when the crunched binary is called via + * its EXECNAME. This one prints out the list of compiled-in binaries, + * or calls one of them based on argv[1]. This allows the testing of + * the crunched binary without creating all the links. + */ +#include +#include + +struct stub { + char *name; + int (*f)(); +}; + +extern struct stub entry_points[]; + +int +main(int argc, char **argv, char **envp) +{ + char *slash, *basename; + struct stub *ep; + + if(argv[0] == NULL || *argv[0] == '\0') + crunched_usage(); + + slash = strrchr(argv[0], '/'); + basename = slash? slash+1 : argv[0]; + + for(ep=entry_points; ep->name != NULL; ep++) + if(!strcmp(basename, ep->name)) break; + + if(ep->name) + return ep->f(argc, argv, envp); + else { + fprintf(stderr, "%s: %s not compiled in\n", EXECNAME, basename); + crunched_usage(); + } +} + + +int +crunched_here(char *path) +{ + char *slash, *basename; + struct stub *ep; + + slash = strrchr(path, '/'); + basename = slash? slash+1 : path; + + for(ep=entry_points; ep->name != NULL; ep++) + if(!strcmp(basename, ep->name)) + return 1; + return 0; +} + + +int +crunched_main(int argc, char **argv, char **envp) +{ + struct stub *ep; + int columns, len; + + if(argc <= 1) + crunched_usage(); + + return main(--argc, ++argv, envp); +} + + +int +crunched_usage(void) +{ + int columns, len; + struct stub *ep; + + fprintf(stderr, "usage: %s ..., where is one of:\n", + EXECNAME); + columns = 0; + for(ep=entry_points; ep->name != NULL; ep++) { + len = strlen(ep->name) + 1; + if(columns+len < 80) + columns += len; + else { + fprintf(stderr, "\n"); + columns = len; + } + fprintf(stderr, " %s", ep->name); + } + fprintf(stderr, "\n"); + exit(1); +} + +/* end of crunched_main.c */ diff --git a/usr.bin/crunch/crunchgen/crunchgen.1 b/usr.bin/crunch/crunchgen/crunchgen.1 new file mode 100644 index 0000000000..de57b15759 --- /dev/null +++ b/usr.bin/crunch/crunchgen/crunchgen.1 @@ -0,0 +1,447 @@ +.\" +.\" 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 +.\" $FreeBSD: src/usr.sbin/crunch/crunchgen/crunchgen.1,v 1.11.2.11 2003/03/12 22:08:13 trhodes Exp $ +.\" $DragonFly: src/usr.sbin/crunch/crunchgen/crunchgen.1,v 1.3 2008/05/02 02:05:07 swildner Exp $ +.\" +.Dd November 16, 2000 +.Dt CRUNCHGEN 1 +.Os +.Sh NAME +.Nm crunchgen +.Nd generates build environment for a crunched binary +.Sh SYNOPSIS +.Bk -words +.Nm +.Op Fl foql +.Op Fl h Ar makefile-header-name +.Op Fl m Ar makefile-name +.Op Fl p Ar obj-prefix +.Op Fl c Ar c-file-name +.Op Fl e Ar exec-file-name +.Op Ar conf-file +.Ek +.Sh DESCRIPTION +A crunched binary is a program made up of many other programs linked +together into a single executable. +The crunched binary +.Fn main +function determines which component program to run by the contents of +.Va argv[0] . +The main reason to crunch programs together is for fitting +as many programs as possible onto an installation or system recovery +floppy. +.Pp +The +.Nm +utility reads in the specifications in +.Ar conf-file +for a crunched binary, and generates a +.Pa Makefile +and accompanying +top-level C source file that when built creates the crunched executable +file from the component programs. +For each component program, +.Nm +can optionally attempt to determine the object (.o) files that make up +the program from its source directory +.Pa Makefile . +This information is cached between runs. +The +.Nm +utility uses the companion program +.Xr crunchide 1 +to eliminate link-time conflicts between the component programs by +hiding all unnecessary symbols. +.Pp +The +.Nm +utility places specific requirements on package +.Pa Makefile Ns s +which make it unsuitable for use with +.No non- Ns Bx +sources. +In particular, the +.Pa Makefile +must contain the target +.Ic depend , +and it must define all object files in the variable +.Va OBJS . +In some cases, you can use a fake +.Pa Makefile : +before looking for +.Pa Makefile +in the source directory +.Pa foo , +.Nm +looks for the file +.Pa Makefile.foo +in the current directory. +.Pp +After +.Nm +is run, the crunched binary can be built by running +.Dq Li make -f .mk . +The component programs' object files must already be built. +An +.Ic objs +target, included in the output makefile, will +run +.Xr make 1 +in each component program's source dir to build the object +files for the user. +This is not done automatically since in release +engineering circumstances it is generally not desirable to be +modifying objects in other directories. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl c Ar c-file-name +Set output C file name to +.Ar c-file-name . +The default name is +.Pa .c . +.It Fl e Ar exec-file-name +Set crunched binary executable file name to +.Ar exec-file-name . +The default name is +.Pa . +.It Fl f +Flush cache. +Forces the recalculation of cached parameters. +.It Fl l +List names. +Lists the names this binary will respond to. +.It Fl h Ar makefile-header-name +Set the name of a file to be included at the beginning of the +.Pa Makefile Ns s +generated by +.Nm . +This is useful to define some make variables such as +.Va RELEASE_CRUNCH +or similar, which might affect the behaviour of +.Xr make 1 +and are annoying to pass through environment variables. +.It Fl m Ar makefile-name +Set output +.Pa Makefile +name to +.Ar makefile-name . +The default name is +.Pa .mk . +.It Fl o +Add +.Dq Li make obj +rules to each program make target. +.It Fl p Ar obj-prefix +Set the pathname to be prepended to the +.Ic srcdir +when computing the +.Ic objdir . +If this option is not present, then the prefix used +is the content of the +.Ev MAKEOBJDIRPREFIX +environment variable, or +.Pa /usr/obj . +.It Fl q +Quiet operation. +Status messages are suppressed. +.El +.Sh CRUNCHGEN CONFIGURATION FILE COMMANDS +The +.Nm +utility reads specifications from the +.Ar conf-file +that describe the components of the crunched binary. +In its simplest +use, the component program names are merely listed along with the +top-level source directories in which their sources can be found. +The +.Nm +utility then calculates (via the source makefiles) and caches the +list of object files and their locations. +For more specialized +situations, the user can specify by hand all the parameters that +.Nm +needs. +.Pp +The +.Ar conf-file +commands are as follows: +.Bl -tag -width indent +.It Ic srcdirs Ar dirname ... +A list of source trees in which the source directories of the +component programs can be found. +These dirs are searched using the +.Bx +.Dq Pa // +convention. +Multiple +.Ic srcdirs +lines can be specified. +The directories are searched in the order they are given. +.It Ic progs Ar progname ... +A list of programs that make up the crunched binary. +Multiple +.Ic progs +lines can be specified. +.It Ic libs Ar libspec ... +A list of library specifications to be included in the crunched binary link. +Multiple +.Ic libs +lines can be specified. +.It Ic buildopts Ar buildopts ... +A list of build options to be added to every make target. +.It Ic ln Ar progname linkname +Causes the crunched binary to invoke +.Ar progname +whenever +.Ar linkname +appears in +.Va argv[0] . +This allows programs that change their behavior when +run under different names to operate correctly. +.El +.Pp +To handle specialized situations, such as when the source is not +available or not built via a conventional +.Pa Makefile , +the following +.Ic special +commands can be used to set +.Nm +parameters for a component program. +.Bl -tag -width indent +.It Ic special Ar progname Ic srcdir Ar pathname +Set the source directory for +.Ar progname . +This is normally calculated by searching the specified +.Ic srcdirs +for a directory named +.Ar progname . +.It Ic special Ar progname Ic objdir Ar pathname +Set the +.Pa obj +directory for +.Ar progname . +The +.Pa obj +directory is normally calculated by looking for a directory +whose name is that of the source directory prepended by +one of the following components, in order of priority: +the +.Fl p +argument passed to the command line; or, +the value of the +.Ev MAKEOBJDIRPREFIX +environment variable, or +.Pa /usr/obj . +If the directory is not found, the +.Ic srcdir +itself becomes the +.Ic objdir . +.It Ic special Ar progname Ic buildopts Ar buildopts +Define a set of build options that should be added to +.Xr make 1 +targets in addition to those specified using +.Ic buildopts +when processing +.Ar progname . +.It Ic special Ar progname Ic objs Ar object-file-name ... +Set the list of object files for program +.Ar progname . +This is normally calculated by constructing a temporary makefile that includes +.Dq Ic srcdir Ns / Ns Pa Makefile +and outputs the value of +.Va $(OBJS) . +.It Ic special Ar progname Ic objpaths Ar full-pathname-to-object-file ... +Sets the pathnames of the object files for program +.Ar progname . +This is normally calculated by prepending the +.Ic objdir +pathname to each file in the +.Ic objs +list. +.It Ic special Ar progname Ic objvar Ar variable_name +Sets the name of the +.Xr make 1 +variable which holds the list of +object files for program +.Ar progname . +This is normally +.Va OBJS +but some +.Pa Makefile Ns s +might like to use other conventions or +prepend the program's name to the variable, e.g.\& +.Va SSHD_OBJS . +.It Ic special Ar progname Ic lib Ar library-name ... +Specifies libraries to be linked with object files to produce +.Ar progname Ns Pa .lo . +This can be useful with libraries which redefine routines in +the standard libraries, or poorly written libraries which +reference symbols in the object files. +.It Ic special Ar progname Ic keep Ar symbol-name ... +Add specified list of symbols to the keep list for program +.Ar progname . +An underscore +.Pq Ql _ +is prepended to each symbol and it becomes the argument to a +.Fl k +option for the +.Xr crunchide 1 +phase. +This option is to be used as a last resort as its use can cause a +symbol conflict, however in certain instances it may be the only way to +have a symbol resolve. +.It Ic special Ar progname Ic ident Ar identifier +Set the +.Pa Makefile Ns / Ns Tn C +identifier for +.Ar progname . +This is normally generated from a +.Ar progname , +mapping +.Ql - +to +.Ql _ +and ignoring all other non-identifier characters. +This leads to programs named +.Qq Li foo.bar +and +.Qq Li foobar +to map to the same identifier. +.El +.Pp +Only the +.Ic objpaths +parameter is actually needed by +.Nm , +but it is calculated from +.Ic objdir +and +.Ic objs , +which are in turn calculated from +.Ic srcdir , +so is sometimes convenient to specify the earlier parameters and let +.Nm +calculate forward from there if it can. +.Pp +The makefile produced by +.Nm +contains an optional +.Ic objs +target that will build the object files for each component program by +running +.Xr make 1 +inside that program's source directory. +For this to work the +.Ic srcdir +and +.Ic objs +parameters must also be valid. +If they are not valid for a particular program, that +program is skipped in the +.Ic objs +target. +.Sh EXAMPLES +Here is an example +.Nm +input conf file, named +.Dq Pa kcopy.conf : +.Bd -literal -offset indent +srcdirs /usr/src/bin /usr/src/sbin + +progs test cp echo sh fsck halt init mount umount myinstall +progs anotherprog +ln test [ # test can be invoked via [ +ln sh -sh # init invokes the shell with "-sh" in argv[0] + +special myprog objpaths /homes/leroy/src/myinstall.o # no sources + +special anotherprog -DNO_FOO WITHOUT_BAR=YES + +libs -lutil -lcrypt +.Ed +.Pp +This conf file specifies a small crunched binary consisting of some +basic system utilities plus a homegrown install program +.Dq Pa myinstall , +for which no source directory is specified, but its object file is +specified directly with the +.Ic special +line. +.Pp +Additionally when +.Dq Pa anotherprog +is built the arguments +.Pp +.Dl -DNO_FOO WITHOUT_BAR=YES +.Pp +are added to all build targets. +.Pp +The crunched binary +.Dq Pa kcopy +can be built as follows: +.Bd -literal -offset indent +% crunchgen -m Makefile kcopy.conf # gen Makefile and kcopy.c +% make objs # build the component programs' .o files +% make # build the crunched binary kcopy +% kcopy sh # test that this invokes a sh shell +$ # it works! +.Ed +.Pp +At this point the binary +.Dq Pa kcopy +can be copied onto an install floppy +and hard-linked to the names of the component programs. +.Sh SEE ALSO +.Xr crunchide 1 , +.Xr make 1 +.Sh CAVEATS +While +.Nm +takes care to eliminate link conflicts between the component programs +of a crunched binary, conflicts are still possible between the +libraries that are linked in. +Some shuffling in the order of +libraries may be required, and in some rare cases two libraries may +have an unresolvable conflict and thus cannot be crunched together. +.Pp +Some versions of the +.Bx +build environment do not by default build the +intermediate object file for single-source file programs. +The +.Dq Li make objs +must then be used to get those object files built, or +some other arrangements made. +.Sh AUTHORS +The +.Nm +utility was written by +.An James da Silva Aq jds@cs.umd.edu . +.Pp +Copyright (c) 1994 University of Maryland. +All Rights Reserved. diff --git a/usr.bin/crunch/crunchgen/crunchgen.c b/usr.bin/crunch/crunchgen/crunchgen.c new file mode 100644 index 0000000000..3e20625a8e --- /dev/null +++ b/usr.bin/crunch/crunchgen/crunchgen.c @@ -0,0 +1,1157 @@ +/* + * 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 + * + * $FreeBSD: src/usr.sbin/crunch/crunchgen/crunchgen.c,v 1.12.2.10 2002/04/14 20:55:21 luigi Exp $ + * $DragonFly: src/usr.sbin/crunch/crunchgen/crunchgen.c,v 1.4 2005/10/30 23:00:57 swildner Exp $ + */ +/* + * ======================================================================== + * crunchgen.c + * + * Generates a Makefile and main C file for a crunched executable, + * from specs given in a .conf file. + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define CRUNCH_VERSION "0.2" + +#define MAXLINELEN 16384 +#define MAXFIELDS 2048 + + +/* internal representation of conf file: */ + +/* simple lists of strings suffice for most parms */ + +typedef struct strlst { + struct strlst *next; + char *str; +} strlst_t; + +/* progs have structure, each field can be set with "special" or calculated */ + +typedef struct prog { + struct prog *next; /* link field */ + char *name; /* program name */ + char *ident; /* C identifier for the program name */ + char *srcdir; + char *realsrcdir; + char *objdir; + char *objvar; /* Makefile variable to replace OBJS */ + strlst_t *objs, *objpaths; + strlst_t *buildopts; + strlst_t *keeplist; + strlst_t *links; + strlst_t *libs; + int goterror; +} prog_t; + + +/* global state */ + +strlst_t *buildopts = NULL; +strlst_t *srcdirs = NULL; +strlst_t *libs = NULL; +prog_t *progs = NULL; + +char confname[MAXPATHLEN], infilename[MAXPATHLEN]; +char outmkname[MAXPATHLEN], outcfname[MAXPATHLEN], execfname[MAXPATHLEN]; +char tempfname[MAXPATHLEN], cachename[MAXPATHLEN], curfilename[MAXPATHLEN]; +char outhdrname[MAXPATHLEN] ; /* user-supplied header for *.mk */ +char *objprefix; /* where are the objects ? */ +int linenum = -1; +int goterror = 0; + +int verbose, readcache; /* options */ +int reading_cache; +int makeobj = 0; /* add 'make obj' rules to the makefile */ + +int list_mode; + +/* general library routines */ + +void status(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); + +/* helper routines for main() */ + +void usage(void); +void parse_conf_file(void); +void gen_outputs(void); + + +int +main(int argc, char **argv) +{ + char *p; + int optc; + + verbose = 1; + readcache = 1; + *outmkname = *outcfname = *execfname = '\0'; + + p = getenv("MAKEOBJDIRPREFIX"); + if (p == NULL || *p == '\0') + objprefix = "/usr/obj"; /* default */ + else + if ((objprefix = strdup(p)) == NULL) + out_of_memory(); + + while((optc = getopt(argc, argv, "lh:m:c:e:p:foq")) != -1) { + switch(optc) { + case 'f': + readcache = 0; + break; + case 'o': + makeobj = 1; + break; + case 'q': + verbose = 0; + break; + + case 'm': + strlcpy(outmkname, optarg, sizeof(outmkname)); + break; + case 'p': + if ((objprefix = strdup(optarg)) == NULL) + out_of_memory(); + break; + + case 'h': + strlcpy(outhdrname, optarg, sizeof(outhdrname)); + break; + case 'c': + strlcpy(outcfname, optarg, sizeof(outcfname)); + break; + case 'e': + strlcpy(execfname, optarg, sizeof(execfname)); + break; + + case 'l': + list_mode++; + verbose = 0; + break; + + case '?': + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + /* + * generate filenames + */ + + strlcpy(infilename, argv[0], sizeof(infilename)); + + /* confname = `basename infilename .conf` */ + + if ((p=strrchr(infilename, '/')) != NULL) + strlcpy(confname, p + 1, sizeof(confname)); + else + strlcpy(confname, infilename, sizeof(confname)); + + if ((p=strrchr(confname, '.')) != NULL && !strcmp(p, ".conf")) + *p = '\0'; + + if (!*outmkname) + snprintf(outmkname, sizeof(outmkname), "%s.mk", confname); + if (!*outcfname) + snprintf(outcfname, sizeof(outcfname), "%s.c", confname); + if (!*execfname) + snprintf(execfname, sizeof(execfname), "%s", confname); + + snprintf(cachename, sizeof(cachename), "%s.cache", confname); + snprintf(tempfname, sizeof(tempfname), "%s/crunchgen_%sXXXXXX", + getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP, confname); + + parse_conf_file(); + if (list_mode) + exit(goterror); + + gen_outputs(); + + exit(goterror); +} + + +void +usage(void) +{ + fprintf(stderr, "%s%s\n\t%s%s\n", "usage: crunchgen [-foq] ", + "[-h ] [-m ]", + "[-p ] [-c ] [-e ] ", + ""); + exit(1); +} + + +/* + * ======================================================================== + * parse_conf_file subsystem + * + */ + +/* helper routines for parse_conf_file */ + +void parse_one_file(char *filename); +void parse_line(char *line, 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); +void add_libs(int argc, char **argv); +void add_buildopts(int argc, char **argv); +void add_special(int argc, char **argv); + +prog_t *find_prog(char *str); +void add_prog(char *progname); + + +void +parse_conf_file(void) +{ + if (!is_nonempty_file(infilename)) + errx(1, "fatal: input file \"%s\" not found", infilename); + + parse_one_file(infilename); + if (readcache && is_nonempty_file(cachename)) { + reading_cache = 1; + parse_one_file(cachename); + } +} + + +void +parse_one_file(char *filename) +{ + char *fieldv[MAXFIELDS]; + int fieldc; + void (*f)(int c, char **v); + FILE *cf; + char line[MAXLINELEN]; + + snprintf(line, sizeof(line), "reading %s", filename); + status(line); + strlcpy(curfilename, filename, sizeof(curfilename)); + + if ((cf = fopen(curfilename, "r")) == NULL) { + warn("%s", curfilename); + goterror = 1; + return; + } + + linenum = 0; + while (fgets(line, MAXLINELEN, cf) != NULL) { + linenum++; + parse_line(line, &fieldc, fieldv, MAXFIELDS); + + if (fieldc < 1) + continue; + + if (!strcmp(fieldv[0], "srcdirs")) + f = add_srcdirs; + else if(!strcmp(fieldv[0], "progs")) + f = add_progs; + else if(!strcmp(fieldv[0], "ln")) + f = add_link; + else if(!strcmp(fieldv[0], "libs")) + f = add_libs; + else if(!strcmp(fieldv[0], "buildopts")) + f = add_buildopts; + else if(!strcmp(fieldv[0], "special")) + f = add_special; + else { + warnx("%s:%d: skipping unknown command `%s'", + curfilename, linenum, fieldv[0]); + goterror = 1; + continue; + } + + if (fieldc < 2) { + warnx("%s:%d: %s %s", + curfilename, linenum, fieldv[0], + "command needs at least 1 argument, skipping"); + goterror = 1; + continue; + } + + f(fieldc, fieldv); + } + + if (ferror(cf)) { + warn("%s", curfilename); + goterror = 1; + } + fclose(cf); +} + + +void +parse_line(char *line, int *fc, char **fv, int nf) +{ + char *p; + + p = line; + *fc = 0; + + while (1) { + while (isspace(*p)) + p++; + + if (*p == '\0' || *p == '#') + break; + + if (*fc < nf) + fv[(*fc)++] = p; + + while (*p && !isspace(*p) && *p != '#') + p++; + + if (*p == '\0' || *p == '#') + break; + + *p++ = '\0'; + } + + if (*p) + *p = '\0'; /* needed for '#' case */ +} + + +void +add_srcdirs(int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; i++) { + if (is_dir(argv[i])) + add_string(&srcdirs, argv[i]); + else { + warnx("%s:%d: `%s' is not a directory, skipping it", + curfilename, linenum, argv[i]); + goterror = 1; + } + } +} + + +void +add_progs(int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; i++) + add_prog(argv[i]); +} + + +void +add_prog(char *progname) +{ + prog_t *p1, *p2; + + /* add to end, but be smart about dups */ + + for (p1 = NULL, p2 = progs; p2 != NULL; p1 = p2, p2 = p2->next) + if (!strcmp(p2->name, progname)) + return; + + p2 = malloc(sizeof(prog_t)); + if(p2) { + memset(p2, 0, sizeof(prog_t)); + p2->name = strdup(progname); + } + if (!p2 || !p2->name) + out_of_memory(); + + p2->next = NULL; + if (p1 == NULL) + progs = p2; + else + p1->next = p2; + + p2->ident = NULL; + p2->srcdir = NULL; + p2->realsrcdir = NULL; + p2->objdir = NULL; + p2->links = NULL; + p2->libs = NULL; + p2->objs = NULL; + p2->keeplist = NULL; + p2->buildopts = NULL; + p2->goterror = 0; + + if (list_mode) + printf("%s\n",progname); +} + + +void +add_link(int argc, char **argv) +{ + int i; + prog_t *p = find_prog(argv[1]); + + if (p == NULL) { + warnx("%s:%d: no prog %s previously declared, skipping link", + curfilename, linenum, argv[1]); + goterror = 1; + return; + } + + for (i = 2; i < argc; i++) { + if (list_mode) + printf("%s\n",argv[i]); + + add_string(&p->links, argv[i]); + } +} + + +void +add_libs(int argc, char **argv) +{ + int i; + + for(i = 1; i < argc; i++) + add_string(&libs, argv[i]); +} + + +void +add_buildopts(int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; i++) + add_string(&buildopts, argv[i]); +} + + +void +add_special(int argc, char **argv) +{ + int i; + prog_t *p = find_prog(argv[1]); + + if (p == NULL) { + if (reading_cache) + return; + + warnx("%s:%d: no prog %s previously declared, skipping special", + curfilename, linenum, argv[1]); + goterror = 1; + return; + } + + if (!strcmp(argv[2], "ident")) { + if (argc != 4) + goto argcount; + if ((p->ident = strdup(argv[3])) == NULL) + out_of_memory(); + } else if (!strcmp(argv[2], "srcdir")) { + if (argc != 4) + goto argcount; + if ((p->srcdir = strdup(argv[3])) == NULL) + out_of_memory(); + } else if (!strcmp(argv[2], "objdir")) { + if(argc != 4) + goto argcount; + if((p->objdir = strdup(argv[3])) == NULL) + out_of_memory(); + } else if (!strcmp(argv[2], "objs")) { + p->objs = NULL; + for (i = 3; i < argc; i++) + add_string(&p->objs, argv[i]); + } else if (!strcmp(argv[2], "objpaths")) { + p->objpaths = NULL; + for (i = 3; i < argc; i++) + add_string(&p->objpaths, argv[i]); + } else if (!strcmp(argv[2], "keep")) { + p->keeplist = NULL; + for(i = 3; i < argc; i++) + add_string(&p->keeplist, argv[i]); + } else if (!strcmp(argv[2], "objvar")) { + if(argc != 4) + goto argcount; + if ((p->objvar = strdup(argv[3])) == NULL) + out_of_memory(); + } else if (!strcmp(argv[2], "buildopts")) { + p->buildopts = NULL; + for (i = 3; i < argc; i++) + add_string(&p->buildopts, argv[i]); + } else if (!strcmp(argv[2], "lib")) { + for (i = 3; i < argc; i++) + add_string(&p->libs, argv[i]); + } else { + warnx("%s:%d: bad parameter name `%s', skipping line", + curfilename, linenum, argv[2]); + goterror = 1; + } + return; + + argcount: + warnx("%s:%d: too %s arguments, expected \"special %s %s \"", + curfilename, linenum, argc < 4? "few" : "many", argv[1], argv[2]); + goterror = 1; +} + + +prog_t * +find_prog(char *str) +{ + prog_t *p; + + for (p = progs; p != NULL; p = p->next) + if (!strcmp(p->name, str)) + return p; + + return NULL; +} + + +/* + * ======================================================================== + * gen_outputs subsystem + * + */ + +/* helper subroutines */ + +void remove_error_progs(void); +void fillin_program(prog_t *p); +void gen_specials_cache(void); +void gen_output_makefile(void); +void gen_output_cfile(void); + +void fillin_program_objs(prog_t *p, char *path); +void top_makefile_rules(FILE *outmk); +void prog_makefile_rules(FILE *outmk, prog_t *p); +void output_strlst(FILE *outf, strlst_t *lst); +char *genident(char *str); +char *dir_search(char *progname); + + +void +gen_outputs(void) +{ + prog_t *p; + + for (p = progs; p != NULL; p = p->next) + fillin_program(p); + + remove_error_progs(); + gen_specials_cache(); + gen_output_cfile(); + gen_output_makefile(); + status(""); + fprintf(stderr, + "Run \"make -f %s\" to build crunched binary.\n", outmkname); +} + +/* + * run the makefile for the program to find which objects are necessary + */ +void +fillin_program(prog_t *p) +{ + char path[MAXPATHLEN]; + char line[MAXLINELEN]; + FILE *f; + + snprintf(line, MAXLINELEN, "filling in parms for %s", p->name); + status(line); + + if (!p->ident) + p->ident = genident(p->name); + + /* look for the source directory if one wasn't specified by a special */ + if (!p->srcdir) { + p->srcdir = dir_search(p->name); + } + + /* Determine the actual srcdir (maybe symlinked). */ + if (p->srcdir) { + snprintf(line, MAXLINELEN, "cd %s && echo -n `/bin/pwd`", + p->srcdir); + f = popen(line,"r"); + if (!f) + errx(1, "Can't execute: %s\n", line); + + path[0] = '\0'; + fgets(path, sizeof path, f); + if (pclose(f)) + errx(1, "Can't execute: %s\n", line); + + if (!*path) + errx(1, "Can't perform pwd on: %s\n", p->srcdir); + + p->realsrcdir = strdup(path); + } + + /* Unless the option to make object files was specified the + * the objects will be built in the source directory unless + * an object directory already exists. + */ + if (!makeobj && !p->objdir && p->srcdir) { + snprintf(line, sizeof line, "%s/%s", objprefix, p->realsrcdir); + if (is_dir(line)) { + if ((p->objdir = strdup(line)) == NULL) + out_of_memory(); + } else + p->objdir = p->realsrcdir; + } + + /* + * XXX look for a Makefile.{name} in local directory first. + * This lets us override the original Makefile. + */ + snprintf(path, sizeof(path), "Makefile.%s", p->name); + if (is_nonempty_file(path)) { + snprintf(line, MAXLINELEN, "Using %s for %s", path, p->name); + status(line); + } else + if (p->srcdir) + snprintf(path, sizeof(path), "%s/Makefile", p->srcdir); + if (!p->objs && p->srcdir && is_nonempty_file(path)) + fillin_program_objs(p, path); + + if (!p->srcdir && !p->objdir && verbose) + warnx("%s: %s: %s", + "warning: could not find source directory", + infilename, p->name); + if (!p->objs && verbose) + warnx("%s: %s: warning: could not find any .o files", + infilename, p->name); + + if ((!p->srcdir || !p->objdir) && !p->objs) + p->goterror = 1; +} + +void +fillin_program_objs(prog_t *p, char *path) +{ + char *obj, *cp; + int fd, rc; + FILE *f; + char *objvar="OBJS"; + strlst_t *s; + char line[MAXLINELEN]; + + /* discover the objs from the srcdir Makefile */ + + if ((fd = mkstemp(tempfname)) == -1) { + perror(tempfname); + exit(1); + } + if ((f = fdopen(fd, "w")) == NULL) { + warn("%s", tempfname); + goterror = 1; + return; + } + if (p->objvar) + objvar = p->objvar; + + /* + * XXX include outhdrname (e.g. to contain Make variables) + */ + if (outhdrname[0] != '\0') + fprintf(f, ".include \"%s\"\n", outhdrname); + fprintf(f, ".include \"%s\"\n", path); + if (buildopts) { + fprintf(f, "BUILDOPTS+="); + output_strlst(f, buildopts); + } + fprintf(f, ".if defined(PROG) && !defined(%s)\n", objvar); + fprintf(f, "%s=${PROG}.o\n", objvar); + fprintf(f, ".endif\n"); + fprintf(f, "loop:\n\t@echo 'OBJS= '${%s}\n", objvar); + + fprintf(f, "crunchgen_objs:\n\t@make -f %s $(BUILDOPTS) $(%s_OPTS)", + tempfname, p->ident); + for (s = p->buildopts; s != NULL; s = s->next) + fprintf(f, " %s", s->str); + fprintf(f, " loop\n"); + + fclose(f); + + snprintf(line, MAXLINELEN, "make -f %s crunchgen_objs 2>&1", tempfname); + if ((f = popen(line, "r")) == NULL) { + warn("submake pipe"); + goterror = 1; + return; + } + + while(fgets(line, MAXLINELEN, f)) { + if (strncmp(line, "OBJS= ", 6)) { + warnx("make error: %s", line); + goterror = 1; + continue; + } + + cp = line + 6; + while (isspace(*cp)) + cp++; + + while(*cp) { + obj = cp; + while (*cp && !isspace(*cp)) + cp++; + if (*cp) + *cp++ = '\0'; + add_string(&p->objs, obj); + while (isspace(*cp)) + cp++; + } + } + + if ((rc=pclose(f)) != 0) { + warnx("make error: make returned %d", rc); + goterror = 1; + } + + unlink(tempfname); +} + +void +remove_error_progs(void) +{ + prog_t *p1, *p2; + + p1 = NULL; p2 = progs; + while (p2 != NULL) { + if (!p2->goterror) + p1 = p2, p2 = p2->next; + else { + /* delete it from linked list */ + warnx("%s: %s: ignoring program because of errors", + infilename, p2->name); + if (p1) + p1->next = p2->next; + else + progs = p2->next; + p2 = p2->next; + } + } +} + +void +gen_specials_cache(void) +{ + FILE *cachef; + prog_t *p; + char line[MAXLINELEN]; + + snprintf(line, MAXLINELEN, "generating %s", cachename); + status(line); + + if ((cachef = fopen(cachename, "w")) == NULL) { + warn("%s", cachename); + goterror = 1; + return; + } + + fprintf(cachef, "# %s - parm cache generated from %s by crunchgen " + " %s\n\n", + cachename, infilename, CRUNCH_VERSION); + + for (p = progs; p != NULL; p = p->next) { + fprintf(cachef, "\n"); + if (p->srcdir) + fprintf(cachef, "special %s srcdir %s\n", + p->name, p->srcdir); + if (p->objdir) + fprintf(cachef, "special %s objdir %s\n", + p->name, p->objdir); + if (p->objs) { + fprintf(cachef, "special %s objs", p->name); + output_strlst(cachef, p->objs); + } + if (p->objpaths) { + fprintf(cachef, "special %s objpaths", p->name); + output_strlst(cachef, p->objpaths); + } + } + fclose(cachef); +} + + +void +gen_output_makefile(void) +{ + prog_t *p; + FILE *outmk; + char line[MAXLINELEN]; + + snprintf(line, MAXLINELEN, "generating %s", outmkname); + status(line); + + if ((outmk = fopen(outmkname, "w")) == NULL) { + warn("%s", outmkname); + goterror = 1; + return; + } + + fprintf(outmk, "# %s - generated from %s by crunchgen %s\n\n", + outmkname, infilename, CRUNCH_VERSION); + + if (outhdrname[0] != '\0') + fprintf(outmk, ".include \"%s\"\n", outhdrname); + + top_makefile_rules(outmk); + for (p = progs; p != NULL; p = p->next) + prog_makefile_rules(outmk, p); + + fprintf(outmk, "\n# ========\n"); + fclose(outmk); +} + + +void +gen_output_cfile(void) +{ + extern char *crunched_skel[]; + char **cp; + FILE *outcf; + prog_t *p; + strlst_t *s; + char line[MAXLINELEN]; + + snprintf(line, MAXLINELEN, "generating %s", outcfname); + status(line); + + if((outcf = fopen(outcfname, "w")) == NULL) { + warn("%s", outcfname); + goterror = 1; + return; + } + + fprintf(outcf, + "/* %s - generated from %s by crunchgen %s */\n", + outcfname, infilename, CRUNCH_VERSION); + + fprintf(outcf, "#define EXECNAME \"%s\"\n", execfname); + for (cp = crunched_skel; *cp != NULL; cp++) + fprintf(outcf, "%s\n", *cp); + + for (p = progs; p != NULL; p = p->next) + fprintf(outcf, "extern int _crunched_%s_stub();\n", p->ident); + + fprintf(outcf, "\nstruct stub entry_points[] = {\n"); + for (p = progs; p != NULL; p = p->next) { + fprintf(outcf, "\t{ \"%s\", _crunched_%s_stub },\n", + p->name, p->ident); + for (s = p->links; s != NULL; s = s->next) + fprintf(outcf, "\t{ \"%s\", _crunched_%s_stub },\n", + s->str, p->ident); + } + + fprintf(outcf, "\t{ EXECNAME, crunched_main },\n"); + fprintf(outcf, "\t{ NULL, NULL }\n};\n"); + fclose(outcf); +} + + +char * +genident(char *str) +{ + char *n, *s, *d; + + /* + * generates a Makefile/C identifier from a program name, + * mapping '-' to '_' and ignoring all other non-identifier + * characters. This leads to programs named "foo.bar" and + * "foobar" to map to the same identifier. + */ + + if ((n = strdup(str)) == NULL) + return NULL; + for (d = s = n; *s != '\0'; s++) { + if (*s == '-') + *d++ = '_'; + else if (*s == '_' || isalnum(*s)) + *d++ = *s; + } + *d = '\0'; + return n; +} + + +char * +dir_search(char *progname) +{ + char path[MAXPATHLEN]; + strlst_t *dir; + char *srcdir; + + for (dir = srcdirs; dir != NULL; dir = dir->next) { + snprintf(path, MAXPATHLEN, "%s/%s", dir->str, progname); + if (!is_dir(path)) + continue; + + if ((srcdir = strdup(path)) == NULL) + out_of_memory(); + + return srcdir; + } + return NULL; +} + + +void +top_makefile_rules(FILE *outmk) +{ + prog_t *p; + + fprintf(outmk, "LIBS+="); + output_strlst(outmk, libs); + + if (makeobj) { + fprintf(outmk, "MAKEOBJDIRPREFIX?=%s\n", objprefix); + fprintf(outmk, "MAKE=env MAKEOBJDIRPREFIX=$(MAKEOBJDIRPREFIX) " + "make\n"); + } else { + fprintf(outmk, "MAKE=make\n"); + } + + if (buildopts) { + fprintf(outmk, "BUILDOPTS+="); + output_strlst(outmk, buildopts); + } + + fprintf(outmk, "CRUNCHED_OBJS="); + for (p = progs; p != NULL; p = p->next) + fprintf(outmk, " %s.lo", p->name); + fprintf(outmk, "\n"); + + fprintf(outmk, "SUBMAKE_TARGETS="); + for (p = progs; p != NULL; p = p->next) + fprintf(outmk, " %s_make", p->ident); + fprintf(outmk, "\nSUBCLEAN_TARGETS="); + for (p = progs; p != NULL; p = p->next) + fprintf(outmk, " %s_clean", p->ident); + fprintf(outmk, "\n\n"); + + fprintf(outmk, "all: objs exe\nobjs: $(SUBMAKE_TARGETS)\n"); + fprintf(outmk, "exe: %s\n", execfname); + fprintf(outmk, "%s: %s.o $(CRUNCHED_OBJS)\n", execfname, execfname); + fprintf(outmk, "\t$(CC) -static -o %s %s.o $(CRUNCHED_OBJS) $(LIBS)\n", + execfname, execfname); + fprintf(outmk, "\tstrip %s\n", execfname); + fprintf(outmk, "realclean: clean subclean\n"); + fprintf(outmk, "clean:\n\trm -f %s *.lo *.o *_stub.c\n", execfname); + fprintf(outmk, "subclean: $(SUBCLEAN_TARGETS)\n"); +} + + +void +prog_makefile_rules(FILE *outmk, prog_t *p) +{ + strlst_t *lst; + + fprintf(outmk, "\n# -------- %s\n\n", p->name); + + fprintf(outmk, "%s_OBJDIR=", p->ident); + if (p->objdir) + fprintf(outmk, "%s", p->objdir); + else + fprintf(outmk, "$(MAKEOBJDIRPREFIX)/$(%s_REALSRCDIR)\n", + p->ident); + fprintf(outmk, "\n"); + + if (p->srcdir && p->objs) { + fprintf(outmk, "%s_SRCDIR=%s\n", p->ident, p->srcdir); + fprintf(outmk, "%s_REALSRCDIR=%s\n", p->ident, p->realsrcdir); + + fprintf(outmk, "%s_OBJS=", p->ident); + output_strlst(outmk, p->objs); + if (p->buildopts != NULL) { + fprintf(outmk, "%s_OPTS+=", p->ident); + output_strlst(outmk, p->buildopts); + } + fprintf(outmk, "%s_make:\n", p->ident); + fprintf(outmk, "\t(cd $(%s_SRCDIR) && ", p->ident); + if (makeobj) + fprintf(outmk, "$(MAKE) obj && "); + fprintf(outmk, "\\\n"); + fprintf(outmk, "\t\t$(MAKE) $(BUILDOPTS) $(%s_OPTS) depend &&", + p->ident); + fprintf(outmk, "\\\n"); + fprintf(outmk, "\t\t$(MAKE) $(BUILDOPTS) $(%s_OPTS) " + "$(%s_OBJS))", + p->ident, p->ident); + fprintf(outmk, "\n"); + fprintf(outmk, "%s_clean:\n", p->ident); + fprintf(outmk, "\t(cd $(%s_SRCDIR) && $(MAKE) $(BUILDOPTS) clean cleandepend)\n\n", + p->ident); + } else { + fprintf(outmk, "%s_make:\n", p->ident); + fprintf(outmk, "\t@echo \"** cannot make objs for %s\"\n\n", + p->name); + } + + fprintf(outmk, "%s_OBJPATHS=", p->ident); + if (p->objpaths) + output_strlst(outmk, p->objpaths); + else { + for (lst = p->objs; lst != NULL; lst = lst->next) { + fprintf(outmk, " $(%s_OBJDIR)/%s", p->ident, lst->str); + } + fprintf(outmk, "\n"); + } + if (p->libs) { + fprintf(outmk, "%s_LIBS=", p->ident); + output_strlst(outmk, p->libs); + } + + fprintf(outmk, "%s_stub.c:\n", p->name); + fprintf(outmk, "\techo \"" + "int _crunched_%s_stub(int argc, char **argv, char **envp)" + "{return main(argc,argv,envp);}\" >%s_stub.c\n", + p->ident, p->name); + fprintf(outmk, "%s.lo: %s_stub.o $(%s_OBJPATHS)", + p->name, p->name, p->ident); + if (p->libs) + fprintf(outmk, " $(%s_LIBS)", p->ident); + fprintf(outmk, "\n"); + fprintf(outmk, "\tld -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); + fprintf(outmk, "\n"); + fprintf(outmk, "\tcrunchide -k _crunched_%s_stub ", p->ident); + for (lst = p->keeplist; lst != NULL; lst = lst->next) + fprintf(outmk, "-k _%s ", lst->str); + fprintf(outmk, "%s.lo\n", p->name); +} + +void +output_strlst(FILE *outf, strlst_t *lst) +{ + for (; lst != NULL; lst = lst->next) + fprintf(outf, " %s", lst->str); + fprintf(outf, "\n"); +} + + +/* + * ======================================================================== + * general library routines + * + */ + +void +status(char *str) +{ + static int lastlen = 0; + int len, spaces; + + if (!verbose) + return; + + len = strlen(str); + spaces = lastlen - len; + if (spaces < 1) + spaces = 1; + + fprintf(stderr, " [%s]%*.*s\r", str, spaces, spaces, " "); + fflush(stderr); + lastlen = len; +} + + +void +out_of_memory(void) +{ + err(1, "%s: %d: out of memory, stopping", infilename, linenum); +} + + +void +add_string(strlst_t **listp, char *str) +{ + strlst_t *p1, *p2; + + /* add to end, but be smart about dups */ + + for (p1 = NULL, p2 = *listp; p2 != NULL; p1 = p2, p2 = p2->next) + if (!strcmp(p2->str, str)) + return; + + p2 = malloc(sizeof(strlst_t)); + if (p2) { + p2->next = NULL; + p2->str = strdup(str); + } + if (!p2 || !p2->str) + out_of_memory(); + + if (p1 == NULL) + *listp = p2; + else + p1->next = p2; +} + + +int +is_dir(char *pathname) +{ + struct stat buf; + + if (stat(pathname, &buf) == -1) + return 0; + + return S_ISDIR(buf.st_mode); +} + +int +is_nonempty_file(char *pathname) +{ + struct stat buf; + + if (stat(pathname, &buf) == -1) + return 0; + + return S_ISREG(buf.st_mode) && buf.st_size > 0; +} diff --git a/usr.bin/crunch/crunchgen/mkskel.sh b/usr.bin/crunch/crunchgen/mkskel.sh new file mode 100644 index 0000000000..fd53d78bbb --- /dev/null +++ b/usr.bin/crunch/crunchgen/mkskel.sh @@ -0,0 +1,15 @@ +#! /bin/sh +# idea and sed lines taken straight from flex + +cat < diff --git a/usr.bin/crunch/crunchide/crunchide.1 b/usr.bin/crunch/crunchide/crunchide.1 new file mode 100644 index 0000000000..1327cc92f4 --- /dev/null +++ b/usr.bin/crunch/crunchide/crunchide.1 @@ -0,0 +1,87 @@ +.\" +.\" 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 +.\" $FreeBSD: src/usr.sbin/crunch/crunchide/crunchide.1,v 1.5.2.5 2003/03/12 22:08:14 trhodes Exp $ +.\" $DragonFly: src/usr.sbin/crunch/crunchide/crunchide.1,v 1.2 2003/06/17 04:29:53 dillon Exp $ +.\" +.Dd June 14, 1994 +.Dt CRUNCHIDE 1 +.Os +.Sh NAME +.Nm crunchide +.Nd hides symbol names from ld, for crunching programs together +.Sh SYNOPSIS +.Nm +.Op Fl f Ar keep-list-file +.Op Fl k Ar keep-symbol +.Op Ar object-file ... +.Sh DESCRIPTION +The +.Nm +utility hides the global symbols of +.Ar object-file +such that they are ignored by subsequent runs of the linker, +.Xr ld 1 . +Some symbols may be left visible via the +.Fl k Ar keep-symbol +and +.Fl f Ar keep-list-file +options. The +.Ar keep-list-file +must contain a list of symbols to keep visible, one symbol per line. +The names given by +.Ar keep-symbol +or in +.Ar keep-list-file +should be C names. For example, +to keep the C function +.Dq foo +visible, the option +.Dq -k foo +should be used. +.Pp +The +.Nm +utility is designed as a companion program for +.Xr crunchgen 1 , +which automates the process of creating crunched binaries from +multiple component programs. +.Sh SEE ALSO +.Xr crunchgen 1 , +.Xr ld 1 +.Sh AUTHORS +The +.Nm crunch +utility was written by +.An James da Silva Aq jds@cs.umd.edu . +.Pp +Copyright (c) 1994 University of Maryland. All Rights Reserved. +.Pp +.An Chris Demetriou Aq cgd@netbsd.org +reorganized +.Nm +so that it supported multiple object formats, and added +ELF object support and ECOFF object recognition. +.Pp +Copyright (c) 1997 Christopher G. Demetriou. All Rights Reserved. diff --git a/usr.bin/crunch/crunchide/crunchide.c b/usr.bin/crunch/crunchide/crunchide.c new file mode 100644 index 0000000000..d9a090251f --- /dev/null +++ b/usr.bin/crunch/crunchide/crunchide.c @@ -0,0 +1,274 @@ +/* $NetBSD: crunchide.c,v 1.8 1997/11/01 06:51:45 lukem Exp $ */ +/* $FreeBSD: src/usr.sbin/crunch/crunchide/crunchide.c,v 1.6.6.1 2002/07/25 09:33:17 ru Exp $ */ +/* $DragonFly: src/usr.sbin/crunch/crunchide/crunchide.c,v 1.4 2003/11/16 14:10:45 eirikn 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 + * + * $NetBSD: crunchide.c,v 1.8 1997/11/01 06:51:45 lukem Exp $ + */ +/* + * 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 + +#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, 1024, 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[] = { +#if defined(__i386__) && defined(arch_i386) +#ifdef NLIST_AOUT + { "a.out", check_aout, hide_aout, }, +#endif +#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; +} diff --git a/usr.bin/crunch/crunchide/exec_aout.c b/usr.bin/crunch/crunchide/exec_aout.c new file mode 100644 index 0000000000..ab49da93d4 --- /dev/null +++ b/usr.bin/crunch/crunchide/exec_aout.c @@ -0,0 +1,207 @@ +/* $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 + * + * $NetBSD: exec_aout.c,v 1.6 1997/08/02 21:30:17 perry Exp $ + * $FreeBSD: src/usr.sbin/crunch/crunchide/exec_aout.c,v 1.1.6.1 2002/07/25 09:33:17 ru Exp $ + * $DragonFly: src/usr.sbin/crunch/crunchide/exec_aout.c,v 1.5 2004/02/08 10:48:30 rob Exp $ + */ +#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) + +#ifdef arch_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; + +#if defined (__DragonFly__) || defined (__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.bin/crunch/crunchide/exec_elf32.c b/usr.bin/crunch/crunchide/exec_elf32.c new file mode 100644 index 0000000000..b0c3782962 --- /dev/null +++ b/usr.bin/crunch/crunchide/exec_elf32.c @@ -0,0 +1,394 @@ +/* + * 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. + * + * $NetBSD: exec_elf32.c,v 1.4 1997/08/12 06:07:24 mikel Exp $ + * $FreeBSD: src/usr.sbin/crunch/crunchide/exec_elf32.c,v 1.1.6.2 2002/07/25 09:33:17 ru Exp $ + * $DragonFly: src/usr.sbin/crunch/crunchide/exec_elf32.c,v 1.2 2003/06/17 04:29:53 dillon Exp $ + */ + +#include + +#ifndef ELFSIZE +#define ELFSIZE 32 +#endif + +#include +#include + +#include +#include +#include +#include +#include + +#include "extern.h" + +#if (defined(NLIST_ELF32) && (ELFSIZE == 32)) || \ + (defined(NLIST_ELF64) && (ELFSIZE == 64)) + +#define __ELF_WORD_SIZE ELFSIZE +#if (ELFSIZE == 32) +#include +#elif (ELFSIZE == 64) +#include +#endif +#include + +#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.bin/crunch/crunchide/exec_elf64.c b/usr.bin/crunch/crunchide/exec_elf64.c new file mode 100644 index 0000000000..a0c0329142 --- /dev/null +++ b/usr.bin/crunch/crunchide/exec_elf64.c @@ -0,0 +1,39 @@ +/* $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. + * + * $NetBSD: exec_elf64.c,v 1.2 1997/08/02 21:30:19 perry Exp $ + */ + +#include + +#define ELFSIZE 64 + +#include "exec_elf32.c" diff --git a/usr.bin/crunch/crunchide/extern.h b/usr.bin/crunch/crunchide/extern.h new file mode 100644 index 0000000000..4de25a863b --- /dev/null +++ b/usr.bin/crunch/crunchide/extern.h @@ -0,0 +1,70 @@ +/* $NetBSD: extern.h,v 1.5 1998/05/06 13:16:57 mycroft Exp $ */ +/* $FreeBSD: src/usr.sbin/crunch/crunchide/extern.h,v 1.1.6.1 2002/07/25 09:33:17 ru Exp $ */ +/* $DragonFly: src/usr.sbin/crunch/crunchide/extern.h,v 1.2 2003/06/17 04:29:53 dillon 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 arch_alpha +#define NLIST_ECOFF +#define NLIST_ELF64 +#else +#ifdef arch_mips +#define NLIST_ELF32 +#else +#ifdef arch_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); diff --git a/usr.bin/crunch/examples/Makefile b/usr.bin/crunch/examples/Makefile new file mode 100644 index 0000000000..861e3028cb --- /dev/null +++ b/usr.bin/crunch/examples/Makefile @@ -0,0 +1,32 @@ + +CRUNCHED= fixit + +# below is boiler-plate to make $(CRUNCHED) from $(CRUNCHED).conf +# I'd use PROG instead of CRUNCHED, but the system makefiles REALLY want +# to build things in the normal way if you use PROG. + +CONF= $(CRUNCHED).conf + +OUTMK= $(CRUNCHED).mk +OUTPUTS= $(OUTMK) $(CRUNCHED).c $(CRUNCHED).cache + +NOMAN= +CLEANFILES+=$(CRUNCHED) *.o *.lo *.c *.mk *.cache +CLEANDIRFILES+=$(OUTPUTS) + +all: $(CRUNCHED) +exe: $(CRUNCHED) + +$(OUTPUTS): $(CONF) + crunchgen ${.CURDIR}/$(CONF) + +$(CRUNCHED): $(OUTPUTS) submake + +submake: + make -f $(OUTMK) +objs: + make -f $(OUTMK) objs +cleandir: + rm -f $(CLEANDIRFILES) + +.include diff --git a/usr.bin/crunch/examples/filesystem.conf b/usr.bin/crunch/examples/filesystem.conf new file mode 100644 index 0000000000..d4315aa3aa --- /dev/null +++ b/usr.bin/crunch/examples/filesystem.conf @@ -0,0 +1,32 @@ +# $FreeBSD: src/usr.sbin/crunch/examples/filesystem.conf,v 1.8 1999/08/28 01:15:57 peter Exp $ +# $DragonFly: src/usr.sbin/crunch/examples/filesystem.conf,v 1.2 2003/06/17 04:29:53 dillon Exp $ + +srcdirs /usr/src/bin /usr/src/sbin /usr/src/gnu/usr.bin /usr/src/usr.sbin +srcdirs /usr/src/sbin/i386 + +# /bin +progs sh expr ls mkdir rm sync test +ln test [ + +# These are needed because of UN*X's idiotic way of indicating that something +# is a login shell. +ln sh - +ln sh -sh + +# /sbin +progs disklabel fdisk init mount newfs reboot umount +ln reboot halt +ln reboot fastboot +ln reboot fasthalt + + +# /usr/bin +progs cpio gzip +ln gzip gunzip +ln gzip gzcat +ln gzip zcat + +# /usr/sbin +progs bad144 + +libs -ll -ledit -ltermcap -lutil -lscrypt diff --git a/usr.bin/crunch/examples/fixit.conf b/usr.bin/crunch/examples/fixit.conf new file mode 100644 index 0000000000..26543c3b65 --- /dev/null +++ b/usr.bin/crunch/examples/fixit.conf @@ -0,0 +1,45 @@ +# fixit.conf - put in anything we think we might want on a fixit floppy + +# first, we list the source dirs that our programs reside in. These are +# searched in order listed to find the dir containing each program. + +srcdirs /usr/src/bin /usr/src/sbin /usr/src/usr.bin /usr/src/usr.sbin +srcdirs /usr/src/gnu/usr.bin /usr/src/usr.bin/vi +srcdirs /usr/src/sbin/i386 + +# second, we list all the programs we want to include in our crunched binary. +# The order doesn't matter. Any program that needs hard links to it gets an +# `ln' directive. + +# /bin stuff + +progs cat chmod cp date dd df echo ed expr hostname kill ln ls mkdir +progs mt mv pwd rcp rm rmdir sh sleep stty sync test + +ln test [ +ln sh -sh # init invokes the shell this way + +# /sbin stuff + +progs badsect chown clri disklabel dump dmesg fdisk fsck ifconfig init +progs mknod mount newfs ping reboot restore swapon umount +ln dump rdump +ln restore rrestore + +# /usr/bin stuff + +progs ftp rsh sed telnet rlogin common find +ln common vi +ln common view +ln common ex + +# gnu stuff + +progs cpio gzip +ln gzip gunzip +ln gzip gzcat + +# finally, we specify the libraries to link in with our binary + +libs -lcrypt -ltelnet -lutil -ll +libs -lcurses -ltermcap -ledit -lkvm diff --git a/usr.bin/crunch/examples/kcopy.conf b/usr.bin/crunch/examples/kcopy.conf new file mode 100644 index 0000000000..a6c1bd1782 --- /dev/null +++ b/usr.bin/crunch/examples/kcopy.conf @@ -0,0 +1,22 @@ +# $FreeBSD: src/usr.sbin/crunch/examples/kcopy.conf,v 1.7 1999/08/28 01:15:57 peter Exp $ +# $DragonFly: src/usr.sbin/crunch/examples/kcopy.conf,v 1.2 2003/06/17 04:29:53 dillon Exp $ + +srcdirs /usr/src/bin /usr/src/sbin + +# Programs from bin/ +progs sh cp echo test +ln test [ + +# These are needed because of UN*X's idiotic way of indicating that something +# is a login shell. +ln sh - +ln sh -sh + +# +# Programs from sbin/ +progs mount mount_cd9660 fsck init reboot umount +ln reboot halt +ln reboot fastboot +ln reboot fasthalt + +libs -ll -ledit -ltermcap -lcompat -lutil -lscrypt diff --git a/usr.bin/crunch/examples/really-big.conf b/usr.bin/crunch/examples/really-big.conf new file mode 100644 index 0000000000..b9b543ae42 --- /dev/null +++ b/usr.bin/crunch/examples/really-big.conf @@ -0,0 +1,149 @@ +# $FreeBSD: src/usr.sbin/crunch/examples/really-big.conf,v 1.2.6.1 2003/02/10 12:21:09 des Exp $ +# $DragonFly: src/usr.sbin/crunch/examples/really-big.conf,v 1.4 2008/02/17 19:51:54 swildner Exp $ +# +# really-big.conf - just about everything, just for testing. +# This ends up having some good examples of the use of specials for +# those hard-to-reach programs. I stopped when I got tired, but we +# could probably get even more stuff (like libexec stuff) in here. +# +# This produces a 4608000 byte binary. Pretty sick and twisted, eh? + +# ========================================================================= + +srcdirs /usr/src/bin + +progs cat chmod cp csh date dd df domainname echo ed expr hostname kill +progs ln ls mkdir mt mv ps pwd rcp rm rmail rmdir sh sleep stty sync test + +ln test [ +ln sh -sh + + +# ========================================================================= + +srcdirs /usr/src/sbin + +progs badsect bim clri disklabel dmesg dump dumpfs fdisk fsck halt +progs ifconfig init mknod modload modunload mount mount_fdesc mount_isofs +progs mount_lofs mount_msdos mount_portal mount_procfs mountd +progs newfs nfsd nfsiod ping quotacheck reboot restore route routed savecore +progs shutdown slattach swapon ttyflags tunefs umount +# shell scripts: fastboot + +ln dump rdump +ln restore rrestore + + +# ========================================================================= + +srcdirs /usr/src/usr.bin + +progs apropos ar asa at basename biff cal calendar cap_mkdb checknr chpass +progs cksum cmp col colcrt colrm column comm compress crontab ctags cut +progs dirname du env error expand false file find finger fmt fold fpr from +progs fsplit fstat ftp getconf getopt gprof head hexdump id indent ipcrm +progs ipcs join kdump ktrace last lastcomm leave lex lock logger locate +progs login logname look m4 machine mail make man mesg mkfifo +progs mkstr modstat more msgs netstat newsyslog nfsstat nice nm nohup +progs pagesize passwd paste patch pr printenv printf quota ranlib +progs renice rev rlogin rpcgen rpcinfo rsh rup ruptime rusers rwall rwho +progs script sed showmount size soelim split strings strip su tail talk +progs tcopy tee telnet tftp time tip tn3270 touch tput tr true tset tsort +progs tty ul uname unexpand unifdef uniq units unvis users uudecode uuencode +progs vacation vgrind vi vis vmstat w wall wc what whatis whereis who +progs whois window write xargs xinstall xstr yacc yes ypcat ypmatch ypwhich + +# shell scripts: lorder mkdep shar which +# problems: rdist uses libcompat.a(regex.o), which conflicts with +# libedit(readline.o) over regerror(). + +# special requirements + +special locate srcdir /usr/src/usr.bin/locate/locate +special tn3270 srcdir /usr/src/usr.bin/tn3270/tn3270 + + +# ========================================================================= + +srcdirs /usr/src/usr.sbin + +progs ac accton amd arp bad144 catman chown chroot config config.new cron +progs dev_mkdb edquota flcopy gettable grfinfo hilinfo htable inetd +progs iostat iteconfig kvm_mkdb mrouted mtree named portmap pppd +progs pstat pwd_mkdb quot quotaon rarpd rbootd repquota rmt rpc.bootparamd +progs rwhod sa sliplogin slstats spray sysctl syslogd tcpdump +progs traceroute trpt trsp 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 + + +srcdirs /usr/src/usr.sbin/lpr # lpr subsystem +progs lpr lpc lpq lprm pac lptest +special lpr srcdir /usr/src/usr.sbin/lpr/lpr + +srcdirs /usr/src/usr.sbin/sendmail # sendmail subsystem +progs mailstats makemap praliases sendmail +special sendmail srcdir /usr/src/usr.sbin/sendmail/src +ln sendmail newaliases +ln sendmail mailq + +srcdirs /usr/src/usr.sbin/timed # timed & timedc +progs timed timedc +special timed srcdir /usr/src/usr.sbin/timed/timed + +srcdirs /usr/src/usr.sbin/yp # yp subsystem +progs ypbind ypwhich ypcat ypmatch ypset yppoll + + +# ========================================================================= + +srcdirs /usr/src/gnu/usr.bin + +progs bc cpio diff diff3 gas gawk grep gzip sdiff sort tar +# shell scripts: send-pr + +srcdirs /usr/src/gnu/usr.bin/ld # ldd and ldconfig +progs ld ldd ldconfig + +# rcs stuff loses because there are cross dependencies between librcs.a and +# the individual programs. The solution would be to specify the objpaths +# directly for each one, and include the full path to librcs.a each the +# objpaths. + +# srcdirs /usr/src/gnu/usr.bin/rcs # rcs subsystem +# progs ci co ident merge rcs rcsclean rcsdiff rcsmerge rlog +# # shell script: rcsfreeze +# special rcs srcdir /usr/src/gnu/usr.bin/rcs/rcs +# libs /usr/src/gnu/usr.bin/rcs/lib/obj/librcs.a + +# gdb loses too +# progs gdb +# special gdb srcdir /usr/src/gnu/usr.bin/gdb/gdb +# libs /usr/src/gnu/usr.bin/gdb/bfd/obj/libbfd.a +# libs /usr/src/gnu/usr.bin/gdb/readline/obj/libreadline.a +# libs /usr/src/gnu/usr.bin/gdb/libiberty/obj/libiberty.a + +# groff has the same problem as rcs +# srcdirs /usr/src/gnu/usr.bin/groff # groff subsystem +# progs groff troff tbl pic eqn grops grotty grodvi refer lookbib +# progs indxbib lkbib tfmtodit addftinfo pfbtops psbb +# shell script: nroff +# special groff srcdir /usr/src/gnu/usr.bin/groff/groff +# libs /usr/src/gnu/usr.bin/groff/libgroff/obj/libgroff.a +# libs /usr/src/gnu/usr.bin/groff/libbib/obj/libbib.a +# libs /usr/src/gnu/usr.bin/groff/libdriver/obj/libdriver.a + +srcdirs /usr/src/gnu/usr.bin/gcc2 # gcc & friends +progs cc cpp cc1 + +# cc1 has the same problem as rcs and groff, but since there's only one program +# I'll go ahead and solve it as an example. + +special cc1 objpaths /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-parse.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-lang.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-lex.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-pragma.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-decl.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-typeck.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-convert.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-aux-info.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-iterate.o /usr/src/gnu/usr.bin/gcc2/common/obj/libcc1.a + +ln gzip gunzip +ln gzip gzcat + +libs -ledit -lgnumalloc -lc -lcrypt -ltermcap -lcurses -ltelnet -lutil -lkvm +libs -ll -ly -lm -lresolv -lrpcsvc -lcompat diff --git a/usr.bin/vi/Makefile b/usr.bin/vi/Makefile index 738dfd35c2..2ed18d4eb5 100644 --- a/usr.bin/vi/Makefile +++ b/usr.bin/vi/Makefile @@ -7,6 +7,17 @@ SRCDIR= ${.CURDIR}/../../contrib/nvi SUBDIR+= catalog +.if defined(RELEASE_CRUNCH) +# When building `vi' for the fixit floppy, don't include any of the +# API stuff. +APISTUFF= ex_notcl.c ex_noperl.c + +.else + +APISTUFF= ex_tcl.c ex_perl.c + +.endif + WARNS?= 0 # some warn issues on 32 bit machines VI= nvi diff --git a/usr.sbin/802_11/wpa_supplicant/Makefile b/usr.sbin/802_11/wpa_supplicant/Makefile index df47797531..9a6bbc6d0a 100644 --- a/usr.sbin/802_11/wpa_supplicant/Makefile +++ b/usr.sbin/802_11/wpa_supplicant/Makefile @@ -50,7 +50,7 @@ LDADD+=${WPA_SUPPLICANT_LDADD} SRCS+= eapol_supp_sm.c eap.c eap_common.c eap_methods.c CFLAGS+= -DIEEE8021X_EAPOL -.if !defined(NO_CRYPT) && !defined(NO_OPENSSL) +.if !defined(NO_CRYPT) && !defined(NO_OPENSSL) && !defined(RELEASE_CRUNCH) CFLAGS+=-DEAP_TLS -DEAP_PEAP -DEAP_MSCHAPv2 -DEAP_LEAP -DEAP_PSK \ -DEAP_TLV -DEAP_TLS_FUNCS -DEAP_TLS_OPENSSL SRCS+= chap.c crypto_openssl.c \ diff --git a/usr.sbin/inetd/Makefile b/usr.sbin/inetd/Makefile index 6cadb66930..56a491fb69 100644 --- a/usr.sbin/inetd/Makefile +++ b/usr.sbin/inetd/Makefile @@ -7,10 +7,14 @@ SRCS= inetd.c builtins.c MAN= inetd.8 MLINKS= inetd.8 inetd.conf.5 -CFLAGS+= -DLOGIN_CAP -DINET6 -DIPSEC +CFLAGS+= -DLOGIN_CAP #CFLAGS+= -DSANITY_CHECK -DPADD+= ${LIBUTIL} ${LIBWRAP} ${LIBIPSEC} -LDADD+= -lutil -lwrap -lipsec - +DPADD+= ${LIBUTIL} ${LIBWRAP} +LDADD+= -lutil -lwrap +.if !defined(RELEASE_CRUNCH) +CFLAGS+=-DINET6 -DIPSEC +DPADD+= ${LIBIPSEC} +LDADD+= -lipsec +.endif .include diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile index 930c84bd3f..a21d11bda1 100644 --- a/usr.sbin/ppp/Makefile +++ b/usr.sbin/ppp/Makefile @@ -8,6 +8,15 @@ SRCS= acf.c arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.c chat.c \ mbuf.c mp.c ncp.c ncpaddr.c pap.c physical.c pred.c probe.c prompt.c \ proto.c route.c server.c sig.c slcompress.c sync.c systems.c tcp.c \ tcpmss.c throughput.c timer.c tty.c tun.c udp.c vjcomp.c +.if defined(RELEASE_CRUNCH) +CFLAGS+=-DRELEASE_CRUNCH +NOATM= true +NOI4B= true +NONAT= true +NOKLDLOAD= true +NORADIUS= true +NOSUID= true +.endif .if defined(NOSUID) || defined(PPP_NOSUID) BINMODE=554 diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index a0a24beab8..98a273851e 100644 --- a/usr.sbin/ppp/bundle.c +++ b/usr.sbin/ppp/bundle.c @@ -677,9 +677,12 @@ bundle_LockTun(struct bundle *bundle) if (lockfile != NULL) { fprintf(lockfile, "%d\n", (int)getpid()); fclose(lockfile); - } else + } +#ifndef RELEASE_CRUNCH + else log_Printf(LogERROR, "Warning: Can't create %s: %s\n", pidfilename, strerror(errno)); +#endif } static void diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c index bf4433fe01..23f43968ec 100644 --- a/usr.sbin/ppp/physical.c +++ b/usr.sbin/ppp/physical.c @@ -369,9 +369,13 @@ physical_Close(struct physical *p) if (*p->name.full == '/') { snprintf(fn, sizeof fn, "%s%s.if", _PATH_VARRUN, p->name.base); +#ifndef RELEASE_CRUNCH if (ID0unlink(fn) == -1) log_Printf(LogALERT, "%s: Can't remove %s: %s\n", p->link.name, fn, strerror(errno)); +#else + ID0unlink(fn); +#endif } physical_Unlock(p); if (p->handler && p->handler->destroy) @@ -976,9 +980,12 @@ physical_Found(struct physical *p) if (lockfile != NULL) { fprintf(lockfile, "%s%d\n", TUN_NAME, p->dl->bundle->unit); fclose(lockfile); - } else + } +#ifndef RELEASE_CRUNCH + else log_Printf(LogALERT, "%s: Can't create %s: %s\n", p->link.name, fn, strerror(errno)); +#endif } throughput_start(&p->link.stats.total, "physical throughput", diff --git a/usr.sbin/pppd/Makefile b/usr.sbin/pppd/Makefile index 15b813e5c4..dccc679885 100644 --- a/usr.sbin/pppd/Makefile +++ b/usr.sbin/pppd/Makefile @@ -29,11 +29,20 @@ LDADD+= -lpcap DPADD+= ${LIBPCAP} # MS-CHAP support. Requires the DES library. -.if exists(${.CURDIR}/../../secure) && !defined(NO_CRYPT) && !defined(NO_OPENSSL) +.if exists(${.CURDIR}/../../secure) && !defined(NO_CRYPT) && !defined(NO_OPENSSL) && !defined(RELEASE_CRUNCH) CFLAGS+=-DCHAPMS SRCS+= chap_ms.c LDADD+= -lcrypto DPADD+= ${LIBCRYPTO} .endif +.if defined(RELEASE_CRUNCH) +# We must create these objects because crunchgen will link them, +# and we don't want any unused symbols to spoil the final link. +SRCS+= chap_ms.c +chap_ms.o: + >null_${.PREFIX}.c + cc -c -o ${.TARGET} null_${.PREFIX}.c +.endif + .include diff --git a/usr.sbin/sendmail/Makefile b/usr.sbin/sendmail/Makefile index 9b8d8d8774..2f28722bae 100644 --- a/usr.sbin/sendmail/Makefile +++ b/usr.sbin/sendmail/Makefile @@ -64,7 +64,7 @@ SRCS+= sm_os.h CLEANFILES+=sm_os.h .if exists(${.CURDIR}/../../secure) && !defined(NO_CRYPT) && \ - !defined(NO_OPENSSL) + !defined(NO_OPENSSL) && !defined(RELEASE_CRUNCH) # STARTTLS support CFLAGS+= -DSTARTTLS -D_FFR_TLS_1 LDADD+= -lssl -lcrypto diff --git a/usr.sbin/tcpdump/Makefile b/usr.sbin/tcpdump/Makefile index d0f3d0982b..fe7d41d953 100644 --- a/usr.sbin/tcpdump/Makefile +++ b/usr.sbin/tcpdump/Makefile @@ -51,7 +51,8 @@ CFLAGS+= -DINET6 -DHAVE_GETNAMEINFO DPADD= ${LIBL} ${LIBPCAP} LDADD= -ll -lpcap -.if exists(../../secure) && !defined(NO_CRYPT) && !defined(NO_OPENSSL) +.if exists(../../secure) && !defined(NO_CRYPT) && !defined(NO_OPENSSL) && \ + !defined(RELEASE_CRUNCH) DPADD+= ${LIBCRYPTO} LDADD+= -lcrypto CFLAGS+= -I${DESTDIR}/usr/include/openssl -DHAVE_LIBCRYPTO -DHAVE_OPENSSL_EVP_H