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