diff options
-rw-r--r-- | usr.bin/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/elf2aout/Makefile | 5 | ||||
-rw-r--r-- | usr.bin/elf2aout/elf2aout.1 | 52 | ||||
-rw-r--r-- | usr.bin/elf2aout/elf2aout.c | 497 | ||||
-rw-r--r-- | usr.bin/elf2ecoff/Makefile | 5 | ||||
-rw-r--r-- | usr.bin/elf2ecoff/elf2ecoff.1 | 53 | ||||
-rw-r--r-- | usr.bin/elf2ecoff/elf2ecoff.c | 417 |
7 files changed, 1 insertions, 1034 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile index ce4cc514ac1..3f52b83db26 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.107 2008/05/09 06:52:10 deraadt Exp $ +# $OpenBSD: Makefile,v 1.108 2008/05/21 19:48:50 miod Exp $ .include <bsd.own.mk> @@ -35,8 +35,4 @@ SUBDIR+=ypcat ypmatch ypwhich SUBDIR+= strip strings .endif -.if make(clean) || make(cleandir) || make(obj) -SUBDIR+= elf2ecoff elf2aout -.endif - .include <bsd.subdir.mk> diff --git a/usr.bin/elf2aout/Makefile b/usr.bin/elf2aout/Makefile deleted file mode 100644 index b90e62f07e8..00000000000 --- a/usr.bin/elf2aout/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# $OpenBSD: Makefile,v 1.1 1996/12/22 15:03:32 graichen Exp $ - -PROG= elf2aout - -.include <bsd.prog.mk> diff --git a/usr.bin/elf2aout/elf2aout.1 b/usr.bin/elf2aout/elf2aout.1 deleted file mode 100644 index b3ea5871fbb..00000000000 --- a/usr.bin/elf2aout/elf2aout.1 +++ /dev/null @@ -1,52 +0,0 @@ -.\" $OpenBSD: elf2aout.1,v 1.10 2007/05/31 19:20:09 jmc Exp $ -.\" -.\" Copyright (c) 1996 Per Fogelstrom -.\" -.\" 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. -.\" -.\" 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. -.\" -.\" -.Dd $Mdocdate: May 31 2007 $ -.Dt ELF2AOUT 1 -.Os -.Sh NAME -.Nm elf2aout -.Nd convert ELF executable to a.out format -.Sh SYNOPSIS -.Nm elf2aout -.Op Ar elfexec -.Oo -.Ar aoutexec -.Oc -.Sh DESCRIPTION -.Nm -reads and converts the file specified as -.Ar elfexec -to a.out format, into file -.Ar aoutexec , -suitable for bootstrapping certain -.Nm MIPS -systems. -The systems currently requiring this -conversion are: -.Nm pmax . -.Sh DIAGNOSTICS -If the conversion fails a diagnostic message is printed to explain the cause. diff --git a/usr.bin/elf2aout/elf2aout.c b/usr.bin/elf2aout/elf2aout.c deleted file mode 100644 index acca8a6cbc8..00000000000 --- a/usr.bin/elf2aout/elf2aout.c +++ /dev/null @@ -1,497 +0,0 @@ -/* $OpenBSD: elf2aout.c,v 1.6 2006/04/02 21:38:56 djm Exp $ */ - -/* - * Copyright (c) 1995 - * Ted Lemon (hereinafter referred to as the author) - * - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <elf_abi.h> -#include <machine/elf_abi.h> -#include <stdio.h> -#include <a.out.h> -#include <errno.h> -#include <string.h> -#include <limits.h> - -#define SHN_MIPS_ACOMMON 0xfff0 - -extern char *__progname; - -struct sect { - unsigned long vaddr; - unsigned long len; -}; -int phcmp(); -char *saveRead(int file, off_t offset, off_t len, char *name); -int copy(int, int, off_t, off_t); -int translate_syms(int, int, off_t, off_t, off_t, off_t); -int *symTypeTable; - -/* Symbol table entry... */ -struct sym { - unsigned long name; /* Index into strtab of symbol name. */ - unsigned long value; /* Section offset, virt addr or common align. */ - unsigned long size; /* Size of object referenced. */ - unsigned type:4; /* Symbol type (e.g., function, data)... */ - unsigned binding:4; /* Symbol binding (e.g., global, - * local)... */ - unsigned char other; /* Unused. */ - unsigned short shndx; /* Section containing symbol. */ -}; - -struct phdr { - unsigned long type; /* Segment type... */ - unsigned long offset; /* File offset... */ - unsigned long vaddr; /* Virtual address... */ - unsigned long paddr; /* Physical address... */ - unsigned long filesz; /* Size of segment in file... */ - unsigned long memsz; /* Size of segment in memory... */ - unsigned long flags; /* Segment flags... */ - unsigned long align; /* Alighment, file and memory... */ -}; - -int -main(int argc, char *argv[]) -{ - Elf32_Ehdr ex; - Elf32_Phdr *ph; - Elf32_Shdr *sh; - struct sym *symtab; - char *shstrtab; - int strtabix, symtabix; - int i; - struct sect text, data, bss; - struct exec aex; - int infile, outfile; - unsigned long cur_vma = ULONG_MAX; - int symflag = 0; - - text.len = data.len = bss.len = 0; - text.vaddr = data.vaddr = bss.vaddr = 0; - - /* Check args... */ - if (argc < 3 || argc > 4) { -usage: - fprintf(stderr, - "usage: %s elf a.out\n", __progname); - exit(1); - } - /* Try the input file... */ - if ((infile = open(argv[1], O_RDONLY)) < 0) { - fprintf(stderr, "Can't open %s for read: %s\n", - argv[1], strerror(errno)); - exit(1); - } - /* Read the header, which is at the beginning of the file... */ - i = read(infile, &ex, sizeof ex); - if (i != sizeof ex) { - fprintf(stderr, "ex: %s: %s.\n", - argv[1], i ? strerror(errno) : "End of file reached"); - exit(1); - } - /* Read the program headers... */ - ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff, - ex.e_phnum * sizeof(Elf32_Phdr), "ph"); - /* Read the section headers... */ - sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff, - ex.e_shnum * sizeof(Elf32_Shdr), "sh"); - /* Read in the section string table. */ - shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset, - sh[ex.e_shstrndx].sh_size, "shstrtab"); - - /* - * Find space for a table matching ELF section indices to a.out - * symbol types. - */ - symTypeTable = calloc(ex.e_shnum, sizeof(int)); - if (!symTypeTable) { - fprintf(stderr, "symTypeTable: can't allocate.\n"); - exit(1); - } - - /* - * Look for the symbol table and string table... Also map section - * indices to symbol types for a.out - */ - for (i = 0; i < ex.e_shnum; i++) { - char *name = shstrtab + sh[i].sh_name; - if (!strcmp(name, ".symtab")) - symtabix = i; - else if (!strcmp(name, ".strtab")) - strtabix = i; - else if (!strcmp(name, ".text") || !strcmp(name, ".rodata")) - symTypeTable[i] = N_TEXT; - else if (!strcmp(name, ".data") || !strcmp(name, ".sdata") || - !strcmp(name, ".lit4") || !strcmp(name, ".lit8")) - symTypeTable[i] = N_DATA; - else if (!strcmp(name, ".bss") || !strcmp(name, ".sbss")) - symTypeTable[i] = N_BSS; - } - - /* - * Figure out if we can cram the program header into an a.out - * header... Basically, we can't handle anything but loadable - * segments, but we can ignore some kinds of segments. We can't - * handle holes in the address space, and we handle start addresses - * other than 0x1000 by hoping that the loader will know where to - * load - a.out doesn't have an explicit load address. Segments may - * be out of order, so we sort them first. - */ - qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp); - for (i = 0; i < ex.e_phnum; i++) { - /* Section types we can ignore... */ - if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE || - ph[i].p_type == PT_PHDR || ph[i].p_type == PT_MIPS_REGINFO) - continue; - /* Section types we can't handle... */ - else if (ph[i].p_type != PT_LOAD) { - fprintf(stderr, - "Program header %d type %d can't be converted.\n", - i, ph[i].p_type); - exit(1); - } - /* Writable (data) segment? */ - if (ph[i].p_flags & PF_W) { - struct sect ndata, nbss; - - ndata.vaddr = ph[i].p_vaddr; - ndata.len = ph[i].p_filesz; - nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz; - nbss.len = ph[i].p_memsz - ph[i].p_filesz; - - combine(&data, &ndata, 0); - combine(&bss, &nbss, 1); - } else { - struct sect ntxt; - - ntxt.vaddr = ph[i].p_vaddr; - ntxt.len = ph[i].p_filesz; - - combine(&text, &ntxt); - } - /* Remember the lowest segment start address. */ - if (ph[i].p_vaddr < cur_vma) - cur_vma = ph[i].p_vaddr; - } - - /* Sections must be in order to be converted... */ - if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr || - text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr) { - fprintf(stderr, "Sections ordering prevents a.out conversion.\n"); - exit(1); - } - /* - * If there's a data section but no text section, then the loader - * combined everything into one section. That needs to be the text - * section, so just make the data section zero length following text. - */ - if (data.len && !text.len) { - text = data; - data.vaddr = text.vaddr + text.len; - data.len = 0; - } - /* - * If there is a gap between text and data, we'll fill it when we - * copy the data, so update the length of the text segment as - * represented in a.out to reflect that, since a.out doesn't allow - * gaps in the program address space. - */ - if (text.vaddr + text.len < data.vaddr) - text.len = data.vaddr - text.vaddr; - - /* We now have enough information to cons up an a.out header... */ - aex.a_midmag = htonl((symflag << 26) | (MID_PMAX << 16) | OMAGIC); - aex.a_text = text.len; - aex.a_data = data.len; - aex.a_bss = bss.len; - aex.a_entry = ex.e_entry; - aex.a_syms = (sizeof(struct nlist) * - (symtabix != -1 - ? sh[symtabix].sh_size / sizeof(struct sym) : 0)); - aex.a_trsize = 0; - aex.a_drsize = 0; - - /* Make the output file... */ - if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) { - fprintf(stderr, "Unable to create %s: %s\n", argv[2], strerror(errno)); - exit(1); - } - /* Write the header... */ - i = write(outfile, &aex, sizeof aex); - if (i != sizeof aex) { - perror("aex: write"); - exit(1); - } - /* - * Copy the loadable sections. Zero-fill any gaps less than 64k; - * complain about any zero-filling, and die if we're asked to - * zero-fill more than 64k. - */ - for (i = 0; i < ex.e_phnum; i++) { - /* - * Unprocessable sections were handled above, so just verify - * that the section can be loaded before copying. - */ - if (ph[i].p_type == PT_LOAD && ph[i].p_filesz) { - if (cur_vma != ph[i].p_vaddr) { - unsigned long gap = ph[i].p_vaddr - cur_vma; - char obuf[1024]; - - if (gap > 65536) { - fprintf(stderr, - "Intersegment gap (%d bytes) too large.\n", - gap); - exit(1); - } - fprintf(stderr, - "Warning: %d byte intersegment gap.\n", gap); - memset(obuf, 0, sizeof obuf); - while (gap) { - int count = write(outfile, obuf, - (gap > sizeof obuf ? sizeof obuf : gap)); - if (count < 0) { - fprintf(stderr, - "Error writing gap: %s\n", - strerror(errno)); - exit(1); - } - gap -= count; - } - } - copy(outfile, infile, ph[i].p_offset, ph[i].p_filesz); - cur_vma = ph[i].p_vaddr + ph[i].p_filesz; - } - } - - /* Copy and translate the symbol table... */ - translate_syms(outfile, infile, sh[symtabix].sh_offset, - sh[symtabix].sh_size, - sh[strtabix].sh_offset, sh[strtabix].sh_size); - - /* Looks like we won... */ - exit(0); -} - -/* - * translate_syms (out, in, offset, size) - * - * Read the ELF symbol table from in at offset; translate it into a.out nlist - * format and write it to out. - */ - -translate_syms(int out, int in, off_t symoff, off_t symsize, off_t stroff, - off_t strsize) -{ -#define SYMS_PER_PASS 64 - struct sym inbuf[64]; - struct nlist outbuf[64]; - int i, remaining, cur; - char *oldstrings; - char *newstrings, *nsp; - int newstringsize; - - /* Zero the unused fields in the output buffer.. */ - memset(outbuf, 0, sizeof outbuf); - - /* Find number of symbols to process... */ - remaining = symsize / sizeof(struct sym); - - /* Suck in the old string table... */ - oldstrings = saveRead(in, stroff, strsize, "string table"); - - /* - * Allocate space for the new one. XXX We make the wild assumption - * that no two symbol table entries will point at the same place in - * the string table - if that assumption is bad, this could easily - * blow up. - */ - newstringsize = strsize + remaining; - newstrings = (char *) malloc(newstringsize); - if (!newstrings) { - fprintf(stderr, "No memory for new string table!\n"); - exit(1); - } - /* Initialize the table pointer... */ - nsp = newstrings; - - /* Go to the start of the ELF symbol table... */ - if (lseek(in, symoff, SEEK_SET) < 0) { - perror("translate_syms: lseek"); - exit(1); - } - /* Translate and copy symbols... */ - while (remaining) { - cur = remaining; - if (cur > SYMS_PER_PASS) - cur = SYMS_PER_PASS; - remaining -= cur; - if ((i = read(in, inbuf, cur * sizeof(struct sym))) - != cur * sizeof(struct sym)) { - if (i < 0) - perror("translate_syms"); - else - fprintf(stderr, - "translate_syms: premature end of file.\n"); - exit(1); - } - /* Do the translation... */ - for (i = 0; i < cur; i++) { - /* - * Copy the symbol into the new table, but prepend an - * underscore. - */ - *nsp = '_'; - strcpy(nsp + 1, oldstrings + inbuf[i].name); - outbuf[i].n_un.n_strx = nsp - newstrings + 4; - nsp += strlen(nsp) + 1; - - /* - * Convert ELF symbol type/section/etc info into - * a.out type info. - */ - if (inbuf[i].type == STT_FILE) - outbuf[i].n_type = N_FN; - else if (inbuf[i].shndx == SHN_UNDEF) - outbuf[i].n_type = N_UNDF; - else if (inbuf[i].shndx == SHN_ABS) - outbuf[i].n_type = N_ABS; - else if (inbuf[i].shndx == SHN_COMMON || - inbuf[i].shndx == SHN_MIPS_ACOMMON) - outbuf[i].n_type = N_COMM; - else - outbuf[i].n_type = symTypeTable[inbuf[i].shndx]; - if (inbuf[i].binding == STB_GLOBAL) - outbuf[i].n_type |= N_EXT; - /* Symbol values in executables should be compatible. */ - outbuf[i].n_value = inbuf[i].value; - } - /* Write out the symbols... */ - if ((i = write(out, outbuf, cur * sizeof(struct nlist))) - != cur * sizeof(struct nlist)) { - fprintf(stderr, "translate_syms: write: %s\n", strerror(errno)); - exit(1); - } - } - /* Write out the string table length... */ - if (write(out, &newstringsize, sizeof newstringsize) - != sizeof newstringsize) { - fprintf(stderr, - "translate_syms: newstringsize: %s\n", strerror(errno)); - exit(1); - } - /* Write out the string table... */ - if (write(out, newstrings, newstringsize) != newstringsize) { - fprintf(stderr, "translate_syms: newstrings: %s\n", strerror(errno)); - exit(1); - } -} - -copy(int out, int in, off_t offset, off_t size) -{ - char ibuf[4096]; - int remaining, cur, count; - - /* Go to the start of the ELF symbol table... */ - if (lseek(in, offset, SEEK_SET) < 0) { - perror("copy: lseek"); - exit(1); - } - remaining = size; - while (remaining) { - cur = remaining; - if (cur > sizeof ibuf) - cur = sizeof ibuf; - remaining -= cur; - if ((count = read(in, ibuf, cur)) != cur) { - fprintf(stderr, "copy: read: %s\n", - count ? strerror(errno) : "premature end of file"); - exit(1); - } - if ((count = write(out, ibuf, cur)) != cur) { - perror("copy: write"); - exit(1); - } - } -} - -/* - * Combine two segments, which must be contiguous. If pad is true, it's - * okay for there to be padding between. - */ -combine(struct sect * base, struct sect * new, int pad) -{ - if (!base->len) - *base = *new; - else if (new->len) { - if (base->vaddr + base->len != new->vaddr) { - if (pad) - base->len = new->vaddr - base->vaddr; - else { - fprintf(stderr, - "Non-contiguous data can't be converted.\n"); - exit(1); - } - } - base->len += new->len; - } -} - -phcmp(struct phdr * h1, struct phdr * h2) -{ - if (h1->vaddr > h2->vaddr) - return 1; - else if (h1->vaddr < h2->vaddr) - return -1; - else - return 0; -} - -char * -saveRead(int file, off_t offset, off_t len, char *name) -{ - char *tmp; - int count; - off_t off; - - if ((off = lseek(file, offset, SEEK_SET)) < 0) { - fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno)); - exit(1); - } - if (!(tmp = (char *) malloc(len))) { - fprintf(stderr, "%s: Can't allocate %d bytes.\n", name, len); - exit(1); - } - count = read(file, tmp, len); - if (count != len) { - fprintf(stderr, "%s: read: %s.\n", - name, count ? strerror(errno) : "End of file reached"); - exit(1); - } - return tmp; -} diff --git a/usr.bin/elf2ecoff/Makefile b/usr.bin/elf2ecoff/Makefile deleted file mode 100644 index aa6c01ba0ba..00000000000 --- a/usr.bin/elf2ecoff/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# $OpenBSD: Makefile,v 1.1 1996/10/02 21:52:32 pefo Exp $ - -PROG= elf2ecoff - -.include <bsd.prog.mk> diff --git a/usr.bin/elf2ecoff/elf2ecoff.1 b/usr.bin/elf2ecoff/elf2ecoff.1 deleted file mode 100644 index beb41260ff6..00000000000 --- a/usr.bin/elf2ecoff/elf2ecoff.1 +++ /dev/null @@ -1,53 +0,0 @@ -.\" $OpenBSD: elf2ecoff.1,v 1.10 2007/05/31 19:20:09 jmc Exp $ -.\" -.\" Copyright (c) 1996 Per Fogelstrom -.\" -.\" 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. -.\" -.\" 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. -.\" -.\" -.Dd $Mdocdate: May 31 2007 $ -.Dt ELF2ECOFF 1 -.Os -.Sh NAME -.Nm elf2ecoff -.Nd convert ELF executable to ecoff format -.Sh SYNOPSIS -.Nm elf2ecoff -.Ar elfexec -.Ar ecoffexec -.Sh DESCRIPTION -.Nm -reads and converts the file specified as -.Ar elfexec -to ecoff format, into file -.Ar ecoffexec , -suitable for bootstrapping certain -.Nm MIPS -systems. -Systems requiring this conversion are the -.Nm arc -and -.Nm pmax . -.Sh DIAGNOSTICS -If the conversion fails a diagnostic message is printed to explain the cause. -.Sh BUGS -Does not preserve the symbol table. diff --git a/usr.bin/elf2ecoff/elf2ecoff.c b/usr.bin/elf2ecoff/elf2ecoff.c deleted file mode 100644 index cc2923a32cc..00000000000 --- a/usr.bin/elf2ecoff/elf2ecoff.c +++ /dev/null @@ -1,417 +0,0 @@ -/* $OpenBSD: elf2ecoff.c,v 1.6 2005/12/21 01:40:24 millert Exp $ */ -/* $NetBSD: elf2ecoff.c,v 1.8 1997/07/20 03:50:54 jonathan Exp $ */ - -/* - * Copyright (c) 1997 Jonathan Stone - * All rights reserved. - * Copyright (c) 1995 - * Ted Lemon (hereinafter referred to as the author) - * - * 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. 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. - */ - -/* - * elf2ecoff.c - * - * This program converts an elf executable to an ECOFF executable. No symbol - * table is retained. This is useful primarily in building net-bootable - * kernels for machines (e.g., DECstation and Alpha) which only support the - * ECOFF object file format. - */ - -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <elf_abi.h> -#include <machine/elf_abi.h> -#include <stdio.h> -#include <sys/exec_ecoff.h> -#include <errno.h> -#include <string.h> -#include <limits.h> - -extern char *__progname; - -struct sect { - unsigned long vaddr; - unsigned long len; -}; - -int phcmp(); -char *saveRead(int file, off_t offset, off_t len, char *name); -int copy(int, int, off_t, off_t); -int translate_syms(int, int, off_t, off_t, off_t, off_t); -int *symTypeTable; - -int -main(int argc, char *argv[]) -{ - Elf32_Ehdr ex; - Elf32_Phdr *ph; - Elf32_Shdr *sh; - struct sym *symtab; - char *shstrtab; - int strtabix, symtabix; - int i, pad; - struct sect text, data, bss; - struct ecoff_exechdr eh; - struct ecoff_scnhdr esecs[3]; - int infile, outfile; - unsigned long cur_vma = ULONG_MAX; - - text.len = data.len = bss.len = 0; - text.vaddr = data.vaddr = bss.vaddr = 0; - - /* Check args... */ - if (argc < 3 || argc > 4) { -usage: - fprintf(stderr, - "usage: %s <elf executable> <ecoff executable>\n", __progname); - exit(1); - } - /* Try the input file... */ - if ((infile = open(argv[1], O_RDONLY)) < 0) { - fprintf(stderr, "Can't open %s for read: %s\n", - argv[1], strerror(errno)); - exit(1); - } - /* Read the header, which is at the beginning of the file... */ - i = read(infile, &ex, sizeof ex); - if (i != sizeof ex) { - fprintf(stderr, "ex: %s: %s.\n", - argv[1], i ? strerror(errno) : "End of file reached"); - exit(1); - } - /* Read the program headers... */ - ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff, - ex.e_phnum * sizeof(Elf32_Phdr), "ph"); - /* Read the section headers... */ - sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff, - ex.e_shnum * sizeof(Elf32_Shdr), "sh"); - /* Read in the section string table. */ - shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset, - sh[ex.e_shstrndx].sh_size, "shstrtab"); - - /* - * Figure out if we can cram the program header into an ECOFF - * header... Basically, we can't handle anything but loadable - * segments, but we can ignore some kinds of segments. We can't - * handle holes in the address space. Segments may be out of order, - * so we sort them first. - */ - - qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp); - - for (i = 0; i < ex.e_phnum; i++) { - /* Section types we can ignore... */ - if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE || - ph[i].p_type == PT_PHDR || ph[i].p_type == PT_MIPS_REGINFO) - continue; - /* Section types we can't handle... */ - else if (ph[i].p_type != PT_LOAD) { - fprintf(stderr, - "Program header %d type %d can't be converted.\n", - i, ph[i].p_type); - exit(1); - } - /* Writable (data) segment? */ - if (ph[i].p_flags & PF_W) { - struct sect ndata, nbss; - - ndata.vaddr = ph[i].p_vaddr; - ndata.len = ph[i].p_filesz; - nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz; - nbss.len = ph[i].p_memsz - ph[i].p_filesz; - - combine(&data, &ndata, 0); - combine(&bss, &nbss, 1); - } else { - struct sect ntxt; - - ntxt.vaddr = ph[i].p_vaddr; - ntxt.len = ph[i].p_filesz; - combine(&text, &ntxt); - } - /* Remember the lowest segment start address. */ - if (ph[i].p_vaddr < cur_vma) - cur_vma = ph[i].p_vaddr; - } - - /* Sections must be in order to be converted... */ - if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr || - text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr) { - fprintf(stderr, "Sections ordering prevents a.out conversion.\n"); - exit(1); - } - /* - * If there's a data section but no text section, then the loader - * combined everything into one section. That needs to be the text - * section, so just make the data section zero length following text. - */ - if (data.len && !text.len) { - text = data; - data.vaddr = text.vaddr + text.len; - data.len = 0; - } - /* - * If there is a gap between text and data, we'll fill it when we - * copy the data, so update the length of the text segment as - * represented in a.out to reflect that, since a.out doesn't allow - * gaps in the program address space. - */ - if (text.vaddr + text.len < data.vaddr) - text.len = data.vaddr - text.vaddr; - - /* We now have enough information to cons up an a.out header... */ - eh.a.magic = ECOFF_OMAGIC; - eh.a.vstamp = 200; - eh.a.tsize = text.len; - eh.a.dsize = data.len; - eh.a.bsize = bss.len; - eh.a.entry = ex.e_entry; - eh.a.text_start = text.vaddr; - eh.a.data_start = data.vaddr; - eh.a.bss_start = bss.vaddr; - eh.a.ea_gprmask = 0xf3fffffe; - bzero(&eh.a.ea_cprmask, sizeof eh.a.ea_cprmask); - eh.a.ea_gp_value = 0; /* unused. */ - - eh.f.f_magic = ECOFF_MAGIC_MIPSEL; - eh.f.f_nscns = 3; - eh.f.f_timdat = 0; /* bogus */ - eh.f.f_symptr = 0; - eh.f.f_nsyms = 0; - eh.f.f_opthdr = sizeof eh.a; - eh.f.f_flags = 0x100f; /* Stripped, not sharable. */ - - strlcpy(esecs[0].s_name, ".text", sizeof(esecs[0].s_name)); - strlcpy(esecs[1].s_name, ".data", sizeof(esecs[0].s_name)); - strlcpy(esecs[2].s_name, ".bss", sizeof(esecs[0].s_name)); - esecs[0].s_paddr = esecs[0].s_vaddr = eh.a.text_start; - esecs[1].s_paddr = esecs[1].s_vaddr = eh.a.data_start; - esecs[2].s_paddr = esecs[2].s_vaddr = eh.a.bss_start; - esecs[0].s_size = eh.a.tsize; - esecs[1].s_size = eh.a.dsize; - esecs[2].s_size = eh.a.bsize; - esecs[0].s_scnptr = ECOFF_TXTOFF(&eh); - esecs[1].s_scnptr = ECOFF_DATOFF(&eh); - esecs[2].s_scnptr = esecs[1].s_scnptr + - ECOFF_ROUND(esecs[1].s_size, ECOFF_SEGMENT_ALIGNMENT(&eh)); - esecs[0].s_relptr = esecs[1].s_relptr = esecs[2].s_relptr = 0; - esecs[0].s_lnnoptr = esecs[1].s_lnnoptr = esecs[2].s_lnnoptr = 0; - esecs[0].s_nreloc = esecs[1].s_nreloc = esecs[2].s_nreloc = 0; - esecs[0].s_nlnno = esecs[1].s_nlnno = esecs[2].s_nlnno = 0; - esecs[0].s_flags = 0x20; - esecs[1].s_flags = 0x40; - esecs[2].s_flags = 0x82; - - /* Make the output file... */ - if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) { - fprintf(stderr, "Unable to create %s: %s\n", argv[2], strerror(errno)); - exit(1); - } - /* Write the headers... */ - i = write(outfile, &eh.f, sizeof(struct ecoff_filehdr)); - if (i != sizeof(struct ecoff_filehdr)) { - perror("efh: write"); - exit(1); - - for (i = 0; i < 6; i++) { - printf("Section %d: %s phys %x size %x file offset %x\n", - i, esecs[i].s_name, esecs[i].s_paddr, - esecs[i].s_size, esecs[i].s_scnptr); - } - } - fprintf(stderr, "wrote %d byte file header.\n", i); - - i = write(outfile, &eh.a, sizeof(struct ecoff_aouthdr)); - if (i != sizeof(struct ecoff_aouthdr)) { - perror("eah: write"); - exit(1); - } - fprintf(stderr, "wrote %d byte a.out header.\n", i); - - i = write(outfile, &esecs, sizeof esecs); - if (i != sizeof esecs) { - perror("esecs: write"); - exit(1); - } - fprintf(stderr, "wrote %d bytes of section headers.\n", i); - - if (pad = ((sizeof eh + sizeof esecs) & 15)) { - pad = 16 - pad; - i = write(outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad); - if (i < 0) { - perror("ipad: write"); - exit(1); - } - fprintf(stderr, "wrote %d byte pad.\n", i); - } - /* - * Copy the loadable sections. Zero-fill any gaps less than 64k; - * complain about any zero-filling, and die if we're asked to - * zero-fill more than 64k. - */ - for (i = 0; i < ex.e_phnum; i++) { - /* - * Unprocessable sections were handled above, so just verify - * that the section can be loaded before copying. - */ - if (ph[i].p_type == PT_LOAD && ph[i].p_filesz) { - if (cur_vma != ph[i].p_vaddr) { - unsigned long gap = ph[i].p_vaddr - cur_vma; - char obuf[1024]; - if (gap > 65536) { - fprintf(stderr, - "Intersegment gap (%d bytes) too large.\n", - gap); - exit(1); - } - fprintf(stderr, - "Warning: %d byte intersegment gap.\n", gap); - memset(obuf, 0, sizeof obuf); - while (gap) { - int count = write(outfile, obuf, - (gap > sizeof obuf - ? sizeof obuf : gap)); - if (count < 0) { - fprintf(stderr, - "Error writing gap: %s\n", - strerror(errno)); - exit(1); - } - gap -= count; - } - } - fprintf(stderr, "writing %d bytes...\n", ph[i].p_filesz); - copy(outfile, infile, ph[i].p_offset, ph[i].p_filesz); - cur_vma = ph[i].p_vaddr + ph[i].p_filesz; - } - } - - /* - * Write a page of padding for boot PROMS that read entire pages. - * Without this, they may attempt to read past the end of the - * data section, incur an error, and refuse to boot. - */ - { - char obuf[4096]; - memset(obuf, 0, sizeof obuf); - if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) { - fprintf(stderr, "Error writing PROM padding: %s\n", - strerror(errno)); - exit(1); - } - } - - /* Looks like we won... */ - exit(0); -} - -void -copy(int out, int in, off_t offset, off_t size) -{ - char ibuf[4096]; - int remaining, cur, count; - - /* Go to the start of the ELF symbol table... */ - if (lseek(in, offset, SEEK_SET) < 0) { - perror("copy: lseek"); - exit(1); - } - remaining = size; - while (remaining) { - cur = remaining; - if (cur > sizeof ibuf) - cur = sizeof ibuf; - remaining -= cur; - if ((count = read(in, ibuf, cur)) != cur) { - fprintf(stderr, "copy: read: %s\n", - count ? strerror(errno) : "premature end of file"); - exit(1); - } - if ((count = write(out, ibuf, cur)) != cur) { - perror("copy: write"); - exit(1); - } - } -} - -/* - * Combine two segments, which must be contiguous. If pad is true, it's - * okay for there to be padding between. - */ -void -combine(struct sect *base, struct sect *new, int pad) -{ - if (!base->len) - *base = *new; - else if (new->len) { - if (base->vaddr + base->len != new->vaddr) { - if (pad) - base->len = new->vaddr - base->vaddr; - else { - fprintf(stderr, - "Non-contiguous data can't be converted.\n"); - exit(1); - } - } - base->len += new->len; - } -} - -int -phcmp(Elf32_Phdr *h1, Elf32_Phdr *h2) -{ - if (h1->p_vaddr > h2->p_vaddr) - return 1; - else if (h1->p_vaddr < h2->p_vaddr) - return -1; - else - return 0; -} - -char * -saveRead(int file, off_t offset, off_t len, char *name) -{ - char *tmp; - int count; - off_t off; - - if ((off = lseek(file, offset, SEEK_SET)) < 0) { - fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno)); - exit(1); - } - if (!(tmp = (char *) malloc(len))) { - fprintf(stderr, "%s: Can't allocate %d bytes.\n", name, len); - exit(1); - } - count = read(file, tmp, len); - if (count != len) { - fprintf(stderr, "%s: read: %s.\n", - name, count ? strerror(errno) : "End of file reached"); - exit(1); - } - return tmp; -} |