Skip to content

Commit 98909b1

Browse files
committed
Fix more things
- Update a couple unicode data files - Disable strace during logger calls - SQLite now uses pread() / pwrite() - pread() past EOF on NT now returns 0 - Make the NT mmap() and fork() code elegant - Give NT a big performance boost with memory - Add many more mmap() tests to prove it works
1 parent b90fa99 commit 98909b1

36 files changed

+1021
-305
lines changed

libc/calls/directmap-nt.c

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,10 @@
1616
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
19-
#include "libc/calls/calls.h"
2019
#include "libc/calls/internal.h"
21-
#include "libc/calls/strace.internal.h"
22-
#include "libc/macros.internal.h"
2320
#include "libc/nt/enum/filemapflags.h"
2421
#include "libc/nt/enum/pageflags.h"
2522
#include "libc/nt/memory.h"
26-
#include "libc/nt/process.h"
2723
#include "libc/nt/runtime.h"
2824
#include "libc/nt/struct/overlapped.h"
2925
#include "libc/runtime/directmap.internal.h"
@@ -33,55 +29,56 @@
3329
textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
3430
int prot, int flags,
3531
int64_t handle, int64_t off) {
36-
/* asan runtime depends on this function */
37-
uint32_t got;
38-
size_t i, upsize;
32+
size_t i;
3933
struct DirectMap dm;
40-
struct NtOverlapped op;
34+
uint32_t flags1, flags2;
35+
const struct NtSecurityAttributes *sec;
36+
37+
if (flags & MAP_PRIVATE) {
38+
sec = 0; // MAP_PRIVATE isn't inherited across fork()
39+
} else {
40+
sec = &kNtIsInheritable; // MAP_SHARED gives us zero-copy fork()
41+
}
42+
4143
if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE) && handle != -1) {
42-
/*
43-
* WIN32 claims it can do COW mappings but we still haven't found a
44-
* combination of flags, that'll cause Windows to actually do this!
45-
*/
46-
upsize = ROUNDUP(size, FRAMESIZE);
47-
if ((dm.maphandle =
48-
CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite,
49-
upsize >> 32, upsize, NULL))) {
50-
if ((dm.addr = MapViewOfFileEx(dm.maphandle,
51-
kNtFileMapWrite | kNtFileMapExecute, 0, 0,
52-
upsize, addr))) {
53-
for (i = 0; i < size; i += got) {
54-
got = 0;
55-
op.Internal = 0;
56-
op.InternalHigh = 0;
57-
op.Pointer = (void *)(uintptr_t)i;
58-
op.hEvent = 0;
59-
if (!ReadFile(handle, (char *)dm.addr + i, size - i, &got, &op)) {
60-
break;
61-
}
62-
}
63-
if (i == size) {
64-
return dm;
65-
}
66-
UnmapViewOfFile(dm.addr);
67-
}
68-
CloseHandle(dm.maphandle);
44+
// windows has cow pages but they can't propagate across fork()
45+
if (prot & PROT_EXEC) {
46+
flags1 = kNtPageExecuteWritecopy;
47+
flags2 = kNtFileMapCopy | kNtFileMapExecute;
48+
} else {
49+
flags1 = kNtPageWritecopy;
50+
flags2 = kNtFileMapCopy;
51+
}
52+
} else if (prot & PROT_WRITE) {
53+
if (prot & PROT_EXEC) {
54+
flags1 = kNtPageExecuteReadwrite;
55+
flags2 = kNtFileMapWrite | kNtFileMapExecute;
56+
} else {
57+
flags1 = kNtPageReadwrite;
58+
flags2 = kNtFileMapWrite;
59+
}
60+
} else if (prot & PROT_READ) {
61+
if (prot & PROT_EXEC) {
62+
flags1 = kNtPageExecuteRead;
63+
flags2 = kNtFileMapRead | kNtFileMapExecute;
64+
} else {
65+
flags1 = kNtPageReadonly;
66+
flags2 = kNtFileMapRead;
6967
}
7068
} else {
71-
if ((dm.maphandle = CreateFileMapping(
72-
handle, &kNtIsInheritable,
73-
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
74-
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL))) {
75-
if ((dm.addr = MapViewOfFileEx(dm.maphandle,
76-
(prot & PROT_WRITE)
77-
? kNtFileMapWrite | kNtFileMapExecute
78-
: kNtFileMapRead | kNtFileMapExecute,
79-
off >> 32, off, size, addr))) {
80-
return dm;
81-
}
82-
CloseHandle(dm.maphandle);
69+
flags1 = kNtPageNoaccess;
70+
flags2 = 0;
71+
}
72+
73+
if ((dm.maphandle = CreateFileMapping(handle, sec, flags1, (size + off) >> 32,
74+
(size + off), 0))) {
75+
if ((dm.addr = MapViewOfFileEx(dm.maphandle, flags2, off >> 32, off, size,
76+
addr))) {
77+
return dm;
8378
}
79+
CloseHandle(dm.maphandle);
8480
}
81+
8582
dm.maphandle = kNtInvalidHandleValue;
8683
dm.addr = (void *)(intptr_t)-1;
8784
return dm;

libc/calls/dup3-sysv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/calls/internal.h"
20+
#include "libc/calls/strace.internal.h"
2021
#include "libc/errno.h"
2122

2223
#define __NR_dup3_linux 0x0124 /*RHEL5:CVE-2010-3301*/
@@ -28,6 +29,7 @@ int32_t sys_dup3(int32_t oldfd, int32_t newfd, int flags) {
2829
olderr = errno;
2930
fd = __sys_dup3(oldfd, newfd, flags);
3031
if ((fd == -1 && errno == ENOSYS) || fd == __NR_dup3_linux) {
32+
STRACE("demodernizing %s() due to %s", "dup3", "RHEL5:CVE-2010-3301");
3133
demodernize = true;
3234
once = true;
3335
errno = olderr;

libc/calls/g_fds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ hidden struct Fds g_fds;
2929
static textwindows int64_t GetHandleNt(long a) {
3030
int64_t b;
3131
b = GetStdHandle(a);
32-
STRACE("GetStdHandle(%ld) → %p% m", a, b);
32+
STRACE("GetStdHandle(%ld) → %ld% m", a, b);
3333
return b;
3434
}
3535

libc/calls/pread.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "libc/bits/weaken.h"
2121
#include "libc/calls/calls.h"
2222
#include "libc/calls/internal.h"
23+
#include "libc/calls/strace.internal.h"
2324
#include "libc/calls/struct/iovec.h"
2425
#include "libc/dce.h"
2526
#include "libc/macros.internal.h"
@@ -54,8 +55,8 @@ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) {
5455
} else {
5556
rc = ebadf();
5657
}
57-
if (!IsTrustworthy() && rc != -1) {
58-
if ((size_t)rc > size) abort();
59-
}
58+
assert(rc == -1 || (size_t)rc <= size);
59+
STRACE("pread(%d, [%#.*hhs%s], %'zu, %'zd) → %'zd% m", fd,
60+
MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, offset, rc);
6061
return rc;
6162
}

libc/calls/preadv.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "libc/bits/weaken.h"
2121
#include "libc/calls/calls.h"
2222
#include "libc/calls/internal.h"
23+
#include "libc/calls/strace.internal.h"
2324
#include "libc/calls/struct/iovec.h"
2425
#include "libc/dce.h"
2526
#include "libc/errno.h"
@@ -70,9 +71,11 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
7071
errno = err;
7172
once = true;
7273
demodernize = true;
74+
STRACE("demodernizing %s() due to %s", "preadv", "ENOSYS");
7375
} else if (IsLinux() && rc == __NR_preadv_linux) {
7476
if (__iovec_size(iov, iovlen) < __NR_preadv_linux) {
75-
demodernize = true; /*RHEL5:CVE-2010-3301*/
77+
demodernize = true;
78+
STRACE("demodernizing %s() due to %s", "preadv", "RHEL5:CVE-2010-3301");
7679
once = true;
7780
} else {
7881
return rc;

libc/calls/pwrite.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "libc/assert.h"
2020
#include "libc/calls/calls.h"
2121
#include "libc/calls/internal.h"
22+
#include "libc/calls/strace.internal.h"
2223
#include "libc/calls/struct/iovec.h"
2324
#include "libc/dce.h"
2425
#include "libc/macros.internal.h"
@@ -57,5 +58,7 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) {
5758
assert(wrote <= size);
5859
}
5960
}
61+
STRACE("pwrite(%d, %#.*hhs%s, %'zu, %'zd) → %'zd% m", fd, MAX(0, MIN(40, rc)),
62+
buf, rc > 40 ? "..." : "", size, offset, rc);
6063
return rc;
6164
}

