exec_elf.c revision 1.8 1 /* $NetBSD: exec_elf.c,v 1.8 1996/06/14 18:15:55 christos Exp $ */
2
3 /*
4 * Copyright (c) 1994 Christos Zoulas
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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 without 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 */
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/proc.h>
35 #include <sys/malloc.h>
36 #include <sys/namei.h>
37 #include <sys/vnode.h>
38 #include <sys/exec.h>
39 #include <sys/exec_elf.h>
40 #include <sys/syscall.h>
41 #include <sys/signalvar.h>
42
43 #include <sys/mman.h>
44 #include <vm/vm.h>
45 #include <vm/vm_param.h>
46 #include <vm/vm_map.h>
47
48 #include <machine/cpu.h>
49 #include <machine/reg.h>
50 #include <machine/exec.h>
51
52 #ifdef COMPAT_LINUX
53 #include <compat/linux/linux_exec.h>
54 #endif
55
56 #ifdef COMPAT_SVR4
57 #include <compat/svr4/svr4_exec.h>
58 #endif
59
60 int (*elf_probe_funcs[]) __P((struct proc *, struct exec_package *,
61 Elf32_Ehdr *, char *, u_long *)) = {
62 #ifdef COMPAT_LINUX
63 linux_elf_probe,
64 #endif
65 #ifdef COMPAT_SVR4
66 svr4_elf_probe,
67 #endif
68 };
69
70 int elf_check_header __P((Elf32_Ehdr *, int));
71 int elf_load_file __P((struct proc *, char *, struct exec_vmcmd_set *,
72 u_long *, struct elf_args *, u_long *));
73
74 static void elf_load_psection __P((struct exec_vmcmd_set *,
75 struct vnode *, Elf32_Phdr *, u_long *, u_long *, int *));
76
77 #define ELF_ALIGN(a, b) ((a) & ~((b) - 1))
78
79 /*
80 * This is the basic elf emul. elf_probe_funcs may change to other emuls.
81 */
82 extern char sigcode[], esigcode[];
83 #ifdef SYSCALL_DEBUG
84 extern char *syscallnames[];
85 #endif
86
87 struct emul emul_elf = {
88 "netbsd",
89 NULL,
90 sendsig,
91 SYS_syscall,
92 SYS_MAXSYSCALL,
93 sysent,
94 #ifdef SYSCALL_DEBUG
95 syscallnames,
96 #else
97 NULL,
98 #endif
99 sizeof(AuxInfo) * ELF_AUX_ENTRIES,
100 elf_copyargs,
101 setregs,
102 sigcode,
103 esigcode,
104 };
105
106
107 /*
108 * Copy arguments onto the stack in the normal way, but add some
109 * extra information in case of dynamic binding.
110 */
111 void *
112 elf_copyargs(pack, arginfo, stack, argp)
113 struct exec_package *pack;
114 struct ps_strings *arginfo;
115 void *stack;
116 void *argp;
117 {
118 size_t len;
119 AuxInfo ai[ELF_AUX_ENTRIES], *a;
120 struct elf_args *ap;
121
122 stack = copyargs(pack, arginfo, stack, argp);
123 if (!stack)
124 return NULL;
125
126 /*
127 * Push extra arguments on the stack needed by dynamically
128 * linked binaries
129 */
130 if ((ap = (struct elf_args *) pack->ep_emul_arg)) {
131 a = ai;
132
133 a->au_id = AUX_phdr;
134 a->au_v = ap->arg_phaddr;
135 a++;
136
137 a->au_id = AUX_phent;
138 a->au_v = ap->arg_phentsize;
139 a++;
140
141 a->au_id = AUX_phnum;
142 a->au_v = ap->arg_phnum;
143 a++;
144
145 a->au_id = AUX_pagesz;
146 a->au_v = NBPG;
147 a++;
148
149 a->au_id = AUX_base;
150 a->au_v = ap->arg_interp;
151 a++;
152
153 a->au_id = AUX_flags;
154 a->au_v = 0;
155 a++;
156
157 a->au_id = AUX_entry;
158 a->au_v = ap->arg_entry;
159 a++;
160
161 a->au_id = AUX_null;
162 a->au_v = 0;
163 a++;
164
165 free((char *) ap, M_TEMP);
166 len = ELF_AUX_ENTRIES * sizeof (AuxInfo);
167 if (copyout(ai, stack, len))
168 return NULL;
169 stack += len;
170 }
171 return stack;
172 }
173
174 /*
175 * elf_check_header():
176 *
177 * Check header for validity; return 0 of ok ENOEXEC if error
178 *
179 * XXX machine type needs to be moved to <machine/param.h> so
180 * just one comparison can be done. Unfortunately, there is both
181 * em_486 and em_386, so this would not work on the i386.
182 */
183 int
184 elf_check_header(eh, type)
185 Elf32_Ehdr *eh;
186 int type;
187 {
188
189 if (bcmp(eh->e_ident, Elf32_e_ident, Elf32_e_siz) != 0)
190 return ENOEXEC;
191
192 switch (eh->e_machine) {
193 /* XXX */
194 #ifdef i386
195 case Elf32_em_386:
196 case Elf32_em_486:
197 #endif
198 #ifdef sparc
199 case Elf32_em_sparc:
200 #endif
201 #ifdef mips
202 case Elf32_em_mips:
203 #endif
204 break;
205
206 default:
207 return ENOEXEC;
208 }
209
210 if (eh->e_type != type)
211 return ENOEXEC;
212
213 return 0;
214 }
215
216 /*
217 * elf_load_psection():
218 *
219 * Load a psection at the appropriate address
220 */
221 static void
222 elf_load_psection(vcset, vp, ph, addr, size, prot)
223 struct exec_vmcmd_set *vcset;
224 struct vnode *vp;
225 Elf32_Phdr *ph;
226 u_long *addr;
227 u_long *size;
228 int *prot;
229 {
230 u_long uaddr, msize, psize, rm, rf;
231 long diff, offset;
232
233 /*
234 * If the user specified an address, then we load there.
235 */
236 if (*addr != ELF32_NO_ADDR) {
237 if (ph->p_align > 1) {
238 *addr = ELF_ALIGN(*addr + ph->p_align, ph->p_align);
239 uaddr = ELF_ALIGN(ph->p_vaddr, ph->p_align);
240 } else
241 uaddr = ph->p_vaddr;
242 diff = ph->p_vaddr - uaddr;
243 } else {
244 *addr = uaddr = ph->p_vaddr;
245 if (ph->p_align > 1)
246 *addr = ELF_ALIGN(uaddr, ph->p_align);
247 diff = uaddr - *addr;
248 }
249
250 *prot |= (ph->p_flags & Elf32_pf_r) ? VM_PROT_READ : 0;
251 *prot |= (ph->p_flags & Elf32_pf_w) ? VM_PROT_WRITE : 0;
252 *prot |= (ph->p_flags & Elf32_pf_x) ? VM_PROT_EXECUTE : 0;
253
254 offset = ph->p_offset - diff;
255 *size = ph->p_filesz + diff;
256 msize = ph->p_memsz + diff;
257 psize = round_page(*size);
258
259 if ((ph->p_flags & Elf32_pf_w) != 0) {
260 /*
261 * Because the pagedvn pager can't handle zero fill of the last
262 * data page if it's not page aligned we map the last page
263 * readvn.
264 */
265 psize = trunc_page(*size);
266 NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp,
267 offset, *prot);
268 if(psize != *size)
269 NEW_VMCMD(vcset, vmcmd_map_readvn, *size - psize,
270 *addr + psize, vp, offset + psize, *prot);
271 }
272 else
273 NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp,
274 offset, *prot);
275
276 /*
277 * Check if we need to extend the size of the segment
278 */
279 rm = round_page(*addr + msize);
280 rf = round_page(*addr + *size);
281
282 if (rm != rf) {
283 NEW_VMCMD(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0, *prot);
284 *size = msize;
285 }
286 }
287
288 /*
289 * elf_read_from():
290 *
291 * Read from vnode into buffer at offset.
292 */
293 int
294 elf_read_from(p, vp, off, buf, size)
295 struct vnode *vp;
296 u_long off;
297 struct proc *p;
298 caddr_t buf;
299 int size;
300 {
301 int error;
302 int resid;
303
304 if ((error = vn_rdwr(UIO_READ, vp, buf, size,
305 off, UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred,
306 &resid, p)) != 0)
307 return error;
308 /*
309 * See if we got all of it
310 */
311 if (resid != 0)
312 return ENOEXEC;
313 return 0;
314 }
315
316 /*
317 * elf_load_file():
318 *
319 * Load a file (interpreter/library) pointed to by path
320 * [stolen from coff_load_shlib()]. Made slightly generic
321 * so it might be used externally.
322 */
323 int
324 elf_load_file(p, path, vcset, entry, ap, last)
325 struct proc *p;
326 char *path;
327 struct exec_vmcmd_set *vcset;
328 u_long *entry;
329 struct elf_args *ap;
330 u_long *last;
331 {
332 int error, i;
333 struct nameidata nd;
334 Elf32_Ehdr eh;
335 Elf32_Phdr *ph = NULL;
336 u_long phsize;
337 char *bp = NULL;
338 u_long addr = *last;
339
340 bp = path;
341 /*
342 * 1. open file
343 * 2. read filehdr
344 * 3. map text, data, and bss out of it using VM_*
345 */
346 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p);
347 if ((error = namei(&nd)) != 0) {
348 return error;
349 }
350 if ((error = elf_read_from(p, nd.ni_vp, 0, (caddr_t) &eh,
351 sizeof(eh))) != 0)
352 goto bad;
353
354 if ((error = elf_check_header(&eh, Elf32_et_dyn)) != 0)
355 goto bad;
356
357 phsize = eh.e_phnum * sizeof(Elf32_Phdr);
358 ph = (Elf32_Phdr *) malloc(phsize, M_TEMP, M_WAITOK);
359
360 if ((error = elf_read_from(p, nd.ni_vp, eh.e_phoff,
361 (caddr_t) ph, phsize)) != 0)
362 goto bad;
363
364 /*
365 * Load all the necessary sections
366 */
367 for (i = 0; i < eh.e_phnum; i++) {
368 u_long size = 0;
369 int prot = 0;
370
371 switch (ph[i].p_type) {
372 case Elf32_pt_load:
373 elf_load_psection(vcset, nd.ni_vp, &ph[i], &addr,
374 &size, &prot);
375 /* If entry is within this section it must be text */
376 if (eh.e_entry >= ph[i].p_vaddr &&
377 eh.e_entry < (ph[i].p_vaddr + size)) {
378 *entry = addr + eh.e_entry;
379 ap->arg_interp = addr;
380 }
381 addr += size;
382 break;
383
384 case Elf32_pt_dynamic:
385 case Elf32_pt_phdr:
386 case Elf32_pt_note:
387 break;
388
389 default:
390 break;
391 }
392 }
393
394 bad:
395 if (ph != NULL)
396 free((char *) ph, M_TEMP);
397
398 *last = addr;
399 vrele(nd.ni_vp);
400 return error;
401 }
402
403 /*
404 * exec_elf_makecmds(): Prepare an Elf binary's exec package
405 *
406 * First, set of the various offsets/lengths in the exec package.
407 *
408 * Then, mark the text image busy (so it can be demand paged) or error
409 * out if this is not possible. Finally, set up vmcmds for the
410 * text, data, bss, and stack segments.
411 */
412 int
413 exec_elf_makecmds(p, epp)
414 struct proc *p;
415 struct exec_package *epp;
416 {
417 Elf32_Ehdr *eh = epp->ep_hdr;
418 Elf32_Phdr *ph, *pp;
419 Elf32_Addr phdr = 0;
420 int error, i, n, nload;
421 char interp[MAXPATHLEN];
422 u_long pos = 0, phsize;
423
424 if (epp->ep_hdrvalid < sizeof(Elf32_Ehdr))
425 return ENOEXEC;
426
427 if (elf_check_header(eh, Elf32_et_exec))
428 return ENOEXEC;
429
430 /*
431 * check if vnode is in open for writing, because we want to
432 * demand-page out of it. if it is, don't do it, for various
433 * reasons
434 */
435 if (epp->ep_vp->v_writecount != 0) {
436 #ifdef DIAGNOSTIC
437 if (epp->ep_vp->v_flag & VTEXT)
438 panic("exec: a VTEXT vnode has writecount != 0\n");
439 #endif
440 return ETXTBSY;
441 }
442 /*
443 * Allocate space to hold all the program headers, and read them
444 * from the file
445 */
446 phsize = eh->e_phnum * sizeof(Elf32_Phdr);
447 ph = (Elf32_Phdr *) malloc(phsize, M_TEMP, M_WAITOK);
448
449 if ((error = elf_read_from(p, epp->ep_vp, eh->e_phoff,
450 (caddr_t) ph, phsize)) != 0)
451 goto bad;
452
453 epp->ep_tsize = ELF32_NO_ADDR;
454 epp->ep_dsize = ELF32_NO_ADDR;
455
456 interp[0] = '\0';
457
458 for (i = 0; i < eh->e_phnum; i++) {
459 pp = &ph[i];
460 if (pp->p_type == Elf32_pt_interp) {
461 if (pp->p_filesz >= sizeof(interp))
462 goto bad;
463 if ((error = elf_read_from(p, epp->ep_vp, pp->p_offset,
464 (caddr_t) interp, pp->p_filesz)) != 0)
465 goto bad;
466 break;
467 }
468 }
469
470 /*
471 * Setup things for native emulation.
472 */
473 epp->ep_emul = &emul_elf;
474 pos = ELF32_NO_ADDR;
475
476 /*
477 * On the same architecture, we may be emulating different systems.
478 * See which one will accept this executable. This currently only
479 * applies to Linux and SVR4 on the i386.
480 *
481 * Probe functions would normally see if the interpreter (if any)
482 * exists. Emulation packages may possibly replace the interpreter in
483 * interp[] with a changed path (/emul/xxx/<path>), and also
484 * set the ep_emul field in the exec package structure.
485 */
486 if ((n = sizeof elf_probe_funcs / sizeof elf_probe_funcs[0])) {
487 error = ENOEXEC;
488 for (i = 0; i < n && error; i++)
489 error = elf_probe_funcs[i](p, epp, eh, interp, &pos);
490
491 #ifdef notyet
492 /*
493 * We should really use a signature in our native binaries
494 * and have our own probe function for matching binaries,
495 * before trying the emulations. For now, if the emulation
496 * probes failed we default to native.
497 */
498 if (error)
499 goto bad;
500 #endif
501 }
502
503 /*
504 * Load all the necessary sections
505 */
506 for (i = nload = 0; i < eh->e_phnum; i++) {
507 u_long addr = ELF32_NO_ADDR, size = 0;
508 int prot = 0;
509
510 pp = &ph[i];
511
512 switch (ph[i].p_type) {
513 case Elf32_pt_load:
514 /*
515 * XXX
516 * Can handle only 2 sections: text and data
517 */
518 if (nload++ == 2)
519 goto bad;
520 elf_load_psection(&epp->ep_vmcmds, epp->ep_vp,
521 &ph[i], &addr, &size, &prot);
522 /*
523 * Decide whether it's text or data by looking
524 * at the entry point.
525 */
526 if (eh->e_entry >= addr && eh->e_entry < (addr + size)){
527 epp->ep_taddr = addr;
528 epp->ep_tsize = size;
529 } else {
530 epp->ep_daddr = addr;
531 epp->ep_dsize = size;
532 }
533 break;
534
535 case Elf32_pt_shlib:
536 error = ENOEXEC;
537 goto bad;
538
539 case Elf32_pt_interp:
540 /* Already did this one */
541 case Elf32_pt_dynamic:
542 case Elf32_pt_note:
543 break;
544
545 case Elf32_pt_phdr:
546 /* Note address of program headers (in text segment) */
547 phdr = pp->p_vaddr;
548 break;
549
550 default:
551 /*
552 * Not fatal, we don't need to understand everything
553 * :-)
554 */
555 break;
556 }
557 }
558
559 /*
560 * If no position to load the interpreter was set by a probe
561 * function, pick the same address that a non-fixed mmap(0, ..)
562 * would (i.e. something safely out of the way).
563 */
564 if (pos == ELF32_NO_ADDR && epp->ep_emul == &emul_elf)
565 pos = round_page(epp->ep_daddr + MAXDSIZ);
566
567 /*
568 * Check if we found a dynamically linked binary and arrange to load
569 * it's interpreter
570 */
571 if (interp[0]) {
572 struct elf_args *ap;
573
574 ap = (struct elf_args *) malloc(sizeof(struct elf_args),
575 M_TEMP, M_WAITOK);
576 if ((error = elf_load_file(p, interp, &epp->ep_vmcmds,
577 &epp->ep_entry, ap, &pos)) != 0) {
578 free((char *) ap, M_TEMP);
579 goto bad;
580 }
581 pos += phsize;
582 ap->arg_phaddr = phdr;
583
584 ap->arg_phentsize = eh->e_phentsize;
585 ap->arg_phnum = eh->e_phnum;
586 ap->arg_entry = eh->e_entry;
587
588 epp->ep_emul_arg = ap;
589 } else
590 epp->ep_entry = eh->e_entry;
591
592 #ifdef ELF_MAP_PAGE_ZERO
593 /* Dell SVR4 maps page zero, yeuch! */
594 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, NBPG, 0, epp->ep_vp, 0,
595 VM_PROT_READ);
596 #endif
597 free((char *) ph, M_TEMP);
598 epp->ep_vp->v_flag |= VTEXT;
599 return exec_aout_setup_stack(p, epp);
600
601 bad:
602 free((char *) ph, M_TEMP);
603 kill_vmcmds(&epp->ep_vmcmds);
604 return ENOEXEC;
605 }
606