Blame src/thread/nt32/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
296178
#include <syscall.h>
9912f3
#include <sched.h>
296178
cde352
/* take advantage of i686 vararg abi */
cde352
#define  __clone ____clone
cde352
#include "pthread_impl.h"
cde352
#undef   __clone
cde352
296178
struct pt_regs {
296178
	unsigned long	ebx;
296178
	unsigned long	ecx;
296178
	unsigned long	edx;
296178
	unsigned long	esi;
296178
	unsigned long	edi;
cde352
	unsigned long	ebp;
cde352
	unsigned long	eax;
cde352
	unsigned long	xds;
cde352
	unsigned long	xes;
cde352
	unsigned long	xfs;
cde352
	unsigned long	xgs;
296178
	unsigned long	orig_eax;
296178
	unsigned long	eip;
cde352
	unsigned long	xcs;
296178
	unsigned long	eflags;
296178
	unsigned long	esp;
cde352
	unsigned long	xss;
cde352
	unsigned long	sbase;
cde352
	unsigned long	slimit;
cde352
	unsigned long	sbottom;
296178
};
296178
296178
typedef long __sys_clone(
296178
	unsigned long	flags,
296178
	void *		child_stack,
296178
	void *		ptid,
296178
	void *		ctid,
296178
	struct pt_regs *regs);
296178
296178
extern unsigned long ** __syscall_vtbl;
296178
296178
int __clone(
296178
	__entry_point *	fn,
296178
	void *		child_stack,
296178
	int		flags,
296178
	void *		arg,
296178
	int *		ptid,
296178
	void *		pthread_self_addr,
296178
	int *		ctid)
296178
{
659ac4
	uintptr_t       sbase;
659ac4
	uintptr_t       slimit;
659ac4
	uintptr_t       sbottom;
659ac4
	void *          stack;
659ac4
296178
	struct pt_regs	regs;
296178
	__sys_clone *	pfn_clone;
cde352
	pthread_t	pthread;
296178
296178
	regs.eip = (unsigned long)fn;
296178
	regs.ecx = (unsigned long)arg;
296178
	regs.edx = (unsigned long)pthread_self_addr;
296178
296178
	pfn_clone = (__sys_clone *)(__syscall_vtbl[SYS_clone]);
296178
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
296178
	return (int)pfn_clone(
296178
		flags,
659ac4
		stack,
296178
		ptid,
296178
		ctid,
296178
		®s;;
296178
}