mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-12 09:17:53 +00:00
Microsoft caused some very gentle breakages for Cosmopolitan. They removed the version information from the PEB which caused uname to report WINDOWS 0.0.0. We should have called GetVersionExW but that doesn't really exist anymore either. Windows policy is now to give whatever version we used in ape/ape.S. Windows8 has been EOL since 2023-01-10 so lets avoid our modern executables being relegated to legacy infrastructure. Requiring Windows 10+ going forward lets us remove runtime compatibility bloat from the codebase. Further note Cosmopolitan maintains a Windows Vista branch on GitHub, so anyone preferring the older versions, can still have a future with Cosmo. Another neat thing this fixes is UTF-8 support in the console. The changes Microsoft made broke the if statement that enabled UTF8 in terminals. This explains why bug reports had broken arrows. In the future this should be less of an issue, since the PEB code is gone which means we more strictly conform to only Microsoft's WIN32 API
189 lines
5.9 KiB
C
189 lines
5.9 KiB
C
#ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
|
#define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
|
#include "ape/sections.internal.h"
|
|
#include "libc/dce.h"
|
|
#include "libc/macros.internal.h"
|
|
#include "libc/runtime/runtime.h"
|
|
#include "libc/runtime/stack.h"
|
|
#include "libc/sysv/consts/ss.h"
|
|
#include "libc/thread/tls.h"
|
|
COSMOPOLITAN_C_START_
|
|
|
|
#define kAutomapStart 0x100080040000
|
|
#define kAutomapSize (kMemtrackStart - kAutomapStart)
|
|
#define kMemtrackStart 0x1fe7fffc0000
|
|
#define kMemtrackSize (0x1ffffffc0000 - kMemtrackStart)
|
|
#define kFixedmapStart 0x300000040000
|
|
#define kFixedmapSize (0x400000040000 - kFixedmapStart)
|
|
#define kMemtrackNsyncStart 0x6fc000040000
|
|
#define kMemtrackNsyncSize (0x6fcffffc0000 - kMemtrackNsyncStart)
|
|
#define kMemtrackFdsStart 0x6fe000040000
|
|
#define kMemtrackFdsSize (0x6feffffc0000 - kMemtrackFdsStart)
|
|
#define kMemtrackZiposStart 0x6fd000040000
|
|
#define kMemtrackZiposSize (0x6fdffffc0000 - kMemtrackZiposStart)
|
|
#define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8)
|
|
|
|
struct MemoryInterval {
|
|
int x;
|
|
int y;
|
|
long h;
|
|
long size;
|
|
long offset;
|
|
int flags;
|
|
char prot;
|
|
bool iscow;
|
|
bool readonlyfile;
|
|
};
|
|
|
|
struct MemoryIntervals {
|
|
size_t i, n;
|
|
struct MemoryInterval *p;
|
|
struct MemoryInterval s[16];
|
|
};
|
|
|
|
extern struct MemoryIntervals _mmi;
|
|
|
|
void __mmi_lock(void);
|
|
void __mmi_unlock(void);
|
|
bool IsMemtracked(int, int);
|
|
void PrintSystemMappings(int);
|
|
unsigned __find_memory(const struct MemoryIntervals *, int) nosideeffect;
|
|
bool __check_memtrack(const struct MemoryIntervals *) nosideeffect;
|
|
void PrintMemoryIntervals(int, const struct MemoryIntervals *);
|
|
int __track_memory(struct MemoryIntervals *, int, int, long, int, int, bool,
|
|
bool, long, long);
|
|
int __untrack_memory(struct MemoryIntervals *, int, int,
|
|
void (*)(struct MemoryIntervals *, int, int));
|
|
void __release_memory_nt(struct MemoryIntervals *, int, int);
|
|
int __untrack_memories(void *, size_t);
|
|
size_t __get_memtrack_size(struct MemoryIntervals *) nosideeffect;
|
|
|
|
#ifdef __x86_64__
|
|
/*
|
|
* AMD64 has 48-bit signed pointers (PML4T)
|
|
* AMD64 is trying to go bigger, i.e. 57-bit (PML5T)
|
|
* LINUX forbids userspace from leveraging negative pointers
|
|
* Q-EMU may impose smaller vaspaces emulating AMD on non-AMD
|
|
*
|
|
* Having "signed pointers" means these top sixteen bits
|
|
*
|
|
* 0x0000000000000000
|
|
* ^^^^
|
|
*
|
|
* must be
|
|
*
|
|
* - 0000 for positive pointers
|
|
* - FFFF for negative pointers
|
|
*
|
|
* otherwise the instruction using the faulty pointer will fault.
|
|
*/
|
|
#define IsLegalPointer(p) \
|
|
(-0x800000000000 <= (intptr_t)(p) && (intptr_t)(p) <= 0x7fffffffffff)
|
|
#define ADDR_32_TO_48(x) (intptr_t)((uint64_t)(int)(x) << 16)
|
|
#elif defined(__aarch64__)
|
|
/*
|
|
* ARM64 has 48-bit unsigned pointers (Armv8.0-A)
|
|
* ARM64 can possibly go bigger, i.e. 52-bit (Armv8.2-A)
|
|
* ARM64 can impose arbitrarily smaller vaspaces, e.g. 40/44-bit
|
|
* APPLE in their limitless authoritarianism forbids 32-bit pointers
|
|
*/
|
|
#define IsLegalPointer(p) ((uintptr_t)(p) <= 0xffffffffffff)
|
|
#define ADDR_32_TO_48(x) (uintptr_t)((uint64_t)(uint32_t)(x) << 16)
|
|
#else
|
|
/* RISC-V Sipeed Nezha has 39-bit vaspace */
|
|
#error "unsupported architecture"
|
|
#endif
|
|
|
|
forceinline pureconst bool IsLegalSize(uint64_t n) {
|
|
/* subtract frame size so roundup is safe */
|
|
return n <= 0x800000000000 - FRAMESIZE;
|
|
}
|
|
|
|
forceinline pureconst bool IsAutoFrame(int x) {
|
|
return (int)(kAutomapStart >> 16) <= x &&
|
|
x <= (int)((kAutomapStart + kAutomapSize - 1) >> 16);
|
|
}
|
|
|
|
forceinline pureconst bool IsMemtrackFrame(int x) {
|
|
return (int)(kAutomapStart >> 16) <= x &&
|
|
x <= (int)((kAutomapStart + kAutomapSize - 1) >> 16);
|
|
}
|
|
|
|
forceinline pureconst bool IsGfdsFrame(int x) {
|
|
return (int)(kMemtrackFdsStart >> 16) <= x &&
|
|
x <= (int)((kMemtrackFdsStart + kMemtrackFdsSize - 1) >> 16);
|
|
}
|
|
|
|
forceinline pureconst bool IsNsyncFrame(int x) {
|
|
return (int)(kMemtrackNsyncStart >> 16) <= x &&
|
|
x <= (int)((kMemtrackNsyncStart + kMemtrackNsyncSize - 1) >> 16);
|
|
}
|
|
|
|
forceinline pureconst bool IsZiposFrame(int x) {
|
|
return (int)(kMemtrackZiposStart >> 16) <= x &&
|
|
x <= (int)((kMemtrackZiposStart + kMemtrackZiposSize - 1) >> 16);
|
|
}
|
|
|
|
forceinline pureconst bool IsShadowFrame(int x) {
|
|
return 0x7fff <= x && x < 0x10008000;
|
|
}
|
|
|
|
forceinline pureconst bool IsStaticStackFrame(int x) {
|
|
intptr_t stack = GetStaticStackAddr(0);
|
|
return (int)(stack >> 16) <= x &&
|
|
x <= (int)((stack + (GetStackSize() - FRAMESIZE)) >> 16);
|
|
}
|
|
|
|
forceinline pureconst bool IsStackFrame(int x) {
|
|
intptr_t stack = GetStackAddr();
|
|
return (int)(stack >> 16) <= x &&
|
|
x <= (int)((stack + (GetStackSize() - FRAMESIZE)) >> 16);
|
|
}
|
|
|
|
forceinline pureconst bool IsOldStack(const void *x) {
|
|
size_t foss_stack_size = 8ul * 1024 * 1024;
|
|
uintptr_t top = __oldstack + foss_stack_size;
|
|
uintptr_t bot = __oldstack - foss_stack_size;
|
|
return bot <= (uintptr_t)x && (uintptr_t)x < top;
|
|
}
|
|
|
|
forceinline pureconst bool IsOldStackFrame(int x) {
|
|
size_t foss_stack_size = 8ul * 1024 * 1024;
|
|
uintptr_t top = __oldstack + foss_stack_size;
|
|
uintptr_t bot = __oldstack - foss_stack_size;
|
|
return (int)(bot >> 16) <= x && x <= (int)((top >> 16) - 1);
|
|
}
|
|
|
|
forceinline pureconst bool IsFixedFrame(int x) {
|
|
return (kFixedmapStart >> 16) <= x &&
|
|
x <= ((kFixedmapStart + (kFixedmapSize - 1)) >> 16);
|
|
}
|
|
|
|
forceinline pureconst bool OverlapsImageSpace(const void *p, size_t n) {
|
|
const unsigned char *BegA, *EndA, *BegB, *EndB;
|
|
if (n) {
|
|
BegA = p;
|
|
EndA = BegA + n;
|
|
BegB = __executable_start;
|
|
EndB = _end;
|
|
return MAX(BegA, BegB) < MIN(EndA, EndB);
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
forceinline pureconst bool OverlapsShadowSpace(const void *p, size_t n) {
|
|
intptr_t BegA, EndA, BegB, EndB;
|
|
if (n) {
|
|
BegA = (intptr_t)p;
|
|
EndA = BegA + n;
|
|
BegB = 0x7fff0000;
|
|
EndB = 0x100080000000;
|
|
return MAX(BegA, BegB) < MIN(EndA, EndB);
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ */
|