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