From 4381b3d9254d6001f4bead71b458a377e854fbc5 Mon Sep 17 00:00:00 2001 From: Joshua Wierenga Date: Tue, 4 Oct 2022 19:20:39 +1100 Subject: [PATCH] Get cosmopolitation working on Vista again (#635) * Fixes virtual memory support for Windows Vista/7/8 Fixes file desciptor and zipos virtual memory sizes given that old versions of windows limit their user virtual memory space to 8tb. Includes some changes from b69f3d2488dbaf9dcc541e699f5b7c09fbf046e0 and 6f7d0cb1c3962f7cb474b04de75df7cd82a3e5d3 in preparation for potentially using them on old windows and because it avoids duplicating addresses everywhere. * Optimise windows version checking Added GetNtMinorVersion() and IsAtleastWindows8p1() macros which get nt version info from the peb. * Planned nsync memory region for old windows Added nsync regon start and size macros that can switch to smaller values on old windows, just like previous fds and zipos change. --- libc/calls/reservefd.c | 4 ++-- libc/intrin/g_fds.c | 6 ++++-- libc/nt/version.h | 10 ++++++++++ libc/runtime/memtrack.internal.h | 17 +++++++++++------ libc/zipos/open.c | 5 +++-- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/libc/calls/reservefd.c b/libc/calls/reservefd.c index d0a4f3e34..5e74fca70 100644 --- a/libc/calls/reservefd.c +++ b/libc/calls/reservefd.c @@ -50,8 +50,8 @@ int __ensurefds_unlocked(int fd) { bool relocate; if (fd < g_fds.n) return fd; g_fds.n = fd + 1; - g_fds.e = - _extend(g_fds.p, g_fds.n * sizeof(*g_fds.p), g_fds.e, 0x6ff000000000); + g_fds.e = _extend(g_fds.p, g_fds.n * sizeof(*g_fds.p), g_fds.e, + kMemtrackFdsStart + kMemtrackFdsSize); return fd; } diff --git a/libc/intrin/g_fds.c b/libc/intrin/g_fds.c index f3c0cfe8b..b524f141d 100644 --- a/libc/intrin/g_fds.c +++ b/libc/intrin/g_fds.c @@ -22,6 +22,7 @@ #include "libc/intrin/pushpop.h" #include "libc/intrin/weaken.h" #include "libc/nt/runtime.h" +#include "libc/runtime/memtrack.internal.h" #include "libc/sysv/consts/o.h" #include "libc/thread/thread.h" @@ -43,10 +44,11 @@ textstartup void InitializeFileDescriptors(void) { struct Fds *fds; __fds_lock_obj._type = PTHREAD_MUTEX_RECURSIVE; fds = VEIL("r", &g_fds); - fds->p = fds->e = (void *)0x6fe000040000; + fds->p = fds->e = (void *)kMemtrackFdsStart; fds->n = 4; fds->f = 3; - fds->e = _extend(fds->p, fds->n * sizeof(*fds->p), fds->e, 0x6ff000000000); + fds->e = _extend(fds->p, fds->n * sizeof(*fds->p), fds->e, + kMemtrackFdsStart + kMemtrackFdsSize);; if (IsMetal()) { extern const char vga_console[]; pushmov(&fds->f, 3ull); diff --git a/libc/nt/version.h b/libc/nt/version.h index 106cc54eb..1c92f0a7c 100644 --- a/libc/nt/version.h +++ b/libc/nt/version.h @@ -9,6 +9,8 @@ bool32 GetVersionEx(struct NtOsVersionInfo *lpVersionInformation); #if defined(__GCC_ASM_FLAG_OUTPUTS__) && !defined(__STRICT_ANSI__) #define IsAtLeastWindows10() (GetNtMajorVersion() >= 10) +#define IsAtleastWindows8p1() \ + (GetNtMajorVersion() > 6 || (GetNtMajorVersion() == 6 && GetNtMinorVersion() == 3)) #define GetNtMajorVersion() \ ({ \ uintptr_t __x; \ @@ -17,6 +19,14 @@ bool32 GetVersionEx(struct NtOsVersionInfo *lpVersionInformation); : "=q"(__x)); \ (unsigned char)__x; \ }) +#define GetNtMinorVersion() \ + ({ \ + uintptr_t __x; \ + asm("mov\t%%gs:96,%q0\r\n" \ + "mov\t284(%q0),%b0" \ + : "=q"(__x)); \ + (unsigned char)__x; \ + }) #endif COSMOPOLITAN_C_END_ diff --git a/libc/runtime/memtrack.internal.h b/libc/runtime/memtrack.internal.h index ff2488f0a..f53dadde2 100644 --- a/libc/runtime/memtrack.internal.h +++ b/libc/runtime/memtrack.internal.h @@ -26,17 +26,22 @@ COSMOPOLITAN_C_START_ #define kFixedmapStart _kMem(0x300000000000, 0x000040000000) #define kFixedmapSize \ _kMem(0x400000000000 - 0x300000000000, 0x000070000000 - 0x000040000000) -#define kMemtrackFdsStart \ - (ROUNDDOWN(_kMem(0x6fe000000000, 0x68000000), FRAMESIZE * 8) - 0x8000 * 8) -#define kMemtrackFdsSize _kMem(0x001000000000, 0x04000000) -#define kMemtrackZiposStart \ - (ROUNDDOWN(_kMem(0x6fd000000000, 0x6c000000), FRAMESIZE * 8) - 0x8000 * 8) -#define kMemtrackZiposSize _kMem(0x001000000000, 0x10000000) +#define kMemtrackFdsStart _kMemVista(0x6fe000040000, 0x5e000040000) +#define kMemtrackFdsSize \ + (_kMemVista(0x6feffffc0000, 0x5effffc0000) - kMemtrackFdsStart) +#define kMemtrackZiposStart _kMemVista(0x6fd000040000, 0x5d000040000) +#define kMemtrackZiposSize \ + (_kMemVista(0x6fdffffc0000, 0x5dffffc0000) - kMemtrackZiposStart) +#define kMemtrackNsyncStart _kMemVista(0x6fc000040000, 0x5c000040000) +#define kMemtrackNsyncSize \ + (_kMemVista(0x6fcffffc0000, 0x5cffffc0000 - kMemtrackNsyncStart) #define _kMmi(VSPACE) \ ROUNDUP(VSPACE / FRAMESIZE * (intptr_t)sizeof(struct MemoryInterval), \ FRAMESIZE) #define _kMem(NORMAL, WIN7) \ (!IsWindows() || IsAtLeastWindows10() ? NORMAL : WIN7) +#define _kMemVista(NORMAL, WINVISTA) \ + (!IsWindows() || IsAtleastWindows8p1() ? NORMAL : WINVISTA) struct MemoryInterval { int x; diff --git a/libc/zipos/open.c b/libc/zipos/open.c index 44979f08e..4d10357e5 100644 --- a/libc/zipos/open.c +++ b/libc/zipos/open.c @@ -52,9 +52,10 @@ static void *__zipos_mmap(size_t mapsize) { assert(mapsize); offset = maptotal; maptotal += mapsize; - start = (char *)0x6fd000040000; + start = (char *)kMemtrackZiposStart; if (!mapend) mapend = start; - mapend = _extend(start, maptotal, mapend, 0x6fdfffff0000); + mapend = _extend(start, maptotal, mapend, + kMemtrackZiposStart + kMemtrackZiposSize);; return start + offset; }