[Devel] [PATCH 2/9] user-cr: x86_32 eclone wrapper

Nathan Lynch ntl at pobox.com
Tue Nov 17 16:55:39 PST 2009


---
 clone_x86_32.c |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/clone_x86_32.c b/clone_x86_32.c
index 8ab3c3e..61b593c 100644
--- a/clone_x86_32.c
+++ b/clone_x86_32.c
@@ -81,3 +81,68 @@ int clone_with_pids(int (*fn)(void *), void *child_stack, int flags,
 }
 
 #endif
+
+#include "eclone.h"
+
+#ifndef __NR_eclone
+#define __NR_eclone 337
+#endif
+
+int eclone(int (*fn)(void *), void *fn_arg, int clone_flags_low,
+	   struct clone_args *clone_args, pid_t *pids)
+{
+	struct clone_args my_args;
+	long retval;
+	void **newstack;
+
+	if (clone_args->child_stack) {
+		/*
+		 * Set up the stack for child:
+		 *  - fn_arg will be the argument for the child function
+		 *  - the fn pointer will be loaded into ebx after the clone
+		 */
+		newstack = (void **)(unsigned long)(clone_args->child_stack +
+					    clone_args->child_stack_size);
+		*--newstack = fn_arg;
+		*--newstack = fn;
+	} else
+		newstack = (void **)0;
+
+	my_args = *clone_args;
+	my_args.child_stack = (unsigned long)newstack;
+	my_args.child_stack_size = 0;
+
+	__asm__	 __volatile__(
+		"movl %0, %%ebx\n\t"	       /* flags -> 1st (ebx) */
+		"movl %1, %%ecx\n\t"	       /* clone_args -> 2nd (ecx) */
+		"movl %2, %%edx\n\t"	       /* args_size -> 3rd (edx) */
+		"movl %3, %%edi\n\t"	       /* pids -> 4th (edi) */
+		"pushl %%ebp\n\t"	       /* save value of ebp */
+		:
+		:"b" (clone_flags_low),
+		 "c" (&my_args),
+		 "d" (sizeof(my_args)),
+		 "D" (pids)
+		);
+
+	__asm__ __volatile__(
+		"int $0x80\n\t"	       /* Linux/i386 system call */
+		"testl %0,%0\n\t"      /* check return value */
+		"jne 1f\n\t"	       /* jump if parent */
+		"popl %%ebx\n\t"       /* get subthread function */
+		"call *%%ebx\n\t"      /* start subthread function */
+		"movl %2,%0\n\t"
+		"int $0x80\n"	       /* exit system call: exit subthread */
+		"1:\n\t"
+		"popl %%ebp\t"	       /* restore parent's ebp */
+		:"=a" (retval)
+		:"0" (__NR_eclone), "i" (__NR_exit)
+		:"ebx", "ecx"
+		);
+
+	if (retval < 0) {
+		errno = -retval;
+		retval = -1;
+	}
+	return retval;
+}
-- 
1.6.2.5

_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers




More information about the Devel mailing list