We now have the exact stack initial stack layout of Darwin:
macho_hdr, argc, *argv, NULL, *envp, NULL, progname, NULL, *progname, **argv, **envp Where progname is a pointer to the program name as given in the first argument to execve(), and macho_hdr a pointer to the Mach-O header at the beginning of the executable file.
This commit is contained in:
parent
b5ffe4c33c
commit
af59b63bbd
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: darwin_exec.c,v 1.2 2002/11/20 23:54:39 manu Exp $ */
|
||||
/* $NetBSD: darwin_exec.c,v 1.3 2002/11/21 19:53:41 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: darwin_exec.c,v 1.2 2002/11/20 23:54:39 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: darwin_exec.c,v 1.3 2002/11/21 19:53:41 manu Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -107,6 +107,7 @@ int
|
|||
exec_darwin_copyargs(struct proc *p, struct exec_package *pack,
|
||||
struct ps_strings *arginfo, char **stackp, void *argp)
|
||||
{
|
||||
struct exec_macho_emul_arg *emea;
|
||||
struct exec_macho_object_header *macho_hdr;
|
||||
char **cpp, *dp, *sp, *progname;
|
||||
size_t len;
|
||||
|
@ -116,7 +117,8 @@ exec_darwin_copyargs(struct proc *p, struct exec_package *pack,
|
|||
|
||||
*stackp -= 16;
|
||||
|
||||
macho_hdr = (struct exec_macho_object_header *)0x1000; /* XXX */
|
||||
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);
|
||||
|
@ -127,15 +129,14 @@ exec_darwin_copyargs(struct proc *p, struct exec_package *pack,
|
|||
if ((error = copyout(&argc, cpp++, sizeof(argc))) != 0)
|
||||
return error;
|
||||
|
||||
dp = (char *) (cpp + argc + envc + 4 + pack->ep_es->es_arglen);
|
||||
sp = argp;
|
||||
dp = (char *) (cpp + argc + envc + 4);
|
||||
|
||||
progname = dp;
|
||||
if ((error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
|
||||
if ((error = copyoutstr(emea->filename, dp, ARG_MAX, &len)) != 0)
|
||||
return error;
|
||||
progname = dp;
|
||||
dp += len;
|
||||
|
||||
|
||||
sp = argp;
|
||||
arginfo->ps_argvstr = cpp; /* remember location of argv for later */
|
||||
for (; --argc >= 0; sp += len, dp += len)
|
||||
if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
|
||||
|
@ -162,26 +163,10 @@ exec_darwin_copyargs(struct proc *p, struct exec_package *pack,
|
|||
|
||||
*stackp = (char *)cpp;
|
||||
|
||||
if ((error = copyoutstr(pack->ep_emul_arg,
|
||||
*stackp, MAXPATHLEN, &len)) != 0)
|
||||
return error;
|
||||
*stackp += len + 1;
|
||||
|
||||
/* We don't need this anymore */
|
||||
free(pack->ep_emul_arg, MAXPATHLEN);
|
||||
free(pack->ep_emul_arg, M_EXEC);
|
||||
pack->ep_emul_arg = NULL;
|
||||
|
||||
len = len % sizeof(nullp);
|
||||
if (len) {
|
||||
if ((error = copyout(&nullp, *stackp, len)) != 0)
|
||||
return error;
|
||||
*stackp += len;
|
||||
}
|
||||
|
||||
if ((error = copyout(&nullp, *stackp, sizeof(nullp))) != 0)
|
||||
return error;
|
||||
*stackp += sizeof(nullp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mach_exec.c,v 1.10 2002/11/19 16:29:32 christos Exp $ */
|
||||
/* $NetBSD: mach_exec.c,v 1.11 2002/11/21 19:53:41 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
|
@ -37,12 +37,13 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.10 2002/11/19 16:29:32 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.11 2002/11/21 19:53:41 manu Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/exec_macho.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
@ -99,16 +100,23 @@ const struct emul emul_mach = {
|
|||
/*
|
||||
* Copy arguments onto the stack in the normal way, but add some
|
||||
* extra information in case of dynamic binding.
|
||||
* XXX This needs a cleanup: it is not used anymore by the Darwin
|
||||
* emulation, and it probably contains Darwin specific bits.
|
||||
*/
|
||||
int
|
||||
exec_mach_copyargs(struct proc *p, struct exec_package *pack,
|
||||
struct ps_strings *arginfo, char **stackp, void *argp)
|
||||
{
|
||||
struct exec_macho_emul_arg *emea;
|
||||
size_t len;
|
||||
size_t zero = 0;
|
||||
int pagelen = PAGE_SIZE;
|
||||
int error;
|
||||
|
||||
emea = (struct exec_macho_emul_arg *)pack->ep_emul_arg;
|
||||
|
||||
*stackp -= 16;
|
||||
|
||||
if ((error = copyout(&pagelen, *stackp, sizeof(pagelen))) != 0) {
|
||||
DPRINTF(("mach: copyout pagelen failed\n"));
|
||||
return error;
|
||||
|
@ -126,15 +134,15 @@ exec_mach_copyargs(struct proc *p, struct exec_package *pack,
|
|||
}
|
||||
*stackp += sizeof(zero);
|
||||
|
||||
if ((error = copyoutstr(pack->ep_emul_arg, *stackp, MAXPATHLEN, &len))
|
||||
!= 0) {
|
||||
if ((error = copyoutstr(emea->filename,
|
||||
*stackp, MAXPATHLEN, &len)) != 0) {
|
||||
DPRINTF(("mach: copyout path failed\n"));
|
||||
return error;
|
||||
}
|
||||
*stackp += len + 1;
|
||||
|
||||
/* We don't need this anymore */
|
||||
free(pack->ep_emul_arg, MAXPATHLEN);
|
||||
free(pack->ep_emul_arg, M_EXEC);
|
||||
pack->ep_emul_arg = NULL;
|
||||
|
||||
len = len % sizeof(zero);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: exec_macho.c,v 1.14 2002/10/31 02:40:41 christos Exp $ */
|
||||
/* $NetBSD: exec_macho.c,v 1.15 2002/11/21 19:53:41 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.14 2002/10/31 02:40:41 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: exec_macho.c,v 1.15 2002/11/21 19:53:41 manu Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
|
@ -154,8 +154,11 @@ exec_macho_load_segment(struct exec_package *epp, struct vnode *vp,
|
|||
u_long foff, struct exec_macho_segment_command *ls, int type)
|
||||
{
|
||||
int flags;
|
||||
struct exec_macho_emul_arg *emea;
|
||||
u_long addr = trunc_page(ls->vmaddr), size = round_page(ls->filesize);
|
||||
|
||||
emea = (struct exec_macho_emul_arg *)epp->ep_emul_arg;
|
||||
|
||||
if (type != MACHO_MOH_DYLIB)
|
||||
flags = VMCMD_BASE;
|
||||
else
|
||||
|
@ -178,6 +181,8 @@ exec_macho_load_segment(struct exec_package *epp, struct vnode *vp,
|
|||
if (strcmp(ls->segname, "__TEXT") == 0) {
|
||||
epp->ep_taddr = addr;
|
||||
epp->ep_tsize = round_page(ls->vmsize);
|
||||
emea->macho_hdr =
|
||||
(struct exec_macho_object_header *)addr;
|
||||
}
|
||||
if (strcmp(ls->segname, "__DATA") == 0) {
|
||||
epp->ep_daddr = addr;
|
||||
|
@ -212,14 +217,16 @@ static int
|
|||
exec_macho_load_dylinker(struct proc *p, struct exec_package *epp,
|
||||
struct exec_macho_dylinker_command *dy, u_long *entry)
|
||||
{
|
||||
struct exec_macho_emul_arg *emea;
|
||||
const char *name = ((const char *)dy) + dy->name.offset;
|
||||
char path[MAXPATHLEN];
|
||||
int error;
|
||||
#ifdef DEBUG_MACHO
|
||||
exec_macho_print_dylinker_command(dy);
|
||||
#endif
|
||||
(void)snprintf(path, sizeof(path), "%s%s",
|
||||
(const char *)epp->ep_emul_arg, name);
|
||||
emea = (struct exec_macho_emul_arg *)epp->ep_emul_arg;
|
||||
|
||||
(void)snprintf(path, sizeof(path), "%s%s", emea->path, name);
|
||||
DPRINTF(("loading linker %s\n", path));
|
||||
if ((error = exec_macho_load_file(p, epp, path, entry,
|
||||
MACHO_MOH_DYLINKER)) != 0)
|
||||
|
@ -231,6 +238,7 @@ static int
|
|||
exec_macho_load_dylib(struct proc *p, struct exec_package *epp,
|
||||
struct exec_macho_dylib_command *dy) {
|
||||
#ifdef notdef
|
||||
struct exec_macho_emul_arg *emea;
|
||||
const char *name = ((const char *)dy) + dy->dylib.name.offset;
|
||||
char path[MAXPATHLEN];
|
||||
int error;
|
||||
|
@ -240,8 +248,8 @@ exec_macho_load_dylib(struct proc *p, struct exec_package *epp,
|
|||
exec_macho_print_dylib_command(dy);
|
||||
#endif
|
||||
#ifdef notdef
|
||||
(void)snprintf(path, sizeof(path), "%s%s",
|
||||
(const char *)epp->ep_emul_arg, name);
|
||||
emea = (struct exec_macho_emul_arg *)epp->ep_emul_arg;
|
||||
(void)snprintf(path, sizeof(path), "%s%s", emea->path, name);
|
||||
DPRINTF(("loading library %s\n", path));
|
||||
if ((error = exec_macho_load_file(p, epp, path, &entry,
|
||||
MACHO_MOH_DYLIB)) != 0)
|
||||
|
@ -507,6 +515,7 @@ int
|
|||
exec_macho_makecmds(struct proc *p, struct exec_package *epp)
|
||||
{
|
||||
struct exec_macho_fat_header *fat = epp->ep_hdr;
|
||||
struct exec_macho_emul_arg *emea;
|
||||
int error;
|
||||
|
||||
if (epp->ep_hdrvalid < sizeof(*fat))
|
||||
|
@ -527,12 +536,15 @@ exec_macho_makecmds(struct proc *p, struct exec_package *epp)
|
|||
if (error)
|
||||
return (error);
|
||||
|
||||
emea = malloc(sizeof(struct exec_macho_emul_arg), M_EXEC, M_WAITOK);
|
||||
epp->ep_emul_arg = (void *)emea;
|
||||
|
||||
if (!epp->ep_esch->u.mach_probe_func)
|
||||
epp->ep_emul_arg = "/";
|
||||
emea->path = "/";
|
||||
else {
|
||||
if ((error = (*epp->ep_esch->u.mach_probe_func)((char **)
|
||||
&epp->ep_emul_arg)) != 0)
|
||||
return error;
|
||||
&emea->path)) != 0)
|
||||
goto bad2;
|
||||
}
|
||||
|
||||
if ((error = exec_macho_load_vnode(p, epp, epp->ep_vp, fat,
|
||||
|
@ -541,17 +553,20 @@ exec_macho_makecmds(struct proc *p, struct exec_package *epp)
|
|||
|
||||
/*
|
||||
* stash a copy of the program name in epp->ep_emul_arg because
|
||||
* might need it later.
|
||||
* we will need it later.
|
||||
*/
|
||||
MALLOC(epp->ep_emul_arg, char *, MAXPATHLEN, M_EXEC, M_WAITOK);
|
||||
if ((error = copyinstr(epp->ep_name, epp->ep_emul_arg,
|
||||
if ((error = copyinstr(epp->ep_name, emea->filename,
|
||||
MAXPATHLEN, NULL)) != 0) {
|
||||
DPRINTF(("Copyinstr %p failed\n", epp->ep_name));
|
||||
goto bad;
|
||||
}
|
||||
uprintf("PATH: %s\n", emea->filename);
|
||||
|
||||
return exec_macho_setup_stack(p, epp);
|
||||
bad:
|
||||
kill_vmcmds(&epp->ep_vmcmds);
|
||||
bad2:
|
||||
free(emea, M_EXEC);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: exec_macho.h,v 1.5 2002/11/19 19:54:36 christos Exp $ */
|
||||
/* $NetBSD: exec_macho.h,v 1.6 2002/11/21 19:53:40 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
|
@ -39,6 +39,8 @@
|
|||
#ifndef _SYS_EXEC_MACHO_H_
|
||||
#define _SYS_EXEC_MACHO_H_
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <machine/int_types.h>
|
||||
#include <machine/macho_machdep.h>
|
||||
|
||||
|
@ -240,6 +242,12 @@ struct exec_macho_thread_command {
|
|||
u_long count;
|
||||
};
|
||||
|
||||
struct exec_macho_emul_arg {
|
||||
char *path;
|
||||
char filename[MAXPATHLEN];
|
||||
struct exec_macho_object_header *macho_hdr;
|
||||
};
|
||||
|
||||
#ifndef _LKM
|
||||
#include "opt_execfmt.h"
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue