Skip to content

Commit 0cb6b6f

Browse files
committed
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.
1 parent efedef6 commit 0cb6b6f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1338
-336
lines changed

ape/ape.S

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,5 +1605,26 @@ ape_idata_ro:
16051605
__data_start:
16061606
.previous
16071607

1608+
.section .dataepilogue,"aw",@progbits
1609+
.type __data_end,@object
1610+
.globl __data_end
1611+
.hidden __data_end
1612+
__data_end:
1613+
.previous
1614+
1615+
.section .bssprologue,"aw",@nobits
1616+
.type __bss_start,@object
1617+
.globl __bss_start
1618+
.hidden __bss_start
1619+
__bss_start:
1620+
.previous
1621+
1622+
.section .bssepilogue,"aw",@nobits
1623+
.type __bss_end,@object
1624+
.globl __bss_end
1625+
.hidden __bss_end
1626+
__bss_end:
1627+
.previous
1628+
16081629
.end
16091630


ape/ape.lds

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ SECTIONS {
342342
/*END: Read Only Data (only needed for initialization) */
343343
/*END: Read Only Data */
344344
} :Rom
345-
345+
346346
.tdata . : {
347347
_tdata_start = .;
348348
*(SORT_BY_ALIGNMENT(.tdata))
@@ -358,6 +358,8 @@ SECTIONS {
358358

359359
.data . : {
360360
/*BEGIN: Read/Write Data */
361+
KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*)))
362+
/*BEGIN: NT FORK COPYING */
361363
KEEP(*(.dataprologue))
362364
*(.data .data.*)
363365
KEEP(*(SORT_BY_NAME(.sort.data.*)))
@@ -378,6 +380,8 @@ SECTIONS {
378380
. = ALIGN(__SIZEOF_POINTER__);
379381
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
380382
KEEP(*(.piro.pad.data))
383+
KEEP(*(.dataepilogue))
384+
/*END: NT FORK COPYING */
381385
. = ALIGN(PAGESIZE);
382386
HIDDEN(_edata = .);
383387
PROVIDE_HIDDEN(edata = .);
@@ -404,6 +408,8 @@ SECTIONS {
404408
/*BEGIN: bss memory that's addressable */
405409

406410
.bss ALIGN(64) : {
411+
/*BEGIN: NT FORK COPYING */
412+
KEEP(*(.bssprologue))
407413
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
408414
*(.piro.bss)
409415
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
@@ -418,6 +424,8 @@ SECTIONS {
418424

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

427+
KEEP(*(.bssepilogue))
428+
/*END: NT FORK COPYING */
421429
. = ALIGN(FRAMESIZE); /* for brk()/sbrk() allocation */
422430
HIDDEN(_end = .);
423431
PROVIDE_HIDDEN(end = .);
@@ -477,9 +485,9 @@ PFSTUB4(ape_elf_phnum, (ape_phdrs_end - ape_phdrs) / 56);
477485
PFSTUB4(ape_elf_shnum, 0);
478486
PFSTUB4(ape_elf_shstrndx, 0);
479487

480-
HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE));
488+
HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE));
481489
HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) -
482-
ROUNDDOWN(__privileged_start, PAGESIZE)));
490+
ROUNDDOWN(__privileged_start, PAGESIZE)));
483491

484492
HIDDEN(ape_rom_offset = 0);
485493
HIDDEN(ape_rom_vaddr = ADDR(.head));

examples/forkrand.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
#include "libc/log/log.h"
1313
#include "libc/nt/nt/process.h"
1414
#include "libc/rand/rand.h"
15+
#include "libc/runtime/gc.h"
16+
#include "libc/runtime/memtrack.internal.h"
1517
#include "libc/runtime/runtime.h"
1618
#include "libc/stdio/stdio.h"
1719
#include "libc/time/time.h"
20+
#include "libc/x/x.h"
1821

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

3033
int main(int argc, char *argv[]) {
3134
int rc, child, wstatus;
35+
/* puts(_gc(xiso8601ts(NULL))); */
36+
PrintMemoryIntervals(2, &_mmi);
3237
CHECK_NE(-1, (child = fork()));
3338
if (!child) {
3439
/* child process */

libc/calls/calls.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ o//libc/calls/fcntl.o: \
9696
OVERRIDE_CFLAGS += \
9797
-Os
9898

99+
# must use alloca()
99100
o/$(MODE)/libc/calls/execl.o \
100101
o/$(MODE)/libc/calls/execle.o \
101102
o/$(MODE)/libc/calls/execlp.o \

libc/calls/directmap-nt.c

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "libc/nt/enum/filemapflags.h"
2424
#include "libc/nt/enum/pageflags.h"
2525
#include "libc/nt/memory.h"
26+
#include "libc/nt/process.h"
2627
#include "libc/nt/runtime.h"
2728
#include "libc/nt/struct/overlapped.h"
2829
#include "libc/runtime/directmap.internal.h"
@@ -33,7 +34,6 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
3334
int prot, int flags,
3435
int64_t handle, int64_t off) {
3536
/* asan runtime depends on this function */
36-
bool32 rc;
3737
uint32_t got;
3838
size_t i, upsize;
3939
struct DirectMap dm;
@@ -44,18 +44,12 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
4444
* combination of flags, that'll cause Windows to actually do this!
4545
*/
4646
upsize = ROUNDUP(size, FRAMESIZE);
47-
dm.maphandle = CreateFileMappingNuma(-1, &kNtIsInheritable,
48-
kNtPageExecuteReadwrite, upsize >> 32,
49-
upsize, NULL, kNtNumaNoPreferredNode);
50-
STRACE(
51-
"CreateFileMappingNuma(-1, kNtPageExecuteReadwrite, %'zu/%'zu) -> %p",
52-
upsize, size, dm.maphandle);
53-
if (dm.maphandle) {
54-
dm.addr =
55-
MapViewOfFileExNuma(dm.maphandle, kNtFileMapWrite | kNtFileMapExecute,
56-
0, 0, upsize, addr, kNtNumaNoPreferredNode);
57-
STRACE("MapViewOfFileExNuma(WX, %p) → addr:%p", addr, dm.addr);
58-
if (dm.addr) {
47+
if ((dm.maphandle = CreateFileMappingNuma(
48+
-1, &kNtIsInheritable, kNtPageExecuteReadwrite, upsize >> 32,
49+
upsize, NULL, kNtNumaNoPreferredNode))) {
50+
if ((dm.addr = MapViewOfFileExNuma(
51+
dm.maphandle, kNtFileMapWrite | kNtFileMapExecute, 0, 0, upsize,
52+
addr, kNtNumaNoPreferredNode))) {
5953
for (i = 0; i < size; i += got) {
6054
got = 0;
6155
op.Internal = 0;
@@ -69,37 +63,27 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
6963
if (i == size) {
7064
return dm;
7165
}
72-
rc = UnmapViewOfFile(dm.addr);
73-
STRACE("%s(addr:%p) → %hhhd% m", "UnmapViewOfFile", dm.maphandle, rc);
66+
UnmapViewOfFile(dm.addr);
7467
}
75-
rc = CloseHandle(dm.maphandle);
76-
STRACE("%s(%p) → %hhhd% m", "CloseHandle", dm.maphandle, rc);
68+
CloseHandle(dm.maphandle);
7769
}
7870
} else {
79-
dm.maphandle = CreateFileMappingNuma(
80-
handle, &kNtIsInheritable,
81-
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
82-
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
83-
kNtNumaNoPreferredNode);
84-
STRACE("CreateFileMappingNuma(fhand:%ld, prot:%s, size:%'zu) → %p", handle,
85-
(prot & PROT_WRITE) ? "XRW" : "XR", handle != -1 ? 0 : size);
86-
if (dm.maphandle) {
87-
dm.addr = MapViewOfFileExNuma(
88-
dm.maphandle,
89-
(prot & PROT_WRITE) ? kNtFileMapWrite | kNtFileMapExecute
90-
: kNtFileMapRead | kNtFileMapExecute,
91-
off >> 32, off, size, addr, kNtNumaNoPreferredNode);
92-
STRACE("MapViewOfFileExNuma(prot:%s, off:%'ld, size:%'zu, addr:%p) → %p",
93-
(prot & PROT_WRITE) ? "WX" : "RX", off, size, addr, dm.addr);
94-
if (dm.addr) {
71+
if ((dm.maphandle = CreateFileMappingNuma(
72+
handle, &kNtIsInheritable,
73+
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
74+
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
75+
kNtNumaNoPreferredNode))) {
76+
if ((dm.addr = MapViewOfFileExNuma(
77+
dm.maphandle,
78+
(prot & PROT_WRITE) ? kNtFileMapWrite | kNtFileMapExecute
79+
: kNtFileMapRead | kNtFileMapExecute,
80+
off >> 32, off, size, addr, kNtNumaNoPreferredNode))) {
9581
return dm;
96-
} else {
97-
rc = CloseHandle(dm.maphandle);
98-
STRACE("%s(%p) → %d% m", "CloseHandle", dm.maphandle, rc);
9982
}
83+
CloseHandle(dm.maphandle);
10084
}
10185
}
10286
dm.maphandle = kNtInvalidHandleValue;
103-
dm.addr = (void *)(intptr_t)__winerr();
87+
dm.addr = (void *)(intptr_t)-1;
10488
return dm;
10589
}

libc/calls/execve-nt.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "libc/nt/struct/processinformation.h"
2828
#include "libc/nt/struct/startupinfo.h"
2929
#include "libc/nt/synchronization.h"
30+
#include "libc/runtime/runtime.h"
3031
#include "libc/str/str.h"
3132
#include "libc/sysv/consts/o.h"
3233

@@ -54,5 +55,5 @@ textwindows int sys_execve_nt(const char *program, char *const argv[],
5455
GetExitCodeProcess(procinfo.hProcess, &dwExitCode);
5556
} while (dwExitCode == kNtStillActive);
5657
CloseHandle(procinfo.hProcess);
57-
ExitProcess(dwExitCode);
58+
_Exit(dwExitCode);
5859
}

libc/calls/mprotect.greg.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
19-
#define ShouldUseMsabiAttribute() 1
2019
#include "libc/bits/bits.h"
2120
#include "libc/calls/internal.h"
2221
#include "libc/calls/strace.internal.h"
@@ -52,7 +51,7 @@ noasan noubsan privileged int mprotect(void *addr, size_t len, int prot) {
5251
rc = -1;
5352
}
5453
} else {
55-
if (__imp_VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) {
54+
if (VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) {
5655
rc = 0;
5756
} else {
5857
rc = __winerr();

libc/calls/ntspawn.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ textwindows int ntspawn(
8484
(block =
8585
MapViewOfFileExNuma(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0,
8686
blocksize, NULL, kNtNumaNoPreferredNode))) {
87-
if (mkntcmdline(block->cmdline, prog, argv + 1) != -1 &&
87+
if (mkntcmdline(block->cmdline, prog, argv) != -1 &&
8888
mkntenvblock(block->envvars, envp, extravar) != -1) {
8989
if (CreateProcess(prog16, block->cmdline, opt_lpProcessAttributes,
9090
opt_lpThreadAttributes, bInheritHandles,
@@ -95,10 +95,11 @@ textwindows int ntspawn(
9595
} else {
9696
__winerr();
9797
}
98-
STRACE("CreateProcess(%#hs, %#hs) → %d% m", prog16, block->cmdline, rc);
98+
STRACE("CreateProcess(%#hs, %!#hs) → %d% m", prog16, block->cmdline, rc);
9999
}
100100
} else {
101101
__winerr();
102+
STRACE("ntspawn() alloc failed %m");
102103
}
103104
if (block) UnmapViewOfFile(block);
104105
if (handle) CloseHandle(handle);

libc/calls/onntconsoleevent.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/bits/pushpop.h"
2020
#include "libc/calls/internal.h"
21+
#include "libc/calls/strace.internal.h"
2122
#include "libc/calls/struct/siginfo.h"
2223
#include "libc/calls/typedef/sigaction_f.h"
2324
#include "libc/nt/enum/ctrlevent.h"
2425
#include "libc/nt/runtime.h"
26+
#include "libc/runtime/runtime.h"
2527
#include "libc/str/str.h"
2628
#include "libc/sysv/consts/sig.h"
2729

@@ -31,24 +33,28 @@ textwindows bool32 __onntconsoleevent(uint32_t CtrlType) {
3133
siginfo_t info;
3234
switch (CtrlType) {
3335
case kNtCtrlCEvent:
36+
STRACE("kNtCtrlCEvent");
3437
sig = pushpop(SIGINT);
3538
break;
3639
case kNtCtrlBreakEvent:
40+
STRACE("kNtCtrlBreakEvent");
3741
sig = pushpop(SIGQUIT);
3842
break;
3943
case kNtCtrlCloseEvent:
44+
STRACE("kNtCtrlCloseEvent");
4045
sig = pushpop(SIGHUP);
4146
break;
4247
case kNtCtrlLogoffEvent: // only received by services so hack hack hack
4348
case kNtCtrlShutdownEvent: // only received by services so hack hack hack
49+
STRACE("kNtCtrlLogoffEvent");
4450
sig = pushpop(SIGALRM);
4551
break;
4652
default:
4753
return false;
4854
}
4955
switch ((rva = __sighandrvas[sig])) {
5056
case (uintptr_t)SIG_DFL:
51-
ExitProcess(128 + sig);
57+
_Exit(128 + sig);
5258
case (uintptr_t)SIG_IGN:
5359
return true;
5460
default:

0 commit comments

Comments
 (0)