Home | History | Annotate | Line # | Download | only in bootcoff
osloader.c revision 1.1
      1  1.1  msaitoh /*********************************************************************
      2  1.1  msaitoh  *      NetBSD(SH3) boot loader
      3  1.1  msaitoh  *
      4  1.1  msaitoh  *                1998.11.10
      5  1.1  msaitoh  *                     By T.Horiuchi (Brains, Corp.)
      6  1.1  msaitoh  *********************************************************************/
      7  1.1  msaitoh 
      8  1.1  msaitoh #include <stdio.h>
      9  1.1  msaitoh #include <stdlib.h>
     10  1.1  msaitoh #include <sys/param.h>
     11  1.1  msaitoh #include <sys/gmon.h>
     12  1.1  msaitoh #include <sys/stat.h>
     13  1.1  msaitoh #include <sys/sysctl.h>
     14  1.1  msaitoh #include <sys/socket.h>
     15  1.1  msaitoh #include <sys/file.h>
     16  1.1  msaitoh #include <vm/vm_param.h>
     17  1.1  msaitoh #include <machine/cpu.h>
     18  1.1  msaitoh #include "osloader.h"
     19  1.1  msaitoh 
     20  1.1  msaitoh #define vm_page_size (1<<12)
     21  1.1  msaitoh 
     22  1.1  msaitoh char *netbsd = "/netbsd";
     23  1.1  msaitoh struct coff_filehdr FileHdr;
     24  1.1  msaitoh struct coff_aouthdr AoutHdr;
     25  1.1  msaitoh 
     26  1.1  msaitoh static int coff_find_section __P((FILE *, struct coff_filehdr *,
     27  1.1  msaitoh 			     struct coff_scnhdr *, int));
     28  1.1  msaitoh 
     29  1.1  msaitoh void LoadAndReset __P((char *));
     30  1.1  msaitoh 
     31  1.1  msaitoh /*
     32  1.1  msaitoh  * coff_find_section - load specified section header
     33  1.1  msaitoh  *
     34  1.1  msaitoh  * TODO - optimize by reading all section headers in at once
     35  1.1  msaitoh  */
     36  1.1  msaitoh 
     37  1.1  msaitoh static int
     38  1.1  msaitoh coff_find_section( fd, fp, sh, s_type)
     39  1.1  msaitoh 	FILE *fd;
     40  1.1  msaitoh 	struct coff_filehdr *fp;
     41  1.1  msaitoh 	struct coff_scnhdr *sh;
     42  1.1  msaitoh 	int s_type;
     43  1.1  msaitoh {
     44  1.1  msaitoh 	int i, pos, siz;
     45  1.1  msaitoh 
     46  1.1  msaitoh 	pos = COFF_HDR_SIZE;
     47  1.1  msaitoh 	for (i = 0; i < fp->f_nscns; i++, pos += sizeof(struct coff_scnhdr)) {
     48  1.1  msaitoh 		siz = sizeof(struct coff_scnhdr);
     49  1.1  msaitoh 		if( fread(sh, 1, siz, fd ) != siz ){
     50  1.1  msaitoh 			perror("osloader");
     51  1.1  msaitoh 			exit( 1 );
     52  1.1  msaitoh 		}
     53  1.1  msaitoh 
     54  1.1  msaitoh 		if (sh->s_flags == s_type)
     55  1.1  msaitoh 			return 0;
     56  1.1  msaitoh 	}
     57  1.1  msaitoh 	return -1;
     58  1.1  msaitoh }
     59  1.1  msaitoh 
     60  1.1  msaitoh void
     61  1.1  msaitoh LoadAndReset( char *osimage )
     62  1.1  msaitoh {
     63  1.1  msaitoh 	int mib[2];
     64  1.1  msaitoh 	u_long val;
     65  1.1  msaitoh 	int len;
     66  1.1  msaitoh 
     67  1.1  msaitoh 	mib[0] = CTL_MACHDEP;
     68  1.1  msaitoh 	mib[1] = CPU_LOADANDRESET;
     69  1.1  msaitoh 	val = (u_long)osimage;
     70  1.1  msaitoh 	len = sizeof( val );
     71  1.1  msaitoh 
     72  1.1  msaitoh 	sysctl(mib, 2, NULL, NULL, &val, len);
     73  1.1  msaitoh }
     74  1.1  msaitoh 
     75  1.1  msaitoh int
     76  1.1  msaitoh main(int argc, char *argv[] )
     77  1.1  msaitoh {
     78  1.1  msaitoh 	FILE *fp;
     79  1.1  msaitoh 	int error;
     80  1.1  msaitoh 	long dsize;
     81  1.1  msaitoh 	struct coff_scnhdr sh;
     82  1.1  msaitoh 	u_long ep_taddr;
     83  1.1  msaitoh 	u_long ep_tsize;
     84  1.1  msaitoh 	u_long toffset;
     85  1.1  msaitoh 	u_long ep_daddr;
     86  1.1  msaitoh 	u_long ep_dsize;
     87  1.1  msaitoh 	u_long doffset;
     88  1.1  msaitoh 	char *osimage;
     89  1.1  msaitoh 	char *p;
     90  1.1  msaitoh 	int i;
     91  1.1  msaitoh 	u_long cksum;
     92  1.1  msaitoh 	u_long size;
     93  1.1  msaitoh 
     94  1.1  msaitoh #if 0
     95  1.1  msaitoh 	printf("osloader: start\n");
     96  1.1  msaitoh #endif
     97  1.1  msaitoh 
     98  1.1  msaitoh 	fp = fopen( netbsd, "r" );
     99  1.1  msaitoh 	if( fp == NULL ){
    100  1.1  msaitoh 		perror("osloader");
    101  1.1  msaitoh 		exit( 1 );
    102  1.1  msaitoh 	}
    103  1.1  msaitoh 
    104  1.1  msaitoh 	if( fread( &FileHdr, 1, sizeof( FileHdr ), fp ) != sizeof(FileHdr)){
    105  1.1  msaitoh 		perror("osloader");
    106  1.1  msaitoh 		exit( 1 );
    107  1.1  msaitoh 	}
    108  1.1  msaitoh 
    109  1.1  msaitoh 	if(fread( &AoutHdr, 1, sizeof( AoutHdr ), fp ) != sizeof(AoutHdr)){
    110  1.1  msaitoh 		perror("osloader");
    111  1.1  msaitoh 		exit( 1 );
    112  1.1  msaitoh 	}
    113  1.1  msaitoh 
    114  1.1  msaitoh 	/* set up command for text segment */
    115  1.1  msaitoh 	error = coff_find_section(fp, &FileHdr, &sh, COFF_STYP_TEXT);
    116  1.1  msaitoh 	if (error) {
    117  1.1  msaitoh 		printf("can't find text section: %d\n", error);
    118  1.1  msaitoh 		exit( 1 );
    119  1.1  msaitoh 	}
    120  1.1  msaitoh 
    121  1.1  msaitoh 	ep_taddr = COFF_ALIGN(sh.s_vaddr);
    122  1.1  msaitoh 	toffset = sh.s_scnptr - (sh.s_vaddr - ep_taddr);
    123  1.1  msaitoh 	ep_tsize = sh.s_size + (sh.s_vaddr - ep_taddr);
    124  1.1  msaitoh 
    125  1.1  msaitoh 	printf("VMCMD: addr %lx size 0x%lx offset 0x%lx\n", ep_taddr,
    126  1.1  msaitoh 	       ep_tsize, toffset);
    127  1.1  msaitoh 
    128  1.1  msaitoh 	/* set up command for data segment */
    129  1.1  msaitoh 	error = coff_find_section(fp, &FileHdr, &sh, COFF_STYP_DATA);
    130  1.1  msaitoh 	if (error) {
    131  1.1  msaitoh 		printf("can't find data section: %d\n", error);
    132  1.1  msaitoh 		exit( 1 );
    133  1.1  msaitoh 	}
    134  1.1  msaitoh 
    135  1.1  msaitoh 	ep_daddr = COFF_ALIGN(sh.s_vaddr);
    136  1.1  msaitoh 	doffset = sh.s_scnptr - (sh.s_vaddr - ep_daddr);
    137  1.1  msaitoh 	dsize = sh.s_size + (sh.s_vaddr - ep_daddr);
    138  1.1  msaitoh 	ep_dsize = round_page(dsize) + AoutHdr.a_bsize;
    139  1.1  msaitoh 
    140  1.1  msaitoh 	printf("VMCMD: addr 0x%lx size 0x%lx offset 0x%lx\n", ep_daddr,
    141  1.1  msaitoh 		 dsize, doffset);
    142  1.1  msaitoh 
    143  1.1  msaitoh 	osimage = malloc( ep_tsize+dsize+sizeof(u_long)*2 );
    144  1.1  msaitoh 	if( osimage == NULL){
    145  1.1  msaitoh 		printf("osloader:no memory\n");
    146  1.1  msaitoh 		exit( 1 );
    147  1.1  msaitoh 	}
    148  1.1  msaitoh 
    149  1.1  msaitoh 	*(u_long *)osimage = ep_tsize+dsize;
    150  1.1  msaitoh 	p = osimage + 2*sizeof( u_long );
    151  1.1  msaitoh 
    152  1.1  msaitoh 	/* load text area */
    153  1.1  msaitoh 	fseek( fp, toffset, SEEK_SET );
    154  1.1  msaitoh 	if( fread(p, 1, ep_tsize, fp) != ep_tsize ){
    155  1.1  msaitoh 		perror("osloader:");
    156  1.1  msaitoh 		exit( 1 );
    157  1.1  msaitoh 	}
    158  1.1  msaitoh 
    159  1.1  msaitoh 	/* load data area */
    160  1.1  msaitoh 	fseek( fp, doffset, SEEK_SET );
    161  1.1  msaitoh 	if( fread(p+ep_daddr-ep_taddr, 1, dsize, fp) != dsize ){
    162  1.1  msaitoh 		perror("osloader:");
    163  1.1  msaitoh 		exit( 1 );
    164  1.1  msaitoh 	}
    165  1.1  msaitoh 
    166  1.1  msaitoh 	fclose( fp );
    167  1.1  msaitoh 
    168  1.1  msaitoh 	cksum = 0;
    169  1.1  msaitoh 	size = (ep_tsize + dsize) >> 2;
    170  1.1  msaitoh 
    171  1.1  msaitoh 	for( i = 0; i < size; i++){
    172  1.1  msaitoh 		cksum += *(u_long *)p;
    173  1.1  msaitoh 		p += sizeof(u_long );
    174  1.1  msaitoh 	}
    175  1.1  msaitoh 
    176  1.1  msaitoh 	*(u_long *)(osimage+sizeof(u_long)) = cksum ;
    177  1.1  msaitoh 
    178  1.1  msaitoh #if 0
    179  1.1  msaitoh 	printf("osimage = %p\n", osimage );
    180  1.1  msaitoh #endif
    181  1.1  msaitoh 
    182  1.1  msaitoh 	LoadAndReset( osimage );
    183  1.1  msaitoh 
    184  1.1  msaitoh 	return (0);	/* NOT REACHED */
    185  1.1  msaitoh }
    186  1.1  msaitoh 
    187  1.1  msaitoh 
    188  1.1  msaitoh #ifdef NOTDEF
    189  1.1  msaitoh 
    190  1.1  msaitoh /*
    191  1.1  msaitoh  * exec_coff_makecmds(): Check if it's an coff-format executable.
    192  1.1  msaitoh  *
    193  1.1  msaitoh  * Given a proc pointer and an exec package pointer, see if the referent
    194  1.1  msaitoh  * of the epp is in coff format.  Check 'standard' magic numbers for
    195  1.1  msaitoh  * this architecture.  If that fails, return failure.
    196  1.1  msaitoh  *
    197  1.1  msaitoh  * This function is  responsible for creating a set of vmcmds which can be
    198  1.1  msaitoh  * used to build the process's vm space and inserting them into the exec
    199  1.1  msaitoh  * package.
    200  1.1  msaitoh  */
    201  1.1  msaitoh 
    202  1.1  msaitoh int
    203  1.1  msaitoh exec_coff_makecmds(p, epp)
    204  1.1  msaitoh 	struct proc *p;
    205  1.1  msaitoh 	struct exec_package *epp;
    206  1.1  msaitoh {
    207  1.1  msaitoh 	int error;
    208  1.1  msaitoh 	struct coff_filehdr *fp = epp->ep_hdr;
    209  1.1  msaitoh 	struct coff_aouthdr *ap;
    210  1.1  msaitoh 
    211  1.1  msaitoh 	if (epp->ep_hdrvalid < COFF_HDR_SIZE)
    212  1.1  msaitoh 		return ENOEXEC;
    213  1.1  msaitoh 
    214  1.1  msaitoh 	if (COFF_BADMAG(fp))
    215  1.1  msaitoh 		return ENOEXEC;
    216  1.1  msaitoh 
    217  1.1  msaitoh 	ap = epp->ep_hdr + sizeof(struct coff_filehdr);
    218  1.1  msaitoh 	switch (ap->a_magic) {
    219  1.1  msaitoh 	case COFF_OMAGIC:
    220  1.1  msaitoh 		error = exec_coff_prep_omagic(p, epp, fp, ap);
    221  1.1  msaitoh 		break;
    222  1.1  msaitoh 	case COFF_NMAGIC:
    223  1.1  msaitoh 		error = exec_coff_prep_nmagic(p, epp, fp, ap);
    224  1.1  msaitoh 		break;
    225  1.1  msaitoh 	case COFF_ZMAGIC:
    226  1.1  msaitoh 		error = exec_coff_prep_zmagic(p, epp, fp, ap);
    227  1.1  msaitoh 		break;
    228  1.1  msaitoh 	default:
    229  1.1  msaitoh 		return ENOEXEC;
    230  1.1  msaitoh 	}
    231  1.1  msaitoh 
    232  1.1  msaitoh #ifdef	TODO
    233  1.1  msaitoh 	if (error == 0)
    234  1.1  msaitoh 		error = cpu_exec_coff_hook(p, epp );
    235  1.1  msaitoh #endif
    236  1.1  msaitoh 
    237  1.1  msaitoh 	if (error)
    238  1.1  msaitoh 		kill_vmcmds(&epp->ep_vmcmds);
    239  1.1  msaitoh 
    240  1.1  msaitoh 	return error;
    241  1.1  msaitoh }
    242  1.1  msaitoh 
    243  1.1  msaitoh /*
    244  1.1  msaitoh  * exec_coff_setup_stack(): Set up the stack segment for a coff
    245  1.1  msaitoh  * executable.
    246  1.1  msaitoh  *
    247  1.1  msaitoh  * Note that the ep_ssize parameter must be set to be the current stack
    248  1.1  msaitoh  * limit; this is adjusted in the body of execve() to yield the
    249  1.1  msaitoh  * appropriate stack segment usage once the argument length is
    250  1.1  msaitoh  * calculated.
    251  1.1  msaitoh  *
    252  1.1  msaitoh  * This function returns an int for uniformity with other (future) formats'
    253  1.1  msaitoh  * stack setup functions.  They might have errors to return.
    254  1.1  msaitoh  */
    255  1.1  msaitoh 
    256  1.1  msaitoh int
    257  1.1  msaitoh exec_coff_setup_stack(p, epp)
    258  1.1  msaitoh 	struct proc *p;
    259  1.1  msaitoh 	struct exec_package *epp;
    260  1.1  msaitoh {
    261  1.1  msaitoh 	/* DPRINTF(("enter exec_coff_setup_stack\n")); */
    262  1.1  msaitoh 
    263  1.1  msaitoh 	epp->ep_maxsaddr = USRSTACK - MAXSSIZ;
    264  1.1  msaitoh 	epp->ep_minsaddr = USRSTACK;
    265  1.1  msaitoh 	epp->ep_ssize = p->p_rlimit[RLIMIT_STACK].rlim_cur;
    266  1.1  msaitoh 
    267  1.1  msaitoh 	/*
    268  1.1  msaitoh 	 * set up commands for stack.  note that this takes *two*, one to
    269  1.1  msaitoh 	 * map the part of the stack which we can access, and one to map
    270  1.1  msaitoh 	 * the part which we can't.
    271  1.1  msaitoh 	 *
    272  1.1  msaitoh 	 * arguably, it could be made into one, but that would require the
    273  1.1  msaitoh 	 * addition of another mapping proc, which is unnecessary
    274  1.1  msaitoh 	 *
    275  1.1  msaitoh 	 * note that in memory, things assumed to be: 0 ....... ep_maxsaddr
    276  1.1  msaitoh 	 * <stack> ep_minsaddr
    277  1.1  msaitoh 	 */
    278  1.1  msaitoh 	/* DPRINTF(("VMCMD: addr %x size %d\n", epp->ep_maxsaddr,
    279  1.1  msaitoh 		 (epp->ep_minsaddr - epp->ep_ssize) - epp->ep_maxsaddr)); */
    280  1.1  msaitoh 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero,
    281  1.1  msaitoh 		  ((epp->ep_minsaddr - epp->ep_ssize) - epp->ep_maxsaddr),
    282  1.1  msaitoh 		  epp->ep_maxsaddr, NULLVP, 0, VM_PROT_NONE);
    283  1.1  msaitoh 	/* DPRINTF(("VMCMD: addr %x size %d\n",
    284  1.1  msaitoh 		 epp->ep_minsaddr - epp->ep_ssize,
    285  1.1  msaitoh 		 epp->ep_ssize)); */
    286  1.1  msaitoh 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, epp->ep_ssize,
    287  1.1  msaitoh 		  (epp->ep_minsaddr - epp->ep_ssize), NULLVP, 0,
    288  1.1  msaitoh 		  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    289  1.1  msaitoh 
    290  1.1  msaitoh 	return 0;
    291  1.1  msaitoh }
    292  1.1  msaitoh 
    293  1.1  msaitoh 
    294  1.1  msaitoh /*
    295  1.1  msaitoh  * exec_coff_prep_omagic(): Prepare a COFF OMAGIC binary's exec package
    296  1.1  msaitoh  */
    297  1.1  msaitoh 
    298  1.1  msaitoh int
    299  1.1  msaitoh exec_coff_prep_omagic(p, epp, fp, ap)
    300  1.1  msaitoh 	struct proc *p;
    301  1.1  msaitoh 	struct exec_package *epp;
    302  1.1  msaitoh 	struct coff_filehdr *fp;
    303  1.1  msaitoh 	struct coff_aouthdr *ap;
    304  1.1  msaitoh {
    305  1.1  msaitoh 	epp->ep_taddr = COFF_SEGMENT_ALIGN(ap, ap->a_tstart);
    306  1.1  msaitoh 	epp->ep_tsize = ap->a_tsize;
    307  1.1  msaitoh 	epp->ep_daddr = COFF_SEGMENT_ALIGN(ap, ap->a_dstart);
    308  1.1  msaitoh 	epp->ep_dsize = ap->a_dsize;
    309  1.1  msaitoh 	epp->ep_entry = ap->a_entry;
    310  1.1  msaitoh 
    311  1.1  msaitoh 	/* set up command for text and data segments */
    312  1.1  msaitoh 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
    313  1.1  msaitoh 		  ap->a_tsize + ap->a_dsize, epp->ep_taddr, epp->ep_vp,
    314  1.1  msaitoh 		  COFF_TXTOFF(fp, ap),
    315  1.1  msaitoh 		  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    316  1.1  msaitoh 
    317  1.1  msaitoh 	/* set up command for bss segment */
    318  1.1  msaitoh #ifdef	sh3
    319  1.1  msaitoh 	if (ap->a_bsize > 0)
    320  1.1  msaitoh 		NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize,
    321  1.1  msaitoh 			  COFF_ROUND(ap->a_dstart + ap->a_dsize, COFF_LDPGSZ),
    322  1.1  msaitoh 			  NULLVP, 0,
    323  1.1  msaitoh 			  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    324  1.1  msaitoh #else
    325  1.1  msaitoh 	if (ap->a_bsize > 0)
    326  1.1  msaitoh 		NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize,
    327  1.1  msaitoh 			  COFF_SEGMENT_ALIGN(ap, ap->a_dstart + ap->a_dsize),
    328  1.1  msaitoh 			  NULLVP, 0,
    329  1.1  msaitoh 			  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    330  1.1  msaitoh #endif
    331  1.1  msaitoh 
    332  1.1  msaitoh 	return exec_coff_setup_stack(p, epp);
    333  1.1  msaitoh }
    334  1.1  msaitoh 
    335  1.1  msaitoh /*
    336  1.1  msaitoh  * exec_coff_prep_nmagic(): Prepare a 'native' NMAGIC COFF binary's exec
    337  1.1  msaitoh  *                          package.
    338  1.1  msaitoh  */
    339  1.1  msaitoh 
    340  1.1  msaitoh int
    341  1.1  msaitoh exec_coff_prep_nmagic(p, epp, fp, ap)
    342  1.1  msaitoh 	struct proc *p;
    343  1.1  msaitoh 	struct exec_package *epp;
    344  1.1  msaitoh 	struct coff_filehdr *fp;
    345  1.1  msaitoh 	struct coff_aouthdr *ap;
    346  1.1  msaitoh {
    347  1.1  msaitoh 	epp->ep_taddr = COFF_SEGMENT_ALIGN(ap, ap->a_tstart);
    348  1.1  msaitoh 	epp->ep_tsize = ap->a_tsize;
    349  1.1  msaitoh 	epp->ep_daddr = COFF_ROUND(ap->a_dstart, COFF_LDPGSZ);
    350  1.1  msaitoh 	epp->ep_dsize = ap->a_dsize;
    351  1.1  msaitoh 	epp->ep_entry = ap->a_entry;
    352  1.1  msaitoh 
    353  1.1  msaitoh 	/* set up command for text segment */
    354  1.1  msaitoh 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_tsize,
    355  1.1  msaitoh 		  epp->ep_taddr, epp->ep_vp, COFF_TXTOFF(fp, ap),
    356  1.1  msaitoh 		  VM_PROT_READ|VM_PROT_EXECUTE);
    357  1.1  msaitoh 
    358  1.1  msaitoh 	/* set up command for data segment */
    359  1.1  msaitoh 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_dsize,
    360  1.1  msaitoh 		  epp->ep_daddr, epp->ep_vp, COFF_DATOFF(fp, ap),
    361  1.1  msaitoh 		  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    362  1.1  msaitoh 
    363  1.1  msaitoh 	/* set up command for bss segment */
    364  1.1  msaitoh 	if (ap->a_bsize > 0)
    365  1.1  msaitoh 		NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize,
    366  1.1  msaitoh 			  COFF_SEGMENT_ALIGN(ap, ap->a_dstart + ap->a_dsize),
    367  1.1  msaitoh 			  NULLVP, 0,
    368  1.1  msaitoh 			  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    369  1.1  msaitoh 
    370  1.1  msaitoh 	return exec_coff_setup_stack(p, epp);
    371  1.1  msaitoh }
    372  1.1  msaitoh 
    373  1.1  msaitoh /*
    374  1.1  msaitoh  * coff_find_section - load specified section header
    375  1.1  msaitoh  *
    376  1.1  msaitoh  * TODO - optimize by reading all section headers in at once
    377  1.1  msaitoh  */
    378  1.1  msaitoh 
    379  1.1  msaitoh static int
    380  1.1  msaitoh coff_find_section(p, vp, fp, sh, s_type)
    381  1.1  msaitoh 	struct proc *p;
    382  1.1  msaitoh 	struct vnode *vp;
    383  1.1  msaitoh 	struct coff_filehdr *fp;
    384  1.1  msaitoh 	struct coff_scnhdr *sh;
    385  1.1  msaitoh 	int s_type;
    386  1.1  msaitoh {
    387  1.1  msaitoh 	int i, pos, resid, siz, error;
    388  1.1  msaitoh 
    389  1.1  msaitoh 	pos = COFF_HDR_SIZE;
    390  1.1  msaitoh 	for (i = 0; i < fp->f_nscns; i++, pos += sizeof(struct coff_scnhdr)) {
    391  1.1  msaitoh 		siz = sizeof(struct coff_scnhdr);
    392  1.1  msaitoh 		error = vn_rdwr(UIO_READ, vp, (caddr_t) sh,
    393  1.1  msaitoh 		    siz, pos, UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred,
    394  1.1  msaitoh 		    &resid, p);
    395  1.1  msaitoh 		if (error) {
    396  1.1  msaitoh 			DPRINTF(("section hdr %d read error %d\n", i, error));
    397  1.1  msaitoh 			return error;
    398  1.1  msaitoh 		}
    399  1.1  msaitoh 		siz -= resid;
    400  1.1  msaitoh 		if (siz != sizeof(struct coff_scnhdr)) {
    401  1.1  msaitoh 			DPRINTF(("incomplete read: hdr %d ask=%d, rem=%d got %d\n",
    402  1.1  msaitoh 				 s_type, sizeof(struct coff_scnhdr),
    403  1.1  msaitoh 				 resid, siz));
    404  1.1  msaitoh 			return ENOEXEC;
    405  1.1  msaitoh 		}
    406  1.1  msaitoh 		/* DPRINTF(("found section: %x\n", sh->s_flags)); */
    407  1.1  msaitoh 		if (sh->s_flags == s_type)
    408  1.1  msaitoh 			return 0;
    409  1.1  msaitoh 	}
    410  1.1  msaitoh 	return ENOEXEC;
    411  1.1  msaitoh }
    412  1.1  msaitoh 
    413  1.1  msaitoh /*
    414  1.1  msaitoh  * exec_coff_prep_zmagic(): Prepare a COFF ZMAGIC binary's exec package
    415  1.1  msaitoh  *
    416  1.1  msaitoh  * First, set the various offsets/lengths in the exec package.
    417  1.1  msaitoh  *
    418  1.1  msaitoh  * Then, mark the text image busy (so it can be demand paged) or error
    419  1.1  msaitoh  * out if this is not possible.  Finally, set up vmcmds for the
    420  1.1  msaitoh  * text, data, bss, and stack segments.
    421  1.1  msaitoh  */
    422  1.1  msaitoh 
    423  1.1  msaitoh int
    424  1.1  msaitoh exec_coff_prep_zmagic(p, epp, fp, ap)
    425  1.1  msaitoh 	struct proc *p;
    426  1.1  msaitoh 	struct exec_package *epp;
    427  1.1  msaitoh 	struct coff_filehdr *fp;
    428  1.1  msaitoh 	struct coff_aouthdr *ap;
    429  1.1  msaitoh {
    430  1.1  msaitoh 	int error;
    431  1.1  msaitoh 	u_long offset;
    432  1.1  msaitoh 	long dsize;
    433  1.1  msaitoh #ifndef	sh3
    434  1.1  msaitoh 	long  baddr, bsize;
    435  1.1  msaitoh #endif
    436  1.1  msaitoh 	struct coff_scnhdr sh;
    437  1.1  msaitoh 
    438  1.1  msaitoh 	/* DPRINTF(("enter exec_coff_prep_zmagic\n")); */
    439  1.1  msaitoh 
    440  1.1  msaitoh 	/* set up command for text segment */
    441  1.1  msaitoh 	error = coff_find_section(p, epp->ep_vp, fp, &sh, COFF_STYP_TEXT);
    442  1.1  msaitoh 	if (error) {
    443  1.1  msaitoh 		DPRINTF(("can't find text section: %d\n", error));
    444  1.1  msaitoh 		return error;
    445  1.1  msaitoh 	}
    446  1.1  msaitoh 	/* DPRINTF(("COFF text addr %x size %d offset %d\n", sh.s_vaddr,
    447  1.1  msaitoh 		 sh.s_size, sh.s_scnptr)); */
    448  1.1  msaitoh 	epp->ep_taddr = COFF_ALIGN(sh.s_vaddr);
    449  1.1  msaitoh 	offset = sh.s_scnptr - (sh.s_vaddr - epp->ep_taddr);
    450  1.1  msaitoh 	epp->ep_tsize = sh.s_size + (sh.s_vaddr - epp->ep_taddr);
    451  1.1  msaitoh 
    452  1.1  msaitoh #ifdef notyet
    453  1.1  msaitoh 	/*
    454  1.1  msaitoh 	 * check if vnode is in open for writing, because we want to
    455  1.1  msaitoh 	 * demand-page out of it.  if it is, don't do it, for various
    456  1.1  msaitoh 	 * reasons
    457  1.1  msaitoh 	 */
    458  1.1  msaitoh 	if ((ap->a_tsize != 0 || ap->a_dsize != 0) &&
    459  1.1  msaitoh 	    epp->ep_vp->v_writecount != 0) {
    460  1.1  msaitoh #ifdef DIAGNOSTIC
    461  1.1  msaitoh 		if (epp->ep_vp->v_flag & VTEXT)
    462  1.1  msaitoh 			panic("exec: a VTEXT vnode has writecount != 0\n");
    463  1.1  msaitoh #endif
    464  1.1  msaitoh 		return ETXTBSY;
    465  1.1  msaitoh 	}
    466  1.1  msaitoh 	epp->ep_vp->v_flag |= VTEXT;
    467  1.1  msaitoh #endif
    468  1.1  msaitoh 
    469  1.1  msaitoh 	/* DPRINTF(("VMCMD: addr %x size %d offset %d\n", epp->ep_taddr,
    470  1.1  msaitoh 		 epp->ep_tsize, offset)); */
    471  1.1  msaitoh #ifdef notyet
    472  1.1  msaitoh 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, epp->ep_tsize,
    473  1.1  msaitoh 		  epp->ep_taddr, epp->ep_vp, offset,
    474  1.1  msaitoh 		  VM_PROT_READ|VM_PROT_EXECUTE);
    475  1.1  msaitoh #else
    476  1.1  msaitoh 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_tsize,
    477  1.1  msaitoh 		  epp->ep_taddr, epp->ep_vp, offset,
    478  1.1  msaitoh 		  VM_PROT_READ|VM_PROT_EXECUTE);
    479  1.1  msaitoh #endif
    480  1.1  msaitoh 
    481  1.1  msaitoh 	/* set up command for data segment */
    482  1.1  msaitoh 	error = coff_find_section(p, epp->ep_vp, fp, &sh, COFF_STYP_DATA);
    483  1.1  msaitoh 	if (error) {
    484  1.1  msaitoh 		DPRINTF(("can't find data section: %d\n", error));
    485  1.1  msaitoh 		return error;
    486  1.1  msaitoh 	}
    487  1.1  msaitoh 	/* DPRINTF(("COFF data addr %x size %d offset %d\n", sh.s_vaddr,
    488  1.1  msaitoh 		 sh.s_size, sh.s_scnptr)); */
    489  1.1  msaitoh 	epp->ep_daddr = COFF_ALIGN(sh.s_vaddr);
    490  1.1  msaitoh 	offset = sh.s_scnptr - (sh.s_vaddr - epp->ep_daddr);
    491  1.1  msaitoh 	dsize = sh.s_size + (sh.s_vaddr - epp->ep_daddr);
    492  1.1  msaitoh #ifdef sh3
    493  1.1  msaitoh 	epp->ep_dsize = round_page(dsize) + ap->a_bsize;
    494  1.1  msaitoh #else
    495  1.1  msaitoh 	epp->ep_dsize = dsize + ap->a_bsize;
    496  1.1  msaitoh #endif
    497  1.1  msaitoh 
    498  1.1  msaitoh 	/* DPRINTF(("VMCMD: addr %x size %d offset %d\n", epp->ep_daddr,
    499  1.1  msaitoh 		 dsize, offset)); */
    500  1.1  msaitoh #ifdef notyet
    501  1.1  msaitoh 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, dsize,
    502  1.1  msaitoh 		  epp->ep_daddr, epp->ep_vp, offset,
    503  1.1  msaitoh 		  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    504  1.1  msaitoh #else
    505  1.1  msaitoh 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
    506  1.1  msaitoh 		  dsize, epp->ep_daddr, epp->ep_vp, offset,
    507  1.1  msaitoh 		  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    508  1.1  msaitoh #endif
    509  1.1  msaitoh 
    510  1.1  msaitoh #ifdef	sh3
    511  1.1  msaitoh 	if (ap->a_bsize > 0){
    512  1.1  msaitoh 		NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize,
    513  1.1  msaitoh 			  COFF_ROUND(ap->a_dstart + ap->a_dsize, COFF_LDPGSZ),
    514  1.1  msaitoh 			  NULLVP, 0,
    515  1.1  msaitoh 			  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    516  1.1  msaitoh 
    517  1.1  msaitoh 	}
    518  1.1  msaitoh #else
    519  1.1  msaitoh 	/* set up command for bss segment */
    520  1.1  msaitoh 	baddr = round_page(epp->ep_daddr + dsize);
    521  1.1  msaitoh 	bsize = epp->ep_daddr + epp->ep_dsize - baddr;
    522  1.1  msaitoh 	if (bsize > 0) {
    523  1.1  msaitoh 		/* DPRINTF(("VMCMD: addr %x size %d offset %d\n",
    524  1.1  msaitoh 			 baddr, bsize, 0)); */
    525  1.1  msaitoh 		NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero,
    526  1.1  msaitoh 			  bsize, baddr, NULLVP, 0,
    527  1.1  msaitoh 			  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
    528  1.1  msaitoh 	}
    529  1.1  msaitoh #endif
    530  1.1  msaitoh 
    531  1.1  msaitoh #ifdef	TODO
    532  1.1  msaitoh 	/* load any shared libraries */
    533  1.1  msaitoh 	error = coff_find_section(p, epp->ep_vp, fp, &sh, COFF_STYP_SHLIB);
    534  1.1  msaitoh 	if (!error) {
    535  1.1  msaitoh 		int resid;
    536  1.1  msaitoh 		struct coff_slhdr *slhdr;
    537  1.1  msaitoh 		char buf[128], *bufp;	/* FIXME */
    538  1.1  msaitoh 		int len = sh.s_size, path_index, entry_len;
    539  1.1  msaitoh 
    540  1.1  msaitoh 		/* DPRINTF(("COFF shlib size %d offset %d\n",
    541  1.1  msaitoh 			 sh.s_size, sh.s_scnptr)); */
    542  1.1  msaitoh 
    543  1.1  msaitoh 		error = vn_rdwr(UIO_READ, epp->ep_vp, (caddr_t) buf,
    544  1.1  msaitoh 				len, sh.s_scnptr,
    545  1.1  msaitoh 				UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred,
    546  1.1  msaitoh 				&resid, p);
    547  1.1  msaitoh 		if (error) {
    548  1.1  msaitoh 			DPRINTF(("shlib section read error %d\n", error));
    549  1.1  msaitoh 			return ENOEXEC;
    550  1.1  msaitoh 		}
    551  1.1  msaitoh 		bufp = buf;
    552  1.1  msaitoh 		while (len) {
    553  1.1  msaitoh 			slhdr = (struct coff_slhdr *)bufp;
    554  1.1  msaitoh 			path_index = slhdr->path_index * sizeof(long);
    555  1.1  msaitoh 			entry_len = slhdr->entry_len * sizeof(long);
    556  1.1  msaitoh 
    557  1.1  msaitoh 			/* DPRINTF(("path_index: %d entry_len: %d name: %s\n",
    558  1.1  msaitoh 				 path_index, entry_len, slhdr->sl_name)); */
    559  1.1  msaitoh 
    560  1.1  msaitoh 			error = coff_load_shlib(p, slhdr->sl_name, epp);
    561  1.1  msaitoh 			if (error)
    562  1.1  msaitoh 				return ENOEXEC;
    563  1.1  msaitoh 			bufp += entry_len;
    564  1.1  msaitoh 			len -= entry_len;
    565  1.1  msaitoh 		}
    566  1.1  msaitoh 	}
    567  1.1  msaitoh #endif
    568  1.1  msaitoh 
    569  1.1  msaitoh 	/* set up entry point */
    570  1.1  msaitoh 	epp->ep_entry = ap->a_entry;
    571  1.1  msaitoh 
    572  1.1  msaitoh #if 0
    573  1.1  msaitoh 	DPRINTF(("text addr: %x size: %d data addr: %x size: %d entry: %x\n",
    574  1.1  msaitoh 		 epp->ep_taddr, epp->ep_tsize,
    575  1.1  msaitoh 		 epp->ep_daddr, epp->ep_dsize,
    576  1.1  msaitoh 		 epp->ep_entry));
    577  1.1  msaitoh #endif
    578  1.1  msaitoh 
    579  1.1  msaitoh 	return exec_coff_setup_stack(p, epp);
    580  1.1  msaitoh }
    581  1.1  msaitoh 
    582  1.1  msaitoh 
    583  1.1  msaitoh #endif /* NOTDEF */
    584