Blame src/thread/nt64/clone.c

9912f3
#define  _GNU_SOURCE
9912f3
860627
#include <syscall.h>
9912f3
#include <sched.h>
860627
cde352
/* take advantage of winnt's x64 vararg abi */
cde352
#define  __clone ____clone
cde352
#include "pthread_impl.h"
cde352
#undef   __clone
cde352
860627
struct pt_regs {
860627
	unsigned long	r15;
860627
	unsigned long	r14;
860627
	unsigned long	r13;
860627
	unsigned long	r12;
860627
	unsigned long	rbp;
860627
	unsigned long	rbx;
860627
	unsigned long	r11;
860627
	unsigned long	r10;
860627
	unsigned long	r9;
860627
	unsigned long	r8;
860627
	unsigned long	rax;
860627
	unsigned long	rcx;
860627
	unsigned long	rdx;
860627
	unsigned long	rsi;
860627
	unsigned long	rdi;
860627
	unsigned long	orig_rax;
860627
	unsigned long	rip;
860627
	unsigned long	cs;
860627
	unsigned long	eflags;
860627
	unsigned long	rsp;
860627
	unsigned long	ss;
cde352
	uintptr_t	sbase;
cde352
	uintptr_t	slimit;
cde352
	uintptr_t	sbottom;
860627
};
860627
860627
typedef long __sys_clone(
860627
	unsigned long	flags,
860627
	void *		child_stack,
860627
	void *		ptid,
860627
	void *		ctid,
860627
	struct pt_regs *regs);
860627
860627
extern unsigned long ** __syscall_vtbl;
860627
cde352
hidden int __clone(
cde352
	int             (*fn)(void *),
860627
	void *		child_stack,
860627
	int		flags,
860627
	void *		arg,
860627
	int *		ptid,
860627
	void *		pthread_self_addr,
860627
	int *		ctid)
860627
{
860627
	struct pt_regs	regs;
860627
	__sys_clone *	pfn_clone;
cde352
	pthread_t	pthread;
860627
860627
	regs.rip = (unsigned long)fn;
860627
	regs.rcx = (unsigned long)arg;
860627
	regs.rdx = (unsigned long)pthread_self_addr;
860627
860627
	pfn_clone = (__sys_clone *)(__syscall_vtbl[SYS_clone]);
860627
cfeeec
	if (flags == (CLONE_VM|CLONE_VFORK|SIGCHLD)) {
9912f3
		regs.sbase   = 0;
9912f3
		regs.slimit  = 0;
9912f3
		regs.sbottom = 0;
9912f3
9912f3
		return (int)pfn_clone(
9912f3
			flags,
9912f3
			child_stack,
9912f3
			0,0,®s;;
9912f3
	}
9912f3
cde352
	pthread      = (pthread_t)pthread_self_addr;
cde352
	regs.sbase   = (unsigned long)pthread->stack;
cde352
	regs.slimit  = regs.sbase  - pthread->stack_size;
cde352
	regs.sbottom = regs.slimit - pthread->guard_size;
cde352
860627
	return (int)pfn_clone(
860627
		flags,
860627
		child_stack,
860627
		ptid,
860627
		ctid,
860627
		®s;;
860627
}