imgact_coff.c revision 173361
1219820Sjeff/*-
2219820Sjeff * Copyright (c) 1994 Sean Eric Fagan
3219820Sjeff * Copyright (c) 1994 S�ren Schmidt
4219820Sjeff * All rights reserved.
5219820Sjeff *
6219820Sjeff * Redistribution and use in source and binary forms, with or without
7219820Sjeff * modification, are permitted provided that the following conditions
8219820Sjeff * are met:
9219820Sjeff * 1. Redistributions of source code must retain the above copyright
10219820Sjeff *    notice, this list of conditions and the following disclaimer
11219820Sjeff *    in this position and unchanged.
12219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
13219820Sjeff *    notice, this list of conditions and the following disclaimer in the
14219820Sjeff *    documentation and/or other materials provided with the distribution.
15219820Sjeff * 3. The name of the author may not be used to endorse or promote products
16219820Sjeff *    derived from this software without specific prior written permission
17219820Sjeff *
18219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28219820Sjeff */
29219820Sjeff
30219820Sjeff#include <sys/cdefs.h>
31219820Sjeff__FBSDID("$FreeBSD: head/sys/i386/ibcs2/imgact_coff.c 173361 2007-11-05 11:36:16Z kib $");
32219820Sjeff
33219820Sjeff#include <sys/param.h>
34219820Sjeff#include <sys/systm.h>
35219820Sjeff#include <sys/exec.h>
36219820Sjeff#include <sys/fcntl.h>
37219820Sjeff#include <sys/imgact.h>
38219820Sjeff#include <sys/kernel.h>
39219820Sjeff#include <sys/lock.h>
40219820Sjeff#include <sys/malloc.h>
41219820Sjeff#include <sys/mman.h>
42219820Sjeff#include <sys/mount.h>
43219820Sjeff#include <sys/namei.h>
44219820Sjeff#include <sys/vnode.h>
45219820Sjeff
46219820Sjeff#include <vm/vm.h>
47219820Sjeff#include <vm/pmap.h>
48219820Sjeff#include <vm/vm_map.h>
49219820Sjeff#include <vm/vm_kern.h>
50219820Sjeff#include <vm/vm_extern.h>
51219820Sjeff
52219820Sjeff#include <i386/ibcs2/coff.h>
53219820Sjeff#include <i386/ibcs2/ibcs2_util.h>
54219820Sjeff
55219820SjeffMODULE_DEPEND(coff, ibcs2, 1, 1, 1);
56219820Sjeff
57219820Sjeffextern struct sysentvec ibcs2_svr3_sysvec;
58219820Sjeff
59219820Sjeffstatic int coff_load_file(struct thread *td, char *name);
60219820Sjeffstatic int exec_coff_imgact(struct image_params *imgp);
61219820Sjeff
62219820Sjeffstatic int load_coff_section(struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot);
63219820Sjeff
64219820Sjeffstatic int
65219820Sjeffload_coff_section(struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset,
66219820Sjeff		  caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot)
67219820Sjeff{
68219820Sjeff	size_t map_len;
69219820Sjeff	vm_offset_t map_offset;
70219820Sjeff	vm_offset_t map_addr;
71219820Sjeff	int error;
72219820Sjeff	unsigned char *data_buf = 0;
73219820Sjeff	size_t copy_len;
74219820Sjeff
75219820Sjeff	map_offset = trunc_page(offset);
76219820Sjeff	map_addr = trunc_page((vm_offset_t)vmaddr);
77219820Sjeff
78219820Sjeff	if (memsz > filsz) {
79219820Sjeff		/*
80219820Sjeff		 * We have the stupid situation that
81219820Sjeff		 * the section is longer than it is on file,
82219820Sjeff		 * which means it has zero-filled areas, and
83219820Sjeff		 * we have to work for it.  Stupid iBCS!
84219820Sjeff		 */
85219820Sjeff		map_len = trunc_page(offset + filsz) - trunc_page(map_offset);
86219820Sjeff	} else {
87219820Sjeff		/*
88219820Sjeff		 * The only stuff we care about is on disk, and we
89219820Sjeff		 * don't care if we map in more than is really there.
90219820Sjeff		 */
91219820Sjeff		map_len = round_page(offset + filsz) - trunc_page(map_offset);
92219820Sjeff	}
93219820Sjeff
94219820Sjeff	DPRINTF(("%s(%d):  vm_mmap(&vmspace->vm_map, &0x%08lx, 0x%x, 0x%x, "
95219820Sjeff		"VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED, OBJT_VNODE, vp, 0x%x)\n",
96219820Sjeff		__FILE__, __LINE__, map_addr, map_len, prot, map_offset));
97219820Sjeff
98219820Sjeff	if ((error = vm_mmap(&vmspace->vm_map,
99219820Sjeff			     &map_addr,
100219820Sjeff			     map_len,
101219820Sjeff			     prot,
102219820Sjeff			     VM_PROT_ALL,
103219820Sjeff			     MAP_PRIVATE | MAP_FIXED,
104219820Sjeff			     OBJT_VNODE,
105219820Sjeff			     vp,
106219820Sjeff			     map_offset)) != 0)
107219820Sjeff		return error;
108219820Sjeff
109219820Sjeff	if (memsz == filsz) {
110219820Sjeff		/* We're done! */
111219820Sjeff		return 0;
112219820Sjeff	}
113219820Sjeff
114219820Sjeff	/*
115219820Sjeff	 * Now we have screwball stuff, to accomodate stupid COFF.
116219820Sjeff	 * We have to map the remaining bit of the file into the kernel's
117219820Sjeff	 * memory map, allocate some anonymous memory, copy that last
118219820Sjeff	 * bit into it, and then we're done. *sigh*
119219820Sjeff	 * For clean-up reasons, we actally map in the file last.
120219820Sjeff	 */
121219820Sjeff
122219820Sjeff	copy_len = (offset + filsz) - trunc_page(offset + filsz);
123219820Sjeff	map_addr = trunc_page((vm_offset_t)vmaddr + filsz);
124219820Sjeff	map_len = round_page((vm_offset_t)vmaddr + memsz) - map_addr;
125219820Sjeff
126219820Sjeff	DPRINTF(("%s(%d): vm_map_find(&vmspace->vm_map, NULL, 0, &0x%08lx,0x%x, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0)\n", __FILE__, __LINE__, map_addr, map_len));
127219820Sjeff
128219820Sjeff	if (map_len != 0) {
129219820Sjeff		error = vm_map_find(&vmspace->vm_map, NULL, 0, &map_addr,
130219820Sjeff				    map_len, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0);
131219820Sjeff		if (error)
132219820Sjeff			return error;
133219820Sjeff	}
134219820Sjeff
135219820Sjeff	if ((error = vm_mmap(kernel_map,
136219820Sjeff			    (vm_offset_t *) &data_buf,
137219820Sjeff			    PAGE_SIZE,
138219820Sjeff			    VM_PROT_READ,
139219820Sjeff			    VM_PROT_READ,
140219820Sjeff			    0,
141219820Sjeff			    OBJT_VNODE,
142219820Sjeff			    vp,
143219820Sjeff			    trunc_page(offset + filsz))) != 0)
144219820Sjeff		return error;
145219820Sjeff
146219820Sjeff	error = copyout(data_buf, (caddr_t) map_addr, copy_len);
147219820Sjeff
148219820Sjeff	if (vm_map_remove(kernel_map,
149219820Sjeff			  (vm_offset_t) data_buf,
150219820Sjeff			  (vm_offset_t) data_buf + PAGE_SIZE))
151219820Sjeff		panic("load_coff_section vm_map_remove failed");
152219820Sjeff
153219820Sjeff	return error;
154219820Sjeff}
155219820Sjeff
156219820Sjeffstatic int
157219820Sjeffcoff_load_file(struct thread *td, char *name)
158219820Sjeff{
159219820Sjeff	struct proc *p = td->td_proc;
160219820Sjeff  	struct vmspace *vmspace = p->p_vmspace;
161219820Sjeff  	int error;
162219820Sjeff  	struct nameidata nd;
163219820Sjeff  	struct vnode *vp;
164219820Sjeff  	struct vattr attr;
165219820Sjeff  	struct filehdr *fhdr;
166219820Sjeff  	struct aouthdr *ahdr;
167219820Sjeff  	struct scnhdr *scns;
168219820Sjeff  	char *ptr = 0;
169219820Sjeff  	int nscns;
170219820Sjeff  	unsigned long text_offset = 0, text_address = 0, text_size = 0;
171219820Sjeff  	unsigned long data_offset = 0, data_address = 0, data_size = 0;
172219820Sjeff  	unsigned long bss_size = 0;
173219820Sjeff  	int i;
174219820Sjeff
175219820Sjeff	NDINIT(&nd, LOOKUP, ISOPEN | LOCKLEAF | FOLLOW | SAVENAME,
176219820Sjeff	    UIO_SYSSPACE, name, td);
177219820Sjeff
178219820Sjeff  	error = namei(&nd);
179219820Sjeff  	if (error)
180219820Sjeff    		return error;
181219820Sjeff
182219820Sjeff  	vp = nd.ni_vp;
183219820Sjeff  	if (vp == NULL)
184219820Sjeff    		return ENOEXEC;
185219820Sjeff
186219820Sjeff  	if (vp->v_writecount) {
187219820Sjeff    		error = ETXTBSY;
188219820Sjeff    		goto fail;
189219820Sjeff  	}
190219820Sjeff
191219820Sjeff  	if ((error = VOP_GETATTR(vp, &attr, td->td_ucred, td)) != 0)
192219820Sjeff    		goto fail;
193219820Sjeff
194219820Sjeff  	if ((vp->v_mount->mnt_flag & MNT_NOEXEC)
195219820Sjeff	    || ((attr.va_mode & 0111) == 0)
196219820Sjeff	    || (attr.va_type != VREG))
197219820Sjeff    		goto fail;
198219820Sjeff
199219820Sjeff  	if (attr.va_size == 0) {
200219820Sjeff    		error = ENOEXEC;
201219820Sjeff    		goto fail;
202219820Sjeff  	}
203219820Sjeff
204219820Sjeff  	if ((error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td)) != 0)
205219820Sjeff    		goto fail;
206219820Sjeff
207219820Sjeff  	if ((error = VOP_OPEN(vp, FREAD, td->td_ucred, td, NULL)) != 0)
208219820Sjeff    		goto fail;
209219820Sjeff
210219820Sjeff	/*
211219820Sjeff	 * Lose the lock on the vnode. It's no longer needed, and must not
212219820Sjeff	 * exist for the pagefault paging to work below.
213219820Sjeff	 */
214219820Sjeff	VOP_UNLOCK(vp, 0, td);
215219820Sjeff
216219820Sjeff  	if ((error = vm_mmap(kernel_map,
217219820Sjeff			    (vm_offset_t *) &ptr,
218219820Sjeff			    PAGE_SIZE,
219219820Sjeff			    VM_PROT_READ,
220219820Sjeff		       	    VM_PROT_READ,
221219820Sjeff			    0,
222219820Sjeff			    OBJT_VNODE,
223219820Sjeff			    vp,
224219820Sjeff			    0)) != 0)
225219820Sjeff		goto unlocked_fail;
226219820Sjeff
227219820Sjeff  	fhdr = (struct filehdr *)ptr;
228219820Sjeff
229219820Sjeff  	if (fhdr->f_magic != I386_COFF) {
230219820Sjeff    		error = ENOEXEC;
231219820Sjeff    		goto dealloc_and_fail;
232219820Sjeff  	}
233219820Sjeff
234219820Sjeff  	nscns = fhdr->f_nscns;
235219820Sjeff
236219820Sjeff  	if ((nscns * sizeof(struct scnhdr)) > PAGE_SIZE) {
237219820Sjeff    		/*
238219820Sjeff     		 * XXX -- just fail.  I'm so lazy.
239219820Sjeff     		 */
240219820Sjeff    		error = ENOEXEC;
241219820Sjeff    		goto dealloc_and_fail;
242219820Sjeff  	}
243219820Sjeff
244219820Sjeff  	ahdr = (struct aouthdr*)(ptr + sizeof(struct filehdr));
245219820Sjeff
246219820Sjeff  	scns = (struct scnhdr*)(ptr + sizeof(struct filehdr)
247219820Sjeff			  + sizeof(struct aouthdr));
248219820Sjeff
249219820Sjeff  	for (i = 0; i < nscns; i++) {
250219820Sjeff    		if (scns[i].s_flags & STYP_NOLOAD)
251219820Sjeff      			continue;
252219820Sjeff    		else if (scns[i].s_flags & STYP_TEXT) {
253219820Sjeff      			text_address = scns[i].s_vaddr;
254219820Sjeff      			text_size = scns[i].s_size;
255219820Sjeff      			text_offset = scns[i].s_scnptr;
256219820Sjeff    		}
257219820Sjeff		else if (scns[i].s_flags & STYP_DATA) {
258219820Sjeff      			data_address = scns[i].s_vaddr;
259219820Sjeff      			data_size = scns[i].s_size;
260219820Sjeff      			data_offset = scns[i].s_scnptr;
261219820Sjeff    		} else if (scns[i].s_flags & STYP_BSS) {
262219820Sjeff      			bss_size = scns[i].s_size;
263219820Sjeff    		}
264219820Sjeff  	}
265219820Sjeff
266219820Sjeff  	if ((error = load_coff_section(vmspace, vp, text_offset,
267219820Sjeff				      (caddr_t)(void *)(uintptr_t)text_address,
268219820Sjeff				      text_size, text_size,
269219820Sjeff				      VM_PROT_READ | VM_PROT_EXECUTE)) != 0) {
270219820Sjeff    		goto dealloc_and_fail;
271219820Sjeff  	}
272219820Sjeff  	if ((error = load_coff_section(vmspace, vp, data_offset,
273219820Sjeff				      (caddr_t)(void *)(uintptr_t)data_address,
274219820Sjeff				      data_size + bss_size, data_size,
275219820Sjeff				      VM_PROT_ALL)) != 0) {
276219820Sjeff    		goto dealloc_and_fail;
277219820Sjeff  	}
278219820Sjeff
279219820Sjeff  	error = 0;
280219820Sjeff
281219820Sjeff dealloc_and_fail:
282219820Sjeff	if (vm_map_remove(kernel_map,
283219820Sjeff			  (vm_offset_t) ptr,
284219820Sjeff			  (vm_offset_t) ptr + PAGE_SIZE))
285219820Sjeff    		panic("%s vm_map_remove failed", __func__);
286219820Sjeff
287219820Sjeff fail:
288219820Sjeff	VOP_UNLOCK(vp, 0, td);
289219820Sjeff unlocked_fail:
290219820Sjeff	NDFREE(&nd, NDF_ONLY_PNBUF);
291219820Sjeff	vrele(nd.ni_vp);
292219820Sjeff  	return error;
293219820Sjeff}
294219820Sjeff
295219820Sjeffstatic int
296219820Sjeffexec_coff_imgact(imgp)
297219820Sjeff	struct image_params *imgp;
298219820Sjeff{
299219820Sjeff	const struct filehdr *fhdr = (const struct filehdr*)imgp->image_header;
300219820Sjeff	const struct aouthdr *ahdr;
301219820Sjeff	const struct scnhdr *scns;
302219820Sjeff	int i;
303219820Sjeff	struct vmspace *vmspace;
304219820Sjeff	int nscns;
305219820Sjeff	int error;
306219820Sjeff	unsigned long text_offset = 0, text_address = 0, text_size = 0;
307219820Sjeff	unsigned long data_offset = 0, data_address = 0, data_size = 0;
308219820Sjeff	unsigned long bss_size = 0;
309219820Sjeff	caddr_t hole;
310219820Sjeff	struct thread *td = curthread;
311219820Sjeff
312219820Sjeff	if (fhdr->f_magic != I386_COFF ||
313219820Sjeff	    !(fhdr->f_flags & F_EXEC)) {
314219820Sjeff
315219820Sjeff		 DPRINTF(("%s(%d): return -1\n", __FILE__, __LINE__));
316219820Sjeff		 return -1;
317219820Sjeff	}
318219820Sjeff
319219820Sjeff	nscns = fhdr->f_nscns;
320219820Sjeff	if ((nscns * sizeof(struct scnhdr)) > PAGE_SIZE) {
321219820Sjeff	  	/*
322219820Sjeff	   	 * For now, return an error -- need to be able to
323219820Sjeff	   	 * read in all of the section structures.
324219820Sjeff	   	 */
325219820Sjeff
326219820Sjeff		DPRINTF(("%s(%d): return -1\n", __FILE__, __LINE__));
327219820Sjeff		return -1;
328219820Sjeff	}
329219820Sjeff
330219820Sjeff	ahdr = (const struct aouthdr*)
331219820Sjeff	       ((const char*)(imgp->image_header) + sizeof(struct filehdr));
332219820Sjeff	imgp->entry_addr = ahdr->entry;
333219820Sjeff
334219820Sjeff	scns = (const struct scnhdr*)
335219820Sjeff	       ((const char*)(imgp->image_header) + sizeof(struct filehdr) +
336219820Sjeff		sizeof(struct aouthdr));
337219820Sjeff
338219820Sjeff	VOP_UNLOCK(imgp->vp, 0, td);
339219820Sjeff
340219820Sjeff	error = exec_new_vmspace(imgp, &ibcs2_svr3_sysvec);
341219820Sjeff	if (error)
342219820Sjeff		goto fail;
343219820Sjeff	vmspace = imgp->proc->p_vmspace;
344219820Sjeff
345219820Sjeff	for (i = 0; i < nscns; i++) {
346219820Sjeff
347219820Sjeff	  DPRINTF(("i = %d, scns[i].s_name = %s, scns[i].s_vaddr = %08lx, "
348219820Sjeff		   "scns[i].s_scnptr = %d\n", i, scns[i].s_name,
349219820Sjeff		   scns[i].s_vaddr, scns[i].s_scnptr));
350219820Sjeff	  if (scns[i].s_flags & STYP_NOLOAD) {
351219820Sjeff	    	/*
352219820Sjeff	     	 * A section that is not loaded, for whatever
353219820Sjeff	     	 * reason.  It takes precedance over other flag
354219820Sjeff	     	 * bits...
355219820Sjeff	     	 */
356219820Sjeff	    	continue;
357219820Sjeff	  } else if (scns[i].s_flags & STYP_TEXT) {
358219820Sjeff	    	text_address = scns[i].s_vaddr;
359219820Sjeff	    	text_size = scns[i].s_size;
360219820Sjeff	    	text_offset = scns[i].s_scnptr;
361219820Sjeff	  } else if (scns[i].s_flags & STYP_DATA) {
362219820Sjeff	    	/* .data section */
363219820Sjeff	    	data_address = scns[i].s_vaddr;
364219820Sjeff	    	data_size = scns[i].s_size;
365219820Sjeff	    	data_offset = scns[i].s_scnptr;
366219820Sjeff	  } else if (scns[i].s_flags & STYP_BSS) {
367219820Sjeff	    	/* .bss section */
368219820Sjeff	    	bss_size = scns[i].s_size;
369219820Sjeff	  } else if (scns[i].s_flags & STYP_LIB) {
370219820Sjeff	    	char *buf = 0;
371219820Sjeff	    	int foff = trunc_page(scns[i].s_scnptr);
372219820Sjeff	    	int off = scns[i].s_scnptr - foff;
373219820Sjeff	    	int len = round_page(scns[i].s_size + PAGE_SIZE);
374219820Sjeff	    	int j;
375219820Sjeff
376219820Sjeff	    	if ((error = vm_mmap(kernel_map,
377219820Sjeff				    (vm_offset_t *) &buf,
378219820Sjeff				    len,
379219820Sjeff				    VM_PROT_READ,
380219820Sjeff				    VM_PROT_READ,
381219820Sjeff				    0,
382219820Sjeff				    OBJT_VNODE,
383219820Sjeff				    imgp->vp,
384219820Sjeff				    foff)) != 0) {
385219820Sjeff	      		error = ENOEXEC;
386219820Sjeff			goto fail;
387219820Sjeff	    	}
388219820Sjeff		if(scns[i].s_size) {
389219820Sjeff			char *libbuf;
390219820Sjeff			int emul_path_len = strlen(ibcs2_emul_path);
391219820Sjeff
392219820Sjeff			libbuf = malloc(MAXPATHLEN + emul_path_len,
393219820Sjeff					M_TEMP, M_WAITOK);
394219820Sjeff			strcpy(libbuf, ibcs2_emul_path);
395219820Sjeff
396219820Sjeff		    	for (j = off; j < scns[i].s_size + off;) {
397219820Sjeff				long stroff, nextoff;
398219820Sjeff	      			char *libname;
399219820Sjeff
400219820Sjeff				nextoff = 4 * *(long *)(buf + j);
401219820Sjeff				stroff = 4 * *(long *)(buf + j + sizeof(long));
402219820Sjeff
403219820Sjeff		      		libname = buf + j + stroff;
404219820Sjeff		      		j += nextoff;
405219820Sjeff
406219820Sjeff				DPRINTF(("%s(%d):  shared library %s\n",
407219820Sjeff					 __FILE__, __LINE__, libname));
408219820Sjeff				strlcpy(&libbuf[emul_path_len], libname, MAXPATHLEN);
409219820Sjeff/* XXXKSE only 1:1 in coff */  	error = coff_load_file(
410219820Sjeff				    FIRST_THREAD_IN_PROC(imgp->proc), libbuf);
411219820Sjeff		      		if (error)
412219820Sjeff	      				error = coff_load_file(
413219820Sjeff					    FIRST_THREAD_IN_PROC(imgp->proc),
414219820Sjeff					    libname);
415219820Sjeff		      		if (error)
416219820Sjeff					break;
417219820Sjeff		    	}
418219820Sjeff			free(libbuf, M_TEMP);
419219820Sjeff		}
420219820Sjeff		if (vm_map_remove(kernel_map,
421219820Sjeff				  (vm_offset_t) buf,
422219820Sjeff				  (vm_offset_t) buf + len))
423219820Sjeff	      		panic("exec_coff_imgact vm_map_remove failed");
424219820Sjeff	    	if (error)
425219820Sjeff	      		goto fail;
426219820Sjeff	  	}
427219820Sjeff	}
428219820Sjeff	/*
429219820Sjeff	 * Map in .text now
430219820Sjeff	 */
431219820Sjeff
432219820Sjeff	DPRINTF(("%s(%d):  load_coff_section(vmspace, "
433219820Sjeff		"imgp->vp, %08lx, %08lx, 0x%x, 0x%x, 0x%x)\n",
434219820Sjeff		__FILE__, __LINE__, text_offset, text_address,
435219820Sjeff		text_size, text_size, VM_PROT_READ | VM_PROT_EXECUTE));
436219820Sjeff	if ((error = load_coff_section(vmspace, imgp->vp,
437219820Sjeff				      text_offset,
438219820Sjeff				      (caddr_t)(void *)(uintptr_t)text_address,
439219820Sjeff				      text_size, text_size,
440219820Sjeff				      VM_PROT_READ | VM_PROT_EXECUTE)) != 0) {
441219820Sjeff		DPRINTF(("%s(%d): error = %d\n", __FILE__, __LINE__, error));
442219820Sjeff		goto fail;
443219820Sjeff       	}
444219820Sjeff	/*
445219820Sjeff	 * Map in .data and .bss now
446219820Sjeff	 */
447219820Sjeff
448219820Sjeff
449219820Sjeff	DPRINTF(("%s(%d): load_coff_section(vmspace, "
450219820Sjeff		"imgp->vp, 0x%08lx, 0x%08lx, 0x%x, 0x%x, 0x%x)\n",
451219820Sjeff		__FILE__, __LINE__, data_offset, data_address,
452219820Sjeff		data_size + bss_size, data_size, VM_PROT_ALL));
453219820Sjeff	if ((error = load_coff_section(vmspace, imgp->vp,
454219820Sjeff				      data_offset,
455219820Sjeff				      (caddr_t)(void *)(uintptr_t)data_address,
456219820Sjeff				      data_size + bss_size, data_size,
457219820Sjeff				      VM_PROT_ALL)) != 0) {
458219820Sjeff
459219820Sjeff		DPRINTF(("%s(%d): error = %d\n", __FILE__, __LINE__, error));
460219820Sjeff		goto fail;
461219820Sjeff	}
462219820Sjeff
463219820Sjeff	imgp->interpreted = 0;
464219820Sjeff	imgp->proc->p_sysent = &ibcs2_svr3_sysvec;
465219820Sjeff
466219820Sjeff	vmspace->vm_tsize = round_page(text_size) >> PAGE_SHIFT;
467219820Sjeff	vmspace->vm_dsize = round_page(data_size + bss_size) >> PAGE_SHIFT;
468219820Sjeff	vmspace->vm_taddr = (caddr_t)(void *)(uintptr_t)text_address;
469219820Sjeff	vmspace->vm_daddr = (caddr_t)(void *)(uintptr_t)data_address;
470219820Sjeff
471219820Sjeff	hole = (caddr_t)trunc_page((vm_offset_t)vmspace->vm_daddr) + ctob(vmspace->vm_dsize);
472219820Sjeff
473219820Sjeff
474219820Sjeff	DPRINTF(("%s(%d): vm_map_find(&vmspace->vm_map, NULL, 0, &0x%08lx, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0)\n",
475219820Sjeff		__FILE__, __LINE__, hole));
476219820Sjeff        DPRINTF(("imgact: error = %d\n", error));
477219820Sjeff
478219820Sjeff	error = vm_map_find(&vmspace->vm_map, NULL, 0,
479219820Sjeff			    (vm_offset_t *) &hole, PAGE_SIZE, FALSE,
480219820Sjeff				VM_PROT_ALL, VM_PROT_ALL, 0);
481219820Sjeff
482219820Sjeff	DPRINTF(("IBCS2: start vm_dsize = 0x%x, vm_daddr = 0x%x end = 0x%x\n",
483219820Sjeff		ctob(vmspace->vm_dsize), vmspace->vm_daddr,
484219820Sjeff		ctob(vmspace->vm_dsize) + vmspace->vm_daddr ));
485219820Sjeff	DPRINTF(("%s(%d):  returning successfully!\n", __FILE__, __LINE__));
486219820Sjeff
487219820Sjefffail:
488219820Sjeff	vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td);
489219820Sjeff
490219820Sjeff	return error;
491219820Sjeff}
492219820Sjeff
493219820Sjeff/*
494219820Sjeff * Tell kern_execve.c about it, with a little help from the linker.
495219820Sjeff */
496219820Sjeffstatic struct execsw coff_execsw = { exec_coff_imgact, "coff" };
497219820SjeffEXEC_SET(coff, coff_execsw);
498219820Sjeff