mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-01 16:58:30 +00:00
Make mmap() work better
- Mapping file offsets now works on Windows - Mapping stack memory now works on OpenBSD
This commit is contained in:
parent
23a14b537c
commit
27c899af56
10 changed files with 71 additions and 56 deletions
|
@ -42,16 +42,7 @@ static textwindows int64_t open$nt$impl(int dirfd, const char *path,
|
|||
char16_t path16[PATH_MAX];
|
||||
if (__mkntpathat(dirfd, path, flags, path16) == -1) return -1;
|
||||
if ((handle = CreateFile(
|
||||
path16,
|
||||
(flags & 0xf000000f) |
|
||||
(/* this is needed if we mmap(rwx+cow)
|
||||
nt is choosy about open() access */
|
||||
(flags & O_APPEND)
|
||||
? kNtFileAppendData
|
||||
: (flags & O_ACCMODE) == O_RDONLY
|
||||
? kNtGenericExecute | kNtFileGenericRead
|
||||
: kNtGenericExecute | kNtFileGenericRead |
|
||||
kNtFileGenericWrite),
|
||||
path16, flags & 0xf000000f, /* see consts.sh */
|
||||
(flags & O_EXCL)
|
||||
? kNtFileShareExclusive
|
||||
: kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete,
|
||||
|
@ -75,14 +66,6 @@ static textwindows int64_t open$nt$impl(int dirfd, const char *path,
|
|||
kNtFileFlagBackupSemantics | kNtFileFlagPosixSemantics |
|
||||
kNtFileAttributeTemporary)))),
|
||||
0)) != -1) {
|
||||
if (flags & O_SPARSE) {
|
||||
/*
|
||||
* TODO(jart): Can all files be sparse files? That seems to be the
|
||||
* way Linux behaves out of the box.
|
||||
* TODO(jart): Wow why does sparse wreak havoc?
|
||||
*/
|
||||
DeviceIoControl(handle, kNtFsctlSetSparse, NULL, 0, NULL, 0, &br, NULL);
|
||||
}
|
||||
return handle;
|
||||
} else if (GetLastError() == kNtErrorFileExists &&
|
||||
((flags & O_CREAT) &&
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/enum/filemapflags.h"
|
||||
#include "libc/nt/enum/pageflags.h"
|
||||
|
@ -30,7 +31,8 @@ textwindows struct DirectMap __mmap$nt(void *addr, size_t size, unsigned prot,
|
|||
if ((dm.maphandle = CreateFileMappingNuma(
|
||||
handle, &kNtIsInheritable,
|
||||
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
|
||||
size >> 32, size, NULL, kNtNumaNoPreferredNode))) {
|
||||
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
|
||||
kNtNumaNoPreferredNode))) {
|
||||
if (!(dm.addr = MapViewOfFileExNuma(
|
||||
dm.maphandle,
|
||||
(prot & PROT_WRITE)
|
||||
|
|
|
@ -52,13 +52,14 @@
|
|||
* @param flags can have MAP_ANONYMOUS, MAP_SHARED, MAP_PRIVATE, etc.
|
||||
* @param fd is an open()'d file descriptor whose contents shall be
|
||||
* mapped, and is ignored if MAP_ANONYMOUS is specified
|
||||
* @param offset specifies absolute byte index of fd's file for mapping,
|
||||
* and should be zero if MAP_ANONYMOUS is specified
|
||||
* @param off specifies absolute byte index of fd's file for mapping,
|
||||
* should be zero if MAP_ANONYMOUS is specified, and sadly needs
|
||||
* to be 64kb aligned too
|
||||
* @return virtual base address of new mapping, or MAP_FAILED w/ errno
|
||||
*/
|
||||
void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) {
|
||||
int i, x, n, a, b;
|
||||
struct DirectMap dm;
|
||||
int i, x, n, a, b, f;
|
||||
if (!size) return VIP(einval());
|
||||
if (!ALIGNED(off)) return VIP(einval());
|
||||
if (!ALIGNED(addr)) return VIP(einval());
|
||||
|
@ -84,7 +85,12 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) {
|
|||
}
|
||||
addr = (void *)(intptr_t)((int64_t)x << 16);
|
||||
}
|
||||
dm = __mmap(addr, size, prot, flags | MAP_FIXED, fd, off);
|
||||
f = flags | MAP_FIXED;
|
||||
if (IsOpenbsd() && (f & MAP_GROWSDOWN)) { /* openbsd:dubstack */
|
||||
dm = __mmap(addr, size, prot, f & ~MAP_GROWSDOWN, fd, off);
|
||||
if (dm.addr == MAP_FAILED) return MAP_FAILED;
|
||||
}
|
||||
dm = __mmap(addr, size, prot, f, fd, off);
|
||||
if (dm.addr == MAP_FAILED || dm.addr != addr) {
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
|
|
@ -205,10 +205,10 @@ syscon sig SIGRTMIN 0 0 65 0 0
|
|||
# │││ │ ┌┴───dwDesiredAccess
|
||||
# N │││ │ │
|
||||
# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD T │││┌─┴┐│ Commentary
|
||||
syscon open O_RDONLY 0 0 0 0 0x80000000 # unix consensus & kNtGenericRead
|
||||
syscon open O_RDONLY 0 0 0 0 0xA0000000 # unix consensus & kNtGenericRead|kNtGenericExecute
|
||||
syscon open O_WRONLY 1 1 1 1 0x40000000 # unix consensus & kNtGenericWrite
|
||||
syscon open O_RDWR 2 2 2 2 0xc0000000 # unix consensus & kNtGenericRead|kNtGenericWrite
|
||||
syscon open O_ACCMODE 3 3 3 3 0xc0000000 # O_RDONLY|O_WRONLY|O_RDWR
|
||||
syscon open O_RDWR 2 2 2 2 0xE0000000 # unix consensus & kNtGenericRead|kNtGenericWrite|kNtGenericExecute
|
||||
syscon open O_ACCMODE 3 3 3 3 0xE0000000 # O_RDONLY|O_WRONLY|O_RDWR
|
||||
syscon open O_APPEND 0x0400 8 8 8 0x00000004 # bsd consensus & kNtFileAppendData; won't pose issues w/ mknod(S_IFIFO)
|
||||
syscon open O_CREAT 0x40 0x0200 0x0200 0x0200 0x00000040 # bsd consensus & NT faked as Linux
|
||||
syscon open O_EXCL 0x80 0x0800 0x0800 0x0800 0x00000080 # bsd consensus & NT faked as Linux
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "libc/sysv/consts/syscon.inc"
|
||||
.syscon open O_ACCMODE 3 3 3 3 0xc0000000
|
||||
.syscon open O_ACCMODE 3 3 3 3 0xE0000000
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "libc/sysv/consts/syscon.inc"
|
||||
.syscon open O_RDONLY 0 0 0 0 0x80000000
|
||||
.syscon open O_RDONLY 0 0 0 0 0xA0000000
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "libc/sysv/consts/syscon.inc"
|
||||
.syscon open O_RDWR 2 2 2 2 0xc0000000
|
||||
.syscon open O_RDWR 2 2 2 2 0xE0000000
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue