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 |
}
|