2020-08-25 04:23:25 -07:00
|
|
|
#ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
|
|
|
#define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
2021-01-16 19:18:37 -08:00
|
|
|
#include "libc/dce.h"
|
2021-02-28 23:42:35 -08:00
|
|
|
#include "libc/macros.internal.h"
|
2021-01-16 19:18:37 -08:00
|
|
|
#include "libc/nt/enum/version.h"
|
2020-10-10 21:18:53 -07:00
|
|
|
#include "libc/runtime/runtime.h"
|
2021-10-13 17:27:13 -07:00
|
|
|
#include "libc/runtime/stack.h"
|
2020-08-25 04:23:25 -07:00
|
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
|
|
COSMOPOLITAN_C_START_
|
|
|
|
|
2021-10-13 17:27:13 -07:00
|
|
|
#define _kAutomapStart 0x0000100080000000
|
|
|
|
#define _kAutomapSize 0x00000fff80000000
|
|
|
|
#define _kFixedmapStart 0x0000300000000000
|
|
|
|
#define _kFixedmapSize 0x00000fff80000000
|
2021-01-16 19:18:37 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO: Why can't we allocate addresses above 4GB on Windows 7 x64?
|
|
|
|
* https://github.com/jart/cosmopolitan/issues/19
|
|
|
|
*/
|
|
|
|
#define MEMTRACK_ADDRESS(NORMAL, WIN7) \
|
|
|
|
(!(IsWindows() && NtGetVersion() < kNtVersionWindows10) ? NORMAL : WIN7)
|
|
|
|
#define kAutomapStart MEMTRACK_ADDRESS(_kAutomapStart, 0x10000000)
|
2021-10-13 17:27:13 -07:00
|
|
|
#define kAutomapSize MEMTRACK_ADDRESS(_kAutomapSize, 0x30000000)
|
|
|
|
#define kFixedmapStart MEMTRACK_ADDRESS(_kFixedmapStart, 0x40000000)
|
|
|
|
#define kFixedmapSize MEMTRACK_ADDRESS(_kFixedmapSize, 0x30000000)
|
2020-08-25 04:23:25 -07:00
|
|
|
|
2021-09-04 13:20:47 -07:00
|
|
|
struct MemoryInterval {
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
long h;
|
|
|
|
int prot;
|
|
|
|
int flags;
|
|
|
|
};
|
|
|
|
|
2020-08-25 04:23:25 -07:00
|
|
|
struct MemoryIntervals {
|
2021-09-04 13:20:47 -07:00
|
|
|
long i, n;
|
|
|
|
struct MemoryInterval *p;
|
|
|
|
struct MemoryInterval s[OPEN_MAX];
|
2020-08-25 04:23:25 -07:00
|
|
|
};
|
|
|
|
|
2021-08-06 14:12:11 -07:00
|
|
|
extern hidden struct MemoryIntervals _mmi;
|
2020-08-25 04:23:25 -07:00
|
|
|
|
2021-10-13 17:27:13 -07:00
|
|
|
const char *DescribeFrame(int);
|
|
|
|
void PrintSystemMappings(int) hidden;
|
|
|
|
char *DescribeMapping(int, int, char[hasatleast 8]) hidden;
|
2021-08-06 14:12:11 -07:00
|
|
|
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden;
|
|
|
|
void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden;
|
|
|
|
int TrackMemoryInterval(struct MemoryIntervals *, int, int, long, int,
|
|
|
|
int) hidden;
|
2020-08-25 04:23:25 -07:00
|
|
|
int ReleaseMemoryIntervals(struct MemoryIntervals *, int, int,
|
2021-08-06 14:12:11 -07:00
|
|
|
void (*)(struct MemoryIntervals *, int, int)) hidden;
|
|
|
|
void ReleaseMemoryNt(struct MemoryIntervals *, int, int) hidden;
|
|
|
|
int UntrackMemoryIntervals(void *, size_t) hidden;
|
2020-08-25 04:23:25 -07:00
|
|
|
|
2021-10-13 17:27:13 -07:00
|
|
|
forceinline pureconst bool IsAutoFrame(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 IsStackFrame(int x) {
|
|
|
|
return (GetStaticStackAddr(0) >> 16) <= x &&
|
|
|
|
x <= ((GetStaticStackAddr(0) + (GetStackSize() - 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) {
|
2021-09-27 22:58:51 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-10-13 17:27:13 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-25 04:23:25 -07:00
|
|
|
COSMOPOLITAN_C_END_
|
|
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
|
|
#endif /* COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ */
|