Home | History | Annotate | Line # | Download | only in libsa
      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
     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