Skip to content

Commit

Permalink
Get Redbean fork() working on the New Technology
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jart committed Mar 20, 2022
1 parent efedef6 commit 0cb6b6f
Show file tree
Hide file tree
Showing 84 changed files with 1,338 additions and 336 deletions.
21 changes: 21 additions & 0 deletions ape/ape.S
Original file line number Diff line number Diff line change
Expand Up @@ -1605,5 +1605,26 @@ ape_idata_ro:
__data_start:
.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

14 changes: 11 additions & 3 deletions ape/ape.lds
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ SECTIONS {
/*END: Read Only Data (only needed for initialization) */
/*END: Read Only Data */
} :Rom

.tdata . : {
_tdata_start = .;
*(SORT_BY_ALIGNMENT(.tdata))
Expand All @@ -358,6 +358,8 @@ SECTIONS {

.data . : {
/*BEGIN: Read/Write Data */
KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*)))
/*BEGIN: NT FORK COPYING */
KEEP(*(.dataprologue))
*(.data .data.*)
KEEP(*(SORT_BY_NAME(.sort.data.*)))
Expand All @@ -378,6 +380,8 @@ SECTIONS {
. = ALIGN(__SIZEOF_POINTER__);
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
KEEP(*(.piro.pad.data))
KEEP(*(.dataepilogue))
/*END: NT FORK COPYING */
. = ALIGN(PAGESIZE);
HIDDEN(_edata = .);
PROVIDE_HIDDEN(edata = .);
Expand All @@ -404,6 +408,8 @@ SECTIONS {
/*BEGIN: bss memory that's addressable */

.bss ALIGN(64) : {
/*BEGIN: NT FORK COPYING */
KEEP(*(.bssprologue))
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
*(.piro.bss)
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
Expand All @@ -418,6 +424,8 @@ SECTIONS {

KEEP(*(SORT_BY_NAME(.sort.bss.*)))

KEEP(*(.bssepilogue))
/*END: NT FORK COPYING */
. = ALIGN(FRAMESIZE); /* for brk()/sbrk() allocation */
HIDDEN(_end = .);
PROVIDE_HIDDEN(end = .);
Expand Down Expand Up @@ -477,9 +485,9 @@ PFSTUB4(ape_elf_phnum, (ape_phdrs_end - ape_phdrs) / 56);
PFSTUB4(ape_elf_shnum, 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) -
ROUNDDOWN(__privileged_start, PAGESIZE)));
ROUNDDOWN(__privileged_start, PAGESIZE)));

HIDDEN(ape_rom_offset = 0);
HIDDEN(ape_rom_vaddr = ADDR(.head));
Expand Down
5 changes: 5 additions & 0 deletions examples/forkrand.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
#include "libc/log/log.h"
#include "libc/nt/nt/process.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/time/time.h"
#include "libc/x/x.h"

