Browse Source

Get address sanitizer mostly working

main
Justine Tunney 1 year ago
parent
commit
7327c345f9
  1. 8
      Makefile
  2. 7
      build/compile
  3. 3
      build/config.mk
  4. 139
      dsp/mpeg/ycbcrio.c
  5. 27
      dsp/mpeg/ycbcrio.h
  6. 5
      examples/fld.c
  7. 1
      examples/mappy.c
  8. 3
      examples/rusage.c
  9. 0
      libc/calls/access.c
  10. 8
      libc/calls/calls.h
  11. 95
      libc/calls/commandv.c
  12. 0
      libc/calls/faccessat-nt.c
  13. 0
      libc/calls/faccessat.c
  14. 4
      libc/calls/g_fds_init.S
  15. 26
      libc/calls/getenv.c
  16. 4
      libc/calls/hefty/execle.c
  17. 7
      libc/calls/hefty/execlp.c
  18. 5
      libc/calls/hefty/execvpe.c
  19. 34
      libc/calls/hefty/sortenvp.c
  20. 3
      libc/calls/hefty/spawnlp.c
  21. 0
      libc/calls/kntsystemdirectory.S
  22. 0
      libc/calls/kntwindowsdirectory.S
  23. 39
      libc/calls/ntaccesscheck.c
  24. 9
      libc/calls/vdprintf.c
  25. 28
      libc/conv/sizemultiply.h
  26. 4
      libc/crypto/unrijndaelinit.c
  27. 11
      libc/dns/parsehoststxt.c
  28. 12
      libc/dns/parseresolvconf.c
  29. 18
      libc/fmt/unbing.c
  30. 1
      libc/integral/c.inc
  31. 2
      libc/integral/normalize.inc
  32. 3
      libc/intrin/intrin.mk
  33. 2
      libc/intrin/repmovsb.h
  34. 2
      libc/intrin/repstosb.h
  35. 370
      libc/log/asan.c
  36. 21
      libc/log/asan.h
  37. 1
      libc/log/attachdebugger.c
  38. 3
      libc/log/backtrace.c
  39. 15
      libc/log/backtrace.h
  40. 63
      libc/log/backtrace2.c
  41. 118
      libc/log/backtrace3.c
  42. 3
      libc/log/commandvenv.c
  43. 1
      libc/log/gdbexec.c
  44. 2
      libc/log/log.h
  45. 17
      libc/log/log.mk
  46. 3
      libc/log/oncrash.c
  47. 116
      libc/log/somanyasan.S
  48. 0
      libc/log/somanyubsan.S
  49. 4
      libc/math/math.mk
  50. 59
      libc/mem/cxx/free.S
  51. 21
      libc/mem/cxx/malloc.S
  52. 15
      libc/mem/cxx/memalign.S
  53. 6
      libc/mem/hook/calloc.S
  54. 6
      libc/mem/hook/free.S
  55. 18
      libc/mem/hook/hook.h
  56. 9
      libc/mem/hook/malloc.S
  57. 33
      libc/mem/hook/malloc_usable_size.S
  58. 9
      libc/mem/hook/memalign.S
  59. 34
      libc/mem/hook/posix_memalign.S
  60. 34
      libc/mem/hook/pvalloc.S
  61. 6
      libc/mem/hook/realloc.S
  62. 34
      libc/mem/hook/realloc_in_place.S
  63. 34
      libc/mem/hook/valloc.S
  64. 1
      libc/mem/malloc.S
  65. 11
      libc/mem/malloc_usable_size.S
  66. 6
      libc/mem/mem.mk
  67. 14
      libc/mem/posix_memalign.S
  68. 16
      libc/mem/pvalloc.S
  69. 3
      libc/mem/realloc.S
  70. 26
      libc/mem/realloc_in_place.S
  71. 16
      libc/mem/valloc.S
  72. 4120
      libc/nexgen32e/djbsort-avx2.S
  73. 3
      libc/nexgen32e/gc.h
  74. 11
      libc/nexgen32e/memcpy.S
  75. 3
      libc/nexgen32e/memmove.S
  76. 6
      libc/nexgen32e/memset.S
  77. 13
      libc/nexgen32e/stackframe.h
  78. 4
      libc/runtime/construct.S
  79. 78
      libc/runtime/directmap.c
  80. 15
      libc/runtime/directmap.h
  81. 13
      libc/runtime/ezmap.c
  82. 1
      libc/runtime/ftrace.greg.c
  83. 3
      libc/runtime/gc.h
  84. 7
      libc/runtime/grow.c
  85. 1
      libc/runtime/internal.h
  86. 9
      libc/runtime/memtrack.h
  87. 121
      libc/runtime/mmap.c
  88. 35
      libc/runtime/munmap.c
  89. 1
      libc/runtime/ringalloc.c
  90. 2
      libc/runtime/ringfree.c
  91. 13
      libc/runtime/runtime.h
  92. 9
      libc/runtime/runtime.mk
  93. 1
      libc/runtime/symbols.h
  94. 10
      libc/runtime/untrackmemoryintervals.c
  95. 4
      libc/stdio/stdio.mk
  96. 18
      libc/str/str.h
  97. 4
      libc/str/str.mk
  98. 279
      libc/stubs/asan.S
  99. 54
      libc/stubs/asan.greg.S
  100. 24
      libc/tinymath/delegates/powif.c

8
Makefile

@ -60,9 +60,10 @@
#
# build/config.mk
SHELL = /bin/sh
HOSTS ?= freebsd openbsd alpine
SANITY := $(shell build/sanitycheck $$PPID)
SHELL = /bin/sh
HOSTS ?= freebsd openbsd alpine
SANITY := $(shell build/sanitycheck $$PPID)
GNUMAKEFLAGS += --output-sync
.SUFFIXES:
.DELETE_ON_ERROR:
@ -156,7 +157,6 @@ include tool/build/lib/buildlib.mk
include tool/build/emucrt/emucrt.mk
include tool/build/emubin/emubin.mk
include tool/build/build.mk
include tool/debug/debug.mk
include tool/decode/lib/decodelib.mk
include tool/decode/decode.mk
include tool/hash/hash.mk

