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