dontinline void dostuff(const char *s) {
int i, us;
Expand All @@ -29,6 +32,8 @@ dontinline void dostuff(const char *s) {

int main(int argc, char *argv[]) {
int rc, child, wstatus;
/* puts(_gc(xiso8601ts(NULL))); */
PrintMemoryIntervals(2, &_mmi);
CHECK_NE(-1, (child = fork()));
if (!child) {
/* child process */
Expand Down
1 change: 1 addition & 0 deletions libc/calls/calls.mk
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ o//libc/calls/fcntl.o: \
OVERRIDE_CFLAGS += \
-Os

# must use alloca()
o/$(MODE)/libc/calls/execl.o \
o/$(MODE)/libc/calls/execle.o \
o/$(MODE)/libc/calls/execlp.o \
Expand Down
58 changes: 21 additions & 37 deletions libc/calls/directmap-nt.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "libc/nt/enum/filemapflags.h"
#include "libc/nt/enum/pageflags.h"
#include "libc/nt/memory.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/overlapped.h"
#include "libc/runtime/directmap.internal.h"
Expand All @@ -33,7 +34,6 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
int prot, int flags,
int64_t handle, int64_t off) {
/* asan runtime depends on this function */
bool32 rc;
uint32_t got;
size_t i, upsize;
struct DirectMap dm;
Expand All @@ -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!
*/
upsize = ROUNDUP(size, FRAMESIZE);
dm.maphandle = CreateFileMappingNuma(-1, &kNtIsInheritable,
kNtPageExecuteReadwrite, upsize >> 32,
upsize, NULL, kNtNumaNoPreferredNode);
STRACE(
"CreateFileMappingNuma(-1, kNtPageExecuteReadwrite, %'zu/%'zu) -> %p",
upsize, size, dm.maphandle);
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) {
if ((dm.maphandle = CreateFileMappingNuma(
-1, &kNtIsInheritable, kNtPageExecuteReadwrite, upsize >> 32,
upsize, NULL, kNtNumaNoPreferredNode))) {
if ((dm.addr = MapViewOfFileExNuma(
dm.maphandle, kNtFileMapWrite | kNtFileMapExecute, 0, 0, upsize,
addr, kNtNumaNoPreferredNode))) {
for (i = 0; i < size; i += got) {
got = 0;
op.Internal = 0;
Expand All @@ -69,37 +63,27 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
if (i == size) {
return dm;
}
rc = UnmapViewOfFile(dm.addr);
STRACE("%s(addr:%p) → %hhhd% m", "UnmapViewOfFile", dm.maphandle, rc);
UnmapViewOfFile(dm.addr);
}
rc = CloseHandle(dm.maphandle);
STRACE("%s(%p) → %hhhd% m", "CloseHandle", dm.maphandle, rc);
CloseHandle(dm.maphandle);
}
} else {
dm.maphandle = CreateFileMappingNuma(
handle, &kNtIsInheritable,
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
kNtNumaNoPreferredNode);
STRACE("CreateFileMappingNuma(fhand:%ld, prot:%s, size:%'zu) → %p", handle,
(prot & PROT_WRITE) ? "XRW" : "XR", handle != -1 ? 0 : size);
if (dm.maphandle) {
dm.addr = MapViewOfFileExNuma(
dm.maphandle,
(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) {
if ((dm.maphandle = CreateFileMappingNuma(
handle, &kNtIsInheritable,
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
kNtNumaNoPreferredNode))) {
if ((dm.addr = MapViewOfFileExNuma(
dm.maphandle,
(prot & PROT_WRITE) ? kNtFileMapWrite | kNtFileMapExecute
: kNtFileMapRead | kNtFileMapExecute,
off >> 32, off, size, addr, kNtNumaNoPreferredNode))) {
return dm;
} else {
rc = CloseHandle(dm.maphandle);
STRACE("%s(%p) → %d% m", "CloseHandle", dm.maphandle, rc);
}
CloseHandle(dm.maphandle);
}
}
dm.maphandle = kNtInvalidHandleValue;
dm.addr = (void *)(intptr_t)__winerr();
dm.addr = (void *)(intptr_t)-1;
return dm;
}
3 changes: 2 additions & 1 deletion libc/calls/execve-nt.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "libc/nt/struct/processinformation.h"
#include "libc/nt/struct/startupinfo.h"
#include "libc/nt/synchronization.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/o.h"

Expand Down Expand Up @@ -54,5 +55,5 @@ textwindows int sys_execve_nt(const char *program, char *const argv[],
GetExitCodeProcess(procinfo.hProcess, &dwExitCode);
} while (dwExitCode == kNtStillActive);
CloseHandle(procinfo.hProcess);
ExitProcess(dwExitCode);
_Exit(dwExitCode);
}
3 changes: 1 addition & 2 deletions libc/calls/mprotect.greg.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#define ShouldUseMsabiAttribute() 1
#include "libc/bits/bits.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
Expand Down Expand Up @@ -52,7 +51,7 @@ noasan noubsan privileged int mprotect(void *addr, size_t len, int prot) {
rc = -1;
}
} else {
if (__imp_VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) {
if (VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) {
rc = 0;
} else {
rc = __winerr();
Expand Down
5 changes: 3 additions & 2 deletions libc/calls/ntspawn.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ textwindows int ntspawn(
(block =
MapViewOfFileExNuma(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0,
blocksize, NULL, kNtNumaNoPreferredNode))) {
if (mkntcmdline(block->cmdline, prog, argv + 1) != -1 &&
if (mkntcmdline(block->cmdline, prog, argv) != -1 &&
mkntenvblock(block->envvars, envp, extravar) != -1) {
if (CreateProcess(prog16, block->cmdline, opt_lpProcessAttributes,
opt_lpThreadAttributes, bInheritHandles,
Expand All @@ -95,10 +95,11 @@ textwindows int ntspawn(
} else {
__winerr();
}
STRACE("CreateProcess(%#hs, %#hs) → %d% m", prog16, block->cmdline, rc);
STRACE("CreateProcess(%#hs, %!#hs) → %d% m", prog16, block->cmdline, rc);
}
} else {
__winerr();
STRACE("ntspawn() alloc failed %m");
}
if (block) UnmapViewOfFile(block);
if (handle) CloseHandle(handle);
Expand Down
8 changes: 7 additions & 1 deletion libc/calls/onntconsoleevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/pushpop.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/siginfo.h"
#include "libc/calls/typedef/sigaction_f.h"
#include "libc/nt/enum/ctrlevent.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"

Expand All @@ -31,24 +33,28 @@ textwindows bool32 __onntconsoleevent(uint32_t CtrlType) {
siginfo_t info;
switch (CtrlType) {
case kNtCtrlCEvent:
STRACE("kNtCtrlCEvent");
sig = pushpop(SIGINT);
break;
case kNtCtrlBreakEvent:
STRACE("kNtCtrlBreakEvent");
sig = pushpop(SIGQUIT);
break;
case kNtCtrlCloseEvent:
STRACE("kNtCtrlCloseEvent");
sig = pushpop(SIGHUP);
break;
case kNtCtrlLogoffEvent: // only received by services so hack hack hack
case kNtCtrlShutdownEvent: // only received by services so hack hack hack
STRACE("kNtCtrlLogoffEvent");
sig = pushpop(SIGALRM);
break;
default:
return false;
}
switch ((rva = __sighandrvas[sig])) {
case (uintptr_t)SIG_DFL:
ExitProcess(128 + sig);
_Exit(128 + sig);
case (uintptr_t)SIG_IGN:
return true;
default:
Expand Down
Loading

0 comments on commit 0cb6b6f

Please sign in to comment.