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