shithub: mc

Download patch

ref: 7e3d48053773f02748160f3ac7fe60cdb1bb2971
parent: 7deb877757f34da0a6f8fce8b2d5b5ae07178429
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Aug 28 15:33:46 EDT 2015

Add fnclone wrapper.

    Since the stack goes away, we need to ensure that the function
    on the stack doesn't.

--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -30,6 +30,7 @@
 	/* write to buffer */
 	const fmt	: (fmt : byte[:], args : ... -> byte[:])
 	const fmtv	: (fmt : byte[:], ap : valist# -> byte[:])
+
 	const bfmt	: (buf : byte[:], fmt : byte[:], args : ... -> byte[:])
 	const bfmtv	: (buf : byte[:], fmt : byte[:], ap : valist# -> byte[:])
 
--- a/lib/std/sys+linux-x64.myr
+++ b/lib/std/sys+linux-x64.myr
@@ -593,6 +593,14 @@
 	const fork	: (-> pid)
 	/* FIXME: where the fuck is 'struct pt_reg' defined?? */
 	const clone	: (flags : cloneopt, stk : byte#, ptid : pid#, ctid : pid#, ptreg : byte# -> pid)
+	extern const fnclone	: ( flags : cloneopt, \
+				stk : byte#, \
+				ptid : pid#, \
+				tls : byte#, \
+				ctid : pid#, \
+				ptreg : byte#, \
+				fn : (-> void) \
+				-> pid)
 	const wait4	: (pid:pid, loc:int32#, opt : int64, usage:rusage#	-> int64)
 	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
 	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
--- a/lib/std/syscall+linux-x64.s
+++ b/lib/std/syscall+linux-x64.s
@@ -20,3 +20,30 @@
 
 	ret
 
+/* clone(flags, stack, ptid, tls, ctid, regs) */
+.globl sys$fnclone
+sys$fnclone:
+	pushq %r15
+        /* %rsp is modified by clone(), so it's saved here */
+	movq 16(%rsp),%r15
+	/*
+        %rdi: flags, %rsi: stack, %rdx: ptid,
+        %rcx: tls, %r8: ctid, %r9: regs
+        */
+	movq $56,%rax	/* syscall num */
+	movq %rcx,%r10	/* tls */
+	syscall
+
+	/* fn() */
+	testl %eax,%eax
+	jnz parent
+	call *%r15
+
+	/* exit(0) */
+	movq $60, %rax  /* exit */
+	movq $0, %rdi   /* arg: 0 */
+	syscall
+
+parent:
+	popq %r15
+	ret