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