Annotation of src/usr.bin/elf2olf/elf2olf.c, Revision 1.6
1.6 ! mpech 1: /* $OpenBSD: elf2olf.c,v 1.5 2001/07/12 05:17:01 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.6 ! mpech 33: static char rcsid[] = "@(#) $Id: elf2olf.c,v 1.5 2001/07/12 05:17:01 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:
1.5 deraadt 62: void usage(void);
63: void pwarn(char *, char *, int);
64:
1.1 etheisen 65: int
66: main(int argc, char*argv[])
67: {
68: extern char *optarg;
69: extern int optind;
1.6 ! mpech 70: int ch, i, okay;
1.1 etheisen 71: char *opstring;
72:
1.6 ! mpech 73: int fd;
1.1 etheisen 74: struct stat st;
75: Elf32_Ehdr ehdr;
76: Elf32_Shdr shdr;
77: int e;
78:
1.5 deraadt 79: if ((progname = strrchr(*argv, '/')))
1.1 etheisen 80: ++progname;
81: else
82: progname = *argv;
83:
84: if (strstr(progname, "olf2elf"))
85: olf2elf = 1;
86:
87: /*
88: * Process cmdline
89: */
90: opstring = olf2elf ? "v" : "vo:";
1.4 millert 91: while((ch = getopt(argc, argv, opstring)) != -1)
1.1 etheisen 92: switch(ch) {
93: case 'v':
94: verbose = 1;
95: break;
96: case 'o':
97: for (i = 1; i <= OOS_NUM; i++) {
98: if (os_namev[i] == NULL) {
99: fprintf(stderr,
100: "%s: illegal -o argument -- %s\n",
101: progname, optarg);
102: usage();
103: }
104: else if (strcmp(optarg, os_namev[i]) == 0) {
105: opsys = i;
106: break;
107: }
108: }
109: break;
110: default:
111: usage();
112: }
113: argc -= optind;
114: argv += optind;
115:
116: if (argc == 0)
117: usage();
118:
119: /*
120: * Process file(s)
121: */
122: do {
123: okay = 0;
124:
125: if ((fd = open(*argv, O_RDWR | O_EXLOCK, 0)) > 0 &&
126: lseek(fd, (off_t)0, SEEK_SET) == 0 &&
127: fstat(fd, &st) == 0) {
128:
129: /* Make sure this is a 32bit ELF or OLF version 1 file */
130: if (read(fd, &ehdr, sizeof(Elf32_Ehdr)) == sizeof(Elf32_Ehdr)&&
131: (IS_ELF(ehdr) || IS_OLF(ehdr)) &&
132: ehdr.e_ident[EI_CLASS] == ELFCLASS32 &&
133: ehdr.e_ident[EI_VERSION] == 1) {
134:
135: /* Is this elf2olf? */
136: if(!olf2elf) {
137:
138: /* Tag, your it... */
139: ehdr.e_ident[OI_MAG0] = OLFMAG0;
140: ehdr.e_ident[OI_MAG1] = OLFMAG1;
141: ehdr.e_ident[OI_MAG2] = OLFMAG2;
142: ehdr.e_ident[OI_MAG3] = OLFMAG3;
143: ehdr.e_ident[OI_OS] = opsys;
144: ehdr.e_ident[OI_DYNAMIC] = ODYNAMIC_N;
145: ehdr.e_ident[OI_STRIP] = OSTRIP;
146:
147: /* We'll need this endian */
148: e = ehdr.e_ident[EI_DATA];
149:
150: /* Now we need to figure out wether or */
151: /* not we're really stripped. */
152: if (lseek(fd, (off_t)word(ehdr.e_shoff, e),
153: SEEK_SET) == word(ehdr.e_shoff, e)) {
154:
155: /*
156: * search through section header table
157: * looking for a section header of type
158: * SHT_SYMTAB and SHT_DYNAMIC. If there is
159: * one present we're NOT stripped and/or
160: * dynamic.
161: */
162: for (i = 0; i < half(ehdr.e_shnum, e); i++) {
163: if (read(fd, &shdr, sizeof(Elf32_Shdr)) == sizeof(Elf32_Shdr)){
164: if (word(shdr.sh_type, e) == SHT_SYMTAB)
165: ehdr.e_ident[OI_STRIP] = OSTRIP_N;
166: else if (word(shdr.sh_type, e) == SHT_DYNAMIC)
167: ehdr.e_ident[OI_DYNAMIC] = ODYNAMIC;
168: } else
1.5 deraadt 169: pwarn(progname, *argv, errno);
1.1 etheisen 170: } /* while less than number of section headers */
171:
172: /* We're ready to modify */
173: okay = 1;
174:
175: } else /* Bogus section header table seek */
1.5 deraadt 176: pwarn(progname, *argv, errno);
1.1 etheisen 177:
178: } else { /* olf2elf */
179: ehdr.e_ident[EI_MAG0] = ELFMAG0;
180: ehdr.e_ident[EI_MAG1] = ELFMAG1;
181: ehdr.e_ident[EI_MAG2] = ELFMAG2;
182: ehdr.e_ident[EI_MAG3] = ELFMAG3;
183: ehdr.e_ident[OI_OS] = 0;
184: ehdr.e_ident[OI_DYNAMIC] = 0;
185: ehdr.e_ident[OI_STRIP] = 0;
186:
187: okay = 1;
188: } /* olf2elf */
189: } else /* Bogus non-ELF file encountered */
1.5 deraadt 190: pwarn(progname, *argv, ENOEXEC);
1.1 etheisen 191:
192: /*
193: * Do It.
194: */
195: if (okay) {
196: if (lseek(fd, (off_t)0, SEEK_SET) == 0) {
197: if (write(fd, &ehdr, sizeof(Elf32_Ehdr)) == sizeof(Elf32_Ehdr)) {
198: if (verbose) {
199: if (!olf2elf) {
1.2 etheisen 200: printf("ELF %s => OLF %d-bit %s %s linked %s OLF.\n",
201: *argv,
202: (ehdr.e_ident[OI_CLASS] == OLFCLASS32)?\
203: 32 : 64,
204: os_namev[ehdr.e_ident[OI_OS]],
205: ehdr.e_ident[OI_DYNAMIC] ? \
206: "dynamically" : "statically",
207: !ehdr.e_ident[OI_STRIP] ?
208: "stripped" : "unstripped");
1.1 etheisen 209: } else
1.2 etheisen 210: printf("OLF %s => ELF.\n", *argv);
1.1 etheisen 211: }
212: } else /* bad write */
1.5 deraadt 213: pwarn(progname, *argv, errno);
1.1 etheisen 214: } else /* bad seek */
1.5 deraadt 215: pwarn(progname, *argv, errno);
1.1 etheisen 216: } /* okay? */
217: fsync(fd);
218: close(fd);
219:
220: } else /* couldn't handle file */
1.5 deraadt 221: pwarn(progname, *argv, errno);
1.1 etheisen 222: } while (*(++argv) != NULL);
223:
224:
225: return (retval);
226: }
227:
1.5 deraadt 228: void
229: pwarn(name, fname, errval)
1.1 etheisen 230: char *name;
231: char *fname;
232: int errval;
233: {
234: fprintf(stderr, "%s: %s: %s.\n", name, fname, strerror(errval));
235: retval = 1;
236: }
237:
1.5 deraadt 238: void
1.1 etheisen 239: usage()
240: {
1.6 ! mpech 241: int i;
1.3 deraadt 242: int col = 8;
1.1 etheisen 243:
244: if (olf2elf) {
245: fprintf(stderr, "usage: %s [-v] file ...\n", progname);
246: } else {
247: fprintf(stderr, "usage: %s [-v] [-o opsys] elffile ...\n", progname);
1.3 deraadt 248: fprintf(stderr, "where opsys is:\n\t");
249: for (i = 1; os_namev[i] != NULL; i++) {
250: col = col + strlen(os_namev[i]) + 2;
251: if (col > 78) {
252: fprintf(stderr, "\n\t");
253: col = 8;
254: }
255: fprintf(stderr, "%s%s", os_namev[i],
256: os_namev[i+1] ? ", " : "\n");
257: }
1.1 etheisen 258: }
259: exit(1);
260: }
261:
262: