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