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