mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Get Redbean fork() working on the New Technology
Now that we have understandable system call tracing on Windows, this change rewrites many of the polyfill internals for that platform, to help things get closer to tip top shape. Support for complex forking scenarios had been in a regressed state for quite some time. Now, it works! Subsequent changes should be able to address the performance.
This commit is contained in:
parent
efedef6e65
commit
0cb6b6ff4b
84 changed files with 1340 additions and 338 deletions
21
ape/ape.S
21
ape/ape.S
|
@ -1605,5 +1605,26 @@ ape_idata_ro:
|
||||||
__data_start:
|
__data_start:
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
|
.section .dataepilogue,"aw",@progbits
|
||||||
|
.type __data_end,@object
|
||||||
|
.globl __data_end
|
||||||
|
.hidden __data_end
|
||||||
|
__data_end:
|
||||||
|
.previous
|
||||||
|
|
||||||
|
.section .bssprologue,"aw",@nobits
|
||||||
|
.type __bss_start,@object
|
||||||
|
.globl __bss_start
|
||||||
|
.hidden __bss_start
|
||||||
|
__bss_start:
|
||||||
|
.previous
|
||||||
|
|
||||||
|
.section .bssepilogue,"aw",@nobits
|
||||||
|
.type __bss_end,@object
|
||||||
|
.globl __bss_end
|
||||||
|
.hidden __bss_end
|
||||||
|
__bss_end:
|
||||||
|
.previous
|
||||||
|
|
||||||
.end
|
.end
|
||||||
|
|
14
ape/ape.lds
14
ape/ape.lds
|
@ -342,7 +342,7 @@ SECTIONS {
|
||||||
/*END: Read Only Data (only needed for initialization) */
|
/*END: Read Only Data (only needed for initialization) */
|
||||||
/*END: Read Only Data */
|
/*END: Read Only Data */
|
||||||
} :Rom
|
} :Rom
|
||||||
|
|
||||||
.tdata . : {
|
.tdata . : {
|
||||||
_tdata_start = .;
|
_tdata_start = .;
|
||||||
*(SORT_BY_ALIGNMENT(.tdata))
|
*(SORT_BY_ALIGNMENT(.tdata))
|
||||||
|
@ -358,6 +358,8 @@ SECTIONS {
|
||||||
|
|
||||||
.data . : {
|
.data . : {
|
||||||
/*BEGIN: Read/Write Data */
|
/*BEGIN: Read/Write Data */
|
||||||
|
KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*)))
|
||||||
|
/*BEGIN: NT FORK COPYING */
|
||||||
KEEP(*(.dataprologue))
|
KEEP(*(.dataprologue))
|
||||||
*(.data .data.*)
|
*(.data .data.*)
|
||||||
KEEP(*(SORT_BY_NAME(.sort.data.*)))
|
KEEP(*(SORT_BY_NAME(.sort.data.*)))
|
||||||
|
@ -378,6 +380,8 @@ SECTIONS {
|
||||||
. = ALIGN(__SIZEOF_POINTER__);
|
. = ALIGN(__SIZEOF_POINTER__);
|
||||||
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
|
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
|
||||||
KEEP(*(.piro.pad.data))
|
KEEP(*(.piro.pad.data))
|
||||||
|
KEEP(*(.dataepilogue))
|
||||||
|
/*END: NT FORK COPYING */
|
||||||
. = ALIGN(PAGESIZE);
|
. = ALIGN(PAGESIZE);
|
||||||
HIDDEN(_edata = .);
|
HIDDEN(_edata = .);
|
||||||
PROVIDE_HIDDEN(edata = .);
|
PROVIDE_HIDDEN(edata = .);
|
||||||
|
@ -404,6 +408,8 @@ SECTIONS {
|
||||||
/*BEGIN: bss memory that's addressable */
|
/*BEGIN: bss memory that's addressable */
|
||||||
|
|
||||||
.bss ALIGN(64) : {
|
.bss ALIGN(64) : {
|
||||||
|
/*BEGIN: NT FORK COPYING */
|
||||||
|
KEEP(*(.bssprologue))
|
||||||
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
|
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
|
||||||
*(.piro.bss)
|
*(.piro.bss)
|
||||||
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
||||||
|
@ -418,6 +424,8 @@ SECTIONS {
|
||||||
|
|
||||||
KEEP(*(SORT_BY_NAME(.sort.bss.*)))
|
KEEP(*(SORT_BY_NAME(.sort.bss.*)))
|
||||||
|
|
||||||
|
KEEP(*(.bssepilogue))
|
||||||
|
/*END: NT FORK COPYING */
|
||||||
. = ALIGN(FRAMESIZE); /* for brk()/sbrk() allocation */
|
. = ALIGN(FRAMESIZE); /* for brk()/sbrk() allocation */
|
||||||
HIDDEN(_end = .);
|
HIDDEN(_end = .);
|
||||||
PROVIDE_HIDDEN(end = .);
|
PROVIDE_HIDDEN(end = .);
|
||||||
|
@ -477,9 +485,9 @@ PFSTUB4(ape_elf_phnum, (ape_phdrs_end - ape_phdrs) / 56);
|
||||||
PFSTUB4(ape_elf_shnum, 0);
|
PFSTUB4(ape_elf_shnum, 0);
|
||||||
PFSTUB4(ape_elf_shstrndx, 0);
|
PFSTUB4(ape_elf_shstrndx, 0);
|
||||||
|
|
||||||
HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE));
|
HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE));
|
||||||
HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) -
|
HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) -
|
||||||
ROUNDDOWN(__privileged_start, PAGESIZE)));
|
ROUNDDOWN(__privileged_start, PAGESIZE)));
|
||||||
|
|
||||||
HIDDEN(ape_rom_offset = 0);
|
HIDDEN(ape_rom_offset = 0);
|
||||||
HIDDEN(ape_rom_vaddr = ADDR(.head));
|
HIDDEN(ape_rom_vaddr = ADDR(.head));
|
||||||
|
|
|
@ -12,9 +12,12 @@
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/nt/nt/process.h"
|
#include "libc/nt/nt/process.h"
|
||||||
#include "libc/rand/rand.h"
|
#include "libc/rand/rand.h"
|
||||||
|
#include "libc/runtime/gc.h"
|
||||||
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
dontinline void dostuff(const char *s) {
|
dontinline void dostuff(const char *s) {
|
||||||
int i, us;
|
int i, us;
|
||||||
|
@ -29,6 +32,8 @@ dontinline void dostuff(const char *s) {
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int rc, child, wstatus;
|
int rc, child, wstatus;
|
||||||
|
/* puts(_gc(xiso8601ts(NULL))); */
|
||||||
|
PrintMemoryIntervals(2, &_mmi);
|
||||||
CHECK_NE(-1, (child = fork()));
|
CHECK_NE(-1, (child = fork()));
|
||||||
if (!child) {
|
if (!child) {
|
||||||
/* child process */
|
/* child process */
|
||||||
|
|
|
@ -96,6 +96,7 @@ o//libc/calls/fcntl.o: \
|
||||||
OVERRIDE_CFLAGS += \
|
OVERRIDE_CFLAGS += \
|
||||||
-Os
|
-Os
|
||||||
|
|
||||||
|
# must use alloca()
|
||||||
o/$(MODE)/libc/calls/execl.o \
|
o/$(MODE)/libc/calls/execl.o \
|
||||||
o/$(MODE)/libc/calls/execle.o \
|
o/$(MODE)/libc/calls/execle.o \
|
||||||
o/$(MODE)/libc/calls/execlp.o \
|
o/$(MODE)/libc/calls/execlp.o \
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "libc/nt/enum/filemapflags.h"
|
#include "libc/nt/enum/filemapflags.h"
|
||||||
#include "libc/nt/enum/pageflags.h"
|
#include "libc/nt/enum/pageflags.h"
|
||||||
#include "libc/nt/memory.h"
|
#include "libc/nt/memory.h"
|
||||||
|
#include "libc/nt/process.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/struct/overlapped.h"
|
#include "libc/nt/struct/overlapped.h"
|
||||||
#include "libc/runtime/directmap.internal.h"
|
#include "libc/runtime/directmap.internal.h"
|
||||||
|
@ -33,7 +34,6 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
int prot, int flags,
|
int prot, int flags,
|
||||||
int64_t handle, int64_t off) {
|
int64_t handle, int64_t off) {
|
||||||
/* asan runtime depends on this function */
|
/* asan runtime depends on this function */
|
||||||
bool32 rc;
|
|
||||||
uint32_t got;
|
uint32_t got;
|
||||||
size_t i, upsize;
|
size_t i, upsize;
|
||||||
struct DirectMap dm;
|
struct DirectMap dm;
|
||||||
|
@ -44,18 +44,12 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
* combination of flags, that'll cause Windows to actually do this!
|
* combination of flags, that'll cause Windows to actually do this!
|
||||||
*/
|
*/
|
||||||
upsize = ROUNDUP(size, FRAMESIZE);
|
upsize = ROUNDUP(size, FRAMESIZE);
|
||||||
dm.maphandle = CreateFileMappingNuma(-1, &kNtIsInheritable,
|
if ((dm.maphandle = CreateFileMappingNuma(
|
||||||
kNtPageExecuteReadwrite, upsize >> 32,
|
-1, &kNtIsInheritable, kNtPageExecuteReadwrite, upsize >> 32,
|
||||||
upsize, NULL, kNtNumaNoPreferredNode);
|
upsize, NULL, kNtNumaNoPreferredNode))) {
|
||||||
STRACE(
|
if ((dm.addr = MapViewOfFileExNuma(
|
||||||
"CreateFileMappingNuma(-1, kNtPageExecuteReadwrite, %'zu/%'zu) -> %p",
|
dm.maphandle, kNtFileMapWrite | kNtFileMapExecute, 0, 0, upsize,
|
||||||
upsize, size, dm.maphandle);
|
addr, kNtNumaNoPreferredNode))) {
|
||||||
if (dm.maphandle) {
|
|
||||||
dm.addr =
|
|
||||||
MapViewOfFileExNuma(dm.maphandle, kNtFileMapWrite | kNtFileMapExecute,
|
|
||||||
0, 0, upsize, addr, kNtNumaNoPreferredNode);
|
|
||||||
STRACE("MapViewOfFileExNuma(WX, %p) → addr:%p", addr, dm.addr);
|
|
||||||
if (dm.addr) {
|
|
||||||
for (i = 0; i < size; i += got) {
|
for (i = 0; i < size; i += got) {
|
||||||
got = 0;
|
got = 0;
|
||||||
op.Internal = 0;
|
op.Internal = 0;
|
||||||
|
@ -69,37 +63,27 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
if (i == size) {
|
if (i == size) {
|
||||||
return dm;
|
return dm;
|
||||||
}
|
}
|
||||||
rc = UnmapViewOfFile(dm.addr);
|
UnmapViewOfFile(dm.addr);
|
||||||
STRACE("%s(addr:%p) → %hhhd% m", "UnmapViewOfFile", dm.maphandle, rc);
|
|
||||||
}
|
}
|
||||||
rc = CloseHandle(dm.maphandle);
|
CloseHandle(dm.maphandle);
|
||||||
STRACE("%s(%p) → %hhhd% m", "CloseHandle", dm.maphandle, rc);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dm.maphandle = CreateFileMappingNuma(
|
if ((dm.maphandle = CreateFileMappingNuma(
|
||||||
handle, &kNtIsInheritable,
|
handle, &kNtIsInheritable,
|
||||||
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
|
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
|
||||||
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
|
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
|
||||||
kNtNumaNoPreferredNode);
|
kNtNumaNoPreferredNode))) {
|
||||||
STRACE("CreateFileMappingNuma(fhand:%ld, prot:%s, size:%'zu) → %p", handle,
|
if ((dm.addr = MapViewOfFileExNuma(
|
||||||
(prot & PROT_WRITE) ? "XRW" : "XR", handle != -1 ? 0 : size);
|
dm.maphandle,
|
||||||
if (dm.maphandle) {
|
(prot & PROT_WRITE) ? kNtFileMapWrite | kNtFileMapExecute
|
||||||
dm.addr = MapViewOfFileExNuma(
|
: kNtFileMapRead | kNtFileMapExecute,
|
||||||
dm.maphandle,
|
off >> 32, off, size, addr, kNtNumaNoPreferredNode))) {
|
||||||
(prot & PROT_WRITE) ? kNtFileMapWrite | kNtFileMapExecute
|
|
||||||
: kNtFileMapRead | kNtFileMapExecute,
|
|
||||||
off >> 32, off, size, addr, kNtNumaNoPreferredNode);
|
|
||||||
STRACE("MapViewOfFileExNuma(prot:%s, off:%'ld, size:%'zu, addr:%p) → %p",
|
|
||||||
(prot & PROT_WRITE) ? "WX" : "RX", off, size, addr, dm.addr);
|
|
||||||
if (dm.addr) {
|
|
||||||
return dm;
|
return dm;
|
||||||
} else {
|
|
||||||
rc = CloseHandle(dm.maphandle);
|
|
||||||
STRACE("%s(%p) → %d% m", "CloseHandle", dm.maphandle, rc);
|
|
||||||
}
|
}
|
||||||
|
CloseHandle(dm.maphandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dm.maphandle = kNtInvalidHandleValue;
|
dm.maphandle = kNtInvalidHandleValue;
|
||||||
dm.addr = (void *)(intptr_t)__winerr();
|
dm.addr = (void *)(intptr_t)-1;
|
||||||
return dm;
|
return dm;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "libc/nt/struct/processinformation.h"
|
#include "libc/nt/struct/processinformation.h"
|
||||||
#include "libc/nt/struct/startupinfo.h"
|
#include "libc/nt/struct/startupinfo.h"
|
||||||
#include "libc/nt/synchronization.h"
|
#include "libc/nt/synchronization.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
|
|
||||||
|
@ -54,5 +55,5 @@ textwindows int sys_execve_nt(const char *program, char *const argv[],
|
||||||
GetExitCodeProcess(procinfo.hProcess, &dwExitCode);
|
GetExitCodeProcess(procinfo.hProcess, &dwExitCode);
|
||||||
} while (dwExitCode == kNtStillActive);
|
} while (dwExitCode == kNtStillActive);
|
||||||
CloseHandle(procinfo.hProcess);
|
CloseHandle(procinfo.hProcess);
|
||||||
ExitProcess(dwExitCode);
|
_Exit(dwExitCode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ShouldUseMsabiAttribute() 1
|
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
|
@ -52,7 +51,7 @@ noasan noubsan privileged int mprotect(void *addr, size_t len, int prot) {
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (__imp_VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) {
|
if (VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
rc = __winerr();
|
rc = __winerr();
|
||||||
|
|
|
@ -84,7 +84,7 @@ textwindows int ntspawn(
|
||||||
(block =
|
(block =
|
||||||
MapViewOfFileExNuma(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0,
|
MapViewOfFileExNuma(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0,
|
||||||
blocksize, NULL, kNtNumaNoPreferredNode))) {
|
blocksize, NULL, kNtNumaNoPreferredNode))) {
|
||||||
if (mkntcmdline(block->cmdline, prog, argv + 1) != -1 &&
|
if (mkntcmdline(block->cmdline, prog, argv) != -1 &&
|
||||||
mkntenvblock(block->envvars, envp, extravar) != -1) {
|
mkntenvblock(block->envvars, envp, extravar) != -1) {
|
||||||
if (CreateProcess(prog16, block->cmdline, opt_lpProcessAttributes,
|
if (CreateProcess(prog16, block->cmdline, opt_lpProcessAttributes,
|
||||||
opt_lpThreadAttributes, bInheritHandles,
|
opt_lpThreadAttributes, bInheritHandles,
|
||||||
|
@ -95,10 +95,11 @@ textwindows int ntspawn(
|
||||||
} else {
|
} else {
|
||||||
__winerr();
|
__winerr();
|
||||||
}
|
}
|
||||||
STRACE("CreateProcess(%#hs, %#hs) → %d% m", prog16, block->cmdline, rc);
|
STRACE("CreateProcess(%#hs, %!#hs) → %d% m", prog16, block->cmdline, rc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
__winerr();
|
__winerr();
|
||||||
|
STRACE("ntspawn() alloc failed %m");
|
||||||
}
|
}
|
||||||
if (block) UnmapViewOfFile(block);
|
if (block) UnmapViewOfFile(block);
|
||||||
if (handle) CloseHandle(handle);
|
if (handle) CloseHandle(handle);
|
||||||
|
|
|
@ -18,10 +18,12 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/pushpop.h"
|
#include "libc/bits/pushpop.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/siginfo.h"
|
#include "libc/calls/struct/siginfo.h"
|
||||||
#include "libc/calls/typedef/sigaction_f.h"
|
#include "libc/calls/typedef/sigaction_f.h"
|
||||||
#include "libc/nt/enum/ctrlevent.h"
|
#include "libc/nt/enum/ctrlevent.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
|
|
||||||
|
@ -31,16 +33,20 @@ textwindows bool32 __onntconsoleevent(uint32_t CtrlType) {
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
switch (CtrlType) {
|
switch (CtrlType) {
|
||||||
case kNtCtrlCEvent:
|
case kNtCtrlCEvent:
|
||||||
|
STRACE("kNtCtrlCEvent");
|
||||||
sig = pushpop(SIGINT);
|
sig = pushpop(SIGINT);
|
||||||
break;
|
break;
|
||||||
case kNtCtrlBreakEvent:
|
case kNtCtrlBreakEvent:
|
||||||
|
STRACE("kNtCtrlBreakEvent");
|
||||||
sig = pushpop(SIGQUIT);
|
sig = pushpop(SIGQUIT);
|
||||||
break;
|
break;
|
||||||
case kNtCtrlCloseEvent:
|
case kNtCtrlCloseEvent:
|
||||||
|
STRACE("kNtCtrlCloseEvent");
|
||||||
sig = pushpop(SIGHUP);
|
sig = pushpop(SIGHUP);
|
||||||
break;
|
break;
|
||||||
case kNtCtrlLogoffEvent: // only received by services so hack hack hack
|
case kNtCtrlLogoffEvent: // only received by services so hack hack hack
|
||||||
case kNtCtrlShutdownEvent: // only received by services so hack hack hack
|
case kNtCtrlShutdownEvent: // only received by services so hack hack hack
|
||||||
|
STRACE("kNtCtrlLogoffEvent");
|
||||||
sig = pushpop(SIGALRM);
|
sig = pushpop(SIGALRM);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -48,7 +54,7 @@ textwindows bool32 __onntconsoleevent(uint32_t CtrlType) {
|
||||||
}
|
}
|
||||||
switch ((rva = __sighandrvas[sig])) {
|
switch ((rva = __sighandrvas[sig])) {
|
||||||
case (uintptr_t)SIG_DFL:
|
case (uintptr_t)SIG_DFL:
|
||||||
ExitProcess(128 + sig);
|
_Exit(128 + sig);
|
||||||
case (uintptr_t)SIG_IGN:
|
case (uintptr_t)SIG_IGN:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -36,42 +36,82 @@
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
#define _O_APPEND 0x00000400 /* kNtFileAppendData */
|
||||||
|
#define _O_CREAT 0x00000040 /* kNtOpenAlways */
|
||||||
|
#define _O_EXCL 0x00000080 /* kNtCreateNew */
|
||||||
|
#define _O_TRUNC 0x00000200 /* kNtCreateAlways */
|
||||||
|
#define _O_DIRECTORY 0x00010000 /* kNtFileFlagBackupSemantics */
|
||||||
|
#define _O_TMPFILE 0x00410000 /* AttributeTemporary|FlagDeleteOnClose */
|
||||||
|
#define _O_DIRECT 0x00004000 /* kNtFileFlagNoBuffering */
|
||||||
|
#define _O_NDELAY 0x00000800 /* kNtFileFlagWriteThrough */
|
||||||
|
#define _O_RANDOM 0x80000000 /* kNtFileFlagRandomAccess */
|
||||||
|
#define _O_SEQUENTIAL 0x40000000 /* kNtFileFlagSequentialScan */
|
||||||
|
#define _O_COMPRESSED 0x20000000 /* kNtFileAttributeCompressed */
|
||||||
|
#define _O_INDEXED 0x10000000 /* !kNtFileAttributeNotContentIndexed */
|
||||||
|
#define _O_NONBLOCK 0x00000800
|
||||||
|
#define _O_CLOEXEC 0x00080000
|
||||||
|
|
||||||
static textwindows int64_t sys_open_nt_impl(int dirfd, const char *path,
|
static textwindows int64_t sys_open_nt_impl(int dirfd, const char *path,
|
||||||
uint32_t flags, int32_t mode) {
|
uint32_t flags, int32_t mode) {
|
||||||
uint32_t br;
|
uint32_t br;
|
||||||
int64_t handle;
|
int64_t handle;
|
||||||
char16_t path16[PATH_MAX];
|
char16_t path16[PATH_MAX];
|
||||||
|
uint32_t perm, share, disp, attr;
|
||||||
if (__mkntpathat(dirfd, path, flags, path16) == -1) return -1;
|
if (__mkntpathat(dirfd, path, flags, path16) == -1) return -1;
|
||||||
if ((handle = CreateFile(
|
|
||||||
path16, flags & 0xf000000f, /* see consts.sh */
|
switch (flags & O_ACCMODE) {
|
||||||
(flags & O_EXCL)
|
case O_RDONLY:
|
||||||
? kNtFileShareExclusive
|
perm = kNtFileGenericRead | kNtGenericExecute;
|
||||||
: kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete,
|
break;
|
||||||
&kNtIsInheritable,
|
case O_WRONLY:
|
||||||
(flags & O_CREAT) && (flags & O_EXCL) ? kNtCreateNew
|
perm = kNtFileGenericWrite | kNtGenericExecute;
|
||||||
: (flags & O_CREAT) && (flags & O_TRUNC) ? kNtCreateAlways
|
break;
|
||||||
: (flags & O_CREAT) ? kNtOpenAlways
|
case O_RDWR:
|
||||||
: (flags & O_TRUNC) ? kNtTruncateExisting
|
perm = kNtFileGenericRead | kNtFileGenericWrite | kNtGenericExecute;
|
||||||
: kNtOpenExisting,
|
break;
|
||||||
/* TODO(jart): Should we just always set overlapped? */
|
default:
|
||||||
(/* note: content indexer demolishes unix-ey i/o performance */
|
unreachable;
|
||||||
kNtFileAttributeNotContentIndexed | kNtFileAttributeNormal |
|
}
|
||||||
(((flags & ((kNtFileFlagWriteThrough | kNtFileFlagOverlapped |
|
|
||||||
kNtFileFlagNoBuffering | kNtFileFlagRandomAccess) >>
|
if (flags & _O_EXCL) {
|
||||||
8))
|
share = kNtFileShareExclusive;
|
||||||
<< 8) |
|
} else {
|
||||||
(flags & (kNtFileFlagSequentialScan | kNtFileFlagDeleteOnClose |
|
share = kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete;
|
||||||
kNtFileFlagBackupSemantics | kNtFileFlagPosixSemantics |
|
}
|
||||||
kNtFileAttributeTemporary)))),
|
|
||||||
0)) != -1) {
|
if ((flags & _O_CREAT) && (flags & _O_EXCL)) {
|
||||||
} else if (GetLastError() == kNtErrorFileExists &&
|
disp = kNtCreateNew;
|
||||||
((flags & O_CREAT) &&
|
} else if ((flags & _O_CREAT) && (flags & _O_TRUNC)) {
|
||||||
(flags & O_TRUNC))) { /* TODO(jart): What was this? */
|
disp = kNtCreateAlways;
|
||||||
handle = eisdir();
|
} else if (flags & _O_CREAT) {
|
||||||
} else {
|
disp = kNtOpenAlways;
|
||||||
handle = __winerr();
|
} else if (flags & _O_TRUNC) {
|
||||||
|
disp = kNtTruncateExisting;
|
||||||
|
} else {
|
||||||
|
disp = kNtOpenExisting;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & _O_TMPFILE) == _O_TMPFILE) {
|
||||||
|
attr = kNtFileAttributeTemporary | kNtFileFlagDeleteOnClose;
|
||||||
|
} else {
|
||||||
|
attr = kNtFileAttributeNormal;
|
||||||
|
if (flags & _O_DIRECTORY) attr |= kNtFileFlagBackupSemantics;
|
||||||
|
}
|
||||||
|
flags |= kNtFileFlagOverlapped;
|
||||||
|
if (~flags & _O_INDEXED) attr |= kNtFileAttributeNotContentIndexed;
|
||||||
|
if (flags & _O_COMPRESSED) attr |= kNtFileAttributeCompressed;
|
||||||
|
if (flags & _O_SEQUENTIAL) attr |= kNtFileFlagSequentialScan;
|
||||||
|
if (flags & _O_RANDOM) attr |= kNtFileFlagRandomAccess;
|
||||||
|
if (flags & _O_DIRECT) attr |= kNtFileFlagNoBuffering;
|
||||||
|
if (flags & _O_NDELAY) attr |= kNtFileFlagWriteThrough;
|
||||||
|
|
||||||
|
if ((handle = CreateFile(path16, perm, share, &kNtIsInheritable, disp, attr,
|
||||||
|
0)) != -1) {
|
||||||
|
} else if (GetLastError() == kNtErrorFileExists &&
|
||||||
|
((flags & _O_CREAT) &&
|
||||||
|
(flags & _O_TRUNC))) { /* TODO(jart): What was this? */
|
||||||
|
handle = eisdir();
|
||||||
}
|
}
|
||||||
STRACE("CreateFile() → %ld% m", handle);
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/getconsolectrlevent.h"
|
#include "libc/calls/getconsolectrlevent.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/nt/console.h"
|
#include "libc/nt/console.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +34,7 @@
|
||||||
*/
|
*/
|
||||||
int raise(int sig) {
|
int raise(int sig) {
|
||||||
int event;
|
int event;
|
||||||
|
STRACE("raise(%d)", sig);
|
||||||
if (sig == SIGTRAP) {
|
if (sig == SIGTRAP) {
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -50,6 +53,6 @@ int raise(int sig) {
|
||||||
return __winerr();
|
return __winerr();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ExitProcess(128 + sig);
|
_Exit(128 + sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,6 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
||||||
}
|
}
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
} else {
|
} else {
|
||||||
STRACE("%s failed %m", "CreateFile(kNtFileFlagOpenReparsePoint)");
|
|
||||||
rc = sys_readlinkat_nt_error();
|
rc = sys_readlinkat_nt_error();
|
||||||
}
|
}
|
||||||
if (freeme && weaken(free)) {
|
if (freeme && weaken(free)) {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/timespec.h"
|
#include "libc/calls/struct/timespec.h"
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
|
|
||||||
|
@ -24,5 +25,8 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int sleep(uint32_t seconds) {
|
int sleep(uint32_t seconds) {
|
||||||
return nanosleep(&(struct timespec){seconds, 0}, NULL);
|
int rc;
|
||||||
|
rc = nanosleep(&(struct timespec){seconds, 0}, NULL);
|
||||||
|
STRACE("sleep(%u) → %d% m", seconds, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1296,7 +1296,7 @@ void __asan_map_shadow(uintptr_t p, size_t n) {
|
||||||
if (sm.addr == MAP_FAILED ||
|
if (sm.addr == MAP_FAILED ||
|
||||||
weaken(TrackMemoryInterval)(
|
weaken(TrackMemoryInterval)(
|
||||||
m, a, a + i - 1, sm.maphandle, PROT_READ | PROT_WRITE,
|
m, a, a + i - 1, sm.maphandle, PROT_READ | PROT_WRITE,
|
||||||
MAP_PRIVATE | *weaken(MAP_ANONYMOUS) | MAP_FIXED) == -1) {
|
MAP_PRIVATE | *weaken(MAP_ANONYMOUS) | MAP_FIXED, 0, size) == -1) {
|
||||||
kprintf("error: could not map asan shadow memory%n");
|
kprintf("error: could not map asan shadow memory%n");
|
||||||
__asan_die()();
|
__asan_die()();
|
||||||
__asan_unreachable();
|
__asan_unreachable();
|
||||||
|
|
69
libc/intrin/createfile.greg.c
Normal file
69
libc/intrin/createfile.greg.c
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/nt/createfile.h"
|
||||||
|
#include "libc/nt/enum/creationdisposition.h"
|
||||||
|
#include "libc/nt/thunk/msabi.h"
|
||||||
|
|
||||||
|
extern typeof(CreateFile) *const __imp_CreateFileW __msabi;
|
||||||
|
|
||||||
|
static const char *DescribeDisposition(int x) {
|
||||||
|
switch (x) {
|
||||||
|
case kNtCreateNew:
|
||||||
|
return "kNtCreateNew";
|
||||||
|
case kNtCreateAlways:
|
||||||
|
return "kNtCreateAlways";
|
||||||
|
case kNtOpenExisting:
|
||||||
|
return "kNtOpenExisting";
|
||||||
|
case kNtOpenAlways:
|
||||||
|
return "kNtOpenAlways";
|
||||||
|
case kNtTruncateExisting:
|
||||||
|
return "kNtTruncateExisting";
|
||||||
|
default:
|
||||||
|
return "wut";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens file on the New Technology.
|
||||||
|
*
|
||||||
|
* @return handle, or -1 on failure
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
* @see MapViewOfFileExNuma()
|
||||||
|
*/
|
||||||
|
int64_t CreateFile(const char16_t *lpFileName, uint32_t dwDesiredAccess,
|
||||||
|
uint32_t dwShareMode,
|
||||||
|
struct NtSecurityAttributes *opt_lpSecurityAttributes,
|
||||||
|
int dwCreationDisposition, uint32_t dwFlagsAndAttributes,
|
||||||
|
int64_t opt_hTemplateFile) {
|
||||||
|
int64_t hHandle;
|
||||||
|
hHandle = __imp_CreateFileW(lpFileName, dwDesiredAccess, dwShareMode,
|
||||||
|
opt_lpSecurityAttributes, dwCreationDisposition,
|
||||||
|
dwFlagsAndAttributes, opt_hTemplateFile);
|
||||||
|
if (hHandle == -1) __winerr();
|
||||||
|
STRACE("CreateFile(%#hs, %s, %s, %p, %s, %s, %ld) → %ld% m", lpFileName,
|
||||||
|
DescribeNtFileAccessFlags(dwDesiredAccess),
|
||||||
|
DescribeNtFileShareFlags(dwShareMode), opt_lpSecurityAttributes,
|
||||||
|
DescribeDisposition(dwCreationDisposition),
|
||||||
|
DescribeNtFileFlagsAndAttributes(dwFlagsAndAttributes),
|
||||||
|
opt_hTemplateFile, hHandle);
|
||||||
|
return hHandle;
|
||||||
|
}
|
51
libc/intrin/createfilemappingnuma.greg.c
Normal file
51
libc/intrin/createfilemappingnuma.greg.c
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/nt/memory.h"
|
||||||
|
#include "libc/nt/struct/securityattributes.h"
|
||||||
|
|
||||||
|
extern typeof(CreateFileMappingNuma) *const
|
||||||
|
__imp_CreateFileMappingNumaW __msabi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates file mapping object on the New Technology.
|
||||||
|
*
|
||||||
|
* @param opt_hFile may be -1 for MAP_ANONYMOUS behavior
|
||||||
|
* @return handle, or 0 on failure
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
* @see MapViewOfFileExNuma()
|
||||||
|
*/
|
||||||
|
int64_t CreateFileMappingNuma(
|
||||||
|
int64_t opt_hFile,
|
||||||
|
const struct NtSecurityAttributes *opt_lpFileMappingAttributes,
|
||||||
|
uint32_t flProtect, uint32_t dwMaximumSizeHigh, uint32_t dwMaximumSizeLow,
|
||||||
|
const char16_t *opt_lpName, uint32_t nndDesiredNumaNode) {
|
||||||
|
int64_t hHandle;
|
||||||
|
hHandle = __imp_CreateFileMappingNumaW(
|
||||||
|
opt_hFile, opt_lpFileMappingAttributes, flProtect, dwMaximumSizeHigh,
|
||||||
|
dwMaximumSizeLow, opt_lpName, nndDesiredNumaNode);
|
||||||
|
if (!hHandle) __winerr();
|
||||||
|
STRACE("CreateFileMappingNuma(%ld, %s, max:%'zu, name:%#hs) → %ld% m",
|
||||||
|
opt_hFile, DescribeNtPageFlags(flProtect),
|
||||||
|
(uint64_t)dwMaximumSizeHigh << 32 | dwMaximumSizeLow, opt_lpName,
|
||||||
|
hHandle);
|
||||||
|
return hHandle;
|
||||||
|
}
|
59
libc/intrin/describeflags.greg.c
Normal file
59
libc/intrin/describeflags.greg.c
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
|
||||||
|
const char *DescribeFlags(char *p, size_t n, struct DescribeFlags *d, size_t m,
|
||||||
|
const char *prefix, unsigned x) {
|
||||||
|
bool t;
|
||||||
|
char b[21];
|
||||||
|
size_t i, j, k;
|
||||||
|
for (t = i = j = 0; j < m; ++j) {
|
||||||
|
if ((x & d[j].flag) == d[j].flag) {
|
||||||
|
x &= ~d[j].flag;
|
||||||
|
if (t) {
|
||||||
|
if (i + 1 < n) p[i++] = '|';
|
||||||
|
} else {
|
||||||
|
t = true;
|
||||||
|
}
|
||||||
|
for (k = 0; prefix && prefix[k]; ++k) {
|
||||||
|
if (i + 1 < n) p[i++] = prefix[k];
|
||||||
|
}
|
||||||
|
for (k = 0; d[j].name[k]; ++k) {
|
||||||
|
if (i + 1 < n) p[i++] = d[j].name[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x || !t) {
|
||||||
|
if (t && i + 1 < n) p[i++] = '|';
|
||||||
|
if (i + 1 < n) p[i++] = '0';
|
||||||
|
if (x) {
|
||||||
|
if (i + 1 < n) p[i++] = 'x';
|
||||||
|
k = 0;
|
||||||
|
do {
|
||||||
|
if (i + 1 < n) b[k++] = "0123456789abcdef"[x % 16];
|
||||||
|
} while ((x /= 16));
|
||||||
|
while (k--) {
|
||||||
|
if (i + 1 < n) p[i++] = b[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < n) p[i] = 0;
|
||||||
|
return p;
|
||||||
|
}
|
21
libc/intrin/describeflags.internal.h
Normal file
21
libc/intrin/describeflags.internal.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_
|
||||||
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
struct thatispacked DescribeFlags {
|
||||||
|
unsigned flag;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *DescribeFlags(char *, size_t, struct DescribeFlags *, size_t,
|
||||||
|
const char *, unsigned);
|
||||||
|
const char *DescribeNtPageFlags(uint32_t);
|
||||||
|
const char *DescribeNtFileMapFlags(uint32_t);
|
||||||
|
const char *DescribeNtFileFlagsAndAttributes(uint32_t);
|
||||||
|
const char *DescribeNtFileShareFlags(uint32_t);
|
||||||
|
const char *DescribeNtFileAccessFlags(uint32_t);
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_ */
|
70
libc/intrin/describentfileaccessflags.greg.c
Normal file
70
libc/intrin/describentfileaccessflags.greg.c
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/nt/enum/accessmask.h"
|
||||||
|
#include "libc/nt/enum/filesharemode.h"
|
||||||
|
|
||||||
|
static const struct DescribeFlags kFileAccessflags[] = {
|
||||||
|
{kNtFileAllAccess, "FileAllAccess"}, // order matters
|
||||||
|
{kNtFileGenericRead, "FileGenericRead"}, // order matters
|
||||||
|
{kNtFileGenericWrite, "FileGenericWrite"}, // order matters
|
||||||
|
{kNtFileGenericExecute, "FileGenericExecute"}, // order matters
|
||||||
|
{kNtGenericRead, "GenericRead"}, //
|
||||||
|
{kNtGenericWrite, "GenericWrite"}, //
|
||||||
|
{kNtGenericExecute, "GenericExecute"}, //
|
||||||
|
{kNtGenericAll, "GenericAll"}, //
|
||||||
|
{kNtDelete, "Delete"}, //
|
||||||
|
{kNtReadControl, "ReadControl"}, //
|
||||||
|
{kNtWriteDac, "WriteDac"}, //
|
||||||
|
{kNtWriteOwner, "WriteOwner"}, //
|
||||||
|
{kNtSynchronize, "Synchronize"}, //
|
||||||
|
{kNtStandardRightsRequired, "StandardRightsRequired"}, //
|
||||||
|
{kNtAccessSystemSecurity, "AccessSystemSecurity"}, //
|
||||||
|
{kNtMaximumAllowed, "MaximumAllowed"}, //
|
||||||
|
{kNtFileReadData, "FileReadData"}, //
|
||||||
|
{kNtFileListDirectory, "FileListDirectory"}, //
|
||||||
|
{kNtFileWriteData, "FileWriteData"}, //
|
||||||
|
{kNtFileAddFile, "FileAddFile"}, //
|
||||||
|
{kNtFileAppendData, "FileAppendData"}, //
|
||||||
|
{kNtFileAddSubdirectory, "FileAddSubdirectory"}, //
|
||||||
|
{kNtFileCreatePipeInstance, "FileCreatePipeInstance"}, //
|
||||||
|
{kNtFileReadEa, "FileReadEa"}, //
|
||||||
|
{kNtFileWriteEa, "FileWriteEa"}, //
|
||||||
|
{kNtFileExecute, "FileExecute"}, //
|
||||||
|
{kNtFileTraverse, "FileTraverse"}, //
|
||||||
|
{kNtFileDeleteChild, "FileDeleteChild"}, //
|
||||||
|
{kNtFileReadAttributes, "FileReadAttributes"}, //
|
||||||
|
{kNtFileWriteAttributes, "FileWriteAttributes"}, //
|
||||||
|
{kNtTokenAssignPrimary, "TokenAssignPrimary"}, //
|
||||||
|
{kNtTokenDuplicate, "TokenDuplicate"}, //
|
||||||
|
{kNtTokenImpersonate, "TokenImpersonate"}, //
|
||||||
|
{kNtTokenQuery, "TokenQuery"}, //
|
||||||
|
{kNtTokenQuerySource, "TokenQuerySource"}, //
|
||||||
|
{kNtTokenAdjustPrivileges, "TokenAdjustPrivileges"}, //
|
||||||
|
{kNtTokenAdjustGroups, "TokenAdjustGroups"}, //
|
||||||
|
{kNtTokenAdjustDefault, "TokenAdjustDefault"}, //
|
||||||
|
{kNtTokenAdjustSessionid, "TokenAdjustSessionid"}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *DescribeNtFileAccessFlags(uint32_t x) {
|
||||||
|
static char ntfileaccessflags[256];
|
||||||
|
return DescribeFlags(ntfileaccessflags, sizeof(ntfileaccessflags),
|
||||||
|
kFileAccessflags, ARRAYLEN(kFileAccessflags), "kNt", x);
|
||||||
|
}
|
56
libc/intrin/describentfileflagsandattributes.greg.c
Normal file
56
libc/intrin/describentfileflagsandattributes.greg.c
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/nt/enum/fileflagandattributes.h"
|
||||||
|
|
||||||
|
static const struct DescribeFlags kFileFlags[] = {
|
||||||
|
{kNtFileAttributeReadonly, "AttributeReadonly"}, //
|
||||||
|
{kNtFileAttributeHidden, "AttributeHidden"}, //
|
||||||
|
{kNtFileAttributeSystem, "AttributeSystem"}, //
|
||||||
|
{kNtFileAttributeVolumelabel, "AttributeVolumelabel"}, //
|
||||||
|
{kNtFileAttributeDirectory, "AttributeDirectory"}, //
|
||||||
|
{kNtFileAttributeArchive, "AttributeArchive"}, //
|
||||||
|
{kNtFileAttributeDevice, "AttributeDevice"}, //
|
||||||
|
{kNtFileAttributeNormal, "AttributeNormal"}, //
|
||||||
|
{kNtFileAttributeTemporary, "AttributeTemporary"}, //
|
||||||
|
{kNtFileAttributeSparseFile, "AttributeSparseFile"}, //
|
||||||
|
{kNtFileAttributeReparsePoint, "AttributeReparsePoint"}, //
|
||||||
|
{kNtFileAttributeCompressed, "AttributeCompressed"}, //
|
||||||
|
{kNtFileAttributeOffline, "AttributeOffline"}, //
|
||||||
|
{kNtFileAttributeNotContentIndexed, "AttributeNotContentIndexed"}, //
|
||||||
|
{kNtFileAttributeEncrypted, "AttributeEncrypted"}, //
|
||||||
|
{kNtFileFlagWriteThrough, "FlagWriteThrough"}, //
|
||||||
|
{kNtFileFlagOverlapped, "FlagOverlapped"}, //
|
||||||
|
{kNtFileFlagNoBuffering, "FlagNoBuffering"}, //
|
||||||
|
{kNtFileFlagRandomAccess, "FlagRandomAccess"}, //
|
||||||
|
{kNtFileFlagSequentialScan, "FlagSequentialScan"}, //
|
||||||
|
{kNtFileFlagDeleteOnClose, "FlagDeleteOnClose"}, //
|
||||||
|
{kNtFileFlagBackupSemantics, "FlagBackupSemantics"}, //
|
||||||
|
{kNtFileFlagPosixSemantics, "FlagPosixSemantics"}, //
|
||||||
|
{kNtFileFlagOpenReparsePoint, "FlagOpenReparsePoint"}, //
|
||||||
|
{kNtFileFlagOpenNoRecall, "FlagOpenNoRecall"}, //
|
||||||
|
{kNtFileFlagFirstPipeInstance, "FlagFirstPipeInstance"}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *DescribeNtFileFlagsAndAttributes(uint32_t x) {
|
||||||
|
static char ntfileflags[256];
|
||||||
|
return DescribeFlags(ntfileflags, sizeof(ntfileflags), kFileFlags,
|
||||||
|
ARRAYLEN(kFileFlags), "kNtFile", x);
|
||||||
|
}
|
37
libc/intrin/describentfilemapflags.greg.c
Normal file
37
libc/intrin/describentfilemapflags.greg.c
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/nt/enum/filemapflags.h"
|
||||||
|
|
||||||
|
static const struct DescribeFlags kFileMapFlags[] = {
|
||||||
|
{kNtFileMapCopy, "Copy"}, //
|
||||||
|
{kNtFileMapWrite, "Write"}, //
|
||||||
|
{kNtFileMapRead, "Read"}, //
|
||||||
|
{kNtFileMapExecute, "Execute"}, //
|
||||||
|
{kNtFileMapReserve, "Reserve"}, //
|
||||||
|
{kNtFileMapTargetsInvalid, "TargetsInvalid"}, //
|
||||||
|
{kNtFileMapLargePages, "LargePages"}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *DescribeNtFileMapFlags(uint32_t x) {
|
||||||
|
static char filemapflags[64];
|
||||||
|
return DescribeFlags(filemapflags, sizeof(filemapflags), kFileMapFlags,
|
||||||
|
ARRAYLEN(kFileMapFlags), "kNtFileMap", x);
|
||||||
|
}
|
34
libc/intrin/describentfileshareflags.greg.c
Normal file
34
libc/intrin/describentfileshareflags.greg.c
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/nt/enum/filesharemode.h"
|
||||||
|
|
||||||
|
static const struct DescribeFlags kFileShareflags[] = {
|
||||||
|
{kNtFileShareRead, "Read"}, //
|
||||||
|
{kNtFileShareWrite, "Write"}, //
|
||||||
|
{kNtFileShareDelete, "Delete"}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *DescribeNtFileShareFlags(uint32_t x) {
|
||||||
|
static char ntfileshareflags[64];
|
||||||
|
return DescribeFlags(ntfileshareflags, sizeof(ntfileshareflags),
|
||||||
|
kFileShareflags, ARRAYLEN(kFileShareflags),
|
||||||
|
"kNtFileShare", x);
|
||||||
|
}
|
48
libc/intrin/describentpageflags.greg.c
Normal file
48
libc/intrin/describentpageflags.greg.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/nt/enum/pageflags.h"
|
||||||
|
|
||||||
|
static const struct DescribeFlags kPageFlags[] = {
|
||||||
|
{kNtPageNoaccess, "PageNoaccess"}, //
|
||||||
|
{kNtPageReadonly, "PageReadonly"}, //
|
||||||
|
{kNtPageReadwrite, "PageReadwrite"}, //
|
||||||
|
{kNtPageWritecopy, "PageWritecopy"}, //
|
||||||
|
{kNtPageExecute, "PageExecute"}, //
|
||||||
|
{kNtPageExecuteRead, "PageExecuteRead"}, //
|
||||||
|
{kNtPageExecuteReadwrite, "PageExecuteReadwrite"}, //
|
||||||
|
{kNtPageExecuteWritecopy, "PageExecuteWritecopy"}, //
|
||||||
|
{kNtPageGuard, "PageGuard"}, //
|
||||||
|
{kNtPageNocache, "PageNocache"}, //
|
||||||
|
{kNtPageWritecombine, "PageWritecombine"}, //
|
||||||
|
{kNtSecReserve, "SecReserve"}, //
|
||||||
|
{kNtSecCommit, "SecCommit"}, //
|
||||||
|
{kNtSecImageNoExecute, "SecImageNoExecute"}, // order matters
|
||||||
|
{kNtSecImage, "SecImage"}, //
|
||||||
|
{kNtSecLargePages, "SecLargePages"}, //
|
||||||
|
{kNtSecNocache, "SecNocache"}, //
|
||||||
|
{kNtSecWritecombine, "SecWritecombine"}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *DescribeNtPageFlags(uint32_t x) {
|
||||||
|
static char pageflags[64];
|
||||||
|
return DescribeFlags(pageflags, sizeof(pageflags), kPageFlags,
|
||||||
|
ARRAYLEN(kPageFlags), "kNt", x);
|
||||||
|
}
|
|
@ -20,12 +20,17 @@
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
|
||||||
#include "libc/nexgen32e/vendor.internal.h"
|
#include "libc/nexgen32e/vendor.internal.h"
|
||||||
|
#include "libc/nt/console.h"
|
||||||
|
#include "libc/nt/process.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/thunk/msabi.h"
|
#include "libc/nt/thunk/msabi.h"
|
||||||
|
#include "libc/runtime/internal.h"
|
||||||
#include "libc/sysv/consts/nr.h"
|
#include "libc/sysv/consts/nr.h"
|
||||||
|
|
||||||
|
uint32_t __winmainpid;
|
||||||
|
const char kConsoleHandles[2] = {kNtStdInputHandle, kNtStdOutputHandle};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminates process, ignoring destructors and atexit() handlers.
|
* Terminates process, ignoring destructors and atexit() handlers.
|
||||||
*
|
*
|
||||||
|
@ -38,7 +43,13 @@
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
privileged noinstrument noasan noubsan wontreturn void _Exit(int exitcode) {
|
privileged noinstrument noasan noubsan wontreturn void _Exit(int exitcode) {
|
||||||
|
int i;
|
||||||
STRACE("_Exit(%d)", exitcode);
|
STRACE("_Exit(%d)", exitcode);
|
||||||
|
if (SupportsWindows() && GetCurrentProcessId() == __winmainpid) {
|
||||||
|
for (i = 0; i < 2; ++i) {
|
||||||
|
SetConsoleMode(GetStdHandle(kConsoleHandles[i]), __ntconsolemode[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
if ((!IsWindows() && !IsMetal()) || (IsMetal() && IsGenuineCosmo())) {
|
if ((!IsWindows() && !IsMetal()) || (IsMetal() && IsGenuineCosmo())) {
|
||||||
asm volatile("syscall"
|
asm volatile("syscall"
|
||||||
: /* no outputs */
|
: /* no outputs */
|
||||||
|
|
|
@ -57,11 +57,23 @@ o/$(MODE)/libc/intrin/asan.o: \
|
||||||
-finline \
|
-finline \
|
||||||
-finline-functions
|
-finline-functions
|
||||||
|
|
||||||
|
o/$(MODE)/libc/intrin/kprintf.greg.o: \
|
||||||
|
OVERRIDE_CFLAGS += \
|
||||||
|
-fpie \
|
||||||
|
-ffreestanding \
|
||||||
|
$(NO_MAGIC)
|
||||||
|
|
||||||
|
o/$(MODE)/libc/intrin/createfile.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/describeflags.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/mapviewoffileexnuma.greg.o \
|
||||||
|
o/$(MODE)/libc/intrin/createfilemappingnuma.greg.o \
|
||||||
o/$(MODE)/libc/intrin/kstarttsc.o \
|
o/$(MODE)/libc/intrin/kstarttsc.o \
|
||||||
o/$(MODE)/libc/intrin/nomultics.o \
|
o/$(MODE)/libc/intrin/nomultics.o \
|
||||||
o/$(MODE)/libc/intrin/ntconsolemode.o: \
|
o/$(MODE)/libc/intrin/ntconsolemode.o: \
|
||||||
OVERRIDE_CFLAGS += \
|
OVERRIDE_CFLAGS += \
|
||||||
-fno-sanitize=all
|
-Os \
|
||||||
|
-ffreestanding \
|
||||||
|
$(NO_MAGIC)
|
||||||
|
|
||||||
o/$(MODE)/libc/intrin/asan.o \
|
o/$(MODE)/libc/intrin/asan.o \
|
||||||
o/$(MODE)/libc/intrin/ubsan.o: \
|
o/$(MODE)/libc/intrin/ubsan.o: \
|
||||||
|
@ -86,13 +98,6 @@ o/$(MODE)/libc/intrin/memmove.o: \
|
||||||
OVERRIDE_CFLAGS += \
|
OVERRIDE_CFLAGS += \
|
||||||
-fpie
|
-fpie
|
||||||
|
|
||||||
o/$(MODE)/libc/intrin/kprintf.greg.o: \
|
|
||||||
OVERRIDE_CFLAGS += \
|
|
||||||
-fpie \
|
|
||||||
-fwrapv \
|
|
||||||
-fno-sanitize=all \
|
|
||||||
-fschedule-insns2
|
|
||||||
|
|
||||||
LIBC_INTRIN_LIBS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)))
|
LIBC_INTRIN_LIBS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)))
|
||||||
LIBC_INTRIN_HDRS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_HDRS))
|
LIBC_INTRIN_HDRS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_HDRS))
|
||||||
LIBC_INTRIN_SRCS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_SRCS))
|
LIBC_INTRIN_SRCS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_SRCS))
|
||||||
|
|
|
@ -54,16 +54,16 @@ struct Timestamps {
|
||||||
extern int __pid;
|
extern int __pid;
|
||||||
extern bool __replmode;
|
extern bool __replmode;
|
||||||
extern bool __nomultics;
|
extern bool __nomultics;
|
||||||
static volatile unsigned long long kbirth;
|
volatile unsigned long long __kbirth;
|
||||||
|
|
||||||
privileged static struct Timestamps kenter(void) {
|
privileged static struct Timestamps kenter(void) {
|
||||||
struct Timestamps ts;
|
struct Timestamps ts;
|
||||||
ts.start = rdtsc();
|
ts.start = rdtsc();
|
||||||
ts.birth = kbirth;
|
ts.birth = __kbirth;
|
||||||
if (!ts.birth) {
|
if (!ts.birth) {
|
||||||
ts.birth = kStartTsc;
|
ts.birth = kStartTsc;
|
||||||
if (!ts.birth) ts.birth = 1;
|
if (!ts.birth) ts.birth = 1;
|
||||||
cmpxchg(&kbirth, 0, ts.birth);
|
cmpxchg(&__kbirth, 0, ts.birth);
|
||||||
}
|
}
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ privileged static void kleave(struct Timestamps ts) {
|
||||||
elapse = unsignedsubtract(finish, ts.start);
|
elapse = unsignedsubtract(finish, ts.start);
|
||||||
adjust = ts.birth + elapse;
|
adjust = ts.birth + elapse;
|
||||||
if (!adjust) adjust = 1;
|
if (!adjust) adjust = 1;
|
||||||
cmpxchg(&kbirth, ts.birth, adjust); /* ignore overlapping time intervals */
|
cmpxchg(&__kbirth, ts.birth, adjust); /* ignore overlapping time intervals */
|
||||||
}
|
}
|
||||||
|
|
||||||
privileged static inline char *kadvance(char *p, char *e, long n) {
|
privileged static inline char *kadvance(char *p, char *e, long n) {
|
||||||
|
@ -465,7 +465,8 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
||||||
}
|
}
|
||||||
goto EmitChar;
|
goto EmitChar;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (!(x = errno) && sign == ' ') {
|
if (!(x = errno) && sign == ' ' &&
|
||||||
|
(!IsWindows() || !__imp_GetLastError())) {
|
||||||
break;
|
break;
|
||||||
} else if (weaken(strerror_r) &&
|
} else if (weaken(strerror_r) &&
|
||||||
!weaken(strerror_r)(x, z, sizeof(z))) {
|
!weaken(strerror_r)(x, z, sizeof(z))) {
|
||||||
|
@ -572,7 +573,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
||||||
goto EmitChar;
|
goto EmitChar;
|
||||||
}
|
}
|
||||||
} else if (type < -1) {
|
} else if (type < -1) {
|
||||||
if ((t = *s++ & 255)) {
|
if ((t = *s++ & 255) || prec) {
|
||||||
t = kCp437[t];
|
t = kCp437[t];
|
||||||
}
|
}
|
||||||
} else if (type < 0) {
|
} else if (type < 0) {
|
||||||
|
|
52
libc/intrin/mapviewoffileexnuma.greg.c
Normal file
52
libc/intrin/mapviewoffileexnuma.greg.c
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/assert.h"
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/nt/enum/filemapflags.h"
|
||||||
|
#include "libc/nt/memory.h"
|
||||||
|
|
||||||
|
extern typeof(MapViewOfFileExNuma) *const __imp_MapViewOfFileExNuma __msabi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps view of file mapping into memory on the New Technology.
|
||||||
|
*
|
||||||
|
* @param hFileMappingObject was returned by CreateFileMapping()
|
||||||
|
* @param dwDesiredAccess has kNtFileMap... flags
|
||||||
|
* @param opt_lpDesiredBaseAddress may be NULL to let o/s choose
|
||||||
|
* @return base address, or NULL on failure
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
*/
|
||||||
|
void *MapViewOfFileExNuma(int64_t hFileMappingObject, uint32_t dwDesiredAccess,
|
||||||
|
uint32_t dwFileOffsetHigh, uint32_t dwFileOffsetLow,
|
||||||
|
size_t dwNumberOfBytesToMap,
|
||||||
|
void *opt_lpDesiredBaseAddress,
|
||||||
|
uint32_t nndDesiredNumaNode) {
|
||||||
|
void *pStartingAddress;
|
||||||
|
pStartingAddress = __imp_MapViewOfFileExNuma(
|
||||||
|
hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow,
|
||||||
|
dwNumberOfBytesToMap, opt_lpDesiredBaseAddress, nndDesiredNumaNode);
|
||||||
|
if (!pStartingAddress) __winerr();
|
||||||
|
STRACE("MapViewOfFileExNuma(%ld, %s, off:%'ld, size:%'zu, %p) → %p% m",
|
||||||
|
hFileMappingObject, DescribeNtFileMapFlags(dwDesiredAccess),
|
||||||
|
(uint64_t)dwFileOffsetHigh << 32 | dwFileOffsetLow,
|
||||||
|
dwNumberOfBytesToMap, opt_lpDesiredBaseAddress, pStartingAddress);
|
||||||
|
return pStartingAddress;
|
||||||
|
}
|
|
@ -18,32 +18,21 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/nt/enum/pageflags.h"
|
#include "libc/nt/enum/pageflags.h"
|
||||||
#include "libc/nt/memory.h"
|
|
||||||
#include "libc/sysv/consts/map.h"
|
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
|
|
||||||
#define HAS(X, BITS) (((X) & (BITS)) == (BITS))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts System Five memory protection flags to Windows NT, Part 1.
|
|
||||||
* @see libc/sysv/consts.sh
|
|
||||||
*/
|
|
||||||
privileged uint32_t __prot2nt(int prot, int flags) {
|
privileged uint32_t __prot2nt(int prot, int flags) {
|
||||||
return (HAS(prot, PROT_READ | PROT_WRITE | PROT_EXEC)
|
switch (prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) {
|
||||||
? (HAS(flags, MAP_SHARED) || HAS(flags, MAP_ANONYMOUS))
|
case PROT_READ:
|
||||||
? kNtPageExecuteReadwrite
|
return kNtPageReadonly;
|
||||||
: kNtPageExecuteWritecopy
|
case PROT_WRITE:
|
||||||
: HAS(prot, PROT_READ | PROT_WRITE)
|
case PROT_READ | PROT_WRITE:
|
||||||
? (HAS(flags, MAP_SHARED) || HAS(flags, MAP_ANONYMOUS))
|
return kNtPageReadwrite;
|
||||||
? kNtPageReadwrite
|
case PROT_READ | PROT_EXEC:
|
||||||
: kNtPageReadwrite /* kNtPageWritecopy */
|
return kNtPageExecuteRead;
|
||||||
: HAS(prot, PROT_READ | PROT_EXEC)
|
case PROT_WRITE | PROT_EXEC:
|
||||||
? kNtPageExecuteRead
|
case PROT_READ | PROT_WRITE | PROT_EXEC:
|
||||||
: HAS(prot, PROT_EXEC)
|
return kNtPageExecuteReadwrite;
|
||||||
? kNtPageExecute
|
default:
|
||||||
: HAS(prot, PROT_READ) ? kNtPageReadonly
|
return kNtPageNoaccess;
|
||||||
: kNtPageNoaccess) |
|
}
|
||||||
((prot | flags) &
|
|
||||||
(kNtSecReserve | kNtSecCommit | kNtSecImage | kNtSecImageNoExecute |
|
|
||||||
kNtSecLargePages | kNtSecNocache | kNtSecWritecombine));
|
|
||||||
}
|
}
|
|
@ -25,8 +25,6 @@
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
|
|
||||||
const char kConsoleHandles[2] = {kNtStdInputHandle, kNtStdOutputHandle};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exits process faster.
|
* Exits process faster.
|
||||||
*
|
*
|
||||||
|
@ -40,11 +38,6 @@ wontreturn void quick_exit(int exitcode) {
|
||||||
if (weaken(fflush)) {
|
if (weaken(fflush)) {
|
||||||
weaken(fflush)(0);
|
weaken(fflush)(0);
|
||||||
}
|
}
|
||||||
if (SupportsWindows() && __ntconsolemode[0]) {
|
|
||||||
for (i = 0; i < 2; ++i) {
|
|
||||||
SetConsoleMode(GetStdHandle(kConsoleHandles[i]), __ntconsolemode[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (p = __fini_array_end; p > __fini_array_start;) {
|
for (p = __fini_array_end; p > __fini_array_start;) {
|
||||||
((void (*)(void))(*--p))();
|
((void (*)(void))(*--p))();
|
||||||
}
|
}
|
||||||
|
|
39
libc/intrin/virtualprotect.greg.c
Normal file
39
libc/intrin/virtualprotect.greg.c
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/nt/memory.h"
|
||||||
|
|
||||||
|
extern typeof(VirtualProtect) *const __imp_VirtualProtect __msabi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protects memory on the New Technology.
|
||||||
|
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||||
|
*/
|
||||||
|
bool32 VirtualProtect(void *lpAddress, uint64_t dwSize, uint32_t flNewProtect,
|
||||||
|
uint32_t *lpflOldProtect) {
|
||||||
|
bool32 bOk;
|
||||||
|
bOk = __imp_VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect);
|
||||||
|
if (!bOk) __winerr();
|
||||||
|
STRACE("VirtualProtect(%p, %'zu, %s, [%s]) → %hhhd% m", lpAddress, dwSize,
|
||||||
|
DescribeNtPageFlags(flNewProtect),
|
||||||
|
DescribeNtPageFlags(*lpflOldProtect), bOk);
|
||||||
|
return bOk;
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ relegated wontreturn void __die(void) {
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
}
|
}
|
||||||
ShowBacktrace(2, NULL);
|
ShowBacktrace(2, NULL);
|
||||||
quick_exit(77);
|
_Exit(77);
|
||||||
}
|
}
|
||||||
__write_str("PANIC: __DIE() DIED\r\n");
|
__write_str("PANIC: __DIE() DIED\r\n");
|
||||||
_Exit(78);
|
_Exit(78);
|
||||||
|
|
|
@ -316,7 +316,7 @@ relegated noinstrument void __oncrash(int sig, struct siginfo *si,
|
||||||
if (!(gdbpid > 0 && (sig == SIGTRAP || sig == SIGQUIT))) {
|
if (!(gdbpid > 0 && (sig == SIGTRAP || sig == SIGQUIT))) {
|
||||||
__restore_tty(1);
|
__restore_tty(1);
|
||||||
ShowCrashReport(err, sig, si, ctx);
|
ShowCrashReport(err, sig, si, ctx);
|
||||||
quick_exit(128 + sig);
|
_Exit(128 + sig);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
__minicrash(sig, si, ctx, "WHILE VFORKED");
|
__minicrash(sig, si, ctx, "WHILE VFORKED");
|
||||||
|
|
|
@ -20,38 +20,38 @@
|
||||||
* };
|
* };
|
||||||
* };
|
* };
|
||||||
*/
|
*/
|
||||||
#define kNtGenericRead 0x80000000u
|
#define kNtGenericRead 0x80000000u
|
||||||
#define kNtGenericWrite 0x40000000u
|
#define kNtGenericWrite 0x40000000u
|
||||||
#define kNtGenericExecute 0x20000000u
|
#define kNtGenericExecute 0x20000000u
|
||||||
#define kNtGenericAll 0x10000000u
|
#define kNtGenericAll 0x10000000u
|
||||||
#define kNtDelete 0x00010000u
|
#define kNtDelete 0x00010000u
|
||||||
#define kNtReadControl 0x00020000u
|
#define kNtReadControl 0x00020000u
|
||||||
#define kNtWriteDac 0x00040000u
|
#define kNtWriteDac 0x00040000u
|
||||||
#define kNtWriteOwner 0x00080000u
|
#define kNtWriteOwner 0x00080000u
|
||||||
#define kNtSynchronize 0x00100000u
|
#define kNtSynchronize 0x00100000u
|
||||||
#define kNtStandardRightsRequired 0x000F0000u
|
#define kNtStandardRightsRequired 0x000F0000u
|
||||||
#define kNtStandardRightsRead kNtReadControl
|
#define kNtStandardRightsRead kNtReadControl
|
||||||
#define kNtStandardRightsWrite kNtReadControl
|
#define kNtStandardRightsWrite kNtReadControl
|
||||||
#define kNtStandardRightsExecute kNtReadControl
|
#define kNtStandardRightsExecute kNtReadControl
|
||||||
#define kNtStandardRightsAll 0x001F0000u
|
#define kNtStandardRightsAll 0x001F0000u
|
||||||
#define kNtSpecificRightsAll 0x0000FFFFu
|
#define kNtSpecificRightsAll 0x0000FFFFu
|
||||||
#define kNtAccessSystemSecurity 0x01000000u
|
#define kNtAccessSystemSecurity 0x01000000u
|
||||||
#define kNtMaximumAllowed 0x02000000u
|
#define kNtMaximumAllowed 0x02000000u
|
||||||
#define kNtFileReadData 0x0001u
|
#define kNtFileReadData 0x0001u
|
||||||
#define kNtFileListDirectory 0x0001u
|
#define kNtFileListDirectory 0x0001u
|
||||||
#define kNtFileWriteData 0x0002u
|
#define kNtFileWriteData 0x0002u
|
||||||
#define kNtFileAddFile 0x0002u
|
#define kNtFileAddFile 0x0002u
|
||||||
#define kNtFileAppendData 0x0004u
|
#define kNtFileAppendData 0x0004u
|
||||||
#define kNtFileAddSubdirectory 0x0004u
|
#define kNtFileAddSubdirectory 0x0004u
|
||||||
#define kNtFileCreatePipeInstance 0x0004u
|
#define kNtFileCreatePipeInstance 0x0004u
|
||||||
#define kNtFileReadEa 0x0008u
|
#define kNtFileReadEa 0x0008u
|
||||||
#define kNtFileWriteEa 0x0010u
|
#define kNtFileWriteEa 0x0010u
|
||||||
#define kNtFileExecute 0x0020u
|
#define kNtFileExecute 0x0020u
|
||||||
#define kNtFileTraverse 0x0020u
|
#define kNtFileTraverse 0x0020u
|
||||||
#define kNtFileDeleteChild 0x0040u
|
#define kNtFileDeleteChild 0x0040u
|
||||||
#define kNtFileReadAttributes 0x0080u
|
#define kNtFileReadAttributes 0x0080u
|
||||||
#define kNtFileWriteAttributes 0x0100u
|
#define kNtFileWriteAttributes 0x0100u
|
||||||
#define kNtFileAllAccess (kNtStandardRightsRequired | kNtSynchronize | 0x1FFu)
|
#define kNtFileAllAccess (kNtStandardRightsRequired | kNtSynchronize | 0x1FFu)
|
||||||
#define kNtFileGenericRead \
|
#define kNtFileGenericRead \
|
||||||
(kNtStandardRightsRead | kNtFileReadData | kNtFileReadAttributes | \
|
(kNtStandardRightsRead | kNtFileReadData | kNtFileReadAttributes | \
|
||||||
kNtFileReadEa | kNtSynchronize)
|
kNtFileReadEa | kNtSynchronize)
|
||||||
|
@ -61,21 +61,21 @@
|
||||||
#define kNtFileGenericExecute \
|
#define kNtFileGenericExecute \
|
||||||
(kNtStandardRightsExecute | kNtFileReadAttributes | kNtFileExecute | \
|
(kNtStandardRightsExecute | kNtFileReadAttributes | kNtFileExecute | \
|
||||||
kNtSynchronize)
|
kNtSynchronize)
|
||||||
#define kNtTokenAssignPrimary 0x0001u
|
#define kNtTokenAssignPrimary 0x0001u
|
||||||
#define kNtTokenDuplicate 0x0002u
|
#define kNtTokenDuplicate 0x0002u
|
||||||
#define kNtTokenImpersonate 0x0004u
|
#define kNtTokenImpersonate 0x0004u
|
||||||
#define kNtTokenQuery 0x0008u
|
#define kNtTokenQuery 0x0008u
|
||||||
#define kNtTokenQuerySource 0x0010u
|
#define kNtTokenQuerySource 0x0010u
|
||||||
#define kNtTokenAdjustPrivileges 0x0020u
|
#define kNtTokenAdjustPrivileges 0x0020u
|
||||||
#define kNtTokenAdjustGroups 0x0040u
|
#define kNtTokenAdjustGroups 0x0040u
|
||||||
#define kNtTokenAdjustDefault 0x0080u
|
#define kNtTokenAdjustDefault 0x0080u
|
||||||
#define kNtTokenAdjustSessionid 0x0100u
|
#define kNtTokenAdjustSessionid 0x0100u
|
||||||
#define kNtTokenAllAccessP \
|
#define kNtTokenAllAccessP \
|
||||||
(kNtStandardRightsRequired | kNtTokenAssignPrimary | kNtTokenDuplicate | \
|
(kNtStandardRightsRequired | kNtTokenAssignPrimary | kNtTokenDuplicate | \
|
||||||
kNtTokenImpersonate | kNtTokenQuery | kNtTokenQuerySource | \
|
kNtTokenImpersonate | kNtTokenQuery | kNtTokenQuerySource | \
|
||||||
kNtTokenAdjustPrivileges | kNtTokenAdjustGroups | kNtTokenAdjustDefault)
|
kNtTokenAdjustPrivileges | kNtTokenAdjustGroups | kNtTokenAdjustDefault)
|
||||||
#define kNtTokenAllAccess kNtTokenAllAccessP | kNtTokenAdjustSessionid
|
#define kNtTokenAllAccess kNtTokenAllAccessP | kNtTokenAdjustSessionid
|
||||||
#define kNtTokenRead kNtStandardRightsRead | kNtTokenQuery
|
#define kNtTokenRead kNtStandardRightsRead | kNtTokenQuery
|
||||||
#define kNtTokenWrite \
|
#define kNtTokenWrite \
|
||||||
(kNtStandardRightsWrite | kNtTokenAdjustPrivileges | kNtTokenAdjustGroups | \
|
(kNtStandardRightsWrite | kNtTokenAdjustPrivileges | kNtTokenAdjustGroups | \
|
||||||
kNtTokenAdjustDefault)
|
kNtTokenAdjustDefault)
|
||||||
|
@ -83,6 +83,6 @@
|
||||||
#define kNtTokenTrustConstraintMask \
|
#define kNtTokenTrustConstraintMask \
|
||||||
(kNtStandardRightsRead | kNtTokenQuery | kNtTokenQuerySource)
|
(kNtStandardRightsRead | kNtTokenQuery | kNtTokenQuerySource)
|
||||||
#define kNtTokenAccessPseudoHandleWin8 kNtTokenQuery | kNtTokenQuerySource
|
#define kNtTokenAccessPseudoHandleWin8 kNtTokenQuery | kNtTokenQuerySource
|
||||||
#define kNtTokenAccessPseudoHandle kNtTokenAccessPseudoHandleWin8
|
#define kNtTokenAccessPseudoHandle kNtTokenAccessPseudoHandleWin8
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_ACCESSMASK_H_ */
|
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_ACCESSMASK_H_ */
|
||||||
|
|
9
libc/nt/enum/heap.h
Normal file
9
libc/nt/enum/heap.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_HEAP_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_NT_ENUM_HEAP_H_
|
||||||
|
|
||||||
|
#define kNtHeapNoSerialize 1
|
||||||
|
#define kNtHeapGenerateExceptions 4
|
||||||
|
#define kNtHeapZeroMemory 8
|
||||||
|
#define kNtHeapReallocInPlaceOnly 16
|
||||||
|
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_HEAP_H_ */
|
|
@ -2,25 +2,25 @@
|
||||||
#define COSMOPOLITAN_LIBC_NT_ENUM_PAGEFLAGS_H_
|
#define COSMOPOLITAN_LIBC_NT_ENUM_PAGEFLAGS_H_
|
||||||
|
|
||||||
/* Pick One */
|
/* Pick One */
|
||||||
#define kNtPageNoaccess 0x01
|
#define kNtPageNoaccess 0x001
|
||||||
#define kNtPageReadonly 0x02
|
#define kNtPageReadonly 0x002
|
||||||
#define kNtPageReadwrite 0x04
|
#define kNtPageReadwrite 0x004
|
||||||
#define kNtPageWritecopy 0x08
|
#define kNtPageWritecopy 0x008
|
||||||
#define kNtPageExecute 0x10
|
#define kNtPageExecute 0x010
|
||||||
#define kNtPageExecuteRead 0x20
|
#define kNtPageExecuteRead 0x020
|
||||||
#define kNtPageExecuteReadwrite 0x40
|
#define kNtPageExecuteReadwrite 0x040
|
||||||
#define kNtPageExecuteWritecopy 0x80
|
#define kNtPageExecuteWritecopy 0x080
|
||||||
#define kNtPageGuard 0x100
|
#define kNtPageGuard 0x100
|
||||||
#define kNtPageNocache 0x200
|
#define kNtPageNocache 0x200
|
||||||
#define kNtPageWritecombine 0x400
|
#define kNtPageWritecombine 0x400
|
||||||
|
|
||||||
/* These may be OR'd */
|
/* These may be OR'd */
|
||||||
#define kNtSecReserve 0x4000000
|
#define kNtSecReserve 0x04000000
|
||||||
#define kNtSecCommit 0x8000000 /* ←default */
|
#define kNtSecCommit 0x08000000 /* default */
|
||||||
#define kNtSecImage 0x1000000
|
|
||||||
#define kNtSecImageNoExecute 0x11000000
|
#define kNtSecImageNoExecute 0x11000000
|
||||||
#define kNtSecLargePages 0x80000000
|
#define kNtSecImage 0x01000000
|
||||||
#define kNtSecNocache 0x10000000
|
#define kNtSecNocache 0x10000000
|
||||||
#define kNtSecWritecombine 0x40000000
|
#define kNtSecLargePages 0x80000000
|
||||||
|
#define kNtSecWritecombine 0x40000000
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_PAGEFLAGS_H_ */
|
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_PAGEFLAGS_H_ */
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
.imp kernel32,__imp_CreateFileMappingNumaW,CreateFileMappingNumaW,0
|
.imp kernel32,__imp_CreateFileMappingNumaW,CreateFileMappingNumaW,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
CreateFileMappingNuma:
|
__CreateFileMappingNuma:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
mov __imp_CreateFileMappingNumaW(%rip),%rax
|
mov __imp_CreateFileMappingNumaW(%rip),%rax
|
||||||
jmp __sysv2nt8
|
jmp __sysv2nt8
|
||||||
.endfn CreateFileMappingNuma,globl
|
.endfn __CreateFileMappingNuma,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
.imp kernel32,__imp_CreateFileW,CreateFileW,0
|
.imp kernel32,__imp_CreateFileW,CreateFileW,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
CreateFile:
|
__CreateFile:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
mov __imp_CreateFileW(%rip),%rax
|
mov __imp_CreateFileW(%rip),%rax
|
||||||
jmp __sysv2nt8
|
jmp __sysv2nt8
|
||||||
.endfn CreateFile,globl
|
.endfn __CreateFile,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -1,2 +1,14 @@
|
||||||
.include "o/libc/nt/codegen.inc"
|
.include "o/libc/nt/codegen.inc"
|
||||||
.imp kernel32,__imp_GetProcessHeap,GetProcessHeap,0
|
.imp kernel32,__imp_GetProcessHeap,GetProcessHeap,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
GetProcessHeap:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
sub $32,%rsp
|
||||||
|
call *__imp_GetProcessHeap(%rip)
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
.endfn GetProcessHeap,globl
|
||||||
|
.previous
|
||||||
|
|
|
@ -1,2 +1,12 @@
|
||||||
.include "o/libc/nt/codegen.inc"
|
.include "o/libc/nt/codegen.inc"
|
||||||
.imp kernel32,__imp_GetProcessHeaps,GetProcessHeaps,0
|
.imp kernel32,__imp_GetProcessHeaps,GetProcessHeaps,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
GetProcessHeaps:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_GetProcessHeaps(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn GetProcessHeaps,globl
|
||||||
|
.previous
|
||||||
|
|
12
libc/nt/kernel32/HeapAlloc.s
Normal file
12
libc/nt/kernel32/HeapAlloc.s
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.include "o/libc/nt/codegen.inc"
|
||||||
|
.imp kernel32,__imp_HeapAlloc,HeapAlloc,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
HeapAlloc:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_HeapAlloc(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn HeapAlloc,globl
|
||||||
|
.previous
|
|
@ -1,2 +1,12 @@
|
||||||
.include "o/libc/nt/codegen.inc"
|
.include "o/libc/nt/codegen.inc"
|
||||||
.imp kernel32,__imp_HeapCompact,HeapCompact,0
|
.imp kernel32,__imp_HeapCompact,HeapCompact,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
HeapCompact:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_HeapCompact(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn HeapCompact,globl
|
||||||
|
.previous
|
||||||
|
|
|
@ -1,2 +1,12 @@
|
||||||
.include "o/libc/nt/codegen.inc"
|
.include "o/libc/nt/codegen.inc"
|
||||||
.imp kernel32,__imp_HeapCreate,HeapCreate,0
|
.imp kernel32,__imp_HeapCreate,HeapCreate,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
HeapCreate:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_HeapCreate(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn HeapCreate,globl
|
||||||
|
.previous
|
||||||
|
|
|
@ -1,2 +1,15 @@
|
||||||
.include "o/libc/nt/codegen.inc"
|
.include "o/libc/nt/codegen.inc"
|
||||||
.imp kernel32,__imp_HeapDestroy,HeapDestroy,0
|
.imp kernel32,__imp_HeapDestroy,HeapDestroy,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
HeapDestroy:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov %rdi,%rcx
|
||||||
|
sub $32,%rsp
|
||||||
|
call *__imp_HeapDestroy(%rip)
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
.endfn HeapDestroy,globl
|
||||||
|
.previous
|
||||||
|
|
|
@ -1,2 +1,12 @@
|
||||||
.include "o/libc/nt/codegen.inc"
|
.include "o/libc/nt/codegen.inc"
|
||||||
.imp kernel32,__imp_HeapFree,HeapFree,847
|
.imp kernel32,__imp_HeapFree,HeapFree,847
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
HeapFree:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_HeapFree(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn HeapFree,globl
|
||||||
|
.previous
|
||||||
|
|
12
libc/nt/kernel32/HeapReAlloc.s
Normal file
12
libc/nt/kernel32/HeapReAlloc.s
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.include "o/libc/nt/codegen.inc"
|
||||||
|
.imp kernel32,__imp_HeapReAlloc,HeapReAlloc,0
|
||||||
|
|
||||||
|
.text.windows
|
||||||
|
HeapReAlloc:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
.profilable
|
||||||
|
mov __imp_HeapReAlloc(%rip),%rax
|
||||||
|
jmp __sysv2nt
|
||||||
|
.endfn HeapReAlloc,globl
|
||||||
|
.previous
|
|
@ -2,11 +2,11 @@
|
||||||
.imp kernel32,__imp_MapViewOfFileExNuma,MapViewOfFileExNuma,0
|
.imp kernel32,__imp_MapViewOfFileExNuma,MapViewOfFileExNuma,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
MapViewOfFileExNuma:
|
__MapViewOfFileExNuma:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
mov __imp_MapViewOfFileExNuma(%rip),%rax
|
mov __imp_MapViewOfFileExNuma(%rip),%rax
|
||||||
jmp __sysv2nt8
|
jmp __sysv2nt8
|
||||||
.endfn MapViewOfFileExNuma,globl
|
.endfn __MapViewOfFileExNuma,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
.imp kernel32,__imp_VirtualProtect,VirtualProtect,0
|
.imp kernel32,__imp_VirtualProtect,VirtualProtect,0
|
||||||
|
|
||||||
.text.windows
|
.text.windows
|
||||||
VirtualProtect:
|
__VirtualProtect:
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
.profilable
|
.profilable
|
||||||
mov __imp_VirtualProtect(%rip),%rax
|
mov __imp_VirtualProtect(%rip),%rax
|
||||||
jmp __sysv2nt
|
jmp __sysv2nt
|
||||||
.endfn VirtualProtect,globl
|
.endfn __VirtualProtect,globl
|
||||||
.previous
|
.previous
|
||||||
|
|
|
@ -593,9 +593,10 @@ imp 'CreateEventEx' CreateEventExW kernel32 0 4 # KernelBase
|
||||||
imp 'CreateEvent' CreateEventW kernel32 0 4 # KernelBase
|
imp 'CreateEvent' CreateEventW kernel32 0 4 # KernelBase
|
||||||
imp 'CreateFiber' CreateFiber kernel32 0 # KernelBase
|
imp 'CreateFiber' CreateFiber kernel32 0 # KernelBase
|
||||||
imp 'CreateFiberEx' CreateFiberEx kernel32 0 # KernelBase
|
imp 'CreateFiberEx' CreateFiberEx kernel32 0 # KernelBase
|
||||||
imp 'CreateFile' CreateFileW kernel32 0 7 # KernelBase
|
|
||||||
imp 'CreateFileA' CreateFileA kernel32 0 7 # KernelBase
|
imp 'CreateFileA' CreateFileA kernel32 0 7 # KernelBase
|
||||||
imp 'CreateFileMappingNuma' CreateFileMappingNumaW kernel32 0 7 # Kernelbase
|
imp '__CreateFile' CreateFileW kernel32 0 7 # KernelBase
|
||||||
|
imp '__CreateFileMappingNuma' CreateFileMappingNumaW kernel32 0 7 # Kernelbase
|
||||||
|
imp '__MapViewOfFileExNuma' MapViewOfFileExNuma kernel32 0 7 # KernelBase
|
||||||
imp 'CreateFileMappingNumaA' CreateFileMappingNumaA kernel32 198 7
|
imp 'CreateFileMappingNumaA' CreateFileMappingNumaA kernel32 198 7
|
||||||
imp 'CreateFileMapping' CreateFileMappingW kernel32 0 7 # KernelBase
|
imp 'CreateFileMapping' CreateFileMappingW kernel32 0 7 # KernelBase
|
||||||
imp 'CreateFileMappingA' CreateFileMappingA kernel32 196 7
|
imp 'CreateFileMappingA' CreateFileMappingA kernel32 196 7
|
||||||
|
@ -2474,8 +2475,8 @@ imp 'GetProcessDefaultLayout' GetProcessDefaultLayout user32 1930
|
||||||
imp 'GetProcessDpiAwarenessInternal' GetProcessDpiAwarenessInternal user32 1931
|
imp 'GetProcessDpiAwarenessInternal' GetProcessDpiAwarenessInternal user32 1931
|
||||||
imp 'GetProcessGroupAffinity' GetProcessGroupAffinity kernel32 0 # KernelBase
|
imp 'GetProcessGroupAffinity' GetProcessGroupAffinity kernel32 0 # KernelBase
|
||||||
imp 'GetProcessHandleCount' GetProcessHandleCount kernel32 0 2 # KernelBase
|
imp 'GetProcessHandleCount' GetProcessHandleCount kernel32 0 2 # KernelBase
|
||||||
imp 'GetProcessHeap' GetProcessHeap kernel32 0 # KernelBase
|
imp 'GetProcessHeap' GetProcessHeap kernel32 0 0 # KernelBase
|
||||||
imp 'GetProcessHeaps' GetProcessHeaps kernel32 0 # KernelBase
|
imp 'GetProcessHeaps' GetProcessHeaps kernel32 0 2 # KernelBase
|
||||||
imp 'GetProcessId' GetProcessId kernel32 0 1 # KernelBase
|
imp 'GetProcessId' GetProcessId kernel32 0 1 # KernelBase
|
||||||
imp 'GetProcessIdOfThread' GetProcessIdOfThread kernel32 0 1 # KernelBase
|
imp 'GetProcessIdOfThread' GetProcessIdOfThread kernel32 0 1 # KernelBase
|
||||||
imp 'GetProcessImageFileNameA' GetProcessImageFileNameA kernel32 676 3
|
imp 'GetProcessImageFileNameA' GetProcessImageFileNameA kernel32 676 3
|
||||||
|
@ -2817,10 +2818,12 @@ imp 'Heap32First' Heap32First kernel32 839
|
||||||
imp 'Heap32ListFirst' Heap32ListFirst kernel32 840
|
imp 'Heap32ListFirst' Heap32ListFirst kernel32 840
|
||||||
imp 'Heap32ListNext' Heap32ListNext kernel32 841
|
imp 'Heap32ListNext' Heap32ListNext kernel32 841
|
||||||
imp 'Heap32Next' Heap32Next kernel32 842
|
imp 'Heap32Next' Heap32Next kernel32 842
|
||||||
imp 'HeapCompact' HeapCompact kernel32 0 # KernelBase
|
imp 'HeapCompact' HeapCompact kernel32 0 2 # KernelBase
|
||||||
imp 'HeapCreate' HeapCreate kernel32 0 # KernelBase
|
imp 'HeapAlloc' HeapAlloc kernel32 0 3
|
||||||
imp 'HeapDestroy' HeapDestroy kernel32 0 # KernelBase
|
imp 'HeapReAlloc' HeapReAlloc kernel32 0 4
|
||||||
imp 'HeapFree' HeapFree kernel32 847
|
imp 'HeapCreate' HeapCreate kernel32 0 3 # KernelBase
|
||||||
|
imp 'HeapDestroy' HeapDestroy kernel32 0 1 # KernelBase
|
||||||
|
imp 'HeapFree' HeapFree kernel32 847 3
|
||||||
imp 'HeapLock' HeapLock kernel32 0 # KernelBase
|
imp 'HeapLock' HeapLock kernel32 0 # KernelBase
|
||||||
imp 'HeapQueryInformation' HeapQueryInformation kernel32 0 # KernelBase
|
imp 'HeapQueryInformation' HeapQueryInformation kernel32 0 # KernelBase
|
||||||
imp 'HeapSetInformation' HeapSetInformation kernel32 0 # KernelBase
|
imp 'HeapSetInformation' HeapSetInformation kernel32 0 # KernelBase
|
||||||
|
@ -3380,7 +3383,6 @@ imp 'MapViewOfFile' MapViewOfFile kernel32 0 # KernelBase
|
||||||
imp 'MapViewOfFile3' MapViewOfFile3 KernelBase 1003
|
imp 'MapViewOfFile3' MapViewOfFile3 KernelBase 1003
|
||||||
imp 'MapViewOfFile3FromApp' MapViewOfFile3FromApp KernelBase 1004
|
imp 'MapViewOfFile3FromApp' MapViewOfFile3FromApp KernelBase 1004
|
||||||
imp 'MapViewOfFileEx' MapViewOfFileEx kernel32 0 # KernelBase
|
imp 'MapViewOfFileEx' MapViewOfFileEx kernel32 0 # KernelBase
|
||||||
imp 'MapViewOfFileExNuma' MapViewOfFileExNuma kernel32 0 7 # KernelBase
|
|
||||||
imp 'MapViewOfFileFromApp' MapViewOfFileFromApp kernel32 0 # KernelBase
|
imp 'MapViewOfFileFromApp' MapViewOfFileFromApp kernel32 0 # KernelBase
|
||||||
imp 'MapViewOfFileNuma2' MapViewOfFileNuma2 KernelBase 1008
|
imp 'MapViewOfFileNuma2' MapViewOfFileNuma2 KernelBase 1008
|
||||||
imp 'MapVirtualKeyA' MapVirtualKeyA user32 2153
|
imp 'MapVirtualKeyA' MapVirtualKeyA user32 2153
|
||||||
|
@ -6879,7 +6881,7 @@ imp 'VirtualAllocFromApp' VirtualAllocFromApp KernelBase 1760
|
||||||
imp 'VirtualFree' VirtualFree kernel32 0 3 # KernelBase
|
imp 'VirtualFree' VirtualFree kernel32 0 3 # KernelBase
|
||||||
imp 'VirtualFreeEx' VirtualFreeEx kernel32 0 # KernelBase
|
imp 'VirtualFreeEx' VirtualFreeEx kernel32 0 # KernelBase
|
||||||
imp 'VirtualLock' VirtualLock kernel32 0 # KernelBase
|
imp 'VirtualLock' VirtualLock kernel32 0 # KernelBase
|
||||||
imp 'VirtualProtect' VirtualProtect kernel32 0 4 # KernelBase
|
imp '__VirtualProtect' VirtualProtect kernel32 0 4 # KernelBase
|
||||||
imp 'VirtualProtectEx' VirtualProtectEx kernel32 0 # KernelBase
|
imp 'VirtualProtectEx' VirtualProtectEx kernel32 0 # KernelBase
|
||||||
imp 'VirtualProtectFromApp' VirtualProtectFromApp KernelBase 1766
|
imp 'VirtualProtectFromApp' VirtualProtectFromApp KernelBase 1766
|
||||||
imp 'VirtualQuery' VirtualQuery kernel32 0 3 # KernelBase
|
imp 'VirtualQuery' VirtualQuery kernel32 0 3 # KernelBase
|
||||||
|
|
|
@ -70,6 +70,12 @@ bool32 PrefetchVirtualMemory(int64_t hProcess, const uint32_t *NumberOfEntries,
|
||||||
bool32 OfferVirtualMemory(void *inout_VirtualAddress, size_t Size,
|
bool32 OfferVirtualMemory(void *inout_VirtualAddress, size_t Size,
|
||||||
int Priority);
|
int Priority);
|
||||||
|
|
||||||
|
int64_t GetProcessHeap(void);
|
||||||
|
void *HeapAlloc(int64_t hHeap, uint32_t dwFlags, size_t dwBytes) nodiscard;
|
||||||
|
bool32 HeapFree(int64_t hHeap, uint32_t dwFlags, void *opt_lpMem);
|
||||||
|
void *HeapReAlloc(int64_t hHeap, uint32_t dwFlags, void *lpMem,
|
||||||
|
size_t dwBytes) nodiscard;
|
||||||
|
|
||||||
void *GlobalAlloc(uint32_t uFlags, uint64_t dwBytes) nodiscard;
|
void *GlobalAlloc(uint32_t uFlags, uint64_t dwBytes) nodiscard;
|
||||||
void *GlobalFree(void *hMem);
|
void *GlobalFree(void *hMem);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
#define CreateFileMappingNuma(...) __imp_CreateFileMappingNumaW(__VA_ARGS__)
|
#define FlushViewOfFile(...) __imp_FlushViewOfFile(__VA_ARGS__)
|
||||||
#define MapViewOfFileExNuma(...) __imp_MapViewOfFileExNuma(__VA_ARGS__)
|
#define UnmapViewOfFile(...) __imp_UnmapViewOfFile(__VA_ARGS__)
|
||||||
#define FlushViewOfFile(...) __imp_FlushViewOfFile(__VA_ARGS__)
|
|
||||||
#define UnmapViewOfFile(...) __imp_UnmapViewOfFile(__VA_ARGS__)
|
|
||||||
|
|
||||||
extern typeof(LocalFree) *const __imp_LocalFree __msabi;
|
extern typeof(LocalFree) *const __imp_LocalFree __msabi;
|
||||||
extern typeof(VirtualProtect) *const __imp_VirtualProtect __msabi;
|
|
||||||
extern typeof(UnmapViewOfFile) *const __imp_UnmapViewOfFile __msabi;
|
extern typeof(UnmapViewOfFile) *const __imp_UnmapViewOfFile __msabi;
|
||||||
extern typeof(FlushViewOfFile) *const __imp_FlushViewOfFile __msabi;
|
extern typeof(FlushViewOfFile) *const __imp_FlushViewOfFile __msabi;
|
||||||
extern typeof(MapViewOfFileExNuma) *const __imp_MapViewOfFileExNuma __msabi;
|
|
||||||
extern typeof(CreateFileMappingNuma) *const
|
|
||||||
__imp_CreateFileMappingNumaW __msabi;
|
|
||||||
|
|
|
@ -22,20 +22,27 @@
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ntspawn.h"
|
#include "libc/calls/ntspawn.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
#include "libc/fmt/itoa.h"
|
#include "libc/fmt/itoa.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/mem/alloca.h"
|
||||||
#include "libc/nexgen32e/nt2sysv.h"
|
#include "libc/nexgen32e/nt2sysv.h"
|
||||||
#include "libc/nt/dll.h"
|
#include "libc/nt/dll.h"
|
||||||
|
#include "libc/nt/enum/exceptionhandleractions.h"
|
||||||
#include "libc/nt/enum/filemapflags.h"
|
#include "libc/nt/enum/filemapflags.h"
|
||||||
#include "libc/nt/enum/memflags.h"
|
#include "libc/nt/enum/memflags.h"
|
||||||
#include "libc/nt/enum/pageflags.h"
|
#include "libc/nt/enum/pageflags.h"
|
||||||
#include "libc/nt/enum/startf.h"
|
#include "libc/nt/enum/startf.h"
|
||||||
#include "libc/nt/enum/wt.h"
|
#include "libc/nt/enum/wt.h"
|
||||||
|
#include "libc/nt/files.h"
|
||||||
#include "libc/nt/ipc.h"
|
#include "libc/nt/ipc.h"
|
||||||
#include "libc/nt/memory.h"
|
#include "libc/nt/memory.h"
|
||||||
#include "libc/nt/process.h"
|
#include "libc/nt/process.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/signals.h"
|
#include "libc/nt/signals.h"
|
||||||
|
#include "libc/nt/struct/context.h"
|
||||||
|
#include "libc/nt/struct/ntexceptionpointers.h"
|
||||||
#include "libc/nt/synchronization.h"
|
#include "libc/nt/synchronization.h"
|
||||||
#include "libc/nt/thread.h"
|
#include "libc/nt/thread.h"
|
||||||
#include "libc/runtime/directmap.internal.h"
|
#include "libc/runtime/directmap.internal.h"
|
||||||
|
@ -49,7 +56,14 @@
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
static textwindows noasan char16_t *ParseInt(char16_t *p, int64_t *x) {
|
extern int __pid;
|
||||||
|
extern unsigned long long __kbirth;
|
||||||
|
extern unsigned char __data_start[]; /* αpε */
|
||||||
|
extern unsigned char __data_end[]; /* αpε */
|
||||||
|
extern unsigned char __bss_start[]; /* αpε */
|
||||||
|
extern unsigned char __bss_end[]; /* αpε */
|
||||||
|
|
||||||
|
static textwindows char16_t *ParseInt(char16_t *p, int64_t *x) {
|
||||||
*x = 0;
|
*x = 0;
|
||||||
while (*p == ' ') p++;
|
while (*p == ' ') p++;
|
||||||
while ('0' <= *p && *p <= '9') {
|
while ('0' <= *p && *p <= '9') {
|
||||||
|
@ -59,89 +73,211 @@ static textwindows noasan char16_t *ParseInt(char16_t *p, int64_t *x) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dontinline textwindows noasan bool ForkIo(int64_t h, void *buf, size_t n,
|
static inline textwindows ssize_t ForkIo(int64_t h, char *p, size_t n,
|
||||||
bool32 (*f)()) {
|
bool32 (*f)()) {
|
||||||
char *p;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
for (p = buf, i = 0; i < n; i += x) {
|
for (i = 0; i < n; i += x) {
|
||||||
if (!f(h, p + i, n - i, &x, NULL)) {
|
if (!f(h, p + i, n - i, &x, NULL)) {
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dontinline textwindows noasan void WriteAll(int64_t h, void *buf,
|
static dontinline textwindows bool ForkIo2(int64_t h, void *buf, size_t n,
|
||||||
size_t n) {
|
bool32 (*fn)(), const char *sf) {
|
||||||
bool rc = ForkIo(h, buf, n, WriteFile);
|
ssize_t rc = ForkIo(h, buf, n, fn);
|
||||||
STRACE("%s(%ld, %'zu) %d% m", "WriteFile", h, n);
|
STRACE("%s(%ld, %'zu) → %'zd% m", sf, h, n, rc);
|
||||||
|
return rc != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static textwindows dontinline noasan void ReadAll(int64_t h, void *buf,
|
static dontinline textwindows bool WriteAll(int64_t h, void *buf, size_t n) {
|
||||||
size_t n) {
|
return ForkIo2(h, buf, n, WriteFile, "WriteFile");
|
||||||
bool rc = ForkIo(h, buf, n, ReadFile);
|
|
||||||
STRACE("%s(%ld, %'zu) %d% m", "ReadFile", h, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
textwindows noasan noinstrument void WinMainForked(void) {
|
static textwindows dontinline bool ReadAll(int64_t h, void *buf, size_t n) {
|
||||||
void *addr;
|
return ForkIo2(h, buf, n, ReadFile, "ReadFile");
|
||||||
|
}
|
||||||
|
|
||||||
|
static textwindows int OnForkCrash(struct NtExceptionPointers *ep) {
|
||||||
|
kprintf("error: fork() child crashed!%n"
|
||||||
|
"\tExceptionCode = %#x%n"
|
||||||
|
"\tRip = %x%n"
|
||||||
|
"\tRax = %.16x R8 = %.16x%n"
|
||||||
|
"\tRbx = %.16x R9 = %.16x%n"
|
||||||
|
"\tRcx = %.16x R10 = %.16x%n"
|
||||||
|
"\tRdx = %.16x R11 = %.16x%n"
|
||||||
|
"\tRdi = %.16x R12 = %.16x%n"
|
||||||
|
"\tRsi = %.16x R13 = %.16x%n"
|
||||||
|
"\tRbp = %.16x R14 = %.16x%n"
|
||||||
|
"\tRsp = %.16x R15 = %.16x%n",
|
||||||
|
ep->ExceptionRecord->ExceptionCode,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->Rip : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->Rax : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->R8 : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->Rbx : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->R9 : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->Rcx : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->R10 : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->Rdx : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->R11 : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->Rdi : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->R12 : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->Rsi : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->R13 : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->Rbp : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->R14 : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->Rsp : -1,
|
||||||
|
ep->ContextRecord ? ep->ContextRecord->R15 : -1);
|
||||||
|
ExitProcess(73);
|
||||||
|
}
|
||||||
|
|
||||||
|
textwindows void WinMainForked(void) {
|
||||||
jmp_buf jb;
|
jmp_buf jb;
|
||||||
long mapcount;
|
char *addr, *shad;
|
||||||
uint64_t size;
|
|
||||||
uint32_t i, varlen;
|
|
||||||
struct DirectMap dm;
|
struct DirectMap dm;
|
||||||
|
uint64_t size, upsize;
|
||||||
int64_t reader, writer;
|
int64_t reader, writer;
|
||||||
struct MemoryInterval *maps;
|
struct MemoryInterval *maps;
|
||||||
char16_t var[21 + 1 + 21 + 1];
|
char16_t fvar[21 + 1 + 21 + 1];
|
||||||
varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var));
|
int64_t oncrash, savetsc, savebir;
|
||||||
if (!varlen) return;
|
uint32_t i, varlen, oldprot, savepid;
|
||||||
if (varlen >= ARRAYLEN(var)) ExitProcess(123);
|
long mapcount, mapcapacity, specialz;
|
||||||
|
extern uint64_t ts asm("kStartTsc");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check to see if the process was actually forked
|
||||||
|
* this variable should have the pipe handle numba
|
||||||
|
*/
|
||||||
|
varlen = GetEnvironmentVariable(u"_FORK", fvar, ARRAYLEN(fvar));
|
||||||
|
if (!varlen || varlen >= ARRAYLEN(fvar)) return;
|
||||||
STRACE("WinMainForked()");
|
STRACE("WinMainForked()");
|
||||||
SetEnvironmentVariable(u"_FORK", NULL);
|
SetEnvironmentVariable(u"_FORK", NULL);
|
||||||
ParseInt(ParseInt(var, &reader), &writer);
|
#ifdef SYSDEBUG
|
||||||
|
oncrash = AddVectoredExceptionHandler(1, NT2SYSV(OnForkCrash));
|
||||||
|
#endif
|
||||||
|
ParseInt(ParseInt(fvar, &reader), &writer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read the cpu state from the parent process
|
||||||
|
*/
|
||||||
ReadAll(reader, jb, sizeof(jb));
|
ReadAll(reader, jb, sizeof(jb));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read the list of mappings from the parent process
|
||||||
|
* this is stored in a special secretive memory map!
|
||||||
|
* read ExtendMemoryIntervals for further details :|
|
||||||
|
*/
|
||||||
|
maps = (void *)kMemtrackStart;
|
||||||
ReadAll(reader, &mapcount, sizeof(_mmi.i));
|
ReadAll(reader, &mapcount, sizeof(_mmi.i));
|
||||||
maps = GlobalAlloc(0, mapcount * sizeof(*_mmi.p));
|
ReadAll(reader, &mapcapacity, sizeof(_mmi.n));
|
||||||
ReadAll(reader, maps, mapcount * sizeof(*_mmi.p));
|
specialz = ROUNDUP(mapcapacity * sizeof(_mmi.p[0]), kMemtrackGran);
|
||||||
|
MapViewOfFileExNuma(CreateFileMappingNuma(
|
||||||
|
-1, &kNtIsInheritable, kNtPageReadwrite,
|
||||||
|
specialz >> 32, specialz, 0, kNtNumaNoPreferredNode),
|
||||||
|
kNtFileMapWrite, 0, 0, specialz, maps,
|
||||||
|
kNtNumaNoPreferredNode);
|
||||||
|
ReadAll(reader, maps, mapcount * sizeof(_mmi.p[0]));
|
||||||
|
if (IsAsan()) {
|
||||||
|
shad = (char *)(((intptr_t)maps >> 3) + 0x7fff8000);
|
||||||
|
size = ROUNDUP(specialz >> 3, FRAMESIZE);
|
||||||
|
MapViewOfFileExNuma(
|
||||||
|
CreateFileMappingNuma(-1, &kNtIsInheritable, kNtPageReadwrite,
|
||||||
|
size >> 32, size, 0, kNtNumaNoPreferredNode),
|
||||||
|
kNtFileMapWrite, 0, 0, size, maps, kNtNumaNoPreferredNode);
|
||||||
|
#if 0
|
||||||
|
ReadAll(reader, shad, (mapcount * sizeof(_mmi.p[0])) >> 3);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read the heap mappings from the parent process
|
||||||
|
* we can avoid copying via pipe for shared maps!
|
||||||
|
*/
|
||||||
for (i = 0; i < mapcount; ++i) {
|
for (i = 0; i < mapcount; ++i) {
|
||||||
addr = (void *)((uint64_t)maps[i].x << 16);
|
addr = (char *)((uint64_t)maps[i].x << 16);
|
||||||
size = ((uint64_t)(maps[i].y - maps[i].x) << 16) + FRAMESIZE;
|
size = maps[i].size;
|
||||||
if (maps[i].flags & MAP_PRIVATE) {
|
if (maps[i].flags & MAP_PRIVATE) {
|
||||||
CloseHandle(maps[i].h);
|
STRACE("fork() child %p %'zu copying private map", addr, size);
|
||||||
maps[i].h =
|
if (!CloseHandle(maps[i].h)) {
|
||||||
sys_mmap_nt(addr, size, maps[i].prot, maps[i].flags, -1, 0).maphandle;
|
STRACE("fork() child CloseHandle(%ld) ~~~FAILED~~~ %m", maps[i].h);
|
||||||
|
}
|
||||||
|
upsize = ROUNDUP(size, FRAMESIZE);
|
||||||
|
maps[i].h = CreateFileMappingNuma(-1, &kNtIsInheritable,
|
||||||
|
kNtPageExecuteReadwrite, upsize >> 32,
|
||||||
|
upsize, NULL, kNtNumaNoPreferredNode);
|
||||||
|
MapViewOfFileExNuma(maps[i].h, kNtFileMapWrite | kNtFileMapExecute, 0, 0,
|
||||||
|
upsize, addr, kNtNumaNoPreferredNode);
|
||||||
ReadAll(reader, addr, size);
|
ReadAll(reader, addr, size);
|
||||||
} else {
|
} else {
|
||||||
MapViewOfFileExNuma(
|
STRACE("fork() child %p %'zu mapping shared hand:%ld offset:%'lu", addr,
|
||||||
maps[i].h,
|
size, maps[i].h, maps[i].offset);
|
||||||
(maps[i].prot & PROT_WRITE)
|
MapViewOfFileExNuma(maps[i].h,
|
||||||
? kNtFileMapWrite | kNtFileMapExecute | kNtFileMapRead
|
(maps[i].prot & PROT_WRITE)
|
||||||
: kNtFileMapExecute | kNtFileMapRead,
|
? kNtFileMapWrite | kNtFileMapExecute
|
||||||
0, 0, size, addr, kNtNumaNoPreferredNode);
|
: kNtFileMapRead | kNtFileMapExecute,
|
||||||
|
maps[i].offset >> 32, maps[i].offset, size, addr,
|
||||||
|
kNtNumaNoPreferredNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReadAll(reader, _etext, _end - _etext);
|
|
||||||
|
/*
|
||||||
|
* read the .data and .bss program image sections
|
||||||
|
*/
|
||||||
|
savepid = __pid;
|
||||||
|
savebir = __kbirth;
|
||||||
|
savetsc = ts;
|
||||||
|
STRACE("fork() child reading %'zu bytes of .data to %p",
|
||||||
|
__data_end - __data_start, __data_start);
|
||||||
|
ReadAll(reader, __data_start, __data_end - __data_start);
|
||||||
|
STRACE("fork() child reading %'zu bytes of .bss to %p",
|
||||||
|
__bss_end - __bss_start, __bss_start);
|
||||||
|
ReadAll(reader, __bss_start, __bss_end - __bss_start);
|
||||||
|
__pid = savepid;
|
||||||
|
__kbirth = savebir;
|
||||||
|
ts = savetsc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* apply fixups and reapply memory protections
|
||||||
|
*/
|
||||||
|
STRACE("fork() child applying fixups to _mmi.p");
|
||||||
|
_mmi.p = maps;
|
||||||
|
_mmi.n = specialz / sizeof(_mmi.p[0]);
|
||||||
for (i = 0; i < mapcount; ++i) {
|
for (i = 0; i < mapcount; ++i) {
|
||||||
_mmi.p[i].h = maps[i].h;
|
if ((maps[i].flags & MAP_PRIVATE) && (~maps[i].prot & PROT_WRITE)) {
|
||||||
|
VirtualProtect((void *)((uint64_t)maps[i].x << 16),
|
||||||
|
ROUNDUP(maps[i].size, FRAMESIZE),
|
||||||
|
__prot2nt(maps[i].prot, 0), &oldprot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clean up and restore old processor state
|
||||||
|
*/
|
||||||
|
STRACE("fork() child almost done!");
|
||||||
CloseHandle(reader);
|
CloseHandle(reader);
|
||||||
CloseHandle(writer);
|
CloseHandle(writer);
|
||||||
GlobalFree(maps);
|
#ifdef SYSDEBUG
|
||||||
|
RemoveVectoredExceptionHandler(oncrash);
|
||||||
|
#endif
|
||||||
if (weaken(__wincrash_nt)) {
|
if (weaken(__wincrash_nt)) {
|
||||||
AddVectoredExceptionHandler(1, (void *)weaken(__wincrash_nt));
|
AddVectoredExceptionHandler(1, (void *)weaken(__wincrash_nt));
|
||||||
}
|
}
|
||||||
|
STRACE("fork() child it's time for the big jump (>'.')>");
|
||||||
longjmp(jb, 1);
|
longjmp(jb, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
textwindows int sys_fork_nt(void) {
|
textwindows int sys_fork_nt(void) {
|
||||||
|
bool ok;
|
||||||
jmp_buf jb;
|
jmp_buf jb;
|
||||||
|
char **args, **args2;
|
||||||
int64_t reader, writer;
|
int64_t reader, writer;
|
||||||
int i, rc, pid, releaseme;
|
int i, n, rc, pid, untrackpid;
|
||||||
char *p, forkvar[6 + 21 + 1 + 21 + 1];
|
char *p, forkvar[6 + 21 + 1 + 21 + 1];
|
||||||
struct NtStartupInfo startinfo;
|
struct NtStartupInfo startinfo;
|
||||||
struct NtProcessInformation procinfo;
|
struct NtProcessInformation procinfo;
|
||||||
if ((pid = releaseme = __reservefd()) == -1) return -1;
|
if ((pid = untrackpid = __reservefd()) == -1) return -1;
|
||||||
if (!setjmp(jb)) {
|
if (!setjmp(jb)) {
|
||||||
if (CreatePipe(&reader, &writer, &kNtIsInheritable, 0)) {
|
if (CreatePipe(&reader, &writer, &kNtIsInheritable, 0)) {
|
||||||
p = stpcpy(forkvar, "_FORK=");
|
p = stpcpy(forkvar, "_FORK=");
|
||||||
|
@ -153,43 +289,94 @@ textwindows int sys_fork_nt(void) {
|
||||||
startinfo.hStdInput = g_fds.p[0].handle;
|
startinfo.hStdInput = g_fds.p[0].handle;
|
||||||
startinfo.hStdOutput = g_fds.p[1].handle;
|
startinfo.hStdOutput = g_fds.p[1].handle;
|
||||||
startinfo.hStdError = g_fds.p[2].handle;
|
startinfo.hStdError = g_fds.p[2].handle;
|
||||||
if (ntspawn(program_executable_name, __argv, environ, forkvar,
|
args = __argv;
|
||||||
|
#ifdef SYSDEBUG
|
||||||
|
/*
|
||||||
|
* If --strace was passed to this program, then propagate it the
|
||||||
|
* forked process since the flag was removed by __intercept_flag
|
||||||
|
*/
|
||||||
|
if (__strace > 0) {
|
||||||
|
for (n = 0; args[n];) ++n;
|
||||||
|
args2 = alloca((n + 2) * sizeof(char *));
|
||||||
|
for (i = 0; i < n; ++i) args2[i] = args[i];
|
||||||
|
args2[i++] = "--strace";
|
||||||
|
args2[i] = 0;
|
||||||
|
args = args2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ntspawn(program_executable_name, args, environ, forkvar,
|
||||||
&kNtIsInheritable, NULL, true, 0, NULL, &startinfo,
|
&kNtIsInheritable, NULL, true, 0, NULL, &startinfo,
|
||||||
&procinfo) != -1) {
|
&procinfo) != -1) {
|
||||||
CloseHandle(reader);
|
CloseHandle(reader);
|
||||||
CloseHandle(procinfo.hThread);
|
CloseHandle(procinfo.hThread);
|
||||||
if (weaken(__sighandrvas) &&
|
ok = WriteAll(writer, jb, sizeof(jb)) &&
|
||||||
weaken(__sighandrvas)[SIGCHLD] == SIG_IGN) {
|
WriteAll(writer, &_mmi.i, sizeof(_mmi.i)) &&
|
||||||
CloseHandle(procinfo.hProcess);
|
WriteAll(writer, &_mmi.n, sizeof(_mmi.n)) &&
|
||||||
} else {
|
WriteAll(writer, _mmi.p, _mmi.i * sizeof(_mmi.p[0]));
|
||||||
g_fds.p[pid].kind = kFdProcess;
|
#if 0
|
||||||
g_fds.p[pid].handle = procinfo.hProcess;
|
if (IsAsan() && ok) {
|
||||||
g_fds.p[pid].flags = O_CLOEXEC;
|
ok = WriteAll(writer, (char *)(((intptr_t)_mmi.p >> 3) + 0x7fff8000),
|
||||||
releaseme = -1;
|
(_mmi.i * sizeof(_mmi.p[0])) >> 3);
|
||||||
}
|
}
|
||||||
WriteAll(writer, jb, sizeof(jb));
|
#endif
|
||||||
WriteAll(writer, &_mmi.i, sizeof(_mmi.i));
|
for (i = 0; i < _mmi.i && ok; ++i) {
|
||||||
WriteAll(writer, _mmi.p, _mmi.i * sizeof(*_mmi.p));
|
|
||||||
for (i = 0; i < _mmi.i; ++i) {
|
|
||||||
if (_mmi.p[i].flags & MAP_PRIVATE) {
|
if (_mmi.p[i].flags & MAP_PRIVATE) {
|
||||||
WriteAll(writer, (void *)((uint64_t)_mmi.p[i].x << 16),
|
ok = WriteAll(writer, (void *)((uint64_t)_mmi.p[i].x << 16),
|
||||||
((uint64_t)(_mmi.p[i].y - _mmi.p[i].x) << 16) + FRAMESIZE);
|
_mmi.p[i].size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WriteAll(writer, _etext, _end - _etext);
|
if (ok) {
|
||||||
CloseHandle(writer);
|
STRACE("fork() parent writing %'zu bytes of .data",
|
||||||
|
__data_end - __data_start);
|
||||||
|
ok = WriteAll(writer, __data_start, __data_end - __data_start);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
STRACE("fork() parent writing %'zu bytes of .bss",
|
||||||
|
__bss_end - __bss_start);
|
||||||
|
ok = WriteAll(writer, __bss_start, __bss_end - __bss_start);
|
||||||
|
}
|
||||||
|
ok = ok & !!CloseHandle(writer);
|
||||||
|
if (ok) {
|
||||||
|
if (!weaken(__sighandrvas) ||
|
||||||
|
weaken(__sighandrvas)[SIGCHLD] != SIG_IGN) {
|
||||||
|
g_fds.p[pid].kind = kFdProcess;
|
||||||
|
g_fds.p[pid].handle = procinfo.hProcess;
|
||||||
|
g_fds.p[pid].flags = O_CLOEXEC;
|
||||||
|
untrackpid = -1;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* XXX: Ignoring SIGCHLD should track the process information.
|
||||||
|
* What we need to do instead, is periodically check if a
|
||||||
|
* process has exited and remove it automatically via i/o
|
||||||
|
* functions like poll() so it doesn't get zombdied.
|
||||||
|
*/
|
||||||
|
STRACE("fork() parent closing process handle b/c SIGCHLD=SIG_IGN");
|
||||||
|
CloseHandle(procinfo.hProcess);
|
||||||
|
}
|
||||||
|
STRACE("fork() parent everything looks good");
|
||||||
|
rc = pid;
|
||||||
|
} else {
|
||||||
|
STRACE("fork() parent ~~failed~~ because writing failed");
|
||||||
|
rc = __winerr();
|
||||||
|
TerminateProcess(procinfo.hProcess, 127);
|
||||||
|
CloseHandle(procinfo.hProcess);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
STRACE("fork() parent ~~failed~~ because ntspawn failed");
|
||||||
|
CloseHandle(writer);
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
rc = pid;
|
|
||||||
} else {
|
} else {
|
||||||
|
STRACE("fork() parent ~~failed~~ because CreatePipe() failed %m");
|
||||||
rc = __winerr();
|
rc = __winerr();
|
||||||
|
CloseHandle(writer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
STRACE("fork() child welcome back <('.'<)");
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
if (releaseme != -1) {
|
if (untrackpid != -1) {
|
||||||
__releasefd(releaseme);
|
__releasefd(untrackpid);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ static noasan bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
|
||||||
base = (char *)kMemtrackStart;
|
base = (char *)kMemtrackStart;
|
||||||
prot = PROT_READ | PROT_WRITE;
|
prot = PROT_READ | PROT_WRITE;
|
||||||
flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED;
|
flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED;
|
||||||
|
/* TODO(jart): These map handles should not leak across NT fork() */
|
||||||
if (mm->p == mm->s) {
|
if (mm->p == mm->s) {
|
||||||
if (IsAsan()) {
|
if (IsAsan()) {
|
||||||
shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000);
|
shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000);
|
||||||
|
@ -170,7 +171,7 @@ noasan int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y,
|
||||||
}
|
}
|
||||||
|
|
||||||
noasan int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h,
|
noasan int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h,
|
||||||
int prot, int flags) {
|
int prot, int flags, long offset, long size) {
|
||||||
/* asan runtime depends on this function */
|
/* asan runtime depends on this function */
|
||||||
unsigned i;
|
unsigned i;
|
||||||
assert(y >= x);
|
assert(y >= x);
|
||||||
|
@ -194,6 +195,8 @@ noasan int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h,
|
||||||
mm->p[i].h = h;
|
mm->p[i].h = h;
|
||||||
mm->p[i].prot = prot;
|
mm->p[i].prot = prot;
|
||||||
mm->p[i].flags = flags;
|
mm->p[i].flags = flags;
|
||||||
|
mm->p[i].offset = offset;
|
||||||
|
mm->p[i].size = size;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,11 @@ COSMOPOLITAN_C_START_
|
||||||
#define kAutomapSize \
|
#define kAutomapSize \
|
||||||
_kMem(0x200000000000 - 0x100080000000 - _kMmi(0x800000000000), \
|
_kMem(0x200000000000 - 0x100080000000 - _kMmi(0x800000000000), \
|
||||||
0x000040000000 - 0x000010000000 - _kMmi(0x000080000000))
|
0x000040000000 - 0x000010000000 - _kMmi(0x000080000000))
|
||||||
#define kMemtrackStart \
|
#define kMemtrackStart \
|
||||||
_kMem(0x200000000000 - _kMmi(0x800000000000), \
|
(ROUNDDOWN(_kMem(0x200000000000 - _kMmi(0x800000000000), \
|
||||||
0x000040000000 - _kMmi(0x000080000000))
|
0x000040000000 - _kMmi(0x000080000000)), \
|
||||||
|
FRAMESIZE * 8) - \
|
||||||
|
0x8000 * 8 /* so frame aligned after adding 0x7fff8000 */)
|
||||||
#define kMemtrackSize _kMem(_kMmi(0x800000000000), _kMmi(0x000080000000))
|
#define kMemtrackSize _kMem(_kMmi(0x800000000000), _kMmi(0x000080000000))
|
||||||
#define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8)
|
#define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8)
|
||||||
#define kFixedmapStart _kMem(0x300000000000, 0x000040000000)
|
#define kFixedmapStart _kMem(0x300000000000, 0x000040000000)
|
||||||
|
@ -34,6 +36,8 @@ struct MemoryInterval {
|
||||||
long h;
|
long h;
|
||||||
int prot;
|
int prot;
|
||||||
int flags;
|
int flags;
|
||||||
|
long offset;
|
||||||
|
long size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MemoryIntervals {
|
struct MemoryIntervals {
|
||||||
|
@ -50,8 +54,8 @@ char *DescribeProt(int, char[hasatleast 4]);
|
||||||
char *DescribeMapping(int, int, char[hasatleast 8]) hidden;
|
char *DescribeMapping(int, int, char[hasatleast 8]) hidden;
|
||||||
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden;
|
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden;
|
||||||
void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden;
|
void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden;
|
||||||
int TrackMemoryInterval(struct MemoryIntervals *, int, int, long, int,
|
int TrackMemoryInterval(struct MemoryIntervals *, int, int, long, int, int,
|
||||||
int) hidden;
|
long, long) hidden;
|
||||||
int ReleaseMemoryIntervals(struct MemoryIntervals *, int, int,
|
int ReleaseMemoryIntervals(struct MemoryIntervals *, int, int,
|
||||||
void (*)(struct MemoryIntervals *, int, int)) hidden;
|
void (*)(struct MemoryIntervals *, int, int)) hidden;
|
||||||
void ReleaseMemoryNt(struct MemoryIntervals *, int, int) hidden;
|
void ReleaseMemoryNt(struct MemoryIntervals *, int, int) hidden;
|
||||||
|
|
|
@ -128,7 +128,8 @@ static noasan void *MapMemory(void *addr, size_t size, int prot, int flags,
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TrackMemoryInterval(&_mmi, x, x + (n - 1), dm.maphandle, prot, flags)) {
|
if (TrackMemoryInterval(&_mmi, x, x + (n - 1), dm.maphandle, prot, flags, off,
|
||||||
|
size)) {
|
||||||
if (sys_munmap(addr, n) == -1) {
|
if (sys_munmap(addr, n) == -1) {
|
||||||
STRACE("TRACK MUNMAP FAILED %m");
|
STRACE("TRACK MUNMAP FAILED %m");
|
||||||
assert(!"MapMemory() failed");
|
assert(!"MapMemory() failed");
|
||||||
|
@ -152,26 +153,31 @@ static textwindows dontinline noasan void *MapMemories(char *addr, size_t size,
|
||||||
int prot, int flags,
|
int prot, int flags,
|
||||||
int fd, int64_t off,
|
int fd, int64_t off,
|
||||||
int f, int x, size_t n) {
|
int f, int x, size_t n) {
|
||||||
|
int64_t oi, sz;
|
||||||
struct DirectMap dm;
|
struct DirectMap dm;
|
||||||
size_t i, m = (n - 1) * FRAMESIZE;
|
size_t i, m = (n - 1) * FRAMESIZE;
|
||||||
assert(m < size && m + FRAMESIZE >= size);
|
assert(m < size && m + FRAMESIZE >= size);
|
||||||
dm = sys_mmap(addr + m, size - m, prot, f, fd, fd == -1 ? 0 : off + m);
|
oi = fd == -1 ? 0 : off + m;
|
||||||
|
sz = size - m;
|
||||||
|
dm = sys_mmap(addr + m, sz, prot, f, fd, oi);
|
||||||
if (dm.addr == MAP_FAILED) {
|
if (dm.addr == MAP_FAILED) {
|
||||||
STRACE("MapMemories(%.12p+%lx/%lx) %m", addr, m, size);
|
STRACE("MapMemories(%.12p+%lx/%lx) %m", addr, m, size);
|
||||||
return MAP_FAILED;
|
return MAP_FAILED;
|
||||||
}
|
}
|
||||||
if (TrackMemoryInterval(&_mmi, x + (n - 1), x + (n - 1), dm.maphandle, prot,
|
if (TrackMemoryInterval(&_mmi, x + (n - 1), x + (n - 1), dm.maphandle, prot,
|
||||||
flags) == -1) {
|
flags, oi, sz) == -1) {
|
||||||
STRACE("MapMemories(%.12p+%lx/%lx) unrecoverable failure #1 %m", addr, m,
|
STRACE("MapMemories(%.12p+%lx/%lx) unrecoverable failure #1 %m", addr, m,
|
||||||
size);
|
size);
|
||||||
assert(!"MapMemories() failed");
|
assert(!"MapMemories() failed");
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
for (i = 0; i < m; i += FRAMESIZE) {
|
for (i = 0; i < m; i += FRAMESIZE) {
|
||||||
dm = sys_mmap(addr + i, FRAMESIZE, prot, f, fd, fd == -1 ? 0 : off + i);
|
oi = fd == -1 ? 0 : off + i;
|
||||||
|
sz = FRAMESIZE;
|
||||||
|
dm = sys_mmap(addr + i, sz, prot, f, fd, oi);
|
||||||
if (dm.addr == MAP_FAILED ||
|
if (dm.addr == MAP_FAILED ||
|
||||||
TrackMemoryInterval(&_mmi, x + i / FRAMESIZE, x + i / FRAMESIZE,
|
TrackMemoryInterval(&_mmi, x + i / FRAMESIZE, x + i / FRAMESIZE,
|
||||||
dm.maphandle, prot, flags) == -1) {
|
dm.maphandle, prot, flags, oi, sz) == -1) {
|
||||||
STRACE("MapMemories(%p+%x/%x) unrecoverable failure #2 %m", addr, i,
|
STRACE("MapMemories(%p+%x/%x) unrecoverable failure #2 %m", addr, i,
|
||||||
size);
|
size);
|
||||||
assert(!"MapMemories() failed");
|
assert(!"MapMemories() failed");
|
||||||
|
|
|
@ -145,7 +145,7 @@ void *mremap(void *p, size_t n, size_t m, int f, ... /* void *q */) {
|
||||||
if (dm.addr == MAP_FAILED) return 0;
|
if (dm.addr == MAP_FAILED) return 0;
|
||||||
if (TrackMemoryInterval(&_mmi, ((uintptr_t)p + n) >> 16,
|
if (TrackMemoryInterval(&_mmi, ((uintptr_t)p + n) >> 16,
|
||||||
((uintptr_t)p + m - FRAMESIZE) >> 16, dm.maphandle,
|
((uintptr_t)p + m - FRAMESIZE) >> 16, dm.maphandle,
|
||||||
prot, flags) != -1) {
|
prot, flags, 0, m - n) != -1) {
|
||||||
if (weaken(__asan_map_shadow)) {
|
if (weaken(__asan_map_shadow)) {
|
||||||
weaken(__asan_map_shadow)((uintptr_t)dm.addr, m - n);
|
weaken(__asan_map_shadow)((uintptr_t)dm.addr, m - n);
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ void *mremap(void *p, size_t n, size_t m, int f, ... /* void *q */) {
|
||||||
if (q == MAP_FAILED) return 0;
|
if (q == MAP_FAILED) return 0;
|
||||||
if (ReleaseMemoryIntervals(&_mmi, (uintptr_t)p >> 16,
|
if (ReleaseMemoryIntervals(&_mmi, (uintptr_t)p >> 16,
|
||||||
((uintptr_t)p + n - FRAMESIZE) >> 16, 0) != -1 &&
|
((uintptr_t)p + n - FRAMESIZE) >> 16, 0) != -1 &&
|
||||||
TrackMemoryInterval(&_mmi, a, b, -1, prot, flags) != -1) {
|
TrackMemoryInterval(&_mmi, a, b, -1, prot, flags, 0, m) != -1) {
|
||||||
if (weaken(__asan_poison)) {
|
if (weaken(__asan_poison)) {
|
||||||
if (!OverlapsShadowSpace(p, n)) {
|
if (!OverlapsShadowSpace(p, n)) {
|
||||||
weaken(__asan_poison)((intptr_t)p, n, kAsanUnmapped);
|
weaken(__asan_poison)((intptr_t)p, n, kAsanUnmapped);
|
||||||
|
|
|
@ -27,6 +27,7 @@ extern unsigned char _base[] forcealign(PAGESIZE); /* αpε */
|
||||||
extern unsigned char _ehead[] forcealign(PAGESIZE); /* αpε */
|
extern unsigned char _ehead[] forcealign(PAGESIZE); /* αpε */
|
||||||
extern unsigned char _etext[] forcealign(PAGESIZE); /* αpε */
|
extern unsigned char _etext[] forcealign(PAGESIZE); /* αpε */
|
||||||
extern unsigned char _edata[] forcealign(PAGESIZE); /* αpε */
|
extern unsigned char _edata[] forcealign(PAGESIZE); /* αpε */
|
||||||
|
extern unsigned char _ezip[]; /* αpε */
|
||||||
extern unsigned char _end[] forcealign(FRAMESIZE); /* αpε */
|
extern unsigned char _end[] forcealign(FRAMESIZE); /* αpε */
|
||||||
extern unsigned char _ereal; /* αpε */
|
extern unsigned char _ereal; /* αpε */
|
||||||
extern unsigned char __privileged_start; /* αpε */
|
extern unsigned char __privileged_start; /* αpε */
|
||||||
|
|
|
@ -59,6 +59,7 @@ $(LIBC_RUNTIME_A).pkg: \
|
||||||
|
|
||||||
o/$(MODE)/libc/runtime/printf.o \
|
o/$(MODE)/libc/runtime/printf.o \
|
||||||
o/$(MODE)/libc/runtime/abort-nt.o \
|
o/$(MODE)/libc/runtime/abort-nt.o \
|
||||||
|
o/$(MODE)/libc/runtime/printmemoryintervals.o \
|
||||||
o/$(MODE)/libc/runtime/arememoryintervalsok.o \
|
o/$(MODE)/libc/runtime/arememoryintervalsok.o \
|
||||||
o/$(MODE)/libc/runtime/assertfail.o \
|
o/$(MODE)/libc/runtime/assertfail.o \
|
||||||
o/$(MODE)/libc/runtime/directmap.o \
|
o/$(MODE)/libc/runtime/directmap.o \
|
||||||
|
@ -81,6 +82,15 @@ o/$(MODE)/libc/runtime/winmain.greg.o: \
|
||||||
OVERRIDE_CFLAGS += \
|
OVERRIDE_CFLAGS += \
|
||||||
$(NO_MAGIC)
|
$(NO_MAGIC)
|
||||||
|
|
||||||
|
# must use alloca()
|
||||||
|
# can't use asan or any runtime services
|
||||||
|
o/$(MODE)/libc/runtime/fork-nt.o: \
|
||||||
|
OVERRIDE_CPPFLAGS += \
|
||||||
|
-DSTACK_FRAME_UNLIMITED
|
||||||
|
o/$(MODE)/libc/runtime/fork-nt.o: \
|
||||||
|
OVERRIDE_CFLAGS += \
|
||||||
|
$(NO_MAGIC)
|
||||||
|
|
||||||
o/$(MODE)/libc/runtime/printf.o \
|
o/$(MODE)/libc/runtime/printf.o \
|
||||||
o/$(MODE)/libc/runtime/memtrack.o \
|
o/$(MODE)/libc/runtime/memtrack.o \
|
||||||
o/$(MODE)/libc/runtime/mman.greg.o: \
|
o/$(MODE)/libc/runtime/mman.greg.o: \
|
||||||
|
|
|
@ -72,6 +72,7 @@ struct WinArgs {
|
||||||
|
|
||||||
extern int __pid;
|
extern int __pid;
|
||||||
extern bool __nomultics;
|
extern bool __nomultics;
|
||||||
|
extern uint32_t __winmainpid;
|
||||||
extern const char kConsoleHandles[2];
|
extern const char kConsoleHandles[2];
|
||||||
|
|
||||||
static const short kConsoleModes[2] = {
|
static const short kConsoleModes[2] = {
|
||||||
|
@ -115,6 +116,7 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(
|
||||||
version = NtGetPeb()->OSMajorVersion;
|
version = NtGetPeb()->OSMajorVersion;
|
||||||
__oldstack = (intptr_t)__builtin_frame_address(0);
|
__oldstack = (intptr_t)__builtin_frame_address(0);
|
||||||
if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) {
|
if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) {
|
||||||
|
__winmainpid = __pid;
|
||||||
rc = SetConsoleCP(kNtCpUtf8);
|
rc = SetConsoleCP(kNtCpUtf8);
|
||||||
STRACE("SetConsoleCP(kNtCpUtf8) → %hhhd", rc);
|
STRACE("SetConsoleCP(kNtCpUtf8) → %hhhd", rc);
|
||||||
rc = SetConsoleOutputCP(kNtCpUtf8);
|
rc = SetConsoleOutputCP(kNtCpUtf8);
|
||||||
|
@ -147,6 +149,7 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(
|
||||||
_mmi.p[0].y = (allocaddr >> 16) + ((allocsize >> 16) - 1);
|
_mmi.p[0].y = (allocaddr >> 16) + ((allocsize >> 16) - 1);
|
||||||
_mmi.p[0].prot = PROT_READ | PROT_WRITE | PROT_EXEC;
|
_mmi.p[0].prot = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||||
_mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
_mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||||
|
_mmi.p[0].size = allocsize;
|
||||||
_mmi.i = 1;
|
_mmi.i = 1;
|
||||||
wa = (struct WinArgs *)allocaddr;
|
wa = (struct WinArgs *)allocaddr;
|
||||||
STRACE("WinMainNew() loading arg block");
|
STRACE("WinMainNew() loading arg block");
|
||||||
|
|
|
@ -16,8 +16,10 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/winsock.h"
|
#include "libc/nt/winsock.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -35,7 +37,17 @@
|
||||||
hidden struct NtWsaData kNtWsaData;
|
hidden struct NtWsaData kNtWsaData;
|
||||||
|
|
||||||
static textwindows void WinSockCleanup(void) {
|
static textwindows void WinSockCleanup(void) {
|
||||||
|
size_t i;
|
||||||
|
STRACE("WSACleanup()");
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
|
for (i = 0; i < g_fds.n; ++i) {
|
||||||
|
if (g_fds.p[i].kind == kFdSocket) {
|
||||||
|
if (weaken(free)) {
|
||||||
|
weaken(free)((struct SockFd *)g_fds.p[i].extra);
|
||||||
|
g_fds.p[i].extra = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
textwindows noasan void WinSockInit(void) {
|
textwindows noasan void WinSockInit(void) {
|
||||||
|
|
|
@ -74,7 +74,7 @@ void longsort(long *x, size_t n) {
|
||||||
}
|
}
|
||||||
if (n > 1) {
|
if (n > 1) {
|
||||||
t = 1ul << bsrl(n - 1);
|
t = 1ul << bsrl(n - 1);
|
||||||
if (X86_HAVE(AVX2)) {
|
if (!IsTiny() && X86_HAVE(AVX2)) {
|
||||||
longsort_avx2(x, n, t);
|
longsort_avx2(x, n, t);
|
||||||
} else {
|
} else {
|
||||||
longsort_pure(x, n, t);
|
longsort_pure(x, n, t);
|
||||||
|
|
|
@ -35,6 +35,10 @@
|
||||||
__ro = 0
|
__ro = 0
|
||||||
__relo_start = 0
|
__relo_start = 0
|
||||||
__relo_end = 0
|
__relo_end = 0
|
||||||
|
__data_start = 0
|
||||||
|
__data_end = 0
|
||||||
|
__bss_start = 0
|
||||||
|
__bss_end = 0
|
||||||
|
|
||||||
// Thread local boundaries defined by linker script
|
// Thread local boundaries defined by linker script
|
||||||
// @see ape/ape.lds
|
// @see ape/ape.lds
|
||||||
|
@ -59,6 +63,10 @@
|
||||||
.globl _tbss_end
|
.globl _tbss_end
|
||||||
.globl _tdata_start
|
.globl _tdata_start
|
||||||
.globl _tdata_end
|
.globl _tdata_end
|
||||||
|
.globl __data_start
|
||||||
|
.globl __data_end
|
||||||
|
.globl __bss_start
|
||||||
|
.globl __bss_end
|
||||||
|
|
||||||
.weak _base
|
.weak _base
|
||||||
.weak ape_xlm
|
.weak ape_xlm
|
||||||
|
@ -76,3 +84,7 @@
|
||||||
.weak _tbss_end
|
.weak _tbss_end
|
||||||
.weak _tdata_start
|
.weak _tdata_start
|
||||||
.weak _tdata_end
|
.weak _tdata_end
|
||||||
|
.weak __data_start
|
||||||
|
.weak __data_end
|
||||||
|
.weak __bss_start
|
||||||
|
.weak __bss_end
|
||||||
|
|
|
@ -175,30 +175,28 @@ syscon compat SIGPOLL 29 23 23 23 23 29 # same as SIGIO
|
||||||
syscon compat SIGIOT 6 6 6 6 6 6 # PDP-11 feature; same as SIGABRT
|
syscon compat SIGIOT 6 6 6 6 6 6 # PDP-11 feature; same as SIGABRT
|
||||||
syscon compat SIGPWR 30 30 30 30 32 30 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead
|
syscon compat SIGPWR 30 30 30 30 32 30 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead
|
||||||
|
|
||||||
# open() flags ┌──────hoo boy
|
# open() flags
|
||||||
# ┌──────┐
|
#
|
||||||
# │┌─<<8─┴───dwFlagsAndAttributes
|
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD Windoze Commentary
|
||||||
# ┌││─────┐
|
syscon open O_RDONLY 0 0 0 0 0 0 # consensus
|
||||||
# │││ │ ┌┴───dwDesiredAccess
|
syscon open O_WRONLY 1 1 1 1 1 1 # consensus
|
||||||
# N │││ │ │
|
syscon open O_RDWR 2 2 2 2 2 2 # consensus
|
||||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD T │││┌─┴┐│ Commentary
|
syscon open O_ACCMODE 3 3 3 3 3 3 # O_RDONLY|O_WRONLY|O_RDWR
|
||||||
syscon open O_RDONLY 0 0 0 0 0 0xA0000000 # unix consensus & kNtGenericRead|kNtGenericExecute
|
syscon open O_APPEND 0x00000400 8 8 8 8 0x00000400 # bsd consensus & kNtFileAppendData; won't pose issues w/ mknod(S_IFIFO) [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_WRONLY 1 1 1 1 1 0x40000000 # unix consensus & kNtGenericWrite
|
syscon open O_CREAT 0x00000040 0x00000200 0x00000200 0x00000200 0x00000200 0x00000040 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_RDWR 2 2 2 2 2 0xE0000000 # unix consensus & kNtGenericRead|kNtGenericWrite|kNtGenericExecute
|
syscon open O_EXCL 0x00000080 0x00000800 0x00000800 0x00000800 0x00000800 0x00000080 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_ACCMODE 3 3 3 3 3 0xE0000000 # O_RDONLY|O_WRONLY|O_RDWR
|
syscon open O_TRUNC 0x00000200 0x00000400 0x00000400 0x00000400 0x00000400 0x00000200 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_APPEND 0x00000400 8 8 8 8 0x00000004 # bsd consensus & kNtFileAppendData; won't pose issues w/ mknod(S_IFIFO)
|
syscon open O_DIRECTORY 0x00010000 0x00100000 0x00020000 0x00020000 0x00200000 0x00010000 # useful hint on UNIX, but required on NT (see kNtFileFlagBackupSemantics) [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_CREAT 0x00000040 0x00000200 0x00000200 0x00000200 0x00000200 0x00000040 # bsd consensus & NT faked as Linux
|
syscon open O_DIRECT 0x00004000 0 0x00010000 0 0x00080000 0x00004000 # kNtFileFlagNoBuffering [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_EXCL 0x00000080 0x00000800 0x00000800 0x00000800 0x00000800 0x00000080 # bsd consensus & NT faked as Linux
|
syscon open O_NDELAY 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # kNtFileFlagWriteThrough [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_TRUNC 0x00000200 0x00000400 0x00000400 0x00000400 0x00000400 0x00000200 # bsd consensus & NT faked as Linux
|
syscon open O_RANDOM 0 0 0 0 0 0x80000000 # kNtFileFlagRandomAccess [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_DIRECTORY 0x00010000 0x00100000 0x00020000 0x00020000 0x00200000 0x02000000 # useful hint on UNIX, but required on NT (see kNtFileFlagBackupSemantics)
|
syscon open O_SEQUENTIAL 0 0 0 0 0 0x40000000 # kNtFileFlagSequentialScan [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_RANDOM 0 0 0 0 0 0x10000000 # kNtFileFlagRandomAccess
|
syscon open O_COMPRESSED 0 0 0 0 0 0x20000000 # kNtFileAttributeCompressed [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_SEQUENTIAL 0 0 0 0 0 0x08000000 # kNtFileFlagSequentialScan
|
syscon open O_INDEXED 0 0 0 0 0 0x10000000 # !kNtFileAttributeNotContentIndexed [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_DIRECT 0x00004000 0 0x00010000 0 0x00080000 0x00200000 # kNtFileFlagNoBuffering>>8
|
syscon open O_CLOEXEC 0x00080000 0x01000000 0x00100000 0x00010000 0x00400000 0x00080000 # NT faked as Linux [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_CLOEXEC 0x00080000 0x01000000 0x00100000 0x00010000 0x00400000 0x00080000 # NT faked as Linux
|
syscon open O_TMPFILE 0x00410000 0 0 0 0 0x00410000 # Linux 3.11+ (c. 2013) & kNtFileAttributeTemporary|kNtFileFlagDeleteOnClose [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_TMPFILE 0x00410000 0 0 0 0 0x00000000 # Linux 3.11+ (c. 2013) & kNtFileAttributeTemporary|kNtFileFlagDeleteOnClose
|
syscon open O_SPARSE 0 0 0 0 0 0 # wut
|
||||||
syscon open O_SPARSE 0 0 0 0 0 0x00040000 # we invented it
|
syscon open O_NONBLOCK 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # bsd consensus
|
||||||
syscon open O_NDELAY 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # bsd consensus & kNtFileFlagWriteThrough>>8 → 0x00800000 (???)
|
|
||||||
syscon open O_NONBLOCK 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # bsd consensus & faked on nt to be same as linux
|
|
||||||
syscon open O_ASYNC 0x00002000 0x00000040 0x00000040 0x00000040 0x00000040 0 # bsd consensus
|
syscon open O_ASYNC 0x00002000 0x00000040 0x00000040 0x00000040 0x00000040 0 # bsd consensus
|
||||||
syscon open O_NOFOLLOW 0x00020000 0x00000100 0x00000100 0x00000100 0x00000100 0 # bsd consensus
|
syscon open O_NOFOLLOW 0x00020000 0x00000100 0x00000100 0x00000100 0x00000100 0 # bsd consensus
|
||||||
syscon open O_NOFOLLOW_ANY 0 0x20000000 0 0 0 0 #
|
syscon open O_NOFOLLOW_ANY 0 0x20000000 0 0 0 0 #
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_ACCMODE,3,3,3,3,3,0xE0000000
|
.syscon open,O_ACCMODE,3,3,3,3,3,3
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_APPEND,0x00000400,8,8,8,8,0x00000004
|
.syscon open,O_APPEND,0x00000400,8,8,8,8,0x00000400
|
||||||
|
|
2
libc/sysv/consts/O_COMPRESSED.S
Normal file
2
libc/sysv/consts/O_COMPRESSED.S
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
|
.syscon open,O_COMPRESSED,0,0,0,0,0,0x20000000
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_DIRECT,0x00004000,0,0x00010000,0,0x00080000,0x00200000
|
.syscon open,O_DIRECT,0x00004000,0,0x00010000,0,0x00080000,0x00004000
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_DIRECTORY,0x00010000,0x00100000,0x00020000,0x00020000,0x00200000,0x02000000
|
.syscon open,O_DIRECTORY,0x00010000,0x00100000,0x00020000,0x00020000,0x00200000,0x00010000
|
||||||
|
|
2
libc/sysv/consts/O_INDEXED.S
Normal file
2
libc/sysv/consts/O_INDEXED.S
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
|
.syscon open,O_INDEXED,0,0,0,0,0,0x10000000
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_RANDOM,0,0,0,0,0,0x10000000
|
.syscon open,O_RANDOM,0,0,0,0,0,0x80000000
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_RDONLY,0,0,0,0,0,0xA0000000
|
.syscon open,O_RDONLY,0,0,0,0,0,0
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_RDWR,2,2,2,2,2,0xE0000000
|
.syscon open,O_RDWR,2,2,2,2,2,2
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_SEQUENTIAL,0,0,0,0,0,0x08000000
|
.syscon open,O_SEQUENTIAL,0,0,0,0,0,0x40000000
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_SPARSE,0,0,0,0,0,0x00040000
|
.syscon open,O_SPARSE,0,0,0,0,0,0
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_TMPFILE,0x00410000,0,0,0,0,0x00000000
|
.syscon open,O_TMPFILE,0x00410000,0,0,0,0,0x00410000
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_WRONLY,1,1,1,1,1,0x40000000
|
.syscon open,O_WRONLY,1,1,1,1,1,1
|
||||||
|
|
|
@ -8,6 +8,7 @@ extern const unsigned O_ACCMODE;
|
||||||
extern const unsigned O_APPEND;
|
extern const unsigned O_APPEND;
|
||||||
extern const unsigned O_ASYNC;
|
extern const unsigned O_ASYNC;
|
||||||
extern const unsigned O_CLOEXEC;
|
extern const unsigned O_CLOEXEC;
|
||||||
|
extern const unsigned O_COMPRESSED;
|
||||||
extern const unsigned O_CREAT;
|
extern const unsigned O_CREAT;
|
||||||
extern const unsigned O_DIRECT;
|
extern const unsigned O_DIRECT;
|
||||||
extern const unsigned O_DIRECTORY;
|
extern const unsigned O_DIRECTORY;
|
||||||
|
@ -15,6 +16,7 @@ extern const unsigned O_DSYNC;
|
||||||
extern const unsigned O_EXCL;
|
extern const unsigned O_EXCL;
|
||||||
extern const unsigned O_EXEC;
|
extern const unsigned O_EXEC;
|
||||||
extern const unsigned O_EXLOCK;
|
extern const unsigned O_EXLOCK;
|
||||||
|
extern const unsigned O_INDEXED;
|
||||||
extern const unsigned O_LARGEFILE;
|
extern const unsigned O_LARGEFILE;
|
||||||
extern const unsigned O_NDELAY;
|
extern const unsigned O_NDELAY;
|
||||||
extern const unsigned O_NOATIME;
|
extern const unsigned O_NOATIME;
|
||||||
|
@ -41,10 +43,15 @@ extern const unsigned O_WRONLY;
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
||||||
#define O_ACCMODE SYMBOLIC(O_ACCMODE)
|
#define O_RDONLY LITERALLY(0)
|
||||||
|
#define O_WRONLY LITERALLY(1)
|
||||||
|
#define O_RDWR LITERALLY(2)
|
||||||
|
#define O_ACCMODE LITERALLY(3)
|
||||||
|
|
||||||
#define O_APPEND SYMBOLIC(O_APPEND)
|
#define O_APPEND SYMBOLIC(O_APPEND)
|
||||||
#define O_ASYNC SYMBOLIC(O_ASYNC)
|
#define O_ASYNC SYMBOLIC(O_ASYNC)
|
||||||
#define O_CLOEXEC SYMBOLIC(O_CLOEXEC)
|
#define O_CLOEXEC SYMBOLIC(O_CLOEXEC)
|
||||||
|
#define O_COMPRESSED SYMBOLIC(O_COMPRESSED)
|
||||||
#define O_CREAT SYMBOLIC(O_CREAT)
|
#define O_CREAT SYMBOLIC(O_CREAT)
|
||||||
#define O_DIRECT SYMBOLIC(O_DIRECT)
|
#define O_DIRECT SYMBOLIC(O_DIRECT)
|
||||||
#define O_DIRECTORY SYMBOLIC(O_DIRECTORY)
|
#define O_DIRECTORY SYMBOLIC(O_DIRECTORY)
|
||||||
|
@ -52,6 +59,7 @@ COSMOPOLITAN_C_END_
|
||||||
#define O_EXCL SYMBOLIC(O_EXCL)
|
#define O_EXCL SYMBOLIC(O_EXCL)
|
||||||
#define O_EXEC SYMBOLIC(O_EXEC)
|
#define O_EXEC SYMBOLIC(O_EXEC)
|
||||||
#define O_EXLOCK SYMBOLIC(O_EXLOCK)
|
#define O_EXLOCK SYMBOLIC(O_EXLOCK)
|
||||||
|
#define O_INDEXED SYMBOLIC(O_INDEXED)
|
||||||
#define O_LARGEFILE SYMBOLIC(O_LARGEFILE)
|
#define O_LARGEFILE SYMBOLIC(O_LARGEFILE)
|
||||||
#define O_NDELAY SYMBOLIC(O_NDELAY)
|
#define O_NDELAY SYMBOLIC(O_NDELAY)
|
||||||
#define O_NOATIME SYMBOLIC(O_NOATIME)
|
#define O_NOATIME SYMBOLIC(O_NOATIME)
|
||||||
|
@ -61,8 +69,6 @@ COSMOPOLITAN_C_END_
|
||||||
#define O_NONBLOCK SYMBOLIC(O_NONBLOCK)
|
#define O_NONBLOCK SYMBOLIC(O_NONBLOCK)
|
||||||
#define O_PATH SYMBOLIC(O_PATH)
|
#define O_PATH SYMBOLIC(O_PATH)
|
||||||
#define O_RANDOM SYMBOLIC(O_RANDOM)
|
#define O_RANDOM SYMBOLIC(O_RANDOM)
|
||||||
#define O_RDONLY SYMBOLIC(O_RDONLY)
|
|
||||||
#define O_RDWR SYMBOLIC(O_RDWR)
|
|
||||||
#define O_RSYNC SYMBOLIC(O_RSYNC)
|
#define O_RSYNC SYMBOLIC(O_RSYNC)
|
||||||
#define O_SEARCH SYMBOLIC(O_SEARCH)
|
#define O_SEARCH SYMBOLIC(O_SEARCH)
|
||||||
#define O_SEQUENTIAL SYMBOLIC(O_SEQUENTIAL)
|
#define O_SEQUENTIAL SYMBOLIC(O_SEQUENTIAL)
|
||||||
|
@ -73,6 +79,5 @@ COSMOPOLITAN_C_END_
|
||||||
#define O_TRUNC SYMBOLIC(O_TRUNC)
|
#define O_TRUNC SYMBOLIC(O_TRUNC)
|
||||||
#define O_TTY_INIT SYMBOLIC(O_TTY_INIT)
|
#define O_TTY_INIT SYMBOLIC(O_TTY_INIT)
|
||||||
#define O_VERIFY SYMBOLIC(O_VERIFY)
|
#define O_VERIFY SYMBOLIC(O_VERIFY)
|
||||||
#define O_WRONLY SYMBOLIC(O_WRONLY)
|
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_O_H_ */
|
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_O_H_ */
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "libc/sysv/consts/map.h"
|
#include "libc/sysv/consts/map.h"
|
||||||
#include "libc/sysv/consts/nr.h"
|
#include "libc/sysv/consts/nr.h"
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
#include "libc/sysv/consts/prot.h"
|
|
||||||
|
|
||||||
/* ▄▄▄
|
/* ▄▄▄
|
||||||
▄▄▄ ▀▓▓▒▄
|
▄▄▄ ▀▓▓▒▄
|
||||||
|
@ -418,11 +417,13 @@ _init_systemfive_stack:
|
||||||
// m.p[0].h 32 8
|
// m.p[0].h 32 8
|
||||||
// m.p[0].prot 40 4
|
// m.p[0].prot 40 4
|
||||||
// m.p[0].flags 44 4
|
// m.p[0].flags 44 4
|
||||||
|
// m.p[0].offset 48 8
|
||||||
|
// m.p[0].size 56 8
|
||||||
.weak _mmi
|
.weak _mmi
|
||||||
ezlea _mmi,cx
|
ezlea _mmi,cx
|
||||||
test %rcx,%rcx
|
test %rcx,%rcx
|
||||||
push %r9 # save the stack size
|
|
||||||
jz 3f
|
jz 3f
|
||||||
|
push %r9 # save the stack size
|
||||||
lea -1(%r11,%r9),%r9 # need incl. interval
|
lea -1(%r11,%r9),%r9 # need incl. interval
|
||||||
shr $16,%r11 # for the stack range
|
shr $16,%r11 # for the stack range
|
||||||
shr $16,%r9
|
shr $16,%r9
|
||||||
|
@ -432,8 +433,9 @@ _init_systemfive_stack:
|
||||||
orq $-1,32(%rcx) # _mmi.s[0].h
|
orq $-1,32(%rcx) # _mmi.s[0].h
|
||||||
mov %edx,40(%rcx) # _mmi.s[0].prot
|
mov %edx,40(%rcx) # _mmi.s[0].prot
|
||||||
mov %r10d,44(%rcx) # _mmi.s[0].flags
|
mov %r10d,44(%rcx) # _mmi.s[0].flags
|
||||||
3: pop %r9 # restore stack size
|
pop %r9 # restore stack size
|
||||||
pop %rsi
|
mov %r9,56(%rcx) # _mmi.s[0].size
|
||||||
|
3: pop %rsi
|
||||||
pop %rdi
|
pop %rdi
|
||||||
leave
|
leave
|
||||||
// switch stacks
|
// switch stacks
|
||||||
|
|
|
@ -76,11 +76,17 @@ TEST(mkntcmdline, fix) {
|
||||||
char *argv1[] = {
|
char *argv1[] = {
|
||||||
"C:/WINDOWS/system32/cmd.exe",
|
"C:/WINDOWS/system32/cmd.exe",
|
||||||
"/C",
|
"/C",
|
||||||
"more < \"C:\\Users\\jtunn\\AppData\\Local\\Temp\\tmplquaa_d6\"",
|
"more < \"C:\\Users\\jart\\AppData\\Local\\Temp\\tmplquaa_d6\"",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
EXPECT_NE(-1, mkntcmdline(cmdline, argv1[0], argv1));
|
EXPECT_NE(-1, mkntcmdline(cmdline, argv1[0], argv1));
|
||||||
EXPECT_STREQ(u"C:\\WINDOWS\\system32\\cmd.exe /C \"more < "
|
EXPECT_STREQ(u"C:\\WINDOWS\\system32\\cmd.exe /C \"more < "
|
||||||
u"\\\"C:\\Users\\jtunn\\AppData\\Local\\Temp\\tmplquaa_d6\\\"\"",
|
u"\\\"C:\\Users\\jart\\AppData\\Local\\Temp\\tmplquaa_d6\\\"\"",
|
||||||
cmdline);
|
cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(mkntcmdline, testWut) {
|
||||||
|
char *argv[] = {"redbean.com", "--strace", NULL};
|
||||||
|
EXPECT_NE(-1, mkntcmdline(cmdline, "C:\\Users\\jart\\redbean.com", argv));
|
||||||
|
EXPECT_STREQ(u"C:\\Users\\jart\\redbean.com --strace", cmdline);
|
||||||
|
}
|
||||||
|
|
40
test/libc/intrin/describeflags_test.c
Normal file
40
test/libc/intrin/describeflags_test.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
static const struct DescribeFlags kFlags[] = {
|
||||||
|
{1, "hi"}, //
|
||||||
|
{2, "there"}, //
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *DescribeIt(uint32_t x) {
|
||||||
|
static char s[64];
|
||||||
|
return DescribeFlags(s, ARRAYLEN(s), kFlags, ARRAYLEN(kFlags), "x", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(describeflags, test) {
|
||||||
|
EXPECT_STREQ("0", DescribeIt(0));
|
||||||
|
EXPECT_STREQ("xhi", DescribeIt(1));
|
||||||
|
EXPECT_STREQ("xthere", DescribeIt(2));
|
||||||
|
EXPECT_STREQ("xhi|xthere", DescribeIt(3));
|
||||||
|
EXPECT_STREQ("xhi|xthere|0x14", DescribeIt(0x17));
|
||||||
|
}
|
|
@ -155,6 +155,9 @@ static const struct {
|
||||||
{"\"\\001\"", "%#s", S("\1")}, //
|
{"\"\\001\"", "%#s", S("\1")}, //
|
||||||
{"", "%.*s", 0}, //
|
{"", "%.*s", 0}, //
|
||||||
{"☺☻♥♦♣♠!", "%hhs", S("\1\2\3\4\5\6!")}, //
|
{"☺☻♥♦♣♠!", "%hhs", S("\1\2\3\4\5\6!")}, //
|
||||||
|
{"☺☻", "%.*hhs", 2, S("\1\2\3\4\5\6!")}, //
|
||||||
|
{"u\"☺☻\"", "%#.*hhs", 2, S("\1\2\3\4\5\6!")}, //
|
||||||
|
{"u\" ☻\"", "%#.*hhs", 2, S("\0\2\3\4\5\6!")}, //
|
||||||
{"", "% s", S("")}, //
|
{"", "% s", S("")}, //
|
||||||
{" a", "% s", S("a")}, //
|
{" a", "% s", S("a")}, //
|
||||||
{"", "% .*s", 0, S("a")}, //
|
{"", "% .*s", 0, S("a")}, //
|
||||||
|
|
|
@ -65,7 +65,7 @@ static void RunTrackMemoryIntervalTest(const struct MemoryIntervals t[2], int x,
|
||||||
struct MemoryIntervals *mm;
|
struct MemoryIntervals *mm;
|
||||||
mm = memcpy(malloc(sizeof(*t)), t, sizeof(*t));
|
mm = memcpy(malloc(sizeof(*t)), t, sizeof(*t));
|
||||||
CheckMemoryIntervalsAreOk(mm);
|
CheckMemoryIntervalsAreOk(mm);
|
||||||
CHECK_NE(-1, TrackMemoryInterval(mm, x, y, h, 0, 0));
|
CHECK_NE(-1, TrackMemoryInterval(mm, x, y, h, 0, 0, 0, 0));
|
||||||
CheckMemoryIntervalsAreOk(mm);
|
CheckMemoryIntervalsAreOk(mm);
|
||||||
CheckMemoryIntervalsEqual(mm, t + 1);
|
CheckMemoryIntervalsEqual(mm, t + 1);
|
||||||
free(mm);
|
free(mm);
|
||||||
|
@ -102,10 +102,10 @@ TEST(TrackMemoryInterval, TestFull) {
|
||||||
mm = calloc(1, sizeof(struct MemoryIntervals));
|
mm = calloc(1, sizeof(struct MemoryIntervals));
|
||||||
for (i = 0; i < mm->n; ++i) {
|
for (i = 0; i < mm->n; ++i) {
|
||||||
CheckMemoryIntervalsAreOk(mm);
|
CheckMemoryIntervalsAreOk(mm);
|
||||||
CHECK_NE(-1, TrackMemoryInterval(mm, i, i, i, 0, 0));
|
CHECK_NE(-1, TrackMemoryInterval(mm, i, i, i, 0, 0, 0, 0));
|
||||||
CheckMemoryIntervalsAreOk(mm);
|
CheckMemoryIntervalsAreOk(mm);
|
||||||
}
|
}
|
||||||
CHECK_EQ(-1, TrackMemoryInterval(mm, i, i, i, 0, 0));
|
CHECK_EQ(-1, TrackMemoryInterval(mm, i, i, i, 0, 0, 0, 0));
|
||||||
CHECK_EQ(ENOMEM, errno);
|
CHECK_EQ(ENOMEM, errno);
|
||||||
CheckMemoryIntervalsAreOk(mm);
|
CheckMemoryIntervalsAreOk(mm);
|
||||||
free(mm);
|
free(mm);
|
||||||
|
|
|
@ -3112,7 +3112,7 @@ int main(int argc, char *argv[]) {
|
||||||
m->mode = XED_MACHINE_MODE_LONG_64;
|
m->mode = XED_MACHINE_MODE_LONG_64;
|
||||||
m->onbinbase = OnBinbase;
|
m->onbinbase = OnBinbase;
|
||||||
m->onlongbranch = OnLongBranch;
|
m->onlongbranch = OnLongBranch;
|
||||||
speed = 32;
|
speed = 4;
|
||||||
SetXmmSize(2);
|
SetXmmSize(2);
|
||||||
SetXmmDisp(kXmmHex);
|
SetXmmDisp(kXmmHex);
|
||||||
if ((colorize = !__nocolor)) {
|
if ((colorize = !__nocolor)) {
|
||||||
|
|
|
@ -914,7 +914,6 @@ static void SetDefaults(void) {
|
||||||
ProgramTimeout(60 * 1000);
|
ProgramTimeout(60 * 1000);
|
||||||
ProgramSslTicketLifetime(24 * 60 * 60);
|
ProgramSslTicketLifetime(24 * 60 * 60);
|
||||||
sslfetchverify = true;
|
sslfetchverify = true;
|
||||||
if (IsWindows()) uniprocess = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddString(struct Strings *l, const char *s, size_t n) {
|
static void AddString(struct Strings *l, const char *s, size_t n) {
|
||||||
|
|
Loading…
Reference in a new issue