mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-08 04:08:32 +00:00
Get address sanitizer mostly working
This commit is contained in:
parent
1f1f3cd477
commit
7327c345f9
149 changed files with 3777 additions and 3457 deletions
|
@ -18,13 +18,14 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/log/asan.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/directmap.h"
|
||||
#include "libc/runtime/memtrack.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -32,79 +33,14 @@
|
|||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#define IP(X) (intptr_t)(X)
|
||||
#define VIP(X) (void *)IP(X)
|
||||
#define COORD(a) (int)(IP(a) >> 16)
|
||||
#define ADDR(c) (void *)(IP(c) << 16)
|
||||
#define ALIGNED(p) (!(IP(p) & (FRAMESIZE - 1)))
|
||||
#define CANONICAL(p) (-0x800000000000 <= IP(p) && IP(p) <= 0x7fffffffffff)
|
||||
#define LAST_COORD(a, n) (COORD(a) + (ROUNDUP(n, FRAMESIZE) >> 16) - 1)
|
||||
|
||||
struct DirectMap {
|
||||
void *addr;
|
||||
int64_t maphandle;
|
||||
};
|
||||
#define IP(X) (intptr_t)(X)
|
||||
#define VIP(X) (void *)IP(X)
|
||||
#define ADDR(c) (void *)(IP(c) << 16)
|
||||
#define ALIGNED(p) (!(IP(p) & (FRAMESIZE - 1)))
|
||||
#define CANONICAL(p) (-0x800000000000 <= IP(p) && IP(p) <= 0x7fffffffffff)
|
||||
|
||||
struct MemoryIntervals _mmi;
|
||||
|
||||
static textwindows struct DirectMap DirectMapNt(void *addr, size_t size,
|
||||
unsigned prot, unsigned flags,
|
||||
int fd, int64_t off) {
|
||||
struct DirectMap res; /* NT IS TORTURE */
|
||||
if ((res.maphandle = CreateFileMappingNuma(
|
||||
fd != -1 ? g_fds.p[fd].handle : kNtInvalidHandleValue,
|
||||
&kNtIsInheritable, prot2nt(prot, flags), size >> 32, size, NULL,
|
||||
kNtNumaNoPreferredNode))) {
|
||||
if (!(res.addr = MapViewOfFileExNuma(res.maphandle, fprot2nt(prot, flags),
|
||||
off >> 32, off, size, addr,
|
||||
kNtNumaNoPreferredNode))) {
|
||||
CloseHandle(res.maphandle);
|
||||
res.maphandle = kNtInvalidHandleValue;
|
||||
res.addr = VIP(winerr());
|
||||
}
|
||||
} else {
|
||||
res.maphandle = kNtInvalidHandleValue;
|
||||
res.addr = VIP(winerr());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct DirectMap DirectMap(void *addr, size_t size, unsigned prot,
|
||||
unsigned flags, int fd, int64_t off) {
|
||||
if (!IsWindows()) {
|
||||
return (struct DirectMap){mmap$sysv(addr, size, prot, flags, fd, off),
|
||||
kNtInvalidHandleValue};
|
||||
} else {
|
||||
return DirectMapNt(addr, size, prot, flags, fd, off);
|
||||
}
|
||||
}
|
||||
|
||||
static int UntrackMemoryIntervals(void *addr, size_t size) {
|
||||
return ReleaseMemoryIntervals(&_mmi, COORD(addr), LAST_COORD(addr, size),
|
||||
ReleaseMemoryNt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases memory pages.
|
||||
*
|
||||
* @param addr is a pointer within any memory mapped region the process
|
||||
* has permission to control, such as address ranges returned by
|
||||
* mmap(), the program image itself, etc.
|
||||
* @param size is the amount of memory to unmap, which needn't be a
|
||||
* multiple of FRAMESIZE, and may be a subset of that which was
|
||||
* mapped previously, and may punch holes in existing mappings,
|
||||
* but your mileage may vary on windows
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int munmap(void *addr, size_t size) {
|
||||
int rc;
|
||||
if (!ALIGNED(addr) || !CANONICAL(addr) || !size) return einval();
|
||||
size = ROUNDUP(size, FRAMESIZE);
|
||||
if (UntrackMemoryIntervals(addr, size) == -1) return -1;
|
||||
if (IsWindows()) return 0;
|
||||
return munmap$sysv(addr, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Beseeches system for page-table entries.
|
||||
*
|
||||
|
@ -120,8 +56,7 @@ int munmap(void *addr, size_t size) {
|
|||
* @return virtual base address of new mapping, or MAP_FAILED w/ errno
|
||||
*/
|
||||
void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) {
|
||||
int i;
|
||||
long gap;
|
||||
int i, x, n, a, b;
|
||||
struct DirectMap dm;
|
||||
if (!size) return VIP(einval());
|
||||
if (!ALIGNED(off)) return VIP(einval());
|
||||
|
@ -134,24 +69,18 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) {
|
|||
if (UntrackMemoryIntervals(addr, size) == -1) {
|
||||
return MAP_FAILED;
|
||||
}
|
||||
} else if (_mmi.i) {
|
||||
if (0 && IsModeDbg()) {
|
||||
addr = VIP(rand64() & 0x00007ffffffff000);
|
||||
} else {
|
||||
for (i = _mmi.i - 1; i > 0; --i) {
|
||||
gap = _mmi.p[i].x - _mmi.p[i - 1].y - 1;
|
||||
assert(gap > 0);
|
||||
if (gap >= (ROUNDUP(size, FRAMESIZE) >> 16)) {
|
||||
addr = ADDR(_mmi.p[i - 1].y + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!addr) {
|
||||
addr = ADDR(_mmi.p[_mmi.i - 1].y + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addr = VIP(kMappingsStart);
|
||||
x = kAutomapStart >> 16;
|
||||
n = ROUNDUP(size, FRAMESIZE) >> 16;
|
||||
for (i = 0; i < _mmi.i; ++i) {
|
||||
if (_mmi.p[i].y < x) continue;
|
||||
if (_mmi.p[i].x > x + n - 1) break;
|
||||
x = _mmi.p[i].y + 1;
|
||||
}
|
||||
if (x + n - 1 >= ((kAutomapStart + kAutomapSize) >> 16)) {
|
||||
return (void *)(intptr_t)enomem();
|
||||
}
|
||||
addr = (void *)(intptr_t)((int64_t)x << 16);
|
||||
}
|
||||
assert((flags & MAP_FIXED) ||
|
||||
(!isheap(addr) && !isheap((char *)addr + size - 1)));
|
||||
|
@ -159,9 +88,13 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) {
|
|||
if (dm.addr == MAP_FAILED || dm.addr != addr) {
|
||||
return MAP_FAILED;
|
||||
}
|
||||
if (TrackMemoryInterval(&_mmi, COORD(dm.addr), LAST_COORD(dm.addr, size),
|
||||
dm.maphandle) == -1) {
|
||||
_Exit(1);
|
||||
a = ROUNDDOWN((intptr_t)addr, FRAMESIZE) >> 16;
|
||||
b = ROUNDDOWN((intptr_t)addr + size - 1, FRAMESIZE) >> 16;
|
||||
if (TrackMemoryInterval(&_mmi, a, b, dm.maphandle) == -1) {
|
||||
abort();
|
||||
}
|
||||
if (weaken(__asan_map_shadow)) {
|
||||
weaken(__asan_map_shadow)(dm.addr, size);
|
||||
}
|
||||
return dm.addr;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue