summaryrefslogtreecommitdiff
path: root/cross/bfd-crunchide
diff options
context:
space:
mode:
authorsakamoto <sakamoto@pkgsrc.org>1999-12-20 05:57:40 +0000
committersakamoto <sakamoto@pkgsrc.org>1999-12-20 05:57:40 +0000
commit872d9f92bc6f1947e1529b807f57f2239df873a4 (patch)
treed6fa773e6ad66e110dca41c297e91d9a4094305f /cross/bfd-crunchide
parent0dc13e72b74a4f01b5afeb7730bf16eba15e43e5 (diff)
downloadpkgsrc-872d9f92bc6f1947e1529b807f57f2239df873a4.tar.gz
Initial import of bfd-crunchide-1.0
crunchide using libbfd. Used for cross-building distributions.
Diffstat (limited to 'cross/bfd-crunchide')
-rw-r--r--cross/bfd-crunchide/Makefile31
-rw-r--r--cross/bfd-crunchide/files/Makefile13
-rw-r--r--cross/bfd-crunchide/files/crunchide.194
-rw-r--r--cross/bfd-crunchide/files/crunchide.c443
-rw-r--r--cross/bfd-crunchide/pkg/COMMENT1
-rw-r--r--cross/bfd-crunchide/pkg/DESCR6
-rw-r--r--cross/bfd-crunchide/pkg/PLIST2
7 files changed, 590 insertions, 0 deletions
diff --git a/cross/bfd-crunchide/Makefile b/cross/bfd-crunchide/Makefile
new file mode 100644
index 00000000000..472001fa92b
--- /dev/null
+++ b/cross/bfd-crunchide/Makefile
@@ -0,0 +1,31 @@
+# $NetBSD: Makefile,v 1.1.1.1 1999/12/20 05:57:40 sakamoto Exp $
+
+DISTNAME= bfd-crunchide-1.0
+CATEGORIES= cross
+MASTER_SITES= # empty
+DISTFILES= # empty
+
+MAINTAINER= sakamoto@netbsd.org
+
+DEPENDS= cross-binutils-2.9.1.1:../binutils
+
+EXTRACT_ONLY= # empty
+NO_WRKSUBDIR= yes
+NO_CHECKSUM= yes
+NO_PATCH= yes
+NO_CONFIGURE= yes
+
+USE_CROSSBASE= yes
+BFD_VERSION= 2.9.1
+MAKE_ENV+= BFD_VERSION=${BFD_VERSION} \
+ CPPFLAGS="-I${PREFIX}/include" \
+ LIBS="-L${PREFIX}/lib -Wl,-R${PREFIX}/lib -lbfd-${BFD_VERSION} -liberty"
+
+do-extract:
+ @${MKDIR} ${WRKSRC}
+ @${CP} ${FILESDIR}/* ${WRKSRC}
+
+pre-install:
+ @if [ ! -d ${PREFIX}/bin ];then ${MKDIR} ${PREFIX}/bin;fi
+
+.include "../../mk/bsd.pkg.mk"
diff --git a/cross/bfd-crunchide/files/Makefile b/cross/bfd-crunchide/files/Makefile
new file mode 100644
index 00000000000..daabf47a8eb
--- /dev/null
+++ b/cross/bfd-crunchide/files/Makefile
@@ -0,0 +1,13 @@
+# $NetBSD: Makefile,v 1.1.1.1 1999/12/20 05:57:40 sakamoto Exp $
+
+PROG= crunchide
+SRCS= crunchide.c
+#MAN= crunchide.1
+MKMAN= no
+
+BINDIR= ${PREFIX}/bin
+
+COPTS+= ${CPPFLAGS}
+LDADD+= ${LIBS}
+
+.include <bsd.prog.mk>
diff --git a/cross/bfd-crunchide/files/crunchide.1 b/cross/bfd-crunchide/files/crunchide.1
new file mode 100644
index 00000000000..3e3186034ed
--- /dev/null
+++ b/cross/bfd-crunchide/files/crunchide.1
@@ -0,0 +1,94 @@
+.\" $NetBSD: crunchide.1,v 1.1.1.1 1999/12/20 05:57:40 sakamoto Exp $
+.\"
+.\" 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
+.\"
+.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 ""
+.Bk -words
+.Op Fl b Ar bfdname
+.Ek
+.Bk -words
+.Op Fl f Ar keep-list-file
+.Ek
+.Bk -words
+.Op Fl k Ar keep-symbol
+.Ek
+.Bk -words
+.Op Ar object-file ...
+.Ek
+.Sh DESCRIPTION
+.Nm Crunchide
+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
+To recognize kernel executable format, the
+.Fl b
+flag specifies BFD name of kernel.
+.Pp
+.Nm Crunchide
+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
+.Nm Crunch
+was written by James da Silva <jds@cs.umd.edu>.
+.sp 0
+Copyright (c) 1994 University of Maryland. All Rights Reserved.
+.Pp
+Chris Demetriou <cgd@netbsd.org> reorganized
+.Nm
+so that it supported multiple object formats, and added
+ELF object support and ECOFF object recognition.
+.sp 0
+Copyright (c) 1997 Christopher G. Demetriou. All Rights Reserved.
diff --git a/cross/bfd-crunchide/files/crunchide.c b/cross/bfd-crunchide/files/crunchide.c
new file mode 100644
index 00000000000..848edc8931b
--- /dev/null
+++ b/cross/bfd-crunchide/files/crunchide.c
@@ -0,0 +1,443 @@
+/* $NetBSD: crunchide.c,v 1.1.1.1 1999/12/20 05:57:40 sakamoto Exp $ */
+/* NetBSD: crunchide.c,v 1.9 1999/01/11 22:40:00 kleink Exp */
+
+/*
+ * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
+ * Copyright (c) 1994 University of Maryland
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
+/*
+ * crunchide.c - tiptoes through an a.out symbol table, hiding all defined
+ * global symbols. Allows the user to supply a "keep list" of symbols
+ * that are not to be hidden. This program relies on the use of the
+ * linker's -dc flag to actually put global bss data into the file's
+ * bss segment (rather than leaving it as undefined "common" data).
+ *
+ * The point of all this is to allow multiple programs to be linked
+ * together without getting multiple-defined errors.
+ *
+ * For example, consider a program "foo.c". It can be linked with a
+ * small stub routine, called "foostub.c", eg:
+ * int foo_main(int argc, char **argv){ return main(argc, argv); }
+ * like so:
+ * cc -c foo.c foostub.c
+ * ld -dc -r foo.o foostub.o -o foo.combined.o
+ * crunchide -k _foo_main foo.combined.o
+ * at this point, foo.combined.o can be linked with another program
+ * and invoked with "foo_main(argc, argv)". foo's main() and any
+ * other globals are hidden and will not conflict with other symbols.
+ *
+ * TODO:
+ * - resolve the theoretical hanging reloc problem (see check_reloc()
+ * below). I have yet to see this problem actually occur in any real
+ * program. In what cases will gcc/gas generate code that needs a
+ * relative reloc from a global symbol, other than PIC? The
+ * solution is to not hide the symbol from the linker in this case,
+ * but to generate some random name for it so that it doesn't link
+ * with anything but holds the place for the reloc.
+ * - arrange that all the BSS segments start at the same address, so
+ * that the final crunched binary BSS size is the max of all the
+ * component programs' BSS sizes, rather than their sum.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: crunchide.c,v 1.1.1.1 1999/12/20 05:57:40 sakamoto Exp $");
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <errno.h>
+#include <a.out.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <bfd.h>
+
+extern const char *__progname;
+
+void usage __P((void));
+void add_to_keep_list __P((char *));
+void add_file_to_keep_list __P((char *));
+int hide_syms __P((const char *, char *));
+static void setup_section __P((bfd *, sec_ptr, PTR));
+static void copy_section __P((bfd *, sec_ptr, PTR));
+
+int verbose;
+
+struct keep {
+ struct keep *next;
+ char *sym;
+} *keep_list;
+
+struct bfd_cookie {
+ bfd *bfd;
+ asymbol **symtable;
+};
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int ch, errors;
+ char *bfdname = NULL;
+
+ while ((ch = getopt(argc, argv, "b:k:f:v")) != -1)
+ switch (ch) {
+ case 'b':
+ bfdname = optarg;
+ break;
+ 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, bfdname))
+ errors = 1;
+ argc--, argv++;
+ }
+
+ return errors;
+}
+
+void
+usage()
+{
+ const char **list;
+
+ fprintf(stderr,
+"Usage: %s [-b bfdname] [-k <symbol-name>] [-f <keep-list-file>] <files> ...\n",
+ __progname);
+ fprintf(stderr, "supported targets:");
+ for (list = bfd_target_list(); *list != NULL; list++)
+ fprintf(stderr, " %s", *list);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+void
+add_to_keep_list(symbol)
+ 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", __progname);
+ exit(1);
+ }
+ newp->next = curp;
+ if (prevp)
+ prevp->next = newp;
+ else
+ keep_list = newp;
+}
+
+int
+in_keep_list(symbol)
+ 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(filename)
+ 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);
+}
+
+int
+hide_syms(filename, bfdname)
+ const char *filename;
+ char *bfdname;
+{
+ int i, n, rv = 0;
+ bfd *org_bfd = NULL, *new_bfd = NULL;
+ char *tempname;
+ char **name;
+ long storage_needed, number_of_symbols;
+ size_t fn_size;
+ asymbol **org_symtable, **new_symtable;
+
+ fn_size = strlen(filename);
+
+ bfd_init();
+ if ((org_bfd = bfd_openr(filename, bfdname)) == NULL) {
+ bfd_perror(filename);
+ return 1;
+ }
+ if (!bfd_check_format(org_bfd, bfd_object)) {
+ bfd_perror(filename);
+ goto err;
+ }
+
+ bfdname = bfd_get_target(org_bfd);
+ tempname = tempnam(".", NULL);
+ if ((new_bfd = bfd_openw(tempname, bfdname)) == NULL) {
+ bfd_perror(tempname);
+ goto err;
+ }
+
+ if (!bfd_set_format(new_bfd, bfd_get_format(org_bfd)) ||
+ !bfd_set_start_address(new_bfd, bfd_get_start_address(org_bfd)) ||
+ !bfd_set_file_flags(new_bfd, (bfd_get_file_flags(org_bfd) &
+ bfd_applicable_file_flags(new_bfd))) ||
+ !bfd_set_arch_mach (new_bfd, bfd_get_arch (org_bfd),
+ bfd_get_mach (org_bfd))) {
+ bfd_perror(tempname);
+ goto err;
+ }
+ bfd_map_over_sections(org_bfd, setup_section, (void *)new_bfd);
+
+ storage_needed = bfd_get_symtab_upper_bound(org_bfd);
+ if (storage_needed < 0)
+ goto err;
+ if (storage_needed == 0)
+ goto out;
+
+ org_symtable = (asymbol **)malloc(storage_needed);
+ number_of_symbols = bfd_canonicalize_symtab(org_bfd, org_symtable);
+ if (number_of_symbols < 0)
+ goto err;
+
+ new_symtable = (asymbol **)malloc(storage_needed);
+ if (new_symtable == NULL)
+ goto err;
+ name = (char **)calloc(sizeof (char *), number_of_symbols);
+ if (name == NULL)
+ goto err;
+
+ n = 0;
+ for (i = 0; i < number_of_symbols; i++) {
+ const char *symname;
+
+ new_symtable[i] = org_symtable[i];
+ if (!(new_symtable[i]->flags & BSF_GLOBAL))
+ continue;
+
+ symname = bfd_asymbol_name(new_symtable[i]);
+ if (symname[0] == '_')
+ symname++;
+ if (in_keep_list(symname))
+ continue;
+
+ n++;
+
+ /*
+ * make sure there's size for the next entry, even if it's
+ * as large as it can be.
+ *
+ * "_$$hide$$ <filename> <symname><NUL>" ->
+ * 9 + 3 + sizes of fn and sym name
+ */
+ name[i] = (char *)malloc(12 + fn_size + strlen(symname));
+ sprintf(name[i], "_$$hide$$ %s %s", filename, symname);
+ new_symtable[i]->name = name[i];
+ }
+
+ if (n > 0) {
+ struct bfd_cookie cookie;
+
+ new_symtable[number_of_symbols] = NULL;
+ bfd_set_symtab(new_bfd, new_symtable, number_of_symbols);
+
+ cookie.bfd = new_bfd;
+ cookie.symtable = org_symtable;
+ bfd_map_over_sections(org_bfd, copy_section, (void *)&cookie);
+
+ if (!bfd_copy_private_bfd_data(org_bfd, new_bfd)) {
+ bfd_perror("bfd_copy_private_bfd_data");
+ goto err;
+ }
+ }
+
+ bfd_close(new_bfd);
+ bfd_close(org_bfd);
+
+ if (rename(tempname, filename) < 0)
+ perror("rename");
+ unlink(tempname);
+
+ for (i = 0; i < number_of_symbols; i++)
+ if (name[i])
+ free(name[i]);
+ free(new_symtable);
+ free(name);
+
+out:
+ return (rv);
+
+err:
+ rv = 1;
+ if (org_bfd)
+ bfd_close(org_bfd);
+ if (new_bfd) {
+ unlink(tempname);
+ bfd_close(new_bfd);
+ }
+ goto out;
+}
+
+static void
+setup_section(ibfd, isection, arg)
+ bfd *ibfd;
+ sec_ptr isection;
+ PTR arg;
+{
+ sec_ptr osection;
+ bfd *obfd = (bfd *)arg;
+
+ if ((osection = bfd_make_section_anyway(obfd,
+ bfd_section_name(ibfd, isection))) == NULL ||
+ !bfd_set_section_size(obfd, osection,
+ bfd_section_size(ibfd, isection)) ||
+ !bfd_set_section_vma(obfd, osection,
+ bfd_section_vma(ibfd, isection)) ||
+ !bfd_set_section_alignment(obfd, osection,
+ bfd_section_alignment(ibfd, isection)) ||
+ !bfd_set_section_flags(obfd, osection,
+ bfd_get_section_flags(ibfd, isection))) {
+ bfd_perror("setup_section");
+ return;
+ }
+
+ isection->output_section = osection;
+ isection->output_offset = 0;
+ if (!bfd_copy_private_section_data(ibfd, isection, obfd, osection)) {
+ bfd_perror("setup_section");
+ return;
+ }
+}
+
+static void
+copy_section(ibfd, isection, arg)
+ bfd *ibfd;
+ sec_ptr isection;
+ PTR arg;
+{
+ struct bfd_cookie *bc = (struct bfd_cookie *)arg;
+ bfd *obfd = bc->bfd;
+ asymbol **isym = bc->symtable;
+ arelent **relpp;
+ sec_ptr osection;
+ PTR memhunk;
+ bfd_size_type size;
+ long relcount, relsize;
+
+ osection = isection->output_section;
+ size = bfd_get_section_size_before_reloc(isection);
+ if (size == 0 || osection == 0)
+ return;
+
+ relsize = bfd_get_reloc_upper_bound(ibfd, isection);
+ if (relsize < 0) {
+ bfd_perror(bfd_get_filename(ibfd));
+ }
+ if (relsize == 0) {
+ bfd_set_reloc(obfd, osection, NULL, 0);
+ } else {
+ relpp = (arelent **)malloc(relsize);
+ relcount = bfd_canonicalize_reloc(ibfd, isection, relpp, isym);
+ if (relcount < 0)
+ bfd_perror(bfd_get_filename(ibfd));
+ bfd_set_reloc(obfd, osection, relpp, relcount);
+ }
+
+ isection->_cooked_size = isection->_raw_size;
+ isection->reloc_done = true;
+
+ if (bfd_get_section_flags(ibfd, isection) & SEC_HAS_CONTENTS) {
+ memhunk = (PTR)malloc((unsigned int)size);
+ if (!bfd_get_section_contents(ibfd, isection, memhunk, 0, size))
+ bfd_perror(bfd_get_filename(ibfd));
+ if (!bfd_set_section_contents(obfd, osection, memhunk, 0, size))
+ bfd_perror(bfd_get_filename(obfd));
+ free(memhunk);
+ } else if (bfd_get_section_flags(ibfd, isection) & SEC_LOAD) {
+ memhunk = (PTR)malloc((unsigned int)size);
+ memset(memhunk, 0, size);
+ if (!bfd_set_section_contents(obfd, osection, memhunk, 0, size))
+ bfd_perror(bfd_get_filename(obfd));
+ free(memhunk);
+ }
+}
diff --git a/cross/bfd-crunchide/pkg/COMMENT b/cross/bfd-crunchide/pkg/COMMENT
new file mode 100644
index 00000000000..9343d8c2bd8
--- /dev/null
+++ b/cross/bfd-crunchide/pkg/COMMENT
@@ -0,0 +1 @@
+crunchide using libbfd. Used for cross-building distributions.
diff --git a/cross/bfd-crunchide/pkg/DESCR b/cross/bfd-crunchide/pkg/DESCR
new file mode 100644
index 00000000000..b9e5ea20f36
--- /dev/null
+++ b/cross/bfd-crunchide/pkg/DESCR
@@ -0,0 +1,6 @@
+This version of crunchide has been written to make use of libbfd. This
+enables it to work for object file formats not normally supported on a
+host.
+
+This version is intended for cross-building snapshots. It is not needed
+to build snapshots of the host architecture type.
diff --git a/cross/bfd-crunchide/pkg/PLIST b/cross/bfd-crunchide/pkg/PLIST
new file mode 100644
index 00000000000..823819ba56c
--- /dev/null
+++ b/cross/bfd-crunchide/pkg/PLIST
@@ -0,0 +1,2 @@
+@comment $NetBSD: PLIST,v 1.1.1.1 1999/12/20 05:57:40 sakamoto Exp $
+bin/crunchide