libc/calls/pwritev.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "libc/bits/weaken.h"
2020
#include "libc/calls/calls.h"
2121
#include "libc/calls/internal.h"
22+
#include "libc/calls/strace.internal.h"
2223
#include "libc/calls/struct/iovec.h"
2324
#include "libc/dce.h"
2425
#include "libc/errno.h"
@@ -74,9 +75,12 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
7475
errno = err;
7576
once = true;
7677
demodernize = true;
78+
STRACE("demodernizing %s() due to %s", "pwritev", "ENOSYS");
7779
} else if (IsLinux() && rc == __NR_pwritev_linux) {
7880
if (__iovec_size(iov, iovlen) < __NR_pwritev_linux) {
79-
demodernize = true; /*RHEL5:CVE-2010-3301*/
81+
demodernize = true;
82+
STRACE("demodernizing %s() due to %s", "pwritev",
83+
"RHEL5:CVE-2010-3301");
8084
once = true;
8185
} else {
8286
return rc;

libc/calls/read-nt.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
3535
if (ReadFile(fd->handle, data, clampio(size), &got,
3636
offset2overlap(offset, &overlap))) {
3737
return got;
38-
} else if (GetLastError() == kNtErrorBrokenPipe) {
38+
} else if (
39+
// make sure read() returns 0 on broken pipe
40+
GetLastError() == kNtErrorBrokenPipe ||
41+
// make sure pread() returns 0 if we start reading after EOF
42+
GetLastError() == kNtErrorHandleEof) {
3943
return 0;
4044
} else {
4145
return __winerr();

libc/calls/read.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ ssize_t read(int fd, void *buf, size_t size) {
6060
} else {
6161
rc = einval();
6262
}
63-
STRACE("read(%d, %p, %'zu) → %'zd% m", fd, buf, size, rc);
63+
STRACE("read(%d, [%#.*hhs%s], %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), buf,
64+
rc > 40 ? "..." : "", size, rc);
6465
return rc;
6566
}

libc/calls/remove.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
19-
#include "libc/errno.h"
2019
#include "libc/calls/calls.h"
20+
#include "libc/errno.h"
2121

2222
/**
2323
* Deletes "file" or empty directory associtaed with name.

0 commit comments

Comments
 (0)