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 b69f3d2488 and 6f7d0cb1c3 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.
This commit is contained in:
Joshua Wierenga 2022-10-04 19:20:39 +11:00 committed by GitHub
parent 30140812f0
commit 4381b3d925
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 12 deletions

View file

@ -50,8 +50,8 @@ int __ensurefds_unlocked(int fd) {
bool relocate; bool relocate;
if (fd < g_fds.n) return fd; if (fd < g_fds.n) return fd;
g_fds.n = fd + 1; g_fds.n = fd + 1;
g_fds.e = g_fds.e = _extend(g_fds.p, g_fds.n * sizeof(*g_fds.p), g_fds.e,
_extend(g_fds.p, g_fds.n * sizeof(*g_fds.p), g_fds.e, 0x6ff000000000); kMemtrackFdsStart + kMemtrackFdsSize);
return fd; return fd;
} }

View file

@ -22,6 +22,7 @@
#include "libc/intrin/pushpop.h" #include "libc/intrin/pushpop.h"
#include "libc/intrin/weaken.h" #include "libc/intrin/weaken.h"
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/sysv/consts/o.h" #include "libc/sysv/consts/o.h"
#include "libc/thread/thread.h" #include "libc/thread/thread.h"
@ -43,10 +44,11 @@ textstartup void InitializeFileDescriptors(void) {
struct Fds *fds; struct Fds *fds;
__fds_lock_obj._type = PTHREAD_MUTEX_RECURSIVE; __fds_lock_obj._type = PTHREAD_MUTEX_RECURSIVE;
fds = VEIL("r", &g_fds); fds = VEIL("r", &g_fds);
fds->p = fds->e = (void *)0x6fe000040000; fds->p = fds->e = (void *)kMemtrackFdsStart;
fds->n = 4; fds->n = 4;
fds->f = 3; 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()) { if (IsMetal()) {
extern const char vga_console[]; extern const char vga_console[];
pushmov(&fds->f, 3ull); pushmov(&fds->f, 3ull);

View file

@ -9,6 +9,8 @@ bool32 GetVersionEx(struct NtOsVersionInfo *lpVersionInformation);
#if defined(__GCC_ASM_FLAG_OUTPUTS__) && !defined(__STRICT_ANSI__) #if defined(__GCC_ASM_FLAG_OUTPUTS__) && !defined(__STRICT_ANSI__)
#define IsAtLeastWindows10() (GetNtMajorVersion() >= 10) #define IsAtLeastWindows10() (GetNtMajorVersion() >= 10)
#define IsAtleastWindows8p1() \
(GetNtMajorVersion() > 6 || (GetNtMajorVersion() == 6 && GetNtMinorVersion() == 3))
#define GetNtMajorVersion() \ #define GetNtMajorVersion() \
({ \ ({ \
uintptr_t __x; \ uintptr_t __x; \
@ -17,6 +19,14 @@ bool32 GetVersionEx(struct NtOsVersionInfo *lpVersionInformation);
: "=q"(__x)); \ : "=q"(__x)); \
(unsigned char)__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 #endif
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_

View file

@ -26,17 +26,22 @@ COSMOPOLITAN_C_START_
#define kFixedmapStart _kMem(0x300000000000, 0x000040000000) #define kFixedmapStart _kMem(0x300000000000, 0x000040000000)
#define kFixedmapSize \ #define kFixedmapSize \
_kMem(0x400000000000 - 0x300000000000, 0x000070000000 - 0x000040000000) _kMem(0x400000000000 - 0x300000000000, 0x000070000000 - 0x000040000000)
#define kMemtrackFdsStart \ #define kMemtrackFdsStart _kMemVista(0x6fe000040000, 0x5e000040000)
(ROUNDDOWN(_kMem(0x6fe000000000, 0x68000000), FRAMESIZE * 8) - 0x8000 * 8) #define kMemtrackFdsSize \
#define kMemtrackFdsSize _kMem(0x001000000000, 0x04000000) (_kMemVista(0x6feffffc0000, 0x5effffc0000) - kMemtrackFdsStart)
#define kMemtrackZiposStart \ #define kMemtrackZiposStart _kMemVista(0x6fd000040000, 0x5d000040000)
(ROUNDDOWN(_kMem(0x6fd000000000, 0x6c000000), FRAMESIZE * 8) - 0x8000 * 8) #define kMemtrackZiposSize \
#define kMemtrackZiposSize _kMem(0x001000000000, 0x10000000) (_kMemVista(0x6fdffffc0000, 0x5dffffc0000) - kMemtrackZiposStart)
#define kMemtrackNsyncStart _kMemVista(0x6fc000040000, 0x5c000040000)
#define kMemtrackNsyncSize \
(_kMemVista(0x6fcffffc0000, 0x5cffffc0000 - kMemtrackNsyncStart)
#define _kMmi(VSPACE) \ #define _kMmi(VSPACE) \
ROUNDUP(VSPACE / FRAMESIZE * (intptr_t)sizeof(struct MemoryInterval), \ ROUNDUP(VSPACE / FRAMESIZE * (intptr_t)sizeof(struct MemoryInterval), \
FRAMESIZE) FRAMESIZE)
#define _kMem(NORMAL, WIN7) \ #define _kMem(NORMAL, WIN7) \
(!IsWindows() || IsAtLeastWindows10() ? NORMAL : WIN7) (!IsWindows() || IsAtLeastWindows10() ? NORMAL : WIN7)
#define _kMemVista(NORMAL, WINVISTA) \
(!IsWindows() || IsAtleastWindows8p1() ? NORMAL : WINVISTA)
struct MemoryInterval { struct MemoryInterval {
int x; int x;

View file

@ -52,9 +52,10 @@ static void *__zipos_mmap(size_t mapsize) {
assert(mapsize); assert(mapsize);
offset = maptotal; offset = maptotal;
maptotal += mapsize; maptotal += mapsize;
start = (char *)0x6fd000040000; start = (char *)kMemtrackZiposStart;
if (!mapend) mapend = start; if (!mapend) mapend = start;
mapend = _extend(start, maptotal, mapend, 0x6fdfffff0000); mapend = _extend(start, maptotal, mapend,
kMemtrackZiposStart + kMemtrackZiposSize);;
return start + offset; return start + offset;
} }