Home | History | Annotate | Line # | Download | only in libsa
loadfile.c revision 1.16
      1  1.16     bjh21 /* $NetBSD: loadfile.c,v 1.16 2001/07/31 21:09:52 bjh21 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.14     bjh21 	int i, j;
    277   1.1  christos 	size_t sz;
    278   1.1  christos 	int first;
    279  1.13      fvdl 	paddr_t minp = ~0, maxp = 0, pos = 0;
    280  1.13      fvdl 	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.14     bjh21 		 * Now load the symbol sections themselves.  Make sure
    374  1.14     bjh21 		 * the sections are aligned. Don't bother with any
    375  1.14     bjh21 		 * string table that isn't referenced by a symbol
    376  1.14     bjh21 		 * table.
    377   1.1  christos 		 */
    378   1.1  christos 		for (first = 1, i = 0; i < elf->e_shnum; i++) {
    379  1.14     bjh21 			switch (shp[i].sh_type) {
    380  1.14     bjh21 			case SHT_STRTAB:
    381  1.14     bjh21 				for (j = 0; j < elf->e_shnum; j++)
    382  1.14     bjh21 					if (shp[j].sh_type == SHT_SYMTAB &&
    383  1.14     bjh21 					    shp[j].sh_link == i)
    384  1.14     bjh21 						goto havesym;
    385  1.14     bjh21 				break;
    386  1.14     bjh21 			havesym:
    387  1.14     bjh21 			case SHT_SYMTAB:
    388  1.14     bjh21 				if (flags & LOAD_SYM) {
    389   1.1  christos 					PROGRESS(("%s%ld", first ? " [" : "+",
    390   1.1  christos 					    (u_long)shp[i].sh_size));
    391   1.1  christos 					if (lseek(fd, shp[i].sh_offset,
    392   1.1  christos 					    SEEK_SET) == -1) {
    393   1.1  christos 						WARN(("lseek symbols"));
    394   1.1  christos 						FREE(shp, sz);
    395   1.1  christos 						return 1;
    396   1.1  christos 					}
    397   1.1  christos 					if (READ(fd, maxp, shp[i].sh_size) !=
    398   1.1  christos 					    shp[i].sh_size) {
    399   1.1  christos 						WARN(("read symbols"));
    400   1.1  christos 						FREE(shp, sz);
    401   1.1  christos 						return 1;
    402   1.1  christos 					}
    403   1.1  christos 				}
    404  1.16     bjh21 				shp[i].sh_offset = maxp - elfp;
    405   1.1  christos 				maxp += roundup(shp[i].sh_size,
    406   1.1  christos 				    sizeof(long));
    407   1.1  christos 				first = 0;
    408   1.1  christos 			}
    409   1.1  christos 		}
    410   1.1  christos 		if (flags & LOAD_SYM) {
    411   1.1  christos 			BCOPY(shp, shpp, sz);
    412   1.1  christos 
    413  1.14     bjh21 			if (first == 0)
    414   1.1  christos 				PROGRESS(("]"));
    415   1.1  christos 		}
    416  1.15     bjh21 		FREE(shp, sz);
    417   1.1  christos 	}
    418   1.1  christos 
    419   1.1  christos 	/*
    420   1.1  christos 	 * Frob the copied ELF header to give information relative
    421   1.1  christos 	 * to elfp.
    422   1.1  christos 	 */
    423   1.1  christos 	if (flags & LOAD_HDR) {
    424   1.1  christos 		elf->e_phoff = 0;
    425   1.1  christos 		elf->e_shoff = sizeof(Elf_Ehdr);
    426   1.1  christos 		elf->e_phentsize = 0;
    427   1.1  christos 		elf->e_phnum = 0;
    428   1.1  christos 		BCOPY(elf, elfp, sizeof(*elf));
    429   1.1  christos 	}
    430   1.1  christos 
    431   1.1  christos 	marks[MARK_START] = LOADADDR(minp);
    432   1.1  christos 	marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
    433  1.12  christos 	/*
    434  1.12  christos 	 * Since there can be more than one symbol section in the code
    435  1.12  christos 	 * and we need to find strtab too in order to do anything
    436  1.12  christos 	 * useful with the symbols, we just pass the whole elf
    437  1.12  christos 	 * header back and we let the kernel debugger find the
    438  1.12  christos 	 * location and number of symbols by itself.
    439  1.12  christos 	 */
    440  1.12  christos 	marks[MARK_NSYM] = 1;	/* XXX: Kernel needs >= 0 */
    441  1.12  christos 	marks[MARK_SYM] = LOADADDR(elfp);
    442   1.1  christos 	marks[MARK_END] = LOADADDR(maxp);
    443   1.1  christos 	return 0;
    444   1.1  christos }
    445   1.1  christos #endif /* BOOT_ELF */
    446   1.1  christos 
    447   1.1  christos #ifdef BOOT_AOUT
    448   1.1  christos static int
    449   1.1  christos aout_exec(fd, x, marks, flags)
    450   1.1  christos 	int fd;
    451   1.1  christos 	struct exec *x;
    452   1.1  christos 	u_long *marks;
    453   1.1  christos 	int flags;
    454   1.1  christos {
    455   1.1  christos 	u_long entry = x->a_entry;
    456   1.1  christos 	paddr_t aoutp = 0;
    457   1.1  christos 	paddr_t minp, maxp;
    458   1.1  christos 	int cc;
    459   1.1  christos 	paddr_t offset = marks[MARK_START];
    460   1.1  christos 	u_long magic = N_GETMAGIC(*x);
    461   1.1  christos 	int sub;
    462   1.1  christos 
    463   1.3     itohy 	/* In OMAGIC and NMAGIC, exec header isn't part of text segment */
    464   1.3     itohy 	if (magic == OMAGIC || magic == NMAGIC)
    465   1.1  christos 		sub = 0;
    466   1.1  christos 	else
    467   1.1  christos 		sub = sizeof(*x);
    468   1.1  christos 
    469   1.1  christos 	minp = maxp = ALIGNENTRY(entry);
    470   1.1  christos 
    471   1.1  christos 	if (lseek(fd, sizeof(*x), SEEK_SET) == -1)  {
    472   1.1  christos 		WARN(("lseek text"));
    473   1.1  christos 		return 1;
    474   1.1  christos 	}
    475   1.1  christos 
    476   1.1  christos 	/*
    477   1.1  christos 	 * Leave a copy of the exec header before the text.
    478   1.1  christos 	 * The kernel may use this to verify that the
    479   1.1  christos 	 * symbols were loaded by this boot program.
    480   1.1  christos 	 */
    481   1.3     itohy 	if (magic == OMAGIC || magic == NMAGIC) {
    482  1.10   tsutsui 		if (flags & LOAD_HDR && maxp >= sizeof(*x))
    483   1.1  christos 			BCOPY(x, maxp - sizeof(*x), sizeof(*x));
    484   1.1  christos 	}
    485   1.1  christos 	else {
    486   1.1  christos 		if (flags & LOAD_HDR)
    487   1.1  christos 			BCOPY(x, maxp, sizeof(*x));
    488   1.1  christos 		if (flags & (LOAD_HDR|COUNT_HDR))
    489   1.1  christos 			maxp += sizeof(*x);
    490   1.1  christos 	}
    491   1.1  christos 
    492   1.1  christos 	/*
    493   1.1  christos 	 * Read in the text segment.
    494   1.1  christos 	 */
    495   1.1  christos 	if (flags & LOAD_TEXT) {
    496   1.1  christos 		PROGRESS(("%ld", x->a_text));
    497   1.1  christos 
    498   1.1  christos 		if (READ(fd, maxp, x->a_text - sub) != x->a_text - sub) {
    499   1.1  christos 			WARN(("read text"));
    500   1.1  christos 			return 1;
    501   1.1  christos 		}
    502   1.1  christos 	} else {
    503   1.1  christos 		if (lseek(fd, x->a_text - sub, SEEK_CUR) == -1) {
    504   1.1  christos 			WARN(("seek text"));
    505   1.1  christos 			return 1;
    506   1.1  christos 		}
    507   1.1  christos 	}
    508   1.1  christos 	if (flags & (LOAD_TEXT|COUNT_TEXT))
    509   1.1  christos 		maxp += x->a_text - sub;
    510   1.1  christos 
    511   1.1  christos 	/*
    512   1.1  christos 	 * Provide alignment if required
    513   1.1  christos 	 */
    514   1.1  christos 	if (magic == ZMAGIC || magic == NMAGIC) {
    515   1.3     itohy 		int size = -(unsigned int)maxp & (__LDPGSZ - 1);
    516   1.1  christos 
    517   1.2  christos 		if (flags & LOAD_TEXTA) {
    518   1.2  christos 			PROGRESS(("/%d", size));
    519   1.1  christos 			BZERO(maxp, size);
    520   1.2  christos 		}
    521   1.1  christos 
    522   1.1  christos 		if (flags & (LOAD_TEXTA|COUNT_TEXTA))
    523   1.1  christos 			maxp += size;
    524   1.1  christos 	}
    525   1.1  christos 
    526   1.1  christos 	/*
    527   1.1  christos 	 * Read in the data segment.
    528   1.1  christos 	 */
    529   1.1  christos 	if (flags & LOAD_DATA) {
    530   1.1  christos 		PROGRESS(("+%ld", x->a_data));
    531   1.1  christos 
    532   1.1  christos 		if (READ(fd, maxp, x->a_data) != x->a_data) {
    533   1.1  christos 			WARN(("read data"));
    534   1.1  christos 			return 1;
    535   1.1  christos 		}
    536   1.1  christos 	}
    537   1.1  christos 	else {
    538   1.1  christos 		if (lseek(fd, x->a_data, SEEK_CUR) == -1) {
    539   1.1  christos 			WARN(("seek data"));
    540   1.1  christos 			return 1;
    541   1.1  christos 		}
    542   1.1  christos 	}
    543   1.1  christos 	if (flags & (LOAD_DATA|COUNT_DATA))
    544   1.1  christos 		maxp += x->a_data;
    545   1.1  christos 
    546   1.1  christos 	/*
    547   1.1  christos 	 * Zero out the BSS section.
    548   1.1  christos 	 * (Kernel doesn't care, but do it anyway.)
    549   1.1  christos 	 */
    550   1.1  christos 	if (flags & LOAD_BSS) {
    551   1.1  christos 		PROGRESS(("+%ld", x->a_bss));
    552   1.1  christos 
    553   1.1  christos 		BZERO(maxp, x->a_bss);
    554   1.1  christos 	}
    555   1.1  christos 
    556   1.1  christos 	if (flags & (LOAD_BSS|COUNT_BSS))
    557   1.1  christos 		maxp += x->a_bss;
    558   1.1  christos 
    559   1.1  christos 	/*
    560   1.1  christos 	 * Read in the symbol table and strings.
    561   1.1  christos 	 * (Always set the symtab size word.)
    562   1.1  christos 	 */
    563   1.1  christos 	if (flags & LOAD_SYM)
    564   1.1  christos 		BCOPY(&x->a_syms, maxp, sizeof(x->a_syms));
    565   1.1  christos 
    566   1.1  christos 	if (flags & (LOAD_SYM|COUNT_SYM)) {
    567   1.1  christos 		maxp += sizeof(x->a_syms);
    568   1.1  christos 		aoutp = maxp;
    569   1.1  christos 	}
    570   1.1  christos 
    571   1.1  christos 	if (x->a_syms > 0) {
    572   1.1  christos 		/* Symbol table and string table length word. */
    573   1.1  christos 
    574   1.1  christos 		if (flags & LOAD_SYM) {
    575   1.1  christos 			PROGRESS(("+[%ld", x->a_syms));
    576   1.1  christos 
    577   1.1  christos 			if (READ(fd, maxp, x->a_syms) != x->a_syms) {
    578   1.1  christos 				WARN(("read symbols"));
    579   1.1  christos 				return 1;
    580   1.1  christos 			}
    581   1.1  christos 		} else  {
    582   1.1  christos 			if (lseek(fd, x->a_syms, SEEK_CUR) == -1) {
    583   1.1  christos 				WARN(("seek symbols"));
    584   1.1  christos 				return 1;
    585   1.1  christos 			}
    586   1.1  christos 		}
    587   1.1  christos 		if (flags & (LOAD_SYM|COUNT_SYM))
    588   1.1  christos 			maxp += x->a_syms;
    589   1.1  christos 
    590   1.1  christos 		if (read(fd, &cc, sizeof(cc)) != sizeof(cc)) {
    591   1.1  christos 			WARN(("read string table"));
    592   1.1  christos 			return 1;
    593   1.1  christos 		}
    594   1.1  christos 
    595   1.1  christos 		if (flags & LOAD_SYM) {
    596   1.1  christos 			BCOPY(&cc, maxp, sizeof(cc));
    597   1.1  christos 
    598   1.1  christos 			/* String table. Length word includes itself. */
    599   1.1  christos 
    600   1.1  christos 			PROGRESS(("+%d]", cc));
    601   1.1  christos 		}
    602   1.1  christos 		if (flags & (LOAD_SYM|COUNT_SYM))
    603   1.1  christos 			maxp += sizeof(cc);
    604   1.1  christos 
    605   1.1  christos 		cc -= sizeof(int);
    606   1.1  christos 		if (cc <= 0) {
    607   1.1  christos 			WARN(("symbol table too short"));
    608   1.1  christos 			return 1;
    609   1.1  christos 		}
    610   1.1  christos 
    611   1.1  christos 		if (flags & LOAD_SYM) {
    612   1.1  christos 			if (READ(fd, maxp, cc) != cc) {
    613   1.1  christos 				WARN(("read strings"));
    614   1.1  christos 				return 1;
    615   1.1  christos 			}
    616   1.1  christos 		} else {
    617   1.1  christos 			if (lseek(fd, cc, SEEK_CUR) == -1) {
    618   1.1  christos 				WARN(("seek strings"));
    619   1.1  christos 				return 1;
    620   1.1  christos 			}
    621   1.1  christos 		}
    622   1.1  christos 		if (flags & (LOAD_SYM|COUNT_SYM))
    623   1.1  christos 			maxp += cc;
    624   1.1  christos 	}
    625   1.1  christos 
    626   1.1  christos 	marks[MARK_START] = LOADADDR(minp);
    627   1.1  christos 	marks[MARK_ENTRY] = LOADADDR(entry);
    628   1.1  christos 	marks[MARK_NSYM] = x->a_syms;
    629   1.1  christos 	marks[MARK_SYM] = LOADADDR(aoutp);
    630   1.1  christos 	marks[MARK_END] = LOADADDR(maxp);
    631   1.1  christos 	return 0;
    632   1.1  christos }
    633   1.1  christos #endif /* BOOT_AOUT */
    634