FreeBSD/Linux Kernel Cross Reference
sys/kern/exec_macho.c
1 /* $NetBSD: exec_macho.c,v 1.31 2004/09/04 23:21:26 manu Exp $ */
2
3 /*-
4 * Copyright (c) 2001 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 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: exec_macho.c,v 1.31 2004/09/04 23:21:26 manu Exp $");
41
42 #include <sys/param.h>
43 #include <sys/proc.h>
44 #include <sys/malloc.h>
45 #include <sys/namei.h>
46 #include <sys/vnode.h>
47 #include <sys/exec.h>
48 #include <sys/exec_macho.h>
49 #include <sys/syscall.h>
50 #include <sys/signalvar.h>
51 #include <sys/resourcevar.h>
52 #include <sys/mount.h>
53 #include <sys/stat.h>
54
55 #include <uvm/uvm.h>
56
57 #ifdef DEBUG_MACHO
58 #define DPRINTF(a) printf a
59 #else
60 #define DPRINTF(a)
61 #endif
62
63 static int exec_macho_load_segment(struct exec_package *, struct vnode *,
64 u_long, struct exec_macho_segment_command *, int);
65 static int exec_macho_load_dylinker(struct proc *, struct exec_package *,
66 struct exec_macho_dylinker_command *, u_long *, int);
67 static int exec_macho_load_dylib(struct proc *, struct exec_package *,
68 struct exec_macho_dylib_command *, int);
69 static u_long exec_macho_load_thread(struct exec_macho_thread_command *);
70 static int exec_macho_load_file(struct proc *, struct exec_package *,
71 const char *, u_long *, int, int, int);
72 static int exec_macho_load_vnode(struct proc *, struct exec_package *,
73 struct vnode *, struct exec_macho_fat_header *, u_long *, int, int, int);
74
75 #ifdef DEBUG_MACHO
76 static void exec_macho_print_segment_command
77 (struct exec_macho_segment_command *);
78 static void exec_macho_print_fat_header(struct exec_macho_fat_header *);
79 static void exec_macho_print_fat_arch(struct exec_macho_fat_arch *);
80 static void exec_macho_print_object_header(struct exec_macho_object_header *);
81 static void exec_macho_print_load_command(struct exec_macho_load_command *);
82 static void exec_macho_print_dylinker_command
83 (struct exec_macho_dylinker_command *);
84 static void exec_macho_print_dylib_command(struct exec_macho_dylib_command *);
85 static void exec_macho_print_thread_command
86 (struct exec_macho_thread_command *);
87
88 static void
89 exec_macho_print_segment_command(ls)
90 struct exec_macho_segment_command *ls;
91 {
92 printf("ls.cmd 0x%lx\n", ls->cmd);
93 printf("ls.cmdsize 0x%ld\n", ls->cmdsize);
94 printf("ls.segname %s\n", ls->segname);
95 printf("ls.vmaddr 0x%lx\n", ls->vmaddr);
96 printf("ls.vmsize %ld\n", ls->vmsize);
97 printf("ls.fileoff 0x%lx\n", ls->fileoff);
98 printf("ls.filesize %ld\n", ls->filesize);
99 printf("ls.maxprot 0x%x\n", ls->maxprot);
100 printf("ls.initprot 0x%x\n", ls->initprot);
101 printf("ls.nsects %ld\n", ls->nsects);
102 printf("ls.flags 0x%lx\n", ls->flags);
103 }
104
105 static void
106 exec_macho_print_fat_header(fat)
107 struct exec_macho_fat_header *fat;
108 {
109 printf("fat.magic 0x%x\n", be32toh(fat->magic));
110 printf("fat.nfat_arch %d\n", be32toh(fat->nfat_arch));
111 }
112
113 static void
114 exec_macho_print_fat_arch(arch)
115 struct exec_macho_fat_arch *arch;
116 {
117 printf("arch.cputype %x\n", be32toh(arch->cputype));
118 printf("arch.cpusubtype %d\n", be32toh(arch->cpusubtype));
119 printf("arch.offset 0x%x\n", (int32_t)be32toh(arch->offset));
120 printf("arch.size %d\n", (int32_t)be32toh(arch->size));
121 printf("arch.align 0x%x\n", (int32_t)be32toh(arch->align));
122 }
123
124 static void
125 exec_macho_print_object_header(hdr)
126 struct exec_macho_object_header *hdr;
127 {
128 printf("hdr.magic 0x%lx\n", hdr->magic);
129 printf("hdr.cputype %x\n", hdr->cputype);
130 printf("hdr.cpusubtype %d\n", hdr->cpusubtype);
131 printf("hdr.filetype 0x%lx\n", hdr->filetype);
132 printf("hdr.ncmds %ld\n", hdr->ncmds);
133 printf("hdr.sizeofcmds %ld\n", hdr->sizeofcmds);
134 printf("hdr.flags 0x%lx\n", hdr->flags);
135 }
136
137 static void
138 exec_macho_print_load_command(lc)
139 struct exec_macho_load_command *lc;
140 {
141 printf("lc.cmd %lx\n", lc->cmd);
142 printf("lc.cmdsize %ld\n", lc->cmdsize);
143 }
144
145 static void
146 exec_macho_print_dylinker_command(dy)
147 struct exec_macho_dylinker_command *dy;
148 {
149 printf("dy.cmd %lx\n", dy->cmd);
150 printf("dy.cmdsize %ld\n", dy->cmdsize);
151 printf("dy.name.offset 0x%lx\n", dy->name.offset);
152 printf("dy.name %s\n", ((char *)dy) + dy->name.offset);
153 }
154
155 static void
156 exec_macho_print_dylib_command(dy)
157 struct exec_macho_dylib_command *dy;
158 {
159 printf("dy.cmd %lx\n", dy->cmd);
160 printf("dy.cmdsize %ld\n", dy->cmdsize);
161 printf("dy.dylib.name.offset 0x%lx\n", dy->dylib.name.offset);
162 printf("dy.dylib.name %s\n", ((char *)dy) + dy->dylib.name.offset);
163 printf("dy.dylib.timestamp %ld\n", dy->dylib.timestamp);
164 printf("dy.dylib.current_version %ld\n", dy->dylib.current_version);
165 printf("dy.dylib.compatibility_version %ld\n",
166 dy->dylib.compatibility_version);
167 }
168
169 static void
170 exec_macho_print_thread_command(th)
171 struct exec_macho_thread_command *th;
172 {
173 printf("th.cmd %lx\n", th->cmd);
174 printf("th.cmdsize %ld\n", th->cmdsize);
175 printf("th.flavor %ld\n", th->flavor);
176 printf("th.count %ld\n", th->count);
177 }
178 #endif /* DEBUG_MACHO */
179
180 static int
181 exec_macho_load_segment(epp, vp, foff, ls, type)
182 struct exec_package *epp;
183 struct vnode *vp;
184 u_long foff;
185 struct exec_macho_segment_command *ls;
186 int type;
187 {
188 int flags;
189 struct exec_macho_emul_arg *emea;
190 u_long addr = trunc_page(ls->vmaddr), size = round_page(ls->filesize);
191
192 emea = (struct exec_macho_emul_arg *)epp->ep_emul_arg;
193
194 flags = VMCMD_BASE;
195
196 #ifdef DEBUG_MACHO
197 exec_macho_print_segment_command(ls);
198 #endif
199 if (strcmp(ls->segname, "__PAGEZERO") == 0)
200 return 0;
201
202 if (strcmp(ls->segname, "__TEXT") != 0 &&
203 strcmp(ls->segname, "__DATA") != 0 &&
204 strcmp(ls->segname, "__LOCK") != 0 &&
205 strcmp(ls->segname, "__OBJC") != 0 &&
206 strcmp(ls->segname, "__CGSERVER") != 0 &&
207 strcmp(ls->segname, "__IMAGE") != 0 &&
208 strcmp(ls->segname, "__LINKEDIT") != 0) {
209 DPRINTF(("Unknown exec_macho segment %s\n", ls->segname));
210 return ENOEXEC;
211 }
212 if (type == MACHO_MOH_EXECUTE) {
213 if (strcmp(ls->segname, "__TEXT") == 0) {
214 epp->ep_taddr = addr;
215 epp->ep_tsize = round_page(ls->vmsize);
216 emea->macho_hdr =
217 (struct exec_macho_object_header *)addr;
218 }
219 if ((strcmp(ls->segname, "__DATA") == 0) ||
220 (strcmp(ls->segname, "__OBJC") == 0) ||
221 (strcmp(ls->segname, "__IMAGE") == 0) ||
222 (strcmp(ls->segname, "__CGSERVER") == 0)) {
223 epp->ep_daddr = addr;
224 epp->ep_dsize = round_page(ls->vmsize);
225 }
226 }
227
228 /*
229 * Some libraries do not have a load base address. The Darwin
230 * kernel seems to skip them, and dyld will do the job.
231 */
232 if (addr == 0)
233 return ENOMEM;
234
235 if (ls->filesize > 0) {
236 NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_pagedvn, size,
237 addr, vp, (off_t)(ls->fileoff + foff),
238 ls->initprot, flags);
239 DPRINTF(("map(0x%lx, 0x%lx, %o, fd@ 0x%lx)\n",
240 addr, size, ls->initprot,
241 ls->fileoff + foff));
242 }
243
244 if (ls->vmsize > size) {
245 addr += size;
246 size = round_page(ls->vmsize - size);
247 NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, size,
248 addr, vp, (off_t)(ls->fileoff + foff),
249 ls->initprot, flags);
250 DPRINTF(("mmap(0x%lx, 0x%lx, %o, zero)\n",
251 ls->vmaddr + ls->filesize, ls->vmsize - ls->filesize,
252 ls->initprot));
253 }
254 return 0;
255 }
256
257
258 static int
259 exec_macho_load_dylinker(p, epp, dy, entry, depth)
260 struct proc *p;
261 struct exec_package *epp;
262 struct exec_macho_dylinker_command *dy;
263 u_long *entry;
264 int depth;
265 {
266 struct exec_macho_emul_arg *emea;
267 const char *name = ((const char *)dy) + dy->name.offset;
268 char path[MAXPATHLEN];
269 int error;
270 #ifdef DEBUG_MACHO
271 exec_macho_print_dylinker_command(dy);
272 #endif
273 emea = (struct exec_macho_emul_arg *)epp->ep_emul_arg;
274
275 (void)snprintf(path, sizeof(path), "%s%s", emea->path, name);
276 DPRINTF(("loading linker %s\n", path));
277 if ((error = exec_macho_load_file(p, epp, path, entry,
278 MACHO_MOH_DYLINKER, 1, depth)) != 0)
279 return error;
280 return 0;
281 }
282
283 static int
284 exec_macho_load_dylib(p, epp, dy, depth)
285 struct proc *p;
286 struct exec_package *epp;
287 struct exec_macho_dylib_command *dy;
288 int depth;
289 {
290 struct exec_macho_emul_arg *emea;
291 const char *name = ((const char *)dy) + dy->dylib.name.offset;
292 char path[MAXPATHLEN];
293 int error;
294 u_long entry;
295 #ifdef DEBUG_MACHO
296 exec_macho_print_dylib_command(dy);
297 #endif
298 emea = (struct exec_macho_emul_arg *)epp->ep_emul_arg;
299 (void)snprintf(path, sizeof(path), "%s%s", emea->path, name);
300 DPRINTF(("loading library %s\n", path));
301 if ((error = exec_macho_load_file(p, epp, path, &entry,
302 MACHO_MOH_DYLIB, 0, depth)) != 0)
303 return error;
304 return 0;
305 }
306
307 static u_long
308 exec_macho_load_thread(th)
309 struct exec_macho_thread_command *th;
310 {
311 #ifdef DEBUG_MACHO
312 exec_macho_print_thread_command(th);
313 #endif
314 return exec_macho_thread_entry(th);
315 }
316
317 /*
318 * exec_macho_load_file(): Load a macho-binary. This is used
319 * for the dynamic linker and library recursive loading.
320 */
321 static int
322 exec_macho_load_file(p, epp, path, entry, type, recursive, depth)
323 struct proc *p;
324 struct exec_package *epp;
325 const char *path;
326 u_long *entry;
327 int type;
328 int recursive;
329 int depth;
330 {
331 int error;
332 struct nameidata nd;
333 struct vnode *vp;
334 struct vattr attr;
335 struct exec_macho_fat_header fat;
336
337 /*
338 * Check for excessive rercursive loading
339 */
340 if (depth++ > 6)
341 return E2BIG;
342
343 /*
344 * 1. open file
345 * 2. read filehdr
346 * 3. map text, data, and bss out of it using VM_*
347 */
348 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p);
349 if ((error = namei(&nd)) != 0)
350 return error;
351 vp = nd.ni_vp;
352
353 /*
354 * Similarly, if it's not marked as executable, or it's not a regular
355 * file, we don't allow it to be used.
356 */
357 if (vp->v_type != VREG) {
358 error = EACCES;
359 goto badunlock;
360 }
361
362 error = vn_marktext(vp);
363 if (error)
364 return (error);
365
366 if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) != 0)
367 goto badunlock;
368
369 /* get attributes */
370 if ((error = VOP_GETATTR(vp, &attr, p->p_ucred, p)) != 0)
371 goto badunlock;
372
373 #ifdef notyet /* XXX cgd 960926 */
374 XXX cgd 960926: (maybe) VOP_OPEN it (and VOP_CLOSE in copyargs?)
375 #endif
376 VOP_UNLOCK(vp, 0);
377
378 if ((error = exec_read_from(p, vp, 0, &fat, sizeof(fat))) != 0)
379 goto bad;
380
381 if ((error = exec_macho_load_vnode(p, epp, vp, &fat,
382 entry, type, recursive, depth)) != 0)
383 goto bad;
384
385 vrele(vp);
386 return 0;
387
388 badunlock:
389 VOP_UNLOCK(vp, 0);
390
391 bad:
392 #ifdef notyet /* XXX cgd 960926 */
393 (maybe) VOP_CLOSE it
394 #endif
395 vrele(vp);
396 return error;
397 }
398
399 /*
400 * exec_macho_load_vnode(): Map a file from the given vnode.
401 * The fat signature is checked,
402 * and it will return the address of the entry point in entry.
403 * The type determines what we are loading, a dynamic linker,
404 * a dynamic library, or a binary. We use that to guess at
405 * the entry point.
406 */
407 static int
408 exec_macho_load_vnode(p, epp, vp, fat, entry, type, recursive, depth)
409 struct proc *p;
410 struct exec_package *epp;
411 struct vnode *vp;
412 struct exec_macho_fat_header *fat;
413 u_long *entry;
414 int type;
415 {
416 u_long aoffs, offs;
417 struct exec_macho_fat_arch arch;
418 struct exec_macho_object_header hdr;
419 struct exec_macho_load_command lc;
420 struct exec_macho_emul_arg *emea;
421 int error = ENOEXEC, i;
422 size_t size;
423 void *buf = &lc;
424 u_int32_t *sc = NULL;
425
426 #ifdef DEBUG_MACHO
427 exec_macho_print_fat_header(fat);
428 #endif
429
430 switch(be32toh(fat->magic)){
431 case MACHO_FAT_MAGIC:
432 for (i = 0; i < be32toh(fat->nfat_arch); i++, arch) {
433 if ((error = exec_read_from(p, vp, sizeof(*fat) +
434 sizeof(arch) * i, &arch, sizeof(arch))) != 0)
435 goto bad;
436 #ifdef DEBUG_MACHO
437 exec_macho_print_fat_arch(&arch);
438 #endif
439 for (sc = exec_macho_supported_cpu; *sc; sc++)
440 if (*sc == be32toh(arch.cputype))
441 break;
442
443 if (sc != NULL)
444 break;
445 }
446 if (sc == NULL || *sc == 0) {
447 DPRINTF(("CPU %d not supported by this binary",
448 be32toh(arch.cputype)));
449 goto bad;
450 }
451 break;
452
453 case MACHO_MOH_MAGIC:
454 /*
455 * This is not a FAT Mach-O binary, the file starts
456 * with the object header.
457 */
458 arch.offset = 0;
459 break;
460
461 default:
462 DPRINTF(("bad exec_macho magic %x\n", fat->magic));
463 goto bad;
464 break;
465 }
466
467 if ((error = exec_read_from(p, vp, be32toh(arch.offset), &hdr,
468 sizeof(hdr))) != 0)
469 goto bad;
470
471 if (hdr.magic != MACHO_MOH_MAGIC) {
472 DPRINTF(("bad exec_macho header magic %lx\n", hdr.magic));
473 goto bad;
474 }
475
476 #ifdef DEBUG_MACHO
477 exec_macho_print_object_header(&hdr);
478 #endif
479 switch (hdr.filetype) {
480 case MACHO_MOH_PRELOAD:
481 case MACHO_MOH_EXECUTE:
482 case MACHO_MOH_DYLINKER:
483 case MACHO_MOH_DYLIB:
484 case MACHO_MOH_BUNDLE:
485 break;
486 default:
487 DPRINTF(("Unsupported exec_macho filetype 0x%lx\n",
488 hdr.filetype));
489 goto bad;
490 }
491
492
493 aoffs = be32toh(arch.offset);
494 offs = aoffs + sizeof(hdr);
495 size = sizeof(lc);
496 for (i = 0; i < hdr.ncmds; i++) {
497 if ((error = exec_read_from(p, vp, offs, &lc, sizeof(lc))) != 0)
498 goto bad;
499
500 #ifdef DEBUG_MACHO
501 exec_macho_print_load_command(&lc);
502 #endif
503 if (size < lc.cmdsize) {
504 if (lc.cmdsize > 4096) {
505 DPRINTF(("Bad command size %ld\n", lc.cmdsize));
506 goto bad;
507 }
508 if (buf != &lc)
509 free(buf, M_TEMP);
510 buf = malloc(size = lc.cmdsize, M_TEMP, M_WAITOK);
511 }
512
513 if ((error = exec_read_from(p, vp, offs, buf, lc.cmdsize)) != 0)
514 goto bad;
515
516 switch (lc.cmd) {
517 case MACHO_LC_SEGMENT:
518 error = exec_macho_load_segment(epp, vp, aoffs,
519 (struct exec_macho_segment_command *)buf, type);
520
521 switch(error) {
522 case ENOMEM: /* Just skip, dyld will load it */
523 DPRINTF(("load segment failed, skipping\n"));
524 i = hdr.ncmds;
525 break;
526 case 0: /* No error, carry on loading file */
527 break;
528 default: /* Abort file load */
529 DPRINTF(("load segment failed, aborting\n"));
530 goto bad;
531 break;
532 }
533 break;
534 case MACHO_LC_LOAD_DYLINKER:
535 if ((error = exec_macho_load_dylinker(p, epp,
536 (struct exec_macho_dylinker_command *)buf,
537 entry, depth)) != 0) {
538 DPRINTF(("load linker failed\n"));
539 goto bad;
540 }
541 emea = (struct exec_macho_emul_arg *)epp->ep_emul_arg;
542 emea->dynamic = 1;
543 break;
544 case MACHO_LC_LOAD_DYLIB:
545 /*
546 * We should only load libraries required by the
547 * binary we want to load, not libraries required
548 * by theses libraries.
549 */
550 if (recursive == 0)
551 break;
552 if ((error = exec_macho_load_dylib(p, epp,
553 (struct exec_macho_dylib_command *)buf,
554 depth)) != 0) {
555 DPRINTF(("load dylib failed\n"));
556 goto bad;
557 }
558 break;
559
560 case MACHO_LC_THREAD:
561 case MACHO_LC_UNIXTHREAD:
562 if (type == MACHO_MOH_DYLINKER || *entry == 0) {
563 *entry = exec_macho_load_thread(
564 (struct exec_macho_thread_command *)buf);
565 } else {
566 (void)exec_macho_load_thread(
567 (struct exec_macho_thread_command *)buf);
568 }
569 break;
570
571 case MACHO_LC_ID_DYLINKER:
572 case MACHO_LC_ID_DYLIB:
573 case MACHO_LC_SYMTAB:
574 case MACHO_LC_DYSYMTAB:
575 break;
576 default:
577 DPRINTF(("Unhandled exec_macho command 0x%lx\n",
578 lc.cmd));
579 break;
580 }
581 offs += lc.cmdsize;
582 }
583 error = 0;
584 bad:
585 if (buf != &lc)
586 free(buf, M_TEMP);
587 return error;
588 }
589
590 /*
591 * exec_macho_makecmds(): Prepare an Mach-O binary's exec package
592 *
593 * First, set of the various offsets/lengths in the exec package.
594 *
595 * Then, mark the text image busy (so it can be demand paged) or error
596 * out if this is not possible. Finally, set up vmcmds for the
597 * text, data, bss, and stack segments.
598 */
599 int
600 exec_macho_makecmds(p, epp)
601 struct proc *p;
602 struct exec_package *epp;
603 {
604 struct exec_macho_fat_header *fat = epp->ep_hdr;
605 struct exec_macho_emul_arg *emea;
606 int error;
607
608 if (epp->ep_hdrvalid < sizeof(*fat))
609 return ENOEXEC;
610
611 /*
612 * Check mount point. Though we're not trying to exec this binary,
613 * we will be executing code from it, so if the mount point
614 * disallows execution or set-id-ness, we punt or kill the set-id.
615 */
616 if (epp->ep_vp->v_mount->mnt_flag & MNT_NOEXEC)
617 return EACCES;
618
619 if (epp->ep_vp->v_mount->mnt_flag & MNT_NOSUID)
620 epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
621
622 error = vn_marktext(epp->ep_vp);
623 if (error)
624 return (error);
625
626 emea = malloc(sizeof(struct exec_macho_emul_arg), M_EXEC, M_WAITOK);
627 epp->ep_emul_arg = (void *)emea;
628 emea->dynamic = 0;
629
630 if (!epp->ep_esch->u.mach_probe_func)
631 emea->path = "/";
632 else {
633 if ((error = (*epp->ep_esch->u.mach_probe_func)((char **)
634 &emea->path)) != 0)
635 goto bad2;
636 }
637
638 /*
639 * Make sure the underlying functions will not get
640 * a random value here. 0 means that no entry point
641 * has been found yet.
642 */
643 epp->ep_entry = 0;
644
645 if ((error = exec_macho_load_vnode(p, epp, epp->ep_vp, fat,
646 &epp->ep_entry, MACHO_MOH_EXECUTE, 1, 0)) != 0)
647 goto bad;
648
649 /*
650 * stash a copy of the program name in epp->ep_emul_arg because
651 * we will need it later.
652 */
653 if ((error = copyinstr(epp->ep_name, emea->filename,
654 MAXPATHLEN, NULL)) != 0) {
655 DPRINTF(("Copyinstr %p failed\n", epp->ep_name));
656 goto bad;
657 }
658
659 return (*epp->ep_esch->es_setup_stack)(p, epp);
660 bad:
661 kill_vmcmds(&epp->ep_vmcmds);
662 bad2:
663 free(emea, M_EXEC);
664 return error;
665 }
Cache object: 57ee5f43f7cb0cf94014f0bf1ce36b91
|