Annotation of src/usr.bin/elf2olf/elf2olf.c, Revision 1.4
1.4 ! millert 1: /* $OpenBSD: elf2olf.c,v 1.3 1996/12/09 07:10:14 deraadt Exp $ */
1.1 etheisen 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
1.4 ! millert 33: static char rcsid[] = "@(#) $Id: elf2olf.c,v 1.3 1996/12/09 07:10:14 deraadt Exp $";
1.1 etheisen 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:";
1.4 ! millert 88: while((ch = getopt(argc, argv, opstring)) != -1)
1.1 etheisen 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) {
1.2 etheisen 197: printf("ELF %s => OLF %d-bit %s %s linked %s OLF.\n",
198: *argv,
199: (ehdr.e_ident[OI_CLASS] == OLFCLASS32)?\
200: 32 : 64,
201: os_namev[ehdr.e_ident[OI_OS]],
202: ehdr.e_ident[OI_DYNAMIC] ? \
203: "dynamically" : "statically",
204: !ehdr.e_ident[OI_STRIP] ?
205: "stripped" : "unstripped");
1.1 etheisen 206: } else
1.2 etheisen 207: printf("OLF %s => ELF.\n", *argv);
1.1 etheisen 208: }
209: } else /* bad write */
210: warn(progname, *argv, errno);
211: } else /* bad seek */
212: warn(progname, *argv, errno);
213: } /* okay? */
214: fsync(fd);
215: close(fd);
216:
217: } else /* couldn't handle file */
218: warn(progname, *argv, errno);
219: } while (*(++argv) != NULL);
220:
221:
222: return (retval);
223: }
224:
225: warn(name, fname, errval)
226: char *name;
227: char *fname;
228: int errval;
229: {
230: fprintf(stderr, "%s: %s: %s.\n", name, fname, strerror(errval));
231: retval = 1;
232: }
233:
234: usage()
235: {
236: register int i;
1.3 deraadt 237: int col = 8;
1.1 etheisen 238:
239: if (olf2elf) {
240: fprintf(stderr, "usage: %s [-v] file ...\n", progname);
241: } else {
242: fprintf(stderr, "usage: %s [-v] [-o opsys] elffile ...\n", progname);
1.3 deraadt 243: fprintf(stderr, "where opsys is:\n\t");
244: for (i = 1; os_namev[i] != NULL; i++) {
245: col = col + strlen(os_namev[i]) + 2;
246: if (col > 78) {
247: fprintf(stderr, "\n\t");
248: col = 8;
249: }
250: fprintf(stderr, "%s%s", os_namev[i],
251: os_namev[i+1] ? ", " : "\n");
252: }
1.1 etheisen 253: }
254: exit(1);
255: }
256:
257: