AddressSanitizer run-time library. Not yet integrated with the compiler-rt build system, but can be built using the old makefile. See details in README.txt
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@145463 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h
new file mode 100644
index 0000000..1de6eb1
--- /dev/null
+++ b/lib/asan/asan_internal.h
@@ -0,0 +1,178 @@
+//===-- asan_internal.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// ASan-private header which defines various general utilities.
+//===----------------------------------------------------------------------===//
+#ifndef ASAN_INTERNAL_H
+#define ASAN_INTERNAL_H
+
+#include <stdint.h> // for __WORDSIZE
+#include <stdlib.h> // for size_t
+#include <unistd.h> // for _exit
+
+#ifdef ANDROID
+#include <sys/atomics.h>
+#endif
+
+#ifdef ADDRESS_SANITIZER
+# error "The AddressSanitizer run-time should not be"
+ " instrumented by AddressSanitizer"
+#endif
+
+// All internal functions in asan reside inside the __asan namespace
+// to avoid namespace collisions with the user programs.
+// Seperate namespace also makes it simpler to distinguish the asan run-time
+// functions from the instrumented user code in a profile.
+namespace __asan {
+
+class AsanThread;
+struct AsanStackTrace;
+
+// asan_rtl.cc
+void CheckFailed(const char *cond, const char *file, int line);
+void ShowStatsAndAbort();
+
+// asan_globals.cc
+bool DescribeAddrIfGlobal(uintptr_t addr);
+
+// asan_malloc_linux.cc / asan_malloc_mac.cc
+void ReplaceSystemMalloc();
+
+// asan_linux.cc / asan_mac.cc
+void *AsanDoesNotSupportStaticLinkage();
+void *asan_mmap(void *addr, size_t length, int prot, int flags,
+ int fd, uint64_t offset);
+ssize_t asan_write(int fd, const void *buf, size_t count);
+
+// asan_printf.cc
+void RawWrite(const char *buffer);
+int SNPrint(char *buffer, size_t length, const char *format, ...);
+void Printf(const char *format, ...);
+void Report(const char *format, ...);
+
+extern size_t FLAG_quarantine_size;
+extern int FLAG_demangle;
+extern bool FLAG_symbolize;
+extern int FLAG_v;
+extern bool FLAG_mt;
+extern size_t FLAG_redzone;
+extern int FLAG_debug;
+extern bool FLAG_poison_shadow;
+extern int FLAG_report_globals;
+extern size_t FLAG_malloc_context_size;
+extern bool FLAG_stats;
+extern bool FLAG_replace_str;
+extern bool FLAG_replace_intrin;
+extern bool FLAG_replace_cfallocator;
+extern bool FLAG_fast_unwind;
+extern bool FLAG_use_fake_stack;
+extern size_t FLAG_max_malloc_fill_size;
+extern int FLAG_exitcode;
+extern bool FLAG_allow_user_poisoning;
+
+extern int asan_inited;
+// Used to avoid infinite recursion in __asan_init().
+extern bool asan_init_is_running;
+
+enum LinkerInitialized { LINKER_INITIALIZED = 0 };
+
+#ifndef ASAN_DIE
+#define ASAN_DIE _exit(FLAG_exitcode)
+#endif // ASAN_DIE
+
+#define CHECK(cond) do { if (!(cond)) { \
+ CheckFailed(#cond, __FILE__, __LINE__); \
+}}while(0)
+
+#define RAW_CHECK_MSG(expr, msg) do { \
+ if (!(expr)) { \
+ RawWrite(msg); \
+ ASAN_DIE; \
+ } \
+} while (0)
+
+#define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr)
+
+#define UNIMPLEMENTED() CHECK("unimplemented" && 0)
+
+#define ASAN_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+
+const size_t kWordSize = __WORDSIZE / 8;
+const size_t kWordSizeInBits = 8 * kWordSize;
+const size_t kPageSizeBits = 12;
+const size_t kPageSize = 1UL << kPageSizeBits;
+
+#define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0)
+#define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0)
+
+#define GET_BP_PC_SP \
+ uintptr_t bp = GET_CURRENT_FRAME(); \
+ uintptr_t pc = GET_CALLER_PC(); \
+ uintptr_t local_stack; \
+ uintptr_t sp = (uintptr_t)&local_stack;
+
+// These magic values are written to shadow for better error reporting.
+const int kAsanHeapLeftRedzoneMagic = 0xfa;
+const int kAsanHeapRightRedzoneMagic = 0xfb;
+const int kAsanHeapFreeMagic = 0xfd;
+const int kAsanStackLeftRedzoneMagic = 0xf1;
+const int kAsanStackMidRedzoneMagic = 0xf2;
+const int kAsanStackRightRedzoneMagic = 0xf3;
+const int kAsanStackPartialRedzoneMagic = 0xf4;
+const int kAsanStackAfterReturnMagic = 0xf5;
+const int kAsanUserPoisonedMemoryMagic = 0xf7;
+const int kAsanGlobalRedzoneMagic = 0xf9;
+
+static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3;
+static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E;
+
+// Poison the shadow memory which corresponds to 'redzone_size' bytes
+// of the original memory, where first 'size' bytes are addressable.
+static inline void
+PoisonShadowPartialRightRedzone(unsigned char *shadow,
+ uintptr_t size,
+ uintptr_t redzone_size,
+ uintptr_t shadow_granularity,
+ unsigned char magic) {
+ for (uintptr_t i = 0; i < redzone_size;
+ i+= shadow_granularity, shadow++) {
+ if (i + shadow_granularity <= size) {
+ *shadow = 0; // fully addressable
+ } else if (i >= size) {
+ *shadow = (shadow_granularity == 128) ? 0xff : magic; // unaddressable
+ } else {
+ *shadow = size - i; // first size-i bytes are addressable
+ }
+ }
+}
+
+// -------------------------- Atomic ---------------- {{{1
+static inline int AtomicInc(int *a) {
+ if (!FLAG_mt) return ++(*a);
+#ifdef ANDROID
+ return __atomic_inc(a) + 1;
+#else
+ return __sync_add_and_fetch(a, 1);
+#endif
+}
+
+static inline int AtomicDec(int *a) {
+ if (!FLAG_mt) return --(*a);
+#ifdef ANDROID
+ return __atomic_dec(a) - 1;
+#else
+ return __sync_add_and_fetch(a, -1);
+#endif
+}
+
+} // namespace __asan
+
+#endif // ASAN_INTERNAL_H