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