7
build/compile

@ -276,10 +276,5 @@ if "$@"; then
exit 0
fi
if [ "$TERM" = "dumb" ]; then
f='%s %s\r\n\r\n'
else
f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n'
fi
printf "$f" "$CCNAME $CCVERSION: compile $REASON:" "$*" >&2
printf "$LOGFMT" "$CCNAME $CCVERSION: compile $REASON:" "$*" >&2
exit 1

3
build/config.mk

@ -17,9 +17,6 @@ CONFIG_CCFLAGS += \
$(FTRACE) \
-Og
CONFIG_COPTS += \
-ftrapv
TARGET_ARCH ?= \
-march=k8-sse3

139
dsp/mpeg/ycbcrio.c

@ -1,139 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/mpeg/mpeg.h"
#include "dsp/mpeg/ycbcrio.h"
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h"
#include "libc/log/check.h"
#include "libc/macros.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
static void CheckPlmFrame(const struct plm_frame_t *frame) {
CHECK_NE(0, frame->width);
CHECK_NE(0, frame->height);
CHECK_GE(frame->y.width, frame->width);
CHECK_GE(frame->y.height, frame->height);
CHECK_EQ(frame->cr.width, frame->cb.width);
CHECK_EQ(frame->cr.height, frame->cb.height);
CHECK_EQ(frame->y.width, frame->cr.width * 2);
CHECK_EQ(frame->y.height, frame->cr.height * 2);
CHECK_NOTNULL(frame->y.data);
CHECK_NOTNULL(frame->cr.data);
CHECK_NOTNULL(frame->cb.data);
}
static size_t GetHeaderBytes(const struct plm_frame_t *frame) {
return MAX(sizeof(struct Ycbcrio), ROUNDUP(frame->y.width, 16));
}
static size_t GetPlaneBytes(const struct plm_plane_t *plane) {
/*
* planes must be 16-byte aligned, but due to their hugeness, and the
* recommendation of intel's 6,000 page manual, it makes sense to have
* planes on isolated 64kb frames for multiprocessing.
*/
return ROUNDUP(ROUNDUP(plane->height, 16) * ROUNDUP(plane->width, 16),
FRAMESIZE);
}
static size_t CalcMapBytes(const struct plm_frame_t *frame) {
return ROUNDUP(GetHeaderBytes(frame) + GetPlaneBytes(&frame->y) +
GetPlaneBytes(&frame->cb) + GetPlaneBytes(&frame->cb),
FRAMESIZE);
}
static void FixupPointers(struct Ycbcrio *map) {
map->frame.y.data = (unsigned char *)map + GetHeaderBytes(&map->frame);
map->frame.cr.data = map->frame.y.data + GetPlaneBytes(&map->frame.y);
map->frame.cb.data = map->frame.cr.data + GetPlaneBytes(&map->frame.cr);
}
static struct Ycbcrio *YcbcrioOpenNew(const char *path,
const struct plm_frame_t *frame) {
int fd;
size_t size;
struct stat st;
struct Ycbcrio *map;
CheckPlmFrame(frame);
size = CalcMapBytes(frame);
CHECK_NE(-1, (fd = open(path, O_CREAT | O_RDWR, 0644)));
CHECK_NE(-1, fstat(fd, &st));
if (st.st_size < size) {
CHECK_NE(-1, ftruncate(fd, size));
}
CHECK_NE(MAP_FAILED,
(map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)));
map->magic = YCBCRIO_MAGIC;
map->fd = fd;
map->size = size;
memcpy(&map->frame, frame, sizeof(map->frame));
FixupPointers(map);
memcpy(&map->frame.y.data, frame->y.data, GetPlaneBytes(&frame->y));
memcpy(&map->frame.cb.data, frame->cb.data, GetPlaneBytes(&frame->cb));
memcpy(&map->frame.cr.data, frame->cr.data, GetPlaneBytes(&frame->cr));
return map;
}
static struct Ycbcrio *YcbcrioOpenExisting(const char *path) {
int fd;
struct stat st;
struct Ycbcrio *map;
CHECK_NE(-1, (fd = open(path, O_RDWR)));
CHECK_NE(-1, fstat(fd, &st));
CHECK_NE(MAP_FAILED, (map = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0)));
CHECK_EQ(YCBCRIO_MAGIC, map->magic);
CHECK_GE(st.st_size, CalcMapBytes(&map->frame));
FixupPointers(map);
map->fd = fd;
map->size = st.st_size;
return map;
}
/**
* Opens shareable persistable MPEG video frame memory.
*
* @param path is a file name
* @param frame if NULL means open existing file, otherwise copies new
* @param points to pointer returned by YcbcrioOpen() which is cleared
* @return memory mapping needing YcbcrioClose()
*/
struct Ycbcrio *YcbcrioOpen(const char *path, const struct plm_frame_t *frame) {
if (frame) {
return YcbcrioOpenNew(path, frame);
} else {
return YcbcrioOpenExisting(path);
}
}
/**
* Closes mapped video frame file.
*
* @param points to pointer returned by YcbcrioOpen() which is cleared
*/
void YcbcrioClose(struct Ycbcrio **map) {
CHECK_NE(-1, close_s(&(*map)->fd));
CHECK_NE(-1, munmap_s(map, (*map)->size));
}

27
dsp/mpeg/ycbcrio.h

