xref: /netbsd-src/sys/lib/libsa/loadfile_aout.c (revision 685add8053ab91f3b2bfbd5330add28aa15be33d)
1 /* $NetBSD: loadfile_aout.c,v 1.15 2014/02/20 00:29:03 joerg Exp $ */
2 
3 /*-
4  * Copyright (c) 1997 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center and by Christos Zoulas.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1992, 1993
35  *	The Regents of the University of California.  All rights reserved.
36  *
37  * This code is derived from software contributed to Berkeley by
38  * Ralph Campbell.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  *    notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  *    notice, this list of conditions and the following disclaimer in the
47  *    documentation and/or other materials provided with the distribution.
48  * 3. Neither the name of the University nor the names of its contributors
49  *    may be used to endorse or promote products derived from this software
50  *    without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62  * SUCH DAMAGE.
63  *
64  *	@(#)boot.c	8.1 (Berkeley) 6/10/93
65  */
66 
67 #ifdef _STANDALONE
68 #include <lib/libsa/stand.h>
69 #include <lib/libkern/libkern.h>
70 #else
71 #include <stdio.h>
72 #include <string.h>
73 #include <errno.h>
74 #include <stdlib.h>
75 #include <unistd.h>
76 #include <fcntl.h>
77 #include <err.h>
78 #endif
79 
80 #include <sys/param.h>
81 #include <sys/exec_aout.h>
82 
83 #include "loadfile.h"
84 
85 #ifdef BOOT_AOUT
86 
87 int
loadfile_aout(int fd,struct exec * x,u_long * marks,int flags)88 loadfile_aout(int fd, struct exec *x, u_long *marks, int flags)
89 {
90 	u_long entry = x->a_entry;
91 	paddr_t aoutp = 0;
92 	paddr_t minp, maxp;
93 	int cc;
94 	paddr_t offset = marks[MARK_START];
95 	u_long magic = N_GETMAGIC(*x);
96 	int sub;
97 	ssize_t nr;
98 
99 	/* some ports don't use the offset */
100 	(void)offset;
101 
102 	/* In OMAGIC and NMAGIC, exec header isn't part of text segment */
103 	if (magic == OMAGIC || magic == NMAGIC)
104 		sub = 0;
105 	else
106 		sub = sizeof(*x);
107 
108 	minp = maxp = ALIGNENTRY(entry);
109 
110 	if (lseek(fd, sizeof(*x), SEEK_SET) == -1)  {
111 		WARN(("lseek text"));
112 		return 1;
113 	}
114 
115 	/*
116 	 * Leave a copy of the exec header before the text.
117 	 * The kernel may use this to verify that the
118 	 * symbols were loaded by this boot program.
119 	 */
120 	if (magic == OMAGIC || magic == NMAGIC) {
121 		if (flags & LOAD_HDR && maxp >= sizeof(*x))
122 			BCOPY(x, maxp - sizeof(*x), sizeof(*x));
123 	}
124 	else {
125 		if (flags & LOAD_HDR)
126 			BCOPY(x, maxp, sizeof(*x));
127 		if (flags & (LOAD_HDR|COUNT_HDR))
128 			maxp += sizeof(*x);
129 	}
130 
131 	/*
132 	 * Read in the text segment.
133 	 */
134 	if (flags & LOAD_TEXT) {
135 		PROGRESS(("%ld", x->a_text));
136 
137 		nr = READ(fd, maxp, x->a_text - sub);
138 		if (nr == -1) {
139 			WARN(("read text"));
140 			return 1;
141 		}
142 		if (nr != (ssize_t)(x->a_text - sub)) {
143 			errno = EIO;
144 			WARN(("read text"));
145 			return 1;
146 		}
147 	} else {
148 		if (lseek(fd, x->a_text - sub, SEEK_CUR) == -1) {
149 			WARN(("seek text"));
150 			return 1;
151 		}
152 	}
153 	if (flags & (LOAD_TEXT|COUNT_TEXT))
154 		maxp += x->a_text - sub;
155 
156 	/*
157 	 * Provide alignment if required
158 	 */
159 	if (magic == ZMAGIC || magic == NMAGIC) {
160 		int size = -(unsigned int)maxp & (AOUT_LDPGSZ - 1);
161 
162 		if (flags & LOAD_TEXTA) {
163 			PROGRESS(("/%d", size));
164 			BZERO(maxp, size);
165 		}
166 
167 		if (flags & (LOAD_TEXTA|COUNT_TEXTA))
168 			maxp += size;
169 	}
170 
171 	/*
172 	 * Read in the data segment.
173 	 */
174 	if (flags & LOAD_DATA) {
175 		PROGRESS(("+%ld", x->a_data));
176 
177 		marks[MARK_DATA] = LOADADDR(maxp);
178 		nr = READ(fd, maxp, x->a_data);
179 		if (nr == -1) {
180 			WARN(("read data"));
181 			return 1;
182 		}
183 		if (nr != (ssize_t)x->a_data) {
184 			errno = EIO;
185 			WARN(("read data"));
186 			return 1;
187 		}
188 	}
189 	else {
190 		if (lseek(fd, x->a_data, SEEK_CUR) == -1) {
191 			WARN(("seek data"));
192 			return 1;
193 		}
194 	}
195 	if (flags & (LOAD_DATA|COUNT_DATA))
196 		maxp += x->a_data;
197 
198 	/*
199 	 * Zero out the BSS section.
200 	 * (Kernel doesn't care, but do it anyway.)
201 	 */
202 	if (flags & LOAD_BSS) {
203 		PROGRESS(("+%ld", x->a_bss));
204 
205 		BZERO(maxp, x->a_bss);
206 	}
207 
208 	if (flags & (LOAD_BSS|COUNT_BSS))
209 		maxp += x->a_bss;
210 
211 	/*
212 	 * Read in the symbol table and strings.
213 	 * (Always set the symtab size word.)
214 	 */
215 	if (flags & LOAD_SYM)
216 		BCOPY(&x->a_syms, maxp, sizeof(x->a_syms));
217 
218 	if (flags & (LOAD_SYM|COUNT_SYM)) {
219 		maxp += sizeof(x->a_syms);
220 		aoutp = maxp;
221 	}
222 
223 	if (x->a_syms > 0) {
224 		/* Symbol table and string table length word. */
225 
226 		if (flags & LOAD_SYM) {
227 			PROGRESS(("+[%ld", x->a_syms));
228 
229 			nr = READ(fd, maxp, x->a_syms);
230 			if (nr == -1) {
231 				WARN(("read symbols"));
232 				return 1;
233 			}
234 			if (nr != (ssize_t)x->a_syms) {
235 				errno = EIO;
236 				WARN(("read symbols"));
237 				return 1;
238 			}
239 		} else  {
240 			if (lseek(fd, x->a_syms, SEEK_CUR) == -1) {
241 				WARN(("seek symbols"));
242 				return 1;
243 			}
244 		}
245 		if (flags & (LOAD_SYM|COUNT_SYM))
246 			maxp += x->a_syms;
247 
248 		nr = read(fd, &cc, sizeof(cc));
249 		if (nr == -1) {
250 			WARN(("read string table"));
251 			return 1;
252 		}
253 		if (nr != sizeof(cc)) {
254 			errno = EIO;
255 			WARN(("read string table"));
256 			return 1;
257 		}
258 
259 		if (flags & LOAD_SYM) {
260 			BCOPY(&cc, maxp, sizeof(cc));
261 
262 			/* String table. Length word includes itself. */
263 
264 			PROGRESS(("+%d]", cc));
265 		}
266 		if (flags & (LOAD_SYM|COUNT_SYM))
267 			maxp += sizeof(cc);
268 
269 		cc -= sizeof(int);
270 		if (cc <= 0) {
271 			WARN(("symbol table too short"));
272 			return 1;
273 		}
274 
275 		if (flags & LOAD_SYM) {
276 			nr = READ(fd, maxp, cc);
277 			if (nr == -1) {
278 				WARN(("read strings"));
279 				return 1;
280 			}
281 			if (nr != cc) {
282 				errno = EIO;
283 				WARN(("read strings"));
284 				return 1;
285 			}
286 		} else {
287 			if (lseek(fd, cc, SEEK_CUR) == -1) {
288 				WARN(("seek strings"));
289 				return 1;
290 			}
291 		}
292 		if (flags & (LOAD_SYM|COUNT_SYM))
293 			maxp += cc;
294 	}
295 
296 	marks[MARK_START] = LOADADDR(minp);
297 	marks[MARK_ENTRY] = LOADADDR(entry);
298 	marks[MARK_NSYM] = x->a_syms;
299 	marks[MARK_SYM] = LOADADDR(aoutp);
300 	marks[MARK_END] = LOADADDR(maxp);
301 	return 0;
302 }
303 
304 #endif /* BOOT_AOUT */
305