summaryrefslogtreecommitdiff
path: root/serverboot/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'serverboot/exec.c')
-rw-r--r--serverboot/exec.c88
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)&regs,
+ &reg_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)&regs,
+ reg_size);
+
+ return (char *)regs.uesp;
+}
+