Annotation of sys/kern/exec_elf.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: exec_elf.c,v 1.61 2007/05/28 23:10:10 beck 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/pool.h>
40: #include <sys/mount.h>
41: #include <sys/namei.h>
42: #include <sys/vnode.h>
43: #include <sys/exec.h>
44: #include <sys/exec_elf.h>
45: #include <sys/exec_olf.h>
46: #include <sys/file.h>
47: #include <sys/syscall.h>
48: #include <sys/signalvar.h>
49: #include <sys/stat.h>
50:
51: #include <sys/mman.h>
52: #include <uvm/uvm_extern.h>
53:
54: #include <machine/cpu.h>
55: #include <machine/reg.h>
56: #include <machine/exec.h>
57:
58: #ifdef COMPAT_LINUX
59: #include <compat/linux/linux_exec.h>
60: #endif
61:
62: #ifdef COMPAT_SVR4
63: #include <compat/svr4/svr4_exec.h>
64: #endif
65:
66: #ifdef COMPAT_FREEBSD
67: #include <compat/freebsd/freebsd_exec.h>
68: #endif
69:
70: struct ELFNAME(probe_entry) {
71: int (*func)(struct proc *, struct exec_package *, char *,
72: u_long *, u_int8_t *);
73: int os_mask;
74: } ELFNAME(probes)[] = {
75: /* XXX - bogus, shouldn't be size independent.. */
76: #ifdef COMPAT_FREEBSD
77: { freebsd_elf_probe, 1 << OOS_FREEBSD },
78: #endif
79: #ifdef COMPAT_SVR4
80: { svr4_elf_probe,
81: 1 << OOS_SVR4 | 1 << OOS_ESIX | 1 << OOS_SOLARIS | 1 << OOS_SCO |
82: 1 << OOS_DELL | 1 << OOS_NCR },
83: #endif
84: #ifdef COMPAT_LINUX
85: { linux_elf_probe, 1 << OOS_LINUX },
86: #endif
87: { 0, 1 << OOS_OPENBSD }
88: };
89:
90: int ELFNAME(load_file)(struct proc *, char *, struct exec_package *,
91: struct elf_args *, Elf_Addr *);
92: int ELFNAME(check_header)(Elf_Ehdr *, int);
93: int ELFNAME(olf_check_header)(Elf_Ehdr *, int, u_int8_t *);
94: int ELFNAME(read_from)(struct proc *, struct vnode *, u_long, caddr_t, int);
95: void ELFNAME(load_psection)(struct exec_vmcmd_set *, struct vnode *,
96: Elf_Phdr *, Elf_Addr *, Elf_Addr *, int *, int);
97:
98: extern char sigcode[], esigcode[];
99: #ifdef SYSCALL_DEBUG
100: extern char *syscallnames[];
101: #endif
102:
103: /* round up and down to page boundaries. */
104: #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1))
105: #define ELF_TRUNC(a, b) ((a) & ~((b) - 1))
106:
107: /*
108: * We limit the number of program headers to 32, this should
109: * be a reasonable limit for ELF, the most we have seen so far is 12
110: */
111: #define ELF_MAX_VALID_PHDR 32
112:
113: /*
114: * This is the basic elf emul. elf_probe_funcs may change to other emuls.
115: */
116: struct emul ELFNAMEEND(emul) = {
117: "native",
118: NULL,
119: sendsig,
120: SYS_syscall,
121: SYS_MAXSYSCALL,
122: sysent,
123: #ifdef SYSCALL_DEBUG
124: syscallnames,
125: #else
126: NULL,
127: #endif
128: sizeof (AuxInfo) * ELF_AUX_ENTRIES,
129: ELFNAME(copyargs),
130: setregs,
131: ELFNAME2(exec,fixup),
132: sigcode,
133: esigcode,
134: EMUL_ENABLED | EMUL_NATIVE,
135: };
136:
137: /*
138: * Copy arguments onto the stack in the normal way, but add some
139: * space for extra information in case of dynamic binding.
140: */
141: void *
142: ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo,
143: void *stack, void *argp)
144: {
145: stack = copyargs(pack, arginfo, stack, argp);
146: if (!stack)
147: return (NULL);
148:
149: /*
150: * Push space for extra arguments on the stack needed by
151: * dynamically linked binaries.
152: */
153: if (pack->ep_interp != NULL) {
154: pack->ep_emul_argp = stack;
155: stack = (char *)stack + ELF_AUX_ENTRIES * sizeof (AuxInfo);
156: }
157: return (stack);
158: }
159:
160: /*
161: * Check header for validity; return 0 for ok, ENOEXEC if error
162: */
163: int
164: ELFNAME(check_header)(Elf_Ehdr *ehdr, int type)
165: {
166: /*
167: * We need to check magic, class size, endianess, and version before
168: * we look at the rest of the Elf_Ehdr structure. These few elements
169: * are represented in a machine independant fashion.
170: */
171: if (!IS_ELF(*ehdr) ||
172: ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
173: ehdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
174: ehdr->e_ident[EI_VERSION] != ELF_TARG_VER)
175: return (ENOEXEC);
176:
177: /* Now check the machine dependant header */
178: if (ehdr->e_machine != ELF_TARG_MACH ||
179: ehdr->e_version != ELF_TARG_VER)
180: return (ENOEXEC);
181:
182: /* Check the type */
183: if (ehdr->e_type != type)
184: return (ENOEXEC);
185:
186: /* Don't allow an insane amount of sections. */
187: if (ehdr->e_phnum > ELF_MAX_VALID_PHDR)
188: return (ENOEXEC);
189:
190: return (0);
191: }
192:
193: #ifndef SMALL_KERNEL
194: /*
195: * Check header for validity; return 0 for ok, ENOEXEC if error.
196: * Remember OS tag for callers sake.
197: */
198: int
199: ELFNAME(olf_check_header)(Elf_Ehdr *ehdr, int type, u_int8_t *os)
200: {
201: int i;
202:
203: /*
204: * We need to check magic, class size, endianess, version, and OS
205: * before we look at the rest of the Elf_Ehdr structure. These few
206: * elements are represented in a machine independant fashion.
207: */
208: if (!IS_OLF(*ehdr) ||
209: ehdr->e_ident[OI_CLASS] != ELF_TARG_CLASS ||
210: ehdr->e_ident[OI_DATA] != ELF_TARG_DATA ||
211: ehdr->e_ident[OI_VERSION] != ELF_TARG_VER)
212: return (ENOEXEC);
213:
214: for (i = 0;
215: i < sizeof(ELFNAME(probes)) / sizeof(ELFNAME(probes)[0]);
216: i++) {
217: if ((1 << ehdr->e_ident[OI_OS]) & ELFNAME(probes)[i].os_mask)
218: goto os_ok;
219: }
220: return (ENOEXEC);
221:
222: os_ok:
223: /* Now check the machine dependant header */
224: if (ehdr->e_machine != ELF_TARG_MACH ||
225: ehdr->e_version != ELF_TARG_VER)
226: return (ENOEXEC);
227:
228: /* Check the type */
229: if (ehdr->e_type != type)
230: return (ENOEXEC);
231:
232: /* Don't allow an insane amount of sections. */
233: if (ehdr->e_phnum > ELF_MAX_VALID_PHDR)
234: return (ENOEXEC);
235:
236: *os = ehdr->e_ident[OI_OS];
237: return (0);
238: }
239: #endif /* !SMALL_KERNEL */
240:
241: /*
242: * Load a psection at the appropriate address
243: */
244: void
245: ELFNAME(load_psection)(struct exec_vmcmd_set *vcset, struct vnode *vp,
246: Elf_Phdr *ph, Elf_Addr *addr, Elf_Addr *size, int *prot, int flags)
247: {
248: u_long uaddr, msize, lsize, psize, rm, rf;
249: long diff, offset, bdiff;
250: Elf_Addr base;
251:
252: /*
253: * If the user specified an address, then we load there.
254: */
255: if (*addr != ELFDEFNNAME(NO_ADDR)) {
256: if (ph->p_align > 1) {
257: *addr = ELF_TRUNC(*addr, ph->p_align);
258: diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align);
259: /* page align vaddr */
260: base = *addr + trunc_page(ph->p_vaddr)
261: - ELF_TRUNC(ph->p_vaddr, ph->p_align);
262:
263: bdiff = ph->p_vaddr - trunc_page(ph->p_vaddr);
264:
265: } else
266: diff = 0;
267: } else {
268: *addr = uaddr = ph->p_vaddr;
269: if (ph->p_align > 1)
270: *addr = ELF_TRUNC(uaddr, ph->p_align);
271: base = trunc_page(uaddr);
272: bdiff = uaddr - base;
273: diff = uaddr - *addr;
274: }
275:
276: *prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0;
277: *prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0;
278: *prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0;
279:
280: msize = ph->p_memsz + diff;
281: offset = ph->p_offset - bdiff;
282: lsize = ph->p_filesz + bdiff;
283: psize = round_page(lsize);
284:
285: /*
286: * Because the pagedvn pager can't handle zero fill of the last
287: * data page if it's not page aligned we map the last page readvn.
288: */
289: if (ph->p_flags & PF_W) {
290: psize = trunc_page(lsize);
291: if (psize > 0)
292: NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp,
293: offset, *prot, flags);
294: if (psize != lsize) {
295: NEW_VMCMD2(vcset, vmcmd_map_readvn, lsize - psize,
296: base + psize, vp, offset + psize, *prot, flags);
297: }
298: } else {
299: NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, offset,
300: *prot, flags);
301: }
302:
303: /*
304: * Check if we need to extend the size of the segment
305: */
306: rm = round_page(*addr + ph->p_memsz + diff);
307: rf = round_page(*addr + ph->p_filesz + diff);
308:
309: if (rm != rf) {
310: NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0,
311: *prot, flags);
312: }
313: *size = msize;
314: }
315:
316: /*
317: * Read from vnode into buffer at offset.
318: */
319: int
320: ELFNAME(read_from)(struct proc *p, struct vnode *vp, u_long off, caddr_t buf,
321: int size)
322: {
323: int error;
324: size_t resid;
325:
326: if ((error = vn_rdwr(UIO_READ, vp, buf, size, off, UIO_SYSSPACE,
327: 0, p->p_ucred, &resid, p)) != 0)
328: return error;
329: /*
330: * See if we got all of it
331: */
332: if (resid != 0)
333: return (ENOEXEC);
334: return (0);
335: }
336:
337: /*
338: * Load a file (interpreter/library) pointed to by path [stolen from
339: * coff_load_shlib()]. Made slightly generic so it might be used externally.
340: */
341: int
342: ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp,
343: struct elf_args *ap, Elf_Addr *last)
344: {
345: int error, i;
346: struct nameidata nd;
347: Elf_Ehdr eh;
348: Elf_Phdr *ph = NULL;
349: u_long phsize;
350: Elf_Addr addr;
351: struct vnode *vp;
352: #ifndef SMALL_KERNEL
353: u_int8_t os; /* Just a dummy in this routine */
354: #endif
355: Elf_Phdr *base_ph = NULL;
356: struct interp_ld_sec {
357: Elf_Addr vaddr;
358: u_long memsz;
359: } loadmap[ELF_MAX_VALID_PHDR];
360: int nload, idx = 0;
361: Elf_Addr pos = *last;
362: int file_align;
363:
364: NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p);
365: if ((error = namei(&nd)) != 0) {
366: return (error);
367: }
368: vp = nd.ni_vp;
369: if (vp->v_type != VREG) {
370: error = EACCES;
371: goto bad;
372: }
373: if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0)
374: goto bad;
375: if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
376: error = EACCES;
377: goto bad;
378: }
379: if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0)
380: goto bad1;
381: if ((error = ELFNAME(read_from)(p, nd.ni_vp, 0,
382: (caddr_t)&eh, sizeof(eh))) != 0)
383: goto bad1;
384:
385: if (ELFNAME(check_header)(&eh, ET_DYN)
386: #ifndef SMALL_KERNEL
387: && ELFNAME(olf_check_header)(&eh, ET_DYN, &os)
388: #endif
389: ) {
390: error = ENOEXEC;
391: goto bad1;
392: }
393:
394: phsize = eh.e_phnum * sizeof(Elf_Phdr);
395: ph = malloc(phsize, M_TEMP, M_WAITOK);
396:
397: if ((error = ELFNAME(read_from)(p, nd.ni_vp, eh.e_phoff, (caddr_t)ph,
398: phsize)) != 0)
399: goto bad1;
400:
401: for (i = 0; i < eh.e_phnum; i++) {
402: if (ph[i].p_type == PT_LOAD) {
403: loadmap[idx].vaddr = trunc_page(ph[i].p_vaddr);
404: loadmap[idx].memsz = round_page (ph[i].p_vaddr +
405: ph[i].p_memsz - loadmap[idx].vaddr);
406: file_align = ph[i].p_align;
407: idx++;
408: }
409: }
410: nload = idx;
411:
412: /*
413: * If no position to load the interpreter was set by a probe
414: * function, pick the same address that a non-fixed mmap(0, ..)
415: * would (i.e. something safely out of the way).
416: */
417: if (pos == ELFDEFNNAME(NO_ADDR)) {
418: pos = uvm_map_hint(p, VM_PROT_EXECUTE);
419: }
420:
421: pos = ELF_ROUND(pos, file_align);
422: *last = epp->ep_interp_pos = pos;
423: for (i = 0; i < nload;/**/) {
424: vaddr_t addr;
425: struct uvm_object *uobj;
426: off_t uoff;
427: size_t size;
428:
429: #ifdef this_needs_fixing
430: if (i == 0) {
431: uobj = &vp->v_uvm.u_obj;
432: /* need to fix uoff */
433: } else {
434: #endif
435: uobj = NULL;
436: uoff = 0;
437: #ifdef this_needs_fixing
438: }
439: #endif
440:
441: addr = trunc_page(pos + loadmap[i].vaddr);
442: size = round_page(addr + loadmap[i].memsz) - addr;
443:
444: /* CRAP - map_findspace does not avoid daddr+MAXDSIZ */
445: if ((addr + size > (vaddr_t)p->p_vmspace->vm_daddr) &&
446: (addr < (vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ))
447: addr = round_page((vaddr_t)p->p_vmspace->vm_daddr +
448: MAXDSIZ);
449:
450: if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size,
451: &addr, uobj, uoff, 0, UVM_FLAG_FIXED) == NULL) {
452: if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size,
453: &addr, uobj, uoff, 0, 0) == NULL) {
454: error = ENOMEM; /* XXX */
455: goto bad1;
456: }
457: }
458: if (addr != pos + loadmap[i].vaddr) {
459: /* base changed. */
460: pos = addr - trunc_page(loadmap[i].vaddr);
461: pos = ELF_ROUND(pos,file_align);
462: epp->ep_interp_pos = *last = pos;
463: i = 0;
464: continue;
465: }
466:
467: i++;
468: }
469:
470: /*
471: * Load all the necessary sections
472: */
473: for (i = 0; i < eh.e_phnum; i++) {
474: Elf_Addr size = 0;
475: int prot = 0;
476: int flags;
477:
478: switch (ph[i].p_type) {
479: case PT_LOAD:
480: if (base_ph == NULL) {
481: flags = VMCMD_BASE;
482: addr = *last;
483: base_ph = &ph[i];
484: } else {
485: flags = VMCMD_RELATIVE;
486: addr = ph[i].p_vaddr - base_ph->p_vaddr;
487: }
488: ELFNAME(load_psection)(&epp->ep_vmcmds, nd.ni_vp,
489: &ph[i], &addr, &size, &prot, flags);
490: /* If entry is within this section it must be text */
491: if (eh.e_entry >= ph[i].p_vaddr &&
492: eh.e_entry < (ph[i].p_vaddr + size)) {
493: epp->ep_entry = addr + eh.e_entry -
494: ELF_TRUNC(ph[i].p_vaddr,ph[i].p_align);
495: ap->arg_interp = addr;
496: }
497: addr += size;
498: break;
499:
500: case PT_DYNAMIC:
501: case PT_PHDR:
502: case PT_NOTE:
503: break;
504:
505: default:
506: break;
507: }
508: }
509:
510: vn_marktext(nd.ni_vp);
511:
512: bad1:
513: VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p);
514: bad:
515: if (ph != NULL)
516: free(ph, M_TEMP);
517:
518: *last = addr;
519: vput(nd.ni_vp);
520: return (error);
521: }
522:
523: /*
524: * Prepare an Elf binary's exec package
525: *
526: * First, set of the various offsets/lengths in the exec package.
527: *
528: * Then, mark the text image busy (so it can be demand paged) or error out if
529: * this is not possible. Finally, set up vmcmds for the text, data, bss, and
530: * stack segments.
531: */
532: int
533: ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp)
534: {
535: Elf_Ehdr *eh = epp->ep_hdr;
536: Elf_Phdr *ph, *pp;
537: Elf_Addr phdr = 0;
538: int error, i;
539: char *interp = NULL;
540: u_long pos = 0, phsize;
541: u_int8_t os = OOS_NULL;
542:
543: if (epp->ep_hdrvalid < sizeof(Elf_Ehdr))
544: return (ENOEXEC);
545:
546: if (ELFNAME(check_header)(eh, ET_EXEC)
547: #ifndef SMALL_KERNEL
548: && ELFNAME(olf_check_header)(eh, ET_EXEC, &os)
549: #endif
550: )
551: return (ENOEXEC);
552:
553: /*
554: * check if vnode is in open for writing, because we want to demand-
555: * page out of it. if it is, don't do it, for various reasons.
556: */
557: if (epp->ep_vp->v_writecount != 0) {
558: #ifdef DIAGNOSTIC
559: if (epp->ep_vp->v_flag & VTEXT)
560: panic("exec: a VTEXT vnode has writecount != 0");
561: #endif
562: return (ETXTBSY);
563: }
564: /*
565: * Allocate space to hold all the program headers, and read them
566: * from the file
567: */
568: phsize = eh->e_phnum * sizeof(Elf_Phdr);
569: ph = malloc(phsize, M_TEMP, M_WAITOK);
570:
571: if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph,
572: phsize)) != 0)
573: goto bad;
574:
575: epp->ep_tsize = ELFDEFNNAME(NO_ADDR);
576: epp->ep_dsize = ELFDEFNNAME(NO_ADDR);
577:
578: for (i = 0; i < eh->e_phnum; i++) {
579: pp = &ph[i];
580: if (pp->p_type == PT_INTERP) {
581: if (pp->p_filesz >= MAXPATHLEN)
582: goto bad;
583: interp = pool_get(&namei_pool, PR_WAITOK);
584: if ((error = ELFNAME(read_from)(p, epp->ep_vp,
585: pp->p_offset, interp, pp->p_filesz)) != 0) {
586: goto bad;
587: }
588: break;
589: }
590: }
591:
592: /*
593: * OK, we want a slightly different twist of the
594: * standard emulation package for "real" elf.
595: */
596: epp->ep_emul = &ELFNAMEEND(emul);
597: pos = ELFDEFNNAME(NO_ADDR);
598:
599: /*
600: * On the same architecture, we may be emulating different systems.
601: * See which one will accept this executable.
602: *
603: * Probe functions would normally see if the interpreter (if any)
604: * exists. Emulation packages may possibly replace the interpreter in
605: * *interp with a changed path (/emul/xxx/<path>), and also
606: * set the ep_emul field in the exec package structure.
607: */
608: error = ENOEXEC;
609: p->p_os = OOS_OPENBSD;
610: #ifdef NATIVE_EXEC_ELF
611: if (ELFNAME(os_pt_note)(p, epp, epp->ep_hdr, "OpenBSD", 8, 4) == 0) {
612: goto native;
613: }
614: #endif
615: for (i = 0;
616: i < sizeof(ELFNAME(probes)) / sizeof(ELFNAME(probes)[0]) && error;
617: i++) {
618: if (os == OOS_NULL || ((1 << os) & ELFNAME(probes)[i].os_mask))
619: error = ELFNAME(probes)[i].func ?
620: (*ELFNAME(probes)[i].func)(p, epp, interp, &pos, &os) :
621: 0;
622: }
623: if (!error)
624: p->p_os = os;
625: #ifndef NATIVE_EXEC_ELF
626: else
627: goto bad;
628: #else
629: native:
630: #endif /* NATIVE_EXEC_ELF */
631: /*
632: * Load all the necessary sections
633: */
634: for (i = 0; i < eh->e_phnum; i++) {
635: Elf_Addr addr = ELFDEFNNAME(NO_ADDR), size = 0;
636: int prot = 0;
637:
638: pp = &ph[i];
639:
640: switch (ph[i].p_type) {
641: case PT_LOAD:
642: /*
643: * Calculates size of text and data segments
644: * by starting at first and going to end of last.
645: * 'rwx' sections are treated as data.
646: * this is correct for BSS_PLT, but may not be
647: * for DATA_PLT, is fine for TEXT_PLT.
648: */
649: ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp,
650: &ph[i], &addr, &size, &prot, 0);
651: /*
652: * Decide whether it's text or data by looking
653: * at the protection of the section
654: */
655: if (prot & VM_PROT_WRITE) {
656: /* data section */
657: if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) {
658: epp->ep_daddr = addr;
659: epp->ep_dsize = size;
660: } else {
661: if (addr < epp->ep_daddr) {
662: epp->ep_dsize =
663: epp->ep_dsize +
664: epp->ep_daddr -
665: addr;
666: epp->ep_daddr = addr;
667: } else
668: epp->ep_dsize = addr+size -
669: epp->ep_daddr;
670: }
671: } else if (prot & VM_PROT_EXECUTE) {
672: /* text section */
673: if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR)) {
674: epp->ep_taddr = addr;
675: epp->ep_tsize = size;
676: } else {
677: if (addr < epp->ep_taddr) {
678: epp->ep_tsize =
679: epp->ep_tsize +
680: epp->ep_taddr -
681: addr;
682: epp->ep_taddr = addr;
683: } else
684: epp->ep_tsize = addr+size -
685: epp->ep_taddr;
686: }
687: }
688: break;
689:
690: case PT_SHLIB:
691: error = ENOEXEC;
692: goto bad;
693:
694: case PT_INTERP:
695: /* Already did this one */
696: case PT_DYNAMIC:
697: case PT_NOTE:
698: break;
699:
700: case PT_PHDR:
701: /* Note address of program headers (in text segment) */
702: phdr = pp->p_vaddr;
703: break;
704:
705: default:
706: /*
707: * Not fatal, we don't need to understand everything
708: * :-)
709: */
710: break;
711: }
712: }
713:
714: /*
715: * Strangely some linux programs may have all load sections marked
716: * writeable, in this case, textsize is not -1, but rather 0;
717: */
718: if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR))
719: epp->ep_tsize = 0;
720: /*
721: * Another possibility is that it has all load sections marked
722: * read-only. Fake a zero-sized data segment right after the
723: * text segment.
724: */
725: if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) {
726: epp->ep_daddr = round_page(epp->ep_taddr + epp->ep_tsize);
727: epp->ep_dsize = 0;
728: }
729:
730: epp->ep_interp = interp;
731: epp->ep_entry = eh->e_entry;
732:
733: /*
734: * Check if we found a dynamically linked binary and arrange to load
735: * its interpreter when the exec file is released.
736: */
737: if (interp) {
738: struct elf_args *ap;
739:
740: ap = malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK);
741:
742: ap->arg_phaddr = phdr;
743: ap->arg_phentsize = eh->e_phentsize;
744: ap->arg_phnum = eh->e_phnum;
745: ap->arg_entry = eh->e_entry;
746: ap->arg_os = os;
747:
748: epp->ep_emul_arg = ap;
749: epp->ep_interp_pos = pos;
750: }
751:
752: #if defined(COMPAT_SVR4) && defined(i386)
753: #ifndef ELF_MAP_PAGE_ZERO
754: /* Dell SVR4 maps page zero, yeuch! */
755: if (p->p_os == OOS_DELL)
756: #endif
757: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0,
758: epp->ep_vp, 0, VM_PROT_READ);
759: #endif
760:
761: free(ph, M_TEMP);
762: vn_marktext(epp->ep_vp);
763: return (exec_setup_stack(p, epp));
764:
765: bad:
766: if (interp)
767: pool_put(&namei_pool, interp);
768: free(ph, M_TEMP);
769: kill_vmcmds(&epp->ep_vmcmds);
770: return (ENOEXEC);
771: }
772:
773: /*
774: * Phase II of load. It is now safe to load the interpreter. Info collected
775: * when loading the program is available for setup of the interpreter.
776: */
777: int
778: ELFNAME2(exec,fixup)(struct proc *p, struct exec_package *epp)
779: {
780: char *interp;
781: int error;
782: struct elf_args *ap;
783: AuxInfo ai[ELF_AUX_ENTRIES], *a;
784: Elf_Addr pos = epp->ep_interp_pos;
785:
786: if (epp->ep_interp == NULL) {
787: return (0);
788: }
789:
790: interp = epp->ep_interp;
791: ap = epp->ep_emul_arg;
792:
793: if ((error = ELFNAME(load_file)(p, interp, epp, ap, &pos)) != 0) {
794: free(ap, M_TEMP);
795: pool_put(&namei_pool, interp);
796: kill_vmcmds(&epp->ep_vmcmds);
797: return (error);
798: }
799: /*
800: * We have to do this ourselves...
801: */
802: error = exec_process_vmcmds(p, epp);
803:
804: /*
805: * Push extra arguments on the stack needed by dynamically
806: * linked binaries
807: */
808: if (error == 0) {
809: a = ai;
810:
811: a->au_id = AUX_phdr;
812: a->au_v = ap->arg_phaddr;
813: a++;
814:
815: a->au_id = AUX_phent;
816: a->au_v = ap->arg_phentsize;
817: a++;
818:
819: a->au_id = AUX_phnum;
820: a->au_v = ap->arg_phnum;
821: a++;
822:
823: a->au_id = AUX_pagesz;
824: a->au_v = PAGE_SIZE;
825: a++;
826:
827: a->au_id = AUX_base;
828: a->au_v = ap->arg_interp;
829: a++;
830:
831: a->au_id = AUX_flags;
832: a->au_v = 0;
833: a++;
834:
835: a->au_id = AUX_entry;
836: a->au_v = ap->arg_entry;
837: a++;
838:
839: a->au_id = AUX_null;
840: a->au_v = 0;
841: a++;
842:
843: error = copyout(ai, epp->ep_emul_argp, sizeof ai);
844: }
845: free(ap, M_TEMP);
846: pool_put(&namei_pool, interp);
847: return (error);
848: }
849:
850: /*
851: * Older ELF binaries use EI_ABIVERSION (formerly EI_BRAND) to brand
852: * executables. Newer ELF binaries use EI_OSABI instead.
853: */
854: char *
855: ELFNAME(check_brand)(Elf_Ehdr *eh)
856: {
857: if (eh->e_ident[EI_ABIVERSION] == '\0')
858: return (NULL);
859: return (&eh->e_ident[EI_ABIVERSION]);
860: }
861:
862: int
863: ELFNAME(os_pt_note)(struct proc *p, struct exec_package *epp, Elf_Ehdr *eh,
864: char *os_name, size_t name_size, size_t desc_size)
865: {
866: Elf_Phdr *hph, *ph;
867: Elf_Note *np = NULL;
868: size_t phsize;
869: int error;
870:
871: phsize = eh->e_phnum * sizeof(Elf_Phdr);
872: hph = malloc(phsize, M_TEMP, M_WAITOK);
873: if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff,
874: (caddr_t)hph, phsize)) != 0)
875: goto out1;
876:
877: for (ph = hph; ph < &hph[eh->e_phnum]; ph++) {
878: if (ph->p_type != PT_NOTE ||
879: ph->p_filesz > 1024 ||
880: ph->p_filesz < sizeof(Elf_Note) + name_size)
881: continue;
882:
883: np = malloc(ph->p_filesz, M_TEMP, M_WAITOK);
884: if ((error = ELFNAME(read_from)(p, epp->ep_vp, ph->p_offset,
885: (caddr_t)np, ph->p_filesz)) != 0)
886: goto out2;
887:
888: #if 0
889: if (np->type != ELF_NOTE_TYPE_OSVERSION) {
890: free(np, M_TEMP);
891: np = NULL;
892: continue;
893: }
894: #endif
895:
896: /* Check the name and description sizes. */
897: if (np->namesz != name_size ||
898: np->descsz != desc_size)
899: goto out3;
900:
901: if (bcmp((np + 1), os_name, name_size))
902: goto out3;
903:
904: /* XXX: We could check for the specific emulation here */
905: /* All checks succeeded. */
906: error = 0;
907: goto out2;
908: }
909:
910: out3:
911: error = ENOEXEC;
912: out2:
913: if (np)
914: free(np, M_TEMP);
915: out1:
916: free(hph, M_TEMP);
917: return error;
918: }
CVSweb