Blame src/thread/nt64/clone.c

716654
/**************************************************************************/
716654
/*  mmglue: midipix architecture- and target-specific bits for musl libc  */
716654
/*  Copyright (C) 2013--2023  SysDeer Technologies, LLC                   */
716654
/*  Released under the Standard MIT License; see COPYING.MMGLUE.          */
716654
/**************************************************************************/
716654
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
{
659ac4
	uintptr_t       sbase;
659ac4
	uintptr_t       slimit;
659ac4
	uintptr_t       sbottom;
659ac4
	void *          stack;
659ac4
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
659ac4
	sbase  = (uintptr_t)child_stack;
659ac4
	sbase &= ~(uintptr_t)(0xf);
659ac4
	stack  = (void *)sbase;
659ac4
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,
659ac4
			stack,
9912f3
			0,0,®s;;
9912f3
	}
9912f3
659ac4
	pthread = (pthread_t)pthread_self_addr;
659ac4
	sbase   = (uintptr_t)pthread->stack;
659ac4
	slimit  = sbase - pthread->stack_size;
659ac4
	sbottom = slimit - pthread->guard_size;
659ac4
659ac4
	sbase  &= ~(uintptr_t)(0xf);
659ac4
	slimit += 0xf;
659ac4
	slimit |= 0xf;
659ac4
	slimit ^= 0xf;
659ac4
659ac4
	regs.sbase   = sbase;
659ac4
	regs.slimit  = slimit;
659ac4
	regs.sbottom = sbottom;
cde352
860627
	return (int)pfn_clone(
860627
		flags,
659ac4
		stack,
860627
		ptid,
860627
		ctid,
860627
		®s;;
860627
}