xref: /openbsd-src/sys/kern/exec_elf.c (revision 62a742911104f98b9185b2c6b6007d9b1c36396c)
1 /*	$OpenBSD: exec_elf.c,v 1.24 1999/02/10 08:07:20 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 1996 Per Fogelstrom
5  * All rights reserved.
6  *
7  * Copyright (c) 1994 Christos Zoulas
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/proc.h>
38 #include <sys/malloc.h>
39 #include <sys/mount.h>
40 #include <sys/namei.h>
41 #include <sys/vnode.h>
42 #include <sys/exec.h>
43 
44 #if defined(_KERN_DO_ELF)
45 
46 #include <sys/exec_elf.h>
47 #include <sys/exec_olf.h>
48 #include <sys/file.h>
49 #include <sys/syscall.h>
50 #include <sys/signalvar.h>
51 #include <sys/stat.h>
52 
53 #include <sys/mman.h>
54 #include <vm/vm.h>
55 #include <vm/vm_param.h>
56 #include <vm/vm_map.h>
57 
58 #include <machine/cpu.h>
59 #include <machine/reg.h>
60 #include <machine/exec.h>
61 
62 #ifdef COMPAT_LINUX
63 #include <compat/linux/linux_exec.h>
64 #endif
65 
66 #ifdef COMPAT_SVR4
67 #include <compat/svr4/svr4_exec.h>
68 #endif
69 
70 #ifdef COMPAT_FREEBSD
71 #include <compat/freebsd/freebsd_exec.h>
72 #endif
73 
74 struct elf_probe_entry {
75 	int (*func) __P((struct proc *, struct exec_package *, char *,
76 	    u_long *, u_int8_t *));
77 	int os_mask;
78 } elf_probes[] = {
79 #ifdef COMPAT_FREEBSD
80 	{ freebsd_elf_probe, OOS_FREEBSD },
81 #endif
82 #ifdef COMPAT_LINUX
83 	{ linux_elf_probe, OOS_LINUX },
84 #endif
85 #ifdef COMPAT_SVR4
86 	{ svr4_elf_probe,
87 	    1 << OOS_SVR4 | 1 << OOS_ESIX | 1 << OOS_SOLARIS | 1 << OOS_SCO |
88 	    1 << OOS_DELL | 1 << OOS_NCR },
89 #endif
90 	{ 0, OOS_OPENBSD }
91 };
92 
93 int elf_load_file __P((struct proc *, char *, struct exec_package *,
94     struct elf_args *, u_long *));
95 
96 int elf_check_header __P((Elf32_Ehdr *, int));
97 int olf_check_header __P((Elf32_Ehdr *, int, u_int8_t *));
98 int elf_read_from __P((struct proc *, struct vnode *, u_long, caddr_t, int));
99 void elf_load_psection __P((struct exec_vmcmd_set *, struct vnode *,
100     Elf32_Phdr *, u_long *, u_long *, int *));
101 
102 int exec_elf_fixup __P((struct proc *, struct exec_package *));
103 
104 #define ELF_ALIGN(a, b) ((a) & ~((b) - 1))
105 
106 /*
107  * This is the basic elf emul. elf_probe_funcs may change to other emuls.
108  */
109 
110 extern char sigcode[], esigcode[];
111 #ifdef SYSCALL_DEBUG
112 extern char *syscallnames[];
113 #endif
114 
115 struct emul emul_elf = {
116 	"native",
117 	NULL,
118 	sendsig,
119 	SYS_syscall,
120 	SYS_MAXSYSCALL,
121 	sysent,
122 #ifdef SYSCALL_DEBUG
123 	syscallnames,
124 #else
125 	NULL,
126 #endif
127 	sizeof (AuxInfo) * ELF_AUX_ENTRIES,
128 	elf_copyargs,
129 	setregs,
130 	exec_elf_fixup,
131 	sigcode,
132 	esigcode,
133 };
134 
135 
136 /*
137  * Copy arguments onto the stack in the normal way, but add some
138  * space for extra information in case of dynamic binding.
139  */
140 void *
141 elf_copyargs(pack, arginfo, stack, argp)
142 	struct exec_package *pack;
143 	struct ps_strings *arginfo;
144 	void *stack;
145 	void *argp;
146 {
147 	stack = copyargs(pack, arginfo, stack, argp);
148 	if (!stack)
149 		return (NULL);
150 
151 	/*
152 	 * Push space for extra arguments on the stack needed by
153 	 * dynamically linked binaries
154 	 */
155 	if (pack->ep_interp != NULL) {
156 		pack->ep_emul_argp = stack;
157 		stack += ELF_AUX_ENTRIES * sizeof (AuxInfo);
158 	}
159 	return (stack);
160 }
161 
162 /*
163  * elf_check_header():
164  *
165  * Check header for validity; return 0 for ok, ENOEXEC if error
166  */
167 int
168 elf_check_header(ehdr, type)
169 	Elf32_Ehdr *ehdr;
170 	int type;
171 {
172         /*
173 	 * We need to check magic, class size, endianess, and version before
174 	 * we look at the rest of the Elf32_Ehdr structure. These few elements
175 	 * are represented in a machine independant fashion.
176 	 */
177 	if (!IS_ELF(*ehdr) ||
178 	    ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
179 	    ehdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
180 	    ehdr->e_ident[EI_VERSION] != ELF_TARG_VER)
181                 return (ENOEXEC);
182 
183         /* Now check the machine dependant header */
184 	if (ehdr->e_machine != ELF_TARG_MACH ||
185 	    ehdr->e_version != ELF_TARG_VER)
186                 return (ENOEXEC);
187 
188         /* Check the type */
189 	if (ehdr->e_type != type)
190 		return (ENOEXEC);
191 
192 	return (0);
193 }
194 
195 /*
196  * olf_check_header():
197  *
198  * Check header for validity; return 0 for ok, ENOEXEC if error.
199  * Remeber OS tag for callers sake.
200  */
201 int
202 olf_check_header(ehdr, type, os)
203 	Elf32_Ehdr *ehdr;
204 	int type;
205 	u_int8_t *os;
206 {
207 	int i;
208 
209         /*
210 	 * We need to check magic, class size, endianess, version, and OS
211 	 * before we look at the rest of the Elf32_Ehdr structure. These few
212 	 * elements are represented in a machine independant fashion.
213 	 */
214 	if (!IS_OLF(*ehdr) ||
215 	    ehdr->e_ident[OI_CLASS] != ELF_TARG_CLASS ||
216 	    ehdr->e_ident[OI_DATA] != ELF_TARG_DATA ||
217 	    ehdr->e_ident[OI_VERSION] != ELF_TARG_VER)
218                 return (ENOEXEC);
219 
220 	for (i = 0; i < sizeof elf_probes / sizeof elf_probes[0]; i++)
221 		if ((1 << ehdr->e_ident[OI_OS]) & elf_probes[i].os_mask)
222                 	goto os_ok;
223 	return (ENOEXEC);
224 
225 os_ok:
226         /* Now check the machine dependant header */
227 	if (ehdr->e_machine != ELF_TARG_MACH ||
228 	    ehdr->e_version != ELF_TARG_VER)
229                 return (ENOEXEC);
230 
231         /* Check the type */
232 	if (ehdr->e_type != type)
233 		return (ENOEXEC);
234 
235 	*os = ehdr->e_ident[OI_OS];
236 	return (0);
237 }
238 
239 /*
240  * elf_load_psection():
241  *
242  * Load a psection at the appropriate address
243  */
244 void
245 elf_load_psection(vcset, vp, ph, addr, size, prot)
246 	struct exec_vmcmd_set *vcset;
247 	struct vnode *vp;
248 	Elf32_Phdr *ph;
249 	u_long *addr;
250 	u_long *size;
251 	int *prot;
252 {
253 	u_long uaddr, msize, psize, rm, rf;
254 	long diff, offset;
255 
256 	/*
257 	 * If the user specified an address, then we load there.
258 	 */
259 	if (*addr != ELF32_NO_ADDR) {
260 		if (ph->p_align > 1) {
261 			*addr = ELF_ALIGN(*addr + ph->p_align, ph->p_align);
262 			uaddr = ELF_ALIGN(ph->p_vaddr, ph->p_align);
263 		} else
264 			uaddr = ph->p_vaddr;
265 		diff = ph->p_vaddr - uaddr;
266 	} else {
267 		*addr = uaddr = ph->p_vaddr;
268 		if (ph->p_align > 1)
269 			*addr = ELF_ALIGN(uaddr, ph->p_align);
270 		diff = uaddr - *addr;
271 	}
272 
273 	*prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0;
274 	*prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0;
275 	*prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0;
276 
277 	offset = ph->p_offset - diff;
278 	*size = ph->p_filesz + diff;
279 	msize = ph->p_memsz + diff;
280 	psize = round_page(*size);
281 
282 	/*
283 	 * Because the pagedvn pager can't handle zero fill of the last
284 	 * data page if it's not page aligned we map the las page readvn.
285 	 */
286 	if(ph->p_flags & PF_W) {
287 		psize = trunc_page(*size);
288 		NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp,
289 		    offset, *prot);
290 		if(psize != *size) {
291 			NEW_VMCMD(vcset, vmcmd_map_readvn, *size - psize,
292 			    *addr + psize, vp, offset + psize, *prot);
293 		}
294 	}
295 	else {
296 		 NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp, offset,
297 		     *prot);
298 	}
299 
300 	/*
301 	 * Check if we need to extend the size of the segment
302 	 */
303 	rm = round_page(*addr + msize);
304 	rf = round_page(*addr + *size);
305 
306 	if (rm != rf) {
307 		NEW_VMCMD(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0,
308 		    *prot);
309 		*size = msize;
310 	}
311 }
312 
313 /*
314  * elf_read_from():
315  *
316  *	Read from vnode into buffer at offset.
317  */
318 int
319 elf_read_from(p, vp, off, buf, size)
320 	struct proc *p;
321 	struct vnode *vp;
322 	u_long off;
323 	caddr_t buf;
324 	int size;
325 {
326 	int error;
327 	size_t resid;
328 
329 	if ((error = vn_rdwr(UIO_READ, vp, buf, size, off, UIO_SYSSPACE,
330 	    IO_NODELOCKED, p->p_ucred, &resid, p)) != 0)
331 		return error;
332 	/*
333 	 * See if we got all of it
334 	 */
335 	if (resid != 0)
336 		return (ENOEXEC);
337 	return (0);
338 }
339 
340 /*
341  * elf_load_file():
342  *
343  * Load a file (interpreter/library) pointed to by path [stolen from
344  * coff_load_shlib()]. Made slightly generic so it might be used externally.
345  */
346 int
347 elf_load_file(p, path, epp, ap, last)
348 	struct proc *p;
349 	char *path;
350 	struct exec_package *epp;
351 	struct elf_args	*ap;
352 	u_long *last;
353 {
354 	int error, i;
355 	struct nameidata nd;
356 	Elf32_Ehdr eh;
357 	Elf32_Phdr *ph = NULL;
358 	u_long phsize;
359 	char *bp = NULL;
360 	u_long addr = *last;
361 	struct vnode *vp;
362 	u_int8_t os;			/* Just a dummy in this routine */
363 
364 	bp = path;
365 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p);
366 	if ((error = namei(&nd)) != 0) {
367 		return (error);
368 	}
369 	vp = nd.ni_vp;
370 	if (vp->v_type != VREG) {
371 		error = EACCES;
372 		goto bad;
373 	}
374 	if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0)
375 		goto bad;
376 	if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
377 		error = EACCES;
378 		goto bad;
379 	}
380 	if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0)
381 		goto bad1;
382 	if ((error = elf_read_from(p, nd.ni_vp, 0,
383 				    (caddr_t)&eh, sizeof(eh))) != 0)
384 		goto bad1;
385 
386 	if (elf_check_header(&eh, ET_DYN) &&
387 	    olf_check_header(&eh, ET_DYN, &os)) {
388 		error = ENOEXEC;
389 		goto bad1;
390 	}
391 
392 	phsize = eh.e_phnum * sizeof(Elf32_Phdr);
393 	ph = (Elf32_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
394 
395 	if ((error = elf_read_from(p, nd.ni_vp, eh.e_phoff, (caddr_t)ph,
396 	    phsize)) != 0)
397 		goto bad1;
398 
399 	/*
400 	 * Load all the necessary sections
401 	 */
402 	for (i = 0; i < eh.e_phnum; i++) {
403 		u_long size = 0;
404 		int prot = 0;
405 #ifdef mips
406 		if (*last == ELF32_NO_ADDR)
407 			addr = ELF32_NO_ADDR;	/* GRRRRR!!!!! */
408 #endif
409 
410 		switch (ph[i].p_type) {
411 		case PT_LOAD:
412 			elf_load_psection(&epp->ep_vmcmds, nd.ni_vp, &ph[i],
413 						&addr, &size, &prot);
414 			/* If entry is within this section it must be text */
415 			if (eh.e_entry >= ph[i].p_vaddr &&
416 			    eh.e_entry < (ph[i].p_vaddr + size)) {
417  				epp->ep_entry = addr + eh.e_entry -
418                                         ELF_ALIGN(ph[i].p_vaddr,ph[i].p_align);
419 				ap->arg_interp = addr;
420 			}
421 			addr += size;
422 			break;
423 
424 		case PT_DYNAMIC:
425 		case PT_PHDR:
426 		case PT_NOTE:
427 			break;
428 
429 		default:
430 			break;
431 		}
432 	}
433 
434 bad1:
435 	VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p);
436 bad:
437 	if (ph != NULL)
438 		free((char *)ph, M_TEMP);
439 
440 	*last = addr;
441 	vput(nd.ni_vp);
442 	return (error);
443 }
444 
445 /*
446  * exec_elf_makecmds(): Prepare an Elf binary's exec package
447  *
448  * First, set of the various offsets/lengths in the exec package.
449  *
450  * Then, mark the text image busy (so it can be demand paged) or error out if
451  * this is not possible.  Finally, set up vmcmds for the text, data, bss, and
452  * stack segments.
453  */
454 int
455 exec_elf_makecmds(p, epp)
456 	struct proc *p;
457 	struct exec_package *epp;
458 {
459 	Elf32_Ehdr *eh = epp->ep_hdr;
460 	Elf32_Phdr *ph, *pp;
461 	Elf32_Addr phdr = 0;
462 	int error, i, nload;
463 	char interp[MAXPATHLEN];
464 	u_long pos = 0, phsize;
465 	u_int8_t os = OOS_NULL;
466 
467 	if (epp->ep_hdrvalid < sizeof(Elf32_Ehdr))
468 		return (ENOEXEC);
469 
470 	if (elf_check_header(eh, ET_EXEC) &&
471 	    olf_check_header(eh, ET_EXEC, &os))
472 		return (ENOEXEC);
473 
474 	/*
475 	 * check if vnode is in open for writing, because we want to demand-
476 	 * page out of it.  if it is, don't do it, for various reasons.
477 	 */
478 	if (epp->ep_vp->v_writecount != 0) {
479 #ifdef DIAGNOSTIC
480 		if (epp->ep_vp->v_flag & VTEXT)
481 			panic("exec: a VTEXT vnode has writecount != 0");
482 #endif
483 		return (ETXTBSY);
484 	}
485 	/*
486 	 * Allocate space to hold all the program headers, and read them
487 	 * from the file
488 	 */
489 	phsize = eh->e_phnum * sizeof(Elf32_Phdr);
490 	ph = (Elf32_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
491 
492 	if ((error = elf_read_from(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph,
493 	    phsize)) != 0)
494 		goto bad;
495 
496 	epp->ep_tsize = ELF32_NO_ADDR;
497 	epp->ep_dsize = ELF32_NO_ADDR;
498 
499 	interp[0] = '\0';
500 
501 	for (i = 0; i < eh->e_phnum; i++) {
502 		pp = &ph[i];
503 		if (pp->p_type == PT_INTERP) {
504 			if (pp->p_filesz >= sizeof(interp))
505 				goto bad;
506 			if ((error = elf_read_from(p, epp->ep_vp, pp->p_offset,
507 			    (caddr_t)interp, pp->p_filesz)) != 0)
508 				goto bad;
509 			break;
510 		}
511 	}
512 
513 	/*
514 	 * OK, we want a slightly different twist of the
515 	 * standard emulation package for "real" elf.
516 	 */
517 	epp->ep_emul = &emul_elf;
518 	pos = ELF32_NO_ADDR;
519 
520 	/*
521 	 * On the same architecture, we may be emulating different systems.
522 	 * See which one will accept this executable. This currently only
523 	 * applies to Linux and SVR4 on the i386.
524 	 *
525 	 * Probe functions would normally see if the interpreter (if any)
526 	 * exists. Emulation packages may possibly replace the interpreter in
527 	 * interp[] with a changed path (/emul/xxx/<path>), and also
528 	 * set the ep_emul field in the exec package structure.
529 	 */
530 	error = ENOEXEC;
531 	p->p_os = OOS_OPENBSD;
532 	for (i = 0; i < sizeof elf_probes / sizeof elf_probes[0] && error; i++)
533 		if (os == OOS_NULL || ((1 << os) & elf_probes[i].os_mask))
534 			error = elf_probes[i].func ?
535 			    (*elf_probes[i].func)(p, epp, interp, &pos, &os) :
536 			    0;
537 	if (!error)
538 		p->p_os = os;
539 #ifndef NATIVE_ELF
540 	else
541 		goto bad;
542 #endif /* NATIVE_ELF */
543 
544 	/*
545 	 * Load all the necessary sections
546 	 */
547 	for (i = nload = 0; i < eh->e_phnum; i++) {
548 		u_long addr = ELF32_NO_ADDR, size = 0;
549 		int prot = 0;
550 
551 		pp = &ph[i];
552 
553 		switch (ph[i].p_type) {
554 		case PT_LOAD:
555 			/*
556 			 * XXX
557 			 * Can handle only 2 sections: text and data
558 			 */
559 			if (nload++ == 2)
560 				goto bad;
561 			elf_load_psection(&epp->ep_vmcmds, epp->ep_vp, &ph[i],
562 			    &addr, &size, &prot);
563 			/*
564 			 * Decide whether it's text or data by looking
565 			 * at the entry point.
566 			 */
567 			if (eh->e_entry >= addr && eh->e_entry < (addr + size))
568 			    {
569 				epp->ep_taddr = addr;
570 				epp->ep_tsize = size;
571 			} else {
572 				epp->ep_daddr = addr;
573 				epp->ep_dsize = size;
574 			}
575 			break;
576 
577 		case PT_SHLIB:
578 			error = ENOEXEC;
579 			goto bad;
580 
581 		case PT_INTERP:
582 			/* Already did this one */
583 		case PT_DYNAMIC:
584 		case PT_NOTE:
585 			break;
586 
587 		case PT_PHDR:
588 			/* Note address of program headers (in text segment) */
589 			phdr = pp->p_vaddr;
590 			break;
591 
592 		default:
593 			/*
594 			 * Not fatal, we don't need to understand everything
595 			 * :-)
596 			 */
597 			break;
598 		}
599 	}
600 
601 #if !defined(mips)
602 	/*
603 	 * If no position to load the interpreter was set by a probe
604 	 * function, pick the same address that a non-fixed mmap(0, ..)
605 	 * would (i.e. something safely out of the way).
606 	 */
607 	if (pos == ELF32_NO_ADDR)
608 		pos = round_page(epp->ep_daddr + MAXDSIZ);
609 #endif
610 
611 	/*
612 	 * Check if we found a dynamically linked binary and arrange to load
613 	 * it's interpreter when the exec file is released.
614 	 */
615 	if (interp[0]) {
616 		char *ip;
617 		struct elf_args *ap;
618 
619 		ip = (char *)malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
620 		ap = (struct elf_args *)
621 		    malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK);
622 
623 		bcopy(interp, ip, MAXPATHLEN);
624 		epp->ep_interp = ip;
625 		epp->ep_interp_pos = pos;
626 
627 		ap->arg_phaddr = phdr;
628 		ap->arg_phentsize = eh->e_phentsize;
629 		ap->arg_phnum = eh->e_phnum;
630 		ap->arg_entry = eh->e_entry;
631 		ap->arg_os = os;
632 
633 		epp->ep_emul_arg = ap;
634 		epp->ep_entry = eh->e_entry; /* keep check_exec() happy */
635 	}
636 	else {
637 		epp->ep_interp = NULL;
638 		epp->ep_entry = eh->e_entry;
639 	}
640 
641 #if defined(COMPAT_SVR4) && defined(i386)
642 #ifndef ELF_MAP_PAGE_ZERO
643 	/* Dell SVR4 maps page zero, yeuch! */
644 	if (p->p_os == OOS_DELL)
645 #endif
646 		NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, NBPG, 0,
647 		    epp->ep_vp, 0, VM_PROT_READ);
648 #endif
649 
650 	free((char *)ph, M_TEMP);
651 	epp->ep_vp->v_flag |= VTEXT;
652 	return (exec_setup_stack(p, epp));
653 
654 bad:
655 	free((char *)ph, M_TEMP);
656 	kill_vmcmds(&epp->ep_vmcmds);
657 	return (ENOEXEC);
658 }
659 
660 /*
661  * Phase II of load. It is now safe to load the interpreter. Info collected
662  * when loading the program is available for setup of the interpreter.
663  */
664 int
665 exec_elf_fixup(p, epp)
666 	struct proc *p;
667 	struct exec_package *epp;
668 {
669 	char	*interp;
670 	int	error, i;
671 	struct	elf_args *ap;
672 	AuxInfo ai[ELF_AUX_ENTRIES], *a;
673 	u_long	pos = epp->ep_interp_pos;
674 
675 	if(epp->ep_interp == 0) {
676 		return (0);
677 	}
678 
679 	interp = (char *)epp->ep_interp;
680 	ap = (struct elf_args *)epp->ep_emul_arg;
681 
682 	if ((error = elf_load_file(p, interp, epp, ap, &pos)) != 0) {
683 		free((char *)ap, M_TEMP);
684 		free((char *)interp, M_TEMP);
685 		kill_vmcmds(&epp->ep_vmcmds);
686 		return (error);
687 	}
688 	/*
689 	 * We have to do this ourselfs...
690 	 */
691 	for (i = 0; i < epp->ep_vmcmds.evs_used && !error; i++) {
692 		struct exec_vmcmd *vcp;
693 
694 		vcp = &epp->ep_vmcmds.evs_cmds[i];
695 		error = (*vcp->ev_proc)(p, vcp);
696 	}
697 	kill_vmcmds(&epp->ep_vmcmds);
698 
699 	/*
700 	 * Push extra arguments on the stack needed by dynamically
701 	 * linked binaries
702 	 */
703 	if(error == 0) {
704 		a = ai;
705 
706 		a->au_id = AUX_phdr;
707 		a->au_v = ap->arg_phaddr;
708 		a++;
709 
710 		a->au_id = AUX_phent;
711 		a->au_v = ap->arg_phentsize;
712 		a++;
713 
714 		a->au_id = AUX_phnum;
715 		a->au_v = ap->arg_phnum;
716 		a++;
717 
718 		a->au_id = AUX_pagesz;
719 		a->au_v = NBPG;
720 		a++;
721 
722 		a->au_id = AUX_base;
723 		a->au_v = ap->arg_interp;
724 		a++;
725 
726 		a->au_id = AUX_flags;
727 		a->au_v = 0;
728 		a++;
729 
730 		a->au_id = AUX_entry;
731 		a->au_v = ap->arg_entry;
732 		a++;
733 
734 		a->au_id = AUX_null;
735 		a->au_v = 0;
736 		a++;
737 
738 		error = copyout(ai, epp->ep_emul_argp, sizeof ai);
739 	}
740 	free((char *)ap, M_TEMP);
741 	free((char *)interp, M_TEMP);
742 	return (error);
743 }
744 
745 char *
746 elf_check_brand(eh)
747 	Elf32_Ehdr *eh;
748 {
749 	if (eh->e_ident[EI_BRAND] == '\0')
750 		return (NULL);
751 	return (&eh->e_ident[EI_BRAND]);
752 }
753 
754 #endif /* _KERN_DO_ELF */
755