xref: /netbsd-src/sys/kern/exec_elf32.c (revision ce2c90c7c172d95d2402a5b3d96d8f8e6d138a21)
1 /*	$NetBSD: exec_elf32.c,v 1.116 2006/10/12 01:32:14 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Christos Zoulas.
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. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the NetBSD
21  *	Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Copyright (c) 1996 Christopher G. Demetriou
41  * All rights reserved.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  * 1. Redistributions of source code must retain the above copyright
47  *    notice, this list of conditions and the following disclaimer.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. The name of the author may not be used to endorse or promote products
52  *    derived from this software without specific prior written permission
53  *
54  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */
65 
66 #include <sys/cdefs.h>
67 __KERNEL_RCSID(1, "$NetBSD: exec_elf32.c,v 1.116 2006/10/12 01:32:14 christos Exp $");
68 
69 /* If not included by exec_elf64.c, ELFSIZE won't be defined. */
70 #ifndef ELFSIZE
71 #define	ELFSIZE		32
72 #endif
73 
74 #ifdef _KERNEL_OPT
75 #include "opt_pax.h"
76 #endif /* _KERNEL_OPT */
77 
78 #include <sys/param.h>
79 #include <sys/proc.h>
80 #include <sys/malloc.h>
81 #include <sys/namei.h>
82 #include <sys/vnode.h>
83 #include <sys/exec.h>
84 #include <sys/exec_elf.h>
85 #include <sys/syscall.h>
86 #include <sys/signalvar.h>
87 #include <sys/mount.h>
88 #include <sys/stat.h>
89 #include <sys/kauth.h>
90 
91 #include <machine/cpu.h>
92 #include <machine/reg.h>
93 
94 #ifdef PAX_MPROTECT
95 #include <sys/pax.h>
96 #endif /* PAX_MPROTECT */
97 
98 extern const struct emul emul_netbsd;
99 
100 #define elf_check_header	ELFNAME(check_header)
101 #define elf_copyargs		ELFNAME(copyargs)
102 #define elf_load_file		ELFNAME(load_file)
103 #define elf_load_psection	ELFNAME(load_psection)
104 #define exec_elf_makecmds	ELFNAME2(exec,makecmds)
105 #define netbsd_elf_signature	ELFNAME2(netbsd,signature)
106 #define netbsd_elf_probe	ELFNAME2(netbsd,probe)
107 
108 int	elf_load_file(struct lwp *, struct exec_package *, char *,
109 	    struct exec_vmcmd_set *, u_long *, struct elf_args *, Elf_Addr *);
110 void	elf_load_psection(struct exec_vmcmd_set *, struct vnode *,
111 	    const Elf_Phdr *, Elf_Addr *, u_long *, int *, int);
112 
113 int	netbsd_elf_signature(struct lwp *, struct exec_package *, Elf_Ehdr *);
114 int	netbsd_elf_probe(struct lwp *, struct exec_package *, void *, char *,
115 	    vaddr_t *);
116 
117 /* round up and down to page boundaries. */
118 #define	ELF_ROUND(a, b)		(((a) + (b) - 1) & ~((b) - 1))
119 #define	ELF_TRUNC(a, b)		((a) & ~((b) - 1))
120 
121 #define MAXPHNUM	50
122 
123 /*
124  * Copy arguments onto the stack in the normal way, but add some
125  * extra information in case of dynamic binding.
126  */
127 int
128 elf_copyargs(struct lwp *l, struct exec_package *pack,
129     struct ps_strings *arginfo, char **stackp, void *argp)
130 {
131 	size_t len;
132 	AuxInfo ai[ELF_AUX_ENTRIES], *a;
133 	struct elf_args *ap;
134 	int error;
135 
136 	if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
137 		return error;
138 
139 	a = ai;
140 
141 	/*
142 	 * Push extra arguments on the stack needed by dynamically
143 	 * linked binaries
144 	 */
145 	if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
146 		struct vattr *vap = pack->ep_vap;
147 
148 		a->a_type = AT_PHDR;
149 		a->a_v = ap->arg_phaddr;
150 		a++;
151 
152 		a->a_type = AT_PHENT;
153 		a->a_v = ap->arg_phentsize;
154 		a++;
155 
156 		a->a_type = AT_PHNUM;
157 		a->a_v = ap->arg_phnum;
158 		a++;
159 
160 		a->a_type = AT_PAGESZ;
161 		a->a_v = PAGE_SIZE;
162 		a++;
163 
164 		a->a_type = AT_BASE;
165 		a->a_v = ap->arg_interp;
166 		a++;
167 
168 		a->a_type = AT_FLAGS;
169 		a->a_v = 0;
170 		a++;
171 
172 		a->a_type = AT_ENTRY;
173 		a->a_v = ap->arg_entry;
174 		a++;
175 
176 		a->a_type = AT_EUID;
177 		if (vap->va_mode & S_ISUID)
178 			a->a_v = vap->va_uid;
179 		else
180 			a->a_v = kauth_cred_geteuid(l->l_cred);
181 		a++;
182 
183 		a->a_type = AT_RUID;
184 		a->a_v = kauth_cred_getuid(l->l_cred);
185 		a++;
186 
187 		a->a_type = AT_EGID;
188 		if (vap->va_mode & S_ISGID)
189 			a->a_v = vap->va_gid;
190 		else
191 			a->a_v = kauth_cred_getegid(l->l_cred);
192 		a++;
193 
194 		a->a_type = AT_RGID;
195 		a->a_v = kauth_cred_getgid(l->l_cred);
196 		a++;
197 
198 		free(ap, M_TEMP);
199 		pack->ep_emul_arg = NULL;
200 	}
201 
202 	a->a_type = AT_NULL;
203 	a->a_v = 0;
204 	a++;
205 
206 	len = (a - ai) * sizeof(AuxInfo);
207 	if ((error = copyout(ai, *stackp, len)) != 0)
208 		return error;
209 	*stackp += len;
210 
211 	return 0;
212 }
213 
214 /*
215  * elf_check_header():
216  *
217  * Check header for validity; return 0 of ok ENOEXEC if error
218  */
219 int
220 elf_check_header(Elf_Ehdr *eh, int type)
221 {
222 
223 	if (memcmp(eh->e_ident, ELFMAG, SELFMAG) != 0 ||
224 	    eh->e_ident[EI_CLASS] != ELFCLASS)
225 		return ENOEXEC;
226 
227 	switch (eh->e_machine) {
228 
229 	ELFDEFNNAME(MACHDEP_ID_CASES)
230 
231 	default:
232 		return ENOEXEC;
233 	}
234 
235 	if (ELF_EHDR_FLAGS_OK(eh) == 0)
236 		return ENOEXEC;
237 
238 	if (eh->e_type != type)
239 		return ENOEXEC;
240 
241 	if (eh->e_shnum > 32768 || eh->e_phnum > 128)
242 		return ENOEXEC;
243 
244 	return 0;
245 }
246 
247 /*
248  * elf_load_psection():
249  *
250  * Load a psection at the appropriate address
251  */
252 void
253 elf_load_psection(struct exec_vmcmd_set *vcset, struct vnode *vp,
254     const Elf_Phdr *ph, Elf_Addr *addr, u_long *size, int *prot, int flags)
255 {
256 	u_long msize, psize, rm, rf;
257 	long diff, offset;
258 
259 	/*
260 	 * If the user specified an address, then we load there.
261 	 */
262 	if (*addr == ELFDEFNNAME(NO_ADDR))
263 		*addr = ph->p_vaddr;
264 
265 	if (ph->p_align > 1) {
266 		/*
267 		 * Make sure we are virtually aligned as we are supposed to be.
268 		 */
269 		diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align);
270 		KASSERT(*addr - diff == ELF_TRUNC(*addr, ph->p_align));
271 		/*
272 		 * But make sure to not map any pages before the start of the
273 		 * psection by limiting the difference to within a page.
274 		 */
275 		diff &= PAGE_MASK;
276 	} else
277 		diff = 0;
278 
279 	*prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0;
280 	*prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0;
281 	*prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0;
282 
283 	/*
284 	 * Adjust everything so it all starts on a page boundary.
285 	 */
286 	*addr -= diff;
287 	offset = ph->p_offset - diff;
288 	*size = ph->p_filesz + diff;
289 	msize = ph->p_memsz + diff;
290 
291 	if (ph->p_align >= PAGE_SIZE) {
292 		if ((ph->p_flags & PF_W) != 0) {
293 			/*
294 			 * Because the pagedvn pager can't handle zero fill
295 			 * of the last data page if it's not page aligned we
296 			 * map the last page readvn.
297 			 */
298 			psize = trunc_page(*size);
299 		} else {
300 			psize = round_page(*size);
301 		}
302 	} else {
303 		psize = *size;
304 	}
305 
306 	if (psize > 0) {
307 		NEW_VMCMD2(vcset, ph->p_align < PAGE_SIZE ?
308 		    vmcmd_map_readvn : vmcmd_map_pagedvn, psize, *addr, vp,
309 		    offset, *prot, flags);
310 		flags &= VMCMD_RELATIVE;
311 	}
312 	if (psize < *size) {
313 		NEW_VMCMD2(vcset, vmcmd_map_readvn, *size - psize,
314 		    *addr + psize, vp, offset + psize, *prot, flags);
315 	}
316 
317 	/*
318 	 * Check if we need to extend the size of the segment (does
319 	 * bss extend page the next page boundary)?
320 	 */
321 	rm = round_page(*addr + msize);
322 	rf = round_page(*addr + *size);
323 
324 	if (rm != rf) {
325 		NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP,
326 		    0, *prot, flags & VMCMD_RELATIVE);
327 		*size = msize;
328 	}
329 }
330 
331 /*
332  * elf_load_file():
333  *
334  * Load a file (interpreter/library) pointed to by path
335  * [stolen from coff_load_shlib()]. Made slightly generic
336  * so it might be used externally.
337  */
338 int
339 elf_load_file(struct lwp *l, struct exec_package *epp, char *path,
340     struct exec_vmcmd_set *vcset, u_long *entryoff,
341     struct elf_args *ap __unused, Elf_Addr *last)
342 {
343 	int error, i;
344 	struct nameidata nd;
345 	struct vnode *vp;
346 	struct vattr attr;
347 	Elf_Ehdr eh;
348 	Elf_Phdr *ph = NULL;
349 	const Elf_Phdr *ph0;
350 	const Elf_Phdr *base_ph;
351 	const Elf_Phdr *last_ph;
352 	u_long phsize;
353 	Elf_Addr addr = *last;
354 	struct proc *p;
355 
356 	p = l->l_proc;
357 
358 	/*
359 	 * 1. open file
360 	 * 2. read filehdr
361 	 * 3. map text, data, and bss out of it using VM_*
362 	 */
363 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, l);
364 	if ((error = namei(&nd)) != 0)
365 		return error;
366 	vp = nd.ni_vp;
367 
368 	/*
369 	 * Similarly, if it's not marked as executable, or it's not a regular
370 	 * file, we don't allow it to be used.
371 	 */
372 	if (vp->v_type != VREG) {
373 		error = EACCES;
374 		goto badunlock;
375 	}
376 	if ((error = VOP_ACCESS(vp, VEXEC, l->l_cred, l)) != 0)
377 		goto badunlock;
378 
379 	/* get attributes */
380 	if ((error = VOP_GETATTR(vp, &attr, l->l_cred, l)) != 0)
381 		goto badunlock;
382 
383 	/*
384 	 * Check mount point.  Though we're not trying to exec this binary,
385 	 * we will be executing code from it, so if the mount point
386 	 * disallows execution or set-id-ness, we punt or kill the set-id.
387 	 */
388 	if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
389 		error = EACCES;
390 		goto badunlock;
391 	}
392 	if (vp->v_mount->mnt_flag & MNT_NOSUID)
393 		epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
394 
395 #ifdef notyet /* XXX cgd 960926 */
396 	XXX cgd 960926: (maybe) VOP_OPEN it (and VOP_CLOSE in copyargs?)
397 #endif
398 
399 	error = vn_marktext(vp);
400 	if (error)
401 		goto badunlock;
402 
403 	VOP_UNLOCK(vp, 0);
404 
405 	if ((error = exec_read_from(l, vp, 0, &eh, sizeof(eh))) != 0)
406 		goto bad;
407 
408 	if ((error = elf_check_header(&eh, ET_DYN)) != 0)
409 		goto bad;
410 
411 	if (eh.e_phnum > MAXPHNUM)
412 		goto bad;
413 
414 	phsize = eh.e_phnum * sizeof(Elf_Phdr);
415 	ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
416 
417 	if ((error = exec_read_from(l, vp, eh.e_phoff, ph, phsize)) != 0)
418 		goto bad;
419 
420 #ifdef ELF_INTERP_NON_RELOCATABLE
421 	/*
422 	 * Evil hack:  Only MIPS should be non-relocatable, and the
423 	 * psections should have a high address (typically 0x5ffe0000).
424 	 * If it's now relocatable, it should be linked at 0 and the
425 	 * psections should have zeros in the upper part of the address.
426 	 * Otherwise, force the load at the linked address.
427 	 */
428 	if (*last == ELF_LINK_ADDR && (ph->p_vaddr & 0xffff0000) == 0)
429 		*last = ELFDEFNNAME(NO_ADDR);
430 #endif
431 
432 	/*
433 	 * If no position to load the interpreter was set by a probe
434 	 * function, pick the same address that a non-fixed mmap(0, ..)
435 	 * would (i.e. something safely out of the way).
436 	 */
437 	if (*last == ELFDEFNNAME(NO_ADDR)) {
438 		u_long limit = 0;
439 		/*
440 		 * Find the start and ending addresses of the psections to
441 		 * be loaded.  This will give us the size.
442 		 */
443 		for (i = 0, ph0 = ph, base_ph = NULL; i < eh.e_phnum;
444 		     i++, ph0++) {
445 			if (ph0->p_type == PT_LOAD) {
446 				u_long psize = ph0->p_vaddr + ph0->p_memsz;
447 				if (base_ph == NULL)
448 					base_ph = ph0;
449 				if (psize > limit)
450 					limit = psize;
451 			}
452 		}
453 
454 		if (base_ph == NULL) {
455 			error = ENOEXEC;
456 			goto bad;
457 		}
458 
459 		/*
460 		 * Now compute the size and load address.
461 		 */
462 		addr = (*epp->ep_esch->es_emul->e_vm_default_addr)(p,
463 		    epp->ep_daddr,
464 		    round_page(limit) - trunc_page(base_ph->p_vaddr));
465 	} else
466 		addr = *last; /* may be ELF_LINK_ADDR */
467 
468 	/*
469 	 * Load all the necessary sections
470 	 */
471 	for (i = 0, ph0 = ph, base_ph = NULL, last_ph = NULL;
472 	     i < eh.e_phnum; i++, ph0++) {
473 		switch (ph0->p_type) {
474 		case PT_LOAD: {
475 			u_long size;
476 			int prot = 0;
477 			int flags;
478 
479 			if (base_ph == NULL) {
480 				/*
481 				 * First encountered psection is always the
482 				 * base psection.  Make sure it's aligned
483 				 * properly (align down for topdown and align
484 				 * upwards for not topdown).
485 				 */
486 				base_ph = ph0;
487 				flags = VMCMD_BASE;
488 				if (addr == ELF_LINK_ADDR)
489 					addr = ph0->p_vaddr;
490 				if (p->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN)
491 					addr = ELF_TRUNC(addr, ph0->p_align);
492 				else
493 					addr = ELF_ROUND(addr, ph0->p_align);
494 			} else {
495 				u_long limit = round_page(last_ph->p_vaddr
496 				    + last_ph->p_memsz);
497 				u_long base = trunc_page(ph0->p_vaddr);
498 
499 				/*
500 				 * If there is a gap in between the psections,
501 				 * map it as inaccessible so nothing else
502 				 * mmap'ed will be placed there.
503 				 */
504 				if (limit != base) {
505 					NEW_VMCMD2(vcset, vmcmd_map_zero,
506 					    base - limit,
507 					    limit - base_ph->p_vaddr, NULLVP,
508 					    0, VM_PROT_NONE, VMCMD_RELATIVE);
509 				}
510 
511 				addr = ph0->p_vaddr - base_ph->p_vaddr;
512 				flags = VMCMD_RELATIVE;
513 			}
514 			last_ph = ph0;
515 			elf_load_psection(vcset, vp, &ph[i], &addr,
516 			    &size, &prot, flags);
517 			/*
518 			 * If entry is within this psection then this
519 			 * must contain the .text section.  *entryoff is
520 			 * relative to the base psection.
521 			 */
522 			if (eh.e_entry >= ph0->p_vaddr &&
523 			    eh.e_entry < (ph0->p_vaddr + size)) {
524 				*entryoff = eh.e_entry - base_ph->p_vaddr;
525 			}
526 			addr += size;
527 			break;
528 		}
529 
530 		case PT_DYNAMIC:
531 		case PT_PHDR:
532 			break;
533 
534 		case PT_NOTE:
535 #ifdef PAX_MPROTECT
536 			pax_mprotect_adjust(l, ph[i].p_flags);
537 			break;
538 #endif /* PAX_MPROTECT */
539 
540 		default:
541 			break;
542 		}
543 	}
544 
545 	free(ph, M_TEMP);
546 	/*
547 	 * This value is ignored if TOPDOWN.
548 	 */
549 	*last = addr;
550 	vrele(vp);
551 	return 0;
552 
553 badunlock:
554 	VOP_UNLOCK(vp, 0);
555 
556 bad:
557 	if (ph != NULL)
558 		free(ph, M_TEMP);
559 #ifdef notyet /* XXX cgd 960926 */
560 	(maybe) VOP_CLOSE it
561 #endif
562 	vrele(vp);
563 	return error;
564 }
565 
566 /*
567  * exec_elf_makecmds(): Prepare an Elf binary's exec package
568  *
569  * First, set of the various offsets/lengths in the exec package.
570  *
571  * Then, mark the text image busy (so it can be demand paged) or error
572  * out if this is not possible.  Finally, set up vmcmds for the
573  * text, data, bss, and stack segments.
574  */
575 int
576 exec_elf_makecmds(struct lwp *l, struct exec_package *epp)
577 {
578 	Elf_Ehdr *eh = epp->ep_hdr;
579 	Elf_Phdr *ph, *pp;
580 	Elf_Addr phdr = 0, pos = 0;
581 	int error, i, nload;
582 	char *interp = NULL;
583 	u_long phsize;
584 	struct proc *p;
585 
586 	if (epp->ep_hdrvalid < sizeof(Elf_Ehdr))
587 		return ENOEXEC;
588 
589 	/*
590 	 * XXX allow for executing shared objects. It seems silly
591 	 * but other ELF-based systems allow it as well.
592 	 */
593 	if (elf_check_header(eh, ET_EXEC) != 0 &&
594 	    elf_check_header(eh, ET_DYN) != 0)
595 		return ENOEXEC;
596 
597 	if (eh->e_phnum > MAXPHNUM)
598 		return ENOEXEC;
599 
600 	error = vn_marktext(epp->ep_vp);
601 	if (error)
602 		return error;
603 
604 	/*
605 	 * Allocate space to hold all the program headers, and read them
606 	 * from the file
607 	 */
608 	p = l->l_proc;
609 	phsize = eh->e_phnum * sizeof(Elf_Phdr);
610 	ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
611 
612 	if ((error = exec_read_from(l, epp->ep_vp, eh->e_phoff, ph, phsize)) !=
613 	    0)
614 		goto bad;
615 
616 	epp->ep_taddr = epp->ep_tsize = ELFDEFNNAME(NO_ADDR);
617 	epp->ep_daddr = epp->ep_dsize = ELFDEFNNAME(NO_ADDR);
618 
619 	for (i = 0; i < eh->e_phnum; i++) {
620 		pp = &ph[i];
621 		if (pp->p_type == PT_INTERP) {
622 			if (pp->p_filesz >= MAXPATHLEN)
623 				goto bad;
624 			interp = PNBUF_GET();
625 			interp[0] = '\0';
626 			if ((error = exec_read_from(l, epp->ep_vp,
627 			    pp->p_offset, interp, pp->p_filesz)) != 0)
628 				goto bad;
629 			break;
630 		}
631 	}
632 
633 	/*
634 	 * On the same architecture, we may be emulating different systems.
635 	 * See which one will accept this executable.
636 	 *
637 	 * Probe functions would normally see if the interpreter (if any)
638 	 * exists. Emulation packages may possibly replace the interpreter in
639 	 * interp[] with a changed path (/emul/xxx/<path>).
640 	 */
641 	pos = ELFDEFNNAME(NO_ADDR);
642 	if (epp->ep_esch->u.elf_probe_func) {
643 		vaddr_t startp = (vaddr_t)pos;
644 
645 		error = (*epp->ep_esch->u.elf_probe_func)(l, epp, eh, interp,
646 							  &startp);
647 		if (error)
648 			goto bad;
649 		pos = (Elf_Addr)startp;
650 	}
651 
652 	/*
653 	 * Load all the necessary sections
654 	 */
655 	for (i = nload = 0; i < eh->e_phnum; i++) {
656 		Elf_Addr  addr = ELFDEFNNAME(NO_ADDR);
657 		u_long size = 0;
658 		int prot = 0;
659 
660 		pp = &ph[i];
661 
662 		switch (ph[i].p_type) {
663 		case PT_LOAD:
664 			/*
665 			 * XXX
666 			 * Can handle only 2 sections: text and data
667 			 */
668 			if (nload++ == 2)
669 				goto bad;
670 			elf_load_psection(&epp->ep_vmcmds, epp->ep_vp,
671 			    &ph[i], &addr, &size, &prot, VMCMD_FIXED);
672 
673 			/*
674 			 * Decide whether it's text or data by looking
675 			 * at the entry point.
676 			 */
677 			if (eh->e_entry >= addr &&
678 			    eh->e_entry < (addr + size)) {
679 				epp->ep_taddr = addr;
680 				epp->ep_tsize = size;
681 				if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) {
682 					epp->ep_daddr = addr;
683 					epp->ep_dsize = size;
684 				}
685 			} else {
686 				epp->ep_daddr = addr;
687 				epp->ep_dsize = size;
688 			}
689 			break;
690 
691 		case PT_SHLIB:
692 			/* SCO has these sections. */
693 		case PT_INTERP:
694 			/* Already did this one. */
695 		case PT_DYNAMIC:
696 		case PT_NOTE:
697 			break;
698 
699 		case PT_PHDR:
700 			/* Note address of program headers (in text segment) */
701 			phdr = pp->p_vaddr;
702 			break;
703 
704 		default:
705 			/*
706 			 * Not fatal; we don't need to understand everything.
707 			 */
708 			break;
709 		}
710 	}
711 
712 	/*
713 	 * Check if we found a dynamically linked binary and arrange to load
714 	 * its interpreter
715 	 */
716 	if (interp) {
717 		struct elf_args *ap;
718 		int j = epp->ep_vmcmds.evs_used;
719 		u_long interp_offset;
720 
721 		MALLOC(ap, struct elf_args *, sizeof(struct elf_args),
722 		    M_TEMP, M_WAITOK);
723 		if ((error = elf_load_file(l, epp, interp,
724 		    &epp->ep_vmcmds, &interp_offset, ap, &pos)) != 0) {
725 			FREE(ap, M_TEMP);
726 			goto bad;
727 		}
728 		ap->arg_interp = epp->ep_vmcmds.evs_cmds[j].ev_addr;
729 		epp->ep_entry = ap->arg_interp + interp_offset;
730 		ap->arg_phaddr = phdr;
731 
732 		ap->arg_phentsize = eh->e_phentsize;
733 		ap->arg_phnum = eh->e_phnum;
734 		ap->arg_entry = eh->e_entry;
735 
736 		epp->ep_emul_arg = ap;
737 
738 		PNBUF_PUT(interp);
739 	} else
740 		epp->ep_entry = eh->e_entry;
741 
742 #ifdef ELF_MAP_PAGE_ZERO
743 	/* Dell SVR4 maps page zero, yeuch! */
744 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0,
745 	    epp->ep_vp, 0, VM_PROT_READ);
746 #endif
747 	free(ph, M_TEMP);
748 	return (*epp->ep_esch->es_setup_stack)(l, epp);
749 
750 bad:
751 	if (interp)
752 		PNBUF_PUT(interp);
753 	free(ph, M_TEMP);
754 	kill_vmcmds(&epp->ep_vmcmds);
755 	return ENOEXEC;
756 }
757 
758 int
759 netbsd_elf_signature(struct lwp *l, struct exec_package *epp,
760     Elf_Ehdr *eh)
761 {
762 	size_t i;
763 	Elf_Phdr *ph;
764 	size_t phsize;
765 	int error;
766 
767 	if (eh->e_phnum > MAXPHNUM)
768 		return ENOEXEC;
769 
770 	phsize = eh->e_phnum * sizeof(Elf_Phdr);
771 	ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
772 	error = exec_read_from(l, epp->ep_vp, eh->e_phoff, ph, phsize);
773 	if (error)
774 		goto out;
775 
776 	for (i = 0; i < eh->e_phnum; i++) {
777 		Elf_Phdr *ephp = &ph[i];
778 		Elf_Nhdr *np;
779 
780 		if (ephp->p_type != PT_NOTE ||
781 		    ephp->p_filesz > 1024 ||
782 		    ephp->p_filesz < sizeof(Elf_Nhdr) + ELF_NOTE_NETBSD_NAMESZ)
783 			continue;
784 
785 		np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK);
786 		error = exec_read_from(l, epp->ep_vp, ephp->p_offset, np,
787 		    ephp->p_filesz);
788 		if (error)
789 			goto next;
790 
791 		if (np->n_type != ELF_NOTE_TYPE_NETBSD_TAG ||
792 		    np->n_namesz != ELF_NOTE_NETBSD_NAMESZ ||
793 		    np->n_descsz != ELF_NOTE_NETBSD_DESCSZ ||
794 		    memcmp((caddr_t)(np + 1), ELF_NOTE_NETBSD_NAME,
795 		    ELF_NOTE_NETBSD_NAMESZ))
796 			goto next;
797 
798 		error = 0;
799 		free(np, M_TEMP);
800 		goto out;
801 
802 	next:
803 		free(np, M_TEMP);
804 		continue;
805 	}
806 
807 	error = ENOEXEC;
808 out:
809 	free(ph, M_TEMP);
810 	return error;
811 }
812 
813 int
814 netbsd_elf_probe(struct lwp *l, struct exec_package *epp,
815     void *eh, char *itp __unused, vaddr_t *pos __unused)
816 {
817 	int error;
818 
819 	if ((error = netbsd_elf_signature(l, epp, eh)) != 0)
820 		return error;
821 #ifdef ELF_INTERP_NON_RELOCATABLE
822 	*pos = ELF_LINK_ADDR;
823 #endif
824 	return 0;
825 }
826