Support Darwin static binaries (I should say: support the only Darwin

static binary: otool). Dynamic binaires have a pointer to the Mach-O
header on the top of the stack, static binaries don't have this, and
having it produced a crash.

One bugfix: the EXEC_MACHO code assumes that entry = NULL means that
the entry point has not been found in the load commands seen so far.
Therefore we need to initialized entry to NULL if we want a static binary
to discover it. (dynamic binaries were forced to iscover it because when
the intepreter load command is found, entry is updated whatever its
value was before).

One hack: Both COMPAT_MACH and COMPAT_DARWIN are willing to run Mach-O
binaries. COMPAT_MACH fails for dynamic binaries because it cannot find
the interpreter in /emul/mach. For static binaires, it will accept them
(and for Darwin static binaries, this will cause a failure). Until we
rite a test for matchinf Darwin static binaries, just swap the order of
COMPAT_MACH and COMPAT_DARWIN in the exec switch so that COMPAT_DARWIN
is tried first (this will have the advantage of speeding up program
startup). EXECSW_PRIO_{FIRST_LAST} does not seem to work...
This commit is contained in:
manu 2003-10-19 07:52:22 +00:00
parent 175f717bf5
commit d77ec799a5
4 changed files with 41 additions and 25 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: darwin_exec.c,v 1.20 2003/09/30 19:49:00 manu Exp $ */
/* $NetBSD: darwin_exec.c,v 1.21 2003/10/19 07:52:22 manu Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
#include "opt_compat_darwin.h" /* For COMPAT_DARWIN in mach_port.h */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: darwin_exec.c,v 1.20 2003/09/30 19:49:00 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: darwin_exec.c,v 1.21 2003/10/19 07:52:22 manu Exp $");
#include "opt_syscall_debug.h"
@ -154,10 +154,14 @@ exec_darwin_copyargs(p, pack, arginfo, stackp, argp)
*stackp = (char *)(((unsigned long)*stackp - 1) & ~0xfUL);
emea = (struct exec_macho_emul_arg *)pack->ep_emul_arg;
macho_hdr = (struct exec_macho_object_header *)emea->macho_hdr;
if ((error = copyout(&macho_hdr, *stackp, sizeof(macho_hdr))) != 0)
return error;
*stackp += sizeof(macho_hdr);
if (emea->dynamic == 1) {
macho_hdr = (struct exec_macho_object_header *)emea->macho_hdr;
error = copyout(&macho_hdr, *stackp, sizeof(macho_hdr));
if (error != 0)
return error;
*stackp += sizeof(macho_hdr);
}
cpp = (char **)*stackp;
argc = arginfo->ps_nargvstr;

View File

@ -1,4 +1,4 @@
/* $NetBSD: exec_conf.c,v 1.83 2003/08/08 18:53:13 christos Exp $ */
/* $NetBSD: exec_conf.c,v 1.84 2003/10/19 07:52:22 manu Exp $ */
/*
* Copyright (c) 1993, 1994 Christopher G. Demetriou
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exec_conf.c,v 1.83 2003/08/08 18:53:13 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: exec_conf.c,v 1.84 2003/10/19 07:52:22 manu Exp $");
#include "opt_execfmt.h"
#include "opt_compat_freebsd.h"
@ -507,20 +507,6 @@ const struct execsw execsw_builtin[] = {
#endif /* EXEC_ELF64 */
#if defined(EXEC_MACHO)
#ifdef COMPAT_MACH
/* Mach MACH-O (native word size) */
{ sizeof (struct exec_macho_fat_header),
exec_macho_makecmds,
{ .mach_probe_func = exec_mach_probe },
&emul_mach,
EXECSW_PRIO_ANY,
MAXPATHLEN + 1,
exec_mach_copyargs,
NULL,
coredump_netbsd,
exec_setup_stack },
#endif
#ifdef COMPAT_DARWIN
/* Darwin Mach-O (native word size) */
{ sizeof (struct exec_macho_fat_header),
@ -534,6 +520,20 @@ const struct execsw execsw_builtin[] = {
coredump_netbsd,
exec_setup_stack },
#endif
#ifdef COMPAT_MACH
/* Mach MACH-O (native word size) */
{ sizeof (struct exec_macho_fat_header),
exec_macho_makecmds,
{ .mach_probe_func = exec_mach_probe },
&emul_mach,
EXECSW_PRIO_ANY,
MAXPATHLEN + 1,
exec_mach_copyargs,
NULL,
coredump_netbsd,
exec_setup_stack },
#endif
#endif /* EXEC_MACHO */
#ifdef COMPAT_SUNOS

View File

@ -1,4 +1,4 @@
/* $NetBSD: exec_macho.c,v 1.27 2003/09/07 11:16:59 manu Exp $ */
/* $NetBSD: exec_macho.c,v 1.28 2003/10/19 07:52:22 manu Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exec_macho.c,v 1.27 2003/09/07 11:16:59 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: exec_macho.c,v 1.28 2003/10/19 07:52:22 manu Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@ -421,6 +421,7 @@ exec_macho_load_vnode(p, epp, vp, fat, entry, type, recursive, depth)
struct exec_macho_fat_arch arch;
struct exec_macho_object_header hdr;
struct exec_macho_load_command lc;
struct exec_macho_emul_arg *emea;
int error = ENOEXEC, i;
size_t size;
void *buf = &lc;
@ -540,6 +541,8 @@ exec_macho_load_vnode(p, epp, vp, fat, entry, type, recursive, depth)
DPRINTF(("load linker failed\n"));
goto bad;
}
emea = (struct exec_macho_emul_arg *)epp->ep_emul_arg;
emea->dynamic = 1;
break;
case MACHO_LC_LOAD_DYLIB:
/*
@ -625,6 +628,7 @@ exec_macho_makecmds(p, epp)
emea = malloc(sizeof(struct exec_macho_emul_arg), M_EXEC, M_WAITOK);
epp->ep_emul_arg = (void *)emea;
emea->dynamic = 0;
if (!epp->ep_esch->u.mach_probe_func)
emea->path = "/";
@ -633,6 +637,13 @@ exec_macho_makecmds(p, epp)
&emea->path)) != 0)
goto bad2;
}
/*
* Make sure the underlying functions will not get
* a random value here. 0 means that no entry point
* has been found yet.
*/
epp->ep_entry = 0;
if ((error = exec_macho_load_vnode(p, epp, epp->ep_vp, fat,
&epp->ep_entry, MACHO_MOH_EXECUTE, 1, 0)) != 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: exec_macho.h,v 1.13 2003/08/08 18:54:16 christos Exp $ */
/* $NetBSD: exec_macho.h,v 1.14 2003/10/19 07:52:22 manu Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -246,6 +246,7 @@ struct exec_macho_emul_arg {
char *path;
char filename[MAXPATHLEN];
struct exec_macho_object_header *macho_hdr;
int dynamic;
};
#ifndef _LKM