Home | History | Annotate | Line # | Download | only in libsa
loadfile.c revision 1.10.2.1
      1  1.10.2.1   nathanw /* $NetBSD: loadfile.c,v 1.10.2.1 2001/08/24 00:11:53 nathanw 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.6   thorpej #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.4    kleink 	if (memcmp(hdr.elf.e_ident, ELFMAG, SELFMAG) == 0 &&
    153       1.4    kleink 	    hdr.elf.e_ident[EI_CLASS] == ELFCLASS) {
    154       1.1  christos 		rval = elf_exec(fd, &hdr.elf, marks, flags);
    155       1.1  christos 	} else
    156       1.1  christos #endif
    157       1.1  christos #ifdef BOOT_AOUT
    158       1.8     ragge 	if (OKMAGIC(N_GETMAGIC(hdr.aout))
    159       1.8     ragge #ifndef NO_MID_CHECK
    160       1.8     ragge 	    && N_GETMID(hdr.aout) == MID_MACHINE
    161       1.8     ragge #endif
    162       1.8     ragge 	    ) {
    163       1.1  christos 		rval = aout_exec(fd, &hdr.aout, marks, flags);
    164       1.1  christos 	} else
    165       1.1  christos #endif
    166       1.1  christos 	{
    167       1.1  christos 		rval = 1;
    168       1.1  christos 		errno = EFTYPE;
    169       1.1  christos 		WARN(("%s", fname ? fname : "<default>"));
    170       1.1  christos 	}
    171       1.1  christos 
    172       1.1  christos 	if (rval == 0) {
    173       1.1  christos 		PROGRESS(("=0x%lx\n", marks[MARK_END] - marks[MARK_START]));
    174       1.1  christos 		return fd;
    175       1.1  christos 	}
    176       1.1  christos err:
    177       1.1  christos 	(void)close(fd);
    178       1.1  christos 	return -1;
    179       1.1  christos }
    180       1.1  christos 
    181       1.1  christos #ifdef BOOT_ECOFF
    182       1.1  christos static int
    183       1.1  christos coff_exec(fd, coff, marks, flags)
    184       1.1  christos 	int fd;
    185       1.1  christos 	struct ecoff_exechdr *coff;
    186       1.1  christos 	u_long *marks;
    187       1.1  christos 	int flags;
    188       1.1  christos {
    189       1.1  christos 	paddr_t offset = marks[MARK_START];
    190       1.1  christos 	paddr_t minp = ~0, maxp = 0, pos;
    191       1.1  christos 
    192       1.1  christos 	/* Read in text. */
    193       1.1  christos 	if (lseek(fd, ECOFF_TXTOFF(coff), SEEK_SET) == -1)  {
    194       1.1  christos 		WARN(("lseek text"));
    195       1.1  christos 		return 1;
    196       1.1  christos 	}
    197       1.1  christos 
    198       1.1  christos 	if (coff->a.tsize != 0) {
    199       1.1  christos 		if (flags & LOAD_TEXT) {
    200       1.1  christos 			PROGRESS(("%lu", coff->a.tsize));
    201       1.1  christos 			if (READ(fd, coff->a.text_start, coff->a.tsize) !=
    202       1.1  christos 			    coff->a.tsize) {
    203       1.1  christos 				return 1;
    204       1.1  christos 			}
    205       1.1  christos 		}
    206       1.1  christos 		else {
    207       1.1  christos 			if (lseek(fd, coff->a.tsize, SEEK_CUR) == -1) {
    208       1.1  christos 				WARN(("read text"));
    209       1.1  christos 				return 1;
    210       1.1  christos 			}
    211       1.1  christos 		}
    212       1.1  christos 		if (flags & (COUNT_TEXT|LOAD_TEXT)) {
    213       1.1  christos 			pos = coff->a.text_start;
    214       1.1  christos 			if (minp > pos)
    215       1.1  christos 				minp = pos;
    216       1.1  christos 			pos += coff->a.tsize;
    217       1.1  christos 			if (maxp < pos)
    218       1.1  christos 				maxp = pos;
    219       1.1  christos 		}
    220       1.1  christos 	}
    221       1.1  christos 
    222       1.1  christos 	/* Read in data. */
    223       1.1  christos 	if (coff->a.dsize != 0) {
    224       1.1  christos 		if (flags & LOAD_DATA) {
    225       1.1  christos 			PROGRESS(("+%lu", coff->a.dsize));
    226       1.1  christos 			if (READ(fd, coff->a.data_start, coff->a.dsize) !=
    227       1.1  christos 			    coff->a.dsize) {
    228       1.1  christos 				WARN(("read data"));
    229       1.1  christos 				return 1;
    230       1.1  christos 			}
    231       1.1  christos 		}
    232       1.1  christos 		if (flags & (COUNT_DATA|LOAD_DATA)) {
    233       1.1  christos 			pos = coff->a.data_start;
    234       1.1  christos 			if (minp > pos)
    235       1.1  christos 				minp = pos;
    236       1.1  christos 			pos += coff->a.dsize;
    237       1.1  christos 			if (maxp < pos)
    238       1.1  christos 				maxp = pos;
    239       1.1  christos 		}
    240       1.1  christos 	}
    241       1.1  christos 
    242       1.1  christos 	/* Zero out bss. */
    243       1.1  christos 	if (coff->a.bsize != 0) {
    244       1.1  christos 		if (flags & LOAD_BSS) {
    245       1.1  christos 			PROGRESS(("+%lu", coff->a.bsize));
    246       1.1  christos 			BZERO(coff->a.bss_start, coff->a.bsize);
    247       1.1  christos 		}
    248       1.1  christos 		if (flags & (COUNT_BSS|LOAD_BSS)) {
    249       1.1  christos 			pos = coff->a.bss_start;
    250       1.1  christos 			if (minp > pos)
    251       1.1  christos 				minp = pos;
    252       1.1  christos 			pos = coff->a.bsize;
    253       1.1  christos 			if (maxp < pos)
    254       1.1  christos 				maxp = pos;
    255       1.1  christos 		}
    256       1.1  christos 	}
    257       1.1  christos 
    258       1.1  christos 	marks[MARK_START] = LOADADDR(minp);
    259       1.1  christos 	marks[MARK_ENTRY] = LOADADDR(coff->a.entry);
    260       1.1  christos 	marks[MARK_NSYM] = 1;	/* XXX: Kernel needs >= 0 */
    261       1.1  christos 	marks[MARK_SYM] = LOADADDR(maxp);
    262       1.1  christos 	marks[MARK_END] = LOADADDR(maxp);
    263       1.1  christos 	return 0;
    264       1.1  christos }
    265       1.1  christos #endif /* BOOT_ECOFF */
    266       1.1  christos 
    267       1.1  christos #ifdef BOOT_ELF
    268       1.1  christos static int
    269       1.1  christos elf_exec(fd, elf, marks, flags)
    270       1.1  christos 	int fd;
    271       1.1  christos 	Elf_Ehdr *elf;
    272       1.1  christos 	u_long *marks;
    273       1.1  christos 	int flags;
    274       1.1  christos {
    275       1.1  christos 	Elf_Shdr *shp;
    276  1.10.2.1   nathanw 	int i, j;
    277       1.1  christos 	size_t sz;
    278       1.1  christos 	int first;
    279  1.10.2.1   nathanw 	paddr_t minp = ~0, maxp = 0, pos = 0;
    280  1.10.2.1   nathanw 	paddr_t offset = marks[MARK_START], shpp, elfp = NULL;
    281       1.1  christos 
    282       1.1  christos 	for (first = 1, i = 0; i < elf->e_phnum; i++) {
    283       1.1  christos 		Elf_Phdr phdr;
    284       1.1  christos 		if (lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET)
    285       1.1  christos 		    == -1)  {
    286       1.1  christos 			WARN(("lseek phdr"));
    287       1.1  christos 			return 1;
    288       1.1  christos 		}
    289       1.1  christos 		if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
    290       1.1  christos 			WARN(("read phdr"));
    291       1.1  christos 			return 1;
    292       1.1  christos 		}
    293       1.4    kleink 		if (phdr.p_type != PT_LOAD ||
    294       1.4    kleink 		    (phdr.p_flags & (PF_W|PF_X)) == 0)
    295       1.1  christos 			continue;
    296       1.1  christos 
    297       1.7   hannken #define IS_TEXT(p)	(p.p_flags & PF_X)
    298       1.7   hannken #define IS_DATA(p)	(p.p_flags & PF_W)
    299       1.1  christos #define IS_BSS(p)	(p.p_filesz < p.p_memsz)
    300       1.1  christos 		/*
    301       1.1  christos 		 * XXX: Assume first address is lowest
    302       1.1  christos 		 */
    303       1.1  christos 		if ((IS_TEXT(phdr) && (flags & LOAD_TEXT)) ||
    304       1.1  christos 		    (IS_DATA(phdr) && (flags & LOAD_DATA))) {
    305       1.1  christos 
    306       1.1  christos 			/* Read in segment. */
    307       1.1  christos 			PROGRESS(("%s%lu", first ? "" : "+",
    308       1.1  christos 			    (u_long)phdr.p_filesz));
    309       1.1  christos 
    310       1.1  christos 			if (lseek(fd, phdr.p_offset, SEEK_SET) == -1)  {
    311       1.1  christos 				WARN(("lseek text"));
    312       1.1  christos 				return 1;
    313       1.1  christos 			}
    314       1.1  christos 			if (READ(fd, phdr.p_vaddr, phdr.p_filesz) !=
    315       1.1  christos 			    phdr.p_filesz) {
    316       1.1  christos 				WARN(("read text"));
    317       1.1  christos 				return 1;
    318       1.1  christos 			}
    319       1.1  christos 			first = 0;
    320       1.1  christos 
    321       1.1  christos 		}
    322       1.1  christos 		if ((IS_TEXT(phdr) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
    323       1.1  christos 		    (IS_DATA(phdr) && (flags & (LOAD_DATA|COUNT_TEXT)))) {
    324       1.1  christos 			pos = phdr.p_vaddr;
    325       1.1  christos 			if (minp > pos)
    326       1.1  christos 				minp = pos;
    327       1.1  christos 			pos += phdr.p_filesz;
    328       1.1  christos 			if (maxp < pos)
    329       1.1  christos 				maxp = pos;
    330       1.1  christos 		}
    331       1.1  christos 
    332       1.1  christos 		/* Zero out bss. */
    333       1.1  christos 		if (IS_BSS(phdr) && (flags & LOAD_BSS)) {
    334       1.1  christos 			PROGRESS(("+%lu",
    335       1.1  christos 			    (u_long)(phdr.p_memsz - phdr.p_filesz)));
    336       1.1  christos 			BZERO((phdr.p_vaddr + phdr.p_filesz),
    337       1.1  christos 			    phdr.p_memsz - phdr.p_filesz);
    338       1.1  christos 		}
    339       1.1  christos 		if (IS_BSS(phdr) && (flags & (LOAD_BSS|COUNT_BSS))) {
    340       1.1  christos 			pos += phdr.p_memsz - phdr.p_filesz;
    341       1.1  christos 			if (maxp < pos)
    342       1.1  christos 				maxp = pos;
    343       1.1  christos 		}
    344       1.1  christos 	}
    345       1.1  christos 
    346       1.1  christos 	/*
    347       1.1  christos 	 * Copy the ELF and section headers.
    348       1.1  christos 	 */
    349       1.1  christos 	maxp = roundup(maxp, sizeof(long));
    350       1.1  christos 	if (flags & (LOAD_HDR|COUNT_HDR)) {
    351       1.1  christos 		elfp = maxp;
    352       1.1  christos 		maxp += sizeof(Elf_Ehdr);
    353       1.1  christos 	}
    354       1.1  christos 
    355       1.1  christos 	if (flags & (LOAD_SYM|COUNT_SYM)) {
    356       1.1  christos 		if (lseek(fd, elf->e_shoff, SEEK_SET) == -1)  {
    357       1.1  christos 			WARN(("lseek section headers"));
    358       1.1  christos 			return 1;
    359       1.1  christos 		}
    360       1.1  christos 		sz = elf->e_shnum * sizeof(Elf_Shdr);
    361       1.1  christos 
    362       1.1  christos 		shp = ALLOC(sz);
    363       1.1  christos 
    364       1.1  christos 		if (read(fd, shp, sz) != sz) {
    365       1.1  christos 			WARN(("read section headers"));
    366       1.1  christos 			return 1;
    367       1.1  christos 		}
    368       1.1  christos 
    369       1.1  christos 		shpp = maxp;
    370       1.1  christos 		maxp += roundup(sz, sizeof(long));
    371       1.1  christos 
    372       1.1  christos 		/*
    373  1.10.2.1   nathanw 		 * Now load the symbol sections themselves.  Make sure
    374  1.10.2.1   nathanw 		 * the sections are aligned. Don't bother with any
    375  1.10.2.1   nathanw 		 * string table that isn't referenced by a symbol
    376  1.10.2.1   nathanw 		 * table.
    377       1.1  christos 		 */
    378       1.1  christos 		for (first = 1, i = 0; i < elf->e_shnum; i++) {
    379  1.10.2.1   nathanw 			switch (shp[i].sh_type) {
    380  1.10.2.1   nathanw 			case SHT_STRTAB:
    381  1.10.2.1   nathanw 				for (j = 0; j < elf->e_shnum; j++)
    382  1.10.2.1   nathanw 					if (shp[j].sh_type == SHT_SYMTAB &&
    383  1.10.2.1   nathanw 					    shp[j].sh_link == i)
    384  1.10.2.1   nathanw 						goto havesym;
    385  1.10.2.1   nathanw 				/* FALLTHROUGH */
    386  1.10.2.1   nathanw 			default:
    387  1.10.2.1   nathanw 				/* Not loading this, so zero out the offset. */
    388  1.10.2.1   nathanw 				shp[i].sh_offset = 0;
    389  1.10.2.1   nathanw 				break;
    390  1.10.2.1   nathanw 			havesym:
    391  1.10.2.1   nathanw 			case SHT_SYMTAB:
    392  1.10.2.1   nathanw 				if (flags & LOAD_SYM) {
    393       1.1  christos 					PROGRESS(("%s%ld", first ? " [" : "+",
    394       1.1  christos 					    (u_long)shp[i].sh_size));
    395       1.1  christos 					if (lseek(fd, shp[i].sh_offset,
    396       1.1  christos 					    SEEK_SET) == -1) {
    397       1.1  christos 						WARN(("lseek symbols"));
    398       1.1  christos 						FREE(shp, sz);
    399       1.1  christos 						return 1;
    400       1.1  christos 					}
    401       1.1  christos 					if (READ(fd, maxp, shp[i].sh_size) !=
    402       1.1  christos 					    shp[i].sh_size) {
    403       1.1  christos 						WARN(("read symbols"));
    404       1.1  christos 						FREE(shp, sz);
    405       1.1  christos 						return 1;
    406       1.1  christos 					}
    407       1.1  christos 				}
    408  1.10.2.1   nathanw 				shp[i].sh_offset = maxp - elfp;
    409       1.1  christos 				maxp += roundup(shp[i].sh_size,
    410       1.1  christos 				    sizeof(long));
    411       1.1  christos 				first = 0;
    412       1.1  christos 			}
    413  1.10.2.1   nathanw 			/* Since we don't load .shstrtab, zero the name. */
    414  1.10.2.1   nathanw 			shp[i].sh_name = 0;
    415       1.1  christos 		}
    416       1.1  christos 		if (flags & LOAD_SYM) {
    417       1.1  christos 			BCOPY(shp, shpp, sz);
    418       1.1  christos 
    419  1.10.2.1   nathanw 			if (first == 0)
    420       1.1  christos 				PROGRESS(("]"));
    421       1.1  christos 		}
    422  1.10.2.1   nathanw 		FREE(shp, sz);
    423       1.1  christos 	}
    424       1.1  christos 
    425       1.1  christos 	/*
    426       1.1  christos 	 * Frob the copied ELF header to give information relative
    427       1.1  christos 	 * to elfp.
    428       1.1  christos 	 */
    429       1.1  christos 	if (flags & LOAD_HDR) {
    430       1.1  christos 		elf->e_phoff = 0;
    431       1.1  christos 		elf->e_shoff = sizeof(Elf_Ehdr);
    432       1.1  christos 		elf->e_phentsize = 0;
    433       1.1  christos 		elf->e_phnum = 0;
    434  1.10.2.1   nathanw 		elf->e_shstrndx = SHN_UNDEF;
    435       1.1  christos 		BCOPY(elf, elfp, sizeof(*elf));
    436       1.1  christos 	}
    437       1.1  christos 
    438       1.1  christos 	marks[MARK_START] = LOADADDR(minp);
    439       1.1  christos 	marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
    440  1.10.2.1   nathanw 	/*
    441  1.10.2.1   nathanw 	 * Since there can be more than one symbol section in the code
    442  1.10.2.1   nathanw 	 * and we need to find strtab too in order to do anything
    443  1.10.2.1   nathanw 	 * useful with the symbols, we just pass the whole elf
    444  1.10.2.1   nathanw 	 * header back and we let the kernel debugger find the
    445  1.10.2.1   nathanw 	 * location and number of symbols by itself.
    446  1.10.2.1   nathanw 	 */
    447       1.1  christos 	marks[MARK_NSYM] = 1;	/* XXX: Kernel needs >= 0 */
    448       1.1  christos 	marks[MARK_SYM] = LOADADDR(elfp);
    449       1.1  christos 	marks[MARK_END] = LOADADDR(maxp);
    450       1.1  christos 	return 0;
    451       1.1  christos }
    452       1.1  christos #endif /* BOOT_ELF */
    453       1.1  christos 
    454       1.1  christos #ifdef BOOT_AOUT
    455       1.1  christos static int
    456       1.1  christos aout_exec(fd, x, marks, flags)
    457       1.1  christos 	int fd;
    458       1.1  christos 	struct exec *x;
    459       1.1  christos 	u_long *marks;
    460       1.1  christos 	int flags;
    461       1.1  christos {
    462       1.1  christos 	u_long entry = x->a_entry;
    463       1.1  christos 	paddr_t aoutp = 0;
    464       1.1  christos 	paddr_t minp, maxp;
    465       1.1  christos 	int cc;
    466       1.1  christos 	paddr_t offset = marks[MARK_START];
    467       1.1  christos 	u_long magic = N_GETMAGIC(*x);
    468       1.1  christos 	int sub;
    469       1.1  christos 
    470       1.3     itohy 	/* In OMAGIC and NMAGIC, exec header isn't part of text segment */
    471       1.3     itohy 	if (magic == OMAGIC || magic == NMAGIC)
    472       1.1  christos 		sub = 0;
    473       1.1  christos 	else
    474       1.1  christos 		sub = sizeof(*x);
    475       1.1  christos 
    476       1.1  christos 	minp = maxp = ALIGNENTRY(entry);
    477       1.1  christos 
    478       1.1  christos 	if (lseek(fd, sizeof(*x), SEEK_SET) == -1)  {
    479       1.1  christos 		WARN(("lseek text"));
    480       1.1  christos 		return 1;
    481       1.1  christos 	}
    482       1.1  christos 
    483       1.1  christos 	/*
    484       1.1  christos 	 * Leave a copy of the exec header before the text.
    485       1.1  christos 	 * The kernel may use this to verify that the
    486       1.1  christos 	 * symbols were loaded by this boot program.
    487       1.1  christos 	 */
    488       1.3     itohy 	if (magic == OMAGIC || magic == NMAGIC) {
    489      1.10   tsutsui 		if (flags & LOAD_HDR && maxp >= sizeof(*x))
    490       1.1  christos 			BCOPY(x, maxp - sizeof(*x), sizeof(*x));
    491       1.1  christos 	}
    492       1.1  christos 	else {
    493       1.1  christos 		if (flags & LOAD_HDR)
    494       1.1  christos 			BCOPY(x, maxp, sizeof(*x));
    495       1.1  christos 		if (flags & (LOAD_HDR|COUNT_HDR))
    496       1.1  christos 			maxp += sizeof(*x);
    497       1.1  christos 	}
    498       1.1  christos 
    499       1.1  christos 	/*
    500       1.1  christos 	 * Read in the text segment.
    501       1.1  christos 	 */
    502       1.1  christos 	if (flags & LOAD_TEXT) {
    503       1.1  christos 		PROGRESS(("%ld", x->a_text));
    504       1.1  christos 
    505       1.1  christos 		if (READ(fd, maxp, x->a_text - sub) != x->a_text - sub) {
    506       1.1  christos 			WARN(("read text"));
    507       1.1  christos 			return 1;
    508       1.1  christos 		}
    509       1.1  christos 	} else {
    510       1.1  christos 		if (lseek(fd, x->a_text - sub, SEEK_CUR) == -1) {
    511       1.1  christos 			WARN(("seek text"));
    512       1.1  christos 			return 1;
    513       1.1  christos 		}
    514       1.1  christos 	}
    515       1.1  christos 	if (flags & (LOAD_TEXT|COUNT_TEXT))
    516       1.1  christos 		maxp += x->a_text - sub;
    517       1.1  christos 
    518       1.1  christos 	/*
    519       1.1  christos 	 * Provide alignment if required
    520       1.1  christos 	 */
    521       1.1  christos 	if (magic == ZMAGIC || magic == NMAGIC) {
    522       1.3     itohy 		int size = -(unsigned int)maxp & (__LDPGSZ - 1);
    523       1.1  christos 
    524       1.2  christos 		if (flags & LOAD_TEXTA) {
    525       1.2  christos 			PROGRESS(("/%d", size));
    526       1.1  christos 			BZERO(maxp, size);
    527       1.2  christos 		}
    528       1.1  christos 
    529       1.1  christos 		if (flags & (LOAD_TEXTA|COUNT_TEXTA))
    530       1.1  christos 			maxp += size;
    531       1.1  christos 	}
    532       1.1  christos 
    533       1.1  christos 	/*
    534       1.1  christos 	 * Read in the data segment.
    535       1.1  christos 	 */
    536       1.1  christos 	if (flags & LOAD_DATA) {
    537       1.1  christos 		PROGRESS(("+%ld", x->a_data));
    538       1.1  christos 
    539       1.1  christos 		if (READ(fd, maxp, x->a_data) != x->a_data) {
    540       1.1  christos 			WARN(("read data"));
    541       1.1  christos 			return 1;
    542       1.1  christos 		}
    543       1.1  christos 	}
    544       1.1  christos 	else {
    545       1.1  christos 		if (lseek(fd, x->a_data, SEEK_CUR) == -1) {
    546       1.1  christos 			WARN(("seek data"));
    547       1.1  christos 			return 1;
    548       1.1  christos 		}
    549       1.1  christos 	}
    550       1.1  christos 	if (flags & (LOAD_DATA|COUNT_DATA))
    551       1.1  christos 		maxp += x->a_data;
    552       1.1  christos 
    553       1.1  christos 	/*
    554       1.1  christos 	 * Zero out the BSS section.
    555       1.1  christos 	 * (Kernel doesn't care, but do it anyway.)
    556       1.1  christos 	 */
    557       1.1  christos 	if (flags & LOAD_BSS) {
    558       1.1  christos 		PROGRESS(("+%ld", x->a_bss));
    559       1.1  christos 
    560       1.1  christos 		BZERO(maxp, x->a_bss);
    561       1.1  christos 	}
    562       1.1  christos 
    563       1.1  christos 	if (flags & (LOAD_BSS|COUNT_BSS))
    564       1.1  christos 		maxp += x->a_bss;
    565       1.1  christos 
    566       1.1  christos 	/*
    567       1.1  christos 	 * Read in the symbol table and strings.
    568       1.1  christos 	 * (Always set the symtab size word.)
    569       1.1  christos 	 */
    570       1.1  christos 	if (flags & LOAD_SYM)
    571       1.1  christos 		BCOPY(&x->a_syms, maxp, sizeof(x->a_syms));
    572       1.1  christos 
    573       1.1  christos 	if (flags & (LOAD_SYM|COUNT_SYM)) {
    574       1.1  christos 		maxp += sizeof(x->a_syms);
    575       1.1  christos 		aoutp = maxp;
    576       1.1  christos 	}
    577       1.1  christos 
    578       1.1  christos 	if (x->a_syms > 0) {
    579       1.1  christos 		/* Symbol table and string table length word. */
    580       1.1  christos 
    581       1.1  christos 		if (flags & LOAD_SYM) {
    582       1.1  christos 			PROGRESS(("+[%ld", x->a_syms));
    583       1.1  christos 
    584       1.1  christos 			if (READ(fd, maxp, x->a_syms) != x->a_syms) {
    585       1.1  christos 				WARN(("read symbols"));
    586       1.1  christos 				return 1;
    587       1.1  christos 			}
    588       1.1  christos 		} else  {
    589       1.1  christos 			if (lseek(fd, x->a_syms, SEEK_CUR) == -1) {
    590       1.1  christos 				WARN(("seek symbols"));
    591       1.1  christos 				return 1;
    592       1.1  christos 			}
    593       1.1  christos 		}
    594       1.1  christos 		if (flags & (LOAD_SYM|COUNT_SYM))
    595       1.1  christos 			maxp += x->a_syms;
    596       1.1  christos 
    597       1.1  christos 		if (read(fd, &cc, sizeof(cc)) != sizeof(cc)) {
    598       1.1  christos 			WARN(("read string table"));
    599       1.1  christos 			return 1;
    600       1.1  christos 		}
    601       1.1  christos 
    602       1.1  christos 		if (flags & LOAD_SYM) {
    603       1.1  christos 			BCOPY(&cc, maxp, sizeof(cc));
    604       1.1  christos 
    605       1.1  christos 			/* String table. Length word includes itself. */
    606       1.1  christos 
    607       1.1  christos 			PROGRESS(("+%d]", cc));
    608       1.1  christos 		}
    609       1.1  christos 		if (flags & (LOAD_SYM|COUNT_SYM))
    610       1.1  christos 			maxp += sizeof(cc);
    611       1.1  christos 
    612       1.1  christos 		cc -= sizeof(int);
    613       1.1  christos 		if (cc <= 0) {
    614       1.1  christos 			WARN(("symbol table too short"));
    615       1.1  christos 			return 1;
    616       1.1  christos 		}
    617       1.1  christos 
    618       1.1  christos 		if (flags & LOAD_SYM) {
    619       1.1  christos 			if (READ(fd, maxp, cc) != cc) {
    620       1.1  christos 				WARN(("read strings"));
    621       1.1  christos 				return 1;
    622       1.1  christos 			}
    623       1.1  christos 		} else {
    624       1.1  christos 			if (lseek(fd, cc, SEEK_CUR) == -1) {
    625       1.1  christos 				WARN(("seek strings"));
    626       1.1  christos 				return 1;
    627       1.1  christos 			}
    628       1.1  christos 		}
    629       1.1  christos 		if (flags & (LOAD_SYM|COUNT_SYM))
    630       1.1  christos 			maxp += cc;
    631       1.1  christos 	}
    632       1.1  christos 
    633       1.1  christos 	marks[MARK_START] = LOADADDR(minp);
    634       1.1  christos 	marks[MARK_ENTRY] = LOADADDR(entry);
    635       1.1  christos 	marks[MARK_NSYM] = x->a_syms;
    636       1.1  christos 	marks[MARK_SYM] = LOADADDR(aoutp);
    637       1.1  christos 	marks[MARK_END] = LOADADDR(maxp);
    638       1.1  christos 	return 0;
    639       1.1  christos }
    640       1.1  christos #endif /* BOOT_AOUT */
    641