Annotation of src/usr.bin/elf2olf/elf2olf.c, Revision 1.1
1.1 ! etheisen 1: /* $OpenBSD$ */
! 2: /*
! 3: * Copyright (c) 1996 Erik Theisen. All rights reserved.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: * 3. The name of the author may not be used to endorse or promote products
! 14: * derived from this software without specific prior written permission
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 19: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 21: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 22: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 23: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 24: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 25: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 26: */
! 27: #ifndef lint
! 28: static char copyright[] =
! 29: "@(#) Copyright (c) 1996 Erik Theisen. All rights reserved.\n";
! 30: #endif /* not lint */
! 31:
! 32: #ifndef lint
! 33: static char rcsid[] = "@(#) $Id$";
! 34: #endif
! 35:
! 36: #include <stdlib.h>
! 37: #include <stdio.h>
! 38: #include <string.h>
! 39: #include <fcntl.h>
! 40: #include <errno.h>
! 41: #include <unistd.h>
! 42:
! 43: #include <sys/types.h>
! 44: #include <sys/uio.h>
! 45: #include <sys/stat.h>
! 46: #include <sys/param.h>
! 47:
! 48: #include <olf_abi.h>
! 49:
! 50: int retval = 0;
! 51: int olf2elf;
! 52: char *progname;
! 53: int verbose;
! 54: int opsys = OS_ID;
! 55:
! 56: char *os_namev[] = ONAMEV;
! 57:
! 58: /* Handle endianess */
! 59: #define word(x,y)((y == ELFDATA2LSB) ? ntohl(htonl(x)) : ntohl(x))
! 60: #define half(x,y)((y == ELFDATA2LSB) ? ntohs(htons(x)) : ntohs(x))
! 61:
! 62: int
! 63: main(int argc, char*argv[])
! 64: {
! 65: extern char *optarg;
! 66: extern int optind;
! 67: register int ch, i, okay;
! 68: char *opstring;
! 69:
! 70: register int fd;
! 71: struct stat st;
! 72: Elf32_Ehdr ehdr;
! 73: Elf32_Shdr shdr;
! 74: int e;
! 75:
! 76: if (progname = strrchr(*argv, '/'))
! 77: ++progname;
! 78: else
! 79: progname = *argv;
! 80:
! 81: if (strstr(progname, "olf2elf"))
! 82: olf2elf = 1;
! 83:
! 84: /*
! 85: * Process cmdline
! 86: */
! 87: opstring = olf2elf ? "v" : "vo:";
! 88: while((ch = getopt(argc, argv, opstring)) != EOF)
! 89: switch(ch) {
! 90: case 'v':
! 91: verbose = 1;
! 92: break;
! 93: case 'o':
! 94: for (i = 1; i <= OOS_NUM; i++) {
! 95: if (os_namev[i] == NULL) {
! 96: fprintf(stderr,
! 97: "%s: illegal -o argument -- %s\n",
! 98: progname, optarg);
! 99: usage();
! 100: }
! 101: else if (strcmp(optarg, os_namev[i]) == 0) {
! 102: opsys = i;
! 103: break;
! 104: }
! 105: }
! 106: break;
! 107: default:
! 108: usage();
! 109: }
! 110: argc -= optind;
! 111: argv += optind;
! 112:
! 113: if (argc == 0)
! 114: usage();
! 115:
! 116: /*
! 117: * Process file(s)
! 118: */
! 119: do {
! 120: okay = 0;
! 121:
! 122: if ((fd = open(*argv, O_RDWR | O_EXLOCK, 0)) > 0 &&
! 123: lseek(fd, (off_t)0, SEEK_SET) == 0 &&
! 124: fstat(fd, &st) == 0) {
! 125:
! 126: /* Make sure this is a 32bit ELF or OLF version 1 file */
! 127: if (read(fd, &ehdr, sizeof(Elf32_Ehdr)) == sizeof(Elf32_Ehdr)&&
! 128: (IS_ELF(ehdr) || IS_OLF(ehdr)) &&
! 129: ehdr.e_ident[EI_CLASS] == ELFCLASS32 &&
! 130: ehdr.e_ident[EI_VERSION] == 1) {
! 131:
! 132: /* Is this elf2olf? */
! 133: if(!olf2elf) {
! 134:
! 135: /* Tag, your it... */
! 136: ehdr.e_ident[OI_MAG0] = OLFMAG0;
! 137: ehdr.e_ident[OI_MAG1] = OLFMAG1;
! 138: ehdr.e_ident[OI_MAG2] = OLFMAG2;
! 139: ehdr.e_ident[OI_MAG3] = OLFMAG3;
! 140: ehdr.e_ident[OI_OS] = opsys;
! 141: ehdr.e_ident[OI_DYNAMIC] = ODYNAMIC_N;
! 142: ehdr.e_ident[OI_STRIP] = OSTRIP;
! 143:
! 144: /* We'll need this endian */
! 145: e = ehdr.e_ident[EI_DATA];
! 146:
! 147: /* Now we need to figure out wether or */
! 148: /* not we're really stripped. */
! 149: if (lseek(fd, (off_t)word(ehdr.e_shoff, e),
! 150: SEEK_SET) == word(ehdr.e_shoff, e)) {
! 151:
! 152: /*
! 153: * search through section header table
! 154: * looking for a section header of type
! 155: * SHT_SYMTAB and SHT_DYNAMIC. If there is
! 156: * one present we're NOT stripped and/or
! 157: * dynamic.
! 158: */
! 159: for (i = 0; i < half(ehdr.e_shnum, e); i++) {
! 160: if (read(fd, &shdr, sizeof(Elf32_Shdr)) == sizeof(Elf32_Shdr)){
! 161: if (word(shdr.sh_type, e) == SHT_SYMTAB)
! 162: ehdr.e_ident[OI_STRIP] = OSTRIP_N;
! 163: else if (word(shdr.sh_type, e) == SHT_DYNAMIC)
! 164: ehdr.e_ident[OI_DYNAMIC] = ODYNAMIC;
! 165: } else
! 166: warn(progname, *argv, errno);
! 167: } /* while less than number of section headers */
! 168:
! 169: /* We're ready to modify */
! 170: okay = 1;
! 171:
! 172: } else /* Bogus section header table seek */
! 173: warn(progname, *argv, errno);
! 174:
! 175: } else { /* olf2elf */
! 176: ehdr.e_ident[EI_MAG0] = ELFMAG0;
! 177: ehdr.e_ident[EI_MAG1] = ELFMAG1;
! 178: ehdr.e_ident[EI_MAG2] = ELFMAG2;
! 179: ehdr.e_ident[EI_MAG3] = ELFMAG3;
! 180: ehdr.e_ident[OI_OS] = 0;
! 181: ehdr.e_ident[OI_DYNAMIC] = 0;
! 182: ehdr.e_ident[OI_STRIP] = 0;
! 183:
! 184: okay = 1;
! 185: } /* olf2elf */
! 186: } else /* Bogus non-ELF file encountered */
! 187: warn(progname, *argv, ENOEXEC);
! 188:
! 189: /*
! 190: * Do It.
! 191: */
! 192: if (okay) {
! 193: if (lseek(fd, (off_t)0, SEEK_SET) == 0) {
! 194: if (write(fd, &ehdr, sizeof(Elf32_Ehdr)) == sizeof(Elf32_Ehdr)) {
! 195: if (verbose) {
! 196: if (!olf2elf) {
! 197: printf("%s ELF => %s %s %s OLF.\n",
! 198: *argv, *argv,
! 199: ehdr.e_ident[OI_STRIP] ? \
! 200: "stripped" : "unstripped",
! 201: os_namev[ehdr.e_ident[OI_OS]]);
! 202: } else
! 203: printf("%s OLF => %s ELF.\n", *argv, *argv);
! 204: }
! 205: } else /* bad write */
! 206: warn(progname, *argv, errno);
! 207: } else /* bad seek */
! 208: warn(progname, *argv, errno);
! 209: } /* okay? */
! 210: fsync(fd);
! 211: close(fd);
! 212:
! 213: } else /* couldn't handle file */
! 214: warn(progname, *argv, errno);
! 215: } while (*(++argv) != NULL);
! 216:
! 217:
! 218: return (retval);
! 219: }
! 220:
! 221: warn(name, fname, errval)
! 222: char *name;
! 223: char *fname;
! 224: int errval;
! 225: {
! 226: fprintf(stderr, "%s: %s: %s.\n", name, fname, strerror(errval));
! 227: retval = 1;
! 228: }
! 229:
! 230: usage()
! 231: {
! 232: register int i;
! 233:
! 234: if (olf2elf) {
! 235: fprintf(stderr, "usage: %s [-v] file ...\n", progname);
! 236: } else {
! 237: fprintf(stderr, "usage: %s [-v] [-o opsys] elffile ...\n", progname);
! 238: fprintf(stderr, "where opsys is:\n");
! 239: for (i = 1; os_namev[i] != NULL; i++)
! 240: fprintf(stderr, "\t%s\n", os_namev[i]);
! 241: }
! 242: exit(1);
! 243: }
! 244:
! 245: