Date: Sun, 1 Nov 1998 23:12:38 -0500 (EST) From: Brian Feldman <green@zone.syracuse.net> To: current@FreeBSD.ORG Subject: Linux clone() Message-ID: <Pine.BSF.4.05.9811012304170.5699-100000@zone.syracuse.net>
next in thread | raw e-mail | index | archive | help
Okay, guys, I think I've gotten a linux clone() syscall implemented... As of now, I have nothing to test it with :( The only thing I have to try it with is MpegTV, and for some really crazy reason: linux_clone()->(1569, 1570); child eip=0xf00, esp=0x80ed0b4 Now come on, passing 0xf00 as the void *fn (really int (*fn)(void *)) is pretty damned bogus (but hey, it's not zero, so it turns into the child's instruction pointer...) If anyone has any REALY examples of programs to test with this, let me know.... This is a pretty important thing to have, when lots more apps use linuxthreads (i.e. StarOffice 5.0). Oh, BTW, someone tell me if this would be something really terrible to accidentally do in kernel space: printf("%d %d %#x %#x"); note no arguments... so far I don't notice any destabilization but I sure hope I didn't fudge up the kernel stack! Cheers, Brian Feldman ---patch follows--- diff -ur /usr/src/sys/i386/linux/linux_dummy.c usr/src/sys/i386/linux/linux_dummy.c --- /usr/src/sys/i386/linux/linux_dummy.c Thu Nov 6 14:28:52 1997 +++ usr/src/sys/i386/linux/linux_dummy.c Sun Nov 1 17:07:31 1998 @@ -212,13 +212,6 @@ } int -linux_clone(struct proc *p, struct linux_clone_args *args) -{ - printf("Linux-emul(%d): clone() not supported\n", p->p_pid); - return ENOSYS; -} - -int linux_uname(struct proc *p, struct linux_uname_args *args) { printf("Linux-emul(%d): uname() not supported\n", p->p_pid); diff -ur /usr/src/sys/i386/linux/linux_misc.c usr/src/sys/i386/linux/linux_misc.c --- /usr/src/sys/i386/linux/linux_misc.c Mon Oct 5 08:40:42 1998 +++ usr/src/sys/i386/linux/linux_misc.c Sun Nov 1 23:06:00 1998 @@ -41,6 +41,7 @@ #include <sys/resourcevar.h> #include <sys/stat.h> #include <sys/sysctl.h> +#include <sys/unistd.h> #include <sys/vnode.h> #include <sys/wait.h> #include <sys/time.h> @@ -557,6 +558,31 @@ return error; if (p->p_retval[1] == 1) p->p_retval[0] = 0; + return 0; +} + +int +linux_clone(struct proc *p, struct linux_clone_args *args) +{ + int error; + struct proc *p2; + + if (error = fork1(p, RFPROC | RFMEM)) + return error; + p2 = pfind(p->p_retval[0]); + if (p2 == 0) + return ESRCH; + if (args->stack) + p2->p_md.md_regs->tf_esp = (int)args->stack; + if (args->fn) { + p2->p_md.md_regs->tf_eip = (int)args->fn; + copyout(&args->arg, (void *)p2->p_md.md_regs->tf_esp, sizeof(void *)); + p2->p_md.md_regs->tf_esp -= sizeof(void *); + } +#ifdef DEBUG_CLONE + printf("linux_clone()->(%d, %d); child eip=%#x, esp=%#x\n", p->p_pid, + p2->p_pid, p2->p_md.md_regs->tf_eip, p2->p_md.md_regs->tf_esp); +#endif return 0; } diff -ur /usr/src/sys/i386/linux/linux_proto.h usr/src/sys/i386/linux/linux_proto.h --- /usr/src/sys/i386/linux/linux_proto.h Fri Jul 10 18:30:04 1998 +++ usr/src/sys/i386/linux/linux_proto.h Sun Nov 1 17:07:31 1998 @@ -2,7 +2,7 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * created from Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde Exp + * created from Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh Exp */ #ifndef _LINUX_SYSPROTO_H_ @@ -301,7 +301,10 @@ struct linux_sigcontext * scp; char scp_[PAD_(struct linux_sigcontext *)]; }; struct linux_clone_args { - register_t dummy; + void * fn; char fn_[PAD_(void *)]; + void * stack; char stack_[PAD_(void *)]; + int flags; char flags_[PAD_(int)]; + void * arg; char arg_[PAD_(void *)]; }; struct linux_newuname_args { struct linux_newuname_t * buf; char buf_[PAD_(struct linux_newuname_t *)]; Only in usr/src/sys/i386/linux/: linux_proto.h.bak diff -ur /usr/src/sys/i386/linux/linux_syscall.h usr/src/sys/i386/linux/linux_syscall.h --- /usr/src/sys/i386/linux/linux_syscall.h Fri Jul 10 18:30:06 1998 +++ usr/src/sys/i386/linux/linux_syscall.h Sun Nov 1 17:07:31 1998 @@ -2,7 +2,7 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * created from Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde Exp + * created from Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh Exp */ #define LINUX_SYS_linux_setup 0 Only in usr/src/sys/i386/linux/: linux_syscall.h.bak diff -ur /usr/src/sys/i386/linux/linux_sysent.c usr/src/sys/i386/linux/linux_sysent.c --- /usr/src/sys/i386/linux/linux_sysent.c Fri Jul 10 18:30:07 1998 +++ usr/src/sys/i386/linux/linux_sysent.c Sun Nov 1 17:07:31 1998 @@ -2,7 +2,7 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * created from Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde Exp + * created from Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh Exp */ #include "opt_compat.h" @@ -134,7 +134,7 @@ { 5, (sy_call_t *)linux_ipc }, /* 117 = linux_ipc */ { 1, (sy_call_t *)fsync }, /* 118 = fsync */ { 1, (sy_call_t *)linux_sigreturn }, /* 119 = linux_sigreturn */ - { 0, (sy_call_t *)linux_clone }, /* 120 = linux_clone */ + { 4, (sy_call_t *)linux_clone }, /* 120 = linux_clone */ { 2, (sy_call_t *)setdomainname }, /* 121 = setdomainname */ { 1, (sy_call_t *)linux_newuname }, /* 122 = linux_newuname */ { 3, (sy_call_t *)linux_modify_ldt }, /* 123 = linux_modify_ldt */ Only in usr/src/sys/i386/linux/: linux_sysent.c.bak diff -ur /usr/src/sys/i386/linux/syscalls.master usr/src/sys/i386/linux/syscalls.master --- /usr/src/sys/i386/linux/syscalls.master Fri Jul 10 18:30:08 1998 +++ usr/src/sys/i386/linux/syscalls.master Sun Nov 1 17:07:31 1998 @@ -171,7 +171,8 @@ caddr_t ptr); } 118 NOPROTO LINUX { int fsync(int fd); } 119 STD LINUX { int linux_sigreturn(struct linux_sigcontext *scp); } -120 STD LINUX { int linux_clone(void); } +120 STD LINUX { int linux_clone(void *fn, void *stack,\ + int flags, void *arg); } 121 NOPROTO LINUX { int setdomainname(char *name, \ int len); } 122 STD LINUX { int linux_newuname(struct linux_newuname_t *buf); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.05.9811012304170.5699-100000>