Home | History | Annotate | Line # | Download | only in libsa
loadfile.c revision 1.3
      1  1.3     itohy /* $NetBSD: loadfile.c,v 1.3 1999/10/08 03:55:06 itohy Exp $ */
      2  1.1  christos 
      3  1.1  christos /*-
      4  1.1  christos  * Copyright (c) 1997 The NetBSD Foundation, Inc.
      5  1.1  christos  * All rights reserved.
      6  1.1  christos  *
      7  1.1  christos  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1  christos  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9  1.1  christos  * NASA Ames Research Center and by Christos Zoulas.
     10  1.1  christos  *
     11  1.1  christos  * Redistribution and use in source and binary forms, with or without
     12  1.1  christos  * modification, are permitted provided that the following conditions
     13  1.1  christos  * are met:
     14  1.1  christos  * 1. Redistributions of source code must retain the above copyright
     15  1.1  christos  *    notice, this list of conditions and the following disclaimer.
     16  1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     17  1.1  christos  *    notice, this list of conditions and the following disclaimer in the
     18  1.1  christos  *    documentation and/or other materials provided with the distribution.
     19  1.1  christos  * 3. All advertising materials mentioning features or use of this software
     20  1.1  christos  *    must display the following acknowledgement:
     21  1.1  christos  *	This product includes software developed by the NetBSD
     22  1.1  christos  *	Foundation, Inc. and its contributors.
     23  1.1  christos  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24  1.1  christos  *    contributors may be used to endorse or promote products derived
     25  1.1  christos  *    from this software without specific prior written permission.
     26  1.1  christos  *
     27  1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28  1.1  christos  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29  1.1  christos  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30  1.1  christos  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31  1.1  christos  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  1.1  christos  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  1.1  christos  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  1.1  christos  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  1.1  christos  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  1.1  christos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  1.1  christos  * POSSIBILITY OF SUCH DAMAGE.
     38  1.1  christos  */
     39  1.1  christos 
     40  1.1  christos /*
     41  1.1  christos  * Copyright (c) 1992, 1993
     42  1.1  christos  *	The Regents of the University of California.  All rights reserved.
     43  1.1  christos  *
     44  1.1  christos  * This code is derived from software contributed to Berkeley by
     45  1.1  christos  * Ralph Campbell.
     46  1.1  christos  *
     47  1.1  christos  * Redistribution and use in source and binary forms, with or without
     48  1.1  christos  * modification, are permitted provided that the following conditions
     49  1.1  christos  * are met:
     50  1.1  christos  * 1. Redistributions of source code must retain the above copyright
     51  1.1  christos  *    notice, this list of conditions and the following disclaimer.
     52  1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     53  1.1  christos  *    notice, this list of conditions and the following disclaimer in the
     54  1.1  christos  *    documentation and/or other materials provided with the distribution.
     55  1.1  christos  * 3. All advertising materials mentioning features or use of this software
     56  1.1  christos  *    must display the following acknowledgement:
     57  1.1  christos  *	This product includes software developed by the University of
     58  1.1  christos  *	California, Berkeley and its contributors.
     59  1.1  christos  * 4. Neither the name of the University nor the names of its contributors
     60  1.1  christos  *    may be used to endorse or promote products derived from this software
     61  1.1  christos  *    without specific prior written permission.
     62  1.1  christos  *
     63  1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     64  1.1  christos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     65  1.1  christos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     66  1.1  christos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     67  1.1  christos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     68  1.1  christos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     69  1.1  christos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     70  1.1  christos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     71  1.1  christos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     72  1.1  christos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     73  1.1  christos  * SUCH DAMAGE.
     74  1.1  christos  *
     75  1.1  christos  *	@(#)boot.c	8.1 (Berkeley) 6/10/93
     76  1.1  christos  */
     77  1.1  christos 
     78  1.1  christos #ifdef _STANDALONE
     79  1.1  christos #include <lib/libsa/stand.h>
     80  1.1  christos #include <lib/libkern/libkern.h>
     81  1.1  christos #else
     82  1.1  christos #include <stdio.h>
     83  1.1  christos #include <string.h>
     84  1.1  christos #include <errno.h>
     85  1.1  christos #include <stdlib.h>
     86  1.1  christos #include <unistd.h>
     87  1.1  christos #include <fcntl.h>
     88  1.1  christos #include <err.h>
     89  1.1  christos #endif
     90  1.1  christos 
     91  1.1  christos #include <sys/param.h>
     92  1.1  christos #include <sys/exec.h>
     93  1.1  christos 
     94  1.1  christos #include "loadfile.h"
     95  1.1  christos 
     96  1.1  christos #ifdef BOOT_ECOFF
     97  1.1  christos #include <sys/exec_ecoff.h>
     98  1.1  christos static int coff_exec __P((int, struct ecoff_exechdr *, u_long *, int));
     99  1.1  christos #endif
    100  1.1  christos #ifdef BOOT_ELF
    101  1.1  christos #include <sys/exec_elf.h>
    102  1.1  christos static int elf_exec __P((int, Elf_Ehdr *, u_long *, int));
    103  1.1  christos #endif
    104  1.1  christos #ifdef BOOT_AOUT
    105  1.1  christos #include <sys/exec_aout.h>
    106  1.1  christos static int aout_exec __P((int, struct exec *, u_long *, int));
    107  1.1  christos #endif
    108  1.1  christos 
    109  1.1  christos /*
    110  1.1  christos  * Open 'filename', read in program and and return 0 if ok 1 on error.
    111  1.1  christos  * Fill in marks
    112  1.1  christos  */
    113  1.1  christos int
    114  1.1  christos loadfile(fname, marks, flags)
    115  1.1  christos 	const char *fname;
    116  1.1  christos 	u_long *marks;
    117  1.1  christos 	int flags;
    118  1.1  christos {
    119  1.1  christos 	union {
    120  1.1  christos #ifdef BOOT_ECOFF
    121  1.1  christos 		struct ecoff_exechdr coff;
    122  1.1  christos #endif
    123  1.1  christos #ifdef BOOT_ELF
    124  1.1  christos 		Elf_Ehdr elf;
    125  1.1  christos #endif
    126  1.1  christos #ifdef BOOT_AOUT
    127  1.1  christos 		struct exec aout;
    128  1.1  christos #endif
    129  1.1  christos 
    130  1.1  christos 	} hdr;
    131  1.1  christos 	ssize_t nr;
    132  1.1  christos 	int fd, rval;
    133  1.1  christos 
    134  1.1  christos 	/* Open the file. */
    135  1.1  christos 	if ((fd = open(fname, 0)) < 0) {
    136  1.1  christos 		WARN(("open %s", fname ? fname : "<default>"));
    137  1.1  christos 		return -1;
    138  1.1  christos 	}
    139  1.1  christos 
    140  1.1  christos 	/* Read the exec header. */
    141  1.1  christos 	if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
    142  1.1  christos 		WARN(("read header"));
    143  1.1  christos 		goto err;
    144  1.1  christos 	}
    145  1.1  christos 
    146  1.1  christos #ifdef BOOT_ECOFF
    147  1.1  christos 	if (!ECOFF_BADMAG(&hdr.coff)) {
    148  1.1  christos 		rval = coff_exec(fd, &hdr.coff, marks, flags);
    149  1.1  christos 	} else
    150  1.1  christos #endif
    151  1.1  christos #ifdef BOOT_ELF
    152  1.1  christos 	if (memcmp(Elf_e_ident, hdr.elf.e_ident, Elf_e_siz) == 0) {
    153  1.1  christos 		rval = elf_exec(fd, &hdr.elf, marks, flags);
    154  1.1  christos 	} else
    155  1.1  christos #endif
    156  1.1  christos #ifdef BOOT_AOUT
    157  1.1  christos 	if (OKMAGIC(N_GETMAGIC(hdr.aout)) &&
    158  1.1  christos 	    N_GETMID(hdr.aout) == MID_MACHINE) {
    159  1.1  christos 		rval = aout_exec(fd, &hdr.aout, marks, flags);
    160  1.1  christos 	} else
    161  1.1  christos #endif
    162  1.1  christos 	{
    163  1.1  christos 		rval = 1;
    164  1.1  christos 		errno = EFTYPE;
    165  1.1  christos 		WARN(("%s", fname ? fname : "<default>"));
    166  1.1  christos 	}
    167  1.1  christos 
    168  1.1  christos 	if (rval == 0) {
    169  1.1  christos 		PROGRESS(("=0x%lx\n", marks[MARK_END] - marks[MARK_START]));
    170  1.1  christos 		return fd;
    171  1.1  christos 	}
    172  1.1  christos err:
    173  1.1  christos 	(void)close(fd);
    174  1.1  christos 	return -1;
    175  1.1  christos }
    176  1.1  christos 
    177  1.1  christos #ifdef BOOT_ECOFF
    178  1.1  christos static int
    179  1.1  christos coff_exec(fd, coff, marks, flags)
    180  1.1  christos 	int fd;
    181  1.1  christos 	struct ecoff_exechdr *coff;
    182  1.1  christos 	u_long *marks;
    183  1.1  christos 	int flags;
    184  1.1  christos {
    185  1.1  christos 	paddr_t offset = marks[MARK_START];
    186  1.1  christos 	paddr_t minp = ~0, maxp = 0, pos;
    187  1.1  christos 
    188  1.1  christos 	/* Read in text. */
    189  1.1  christos 	if (lseek(fd, ECOFF_TXTOFF(coff), SEEK_SET) == -1)  {
    190  1.1  christos 		WARN(("lseek text"));
    191  1.1  christos 		return 1;
    192  1.1  christos 	}
    193  1.1  christos 
    194  1.1  christos 	if (coff->a.tsize != 0) {
    195  1.1  christos 		if (flags & LOAD_TEXT) {
    196  1.1  christos 			PROGRESS(("%lu", coff->a.tsize));
    197  1.1  christos 			if (READ(fd, coff->a.text_start, coff->a.tsize) !=
    198  1.1  christos 			    coff->a.tsize) {
    199  1.1  christos 				return 1;
    200  1.1  christos 			}
    201  1.1  christos 		}
    202  1.1  christos 		else {
    203  1.1  christos 			if (lseek(fd, coff->a.tsize, SEEK_CUR) == -1) {
    204  1.1  christos 				WARN(("read text"));
    205  1.1  christos 				return 1;
    206  1.1  christos 			}
    207  1.1  christos 		}
    208  1.1  christos 		if (flags & (COUNT_TEXT|LOAD_TEXT)) {
    209  1.1  christos 			pos = coff->a.text_start;
    210  1.1  christos 			if (minp > pos)
    211  1.1  christos 				minp = pos;
    212  1.1  christos 			pos += coff->a.tsize;
    213  1.1  christos 			if (maxp < pos)
    214  1.1  christos 				maxp = pos;
    215  1.1  christos 		}
    216  1.1  christos 	}
    217  1.1  christos 
    218  1.1  christos 	/* Read in data. */
    219  1.1  christos 	if (coff->a.dsize != 0) {
    220  1.1  christos 		if (flags & LOAD_DATA) {
    221  1.1  christos 			PROGRESS(("+%lu", coff->a.dsize));
    222  1.1  christos 			if (READ(fd, coff->a.data_start, coff->a.dsize) !=
    223  1.1  christos 			    coff->a.dsize) {
    224  1.1  christos 				WARN(("read data"));
    225  1.1  christos 				return 1;
    226  1.1  christos 			}
    227  1.1  christos 		}
    228  1.1  christos 		if (flags & (COUNT_DATA|LOAD_DATA)) {
    229  1.1  christos 			pos = coff->a.data_start;
    230  1.1  christos 			if (minp > pos)
    231  1.1  christos 				minp = pos;
    232  1.1  christos 			pos += coff->a.dsize;
    233  1.1  christos 			if (maxp < pos)
    234  1.1  christos 				maxp = pos;
    235  1.1  christos 		}
    236  1.1  christos 	}
    237  1.1  christos 
    238  1.1  christos 	/* Zero out bss. */
    239  1.1  christos 	if (coff->a.bsize != 0) {
    240  1.1  christos 		if (flags & LOAD_BSS) {
    241  1.1  christos 			PROGRESS(("+%lu", coff->a.bsize));
    242  1.1  christos 			BZERO(coff->a.bss_start, coff->a.bsize);
    243  1.1  christos 		}
    244  1.1  christos 		if (flags & (COUNT_BSS|LOAD_BSS)) {
    245  1.1  christos 			pos = coff->a.bss_start;
    246  1.1  christos 			if (minp > pos)
    247  1.1  christos 				minp = pos;
    248  1.1  christos 			pos = coff->a.bsize;
    249  1.1  christos 			if (maxp < pos)
    250  1.1  christos 				maxp = pos;
    251  1.1  christos 		}
    252  1.1  christos 	}
    253  1.1  christos 
    254  1.1  christos 	marks[MARK_START] = LOADADDR(minp);
    255  1.1  christos 	marks[MARK_ENTRY] = LOADADDR(coff->a.entry);
    256  1.1  christos 	marks[MARK_NSYM] = 1;	/* XXX: Kernel needs >= 0 */
    257  1.1  christos 	marks[MARK_SYM] = LOADADDR(maxp);
    258  1.1  christos 	marks[MARK_END] = LOADADDR(maxp);
    259  1.1  christos 	return 0;
    260  1.1  christos }
    261  1.1  christos #endif /* BOOT_ECOFF */
    262  1.1  christos 
    263  1.1  christos #ifdef BOOT_ELF
    264  1.1  christos static int
    265  1.1  christos elf_exec(fd, elf, marks, flags)
    266  1.1  christos 	int fd;
    267  1.1  christos 	Elf_Ehdr *elf;
    268  1.1  christos 	u_long *marks;
    269  1.1  christos 	int flags;
    270  1.1  christos {
    271  1.1  christos 	Elf_Shdr *shp;
    272  1.1  christos 	Elf_Off off;
    273  1.1  christos 	int i;
    274  1.1  christos 	size_t sz;
    275  1.1  christos 	int first;
    276  1.1  christos 	int havesyms;
    277  1.1  christos 	paddr_t minp = ~0, maxp = 0, pos;
    278  1.1  christos 	paddr_t offset = marks[MARK_START], shpp, elfp;
    279  1.1  christos 
    280  1.1  christos 	for (first = 1, i = 0; i < elf->e_phnum; i++) {
    281  1.1  christos 		Elf_Phdr phdr;
    282  1.1  christos 		if (lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET)
    283  1.1  christos 		    == -1)  {
    284  1.1  christos 			WARN(("lseek phdr"));
    285  1.1  christos 			return 1;
    286  1.1  christos 		}
    287  1.1  christos 		if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
    288  1.1  christos 			WARN(("read phdr"));
    289  1.1  christos 			return 1;
    290  1.1  christos 		}
    291  1.1  christos 		if (phdr.p_type != Elf_pt_load ||
    292  1.1  christos 		    (phdr.p_flags & (Elf_pf_w|Elf_pf_x)) == 0)
    293  1.1  christos 			continue;
    294  1.1  christos 
    295  1.1  christos #define IS_TEXT(p)	(p.p_type & Elf_pf_x)
    296  1.1  christos #define IS_DATA(p)	(p.p_type & Elf_pf_w)
    297  1.1  christos #define IS_BSS(p)	(p.p_filesz < p.p_memsz)
    298  1.1  christos 		/*
    299  1.1  christos 		 * XXX: Assume first address is lowest
    300  1.1  christos 		 */
    301  1.1  christos 		if ((IS_TEXT(phdr) && (flags & LOAD_TEXT)) ||
    302  1.1  christos 		    (IS_DATA(phdr) && (flags & LOAD_DATA))) {
    303  1.1  christos 
    304  1.1  christos 			/* Read in segment. */
    305  1.1  christos 			PROGRESS(("%s%lu", first ? "" : "+",
    306  1.1  christos 			    (u_long)phdr.p_filesz));
    307  1.1  christos 
    308  1.1  christos 			if (lseek(fd, phdr.p_offset, SEEK_SET) == -1)  {
    309  1.1  christos 				WARN(("lseek text"));
    310  1.1  christos 				return 1;
    311  1.1  christos 			}
    312  1.1  christos 			if (READ(fd, phdr.p_vaddr, phdr.p_filesz) !=
    313  1.1  christos 			    phdr.p_filesz) {
    314  1.1  christos 				WARN(("read text"));
    315  1.1  christos 				return 1;
    316  1.1  christos 			}
    317  1.1  christos 			first = 0;
    318  1.1  christos 
    319  1.1  christos 		}
    320  1.1  christos 		if ((IS_TEXT(phdr) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
    321  1.1  christos 		    (IS_DATA(phdr) && (flags & (LOAD_DATA|COUNT_TEXT)))) {
    322  1.1  christos 			pos = phdr.p_vaddr;
    323  1.1  christos 			if (minp > pos)
    324  1.1  christos 				minp = pos;
    325  1.1  christos 			pos += phdr.p_filesz;
    326  1.1  christos 			if (maxp < pos)
    327  1.1  christos 				maxp = pos;
    328  1.1  christos 		}
    329  1.1  christos 
    330  1.1  christos 		/* Zero out bss. */
    331  1.1  christos 		if (IS_BSS(phdr) && (flags & LOAD_BSS)) {
    332  1.1  christos 			PROGRESS(("+%lu",
    333  1.1  christos 			    (u_long)(phdr.p_memsz - phdr.p_filesz)));
    334  1.1  christos 			BZERO((phdr.p_vaddr + phdr.p_filesz),
    335  1.1  christos 			    phdr.p_memsz - phdr.p_filesz);
    336  1.1  christos 		}
    337  1.1  christos 		if (IS_BSS(phdr) && (flags & (LOAD_BSS|COUNT_BSS))) {
    338  1.1  christos 			pos += phdr.p_memsz - phdr.p_filesz;
    339  1.1  christos 			if (maxp < pos)
    340  1.1  christos 				maxp = pos;
    341  1.1  christos 		}
    342  1.1  christos 	}
    343  1.1  christos 
    344  1.1  christos 	/*
    345  1.1  christos 	 * Copy the ELF and section headers.
    346  1.1  christos 	 */
    347  1.1  christos 	maxp = roundup(maxp, sizeof(long));
    348  1.1  christos 	if (flags & (LOAD_HDR|COUNT_HDR)) {
    349  1.1  christos 		elfp = maxp;
    350  1.1  christos 		maxp += sizeof(Elf_Ehdr);
    351  1.1  christos 	}
    352  1.1  christos 
    353  1.1  christos 	if (flags & (LOAD_SYM|COUNT_SYM)) {
    354  1.1  christos 		if (lseek(fd, elf->e_shoff, SEEK_SET) == -1)  {
    355  1.1  christos 			WARN(("lseek section headers"));
    356  1.1  christos 			return 1;
    357  1.1  christos 		}
    358  1.1  christos 		sz = elf->e_shnum * sizeof(Elf_Shdr);
    359  1.1  christos 
    360  1.1  christos 		shp = ALLOC(sz);
    361  1.1  christos 
    362  1.1  christos 		if (read(fd, shp, sz) != sz) {
    363  1.1  christos 			WARN(("read section headers"));
    364  1.1  christos 			return 1;
    365  1.1  christos 		}
    366  1.1  christos 
    367  1.1  christos 		shpp = maxp;
    368  1.1  christos 		maxp += roundup(sz, sizeof(long));
    369  1.1  christos 
    370  1.1  christos 		/*
    371  1.1  christos 		 * Now load the symbol sections themselves.  Make sure the
    372  1.1  christos 		 * sections are aligned. Don't bother with string tables if
    373  1.1  christos 		 * there are no symbol sections.
    374  1.1  christos 		 */
    375  1.1  christos 		off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(long));
    376  1.1  christos 
    377  1.1  christos 		for (havesyms = i = 0; i < elf->e_shnum; i++)
    378  1.1  christos 			if (shp[i].sh_type == Elf_sht_symtab)
    379  1.1  christos 				havesyms = 1;
    380  1.1  christos 
    381  1.1  christos 		for (first = 1, i = 0; i < elf->e_shnum; i++) {
    382  1.1  christos 			if (shp[i].sh_type == Elf_sht_symtab ||
    383  1.1  christos 			    shp[i].sh_type == Elf_sht_strtab) {
    384  1.1  christos 				if (havesyms && (flags & LOAD_SYM)) {
    385  1.1  christos 					PROGRESS(("%s%ld", first ? " [" : "+",
    386  1.1  christos 					    (u_long)shp[i].sh_size));
    387  1.1  christos 					if (lseek(fd, shp[i].sh_offset,
    388  1.1  christos 					    SEEK_SET) == -1) {
    389  1.1  christos 						WARN(("lseek symbols"));
    390  1.1  christos 						FREE(shp, sz);
    391  1.1  christos 						return 1;
    392  1.1  christos 					}
    393  1.1  christos 					if (READ(fd, maxp, shp[i].sh_size) !=
    394  1.1  christos 					    shp[i].sh_size) {
    395  1.1  christos 						WARN(("read symbols"));
    396  1.1  christos 						FREE(shp, sz);
    397  1.1  christos 						return 1;
    398  1.1  christos 					}
    399  1.1  christos 				}
    400  1.1  christos 				maxp += roundup(shp[i].sh_size,
    401  1.1  christos 				    sizeof(long));
    402  1.1  christos 				shp[i].sh_offset = off;
    403  1.1  christos 				off += roundup(shp[i].sh_size, sizeof(long));
    404  1.1  christos 				first = 0;
    405  1.1  christos 			}
    406  1.1  christos 		}
    407  1.1  christos 		if (flags & LOAD_SYM) {
    408  1.1  christos 			BCOPY(shp, shpp, sz);
    409  1.1  christos 			FREE(shp, sz);
    410  1.1  christos 
    411  1.1  christos 			if (first == 0)
    412  1.1  christos 				PROGRESS(("]"));
    413  1.1  christos 		}
    414  1.1  christos 	}
    415  1.1  christos 
    416  1.1  christos 	/*
    417  1.1  christos 	 * Frob the copied ELF header to give information relative
    418  1.1  christos 	 * to elfp.
    419  1.1  christos 	 */
    420  1.1  christos 	if (flags & LOAD_HDR) {
    421  1.1  christos 		elf->e_phoff = 0;
    422  1.1  christos 		elf->e_shoff = sizeof(Elf_Ehdr);
    423  1.1  christos 		elf->e_phentsize = 0;
    424  1.1  christos 		elf->e_phnum = 0;
    425  1.1  christos 		BCOPY(elf, elfp, sizeof(*elf));
    426  1.1  christos 	}
    427  1.1  christos 
    428  1.1  christos 	marks[MARK_START] = LOADADDR(minp);
    429  1.1  christos 	marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
    430  1.1  christos 	marks[MARK_NSYM] = 1;	/* XXX: Kernel needs >= 0 */
    431  1.1  christos 	marks[MARK_SYM] = LOADADDR(elfp);
    432  1.1  christos 	marks[MARK_END] = LOADADDR(maxp);
    433  1.1  christos 	return 0;
    434  1.1  christos }
    435  1.1  christos #endif /* BOOT_ELF */
    436  1.1  christos 
    437  1.1  christos #ifdef BOOT_AOUT
    438  1.1  christos static int
    439  1.1  christos aout_exec(fd, x, marks, flags)
    440  1.1  christos 	int fd;
    441  1.1  christos 	struct exec *x;
    442  1.1  christos 	u_long *marks;
    443  1.1  christos 	int flags;
    444  1.1  christos {
    445  1.1  christos 	u_long entry = x->a_entry;
    446  1.1  christos 	paddr_t aoutp = 0;
    447  1.1  christos 	paddr_t minp, maxp;
    448  1.1  christos 	int cc;
    449  1.1  christos 	paddr_t offset = marks[MARK_START];
    450  1.1  christos 	u_long magic = N_GETMAGIC(*x);
    451  1.1  christos 	int sub;
    452  1.1  christos 
    453  1.3     itohy 	/* In OMAGIC and NMAGIC, exec header isn't part of text segment */
    454  1.3     itohy 	if (magic == OMAGIC || magic == NMAGIC)
    455  1.1  christos 		sub = 0;
    456  1.1  christos 	else
    457  1.1  christos 		sub = sizeof(*x);
    458  1.1  christos 
    459  1.1  christos 	minp = maxp = ALIGNENTRY(entry);
    460  1.1  christos 
    461  1.1  christos 	if (lseek(fd, sizeof(*x), SEEK_SET) == -1)  {
    462  1.1  christos 		WARN(("lseek text"));
    463  1.1  christos 		return 1;
    464  1.1  christos 	}
    465  1.1  christos 
    466  1.1  christos 	/*
    467  1.1  christos 	 * Leave a copy of the exec header before the text.
    468  1.1  christos 	 * The kernel may use this to verify that the
    469  1.1  christos 	 * symbols were loaded by this boot program.
    470  1.1  christos 	 */
    471  1.3     itohy 	if (magic == OMAGIC || magic == NMAGIC) {
    472  1.1  christos 		if (flags & LOAD_HDR)
    473  1.1  christos 			BCOPY(x, maxp - sizeof(*x), sizeof(*x));
    474  1.1  christos 	}
    475  1.1  christos 	else {
    476  1.1  christos 		if (flags & LOAD_HDR)
    477  1.1  christos 			BCOPY(x, maxp, sizeof(*x));
    478  1.1  christos 		if (flags & (LOAD_HDR|COUNT_HDR))
    479  1.1  christos 			maxp += sizeof(*x);
    480  1.1  christos 	}
    481  1.1  christos 
    482  1.1  christos 	/*
    483  1.1  christos 	 * Read in the text segment.
    484  1.1  christos 	 */
    485  1.1  christos 	if (flags & LOAD_TEXT) {
    486  1.1  christos 		PROGRESS(("%ld", x->a_text));
    487  1.1  christos 
    488  1.1  christos 		if (READ(fd, maxp, x->a_text - sub) != x->a_text - sub) {
    489  1.1  christos 			WARN(("read text"));
    490  1.1  christos 			return 1;
    491  1.1  christos 		}
    492  1.1  christos 	} else {
    493  1.1  christos 		if (lseek(fd, x->a_text - sub, SEEK_CUR) == -1) {
    494  1.1  christos 			WARN(("seek text"));
    495  1.1  christos 			return 1;
    496  1.1  christos 		}
    497  1.1  christos 	}
    498  1.1  christos 	if (flags & (LOAD_TEXT|COUNT_TEXT))
    499  1.1  christos 		maxp += x->a_text - sub;
    500  1.1  christos 
    501  1.1  christos 	/*
    502  1.1  christos 	 * Provide alignment if required
    503  1.1  christos 	 */
    504  1.1  christos 	if (magic == ZMAGIC || magic == NMAGIC) {
    505  1.3     itohy 		int size = -(unsigned int)maxp & (__LDPGSZ - 1);
    506  1.1  christos 
    507  1.2  christos 		if (flags & LOAD_TEXTA) {
    508  1.2  christos 			PROGRESS(("/%d", size));
    509  1.1  christos 			BZERO(maxp, size);
    510  1.2  christos 		}
    511  1.1  christos 
    512  1.1  christos 		if (flags & (LOAD_TEXTA|COUNT_TEXTA))
    513  1.1  christos 			maxp += size;
    514  1.1  christos 	}
    515  1.1  christos 
    516  1.1  christos 	/*
    517  1.1  christos 	 * Read in the data segment.
    518  1.1  christos 	 */
    519  1.1  christos 	if (flags & LOAD_DATA) {
    520  1.1  christos 		PROGRESS(("+%ld", x->a_data));
    521  1.1  christos 
    522  1.1  christos 		if (READ(fd, maxp, x->a_data) != x->a_data) {
    523  1.1  christos 			WARN(("read data"));
    524  1.1  christos 			return 1;
    525  1.1  christos 		}
    526  1.1  christos 	}
    527  1.1  christos 	else {
    528  1.1  christos 		if (lseek(fd, x->a_data, SEEK_CUR) == -1) {
    529  1.1  christos 			WARN(("seek data"));
    530  1.1  christos 			return 1;
    531  1.1  christos 		}
    532  1.1  christos 	}
    533  1.1  christos 	if (flags & (LOAD_DATA|COUNT_DATA))
    534  1.1  christos 		maxp += x->a_data;
    535  1.1  christos 
    536  1.1  christos 	/*
    537  1.1  christos 	 * Zero out the BSS section.
    538  1.1  christos 	 * (Kernel doesn't care, but do it anyway.)
    539  1.1  christos 	 */
    540  1.1  christos 	if (flags & LOAD_BSS) {
    541  1.1  christos 		PROGRESS(("+%ld", x->a_bss));
    542  1.1  christos 
    543  1.1  christos 		BZERO(maxp, x->a_bss);
    544  1.1  christos 	}
    545  1.1  christos 
    546  1.1  christos 	if (flags & (LOAD_BSS|COUNT_BSS))
    547  1.1  christos 		maxp += x->a_bss;
    548  1.1  christos 
    549  1.1  christos 	/*
    550  1.1  christos 	 * Read in the symbol table and strings.
    551  1.1  christos 	 * (Always set the symtab size word.)
    552  1.1  christos 	 */
    553  1.1  christos 	if (flags & LOAD_SYM)
    554  1.1  christos 		BCOPY(&x->a_syms, maxp, sizeof(x->a_syms));
    555  1.1  christos 
    556  1.1  christos 	if (flags & (LOAD_SYM|COUNT_SYM)) {
    557  1.1  christos 		maxp += sizeof(x->a_syms);
    558  1.1  christos 		aoutp = maxp;
    559  1.1  christos 	}
    560  1.1  christos 
    561  1.1  christos 	if (x->a_syms > 0) {
    562  1.1  christos 		/* Symbol table and string table length word. */
    563  1.1  christos 
    564  1.1  christos 		if (flags & LOAD_SYM) {
    565  1.1  christos 			PROGRESS(("+[%ld", x->a_syms));
    566  1.1  christos 
    567  1.1  christos 			if (READ(fd, maxp, x->a_syms) != x->a_syms) {
    568  1.1  christos 				WARN(("read symbols"));
    569  1.1  christos 				return 1;
    570  1.1  christos 			}
    571  1.1  christos 		} else  {
    572  1.1  christos 			if (lseek(fd, x->a_syms, SEEK_CUR) == -1) {
    573  1.1  christos 				WARN(("seek symbols"));
    574  1.1  christos 				return 1;
    575  1.1  christos 			}
    576  1.1  christos 		}
    577  1.1  christos 		if (flags & (LOAD_SYM|COUNT_SYM))
    578  1.1  christos 			maxp += x->a_syms;
    579  1.1  christos 
    580  1.1  christos 		if (read(fd, &cc, sizeof(cc)) != sizeof(cc)) {
    581  1.1  christos 			WARN(("read string table"));
    582  1.1  christos 			return 1;
    583  1.1  christos 		}
    584  1.1  christos 
    585  1.1  christos 		if (flags & LOAD_SYM) {
    586  1.1  christos 			BCOPY(&cc, maxp, sizeof(cc));
    587  1.1  christos 
    588  1.1  christos 			/* String table. Length word includes itself. */
    589  1.1  christos 
    590  1.1  christos 			PROGRESS(("+%d]", cc));
    591  1.1  christos 		}
    592  1.1  christos 		if (flags & (LOAD_SYM|COUNT_SYM))
    593  1.1  christos 			maxp += sizeof(cc);
    594  1.1  christos 
    595  1.1  christos 		cc -= sizeof(int);
    596  1.1  christos 		if (cc <= 0) {
    597  1.1  christos 			WARN(("symbol table too short"));
    598  1.1  christos 			return 1;
    599  1.1  christos 		}
    600  1.1  christos 
    601  1.1  christos 		if (flags & LOAD_SYM) {
    602  1.1  christos 			if (READ(fd, maxp, cc) != cc) {
    603  1.1  christos 				WARN(("read strings"));
    604  1.1  christos 				return 1;
    605  1.1  christos 			}
    606  1.1  christos 		} else {
    607  1.1  christos 			if (lseek(fd, cc, SEEK_CUR) == -1) {
    608  1.1  christos 				WARN(("seek strings"));
    609  1.1  christos 				return 1;
    610  1.1  christos 			}
    611  1.1  christos 		}
    612  1.1  christos 		if (flags & (LOAD_SYM|COUNT_SYM))
    613  1.1  christos 			maxp += cc;
    614  1.1  christos 	}
    615  1.1  christos 
    616  1.1  christos 	marks[MARK_START] = LOADADDR(minp);
    617  1.1  christos 	marks[MARK_ENTRY] = LOADADDR(entry);
    618  1.1  christos 	marks[MARK_NSYM] = x->a_syms;
    619  1.1  christos 	marks[MARK_SYM] = LOADADDR(aoutp);
    620  1.1  christos 	marks[MARK_END] = LOADADDR(maxp);
    621  1.1  christos 	return 0;
    622  1.1  christos }
    623  1.1  christos #endif /* BOOT_AOUT */
    624