diff options
Diffstat (limited to 'serverboot/exec.c')
-rw-r--r-- | serverboot/exec.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/serverboot/exec.c b/serverboot/exec.c new file mode 100644 index 00000000..5b5feedc --- /dev/null +++ b/serverboot/exec.c @@ -0,0 +1,88 @@ +/* + * Mach Operating System + * Copyright (c) 1993-1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * i386-specific routines for loading a.out files. + */ + +#include <mach.h> +#include <mach/machine/vm_param.h> +#include <mach/machine/eflags.h> +#include <mach/exec/exec.h> + +#include <file_io.h> + +/* + * Machine-dependent portions of execve() for the i386. + */ + +#define STACK_SIZE (64*1024) + +char *set_regs( + mach_port_t user_task, + mach_port_t user_thread, + struct exec_info *info, + int arg_size) +{ + vm_offset_t stack_start; + vm_offset_t stack_end; + struct i386_thread_state regs; + unsigned int reg_size; + + /* + * Add space for 5 ints to arguments, for + * PS program. XXX + */ + arg_size += 5 * sizeof(int); + + /* + * Allocate stack. + */ + stack_end = VM_MAX_ADDRESS; + stack_start = VM_MAX_ADDRESS - STACK_SIZE; + (void)vm_allocate(user_task, + &stack_start, + (vm_size_t)(stack_end - stack_start), + FALSE); + + reg_size = i386_THREAD_STATE_COUNT; + (void)thread_get_state(user_thread, + i386_THREAD_STATE, + (thread_state_t)®s, + ®_size); + + regs.eip = info->entry; + regs.uesp = (int)((stack_end - arg_size) & ~(sizeof(int)-1)); + + /* regs.efl |= EFL_TF; trace flag*/ + + (void)thread_set_state(user_thread, + i386_THREAD_STATE, + (thread_state_t)®s, + reg_size); + + return (char *)regs.uesp; +} + |