@ -1,27 +0,0 @@
#ifndef COSMOPOLITAN_DSP_MPEG_YCBCRIO_H_
#define COSMOPOLITAN_DSP_MPEG_YCBCRIO_H_
#include "dsp/mpeg/mpeg.h"
#include "libc/bits/bswap.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define YCBCRIO_MAGIC bswap_32(0xBCCBCCBCu)
/**
* Mappable persistable MPEG-2 video frame in Y-Cr-Cb colorspace.
*/
struct Ycbcrio {
uint32_t magic;
int32_t fd;
uint64_t size;
plm_frame_t frame;
};
struct Ycbcrio *YcbcrioOpen(const char *, const struct plm_frame_t *)
paramsnonnull((1)) vallocesque returnsnonnull;
void YcbcrioClose(struct Ycbcrio **) paramsnonnull();
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_DSP_MPEG_YCBCRIO_H_ */

5
examples/fld.c

@ -7,6 +7,7 @@
http://creativecommons.org/publicdomain/zero/1.0/
*/
#endif
#include "libc/bits/bits.h"
#include "libc/inttypes.h"
#include "libc/literal.h"
#include "libc/math.h"
@ -34,7 +35,7 @@ void dobin(const char *op, long double x, FILE *f) {
memcpy(buf, &x, sizeof(x));
memcpy(&lo, &buf[0], sizeof(lo));
memcpy(&hi, &buf[8], sizeof(hi));
fprintf(f, "/\t%016" PRIb16 "%064" PRIb64 " %-8s %19.19Lf\n", hi, lo, op, x);
fprintf(f, "/\t%016" PRIb16 "%064" PRIb64 " %-8s % 19.19Lf\n", hi, lo, op, x);
}
void dohex(const char *op, long double x, FILE *f) {
@ -44,7 +45,7 @@ void dohex(const char *op, long double x, FILE *f) {
memcpy(buf, &x, sizeof(x));
memcpy(&lo, &buf[0], sizeof(lo));
memcpy(&hi, &buf[8], sizeof(hi));
fprintf(f, "/\t%04" PRIx16 "%016" PRIx64 " %-8s %19.19Lf\n", hi, lo, op, x);
fprintf(f, "/\t%04" PRIx16 "%016" PRIx64 " %-8s % 19.19Lf\n", hi, lo, op, x);
}
#define DOBIN(OP) \

1
examples/mappy.c

@ -10,6 +10,7 @@
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/macros.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"

3
examples/rusage.c

@ -32,9 +32,10 @@ int main(int argc, char *argv[]) {
int pid, wstatus;
long double ts1, ts2;
struct rusage rusage;
char pathbuf[PATH_MAX];
memset(&rusage, -1, sizeof(rusage));
CHECK_GT(argc, 1);
CHECK_NOTNULL((exe = commandv(argv[1])));
CHECK_NOTNULL((exe = commandv(argv[1], pathbuf)));
ts1 = nowl();
CHECK_NE(-1, (pid = spawnve(0, NULL, exe, &argv[1], environ)));
CHECK_NE(-1, wait4(pid, &wstatus, 0, &rusage));

0
libc/calls/hefty/access.c → libc/calls/access.c

8
libc/calls/calls.h

@ -86,7 +86,7 @@ char *realpath(const char *, char *);
char *replaceuser(const char *) nodiscard;
char *slurp(const char *, size_t *) nodiscard;
char *ttyname(int);
const char *commandv(const char *);
char *commandv(const char *, char[hasatleast PATH_MAX]);
int access(const char *, int) nothrow;
int arch_prctl();
int chdir(const char *);
@ -140,12 +140,8 @@ int mknodat(int, const char *, int32_t, uint64_t);
int mlock(const void *, size_t);
int mlock2(const void *, size_t, int);
int mlockall(int);
int mprotect(void *, uint64_t, int) privileged;
int msync(void *, size_t, int);
int munlock(const void *, size_t);
int munlockall(void);
int munmap(void *, uint64_t);
int munmap_s(void *, uint64_t);
int nice(int);
int open(const char *, int, ...) nodiscard;
int openanon(char *, unsigned) nodiscard;
@ -229,8 +225,6 @@ uint32_t gettid(void) nosideeffect;
uint32_t getuid(void) nosideeffect;
uint32_t umask(int32_t);
void *getprocaddressmodule(const char *, const char *);
void *mmap(void *, uint64_t, int32_t, int32_t, int32_t, int64_t);
void *mremap(void *, uint64_t, uint64_t, int32_t, void *);
#define getcwd(BUF, SIZE) \
(isconstant(BUF) && (&(BUF)[0] == NULL) ? get_current_dir_name() \

95
libc/calls/hefty/commandv.c → libc/calls/commandv.c

@ -17,28 +17,18 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/alg/alg.h"
#include "libc/bits/progn.h"
#include "libc/bits/safemacros.h"
#include "libc/calls/calls.h"
#include "libc/conv/conv.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/nt/ntdll.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/errfuns.h"
static struct critbit0 g_commandv;
textstartup static void g_commandv_init(void) {
__cxa_atexit(critbit0_clear, &g_commandv, NULL);
}
const void *const g_commandv_ctor[] initarray = {g_commandv_init};
static int accessexe(char pathname[hasatleast PATH_MAX], size_t len,
const char *ext) {
len = stpcpy(&pathname[len], ext) - &pathname[0];
@ -76,21 +66,21 @@ static int accesscmd(char pathname[hasatleast PATH_MAX], const char *path,
static int searchcmdpath(char pathname[hasatleast PATH_MAX], const char *name,
size_t namelen) {
int rc;
char *ep, *path, *pathtok;
struct critbit0 deduplicate;
char *path, *pathtok, ep[PATH_MAX];
rc = -1;
pathtok = ep =
strdup(firstnonnull(getenv("PATH"), "/bin:/usr/local/bin:/usr/bin"));
memset(&deduplicate, 0, sizeof(deduplicate));
if (!memccpy(ep,
firstnonnull(emptytonull(getenv("PATH")),
"/bin:/usr/local/bin:/usr/bin"),
'\0', sizeof(ep))) {
return enomem();
}
pathtok = ep;
while ((path = strsep(&pathtok, IsWindows() ? ";" : ":"))) {
if (strchr(path, '=')) continue;
if (!critbit0_insert(&deduplicate, path)) continue;
if ((rc = accesscmd(pathname, path, name, namelen)) != -1) {
break;
}
}
critbit0_clear(&deduplicate);
free(ep);
return rc;
}
@ -105,66 +95,29 @@ static char *mkcmdquery(const char *name, size_t namelen,
return &scratch[0];
}
static const char *cachecmd(const char *name, size_t namelen,
const char *pathname, size_t pathnamelen) {
size_t entrylen;
char *res, *entry;
if ((entry = malloc((entrylen = namelen + 1 + pathnamelen) + 1))) {
mkcmdquery(name, namelen, entry);
res = memcpy(&entry[namelen + 1], pathname, pathnamelen + 1);
critbit0_emplace(&g_commandv, entry, entrylen);
} else {
res = NULL;
}
return res;
}
static const char *getcmdcache(const char *name, size_t namelen,
char scratch[hasatleast PATH_MAX]) {
const char *entry;
if ((entry = critbit0_get(&g_commandv, mkcmdquery(name, namelen, scratch)))) {
return &entry[namelen + 1];
}
return NULL;
}
noinline static const char *findcmdpath(const char *name,
char pathname[hasatleast PATH_MAX]) {
/**
* Resolves full pathname of executable.
*
* @return execve()'able path, or NULL w/ errno
* @errno ENOENT, EACCES, ENOMEM
* @see free(), execvpe()
*/
char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
char *p;
int rc, olderr;
size_t len;
int rc, olderr;
olderr = errno;
if (!(len = strlen(name))) return PROGN(enoent(), NULL);
if (memchr(name, '=', len)) return PROGN(einval(), NULL);
if ((p = getcmdcache(name, len, pathname)) ||
(((IsWindows() &&
((rc = accesscmd(pathname, kNtSystemDirectory, name, len)) != -1 ||
(rc = accesscmd(pathname, kNtWindowsDirectory, name, len)) != -1)) ||
(rc = accesscmd(pathname, "", name, len)) != -1 ||
(!strpbrk(name, "/\\") &&
(rc = searchcmdpath(pathname, name, len)) != -1)) &&
(p = cachecmd(name, len, pathname, rc)))) {
if ((IsWindows() &&
((rc = accesscmd(pathbuf, kNtSystemDirectory, name, len)) != -1 ||
(rc = accesscmd(pathbuf, kNtWindowsDirectory, name, len)) != -1)) ||
(rc = accesscmd(pathbuf, "", name, len)) != -1 ||
(!strpbrk(name, "/\\") &&
(rc = searchcmdpath(pathbuf, name, len)) != -1)) {
errno = olderr;
return p;
return pathbuf;
} else {
return NULL;
}
}
/**
* Resolves pathname of executable.
*
* This does the same thing as `command -v` in bourne shell. Path
* lookups are cached for the lifetime of the process. Paths with
* multiple components will skip the resolution process. Undotted
* basenames get automatic .com and .exe suffix resolution on all
* platforms. Windows' system directories will always trump PATH.
*
* @return execve()'able path, or NULL w/ errno
* @errno ENOENT, EACCES, ENOMEM
* @see free(), execvpe()
*/
const char *commandv(const char *name) {
char pathname[PATH_MAX];
return findcmdpath(name, pathname);
}

0
libc/calls/hefty/faccessat-nt.c → libc/calls/faccessat-nt.c

0
libc/calls/hefty/faccessat.c → libc/calls/faccessat.c

4
libc/calls/g_fds_init.S

@ -19,11 +19,11 @@
*/
#include "libc/macros.h"
.init.start 300,_init_g_fds
.init.start 302,_init_g_fds
push %rdi
push %rsi
call InitializeFileDescriptors
pop %rsi
pop %rdi
.init.end 300,_init_g_fds
.init.end 302,_init_g_fds
.source __FILE__

26
libc/calls/getenv.c

@ -25,16 +25,22 @@
/**
* Returns value of environment variable, or NULL if not found.
*/
char *getenv(const char *name) {
char **ep;
size_t i, namelen;
char *empty[1] = {0};
ep = environ;
if (!ep) ep = empty;
namelen = strlen(name);
for (i = 0; ep[i]; ++i) {
if (strncmp(ep[i], name, namelen) == 0 && ep[i][namelen] == '=') {
return &ep[i][namelen + 1];
char *getenv(const char *s) {
char **p;
size_t i, j;
if ((p = environ)) {
for (i = 0; p[i]; ++i) {
for (j = 0;; ++j) {
if (!s[j]) {
if (p[i][j] == '=') {
return &p[i][j + 1];
}
break;
}
if (s[j] != p[i][j]) {
break;
}
}
}
}
return NULL;

4
libc/calls/hefty/execle.c

@ -17,9 +17,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/mem/mem.h"
#include "libc/calls/hefty/mkvarargv.h"
#include "libc/calls/calls.h"
#include "libc/calls/hefty/mkvarargv.h"
#include "libc/mem/mem.h"
/**
* Executes program, with custom environment.

7
libc/calls/hefty/execlp.c

@ -17,10 +17,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/calls/calls.h"
#include "libc/calls/hefty/mkvarargv.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/calls/hefty/mkvarargv.h"
#include "libc/calls/calls.h"
/**
* Executes program, with PATH search and current environment.
@ -36,7 +36,8 @@
*/
int execlp(const char *prog, const char *arg, ... /*, NULL*/) {
char *exe;
if ((exe = commandv(prog))) {
char pathbuf[PATH_MAX];
if ((exe = commandv(prog, pathbuf))) {
va_list va;
void *argv;
va_start(va, arg);

5
libc/calls/hefty/execvpe.c

@ -17,8 +17,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/mem/mem.h"
#include "libc/calls/calls.h"
#include "libc/mem/mem.h"
/**
* Executes program, with path environment search.
@ -33,7 +33,8 @@
*/
int execvpe(const char *prog, char *const argv[], char *const *envp) {
char *exe;
if ((exe = commandv(prog))) {
char pathbuf[PATH_MAX];
if ((exe = commandv(prog, pathbuf))) {
execve(exe, argv, envp);
}
return -1;

34
libc/calls/hefty/sortenvp.c

@ -24,17 +24,18 @@
#include "libc/nexgen32e/tinystrcmp.h"
#include "libc/str/str.h"
static int sortenvpcb(const char **a, const char **b) { return strcmp(*a, *b); }
static int CompareStrings(const char *l, const char *r) {
size_t i = 0;
while (l[i] == r[i] && r[i]) ++i;
return (l[i] & 0xff) - (r[i] & 0xff);
}
static void slowsort(char **a, int n) {
static void SortStrings(char **a, size_t n) {
char *t;
size_t i, j;
const char *t;
for (i = 1; i < n; ++i) {
j = i;
t = a[i];
while (j > 0 && tinystrcmp(t, a[j - 1]) < 0) {
for (t = a[i], j = i; j > 0 && CompareStrings(t, a[j - 1]) < 0; --j) {
a[j] = a[j - 1];
--j;
}
a[j] = t;
}
@ -52,17 +53,14 @@ static void slowsort(char **a, int n) {
* @return newly allocated sorted copy of envp pointer array
*/
hidden textwindows nodiscard char **sortenvp(char *const envp[]) {
size_t count = 0;
while (envp[count]) count++;
size_t bytesize = (count + 1) * sizeof(char *);
char **copy = malloc(bytesize);
if (copy) {
memcpy(copy, envp, bytesize);
if (IsTiny()) {
slowsort(copy, count);
} else {
qsort(copy, count, sizeof(char *), (void *)sortenvpcb);
}
char **copy;
size_t n, size;
n = 0;
while (envp[n]) n++;
size = (n + 1) * sizeof(char *);
if ((copy = malloc(size))) {
memcpy(copy, envp, size);
SortStrings(copy, n);
}
return copy;
}

3
libc/calls/hefty/spawnlp.c

@ -40,8 +40,9 @@ nodiscard int spawnlp(unsigned flags, int stdiofds[3], const char *prog,
char *exe;
va_list va;
void *argv;
char pathbuf[PATH_MAX];
pid = -1;
if ((exe = commandv(prog))) {
if ((exe = commandv(prog, pathbuf))) {
va_start(va, arg);
if ((argv = mkvarargv(arg, va))) {
pid = spawnve(flags, stdiofds, exe, argv, environ);

0
libc/runtime/kntsystemdirectory.S → libc/calls/kntsystemdirectory.S

0
libc/runtime/kntwindowsdirectory.S → libc/calls/kntwindowsdirectory.S

39
libc/calls/hefty/ntaccesscheck.c → libc/calls/ntaccesscheck.c

@ -17,7 +17,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/mem/mem.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/securityinformation.h"
#include "libc/nt/errors.h"
@ -28,33 +29,33 @@
#include "libc/nt/struct/securitydescriptor.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/calls/internal.h"
#include "libc/calls/calls.h"
#include "libc/sysv/consts/ok.h"
/**
* Checks if current process has access to folder or file.
* Asks Microsoft if we're authorized to use a folder or file.
*
* Implementation Details: MSDN documentation imposes no limit on the
* internal size of SECURITY_DESCRIPTOR, which we are responsible for
* allocating. We've selected 1024 which shall hopefully be adequate.
*
* @param flags can have R_OK, W_OK, X_OK, etc.
* @return 0 if authorized, or -1 w/ errno
* @kudos Aaron Ballman for teaching how to do this
* @kudos Aaron Ballman for teaching this
* @see libc/sysv/consts.sh
*/
textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
int rc;
bool32 result;
struct NtGenericMapping mapping;
struct NtPrivilegeSet privileges;
int64_t hToken, hImpersonatedToken;
uint32_t secsize, granted, privsize;
struct NtPrivilegeSet privileges;
struct NtGenericMapping mapping;
struct NtSecurityDescriptor security;
struct NtSecurityDescriptor *psecurity;
const uint32_t request = kNtOwnerSecurityInformation |
kNtGroupSecurityInformation |
kNtDaclSecurityInformation;
union NtSecurityDescriptorLol {
struct NtSecurityDescriptor s;
char b[1024];
} security;
granted = 0;
result = false;
psecurity = &security;
secsize = sizeof(security);
privsize = sizeof(privileges);
memset(&privileges, 0, sizeof(privileges));
@ -64,23 +65,23 @@ textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
mapping.GenericAll = kNtFileAllAccess;
MapGenericMask(&flags, &mapping);
hImpersonatedToken = hToken = -1;
if ((GetFileSecurity(pathname, request, psecurity, 0, &secsize) ||
(GetLastError() == kNtErrorInsufficientBuffer &&
(psecurity = malloc(secsize)) &&
GetFileSecurity(pathname, request, psecurity, secsize, &secsize))) &&
if (GetFileSecurity(pathname,
kNtOwnerSecurityInformation |
kNtGroupSecurityInformation |
kNtDaclSecurityInformation,
&security.s, 0, &secsize) &&
OpenProcessToken(GetCurrentProcess(),
kNtTokenImpersonate | kNtTokenQuery | kNtTokenDuplicate |
kNtStandardRightsRead,
&hToken) &&
DuplicateToken(hToken, kNtSecurityImpersonation, &hImpersonatedToken) &&
AccessCheck(psecurity, hImpersonatedToken, flags, &mapping, &privileges,
AccessCheck(&security.s, hImpersonatedToken, flags, &mapping, &privileges,
&privsize, &granted, &result) &&
(result || flags == F_OK)) {
rc = 0;
} else {
rc = winerr();
}
free_s(&psecurity);
close(hImpersonatedToken);
close(hToken);
return rc;

9
libc/calls/vdprintf.c

@ -57,10 +57,7 @@ int(vdprintf)(int fd, const char *fmt, va_list va) {
struct VdprintfState df;
df.n = 0;
df.fd = fd;
if (palandprintf(vdprintfputchar, &df, fmt, va) != -1 ||
vdprintf_flush(&df, df.n & (ARRAYLEN(df.buf) - 1)) != -1) {
return df.n;
} else {
return -1;
}
if (palandprintf(vdprintfputchar, &df, fmt, va) == -1) return -1;
if (vdprintf_flush(&df, df.n & (ARRAYLEN(df.buf) - 1)) == -1) return -1;
return df.n;
}

28
libc/conv/sizemultiply.h

@ -1,28 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CONV_SIZEMULTIPLY_H_
#define COSMOPOLITAN_LIBC_CONV_SIZEMULTIPLY_H_
#include "libc/limits.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
/**
* Multiplies memory sizes.
*
* @param count may be 0 to for realloc() free() behavior
* @param opt_out set to count*itemsize or SIZE_MAX on overflow
* @return true on success or false on overflow
*/
forceinline bool sizemultiply(size_t *opt_out, size_t count, size_t itemsize) {
size_t res = 0;
bool overflowed = false;
if (count != 0) {
res = count * itemsize;
if (((count | itemsize) & ~0xfffful) && (res / count != itemsize)) {
overflowed = true;
res = SIZE_MAX;
}
}
if (opt_out) *opt_out = res;
return !overflowed;
}
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CONV_SIZEMULTIPLY_H_ */

4
libc/crypto/unrijndaelinit.c

@ -33,7 +33,7 @@ static void unrijndaelinit$westmere(struct Rijndael *ctx, uint32_t n,
x = ctx->rk[i].xmm;
asm("aesimc\t%1,%0" : "=x"(x) : "0"(x));
ctx->rk[i].xmm = x;
} while (i++ < n);
} while (++i < n);
XMM_DESTROY(x);
}
@ -49,7 +49,7 @@ static relegated noinline void unrijndaelinit$pure(struct Rijndael *ctx,
x = ctx->rk[i].xmm;
x = InvMixColumns(x);
ctx->rk[i].xmm = x;
} while (i++ < n);
} while (++i < n);
XMM_DESTROY(x);
}

11
libc/dns/parsehoststxt.c

@ -45,10 +45,11 @@
*/
int parsehoststxt(struct HostsTxt *ht, FILE *f) {
int rc = 0;
char stackline[128];
char *line = stackline;
size_t linecap = sizeof(stackline);
while ((getline(&line, &linecap, f)) != -1) {
char *line;
size_t linesize;
line = NULL;
linesize = 0;
while ((getline(&line, &linesize, f)) != -1) {
struct HostsTxtEntry entry;
char *addr, *name, *tok, *comment;
if ((comment = strchr(line, '#'))) *comment = '\0';
@ -64,6 +65,6 @@ int parsehoststxt(struct HostsTxt *ht, FILE *f) {
}
}
}
free_s(&line);
free(line);
return rc | ferror(f);
}

12
libc/dns/parseresolvconf.c

@ -20,6 +20,7 @@
#include "libc/alg/arraylist.h"
#include "libc/dns/dns.h"
#include "libc/dns/resolvconf.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
@ -44,13 +45,14 @@
int parseresolvconf(struct ResolvConf *resolv, struct FILE *f) {
/* TODO(jart): options ndots:5 */
int rc = 0;
char stackline[32];
char *line = stackline;
size_t linecap = sizeof(stackline);
char *line;
size_t linesize;
struct sockaddr_in nameserver;
line = NULL;
linesize = 0;
nameserver.sin_family = AF_INET;
nameserver.sin_port = htons(DNS_PORT);
while (getline(&line, &linecap, f) != -1) {
while (getline(&line, &linesize, f) != -1) {
char *directive, *value, *tok, *comment;
if ((comment = strchr(line, '#'))) *comment = '\0';
if ((directive = strtok_r(line, " \t\r\n\v", &tok)) &&
@ -61,6 +63,6 @@ int parseresolvconf(struct ResolvConf *resolv, struct FILE *f) {
}
}
}
free_s(&line);
free(line);
return rc | ferror(f);
}

18
libc/fmt/unbing.c

@ -56,14 +56,7 @@ static int g_cp437i[256 + ARRAYLEN(kCp437iMultimappings)];
* @see bing()
*/
int unbing(int c) {
int i, m, l, r;
static bool once;
if (!once) {
for (i = 0; i < 256; ++i) g_cp437i[i] = kCp437[i] << 8 | i;
memcpy(g_cp437i + 256, kCp437iMultimappings, sizeof(kCp437iMultimappings));
insertionsort(ARRAYLEN(g_cp437i), g_cp437i);
once = true;
}
int m, l, r;
l = 0;
r = ARRAYLEN(g_cp437i) - 1;
while (l <= r) {
@ -78,3 +71,12 @@ int unbing(int c) {
}
return -1;
}
static textstartup void g_cp437i_init() {
unsigned i;
for (i = 0; i < 256; ++i) g_cp437i[i] = kCp437[i] << 8 | i;
memcpy(g_cp437i + 256, kCp437iMultimappings, sizeof(kCp437iMultimappings));
djbsort(ARRAYLEN(g_cp437i), g_cp437i);
}
const void *const g_cp437i_ctor[] initarray = {g_cp437i_init};

1
libc/integral/c.inc

@ -336,6 +336,7 @@ typedef uint64_t uintmax_t;
* 4. unprofilable
* 5. unhookable
*
* @note consider static or writing a macro
* @see externinline
*/
#ifndef forceinline

2
libc/integral/normalize.inc

@ -66,8 +66,8 @@
#endif
#define BIGPAGESIZE 0x200000
#define STACKSIZE 0x20000
#define FRAMESIZE 0x10000 /* 8086 */
#define STACKSIZE 0x10000 /* goog */
#define PAGESIZE 0x1000 /* i386+ */
#define BUFSIZ 0x1000 /* best stdio default */
#define CACHELINE 0x40 /* nexgen32e */

3
libc/intrin/intrin.mk

@ -13,8 +13,7 @@ LIBC_INTRIN_A_SRCS = $(LIBC_INTRIN_A_SRCS_S) $(LIBC_INTRIN_A_SRCS_C)
LIBC_INTRIN_A_CHECKS = $(LIBC_INTRIN_A).pkg
LIBC_INTRIN_A_FILES := \
$(wildcard libc/intrin/*) \
$(wildcard libc/intrin/delegates/*)
$(wildcard libc/intrin/*)
LIBC_INTRIN_A_OBJS = \
$(LIBC_INTRIN_A_SRCS:%=o/$(MODE)/%.zip.o) \

2
libc/intrin/repmovsb.h

@ -2,7 +2,7 @@
#define COSMOPOLITAN_LIBC_INTRIN_REPMOVSB_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
static void repmovsb(void **dest, const void **src, size_t cx) {
forceinline void repmovsb(void **dest, const void **src, size_t cx) {
char *di = (char *)*dest;
const char *si = (const char *)*src;
while (cx) *di++ = *si++, cx--;

2
libc/intrin/repstosb.h

@ -2,7 +2,7 @@
#define COSMOPOLITAN_LIBC_INTRIN_REPSTOSB_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
static void *repstosb(void *dest, unsigned char al, size_t cx) {
forceinline void *repstosb(void *dest, unsigned char al, size_t cx) {
unsigned char *di = (unsigned char *)dest;
while (cx) *di++ = al, cx--;
return di;

370
libc/log/asan.c

@ -0,0 +1,370 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/assert.h"
#include "libc/bits/safemacros.h"
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/conv/conv.h"
#include "libc/conv/itoa.h"
#include "libc/log/asan.h"
#include "libc/log/backtrace.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/mem/hook/hook.h"
#include "libc/runtime/directmap.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/memtrack.h"
#include "libc/runtime/missioncritical.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
#include "third_party/dlmalloc/dlmalloc.h"
/**
* @fileoverview Cosmopolitan Address Sanitizer Runtime.
*
* Someone brilliant at Google figured out a way to improve upon memory
* protection. Rather than invent another Java or Rust they changed GCC
* so it can emit fast code, that checks the validity of each memory op
* with byte granularity, by probing shadow memory.
*
* AddressSanitizer dedicates one-eighth of the virtual address space
* to its shadow memory and uses a direct mapping with a scale and
* offset to translate an application address to its corresponding
* shadow address. Given the application memory address Addr, the
* address of the shadow byte is computed as (Addr>>3)+Offset."
*
* We use the following encoding for each shadow byte: 0 means that
* all 8 bytes of the corresponding application memory region are
* addressable; k (1 k 7) means that the first k bytes are
* addressible; any negative value indicates that the entire 8-byte
* word is unaddressable. We use different negative values to
* distinguish between different kinds of unaddressable memory (heap
* redzones, stack redzones, global redzones, freed memory).
*
* Here's what the generated code looks like for 64-bit reads:
*
* movq %addr,%tmp
* shrq $3,%tmp
* cmpb $0,0x7fff8000(%tmp)
* jnz abort
* movq (%addr),%dst
*/
#define HOOK(HOOK, IMPL) \
if (weaken(HOOK)) { \
*weaken(HOOK) = IMPL; \
}
struct AsanSourceLocation {
const char *filename;
int line;
int column;
};
struct AsanAccessInfo {
const char *addr;
const char *first_bad_addr;
size_t size;
bool iswrite;
unsigned long ip;
};
struct AsanGlobal {
const char *addr;
size_t size;
size_t size_with_redzone;
const void *name;
const void *module_name;
unsigned long has_cxx_init;
struct AsanSourceLocation *location;
char *odr_indicator;
};
static bool __asan_is_mapped(void *p) {
int x, i;
x = (intptr_t)p >> 16;
i = FindMemoryInterval(&_mmi, x);
return i < _mmi.i && x >= _mmi.p[i].x && x <= _mmi.p[i].y;
}
void __asan_map_shadow(void *addr, size_t size) {
int i, n, x;
char *a, *b;
struct DirectMap sm;
a = (char *)ROUNDDOWN(SHADOW((intptr_t)addr), FRAMESIZE);
b = (char *)ROUNDDOWN(SHADOW((intptr_t)addr + size - 1), FRAMESIZE);
for (; a <= b; a += FRAMESIZE) {
if (!__asan_is_mapped(a)) {
sm = DirectMap(a, FRAMESIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (sm.addr == MAP_FAILED ||
TrackMemoryInterval(&_mmi, (intptr_t)a >> 16, (intptr_t)a >> 16,
sm.maphandle) == -1) {
abort();
}
}
}
}
size_t __asan_malloc_usable_size(const void *vp) {
char *s;
size_t n;
for (n = 0, s = (char *)SHADOW((intptr_t)vp);; ++s) {
if (!*s) {
n += 8;
} else if (*s > 0) {
n += *s & 7;
} else {
break;
}
}
return n;
}
void *__asan_allocate(size_t align, size_t size, int underrun, int overrun) {
char *p, *s;
size_t q, r, i;
if (!(p = dlmemalign(align, ROUNDUP(size, 8) + 16))) return NULL;
s = (char *)SHADOW((intptr_t)p - 16);
q = size / 8;
r = size % 8;
*s++ = underrun;
*s++ = underrun;
memset(s, 0, q);
s += q;
if (r) *s++ = r;
*s++ = overrun;
*s++ = overrun;
return p;
}
void __asan_deallocate(char *p, int kind) {
char *s;
size_t n;
s = (char *)SHADOW((intptr_t)p);
n = dlmalloc_usable_size(p);
n /= 8;
memset(s, kind, n);
dlfree(p);
}
void __asan_free(void *vp) {
__asan_deallocate(vp, kAsanHeapFree);
}
void *__asan_memalign(size_t align, size_t size) {
return __asan_allocate(align, size, kAsanHeapUnderrun, kAsanHeapOverrun);
}
void *__asan_malloc(size_t size) {
return __asan_memalign(16, size);
}
void *__asan_calloc(size_t n, size_t m) {
char *p;
size_t size;
if (__builtin_mul_overflow(n, m, &size)) size = -1;
if ((p = __asan_malloc(size))) memset(p, 0, size);
return p;
}
void *__asan_realloc(void *p, size_t n) {
char *p2;
if (p) {
if (n) {
if ((p2 = __asan_malloc(n))) {
memcpy(p2, p, min(n, dlmalloc_usable_size(p)));
__asan_deallocate(p, kAsanRelocated);
}
} else {
__asan_free(p);
p2 = NULL;
}
} else {
p2 = __asan_malloc(n);
}
return p2;
}
void *__asan_valloc(size_t n) {
return __asan_memalign(PAGESIZE, n);
}
void *__asan_pvalloc(size_t n) {
return __asan_valloc(ROUNDUP(n, PAGESIZE));
}
void __asan_poison(intptr_t addr, size_t size, size_t redsize, int kind) {
char *s;
intptr_t p;
size_t a, b, w;
w = (intptr_t)addr & 7;
p = (intptr_t)addr - w;
a = w + size;
b = w + redsize;
s = (char *)SHADOW(p + a);
if (a & 7) *s++ = a & 7;
memset(s, kind, (b - ROUNDUP(a, 8)) >> 3);
}
void __asan_register_globals(struct AsanGlobal g[], int n) {
size_t i;
for (i = 0; i < n; ++i) {
__asan_poison((intptr_t)g[i].addr, g[i].size, g[i].size_with_redzone,
kAsanGlobalOverrun);
}
}
void __asan_report_memory_fault(uint8_t *addr, int size, const char *kind) {
char *p, *s, ibuf[21], buf[256];
switch (*(char *)SHADOW((intptr_t)addr)) {
case kAsanStackFree:
s = "stack use after release";
break;
case kAsanHeapFree:
s = "heap use after free";
break;
case kAsanRelocated:
s = "heap use after relocate";
break;
case kAsanHeapUnderrun:
s = "heap underrun";
break;
case kAsanHeapOverrun:
s = "heap overrun";
break;
case kAsanStackUnderrun:
s = "stack underflow";
break;
case kAsanStackOverrun:
s = "stack overflow";
break;
case kAsanAllocaOverrun:
s = "alloca overflow";
break;
case kAsanUnscoped:
s = "unscoped";
break;
default:
s = "poisoned";
break;
}
p = buf;
p = stpcpy(p, "error: ");
p = stpcpy(p, s);
p = stpcpy(p, " ");
uint64toarray_radix10(size, ibuf);
p = stpcpy(p, ibuf);
p = stpcpy(p, "-byte ");
p = stpcpy(p, kind);
p = stpcpy(p, " at 0x");
uint64toarray_fixed16((intptr_t)addr, ibuf, 48);
p = stpcpy(p, ibuf);
p = stpcpy(p, "\n");
__print(buf, p - buf);
PrintBacktraceUsingSymbols(stderr, __builtin_frame_address(0),
getsymboltable());
DebugBreak();
_Exit(66);
}
void *__asan_stack_malloc(size_t size, int classid) {
return __asan_allocate(32, size, kAsanStackUnderrun, kAsanStackOverrun);
}
void __asan_stack_free(char *p, size_t size, int classid) {
return __asan_deallocate(p, kAsanStackFree);
}
void __asan_report_load_n(uint8_t *addr, int size) {
__asan_report_memory_fault(addr, size, "load");
}
void __asan_report_store_n(uint8_t *addr, int size) {
__asan_report_memory_fault(addr, size, "store");
}
void __asan_poison_stack_memory(uintptr_t p, size_t n) {
memset((char *)SHADOW(p), kAsanUnscoped, n >> 3);
if (n & 7) *(char *)SHADOW(p + n) = 8 - (n & 7);
}
void __asan_unpoison_stack_memory(uintptr_t p, size_t n) {
memset((char *)SHADOW(p), 0, n >> 3);
if (n & 7) *(char *)SHADOW(p + n) = n & 7;
}
void __asan_loadN(intptr_t ptr, size_t size) {
DebugBreak();
}
void __asan_storeN(intptr_t ptr, size_t size) {
DebugBreak();
}
void __asan_alloca_poison(intptr_t addr, size_t size) {
__asan_poison(addr, size, size + 32, kAsanAllocaOverrun);
}
void __asan_allocas_unpoison(uintptr_t top, uintptr_t bottom) {
memset((char *)SHADOW(top), 0, (bottom - top) >> 3);
}
void *__asan_addr_is_in_fake_stack(void *fakestack, void *addr, void **beg,
void **end) {
return NULL;
}
void *__asan_get_current_fake_stack(void) {
return NULL;