Make improvements

- Make rand64() thread safe
- Introduce lemur64 lcg prng
- Improve strace on New Technology
- Improve msync() on New Technology
This commit is contained in:
Justine Tunney 2022-04-07 00:15:35 -07:00
parent 43ba3009b2
commit 29bf8b1a30
73 changed files with 888 additions and 269 deletions

View file

@ -29,7 +29,9 @@ textwindows wontreturn void sys_abort_nt(void) {
info.si_signo = SIGABRT;
rva = __sighandrvas[SIGABRT];
if (rva >= kSigactionMinRva) {
((sigaction_f)(_base + rva))(SIGABRT, &info, NULL);
if (((sigaction_f)(_base + rva))) {
((sigaction_f)(_base + rva))(SIGABRT, &info, NULL);
}
}
_Exit(128 + SIGABRT);
}

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h"
#include "libc/dce.h"
#include "libc/nexgen32e/nt2sysv.h"
#include "libc/nexgen32e/stackframe.h"
@ -24,6 +25,8 @@
#include "libc/nt/thread.h"
#include "libc/sysv/consts/clone.h"
#include "libc/sysv/consts/nr.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/sicode.h"
#include "libc/sysv/errfuns.h"
struct WinThread {
@ -32,7 +35,7 @@ struct WinThread {
void *stack;
};
static noasan textwindows uint32_t winthread(void *param) {
static noasan textwindows uint32_t WinThreadMain(void *param) {
struct WinThread *wt = param;
asm volatile("mov\t%%rbp,%%r14\n\t"
"mov\t%%rsp,%%r15\n\t"
@ -50,15 +53,19 @@ static noasan textwindows uint32_t winthread(void *param) {
/**
* Creates thread.
*
* @note CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND creates thread
* @note CLONE_VFORK|CLONE_VM|SIGCHLD does vfork()
* @note SIGCHLD does fork()
* @param flags usually has one of
* - `CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND` for threads
* - `CLONE_VFORK|CLONE_VM|SIGCHLD` for vfork()
* - `SIGCHLD` for fork()
* as part high bytes, and the low order byte may optionally contain
* a signal e.g. SIGCHLD, to enable parent notification on terminate
*/
privileged int clone(int (*f)(void *), void *stack, int flags, void *arg, ...) {
int64_t h;
int tidfd;
va_list va;
intptr_t ax;
uint32_t tid;
int64_t hand;
int32_t *ptid;
register void *tls asm("r8");
register int32_t *ctid asm("r10");
@ -90,11 +97,16 @@ privileged int clone(int (*f)(void *), void *stack, int flags, void *arg, ...) {
: "memory");
unreachable;
} else if (IsWindows()) {
if (flags == (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)) {
if ((h = CreateThread(0, PAGESIZE, NT2SYSV(winthread),
&(struct WinThread){f, arg, stack}, 0, &tid))) {
CloseHandle(h);
return tid;
if ((tidfd = __reservefd()) == -1) return -1;
if (flags == CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) {
if ((hand = CreateThread(&kNtIsInheritable, 0, NT2SYSV(WinThreadMain),
&(struct WinThread){f, arg, stack}, 0, &tid))) {
// XXX: this should be tracked in a separate data structure
g_fds.p[tidfd].kind = kFdProcess;
g_fds.p[tidfd].handle = hand;
g_fds.p[tidfd].flags = O_CLOEXEC;
g_fds.p[tidfd].zombie = false;
return tidfd;
} else {
return -1;
}

View file

@ -3,6 +3,11 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct ProtectNt {
uint32_t flags1;
uint32_t flags2;
};
struct DirectMap {
void *addr;
int64_t maphandle;
@ -12,6 +17,8 @@ struct DirectMap sys_mmap(void *, size_t, int, int, int, int64_t);
struct DirectMap sys_mmap_nt(void *, size_t, int, int, int64_t, int64_t);
struct DirectMap sys_mmap_metal(void *, size_t, int, int, int, int64_t);
int sys_munmap_metal(void *, size_t);
uint32_t __prot2nt(int, int);
struct ProtectNt __nt2prot(int);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -177,23 +177,8 @@ textwindows void WinMainForked(void) {
}
} else {
// we can however safely inherit MAP_SHARED with zero copy
if (maps[i].prot & PROT_WRITE) {
if (maps[i].prot & PROT_EXEC) {
flags2 = kNtFileMapWrite | kNtFileMapExecute;
} else {
flags2 = kNtFileMapWrite;
}
} else if (maps[i].prot & PROT_READ) {
if (maps[i].prot & PROT_EXEC) {
flags2 = kNtFileMapRead | kNtFileMapExecute;
} else {
flags2 = kNtFileMapRead;
}
} else {
flags2 = 0;
}
if (!MapViewOfFileEx(maps[i].h, flags2, maps[i].offset >> 32,
maps[i].offset, size, addr)) {
if (!MapViewOfFileEx(maps[i].h, __nt2prot(maps[i].prot).flags2,
maps[i].offset >> 32, maps[i].offset, size, addr)) {
ExitProcess(45);
}
}
@ -216,29 +201,14 @@ textwindows void WinMainForked(void) {
_mmi.n = specialz / sizeof(_mmi.p[0]);
for (i = 0; i < mapcount; ++i) {
if ((maps[i].flags & MAP_PRIVATE) && (~maps[i].prot & PROT_WRITE)) {
if (maps[i].prot & PROT_WRITE) {
if (maps[i].prot & PROT_EXEC) {
flags1 = kNtPageExecuteReadwrite;
} else {
flags1 = kNtPageReadwrite;
}
} else if (maps[i].prot & PROT_READ) {
if (maps[i].prot & PROT_EXEC) {
flags1 = kNtPageExecuteRead;
} else {
flags1 = kNtPageReadonly;
}
} else {
flags1 = kNtPageNoaccess;
}
VirtualProtect((void *)((uint64_t)maps[i].x << 16),
ROUNDUP(maps[i].size, FRAMESIZE), flags1, &oldprot);
ROUNDUP(maps[i].size, FRAMESIZE),
__nt2prot(maps[i].prot).flags1, &oldprot);
}
}
// we're all done reading!
if (!CloseHandle(reader)) {
STRACE("CloseHandle(reader) failed %m");
ExitProcess(47);
}
@ -309,7 +279,6 @@ textwindows int sys_fork_nt(void) {
if (ok) ok = WriteAll(writer, __bss_start, __bss_end - __bss_start);
if (ok) {
if (!CloseHandle(writer)) {
STRACE("CloseHandle(writer) failed %m");
ok = false;
}
}
@ -332,7 +301,7 @@ textwindows int sys_fork_nt(void) {
}
} else {
STRACE("CreatePipe() failed %m");
rc = __winerr();
rc = -1;
CloseHandle(writer);
}
} else {

View file

@ -37,11 +37,7 @@ noasan void ReleaseMemoryNt(struct MemoryIntervals *mm, int l, int r) {
for (i = l; i <= r; ++i) {
addr = GetFrameAddr(mm->p[i].x);
last = GetFrameAddr(mm->p[i].y);
STRACE("UnmapViewOfFile(%p, size:%'zu, hand:%ld)", addr,
last - addr + FRAMESIZE, mm->p[i].h);
ok = UnmapViewOfFile(addr);
assert(ok);
ok = CloseHandle(mm->p[i].h);
assert(ok);
UnmapViewOfFile(addr);
CloseHandle(mm->p[i].h);
}
}

View file

@ -17,22 +17,40 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
#include "libc/nt/files.h"
#include "libc/nt/memory.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/sysv/consts/msync.h"
noasan textwindows int sys_msync_nt(void *addr, size_t size, int flags) {
int x, y, l, r, i;
x = ROUNDDOWN((intptr_t)addr, FRAMESIZE) >> 16;
y = ROUNDDOWN((intptr_t)addr + size - 1, FRAMESIZE) >> 16;
for (i = FindMemoryInterval(&_mmi, x); i < _mmi.i; ++i) {
if ((x >= _mmi.p[i].x && x <= _mmi.p[i].y) ||
(y >= _mmi.p[i].x && y <= _mmi.p[i].y)) {
FlushFileBuffers(_mmi.p[i].h);
#define ADDR(x) ((char *)((int64_t)((uint64_t)(x) << 32) >> 16))
noasan textwindows int sys_msync_nt(char *addr, size_t size, int flags) {
char *a, *b;
int rc, x, y, l, r, i;
rc = 0;
for (i = FindMemoryInterval(&_mmi, (intptr_t)addr >> 16); i < _mmi.i; ++i) {
if ((ADDR(_mmi.p[i].x) <= addr && addr < ADDR(_mmi.p[i].y + 1)) ||
(ADDR(_mmi.p[i].x) < addr + size &&
addr + size <= ADDR(_mmi.p[i].y + 1)) ||
(addr < ADDR(_mmi.p[i].x) && ADDR(_mmi.p[i].y + 1) < addr + size)) {
a = MIN(MAX(addr, ADDR(_mmi.p[i].x)), ADDR(_mmi.p[i].y + 1));
b = MAX(MIN(addr + size, ADDR(_mmi.p[i].y + 1)), ADDR(_mmi.p[i].x));
if (!FlushViewOfFile(a, b - a)) {
rc = -1;
break;
}
if (flags & MS_SYNC) {
if (!FlushFileBuffers(_mmi.p[i].h)) {
// TODO(jart): what's up with this?
// rc = -1;
// break;
}
}
} else {
break;
}
}
return 0;
return rc;
}