mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 19:43:32 +00:00
f531acc8f9
- Invent openatemp() API - Invent O_UNLINK open flag - Introduce getenv_secure() API - Remove `git pull` from cosmocc - Fix utimes() when path is NULL - Fix mktemp() to never return NULL - Fix utimensat() UTIME_OMIT on XNU - Improve utimensat() code for RHEL5 - Turn `argv[0]` C:/ to /C/ on Windows - Introduce tmpnam() and tmpnam_r() APIs - Fix more const issues with internal APIs - Permit utimes() on WIN32 in O_RDONLY mode - Fix fdopendir() to check fd is a directory - Fix recent crash regression in landlock make - Fix futimens(AT_FDCWD, NULL) to return EBADF - Use workaround so `make -j` doesn't fork bomb - Rename dontdiscard to __wur (just like glibc) - Fix st_size for WIN32 symlinks containing UTF-8 - Introduce stdio ext APIs needed by GNU coreutils - Fix lstat() on WIN32 for symlinks to directories - Move some constants from normalize.inc to limits.h - Fix segv with memchr() and memcmp() overlapping page - Implement POSIX fflush() behavior for reader streams - Implement AT_SYMLINK_NOFOLLOW for utimensat() on WIN32 - Don't change read-only status of existing files on WIN32 - Correctly handle `0x[^[:xdigit:]]` case in strtol() functions
203 lines
6.4 KiB
C
203 lines
6.4 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/intrin/nopl.internal.h"
|
|
#include "libc/macros.internal.h"
|
|
#include "libc/nt/version.h"
|
|
#include "libc/runtime/runtime.h"
|
|
#include "libc/runtime/stack.h"
|
|
#include "libc/sysv/consts/ss.h"
|
|
#include "libc/thread/tls.h"
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
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 kMemtrackFdsStart 0x6fe000040000
|
|
#define kMemtrackFdsSize (0x6feffffc0000 - kMemtrackFdsStart)
|
|
#define kMemtrackZiposStart 0x6fd000040000
|
|
#define kMemtrackZiposSize (0x6fdffffc0000 - kMemtrackZiposStart)
|
|
#define kMemtrackKmallocStart 0x6fc000040000
|
|
#define kMemtrackKmallocSize (0x6fcffffc0000 - kMemtrackKmallocStart)
|
|
#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_init(void);
|
|
void __mmi_lock(void);
|
|
void __mmi_unlock(void);
|
|
void __mmi_funlock(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 *);
|
|
|
|
#ifdef _NOPL0
|
|
#define __mmi_lock() _NOPL0("__threadcalls", __mmi_lock)
|
|
#define __mmi_unlock() _NOPL0("__threadcalls", __mmi_unlock)
|
|
#else
|
|
#define __mmi_lock() (__threaded ? __mmi_lock() : 0)
|
|
#define __mmi_unlock() (__threaded ? __mmi_unlock() : 0)
|
|
#endif
|
|
|
|
#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 IsZiposFrame(int x) {
|
|
return (int)(kMemtrackZiposStart >> 16) <= x &&
|
|
x <= (int)((kMemtrackZiposStart + kMemtrackZiposSize - 1) >> 16);
|
|
}
|
|
|
|
forceinline pureconst bool IsKmallocFrame(int x) {
|
|
return (int)(kMemtrackKmallocStart >> 16) <= x &&
|
|
x <= (int)((kMemtrackKmallocStart + kMemtrackKmallocSize - 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 - 1);
|
|
BegB = __executable_start;
|
|
EndB = _end - 1;
|
|
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 - 1);
|
|
BegB = 0x7fff0000;
|
|
EndB = 0x10007fffffff;
|
|
return MAX(BegA, BegB) < MIN(EndA, EndB);
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ */
|