cosmopolitan/libc/runtime/memtrack.internal.h
Justine Tunney b45d50b690 Make improvements
- Fix build flakes
- Polyfill SIGWINCH on Windows
- Fix an execve issue on Windows
- Make strerror show more information
- Improve cmd.exe setup/teardown on Windows
- Support bracketed paste mode in Blinkenlights
- Show keyboard shortcuts in Blinkenlights status bar
- Fixed copy_file_range() and copyfile() w/ zip filesystem
- Size optimize GetDosArgv() to keep life.com 12kb in size
- Improve Blinkenlights ability to load weird ELF executables
- Fix program_executable_name and add GetInterpreterExecutableName
- Make Python in tiny mode fail better if docstrings are requested
- Update Python test exclusions in tiny* modes such as tinylinux
- Add bulletproof unbreakable kprintf() troubleshooting function
- Remove "oldskool" keyword from ape.S for virus scanners
- Fix issue that caused backtraces to not print sometimes
- Improve Blinkenlights serial uart character i/o
- Make clock_gettime() not clobber errno on xnu
- Improve sha256 cpuid check for old computers
- Integrate some bestline linenoise fixes
- Show runit process names better in htop
- Remove SIGPIPE from ShowCrashReports()
- Make realpath() not clobber errno
- Avoid attaching GDB on non-Linux
- Improve img.com example
2022-03-16 13:40:10 -07:00

184 lines
5.6 KiB
C

#ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
#define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
#include "libc/dce.h"
#include "libc/macros.internal.h"
#include "libc/nt/enum/version.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/sysv/consts/ss.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define kAutomapStart _kMem(0x100080000000, 0x000010000000)
#define kAutomapSize \
_kMem(0x200000000000 - 0x100080000000 - _kMmi(0x800000000000), \
0x000040000000 - 0x000010000000 - _kMmi(0x000080000000))
#define kMemtrackStart \
_kMem(0x200000000000 - _kMmi(0x800000000000), \
0x000040000000 - _kMmi(0x000080000000))
#define kMemtrackSize _kMem(_kMmi(0x800000000000), _kMmi(0x000080000000))
#define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8)
#define kFixedmapStart _kMem(0x300000000000, 0x000040000000)
#define kFixedmapSize \
_kMem(0x400000000000 - 0x300000000000, 0x000070000000 - 0x000040000000)
#define _kMmi(VSPACE) \
ROUNDUP(VSPACE / FRAMESIZE * (intptr_t)sizeof(struct MemoryInterval), \
FRAMESIZE)
#define _kMem(NORMAL, WIN7) \
(!(IsWindows() && NtGetVersion() < kNtVersionWindows10) ? NORMAL : WIN7)
struct MemoryInterval {
int x;
int y;
long h;
int prot;
int flags;
};
struct MemoryIntervals {
size_t i, n;
struct MemoryInterval *p;
struct MemoryInterval s[OPEN_MAX];
};
extern hidden struct MemoryIntervals _mmi;
const char *DescribeFrame(int);
void PrintSystemMappings(int) hidden;
char *DescribeMapping(int, int, char[hasatleast 8]) hidden;
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden;
void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden;
int TrackMemoryInterval(struct MemoryIntervals *, int, int, long, int,
int) hidden;
int ReleaseMemoryIntervals(struct MemoryIntervals *, int, int,
void (*)(struct MemoryIntervals *, int, int)) hidden;
void ReleaseMemoryNt(struct MemoryIntervals *, int, int) hidden;
int UntrackMemoryIntervals(void *, size_t) hidden;
#define IsLegalPointer(p) \
(-0x800000000000 <= (intptr_t)(p) && (intptr_t)(p) <= 0x7fffffffffff)
forceinline pureconst bool IsLegalSize(size_t n) {
return n <= 0xffffffffffff;
}
forceinline pureconst bool IsAutoFrame(int x) {
return (kAutomapStart >> 16) <= x &&
x <= ((kAutomapStart + (kAutomapSize - 1)) >> 16);
}
forceinline pureconst bool IsMemtrackFrame(int x) {
return (kAutomapStart >> 16) <= x &&
x <= ((kAutomapStart + (kAutomapSize - 1)) >> 16);
}
forceinline pureconst bool IsArenaFrame(int x) {
return 0x5000 <= x && x < 0x7ffe;
}
forceinline pureconst bool IsShadowFrame(int x) {
return 0x7fff <= x && x < 0x10008000;
}
forceinline pureconst bool IsKernelFrame(int x) {
return (int)(GetStaticStackAddr(0) >> 16) <= x &&
x <= (int)((GetStaticStackAddr(0) + (GetStackSize() - FRAMESIZE)) >>
16);
}
forceinline pureconst bool IsStaticStackFrame(int x) {
return (int)(GetStaticStackAddr(0) >> 16) <= x &&
x <= (int)((GetStaticStackAddr(0) + (GetStackSize() - FRAMESIZE)) >>
16);
}
forceinline pureconst bool IsStackFrame(int x) {
return (int)(GetStackAddr(0) >> 16) <= x &&
x <= (int)((GetStackAddr(0) + (GetStackSize() - FRAMESIZE)) >> 16);
}
forceinline pureconst bool IsSigAltStackFrame(int x) {
return (int)(GetStackAddr(0) >> 16) <= x &&
x <= (int)((GetStackAddr(0) + (SIGSTKSZ - FRAMESIZE)) >> 16);
}
forceinline pureconst bool IsOldStackFrame(int x) {
intptr_t old = ROUNDDOWN(__oldstack, STACKSIZE);
return (old >> 16) <= x && x <= ((old + (STACKSIZE - FRAMESIZE)) >> 16);
}
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 *start, *ender;
if (n) {
start = p;
ender = start + (n - 1);
return ((_base <= start && start < _end) ||
(_base <= ender && ender < _end) ||
(start < _base && _end <= ender));
} else {
return 0;
}
}
forceinline pureconst bool OverlapsArenaSpace(const void *p, size_t n) {
intptr_t x, y;
if (n) {
x = (intptr_t)p;
y = x + (n - 1);
return ((0x50000000 <= x && x <= 0x7ffdffff) ||
(0x50000000 <= y && y <= 0x7ffdffff) ||
(x < 0x50000000 && 0x7ffdffff < y));
} else {
return 0;
}
}
forceinline pureconst bool OverlapsShadowSpace(const void *p, size_t n) {
intptr_t x, y;
if (n) {
x = (intptr_t)p;
y = x + (n - 1);
return ((0x7fff0000 <= x && x <= 0x10007fffffff) ||
(0x7fff0000 <= y && y <= 0x10007fffffff) ||
(x < 0x7fff0000 && 0x10007fffffff < y));
} else {
return 0;
}
}
forceinline unsigned FindMemoryInterval(const struct MemoryIntervals *mm,
int x) {
unsigned l, m, r;
l = 0;
r = mm->i;
while (l < r) {
m = (l + r) >> 1;
if (mm->p[m].y < x) {
l = m + 1;
} else {
r = m;
}
}
return l;
}
forceinline bool IsMemtracked(int x, int y) {
unsigned i;
i = FindMemoryInterval(&_mmi, x);
if (i == _mmi.i) return false;
if (!(_mmi.p[i].x <= x && x <= _mmi.p[i].y)) return false;
for (;;) {
if (y <= _mmi.p[i].y) return true;
if (++i == _mmi.i) return false;
if (_mmi.p[i].x != _mmi.p[i - 1].y + 1) return false;
}
}
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ */