1 /* $NetBSD: exec_macho.c,v 1.41 2008/01/03 14:25:50 yamt Exp $ */
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: exec_macho.c,v 1.41 2008/01/03 14:25:50 yamt Exp $");
35 #include <sys/param.h>
37 #include <sys/malloc.h>
38 #include <sys/namei.h>
39 #include <sys/vnode.h>
41 #include <sys/exec_macho.h>
42 #include <sys/syscall.h>
43 #include <sys/signalvar.h>
44 #include <sys/resourcevar.h>
45 #include <sys/mount.h>
51 #define DPRINTF(a) printf a
56 static int exec_macho_load_segment(struct exec_package
*, struct vnode
*,
57 u_long
, struct exec_macho_segment_command
*, int);
58 static int exec_macho_load_dylinker(struct lwp
*, struct exec_package
*,
59 struct exec_macho_dylinker_command
*, u_long
*, int);
60 static int exec_macho_load_dylib(struct lwp
*, struct exec_package
*,
61 struct exec_macho_dylib_command
*, int);
62 static u_long
exec_macho_load_thread(struct exec_macho_thread_command
*);
63 static int exec_macho_load_file(struct lwp
*, struct exec_package
*,
64 const char *, u_long
*, int, int, int);
65 static int exec_macho_load_vnode(struct lwp
*, struct exec_package
*,
66 struct vnode
*, struct exec_macho_fat_header
*, u_long
*, int, int, int);
70 exec_macho_print_segment_command(struct exec_macho_segment_command
*ls
)
72 printf("ls.cmd 0x%lx\n", ls
->cmd
);
73 printf("ls.cmdsize 0x%ld\n", ls
->cmdsize
);
74 printf("ls.segname %s\n", ls
->segname
);
75 printf("ls.vmaddr 0x%lx\n", ls
->vmaddr
);
76 printf("ls.vmsize %ld\n", ls
->vmsize
);
77 printf("ls.fileoff 0x%lx\n", ls
->fileoff
);
78 printf("ls.filesize %ld\n", ls
->filesize
);
79 printf("ls.maxprot 0x%x\n", ls
->maxprot
);
80 printf("ls.initprot 0x%x\n", ls
->initprot
);
81 printf("ls.nsects %ld\n", ls
->nsects
);
82 printf("ls.flags 0x%lx\n", ls
->flags
);
86 exec_macho_print_fat_header(struct exec_macho_fat_header
*fat
)
88 printf("fat.magic 0x%x\n", be32toh(fat
->magic
));
89 printf("fat.nfat_arch %d\n", be32toh(fat
->nfat_arch
));
93 exec_macho_print_fat_arch(struct exec_macho_fat_arch
*arch
)
95 printf("arch.cputype %x\n", be32toh(arch
->cputype
));
96 printf("arch.cpusubtype %d\n", be32toh(arch
->cpusubtype
));
97 printf("arch.offset 0x%x\n", (int32_t)be32toh(arch
->offset
));
98 printf("arch.size %d\n", (int32_t)be32toh(arch
->size
));
99 printf("arch.align 0x%x\n", (int32_t)be32toh(arch
->align
));
103 exec_macho_print_object_header(struct exec_macho_object_header
*hdr
)
105 printf("hdr.magic 0x%lx\n", hdr
->magic
);
106 printf("hdr.cputype %x\n", hdr
->cputype
);
107 printf("hdr.cpusubtype %d\n", hdr
->cpusubtype
);
108 printf("hdr.filetype 0x%lx\n", hdr
->filetype
);
109 printf("hdr.ncmds %ld\n", hdr
->ncmds
);
110 printf("hdr.sizeofcmds %ld\n", hdr
->sizeofcmds
);
111 printf("hdr.flags 0x%lx\n", hdr
->flags
);
115 exec_macho_print_load_command(struct exec_macho_load_command
*lc
)
117 printf("lc.cmd %lx\n", lc
->cmd
);
118 printf("lc.cmdsize %ld\n", lc
->cmdsize
);
122 exec_macho_print_dylinker_command(struct exec_macho_dylinker_command
*dy
)
124 printf("dy.cmd %lx\n", dy
->cmd
);
125 printf("dy.cmdsize %ld\n", dy
->cmdsize
);
126 printf("dy.name.offset 0x%lx\n", dy
->name
.offset
);
127 printf("dy.name %s\n", ((char *)dy
) + dy
->name
.offset
);
131 exec_macho_print_dylib_command(struct exec_macho_dylib_command
*dy
)
133 printf("dy.cmd %lx\n", dy
->cmd
);
134 printf("dy.cmdsize %ld\n", dy
->cmdsize
);
135 printf("dy.dylib.name.offset 0x%lx\n", dy
->dylib
.name
.offset
);
136 printf("dy.dylib.name %s\n", ((char *)dy
) + dy
->dylib
.name
.offset
);
137 printf("dy.dylib.timestamp %ld\n", dy
->dylib
.timestamp
);
138 printf("dy.dylib.current_version %ld\n", dy
->dylib
.current_version
);
139 printf("dy.dylib.compatibility_version %ld\n",
140 dy
->dylib
.compatibility_version
);
144 exec_macho_print_thread_command(struct exec_macho_thread_command
*th
)
146 printf("th.cmd %lx\n", th
->cmd
);
147 printf("th.cmdsize %ld\n", th
->cmdsize
);
148 printf("th.flavor %ld\n", th
->flavor
);
149 printf("th.count %ld\n", th
->count
);
151 #endif /* DEBUG_MACHO */
154 exec_macho_load_segment(struct exec_package
*epp
, struct vnode
*vp
,
155 u_long foff
, struct exec_macho_segment_command
*ls
, int type
)
158 struct exec_macho_emul_arg
*emea
;
159 u_long addr
= trunc_page(ls
->vmaddr
), size
= round_page(ls
->filesize
);
161 emea
= (struct exec_macho_emul_arg
*)epp
->ep_emul_arg
;
166 exec_macho_print_segment_command(ls
);
168 if (strcmp(ls
->segname
, "__PAGEZERO") == 0)
171 if (strcmp(ls
->segname
, "__TEXT") != 0 &&
172 strcmp(ls
->segname
, "__DATA") != 0 &&
173 strcmp(ls
->segname
, "__LOCK") != 0 &&
174 strcmp(ls
->segname
, "__OBJC") != 0 &&
175 strcmp(ls
->segname
, "__CGSERVER") != 0 &&
176 strcmp(ls
->segname
, "__IMAGE") != 0 &&
177 strcmp(ls
->segname
, "__LINKEDIT") != 0) {
178 DPRINTF(("Unknown exec_macho segment %s\n", ls
->segname
));
181 if (type
== MACHO_MOH_EXECUTE
) {
182 if (strcmp(ls
->segname
, "__TEXT") == 0) {
183 epp
->ep_taddr
= addr
;
184 epp
->ep_tsize
= round_page(ls
->vmsize
);
186 (struct exec_macho_object_header
*)addr
;
188 if ((strcmp(ls
->segname
, "__DATA") == 0) ||
189 (strcmp(ls
->segname
, "__OBJC") == 0) ||
190 (strcmp(ls
->segname
, "__IMAGE") == 0) ||
191 (strcmp(ls
->segname
, "__CGSERVER") == 0)) {
192 epp
->ep_daddr
= addr
;
193 epp
->ep_dsize
= round_page(ls
->vmsize
);
198 * Some libraries do not have a load base address. The Darwin
199 * kernel seems to skip them, and dyld will do the job.
204 if (ls
->filesize
> 0) {
205 NEW_VMCMD2(&epp
->ep_vmcmds
, vmcmd_map_pagedvn
, size
,
206 addr
, vp
, (off_t
)(ls
->fileoff
+ foff
),
207 ls
->initprot
, flags
);
208 DPRINTF(("map(0x%lx, 0x%lx, %o, fd@ 0x%lx)\n",
209 addr
, size
, ls
->initprot
,
210 ls
->fileoff
+ foff
));
213 if (ls
->vmsize
> size
) {
215 size
= round_page(ls
->vmsize
- size
);
216 NEW_VMCMD2(&epp
->ep_vmcmds
, vmcmd_map_zero
, size
,
217 addr
, vp
, (off_t
)(ls
->fileoff
+ foff
),
218 ls
->initprot
, flags
);
219 DPRINTF(("mmap(0x%lx, 0x%lx, %o, zero)\n",
220 ls
->vmaddr
+ ls
->filesize
, ls
->vmsize
- ls
->filesize
,
228 exec_macho_load_dylinker(struct lwp
*l
, struct exec_package
*epp
,
229 struct exec_macho_dylinker_command
*dy
, u_long
*entry
, int depth
)
231 struct exec_macho_emul_arg
*emea
;
232 const char *name
= ((const char *)dy
) + dy
->name
.offset
;
233 char path
[MAXPATHLEN
];
236 exec_macho_print_dylinker_command(dy
);
238 emea
= (struct exec_macho_emul_arg
*)epp
->ep_emul_arg
;
240 (void)snprintf(path
, sizeof(path
), "%s%s", emea
->path
, name
);
241 DPRINTF(("loading linker %s\n", path
));
242 if ((error
= exec_macho_load_file(l
, epp
, path
, entry
,
243 MACHO_MOH_DYLINKER
, 1, depth
)) != 0)
249 exec_macho_load_dylib(struct lwp
*l
, struct exec_package
*epp
,
250 struct exec_macho_dylib_command
*dy
, int depth
)
252 struct exec_macho_emul_arg
*emea
;
253 const char *name
= ((const char *)dy
) + dy
->dylib
.name
.offset
;
254 char path
[MAXPATHLEN
];
258 exec_macho_print_dylib_command(dy
);
260 emea
= (struct exec_macho_emul_arg
*)epp
->ep_emul_arg
;
261 (void)snprintf(path
, sizeof(path
), "%s%s", emea
->path
, name
);
262 DPRINTF(("loading library %s\n", path
));
263 if ((error
= exec_macho_load_file(l
, epp
, path
, &entry
,
264 MACHO_MOH_DYLIB
, 0, depth
)) != 0)
270 exec_macho_load_thread(struct exec_macho_thread_command
*th
)
273 exec_macho_print_thread_command(th
);
275 return exec_macho_thread_entry(th
);
279 * exec_macho_load_file(): Load a macho-binary. This is used
280 * for the dynamic linker and library recursive loading.
283 exec_macho_load_file(struct lwp
*l
, struct exec_package
*epp
,
284 const char *path
, u_long
*entry
, int type
, int recursive
, int depth
)
290 struct exec_macho_fat_header fat
;
293 * Check for excessive rercursive loading
301 * 3. map text, data, and bss out of it using VM_*
303 NDINIT(&nd
, LOOKUP
, FOLLOW
| LOCKLEAF
, UIO_SYSSPACE
, path
);
304 if ((error
= namei(&nd
)) != 0)
309 * Similarly, if it's not marked as executable, or it's not a regular
310 * file, we don't allow it to be used.
312 if (vp
->v_type
!= VREG
) {
317 error
= vn_marktext(vp
);
321 if ((error
= VOP_ACCESS(vp
, VEXEC
, l
->l_cred
)) != 0)
325 if ((error
= VOP_GETATTR(vp
, &attr
, l
->l_cred
)) != 0)
328 #ifdef notyet /* XXX cgd 960926 */
329 XXX cgd
960926: (maybe
) VOP_OPEN
it (and VOP_CLOSE in copyargs
?)
333 if ((error
= exec_read_from(l
, vp
, 0, &fat
, sizeof(fat
))) != 0)
336 if ((error
= exec_macho_load_vnode(l
, epp
, vp
, &fat
,
337 entry
, type
, recursive
, depth
)) != 0)
347 #ifdef notyet /* XXX cgd 960926 */
355 * exec_macho_load_vnode(): Map a file from the given vnode.
356 * The fat signature is checked,
357 * and it will return the address of the entry point in entry.
358 * The type determines what we are loading, a dynamic linker,
359 * a dynamic library, or a binary. We use that to guess at
363 exec_macho_load_vnode(struct lwp
*l
, struct exec_package
*epp
,
364 struct vnode
*vp
, struct exec_macho_fat_header
*fat
, u_long
*entry
,
365 int type
, int recursive
, int depth
)
368 struct exec_macho_fat_arch arch
;
369 struct exec_macho_object_header hdr
;
370 struct exec_macho_load_command lc
;
371 struct exec_macho_emul_arg
*emea
;
372 int error
= ENOEXEC
, i
;
378 exec_macho_print_fat_header(fat
);
381 switch (fat
->magic
) {
382 case MACHO_FAT_MAGIC
:
383 for (i
= 0; i
< be32toh(fat
->nfat_arch
); i
++, arch
) {
384 if ((error
= exec_read_from(l
, vp
, sizeof(*fat
) +
385 sizeof(arch
) * i
, &arch
, sizeof(arch
))) != 0)
388 exec_macho_print_fat_arch(&arch
);
390 for (sc
= exec_macho_supported_cpu
; *sc
; sc
++)
391 if (*sc
== be32toh(arch
.cputype
))
397 if (sc
== NULL
|| *sc
== 0) {
398 DPRINTF(("CPU %d not supported by this binary",
399 be32toh(arch
.cputype
)));
404 case MACHO_MOH_MAGIC
:
406 * This is not a FAT Mach-O binary, the file starts
407 * with the object header.
413 DPRINTF(("bad exec_macho magic %x\n", fat
->magic
));
418 if ((error
= exec_read_from(l
, vp
, be32toh(arch
.offset
), &hdr
,
422 if (hdr
.magic
!= MACHO_MOH_MAGIC
) {
423 DPRINTF(("bad exec_macho header magic %lx\n", hdr
.magic
));
428 exec_macho_print_object_header(&hdr
);
430 switch (hdr
.filetype
) {
431 case MACHO_MOH_PRELOAD
:
432 case MACHO_MOH_EXECUTE
:
433 case MACHO_MOH_DYLINKER
:
434 case MACHO_MOH_DYLIB
:
435 case MACHO_MOH_BUNDLE
:
438 DPRINTF(("Unsupported exec_macho filetype 0x%lx\n",
444 aoffs
= be32toh(arch
.offset
);
445 offs
= aoffs
+ sizeof(hdr
);
447 for (i
= 0; i
< hdr
.ncmds
; i
++) {
448 if ((error
= exec_read_from(l
, vp
, offs
, &lc
, sizeof(lc
))) != 0)
452 exec_macho_print_load_command(&lc
);
454 if (size
< lc
.cmdsize
) {
455 if (lc
.cmdsize
> 4096) {
456 DPRINTF(("Bad command size %ld\n", lc
.cmdsize
));
461 bf
= malloc(size
= lc
.cmdsize
, M_TEMP
, M_WAITOK
);
464 if ((error
= exec_read_from(l
, vp
, offs
, bf
, lc
.cmdsize
)) != 0)
468 case MACHO_LC_SEGMENT
:
469 error
= exec_macho_load_segment(epp
, vp
, aoffs
,
470 (struct exec_macho_segment_command
*)bf
, type
);
473 case ENOMEM
: /* Just skip, dyld will load it */
474 DPRINTF(("load segment failed, skipping\n"));
477 case 0: /* No error, carry on loading file */
479 default: /* Abort file load */
480 DPRINTF(("load segment failed, aborting\n"));
485 case MACHO_LC_LOAD_DYLINKER
:
486 if ((error
= exec_macho_load_dylinker(l
, epp
,
487 (struct exec_macho_dylinker_command
*)bf
,
488 entry
, depth
)) != 0) {
489 DPRINTF(("load linker failed\n"));
492 emea
= (struct exec_macho_emul_arg
*)epp
->ep_emul_arg
;
495 case MACHO_LC_LOAD_DYLIB
:
497 * We should only load libraries required by the
498 * binary we want to load, not libraries required
499 * by theses libraries.
503 if ((error
= exec_macho_load_dylib(l
, epp
,
504 (struct exec_macho_dylib_command
*)bf
,
506 DPRINTF(("load dylib failed\n"));
511 case MACHO_LC_THREAD
:
512 case MACHO_LC_UNIXTHREAD
:
513 if (type
== MACHO_MOH_DYLINKER
|| *entry
== 0) {
514 *entry
= exec_macho_load_thread(
515 (struct exec_macho_thread_command
*)bf
);
517 (void)exec_macho_load_thread(
518 (struct exec_macho_thread_command
*)bf
);
522 case MACHO_LC_ID_DYLINKER
:
523 case MACHO_LC_ID_DYLIB
:
524 case MACHO_LC_SYMTAB
:
525 case MACHO_LC_DYSYMTAB
:
528 DPRINTF(("Unhandled exec_macho command 0x%lx\n",
542 * exec_macho_makecmds(): Prepare an Mach-O binary's exec package
544 * First, set of the various offsets/lengths in the exec package.
546 * Then, mark the text image busy (so it can be demand paged) or error
547 * out if this is not possible. Finally, set up vmcmds for the
548 * text, data, bss, and stack segments.
551 exec_macho_makecmds(struct lwp
*l
, struct exec_package
*epp
)
553 struct exec_macho_fat_header
*fat
= epp
->ep_hdr
;
554 struct exec_macho_emul_arg
*emea
;
557 if (epp
->ep_hdrvalid
< sizeof(*fat
))
561 * Check mount point. Though we're not trying to exec this binary,
562 * we will be executing code from it, so if the mount point
563 * disallows execution or set-id-ness, we punt or kill the set-id.
565 if (epp
->ep_vp
->v_mount
->mnt_flag
& MNT_NOEXEC
)
568 if (epp
->ep_vp
->v_mount
->mnt_flag
& MNT_NOSUID
)
569 epp
->ep_vap
->va_mode
&= ~(S_ISUID
| S_ISGID
);
571 error
= vn_marktext(epp
->ep_vp
);
575 emea
= malloc(sizeof(struct exec_macho_emul_arg
), M_TEMP
, M_WAITOK
);
576 epp
->ep_emul_arg
= (void *)emea
;
579 if (!epp
->ep_esch
->u
.mach_probe_func
)
582 if ((error
= (*epp
->ep_esch
->u
.mach_probe_func
)(&emea
->path
)) != 0)
587 * Make sure the underlying functions will not get
588 * a random value here. 0 means that no entry point
589 * has been found yet.
593 if ((error
= exec_macho_load_vnode(l
, epp
, epp
->ep_vp
, fat
,
594 &epp
->ep_entry
, MACHO_MOH_EXECUTE
, 1, 0)) != 0)
598 * stash a copy of the program name in epp->ep_emul_arg because
599 * we will need it later.
601 if ((error
= copyinstr(epp
->ep_name
, emea
->filename
,
602 MAXPATHLEN
, NULL
)) != 0) {
603 DPRINTF(("Copyinstr %p failed\n", epp
->ep_name
));
607 return (*epp
->ep_esch
->es_setup_stack
)(l
, epp
);
609 kill_vmcmds(&epp
->ep_vmcmds
);