Make mmap() work better

- Mapping file offsets now works on Windows
- Mapping stack memory now works on OpenBSD
This commit is contained in:
Justine Tunney 2021-02-03 00:10:12 -08:00
parent 23a14b537c
commit 27c899af56
10 changed files with 71 additions and 56 deletions

View file

@ -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)

View file

@ -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;
}