1/* $NetBSD: loadfile_aout.c,v 1.14 2009/08/16 13:26:16 matt 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 87int 88loadfile_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