1 /* $OpenBSD: exec_ecoff.c,v 1.9 2003/09/26 17:00:27 deraadt Exp $ */
2
3 /*
4 * Copyright (c) 1999 Mats O Jansson. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <err.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <nlist.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <sys/exec.h>
35 #include <sys/exec_ecoff.h>
36 #include <sys/types.h>
37
38 #include "config.h"
39 #include "ukc.h"
40
41 __RCSID("$MirOS: src/usr.sbin/config/exec_ecoff.c,v 1.3 2010/07/25 16:31:08 tg Exp $");
42
43 caddr_t ecoff_p, ecoff_r, ecoff_b;
44 int ecoff_psz = 0, ecoff_rsz = 0, ecoff_bsz = 0;
45 struct ecoff_exechdr ecoff_ex;
46
47 caddr_t
ecoff_adjust(caddr_t x)48 ecoff_adjust(caddr_t x)
49 {
50 unsigned long y;
51
52 y = (unsigned long)x - nl[P_KERNEL_TEXT].n_value + (unsigned long)ecoff_p;
53
54 return((caddr_t)y);
55 }
56
57 caddr_t
ecoff_readjust(caddr_t x)58 ecoff_readjust(caddr_t x)
59 {
60 unsigned long y;
61
62 y = (unsigned long)x - (unsigned long)ecoff_p + nl[P_KERNEL_TEXT].n_value;
63
64 return((caddr_t)y);
65 }
66
67 int
ecoff_check(char * file)68 ecoff_check(char *file)
69 {
70 int fd, ret = 1;
71
72 if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
73 return (0);
74
75 if (read(fd,(char *)&ecoff_ex, sizeof(ecoff_ex)) != sizeof(ecoff_ex))
76 ret = 0;
77
78 if (ret) {
79 if (ECOFF_BADMAG(&ecoff_ex))
80 ret = 0;
81 }
82
83 close(fd);
84 return (ret);
85 }
86
87 void
ecoff_loadkernel(const char * file)88 ecoff_loadkernel(const char *file)
89 {
90 int fd;
91 off_t beg, cur, end;
92
93 if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0)
94 err(1, "%s", file);
95
96 if (read(fd, (char *)&ecoff_ex, sizeof(ecoff_ex)) != sizeof(ecoff_ex))
97 errx(1, "can't read ecoff header");
98
99 if (ECOFF_BADMAG(&ecoff_ex))
100 errx(1, "bad ecoff magic");
101
102 ecoff_psz = ecoff_ex.a.tsize + ecoff_ex.a.dsize;
103 beg = lseek(fd, ECOFF_TXTOFF(&ecoff_ex), SEEK_SET);
104
105 ecoff_bsz = (int)beg;
106 ecoff_b = emalloc(ecoff_bsz);
107
108 ecoff_p = emalloc(ecoff_psz);
109
110 if (read(fd, ecoff_p, ecoff_psz) != ecoff_psz)
111 errx(1, "can't read ecoff text and data");
112
113 cur = lseek(fd, (off_t)0, SEEK_CUR);
114 end = lseek(fd, (off_t)0, SEEK_END);
115 (void)lseek(fd, (off_t)0, SEEK_SET);
116 if (read(fd, ecoff_b, ecoff_bsz) != ecoff_bsz)
117 errx(1, "can't read begining of file %s", file);
118 (void)lseek(fd, cur, SEEK_SET);
119
120 ecoff_rsz = (int)(end - cur);
121
122 ecoff_r = emalloc(ecoff_rsz);
123
124 if (read(fd, ecoff_r, ecoff_rsz) != ecoff_rsz)
125 errx(1, "can't read rest of file %s", file);
126
127 close(fd);
128 }
129
130 void
ecoff_savekernel(const char * outfile)131 ecoff_savekernel(const char *outfile)
132 {
133 int fd;
134
135 if ((fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0755)) < 0)
136 err(1, "%s", outfile);
137
138 if (write(fd, ecoff_b, ecoff_bsz) != ecoff_bsz)
139 errx(1, "can't write beginning of file %s",outfile);
140
141 if (write(fd, ecoff_p, ecoff_psz) != ecoff_psz)
142 errx(1, "can't write ecoff text and data");
143
144 if (write(fd, ecoff_r, ecoff_rsz) != ecoff_rsz)
145 errx(1, "can't write rest of file %s", outfile);
146
147 close(fd);
148 }
149