+
+/* This routine is called from assembly after each mach system call
+ */
+
+extern unsigned int mach_call_end(unsigned int, unsigned int);
+
+__private_extern__
+unsigned int
+mach_call_end(unsigned int call_number, unsigned int retval)
+{
+ KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_SC,(call_number>>4)) | DBG_FUNC_END,
+ retval, 0, 0, 0, 0);
+ return retval; /* pass this back thru */
+}
+
+typedef kern_return_t (*mach_call_t)(void *);
+
+extern __attribute__((regparm(1))) kern_return_t
+mach_call_munger(unsigned int call_number,
+ unsigned int arg1,
+ unsigned int arg2,
+ unsigned int arg3,
+ unsigned int arg4,
+ unsigned int arg5,
+ unsigned int arg6,
+ unsigned int arg7,
+ unsigned int arg8,
+ unsigned int arg9
+);
+
+struct mach_call_args {
+ unsigned int arg1;
+ unsigned int arg2;
+ unsigned int arg3;
+ unsigned int arg4;
+ unsigned int arg5;
+ unsigned int arg6;
+ unsigned int arg7;
+ unsigned int arg8;
+ unsigned int arg9;
+};
+__private_extern__
+__attribute__((regparm(1))) kern_return_t
+mach_call_munger(unsigned int call_number,
+ unsigned int arg1,
+ unsigned int arg2,
+ unsigned int arg3,
+ unsigned int arg4,
+ unsigned int arg5,
+ unsigned int arg6,
+ unsigned int arg7,
+ unsigned int arg8,
+ unsigned int arg9
+)
+{
+ int argc;
+ mach_call_t mach_call;
+ kern_return_t retval;
+ struct mach_call_args args = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ current_thread()->task->syscalls_mach++; /* MP-safety ignored */
+ call_number >>= 4;
+
+ argc = mach_trap_table[call_number].mach_trap_arg_count;
+ switch (argc) {
+ case 9: args.arg9 = arg9;
+ case 8: args.arg8 = arg8;
+ case 7: args.arg7 = arg7;
+ case 6: args.arg6 = arg6;
+ case 5: args.arg5 = arg5;
+ case 4: args.arg4 = arg4;
+ case 3: args.arg3 = arg3;
+ case 2: args.arg2 = arg2;
+ case 1: args.arg1 = arg1;
+ }
+
+ KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_SC, (call_number)) | DBG_FUNC_START,
+ args.arg1, args.arg2, args.arg3, 0, 0);
+
+ mach_call = (mach_call_t)mach_trap_table[call_number].mach_trap_function;
+ retval = mach_call(&args);
+
+ KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_SC,(call_number)) | DBG_FUNC_END,
+ retval, 0, 0, 0, 0);
+
+ return retval;
+}
+
+/*
+ * thread_setuserstack:
+ *
+ * Sets the user stack pointer into the machine
+ * dependent thread state info.
+ */
+void
+thread_setuserstack(
+ thread_t thread,
+ mach_vm_address_t user_stack)
+{
+ struct i386_saved_state *ss = get_user_regs(thread);
+
+ ss->uesp = CAST_DOWN(unsigned int,user_stack);
+}
+
+/*
+ * thread_adjuserstack:
+ *
+ * Returns the adjusted user stack pointer from the machine
+ * dependent thread state info. Used for small (<2G) deltas.
+ */
+uint64_t
+thread_adjuserstack(
+ thread_t thread,
+ int adjust)
+{
+ struct i386_saved_state *ss = get_user_regs(thread);
+
+ ss->uesp += adjust;
+ return CAST_USER_ADDR_T(ss->uesp);
+}
+
+/*
+ * thread_setentrypoint:
+ *
+ * Sets the user PC into the machine
+ * dependent thread state info.
+ */
+void
+thread_setentrypoint(
+ thread_t thread,
+ mach_vm_address_t entry)
+{
+ struct i386_saved_state *ss = get_user_regs(thread);
+
+ ss->eip = CAST_DOWN(unsigned int,entry);
+}
+