1e1743d02SSøren Schmidt /*- 2e1743d02SSøren Schmidt * Copyright (c) 1995-1996 S�ren Schmidt 3e1743d02SSøren Schmidt * Copyright (c) 1996 Peter Wemm 4e1743d02SSøren Schmidt * All rights reserved. 5e1743d02SSøren Schmidt * 6e1743d02SSøren Schmidt * Redistribution and use in source and binary forms, with or without 7e1743d02SSøren Schmidt * modification, are permitted provided that the following conditions 8e1743d02SSøren Schmidt * are met: 9e1743d02SSøren Schmidt * 1. Redistributions of source code must retain the above copyright 10e1743d02SSøren Schmidt * notice, this list of conditions and the following disclaimer 11e1743d02SSøren Schmidt * in this position and unchanged. 12e1743d02SSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 13e1743d02SSøren Schmidt * notice, this list of conditions and the following disclaimer in the 14e1743d02SSøren Schmidt * documentation and/or other materials provided with the distribution. 15e1743d02SSøren Schmidt * 3. The name of the author may not be used to endorse or promote products 16e1743d02SSøren Schmidt * derived from this software withough specific prior written permission 17e1743d02SSøren Schmidt * 18e1743d02SSøren Schmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19e1743d02SSøren Schmidt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20e1743d02SSøren Schmidt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21e1743d02SSøren Schmidt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22e1743d02SSøren Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23e1743d02SSøren Schmidt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24e1743d02SSøren Schmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25e1743d02SSøren Schmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26e1743d02SSøren Schmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27e1743d02SSøren Schmidt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28e1743d02SSøren Schmidt * 29ea5a2b2eSSøren Schmidt * $Id: imgact_elf.c,v 1.9 1996/10/03 06:14:48 peter Exp $ 30e1743d02SSøren Schmidt */ 31e1743d02SSøren Schmidt 32e1743d02SSøren Schmidt #include <sys/param.h> 33e1743d02SSøren Schmidt #include <sys/systm.h> 34e1743d02SSøren Schmidt #include <sys/resourcevar.h> 35e1743d02SSøren Schmidt #include <sys/exec.h> 36e1743d02SSøren Schmidt #include <sys/mman.h> 37e1743d02SSøren Schmidt #include <sys/imgact.h> 38e1743d02SSøren Schmidt #include <sys/imgact_elf.h> 39e1743d02SSøren Schmidt #include <sys/kernel.h> 40e1743d02SSøren Schmidt #include <sys/sysent.h> 41e1743d02SSøren Schmidt #include <sys/file.h> 42e1743d02SSøren Schmidt #include <sys/malloc.h> 43e1743d02SSøren Schmidt #include <sys/mount.h> 44a794e791SBruce Evans #include <sys/namei.h> 45a794e791SBruce Evans #include <sys/proc.h> 46e1743d02SSøren Schmidt #include <sys/sysproto.h> 47e1743d02SSøren Schmidt #include <sys/syscall.h> 48e1743d02SSøren Schmidt #include <sys/signalvar.h> 49e1743d02SSøren Schmidt #include <sys/sysctl.h> 50a794e791SBruce Evans #include <sys/vnode.h> 51e1743d02SSøren Schmidt 52e1743d02SSøren Schmidt #include <vm/vm.h> 53e1743d02SSøren Schmidt #include <vm/vm_kern.h> 54e1743d02SSøren Schmidt #include <vm/vm_param.h> 55e1743d02SSøren Schmidt #include <vm/pmap.h> 56e1743d02SSøren Schmidt #include <vm/lock.h> 57e1743d02SSøren Schmidt #include <vm/vm_map.h> 58e1743d02SSøren Schmidt #include <vm/vm_prot.h> 59e1743d02SSøren Schmidt #include <vm/vm_extern.h> 60e1743d02SSøren Schmidt 61e1743d02SSøren Schmidt #include <machine/md_var.h> 62e1743d02SSøren Schmidt #include <i386/linux/linux_syscall.h> 63e1743d02SSøren Schmidt #include <i386/linux/linux.h> 64e1743d02SSøren Schmidt 65e1743d02SSøren Schmidt #define MAX_PHDR 32 /* XXX enough ? */ 66e1743d02SSøren Schmidt 67e1743d02SSøren Schmidt static int map_pages __P((struct vnode *vp, vm_offset_t offset, vm_offset_t *buf, vm_size_t size)); 681a7eb2dcSPeter Wemm static void unmap_pages __P((vm_offset_t buf, vm_size_t size)); 69250c11f9SPeter Wemm static int elf_check_permissions __P((struct proc *p, struct vnode *vp)); 70e0c95ed9SBruce Evans static int elf_check_header __P((const Elf32_Ehdr *hdr, int type)); 71e1743d02SSøren Schmidt static int elf_load_section __P((struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot)); 72e1743d02SSøren Schmidt static int elf_load_file __P((struct proc *p, char *file, u_long *addr, u_long *entry)); 73e1743d02SSøren Schmidt static int elf_freebsd_fixup __P((int **stack_base, struct image_params *imgp)); 74e1743d02SSøren Schmidt int exec_elf_imgact __P((struct image_params *imgp)); 75e1743d02SSøren Schmidt 76e1743d02SSøren Schmidt int elf_trace = 0; 77e1743d02SSøren Schmidt SYSCTL_INT(_debug, 1, elf_trace, CTLFLAG_RW, &elf_trace, 0, ""); 78e1743d02SSøren Schmidt #define UPRINTF if (elf_trace) uprintf 79e1743d02SSøren Schmidt 80e1743d02SSøren Schmidt static struct sysentvec elf_freebsd_sysvec = { 81e1743d02SSøren Schmidt SYS_MAXSYSCALL, 82e1743d02SSøren Schmidt sysent, 83e1743d02SSøren Schmidt 0, 84e1743d02SSøren Schmidt 0, 85e1743d02SSøren Schmidt 0, 86e1743d02SSøren Schmidt 0, 87e1743d02SSøren Schmidt 0, 88e1743d02SSøren Schmidt elf_freebsd_fixup, 89e1743d02SSøren Schmidt sendsig, 90e1743d02SSøren Schmidt sigcode, 91e1743d02SSøren Schmidt &szsigcode, 92e1743d02SSøren Schmidt 0, 936ead3eddSJohn Dyson "FreeBSD ELF" 94e1743d02SSøren Schmidt }; 95e1743d02SSøren Schmidt 96ea5a2b2eSSøren Schmidt static Elf32_Brandinfo freebsd_brand_info = { 97ea5a2b2eSSøren Schmidt "FreeBSD", 98ea5a2b2eSSøren Schmidt "", 99e1743d02SSøren Schmidt "/usr/libexec/ld-elf.so.1", 100ea5a2b2eSSøren Schmidt &elf_freebsd_sysvec 101e1743d02SSøren Schmidt }; 102ea5a2b2eSSøren Schmidt static Elf32_Brandinfo *elf_brand_list[MAX_BRANDS] = { 103ea5a2b2eSSøren Schmidt &freebsd_brand_info, 104e1743d02SSøren Schmidt NULL, NULL, NULL, 105e1743d02SSøren Schmidt NULL, NULL, NULL, NULL 106e1743d02SSøren Schmidt }; 107e1743d02SSøren Schmidt 108e1743d02SSøren Schmidt int 109ea5a2b2eSSøren Schmidt elf_insert_brand_entry(Elf32_Brandinfo *entry) 110e1743d02SSøren Schmidt { 111e1743d02SSøren Schmidt int i; 112e1743d02SSøren Schmidt 113ea5a2b2eSSøren Schmidt for (i=1; i<MAX_BRANDS; i++) { 114ea5a2b2eSSøren Schmidt if (elf_brand_list[i] == NULL) { 115ea5a2b2eSSøren Schmidt elf_brand_list[i] = entry; 116e1743d02SSøren Schmidt break; 117e1743d02SSøren Schmidt } 118e1743d02SSøren Schmidt } 119ea5a2b2eSSøren Schmidt if (i == MAX_BRANDS) 120e1743d02SSøren Schmidt return -1; 121e1743d02SSøren Schmidt return 0; 122e1743d02SSøren Schmidt } 123e1743d02SSøren Schmidt 124e1743d02SSøren Schmidt int 125ea5a2b2eSSøren Schmidt elf_remove_brand_entry(Elf32_Brandinfo *entry) 126e1743d02SSøren Schmidt { 127e1743d02SSøren Schmidt int i; 128e1743d02SSøren Schmidt 129ea5a2b2eSSøren Schmidt for (i=1; i<MAX_BRANDS; i++) { 130ea5a2b2eSSøren Schmidt if (elf_brand_list[i] == entry) { 131ea5a2b2eSSøren Schmidt elf_brand_list[i] = NULL; 132e1743d02SSøren Schmidt break; 133e1743d02SSøren Schmidt } 134e1743d02SSøren Schmidt } 135ea5a2b2eSSøren Schmidt if (i == MAX_BRANDS) 136e1743d02SSøren Schmidt return -1; 137e1743d02SSøren Schmidt return 0; 138e1743d02SSøren Schmidt } 139e1743d02SSøren Schmidt 140e1743d02SSøren Schmidt static int 141e1743d02SSøren Schmidt map_pages(struct vnode *vp, vm_offset_t offset, 142e1743d02SSøren Schmidt vm_offset_t *buf, vm_size_t size) 143e1743d02SSøren Schmidt { 144c23670e2SGary Palmer int error; 145e1743d02SSøren Schmidt vm_offset_t kern_buf; 146e1743d02SSøren Schmidt vm_size_t pageoff; 147e1743d02SSøren Schmidt 148e1743d02SSøren Schmidt /* 149e1743d02SSøren Schmidt * The request may not be aligned, and may even cross several 150e1743d02SSøren Schmidt * page boundaries in the file... 151e1743d02SSøren Schmidt */ 152e1743d02SSøren Schmidt pageoff = (offset & PAGE_MASK); 153e1743d02SSøren Schmidt offset -= pageoff; /* start of first aligned page to map */ 154e1743d02SSøren Schmidt size += pageoff; 155e1743d02SSøren Schmidt size = round_page(size); /* size of aligned pages to map */ 156e1743d02SSøren Schmidt 157e1743d02SSøren Schmidt if (error = vm_mmap(kernel_map, 158e1743d02SSøren Schmidt &kern_buf, 159e1743d02SSøren Schmidt size, 160e1743d02SSøren Schmidt VM_PROT_READ, 161e1743d02SSøren Schmidt VM_PROT_READ, 16271d7d1b1SPeter Wemm 0, 163e1743d02SSøren Schmidt (caddr_t)vp, 164e1743d02SSøren Schmidt offset)) 165e1743d02SSøren Schmidt return error; 166e1743d02SSøren Schmidt 167e1743d02SSøren Schmidt *buf = kern_buf + pageoff; 168e1743d02SSøren Schmidt 169e1743d02SSøren Schmidt return 0; 170e1743d02SSøren Schmidt } 171e1743d02SSøren Schmidt 172e1743d02SSøren Schmidt static void 1731a7eb2dcSPeter Wemm unmap_pages(vm_offset_t buf, vm_size_t size) 174e1743d02SSøren Schmidt { 175e1743d02SSøren Schmidt vm_size_t pageoff; 176e1743d02SSøren Schmidt 177e1743d02SSøren Schmidt pageoff = (buf & PAGE_MASK); 178e1743d02SSøren Schmidt buf -= pageoff; /* start of first aligned page to map */ 179e1743d02SSøren Schmidt size += pageoff; 180e1743d02SSøren Schmidt size = round_page(size);/* size of aligned pages to map */ 181e1743d02SSøren Schmidt 1828191d577SPeter Wemm vm_map_remove(kernel_map, buf, buf + size); 183e1743d02SSøren Schmidt } 184e1743d02SSøren Schmidt 185e1743d02SSøren Schmidt static int 186e1743d02SSøren Schmidt elf_check_permissions(struct proc *p, struct vnode *vp) 187e1743d02SSøren Schmidt { 188e1743d02SSøren Schmidt struct vattr attr; 189e1743d02SSøren Schmidt int error; 190e1743d02SSøren Schmidt 191e1743d02SSøren Schmidt /* 192e1743d02SSøren Schmidt * Check number of open-for-writes on the file and deny execution 193e1743d02SSøren Schmidt * if there are any. 194e1743d02SSøren Schmidt */ 195e1743d02SSøren Schmidt if (vp->v_writecount) { 196e1743d02SSøren Schmidt return (ETXTBSY); 197e1743d02SSøren Schmidt } 198e1743d02SSøren Schmidt 199e1743d02SSøren Schmidt /* Get file attributes */ 200e1743d02SSøren Schmidt error = VOP_GETATTR(vp, &attr, p->p_ucred, p); 201e1743d02SSøren Schmidt if (error) 202e1743d02SSøren Schmidt return (error); 203e1743d02SSøren Schmidt 204e1743d02SSøren Schmidt /* 205e1743d02SSøren Schmidt * 1) Check if file execution is disabled for the filesystem that this 206e1743d02SSøren Schmidt * file resides on. 207e1743d02SSøren Schmidt * 2) Insure that at least one execute bit is on - otherwise root 208e1743d02SSøren Schmidt * will always succeed, and we don't want to happen unless the 209e1743d02SSøren Schmidt * file really is executable. 210e1743d02SSøren Schmidt * 3) Insure that the file is a regular file. 211e1743d02SSøren Schmidt */ 212e1743d02SSøren Schmidt if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || 213e1743d02SSøren Schmidt ((attr.va_mode & 0111) == 0) || 214e1743d02SSøren Schmidt (attr.va_type != VREG)) { 215e1743d02SSøren Schmidt return (EACCES); 216e1743d02SSøren Schmidt } 217e1743d02SSøren Schmidt 218e1743d02SSøren Schmidt /* 219e1743d02SSøren Schmidt * Zero length files can't be exec'd 220e1743d02SSøren Schmidt */ 221e1743d02SSøren Schmidt if (attr.va_size == 0) 222e1743d02SSøren Schmidt return (ENOEXEC); 223e1743d02SSøren Schmidt 224e1743d02SSøren Schmidt /* 225e1743d02SSøren Schmidt * Check for execute permission to file based on current credentials. 226e1743d02SSøren Schmidt * Then call filesystem specific open routine (which does nothing 227e1743d02SSøren Schmidt * in the general case). 228e1743d02SSøren Schmidt */ 229e1743d02SSøren Schmidt error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 230e1743d02SSøren Schmidt if (error) 231e1743d02SSøren Schmidt return (error); 232e1743d02SSøren Schmidt 233e1743d02SSøren Schmidt error = VOP_OPEN(vp, FREAD, p->p_ucred, p); 234e1743d02SSøren Schmidt if (error) 235e1743d02SSøren Schmidt return (error); 236e1743d02SSøren Schmidt 237e1743d02SSøren Schmidt return (0); 238e1743d02SSøren Schmidt } 239e1743d02SSøren Schmidt 240e1743d02SSøren Schmidt static int 241e0c95ed9SBruce Evans elf_check_header(const Elf32_Ehdr *hdr, int type) 242e1743d02SSøren Schmidt { 243e1743d02SSøren Schmidt if (!(hdr->e_ident[EI_MAG0] == ELFMAG0 && 244e1743d02SSøren Schmidt hdr->e_ident[EI_MAG1] == ELFMAG1 && 245e1743d02SSøren Schmidt hdr->e_ident[EI_MAG2] == ELFMAG2 && 246e1743d02SSøren Schmidt hdr->e_ident[EI_MAG3] == ELFMAG3)) 247e1743d02SSøren Schmidt return ENOEXEC; 248e1743d02SSøren Schmidt 249e1743d02SSøren Schmidt if (hdr->e_machine != EM_386 && hdr->e_machine != EM_486) 250e1743d02SSøren Schmidt return ENOEXEC; 251e1743d02SSøren Schmidt 252e1743d02SSøren Schmidt if (hdr->e_type != type) 253e1743d02SSøren Schmidt return ENOEXEC; 254e1743d02SSøren Schmidt 255e1743d02SSøren Schmidt return 0; 256e1743d02SSøren Schmidt } 257e1743d02SSøren Schmidt 258e1743d02SSøren Schmidt static int 259e1743d02SSøren Schmidt elf_load_section(struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot) 260e1743d02SSøren Schmidt { 261e1743d02SSøren Schmidt size_t map_len; 262e1743d02SSøren Schmidt vm_offset_t map_addr; 263e1743d02SSøren Schmidt int error; 264e1743d02SSøren Schmidt unsigned char *data_buf = 0; 265e1743d02SSøren Schmidt size_t copy_len; 266e1743d02SSøren Schmidt 267e1743d02SSøren Schmidt map_addr = trunc_page(vmaddr); 268e1743d02SSøren Schmidt 269e1743d02SSøren Schmidt if (memsz > filsz) 270e1743d02SSøren Schmidt map_len = trunc_page(offset+filsz) - trunc_page(offset); 271e1743d02SSøren Schmidt else 272e1743d02SSøren Schmidt map_len = round_page(offset+filsz) - trunc_page(offset); 273e1743d02SSøren Schmidt 274e1743d02SSøren Schmidt if (error = vm_mmap (&vmspace->vm_map, 275e1743d02SSøren Schmidt &map_addr, 276e1743d02SSøren Schmidt map_len, 277e1743d02SSøren Schmidt prot, 278e1743d02SSøren Schmidt VM_PROT_ALL, 27971d7d1b1SPeter Wemm MAP_PRIVATE | MAP_FIXED, 280e1743d02SSøren Schmidt (caddr_t)vp, 281e1743d02SSøren Schmidt trunc_page(offset))) 282e1743d02SSøren Schmidt return error; 283e1743d02SSøren Schmidt 284e1743d02SSøren Schmidt if (memsz == filsz) 285e1743d02SSøren Schmidt return 0; 286e1743d02SSøren Schmidt 287e1743d02SSøren Schmidt /* 288e1743d02SSøren Schmidt * We have to map the remaining bit of the file into the kernel's 289e1743d02SSøren Schmidt * memory map, allocate some anonymous memory, and copy that last 290e1743d02SSøren Schmidt * bit into it. The remaining space should be .bss... 291e1743d02SSøren Schmidt */ 292e1743d02SSøren Schmidt copy_len = (offset + filsz) - trunc_page(offset + filsz); 293e1743d02SSøren Schmidt map_addr = trunc_page(vmaddr + filsz); 294250c11f9SPeter Wemm map_len = round_page(vmaddr + memsz) - map_addr; 295e1743d02SSøren Schmidt 2968191d577SPeter Wemm if (map_len != 0) { 297e1743d02SSøren Schmidt if (error = vm_map_find(&vmspace->vm_map, NULL, 0, 298e1743d02SSøren Schmidt &map_addr, map_len, FALSE, 299e1743d02SSøren Schmidt VM_PROT_ALL, VM_PROT_ALL,0)) 300e1743d02SSøren Schmidt return error; 3018191d577SPeter Wemm } 302e1743d02SSøren Schmidt 303e1743d02SSøren Schmidt if (error = vm_mmap(kernel_map, 304e1743d02SSøren Schmidt (vm_offset_t *)&data_buf, 305e1743d02SSøren Schmidt PAGE_SIZE, 306e1743d02SSøren Schmidt VM_PROT_READ, 307e1743d02SSøren Schmidt VM_PROT_READ, 30871d7d1b1SPeter Wemm 0, 309e1743d02SSøren Schmidt (caddr_t)vp, 310e1743d02SSøren Schmidt trunc_page(offset + filsz))) 311e1743d02SSøren Schmidt return error; 312e1743d02SSøren Schmidt 313e1743d02SSøren Schmidt error = copyout(data_buf, (caddr_t)map_addr, copy_len); 314e1743d02SSøren Schmidt 315e1743d02SSøren Schmidt vm_map_remove(kernel_map, (vm_offset_t)data_buf, 316e1743d02SSøren Schmidt (vm_offset_t)data_buf + PAGE_SIZE); 317e1743d02SSøren Schmidt 318e1743d02SSøren Schmidt /* 3198191d577SPeter Wemm * set it to the specified protection 320e1743d02SSøren Schmidt */ 3218191d577SPeter Wemm vm_map_protect(&vmspace->vm_map, map_addr, map_addr + map_len, prot, 3228191d577SPeter Wemm FALSE); 3238191d577SPeter Wemm 324e1743d02SSøren Schmidt UPRINTF("bss size %d (%x)\n", map_len-copy_len, map_len-copy_len); 325e1743d02SSøren Schmidt return error; 326e1743d02SSøren Schmidt } 327e1743d02SSøren Schmidt 328e1743d02SSøren Schmidt static int 329e1743d02SSøren Schmidt elf_load_file(struct proc *p, char *file, u_long *addr, u_long *entry) 330e1743d02SSøren Schmidt { 331e1743d02SSøren Schmidt Elf32_Ehdr *hdr = NULL; 332e1743d02SSøren Schmidt Elf32_Phdr *phdr = NULL; 333e1743d02SSøren Schmidt struct nameidata nd; 334e1743d02SSøren Schmidt struct vmspace *vmspace = p->p_vmspace; 335e1743d02SSøren Schmidt vm_prot_t prot = 0; 336e1743d02SSøren Schmidt unsigned long text_size = 0, data_size = 0; 337e1743d02SSøren Schmidt unsigned long text_addr = 0, data_addr = 0; 338e1743d02SSøren Schmidt int header_size = 0; 339e1743d02SSøren Schmidt int error, i; 340e1743d02SSøren Schmidt 341e1743d02SSøren Schmidt NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_SYSSPACE, file, p); 342e1743d02SSøren Schmidt 343e1743d02SSøren Schmidt if (error = namei(&nd)) 344e1743d02SSøren Schmidt goto fail; 345e1743d02SSøren Schmidt 346e1743d02SSøren Schmidt if (nd.ni_vp == NULL) { 347e1743d02SSøren Schmidt error = ENOEXEC; 348e1743d02SSøren Schmidt goto fail; 349e1743d02SSøren Schmidt } 350e1743d02SSøren Schmidt 351e1743d02SSøren Schmidt /* 352e1743d02SSøren Schmidt * Check permissions, modes, uid, etc on the file, and "open" it. 353e1743d02SSøren Schmidt */ 354e1743d02SSøren Schmidt error = elf_check_permissions(p, nd.ni_vp); 355e1743d02SSøren Schmidt 356e1743d02SSøren Schmidt /* 357e1743d02SSøren Schmidt * No longer need this, and it prevents demand paging. 358e1743d02SSøren Schmidt */ 359e1743d02SSøren Schmidt VOP_UNLOCK(nd.ni_vp); 360e1743d02SSøren Schmidt 361e1743d02SSøren Schmidt if (error) 362e1743d02SSøren Schmidt goto fail; 363e1743d02SSøren Schmidt 364e1743d02SSøren Schmidt /* 365e1743d02SSøren Schmidt * Map in the header 366e1743d02SSøren Schmidt */ 367e1743d02SSøren Schmidt if (error = map_pages(nd.ni_vp, 0, (vm_offset_t *)&hdr, sizeof(hdr))) 368e1743d02SSøren Schmidt goto fail; 369e1743d02SSøren Schmidt 370e1743d02SSøren Schmidt /* 371e1743d02SSøren Schmidt * Do we have a valid ELF header ? 372e1743d02SSøren Schmidt */ 373e1743d02SSøren Schmidt if (error = elf_check_header(hdr, ET_DYN)) 374e1743d02SSøren Schmidt goto fail; 375e1743d02SSøren Schmidt 376e1743d02SSøren Schmidt /* 377e1743d02SSøren Schmidt * ouch, need to bounds check in case user gives us a corrupted 378e1743d02SSøren Schmidt * file with an insane header size 379e1743d02SSøren Schmidt */ 380e1743d02SSøren Schmidt if (hdr->e_phnum > MAX_PHDR) { /* XXX: ever more than this? */ 381e1743d02SSøren Schmidt error = ENOEXEC; 382e1743d02SSøren Schmidt goto fail; 383e1743d02SSøren Schmidt } 384e1743d02SSøren Schmidt 385e1743d02SSøren Schmidt header_size = hdr->e_phentsize * hdr->e_phnum; 386e1743d02SSøren Schmidt 387e1743d02SSøren Schmidt if (error = map_pages(nd.ni_vp, hdr->e_phoff, (vm_offset_t *)&phdr, 388e1743d02SSøren Schmidt header_size)) 389e1743d02SSøren Schmidt goto fail; 390e1743d02SSøren Schmidt 391e1743d02SSøren Schmidt for (i = 0; i < hdr->e_phnum; i++) { 392e1743d02SSøren Schmidt switch(phdr[i].p_type) { 393e1743d02SSøren Schmidt 394e1743d02SSøren Schmidt case PT_NULL: /* NULL section */ 395e1743d02SSøren Schmidt UPRINTF ("ELF(file) PT_NULL section\n"); 396e1743d02SSøren Schmidt break; 397e1743d02SSøren Schmidt case PT_LOAD: /* Loadable segment */ 398e1743d02SSøren Schmidt { 399e1743d02SSøren Schmidt UPRINTF ("ELF(file) PT_LOAD section "); 400e1743d02SSøren Schmidt if (phdr[i].p_flags & PF_X) 401e1743d02SSøren Schmidt prot |= VM_PROT_EXECUTE; 402e1743d02SSøren Schmidt if (phdr[i].p_flags & PF_W) 403e1743d02SSøren Schmidt prot |= VM_PROT_WRITE; 404e1743d02SSøren Schmidt if (phdr[i].p_flags & PF_R) 405e1743d02SSøren Schmidt prot |= VM_PROT_READ; 406e1743d02SSøren Schmidt 407e1743d02SSøren Schmidt if (error = elf_load_section(vmspace, nd.ni_vp, 408e1743d02SSøren Schmidt phdr[i].p_offset, 409e1743d02SSøren Schmidt (caddr_t)phdr[i].p_vaddr + 410e1743d02SSøren Schmidt (*addr), 411e1743d02SSøren Schmidt phdr[i].p_memsz, 412e1743d02SSøren Schmidt phdr[i].p_filesz, prot)) 413e1743d02SSøren Schmidt goto fail; 414e1743d02SSøren Schmidt 415e1743d02SSøren Schmidt /* 416e1743d02SSøren Schmidt * Is this .text or .data ?? 417e1743d02SSøren Schmidt * 418e1743d02SSøren Schmidt * We only handle one each of those yet XXX 419e1743d02SSøren Schmidt */ 420e1743d02SSøren Schmidt if (hdr->e_entry >= phdr[i].p_vaddr && 421e1743d02SSøren Schmidt hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { 422e1743d02SSøren Schmidt text_addr = trunc_page(phdr[i].p_vaddr+(*addr)); 4238191d577SPeter Wemm text_size = round_page(phdr[i].p_memsz + 4248191d577SPeter Wemm phdr[i].p_vaddr - 4258191d577SPeter Wemm trunc_page(phdr[i].p_vaddr)); 426e1743d02SSøren Schmidt *entry=(unsigned long)hdr->e_entry+(*addr); 427e1743d02SSøren Schmidt UPRINTF(".text <%08x,%08x> entry=%08x\n", 428e1743d02SSøren Schmidt text_addr, text_size, *entry); 429e1743d02SSøren Schmidt } else { 430e1743d02SSøren Schmidt data_addr = trunc_page(phdr[i].p_vaddr+(*addr)); 4318191d577SPeter Wemm data_size = round_page(phdr[i].p_memsz + 4328191d577SPeter Wemm phdr[i].p_vaddr - 4338191d577SPeter Wemm trunc_page(phdr[i].p_vaddr)); 434e1743d02SSøren Schmidt UPRINTF(".data <%08x,%08x>\n", 435e1743d02SSøren Schmidt data_addr, data_size); 436e1743d02SSøren Schmidt } 437e1743d02SSøren Schmidt } 438e1743d02SSøren Schmidt break; 439e1743d02SSøren Schmidt 440e1743d02SSøren Schmidt case PT_DYNAMIC:/* Dynamic link information */ 441e1743d02SSøren Schmidt UPRINTF ("ELF(file) PT_DYNAMIC section\n"); 442e1743d02SSøren Schmidt break; 443e1743d02SSøren Schmidt case PT_INTERP: /* Path to interpreter */ 444e1743d02SSøren Schmidt UPRINTF ("ELF(file) PT_INTERP section\n"); 445e1743d02SSøren Schmidt break; 446e1743d02SSøren Schmidt case PT_NOTE: /* Note section */ 447e1743d02SSøren Schmidt UPRINTF ("ELF(file) PT_NOTE section\n"); 448e1743d02SSøren Schmidt break; 449e1743d02SSøren Schmidt case PT_SHLIB: /* Shared lib section */ 450e1743d02SSøren Schmidt UPRINTF ("ELF(file) PT_SHLIB section\n"); 451e1743d02SSøren Schmidt break; 452e1743d02SSøren Schmidt case PT_PHDR: /* Program header table info */ 453e1743d02SSøren Schmidt UPRINTF ("ELF(file) PT_PHDR section\n"); 454e1743d02SSøren Schmidt break; 455e1743d02SSøren Schmidt default: 456e1743d02SSøren Schmidt UPRINTF ("ELF(file) %d section ??\n", phdr[i].p_type ); 457e1743d02SSøren Schmidt } 458e1743d02SSøren Schmidt } 459e1743d02SSøren Schmidt 460e1743d02SSøren Schmidt fail: 461e1743d02SSøren Schmidt if (phdr) 4621a7eb2dcSPeter Wemm unmap_pages((vm_offset_t)phdr, header_size); 463e1743d02SSøren Schmidt if (hdr) 4641a7eb2dcSPeter Wemm unmap_pages((vm_offset_t)hdr, sizeof(hdr)); 465e1743d02SSøren Schmidt 466e1743d02SSøren Schmidt return error; 467e1743d02SSøren Schmidt } 468e1743d02SSøren Schmidt 469e1743d02SSøren Schmidt int 470e1743d02SSøren Schmidt exec_elf_imgact(struct image_params *imgp) 471e1743d02SSøren Schmidt { 472e0c95ed9SBruce Evans const Elf32_Ehdr *hdr = (const Elf32_Ehdr *) imgp->image_header; 473e0c95ed9SBruce Evans const Elf32_Phdr *phdr, *mapped_phdr = NULL; 474e1743d02SSøren Schmidt Elf32_Auxargs *elf_auxargs = NULL; 475e1743d02SSøren Schmidt struct vmspace *vmspace = imgp->proc->p_vmspace; 476e1743d02SSøren Schmidt vm_prot_t prot = 0; 477e1743d02SSøren Schmidt u_long text_size = 0, data_size = 0; 478e1743d02SSøren Schmidt u_long text_addr = 0, data_addr = 0; 479e1743d02SSøren Schmidt u_long addr, entry = 0, proghdr = 0; 480e1743d02SSøren Schmidt int error, i, header_size = 0, interp_len = 0; 481e1743d02SSøren Schmidt char *interp = NULL; 482ea5a2b2eSSøren Schmidt char *brand = NULL; 483ea5a2b2eSSøren Schmidt char path[MAXPATHLEN]; 484e1743d02SSøren Schmidt 485e1743d02SSøren Schmidt /* 486e1743d02SSøren Schmidt * Do we have a valid ELF header ? 487e1743d02SSøren Schmidt */ 488e1743d02SSøren Schmidt if (elf_check_header(hdr, ET_EXEC)) 489e1743d02SSøren Schmidt return -1; 490e1743d02SSøren Schmidt 491e1743d02SSøren Schmidt /* 492e1743d02SSøren Schmidt * From here on down, we return an errno, not -1, as we've 493e1743d02SSøren Schmidt * detected an ELF file. 494e1743d02SSøren Schmidt */ 495e1743d02SSøren Schmidt 496e1743d02SSøren Schmidt /* 497e1743d02SSøren Schmidt * ouch, need to bounds check in case user gives us a corrupted 498e1743d02SSøren Schmidt * file with an insane header size 499e1743d02SSøren Schmidt */ 500e1743d02SSøren Schmidt if (hdr->e_phnum > MAX_PHDR) { /* XXX: ever more than this? */ 501e1743d02SSøren Schmidt return ENOEXEC; 502e1743d02SSøren Schmidt } 503e1743d02SSøren Schmidt 504e1743d02SSøren Schmidt header_size = hdr->e_phentsize * hdr->e_phnum; 505e1743d02SSøren Schmidt 506e1743d02SSøren Schmidt if ((hdr->e_phoff > PAGE_SIZE) || 507e1743d02SSøren Schmidt (hdr->e_phoff + header_size) > PAGE_SIZE) { 508e1743d02SSøren Schmidt /* 509e1743d02SSøren Schmidt * Ouch ! we only get one page full of header... 510e1743d02SSøren Schmidt * Try to map it in ourselves, and see how we go. 511e1743d02SSøren Schmidt */ 512e1743d02SSøren Schmidt if (error = map_pages(imgp->vp, hdr->e_phoff, 513e1743d02SSøren Schmidt (vm_offset_t *)&mapped_phdr, header_size)) 514e1743d02SSøren Schmidt return (error); 515e1743d02SSøren Schmidt /* 516e1743d02SSøren Schmidt * Save manual mapping for cleanup 517e1743d02SSøren Schmidt */ 518e1743d02SSøren Schmidt phdr = mapped_phdr; 519e1743d02SSøren Schmidt } else { 520e0c95ed9SBruce Evans phdr = (const Elf32_Phdr*) 521e0c95ed9SBruce Evans ((const char *)imgp->image_header + hdr->e_phoff); 522e1743d02SSøren Schmidt } 523e1743d02SSøren Schmidt 524e1743d02SSøren Schmidt /* 525e1743d02SSøren Schmidt * From this point on, we may have resources that need to be freed. 526e1743d02SSøren Schmidt */ 527e1743d02SSøren Schmidt if (error = exec_extract_strings(imgp)) 528e1743d02SSøren Schmidt goto fail; 529e1743d02SSøren Schmidt 530e1743d02SSøren Schmidt exec_new_vmspace(imgp); 531e1743d02SSøren Schmidt 532e1743d02SSøren Schmidt for (i = 0; i < hdr->e_phnum; i++) { 533e1743d02SSøren Schmidt switch(phdr[i].p_type) { 534e1743d02SSøren Schmidt 535e1743d02SSøren Schmidt case PT_NULL: /* NULL section */ 536e1743d02SSøren Schmidt UPRINTF ("ELF PT_NULL section\n"); 537e1743d02SSøren Schmidt break; 538e1743d02SSøren Schmidt case PT_LOAD: /* Loadable segment */ 539e1743d02SSøren Schmidt { 540e1743d02SSøren Schmidt UPRINTF ("ELF PT_LOAD section "); 541e1743d02SSøren Schmidt if (phdr[i].p_flags & PF_X) 542e1743d02SSøren Schmidt prot |= VM_PROT_EXECUTE; 543e1743d02SSøren Schmidt if (phdr[i].p_flags & PF_W) 544e1743d02SSøren Schmidt prot |= VM_PROT_WRITE; 545e1743d02SSøren Schmidt if (phdr[i].p_flags & PF_R) 546e1743d02SSøren Schmidt prot |= VM_PROT_READ; 547e1743d02SSøren Schmidt 548e1743d02SSøren Schmidt if (error = elf_load_section(vmspace, imgp->vp, 549e1743d02SSøren Schmidt phdr[i].p_offset, 550e1743d02SSøren Schmidt (caddr_t)phdr[i].p_vaddr, 551e1743d02SSøren Schmidt phdr[i].p_memsz, 552e1743d02SSøren Schmidt phdr[i].p_filesz, prot)) 553e1743d02SSøren Schmidt goto fail; 554e1743d02SSøren Schmidt 555e1743d02SSøren Schmidt /* 556e1743d02SSøren Schmidt * Is this .text or .data ?? 557e1743d02SSøren Schmidt * 558e1743d02SSøren Schmidt * We only handle one each of those yet XXX 559e1743d02SSøren Schmidt */ 560e1743d02SSøren Schmidt if (hdr->e_entry >= phdr[i].p_vaddr && 561e1743d02SSøren Schmidt hdr->e_entry <(phdr[i].p_vaddr+phdr[i].p_memsz)) { 562e1743d02SSøren Schmidt text_addr = trunc_page(phdr[i].p_vaddr); 5638191d577SPeter Wemm text_size = round_page(phdr[i].p_memsz + 5648191d577SPeter Wemm phdr[i].p_vaddr - 5658191d577SPeter Wemm text_addr); 566e1743d02SSøren Schmidt entry = (u_long)hdr->e_entry; 567e1743d02SSøren Schmidt UPRINTF(".text <%08x,%08x> entry=%08x\n", 568e1743d02SSøren Schmidt text_addr, text_size, entry); 569e1743d02SSøren Schmidt } else { 570e1743d02SSøren Schmidt data_addr = trunc_page(phdr[i].p_vaddr); 5718191d577SPeter Wemm data_size = round_page(phdr[i].p_memsz + 5728191d577SPeter Wemm phdr[i].p_vaddr - 5738191d577SPeter Wemm data_addr); 574e1743d02SSøren Schmidt UPRINTF(".data <%08x,%08x>\n", 575e1743d02SSøren Schmidt data_addr, data_size); 576e1743d02SSøren Schmidt } 577e1743d02SSøren Schmidt } 578e1743d02SSøren Schmidt break; 579e1743d02SSøren Schmidt 580e1743d02SSøren Schmidt case PT_DYNAMIC:/* Dynamic link information */ 581e1743d02SSøren Schmidt UPRINTF ("ELF PT_DYNAMIC section ??\n"); 582e1743d02SSøren Schmidt break; 583e1743d02SSøren Schmidt case PT_INTERP: /* Path to interpreter */ 584e1743d02SSøren Schmidt UPRINTF ("ELF PT_INTERP section "); 585e1743d02SSøren Schmidt if (phdr[i].p_filesz > MAXPATHLEN) { 586e1743d02SSøren Schmidt error = ENOEXEC; 587e1743d02SSøren Schmidt goto fail; 588e1743d02SSøren Schmidt } 589e1743d02SSøren Schmidt interp_len = MAXPATHLEN; 590e1743d02SSøren Schmidt if (error = map_pages(imgp->vp, phdr[i].p_offset, 591e1743d02SSøren Schmidt (vm_offset_t *)&interp, interp_len)) 592e1743d02SSøren Schmidt goto fail; 593e1743d02SSøren Schmidt UPRINTF("<%s>\n", interp); 594e1743d02SSøren Schmidt break; 595e1743d02SSøren Schmidt case PT_NOTE: /* Note section */ 596e1743d02SSøren Schmidt UPRINTF ("ELF PT_NOTE section\n"); 597e1743d02SSøren Schmidt break; 598e1743d02SSøren Schmidt case PT_SHLIB: /* Shared lib section */ 599e1743d02SSøren Schmidt UPRINTF ("ELF PT_SHLIB section\n"); 600e1743d02SSøren Schmidt break; 601e1743d02SSøren Schmidt case PT_PHDR: /* Program header table info */ 602e1743d02SSøren Schmidt UPRINTF ("ELF PT_PHDR section <%x>\n", phdr[i].p_vaddr); 603e1743d02SSøren Schmidt proghdr = phdr[i].p_vaddr; 604e1743d02SSøren Schmidt break; 605e1743d02SSøren Schmidt default: 606e1743d02SSøren Schmidt UPRINTF ("ELF %d section ??\n", phdr[i].p_type); 607e1743d02SSøren Schmidt } 608e1743d02SSøren Schmidt } 609e1743d02SSøren Schmidt 610e1743d02SSøren Schmidt vmspace->vm_tsize = text_size >> PAGE_SHIFT; 611e1743d02SSøren Schmidt vmspace->vm_taddr = (caddr_t)text_addr; 612e1743d02SSøren Schmidt vmspace->vm_dsize = data_size >> PAGE_SHIFT; 613e1743d02SSøren Schmidt vmspace->vm_daddr = (caddr_t)data_addr; 614e1743d02SSøren Schmidt 615e1743d02SSøren Schmidt addr = 2*MAXDSIZ; /* May depend on OS type XXX */ 616e1743d02SSøren Schmidt 617ea5a2b2eSSøren Schmidt imgp->entry_addr = entry; 618ea5a2b2eSSøren Schmidt 619e1743d02SSøren Schmidt /* 620ea5a2b2eSSøren Schmidt * So which kind (brand) of ELF binary do we have at hand 621ea5a2b2eSSøren Schmidt * FreeBSD, Linux, SVR4 or something else ?? 622ea5a2b2eSSøren Schmidt * If its has a interpreter section try that first 623e1743d02SSøren Schmidt */ 624ea5a2b2eSSøren Schmidt if (interp) { 625ea5a2b2eSSøren Schmidt for (i=0; i<MAX_BRANDS; i++) { 626ea5a2b2eSSøren Schmidt if (elf_brand_list[i] != NULL) { 627ea5a2b2eSSøren Schmidt if (!strcmp(interp, elf_brand_list[i]->interp_path)) { 628e1743d02SSøren Schmidt imgp->proc->p_sysent = 629ea5a2b2eSSøren Schmidt elf_brand_list[i]->sysvec; 630ea5a2b2eSSøren Schmidt strcpy(path, elf_brand_list[i]->emul_path); 631ea5a2b2eSSøren Schmidt strcat(path, elf_brand_list[i]->interp_path); 632e1743d02SSøren Schmidt UPRINTF("interpreter=<%s> %s\n", 633ea5a2b2eSSøren Schmidt elf_brand_list[i]->interp_path, 634ea5a2b2eSSøren Schmidt elf_brand_list[i]->emul_path); 635e1743d02SSøren Schmidt break; 636e1743d02SSøren Schmidt } 637e1743d02SSøren Schmidt } 638e1743d02SSøren Schmidt } 639ea5a2b2eSSøren Schmidt } 640ea5a2b2eSSøren Schmidt 641ea5a2b2eSSøren Schmidt /* 642ea5a2b2eSSøren Schmidt * If there is no interpreter, or recognition of it 643ea5a2b2eSSøren Schmidt * failed, se if the binary is branded. 644ea5a2b2eSSøren Schmidt */ 645ea5a2b2eSSøren Schmidt if (!interp || i == MAX_BRANDS) { 646ea5a2b2eSSøren Schmidt brand = (char *)&(hdr->e_ident[EI_BRAND]); 647ea5a2b2eSSøren Schmidt for (i=0; i<MAX_BRANDS; i++) { 648ea5a2b2eSSøren Schmidt if (elf_brand_list[i] != NULL) { 649ea5a2b2eSSøren Schmidt if (!strcmp(brand, elf_brand_list[i]->brand)) { 650ea5a2b2eSSøren Schmidt imgp->proc->p_sysent = elf_brand_list[i]->sysvec; 651ea5a2b2eSSøren Schmidt if (interp) { 652ea5a2b2eSSøren Schmidt strcpy(path, elf_brand_list[i]->emul_path); 653ea5a2b2eSSøren Schmidt strcat(path, elf_brand_list[i]->interp_path); 654ea5a2b2eSSøren Schmidt UPRINTF("interpreter=<%s> %s\n", 655ea5a2b2eSSøren Schmidt elf_brand_list[i]->interp_path, 656ea5a2b2eSSøren Schmidt elf_brand_list[i]->emul_path); 657ea5a2b2eSSøren Schmidt } 658ea5a2b2eSSøren Schmidt } 659ea5a2b2eSSøren Schmidt } 660ea5a2b2eSSøren Schmidt } 661ea5a2b2eSSøren Schmidt } 662ea5a2b2eSSøren Schmidt if (i == MAX_BRANDS) { 663ea5a2b2eSSøren Schmidt uprintf("ELF binary type not known\n"); 664e1743d02SSøren Schmidt error = ENOEXEC; 665e1743d02SSøren Schmidt goto fail; 666e1743d02SSøren Schmidt } 667ea5a2b2eSSøren Schmidt if (interp) { 668e1743d02SSøren Schmidt if (error = elf_load_file(imgp->proc, 669e1743d02SSøren Schmidt path, 670e1743d02SSøren Schmidt &addr, /* XXX */ 671e1743d02SSøren Schmidt &imgp->entry_addr)) { 672e1743d02SSøren Schmidt uprintf("ELF interpreter %s not found\n", path); 673e1743d02SSøren Schmidt goto fail; 674e1743d02SSøren Schmidt } 675e1743d02SSøren Schmidt } 676ea5a2b2eSSøren Schmidt 677ea5a2b2eSSøren Schmidt uprintf("Executing %s binary\n", elf_brand_list[i]->brand); 678e1743d02SSøren Schmidt 679e1743d02SSøren Schmidt /* 680e1743d02SSøren Schmidt * Construct auxargs table (used by the fixup routine) 681e1743d02SSøren Schmidt */ 682e1743d02SSøren Schmidt elf_auxargs = malloc(sizeof(Elf32_Auxargs), M_TEMP, M_WAITOK); 683e1743d02SSøren Schmidt elf_auxargs->execfd = -1; 684e1743d02SSøren Schmidt elf_auxargs->phdr = proghdr; 685e1743d02SSøren Schmidt elf_auxargs->phent = hdr->e_phentsize; 686e1743d02SSøren Schmidt elf_auxargs->phnum = hdr->e_phnum; 687e1743d02SSøren Schmidt elf_auxargs->pagesz = PAGE_SIZE; 688e1743d02SSøren Schmidt elf_auxargs->base = addr; 689e1743d02SSøren Schmidt elf_auxargs->flags = 0; 690e1743d02SSøren Schmidt elf_auxargs->entry = entry; 691e1743d02SSøren Schmidt elf_auxargs->trace = elf_trace; 692e1743d02SSøren Schmidt 693e1743d02SSøren Schmidt imgp->auxargs = elf_auxargs; 694e1743d02SSøren Schmidt imgp->interpreted = 0; 695e1743d02SSøren Schmidt 696e1743d02SSøren Schmidt /* don't allow modifying the file while we run it */ 697e1743d02SSøren Schmidt imgp->vp->v_flag |= VTEXT; 698e1743d02SSøren Schmidt 699e1743d02SSøren Schmidt fail: 700e1743d02SSøren Schmidt if (mapped_phdr) 7011a7eb2dcSPeter Wemm unmap_pages((vm_offset_t)mapped_phdr, header_size); 702e1743d02SSøren Schmidt if (interp) 7031a7eb2dcSPeter Wemm unmap_pages((vm_offset_t)interp, interp_len); 704e1743d02SSøren Schmidt 705e1743d02SSøren Schmidt return error; 706e1743d02SSøren Schmidt } 707e1743d02SSøren Schmidt 708e1743d02SSøren Schmidt static int 709e1743d02SSøren Schmidt elf_freebsd_fixup(int **stack_base, struct image_params *imgp) 710e1743d02SSøren Schmidt { 711e1743d02SSøren Schmidt Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; 712e1743d02SSøren Schmidt int *pos; 713e1743d02SSøren Schmidt 714e1743d02SSøren Schmidt pos = *stack_base + (imgp->argc + imgp->envc + 2); 715e1743d02SSøren Schmidt 716e1743d02SSøren Schmidt if (args->trace) { 717e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_DEBUG, 1); 718e1743d02SSøren Schmidt } 719e1743d02SSøren Schmidt if (args->execfd != -1) { 720e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 721e1743d02SSøren Schmidt } 722e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 723e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 724e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 725e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 726e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 727e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 728e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_BASE, args->base); 729e1743d02SSøren Schmidt AUXARGS_ENTRY(pos, AT_NULL, 0); 730e1743d02SSøren Schmidt 731e1743d02SSøren Schmidt free(imgp->auxargs, M_TEMP); 732e1743d02SSøren Schmidt imgp->auxargs = NULL; 733e1743d02SSøren Schmidt 734e1743d02SSøren Schmidt (*stack_base)--; 735e1743d02SSøren Schmidt **stack_base = (int)imgp->argc; 736e1743d02SSøren Schmidt return 0; 737e1743d02SSøren Schmidt } 738e1743d02SSøren Schmidt 739e1743d02SSøren Schmidt /* 740e1743d02SSøren Schmidt * Tell kern_execve.c about it, with a little help from the linker. 741e1743d02SSøren Schmidt * Since `const' objects end up in the text segment, TEXT_SET is the 742e1743d02SSøren Schmidt * correct directive to use. 743e1743d02SSøren Schmidt */ 744e1743d02SSøren Schmidt const struct execsw elf_execsw = {exec_elf_imgact, "ELF"}; 745e1743d02SSøren Schmidt TEXT_SET(execsw_set, elf_execsw); 746e1743d02SSøren Schmidt 747