mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-01 08:48:29 +00:00
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:
parent
43ba3009b2
commit
29bf8b1a30
73 changed files with 888 additions and 269 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue