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