Home | History | Annotate | Line # | Download | only in bootxx
bootxx.c revision 1.5
      1  1.5    thomas /*	$NetBSD: bootxx.c,v 1.5 2001/09/08 16:57:09 thomas Exp $	*/
      2  1.1       leo 
      3  1.1       leo /*
      4  1.1       leo  * Copyright (c) 1995 Waldi Ravens.
      5  1.1       leo  * All rights reserved.
      6  1.1       leo  *
      7  1.1       leo  * Redistribution and use in source and binary forms, with or without
      8  1.1       leo  * modification, are permitted provided that the following conditions
      9  1.1       leo  * are met:
     10  1.1       leo  * 1. Redistributions of source code must retain the above copyright
     11  1.1       leo  *    notice, this list of conditions and the following disclaimer.
     12  1.1       leo  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1       leo  *    notice, this list of conditions and the following disclaimer in the
     14  1.1       leo  *    documentation and/or other materials provided with the distribution.
     15  1.1       leo  * 3. All advertising materials mentioning features or use of this software
     16  1.1       leo  *    must display the following acknowledgement:
     17  1.1       leo  *        This product includes software developed by Waldi Ravens.
     18  1.1       leo  * 4. The name of the author may not be used to endorse or promote products
     19  1.1       leo  *    derived from this software without specific prior written permission
     20  1.1       leo  *
     21  1.1       leo  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  1.1       leo  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  1.1       leo  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  1.1       leo  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  1.1       leo  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  1.1       leo  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  1.1       leo  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  1.1       leo  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  1.1       leo  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  1.1       leo  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  1.1       leo  */
     32  1.1       leo 
     33  1.1       leo #define	boot_BSD	bsd_startup
     34  1.1       leo 
     35  1.1       leo #include <stand.h>
     36  1.2       leo #include <atari_stand.h>
     37  1.1       leo #include <string.h>
     38  1.1       leo #include <libkern.h>
     39  1.1       leo #include <kparamb.h>
     40  1.4  jdolecek #include <sys/boot_flag.h>
     41  1.5    thomas #ifndef __ELF__
     42  1.1       leo #include <sys/exec.h>
     43  1.5    thomas #else
     44  1.5    thomas #include <sys/exec_elf.h>
     45  1.5    thomas #endif
     46  1.1       leo #include <sys/reboot.h>
     47  1.1       leo #include <machine/cpu.h>
     48  1.1       leo 
     49  1.1       leo #include "bootxx.h"
     50  1.1       leo 
     51  1.1       leo void	boot_BSD __P((kparb *)__attribute__((noreturn)));
     52  1.1       leo int	load_BSD __P((osdsc *));
     53  1.1       leo int	sys_info __P((osdsc *));
     54  1.1       leo int	usr_info __P((osdsc *));
     55  1.1       leo 
     56  1.1       leo int
     57  1.1       leo bootxx(readsector, disklabel, autoboot)
     58  1.1       leo 	void	*readsector,
     59  1.1       leo 		*disklabel;
     60  1.1       leo 	int	autoboot;
     61  1.1       leo {
     62  1.1       leo 	static osdsc	os_desc;
     63  1.1       leo 	extern char	end[], edata[];
     64  1.1       leo 	osdsc		*od = &os_desc;
     65  1.1       leo 
     66  1.1       leo 	bzero(edata, end - edata);
     67  1.1       leo 
     68  1.5    thomas 	printf("\033v\nNetBSD/Atari boot loader ($Revision: 1.5 $)\n\n");
     69  1.1       leo 
     70  1.1       leo 	if (init_dskio(readsector, disklabel, -1))
     71  1.1       leo 		return(-1);
     72  1.1       leo 
     73  1.1       leo 	if (sys_info(od))
     74  1.1       leo 		return(-2);
     75  1.1       leo 
     76  1.1       leo 	for (;;) {
     77  1.1       leo 		od->rootfs = 0;			/* partition a */
     78  1.1       leo 		od->osname = "/netbsd";
     79  1.1       leo 		od->ostype = &od->osname[1];
     80  1.1       leo 		od->boothowto = (RB_RDONLY);
     81  1.1       leo 
     82  1.1       leo 		if (!autoboot) {
     83  1.1       leo 			int	pref;
     84  1.1       leo 
     85  1.1       leo 			od->boothowto = (RB_RDONLY|RB_SINGLE);
     86  1.1       leo 			pref = usr_info(od);
     87  1.1       leo 			if (pref < 0)
     88  1.1       leo 				continue;
     89  1.1       leo 			if (pref > 0)
     90  1.1       leo 				return(pref);
     91  1.1       leo 		}
     92  1.1       leo 		autoboot = 0;			/* in case auto boot fails */
     93  1.1       leo 
     94  1.1       leo 		if (init_dskio(readsector, disklabel, od->rootfs))
     95  1.1       leo 			continue;
     96  1.1       leo 
     97  1.1       leo 		if (load_BSD(od))
     98  1.1       leo 			continue;
     99  1.1       leo 
    100  1.1       leo 		boot_BSD(&od->kp);
    101  1.1       leo 	}
    102  1.1       leo 	/* NOTREACHED */
    103  1.1       leo }
    104  1.1       leo 
    105  1.1       leo int
    106  1.1       leo sys_info(od)
    107  1.1       leo 	osdsc	*od;
    108  1.1       leo {
    109  1.1       leo 	long	*jar;
    110  1.1       leo 	int	tos;
    111  1.1       leo 
    112  1.1       leo 	od->stmem_size = *ADDR_PHYSTOP;
    113  1.1       leo 
    114  1.1       leo 	if (*ADDR_CHKRAMTOP == RAMTOP_MAGIC) {
    115  1.1       leo 		od->ttmem_size  = *ADDR_RAMTOP;
    116  1.1       leo 		if (od->ttmem_size > TTRAM_BASE) {
    117  1.1       leo 			od->ttmem_size  -= TTRAM_BASE;
    118  1.1       leo 			od->ttmem_start  = TTRAM_BASE;
    119  1.1       leo 		}
    120  1.1       leo 	}
    121  1.1       leo 
    122  1.1       leo 	tos = (*ADDR_SYSBASE)->os_version;
    123  1.1       leo 	if ((tos > 0x300) && (tos < 0x306))
    124  1.1       leo 		od->cputype = ATARI_CLKBROKEN;
    125  1.1       leo 
    126  1.1       leo 	if ((jar = *ADDR_P_COOKIE)) {
    127  1.1       leo 		while (jar[0]) {
    128  1.5    thomas 			if ((jar[0] == 0x5f435055L) && ((jar[1] % 10) == 0)) { /* _CPU  */
    129  1.5    thomas 				switch(jar[1] / 10) {
    130  1.1       leo 					case 0:
    131  1.1       leo 						od->cputype |= ATARI_68000;
    132  1.1       leo 						break;
    133  1.5    thomas 					case 1:
    134  1.1       leo 						od->cputype |= ATARI_68010;
    135  1.1       leo 						break;
    136  1.5    thomas 					case 2:
    137  1.1       leo 						od->cputype |= ATARI_68020;
    138  1.1       leo 						break;
    139  1.5    thomas 					case 3:
    140  1.1       leo 						od->cputype |= ATARI_68030;
    141  1.1       leo 						break;
    142  1.5    thomas 					case 4:
    143  1.1       leo 						od->cputype |= ATARI_68040;
    144  1.3       leo 						break;
    145  1.5    thomas 					case 6:
    146  1.3       leo 						od->cputype |= ATARI_68060;
    147  1.1       leo 						break;
    148  1.1       leo 				}
    149  1.1       leo 			}
    150  1.1       leo 			jar += 2;
    151  1.1       leo 		}
    152  1.1       leo 	}
    153  1.1       leo 	if (!(od->cputype & ATARI_ANYCPU)) {
    154  1.1       leo 		printf("Unknown CPU-type.\n");
    155  1.1       leo 		return(-1);
    156  1.1       leo 	}
    157  1.1       leo 
    158  1.1       leo 	return(0);
    159  1.1       leo }
    160  1.1       leo 
    161  1.1       leo int
    162  1.1       leo usr_info(od)
    163  1.1       leo 	osdsc	*od;
    164  1.1       leo {
    165  1.1       leo 	static char	line[800];
    166  1.1       leo 	char		c, *p = line;
    167  1.1       leo 
    168  1.1       leo 	printf("\nEnter os-type [.%s] root-fs [:a] kernel [%s]"
    169  1.1       leo 	       " options [none]:\n\033e", od->ostype, od->osname);
    170  1.1       leo 	gets(p);
    171  1.1       leo 	printf("\033f");
    172  1.1       leo 
    173  1.1       leo 	for (;;) {
    174  1.1       leo 		while (isspace(*p))
    175  1.1       leo 			*p++ = '\0';
    176  1.1       leo 
    177  1.1       leo 		switch (*p++) {
    178  1.1       leo 		  case '\0':
    179  1.1       leo 			goto done;
    180  1.1       leo 		  case ':':
    181  1.1       leo 			if ((c = *p) >= 'a' && c <= 'z')
    182  1.1       leo 				od->rootfs = c - 'a';
    183  1.1       leo 			else if (c >= 'A' && c <= 'Z')
    184  1.1       leo 				od->rootfs = c - ('A' - 27);
    185  1.1       leo 			else return(-1);
    186  1.1       leo 
    187  1.1       leo 			if (!od->rootfs)
    188  1.1       leo 				break;
    189  1.1       leo 			*p = 'b';
    190  1.1       leo 			/* FALLTHROUGH */
    191  1.1       leo 		  case '-':
    192  1.1       leo 			if ((c = *p) == 'a')
    193  1.1       leo 				od->boothowto &= ~RB_SINGLE;
    194  1.1       leo 			else if (c == 'b')
    195  1.1       leo 				od->boothowto |= RB_ASKNAME;
    196  1.4  jdolecek 			else
    197  1.4  jdolecek 				BOOT_FLAG(c, od->boothowto);
    198  1.1       leo 			break;
    199  1.1       leo 		  case '.':
    200  1.1       leo 			od->ostype = p;
    201  1.1       leo 			break;
    202  1.1       leo 		  case '/':
    203  1.1       leo 			od->osname = --p;
    204  1.1       leo 			break;
    205  1.1       leo 		  default:
    206  1.1       leo 			return(-1);
    207  1.1       leo 		}
    208  1.1       leo 
    209  1.1       leo 		while ((c = *p) && !isspace(c))
    210  1.1       leo 			p += 1;
    211  1.1       leo 	}
    212  1.1       leo 
    213  1.1       leo done:
    214  1.1       leo 	c = od->ostype[0];
    215  1.1       leo 	if (isupper(c))
    216  1.1       leo 		c = tolower(c);
    217  1.1       leo 
    218  1.1       leo 	switch (c) {
    219  1.1       leo 	  case 'n':		/* NetBSD */
    220  1.1       leo 		return(0);
    221  1.1       leo 	  case 'l':		/* Linux  */
    222  1.1       leo 		return(0x10);
    223  1.1       leo 	  case 'a':		/* ASV    */
    224  1.1       leo 		return(0x40);
    225  1.1       leo 	  case 't':		/* TOS    */
    226  1.1       leo 		return(0x80);
    227  1.1       leo 	  default:
    228  1.1       leo 		return(-1);
    229  1.1       leo 	}
    230  1.1       leo }
    231  1.1       leo 
    232  1.5    thomas #ifndef __ELF__		/* a.out */
    233  1.1       leo int
    234  1.1       leo load_BSD(od)
    235  1.1       leo 	osdsc		*od;
    236  1.1       leo {
    237  1.1       leo 	struct exec	hdr;
    238  1.1       leo 	int		err, fd;
    239  1.1       leo 	u_int		textsz, strsz;
    240  1.1       leo 
    241  1.1       leo 	/*
    242  1.1       leo 	 * Read kernel's exec-header.
    243  1.1       leo 	 */
    244  1.1       leo 	err = 1;
    245  1.1       leo 	if ((fd = open(od->osname, 0)) < 0)
    246  1.1       leo 		goto error;
    247  1.1       leo 	err = 2;
    248  1.1       leo 	if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
    249  1.1       leo 		goto error;
    250  1.1       leo 	err = 3;
    251  1.5    thomas 	if ((N_GETMAGIC(hdr) != NMAGIC) && (N_GETMAGIC(hdr) != OMAGIC))
    252  1.1       leo 		goto error;
    253  1.1       leo 
    254  1.1       leo 	/*
    255  1.1       leo 	 * Extract sizes from kernel executable.
    256  1.1       leo 	 */
    257  1.1       leo 	textsz     = (hdr.a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1);
    258  1.1       leo 	od->ksize  = textsz + hdr.a_data + hdr.a_bss;
    259  1.1       leo 	od->kentry = hdr.a_entry;
    260  1.1       leo 	od->kstart = NULL;
    261  1.1       leo 	od->k_esym = 0;
    262  1.1       leo 
    263  1.1       leo 	if (hdr.a_syms) {
    264  1.1       leo 	    u_int x = sizeof(hdr) + hdr.a_text + hdr.a_data + hdr.a_syms;
    265  1.1       leo 	    err = 8;
    266  1.1       leo 	    if (lseek(fd, (off_t)x, SEEK_SET) != x)
    267  1.1       leo 		goto error;
    268  1.1       leo 	    err = 9;
    269  1.1       leo 	    if (read(fd, &strsz, sizeof(strsz)) != sizeof(strsz))
    270  1.1       leo 		goto error;
    271  1.1       leo 	    err = 10;
    272  1.1       leo 	    if (lseek(fd, (off_t)sizeof(hdr), SEEK_SET) != sizeof(hdr))
    273  1.1       leo 		goto error;
    274  1.1       leo 	    od->ksize += sizeof(strsz) + hdr.a_syms + strsz;
    275  1.1       leo 	}
    276  1.1       leo 
    277  1.1       leo 	/*
    278  1.1       leo 	 * Read text & data, clear bss
    279  1.1       leo 	 */
    280  1.1       leo 	err = 16;
    281  1.1       leo 	if ((od->kstart = alloc(od->ksize)) == NULL)
    282  1.1       leo 		goto error;
    283  1.1       leo 	err = 17;
    284  1.1       leo 	if (read(fd, od->kstart, hdr.a_text) != hdr.a_text)
    285  1.1       leo 		goto error;
    286  1.1       leo 	err = 18;
    287  1.1       leo 	if (read(fd, od->kstart + textsz, hdr.a_data) != hdr.a_data)
    288  1.1       leo 		goto error;
    289  1.1       leo 	bzero(od->kstart + textsz + hdr.a_data, hdr.a_bss);
    290  1.1       leo 
    291  1.1       leo 	/*
    292  1.1       leo 	 * Read symbol and string table
    293  1.1       leo 	 */
    294  1.1       leo 	if (hdr.a_syms) {
    295  1.1       leo 		char *p = od->kstart + textsz + hdr.a_data + hdr.a_bss;
    296  1.1       leo 		*((u_int32_t *)p)++ = hdr.a_syms;
    297  1.1       leo 		err = 24;
    298  1.1       leo 		if (read(fd, p, hdr.a_syms) != hdr.a_syms)
    299  1.1       leo 			goto error;
    300  1.1       leo 		p += hdr.a_syms;
    301  1.1       leo 		err = 25;
    302  1.1       leo 		if (read(fd, p, strsz) != strsz)
    303  1.1       leo 			goto error;
    304  1.1       leo 		od->k_esym = (p - (char *)od->kstart) + strsz;
    305  1.1       leo 	}
    306  1.1       leo 
    307  1.1       leo 	return(0);
    308  1.1       leo 
    309  1.1       leo error:
    310  1.1       leo 	if (fd >= 0) {
    311  1.1       leo 		if (od->kstart)
    312  1.1       leo 			free(od->kstart, od->ksize);
    313  1.1       leo 		close(fd);
    314  1.1       leo 	}
    315  1.1       leo 	printf("Error %d in load_BSD.\n", err);
    316  1.1       leo 	return(-1);
    317  1.1       leo }
    318  1.5    thomas 
    319  1.5    thomas #else			/* __ELF__ */
    320  1.5    thomas 
    321  1.5    thomas #define ELFMAGIC	((ELFMAG0 << 24) | (ELFMAG1 << 16) | (ELFMAG2 << 8) | ELFMAG3)
    322  1.5    thomas 
    323  1.5    thomas int
    324  1.5    thomas load_BSD(od)
    325  1.5    thomas 	osdsc		*od;
    326  1.5    thomas {
    327  1.5    thomas     int err, fd, i, j;
    328  1.5    thomas     Elf32_Ehdr ehdr;
    329  1.5    thomas     Elf32_Word kernsize;
    330  1.5    thomas #if 0
    331  1.5    thomas     Elf32_Word symsize, symstart;
    332  1.5    thomas #endif
    333  1.5    thomas 
    334  1.5    thomas     /*
    335  1.5    thomas      * Read kernel's exec-header.
    336  1.5    thomas      */
    337  1.5    thomas     od->kstart = NULL;
    338  1.5    thomas     err = 1;
    339  1.5    thomas     if ((fd = open(od->osname, 0)) < 0)
    340  1.5    thomas 	goto error;
    341  1.5    thomas     err = 2;
    342  1.5    thomas     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
    343  1.5    thomas 	goto error;
    344  1.5    thomas     err = 3;
    345  1.5    thomas     if (*((u_int *)ehdr.e_ident) != ELFMAGIC)
    346  1.5    thomas 	goto error;
    347  1.5    thomas     err = 4;
    348  1.5    thomas     if (lseek(fd, (off_t)ehdr.e_phoff, SEEK_SET) < 0)
    349  1.5    thomas 	goto error;
    350  1.5    thomas 
    351  1.5    thomas     /*
    352  1.5    thomas      * calculate highest used address
    353  1.5    thomas      */
    354  1.5    thomas     i = ehdr.e_phnum + 1;
    355  1.5    thomas     kernsize = 0;
    356  1.5    thomas     while (--i) {
    357  1.5    thomas 	Elf32_Phdr phdr;
    358  1.5    thomas 	Elf32_Word sum;
    359  1.5    thomas 	err = 5;
    360  1.5    thomas 	if (read(fd, &phdr, sizeof(phdr)) != sizeof(phdr))
    361  1.5    thomas 	    goto error;
    362  1.5    thomas 	sum = phdr.p_vaddr + phdr.p_memsz;
    363  1.5    thomas 	if ((phdr.p_flags & (PF_W|PF_X)) && (sum > kernsize))
    364  1.5    thomas 	    kernsize = sum;
    365  1.5    thomas     }
    366  1.5    thomas 
    367  1.5    thomas #if 0
    368  1.5    thomas     /*
    369  1.5    thomas      * look for symbols and calculate the size
    370  1.5    thomas      */
    371  1.5    thomas     err = 6;
    372  1.5    thomas     if (lseek(fd, (off_t)ehdr.e_shoff, SEEK_SET) < 0)
    373  1.5    thomas 	goto error;
    374  1.5    thomas     i = ehdr.e_shnum + 1;
    375  1.5    thomas     symsize = 0;
    376  1.5    thomas     symstart = 0;
    377  1.5    thomas     while (--i) {
    378  1.5    thomas 	Elf32_Shdr shdr;
    379  1.5    thomas 	err = 7;
    380  1.5    thomas 	if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
    381  1.5    thomas 	    goto error;
    382  1.5    thomas 	if ((shdr.sh_type == SHT_SYMTAB) || (shdr.sh_type == SHT_STRTAB))
    383  1.5    thomas 	    symsize += shdr.sh_size;
    384  1.5    thomas     }
    385  1.5    thomas 
    386  1.5    thomas     if (symsize) {
    387  1.5    thomas 	symstart = kernsize;
    388  1.5    thomas 	kernsize += symsize + sizeof(ehdr) + ehdr.e_shoff * sizeof(Elf32_Shdr);
    389  1.5    thomas     }
    390  1.5    thomas #endif
    391  1.5    thomas 
    392  1.5    thomas     od->ksize = kernsize;
    393  1.5    thomas     od->kentry = ehdr.e_entry;
    394  1.5    thomas     od->k_esym = 0;
    395  1.5    thomas 
    396  1.5    thomas     err = 10;
    397  1.5    thomas     if ((od->kstart = alloc(od->ksize)) == NULL)
    398  1.5    thomas 	goto error;
    399  1.5    thomas 
    400  1.5    thomas     /*
    401  1.5    thomas      * read segements, clear bss
    402  1.5    thomas      */
    403  1.5    thomas     i = ehdr.e_phnum + 1;
    404  1.5    thomas     j = 0;
    405  1.5    thomas     while (--i) {
    406  1.5    thomas 	Elf32_Phdr phdr;
    407  1.5    thomas 	Elf32_Word pos;
    408  1.5    thomas 	u_char *p;
    409  1.5    thomas 	pos = ehdr.e_phoff + j * sizeof(phdr);
    410  1.5    thomas 	err = 11;
    411  1.5    thomas 	if (lseek(fd, (off_t)pos, SEEK_SET) < 0)
    412  1.5    thomas 	    goto error;
    413  1.5    thomas 	err = 12;
    414  1.5    thomas 	if (read(fd, &phdr, sizeof(phdr)) != sizeof(phdr))
    415  1.5    thomas 	    goto error;
    416  1.5    thomas 	if (phdr.p_flags & (PF_W|PF_X)) {
    417  1.5    thomas 	    err = 13;
    418  1.5    thomas             if (lseek(fd, (off_t)phdr.p_offset, SEEK_SET) < 0)
    419  1.5    thomas 		goto error;
    420  1.5    thomas 	    p = (u_char *)(od->kstart) + phdr.p_vaddr;
    421  1.5    thomas 	    err = 14;
    422  1.5    thomas 	    if (read(fd, p, phdr.p_filesz) != phdr.p_filesz)
    423  1.5    thomas 		goto error;
    424  1.5    thomas 	    if (phdr.p_memsz > phdr.p_filesz)
    425  1.5    thomas 		bzero(p + phdr.p_filesz, phdr.p_memsz - phdr.p_filesz);
    426  1.5    thomas 	}
    427  1.5    thomas 	++j;
    428  1.5    thomas     }
    429  1.5    thomas 
    430  1.5    thomas #if 0
    431  1.5    thomas     /*
    432  1.5    thomas      * read symbol and string
    433  1.5    thomas      */
    434  1.5    thomas     if (symsize) {
    435  1.5    thomas 	Elf32_Word pos;
    436  1.5    thomas 	int k = ehdr.e_shoff;
    437  1.5    thomas 	j = symstart + sizeof(ehdr);
    438  1.5    thomas 	pos = symstart + sizeof(ehdr) + ehdr.e_shoff * sizeof(Elf32_Shdr);
    439  1.5    thomas 	bzero((u_char *)(od->kstart) + j, ehdr.e_shoff * sizeof(Elf32_Shdr));
    440  1.5    thomas 	i = ehdr.e_shnum + 1;
    441  1.5    thomas 	while (--i) {
    442  1.5    thomas 	    Elf32_Shdr shdr;
    443  1.5    thomas 	    u_char *p;
    444  1.5    thomas 	    err = 20;
    445  1.5    thomas 	    if (lseek(fd, (off_t)k, SEEK_SET) < 0)
    446  1.5    thomas 		goto error;
    447  1.5    thomas 	    err = 21;
    448  1.5    thomas 	    if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
    449  1.5    thomas 		goto error;
    450  1.5    thomas 	    if ((shdr.sh_type == SHT_SYMTAB) || (shdr.sh_type == SHT_STRTAB)) {
    451  1.5    thomas 		err = 22;
    452  1.5    thomas 		if (lseek(fd, (off_t)shdr.sh_offset, SEEK_SET) < 0)
    453  1.5    thomas 		    goto error;
    454  1.5    thomas 		p = (u_char *)(od->kstart) + pos;
    455  1.5    thomas 		err = 23;
    456  1.5    thomas 		if (read(fd, p, shdr.sh_size) != shdr.sh_size)
    457  1.5    thomas 		    goto error;
    458  1.5    thomas 		shdr.sh_offset = pos;
    459  1.5    thomas 		pos += shdr.sh_size;
    460  1.5    thomas 		bcopy(&shdr, (u_char *)(od->kstart) + j, sizeof(shdr));
    461  1.5    thomas 	    }
    462  1.5    thomas 	    j += sizeof(shdr);
    463  1.5    thomas 	    k += sizeof(shdr);
    464  1.5    thomas 	}
    465  1.5    thomas 	ehdr.e_shoff = symstart + sizeof(ehdr);
    466  1.5    thomas 	bcopy(&ehdr, (u_char *)(od->kstart) + symstart, sizeof(ehdr));
    467  1.5    thomas     }
    468  1.5    thomas #endif
    469  1.5    thomas 
    470  1.5    thomas     return(0);
    471  1.5    thomas 
    472  1.5    thomas error:
    473  1.5    thomas 
    474  1.5    thomas     if (fd >= 0) {
    475  1.5    thomas 	if (od->kstart)
    476  1.5    thomas 	    free(od->kstart, od->ksize);
    477  1.5    thomas 	close(fd);
    478  1.5    thomas     }
    479  1.5    thomas     printf("Error %d in load_BSD.\n", err);
    480  1.5    thomas     return(-1);
    481  1.5    thomas 
    482  1.5    thomas }
    483  1.5    thomas #endif /* __ELF__ */
    484