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