aboutsummaryrefslogtreecommitdiff
path: root/contrib/compiler-rt/lib/asan
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-02-06 13:39:20 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-02-06 13:39:20 +0000
commitf8ca070d3aeee9332d1843f5aa44945374b51b8e (patch)
tree4efb8604227ede935238eb1c67b626da1265d459 /contrib/compiler-rt/lib/asan
parent752d00608cb24d3c902d6890efe6964247c2532c (diff)
parent807551b099338b7cc4f66ee567aae20a529dd27e (diff)
downloadsrc-f8ca070d3aeee9332d1843f5aa44945374b51b8e.tar.gz
src-f8ca070d3aeee9332d1843f5aa44945374b51b8e.zip
Merge compiler-rt release_38 branch r258968.
Note that there is still a problem on amd64, causing SIGBUS in the early startup of Address Sanitizer. This is being investigated.
Notes
Notes: svn path=/projects/clang380-import/; revision=295349
Diffstat (limited to 'contrib/compiler-rt/lib/asan')
-rw-r--r--contrib/compiler-rt/lib/asan/README.txt2
-rw-r--r--contrib/compiler-rt/lib/asan/asan_activation.cc9
-rw-r--r--contrib/compiler-rt/lib/asan/asan_allocator.cc22
-rw-r--r--contrib/compiler-rt/lib/asan/asan_allocator.h5
-rw-r--r--contrib/compiler-rt/lib/asan/asan_debugging.cc4
-rw-r--r--contrib/compiler-rt/lib/asan/asan_fake_stack.cc22
-rw-r--r--contrib/compiler-rt/lib/asan/asan_flags.cc9
-rw-r--r--contrib/compiler-rt/lib/asan/asan_flags.inc24
-rw-r--r--contrib/compiler-rt/lib/asan/asan_globals.cc5
-rw-r--r--contrib/compiler-rt/lib/asan/asan_init_version.h4
-rw-r--r--contrib/compiler-rt/lib/asan/asan_interceptors.cc74
-rw-r--r--contrib/compiler-rt/lib/asan/asan_interceptors.h6
-rw-r--r--contrib/compiler-rt/lib/asan/asan_interface_internal.h23
-rw-r--r--contrib/compiler-rt/lib/asan/asan_internal.h7
-rw-r--r--contrib/compiler-rt/lib/asan/asan_linux.cc23
-rw-r--r--contrib/compiler-rt/lib/asan/asan_mac.cc197
-rw-r--r--contrib/compiler-rt/lib/asan/asan_malloc_linux.cc21
-rw-r--r--contrib/compiler-rt/lib/asan/asan_malloc_mac.cc371
-rw-r--r--contrib/compiler-rt/lib/asan/asan_mapping.h33
-rw-r--r--contrib/compiler-rt/lib/asan/asan_new_delete.cc10
-rw-r--r--contrib/compiler-rt/lib/asan/asan_poisoning.cc29
-rw-r--r--contrib/compiler-rt/lib/asan/asan_posix.cc10
-rw-r--r--contrib/compiler-rt/lib/asan/asan_report.cc226
-rw-r--r--contrib/compiler-rt/lib/asan/asan_report.h67
-rw-r--r--contrib/compiler-rt/lib/asan/asan_rtl.cc152
-rw-r--r--contrib/compiler-rt/lib/asan/asan_stack.h9
-rw-r--r--contrib/compiler-rt/lib/asan/asan_thread.cc21
-rw-r--r--contrib/compiler-rt/lib/asan/asan_thread.h13
-rw-r--r--contrib/compiler-rt/lib/asan/asan_win.cc20
-rw-r--r--contrib/compiler-rt/lib/asan/asan_win_dll_thunk.cc30
-rw-r--r--contrib/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cc2
-rwxr-xr-xcontrib/compiler-rt/lib/asan/scripts/asan_device_setup344
-rwxr-xr-xcontrib/compiler-rt/lib/asan/scripts/asan_symbolize.py482
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_asm_test.cc267
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_benchmarks_test.cc85
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_exceptions_test.cc27
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_fake_stack_test.cc152
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_globals_test.cc45
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_interface_test.cc433
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_mac_test.cc236
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_mac_test.h19
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_mac_test_helpers.mm240
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_mem_test.cc241
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_noinst_test.cc263
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_oob_test.cc128
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_racy_double_free_test.cc32
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_str_test.cc573
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_test.cc1319
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_test.ignore3
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_test_config.h54
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_test_main.cc19
-rw-r--r--contrib/compiler-rt/lib/asan/tests/asan_test_utils.h107
52 files changed, 540 insertions, 5979 deletions
diff --git a/contrib/compiler-rt/lib/asan/README.txt b/contrib/compiler-rt/lib/asan/README.txt
index 8cc9bb17b59d..bb6ff42c5cde 100644
--- a/contrib/compiler-rt/lib/asan/README.txt
+++ b/contrib/compiler-rt/lib/asan/README.txt
@@ -23,4 +23,4 @@ from the root of your CMake build tree:
make check-asan
For more instructions see:
-http://code.google.com/p/address-sanitizer/wiki/HowToBuild
+https://github.com/google/sanitizers/wiki/AddressSanitizerHowToBuild
diff --git a/contrib/compiler-rt/lib/asan/asan_activation.cc b/contrib/compiler-rt/lib/asan/asan_activation.cc
index 3bc01984898d..9df3b977ea1b 100644
--- a/contrib/compiler-rt/lib/asan/asan_activation.cc
+++ b/contrib/compiler-rt/lib/asan/asan_activation.cc
@@ -38,7 +38,7 @@ static struct AsanDeactivatedFlags {
#undef ASAN_ACTIVATION_FLAG
#undef COMMON_ACTIVATION_FLAG
- RegisterIncludeFlag(parser, cf);
+ RegisterIncludeFlags(parser, cf);
}
void OverrideFromActivationFlags() {
@@ -61,11 +61,6 @@ static struct AsanDeactivatedFlags {
parser.ParseString(env);
}
- // Override from getprop asan.options.
- char buf[100];
- GetExtraActivationFlags(buf, sizeof(buf));
- parser.ParseString(buf);
-
SetVerbosity(cf.verbosity);
if (Verbosity()) ReportUnrecognizedFlags();
@@ -124,6 +119,8 @@ void AsanActivate() {
if (!asan_is_deactivated) return;
VReport(1, "Activating ASan\n");
+ UpdateProcessName();
+
asan_deactivated_flags.OverrideFromActivationFlags();
SetCanPoisonMemory(asan_deactivated_flags.poison_heap);
diff --git a/contrib/compiler-rt/lib/asan/asan_allocator.cc b/contrib/compiler-rt/lib/asan/asan_allocator.cc
index 2df9a510bd9a..56f184a36651 100644
--- a/contrib/compiler-rt/lib/asan/asan_allocator.cc
+++ b/contrib/compiler-rt/lib/asan/asan_allocator.cc
@@ -14,8 +14,8 @@
// with ThreadSanitizer and MemorySanitizer.
//
//===----------------------------------------------------------------------===//
-#include "asan_allocator.h"
+#include "asan_allocator.h"
#include "asan_mapping.h"
#include "asan_poisoning.h"
#include "asan_report.h"
@@ -541,7 +541,7 @@ struct Allocator {
u8 chunk_state = m->chunk_state;
if (chunk_state != CHUNK_ALLOCATED)
ReportInvalidFree(old_ptr, chunk_state, stack);
- CHECK_NE(REAL(memcpy), (void*)0);
+ CHECK_NE(REAL(memcpy), nullptr);
uptr memcpy_size = Min(new_size, m->UsedSize());
// If realloc() races with free(), we may start copying freed memory.
// However, we will report racy double-free later anyway.
@@ -579,7 +579,7 @@ struct Allocator {
// Assumes alloc_beg == allocator.GetBlockBegin(alloc_beg).
AsanChunk *GetAsanChunk(void *alloc_beg) {
- if (!alloc_beg) return 0;
+ if (!alloc_beg) return nullptr;
if (!allocator.FromPrimary(alloc_beg)) {
uptr *meta = reinterpret_cast<uptr *>(allocator.GetMetaData(alloc_beg));
AsanChunk *m = reinterpret_cast<AsanChunk *>(meta[1]);
@@ -619,7 +619,7 @@ struct Allocator {
// The address is in the chunk's left redzone, so maybe it is actually
// a right buffer overflow from the other chunk to the left.
// Search a bit to the left to see if there is another chunk.
- AsanChunk *m2 = 0;
+ AsanChunk *m2 = nullptr;
for (uptr l = 1; l < GetPageSizeCached(); l++) {
m2 = GetAsanChunkByAddr(addr - l);
if (m2 == m1) continue; // Still the same chunk.
@@ -653,7 +653,7 @@ static AsanAllocator &get_allocator() {
}
bool AsanChunkView::IsValid() {
- return chunk_ != 0 && chunk_->chunk_state != CHUNK_AVAILABLE;
+ return chunk_ && chunk_->chunk_state != CHUNK_AVAILABLE;
}
uptr AsanChunkView::Beg() { return chunk_->Beg(); }
uptr AsanChunkView::End() { return Beg() + UsedSize(); }
@@ -723,11 +723,11 @@ void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {
}
void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) {
- if (p == 0)
+ if (!p)
return instance.Allocate(size, 8, stack, FROM_MALLOC, true);
if (size == 0) {
instance.Deallocate(p, 0, stack, FROM_MALLOC);
- return 0;
+ return nullptr;
}
return instance.Reallocate(p, size, stack);
}
@@ -755,7 +755,7 @@ int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
}
uptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp) {
- if (ptr == 0) return 0;
+ if (!ptr) return 0;
uptr usable_size = instance.AllocationSize(reinterpret_cast<uptr>(ptr));
if (flags()->check_malloc_usable_size && (usable_size == 0)) {
GET_STACK_TRACE_FATAL(pc, bp);
@@ -780,7 +780,7 @@ void AsanSoftRssLimitExceededCallback(bool exceeded) {
instance.allocator.SetRssLimitIsExceeded(exceeded);
}
-} // namespace __asan
+} // namespace __asan
// --- Implementation of LSan-specific functions --- {{{1
namespace __lsan {
@@ -881,7 +881,7 @@ int __sanitizer_get_ownership(const void *p) {
}
uptr __sanitizer_get_allocated_size(const void *p) {
- if (p == 0) return 0;
+ if (!p) return 0;
uptr ptr = reinterpret_cast<uptr>(p);
uptr allocated_size = instance.AllocationSize(ptr);
// Die if p is not malloced or if it is already freed.
@@ -904,5 +904,5 @@ SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
void __sanitizer_free_hook(void *ptr) {
(void)ptr;
}
-} // extern "C"
+} // extern "C"
#endif
diff --git a/contrib/compiler-rt/lib/asan/asan_allocator.h b/contrib/compiler-rt/lib/asan/asan_allocator.h
index 5ccd00c97bab..e3d53330cd2f 100644
--- a/contrib/compiler-rt/lib/asan/asan_allocator.h
+++ b/contrib/compiler-rt/lib/asan/asan_allocator.h
@@ -114,6 +114,11 @@ struct AsanMapUnmapCallback {
# if defined(__powerpc64__)
const uptr kAllocatorSpace = 0xa0000000000ULL;
const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
+# elif defined(__aarch64__)
+// AArch64/SANITIZIER_CAN_USER_ALLOCATOR64 is only for 42-bit VMA
+// so no need to different values for different VMA.
+const uptr kAllocatorSpace = 0x10000000000ULL;
+const uptr kAllocatorSize = 0x10000000000ULL; // 3T.
# else
const uptr kAllocatorSpace = 0x600000000000ULL;
const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
diff --git a/contrib/compiler-rt/lib/asan/asan_debugging.cc b/contrib/compiler-rt/lib/asan/asan_debugging.cc
index 6fc5b690de99..7c3a8a73bd4e 100644
--- a/contrib/compiler-rt/lib/asan/asan_debugging.cc
+++ b/contrib/compiler-rt/lib/asan/asan_debugging.cc
@@ -108,14 +108,14 @@ static uptr AsanGetStack(uptr addr, uptr *trace, u32 size, u32 *thread_id,
return 0;
}
-} // namespace __asan
+} // namespace __asan
using namespace __asan;
SANITIZER_INTERFACE_ATTRIBUTE
const char *__asan_locate_address(uptr addr, char *name, uptr name_size,
uptr *region_address, uptr *region_size) {
- AddressDescription descr = { name, name_size, 0, 0, 0 };
+ AddressDescription descr = { name, name_size, 0, 0, nullptr };
AsanLocateAddress(addr, &descr);
if (region_address) *region_address = descr.region_address;
if (region_size) *region_size = descr.region_size;
diff --git a/contrib/compiler-rt/lib/asan/asan_fake_stack.cc b/contrib/compiler-rt/lib/asan/asan_fake_stack.cc
index d20641155b88..91fdf0aa1dca 100644
--- a/contrib/compiler-rt/lib/asan/asan_fake_stack.cc
+++ b/contrib/compiler-rt/lib/asan/asan_fake_stack.cc
@@ -11,6 +11,7 @@
//
// FakeStack is used to detect use-after-return bugs.
//===----------------------------------------------------------------------===//
+
#include "asan_allocator.h"
#include "asan_poisoning.h"
#include "asan_thread.h"
@@ -32,7 +33,8 @@ ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
if (class_id <= 6) {
for (uptr i = 0; i < (1U << class_id); i++) {
shadow[i] = magic;
- SanitizerBreakOptimization(0); // Make sure this does not become memset.
+ // Make sure this does not become memset.
+ SanitizerBreakOptimization(nullptr);
}
} else {
// The size class is too big, it's cheaper to poison only size bytes.
@@ -80,7 +82,9 @@ void FakeStack::PoisonAll(u8 magic) {
magic);
}
+#if !defined(_MSC_VER) || defined(__clang__)
ALWAYS_INLINE USED
+#endif
FakeFrame *FakeStack::Allocate(uptr stack_size_log, uptr class_id,
uptr real_stack) {
CHECK_LT(class_id, kNumberOfSizeClasses);
@@ -106,7 +110,7 @@ FakeFrame *FakeStack::Allocate(uptr stack_size_log, uptr class_id,
*SavedFlagPtr(reinterpret_cast<uptr>(res), class_id) = &flags[pos];
return res;
}
- return 0; // We are out of fake stack.
+ return nullptr; // We are out of fake stack.
}
uptr FakeStack::AddrIsInFakeStack(uptr ptr, uptr *frame_beg, uptr *frame_end) {
@@ -183,7 +187,7 @@ void SetTLSFakeStack(FakeStack *fs) { }
static FakeStack *GetFakeStack() {
AsanThread *t = GetCurrentThread();
- if (!t) return 0;
+ if (!t) return nullptr;
return t->fake_stack();
}
@@ -191,7 +195,7 @@ static FakeStack *GetFakeStackFast() {
if (FakeStack *fs = GetTLSFakeStack())
return fs;
if (!__asan_option_detect_stack_use_after_return)
- return 0;
+ return nullptr;
return GetFakeStack();
}
@@ -212,7 +216,7 @@ ALWAYS_INLINE void OnFree(uptr ptr, uptr class_id, uptr size) {
SetShadow(ptr, size, class_id, kMagic8);
}
-} // namespace __asan
+} // namespace __asan
// ---------------------- Interface ---------------- {{{1
using namespace __asan;
@@ -245,13 +249,13 @@ SANITIZER_INTERFACE_ATTRIBUTE
void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
void **end) {
FakeStack *fs = reinterpret_cast<FakeStack*>(fake_stack);
- if (!fs) return 0;
+ if (!fs) return nullptr;
uptr frame_beg, frame_end;
FakeFrame *frame = reinterpret_cast<FakeFrame *>(fs->AddrIsInFakeStack(
reinterpret_cast<uptr>(addr), &frame_beg, &frame_end));
- if (!frame) return 0;
+ if (!frame) return nullptr;
if (frame->magic != kCurrentStackFrameMagic)
- return 0;
+ return nullptr;
if (beg) *beg = reinterpret_cast<void*>(frame_beg);
if (end) *end = reinterpret_cast<void*>(frame_end);
return reinterpret_cast<void*>(frame->real_stack);
@@ -276,4 +280,4 @@ void __asan_allocas_unpoison(uptr top, uptr bottom) {
REAL(memset)(reinterpret_cast<void*>(MemToShadow(top)), 0,
(bottom - top) / SHADOW_GRANULARITY);
}
-} // extern "C"
+} // extern "C"
diff --git a/contrib/compiler-rt/lib/asan/asan_flags.cc b/contrib/compiler-rt/lib/asan/asan_flags.cc
index e8ea549b62e3..363ee67e77c6 100644
--- a/contrib/compiler-rt/lib/asan/asan_flags.cc
+++ b/contrib/compiler-rt/lib/asan/asan_flags.cc
@@ -65,6 +65,7 @@ void InitializeFlags() {
cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
cf.malloc_context_size = kDefaultMallocContextSize;
cf.intercept_tls_get_addr = true;
+ cf.exitcode = 1;
OverrideCommonFlags(cf);
}
Flags *f = flags();
@@ -115,14 +116,6 @@ void InitializeFlags() {
ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
#endif
- // Let activation flags override current settings. On Android they come
- // from a system property. On other platforms this is no-op.
- if (!flags()->start_deactivated) {
- char buf[100];
- GetExtraActivationFlags(buf, sizeof(buf));
- asan_parser.ParseString(buf);
- }
-
SetVerbosity(common_flags()->verbosity);
// TODO(eugenis): dump all flags at verbosity>=2?
diff --git a/contrib/compiler-rt/lib/asan/asan_flags.inc b/contrib/compiler-rt/lib/asan/asan_flags.inc
index 53a8a4039e7e..5e69242fb8e9 100644
--- a/contrib/compiler-rt/lib/asan/asan_flags.inc
+++ b/contrib/compiler-rt/lib/asan/asan_flags.inc
@@ -44,9 +44,6 @@ ASAN_FLAG(
"to find more errors.")
ASAN_FLAG(bool, replace_intrin, true,
"If set, uses custom wrappers for memset/memcpy/memmove intinsics.")
-ASAN_FLAG(bool, mac_ignore_invalid_free, false,
- "Ignore invalid free() calls to work around some bugs. Used on OS X "
- "only.")
ASAN_FLAG(bool, detect_stack_use_after_return, false,
"Enables stack-use-after-return checking at run-time.")
ASAN_FLAG(int, min_uar_stack_size_log, 16, // We can't do smaller anyway.
@@ -62,8 +59,6 @@ ASAN_FLAG(
"bytes that will be filled with malloc_fill_byte on malloc.")
ASAN_FLAG(int, malloc_fill_byte, 0xbe,
"Value used to fill the newly allocated memory.")
-ASAN_FLAG(int, exitcode, ASAN_DEFAULT_FAILURE_EXITCODE,
- "Override the program exit status if the tool found an error.")
ASAN_FLAG(bool, allow_user_poisoning, true,
"If set, user may manually mark memory regions as poisoned or "
"unpoisoned.")
@@ -77,10 +72,7 @@ ASAN_FLAG(bool, check_malloc_usable_size, true,
"295.*.")
ASAN_FLAG(bool, unmap_shadow_on_exit, false,
"If set, explicitly unmaps the (huge) shadow at exit.")
-ASAN_FLAG(
- bool, abort_on_error, false,
- "If set, the tool calls abort() instead of _exit() after printing the "
- "error report.")
+ASAN_FLAG(bool, protect_shadow_gap, true, "If set, mprotect the shadow gap")
ASAN_FLAG(bool, print_stats, false,
"Print various statistics after printing an error message or if "
"atexit=1.")
@@ -104,8 +96,8 @@ ASAN_FLAG(bool, poison_array_cookie, true,
"Poison (or not) the array cookie after operator new[].")
// Turn off alloc/dealloc mismatch checker on Mac and Windows for now.
-// https://code.google.com/p/address-sanitizer/issues/detail?id=131
-// https://code.google.com/p/address-sanitizer/issues/detail?id=309
+// https://github.com/google/sanitizers/issues/131
+// https://github.com/google/sanitizers/issues/309
// TODO(glider,timurrrr): Fix known issues and enable this back.
ASAN_FLAG(bool, alloc_dealloc_mismatch,
(SANITIZER_MAC == 0) && (SANITIZER_WINDOWS == 0),
@@ -113,9 +105,6 @@ ASAN_FLAG(bool, alloc_dealloc_mismatch,
ASAN_FLAG(bool, new_delete_type_mismatch, true,
"Report errors on mismatch betwen size of new and delete.")
-ASAN_FLAG(bool, strict_memcmp, true,
- "If true, assume that memcmp(p1, p2, n) always reads n bytes before "
- "comparing p1 and p2.")
ASAN_FLAG(
bool, strict_init_order, false,
"If true, assume that dynamic initializers can never access globals from "
@@ -134,8 +123,8 @@ ASAN_FLAG(
"The bigger the value the harder we try.")
ASAN_FLAG(
bool, detect_container_overflow, true,
- "If true, honor the container overflow annotations. "
- "See https://code.google.com/p/address-sanitizer/wiki/ContainerOverflow")
+ "If true, honor the container overflow annotations. See "
+ "https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow")
ASAN_FLAG(int, detect_odr_violation, 2,
"If >=2, detect violation of One-Definition-Rule (ODR); "
"If ==1, detect ODR-violation only if the two variables "
@@ -143,3 +132,6 @@ ASAN_FLAG(int, detect_odr_violation, 2,
ASAN_FLAG(bool, dump_instruction_bytes, false,
"If true, dump 16 bytes starting at the instruction that caused SEGV")
ASAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
+ASAN_FLAG(bool, halt_on_error, true,
+ "Crash the program after printing the first error report "
+ "(WARNING: USE AT YOUR OWN RISK!)")
diff --git a/contrib/compiler-rt/lib/asan/asan_globals.cc b/contrib/compiler-rt/lib/asan/asan_globals.cc
index c34b1d3cedf2..eb9f1bfefec2 100644
--- a/contrib/compiler-rt/lib/asan/asan_globals.cc
+++ b/contrib/compiler-rt/lib/asan/asan_globals.cc
@@ -11,6 +11,7 @@
//
// Handle globals.
//===----------------------------------------------------------------------===//
+
#include "asan_interceptors.h"
#include "asan_internal.h"
#include "asan_mapping.h"
@@ -167,7 +168,7 @@ static void RegisterGlobal(const Global *g) {
l->next = list_of_all_globals;
list_of_all_globals = l;
if (g->has_dynamic_init) {
- if (dynamic_init_globals == 0) {
+ if (!dynamic_init_globals) {
dynamic_init_globals = new(allocator_for_globals)
VectorOfGlobals(kDynamicInitGlobalsInitialCapacity);
}
@@ -206,7 +207,7 @@ void StopInitOrderChecking() {
}
}
-} // namespace __asan
+} // namespace __asan
// ---------------------- Interface ---------------- {{{1
using namespace __asan; // NOLINT
diff --git a/contrib/compiler-rt/lib/asan/asan_init_version.h b/contrib/compiler-rt/lib/asan/asan_init_version.h
index 6cf57c4aa2a8..bc8a622f5bb1 100644
--- a/contrib/compiler-rt/lib/asan/asan_init_version.h
+++ b/contrib/compiler-rt/lib/asan/asan_init_version.h
@@ -27,8 +27,8 @@ extern "C" {
// v3=>v4: added '__asan_global_source_location' to __asan_global.
// v4=>v5: changed the semantics and format of __asan_stack_malloc_ and
// __asan_stack_free_ functions.
- #define __asan_init __asan_init_v5
- #define __asan_init_name "__asan_init_v5"
+ // v5=>v6: changed the name of the version check symbol
+ #define __asan_version_mismatch_check __asan_version_mismatch_check_v6
}
#endif // ASAN_INIT_VERSION_H
diff --git a/contrib/compiler-rt/lib/asan/asan_interceptors.cc b/contrib/compiler-rt/lib/asan/asan_interceptors.cc
index d8b48d391ab8..d9a0c71a002d 100644
--- a/contrib/compiler-rt/lib/asan/asan_interceptors.cc
+++ b/contrib/compiler-rt/lib/asan/asan_interceptors.cc
@@ -11,8 +11,8 @@
//
// Intercept various libc functions.
//===----------------------------------------------------------------------===//
-#include "asan_interceptors.h"
+#include "asan_interceptors.h"
#include "asan_allocator.h"
#include "asan_internal.h"
#include "asan_mapping.h"
@@ -27,6 +27,12 @@
#include "sanitizer_common/sanitizer_posix.h"
#endif
+#if defined(__i386) && SANITIZER_LINUX
+#define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1"
+#elif defined(__mips__) && SANITIZER_LINUX
+#define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2"
+#endif
+
namespace __asan {
// Return true if we can quickly decide that the region is unpoisoned.
@@ -69,7 +75,7 @@ struct AsanInterceptorContext {
} \
if (!suppressed) { \
GET_CURRENT_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, __bad, isWrite, __size, 0); \
+ ReportGenericError(pc, bp, sp, __bad, isWrite, __size, 0, false);\
} \
} \
} while (0)
@@ -105,7 +111,7 @@ static inline bool RangesOverlap(const char *offset1, uptr length1,
static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
#if ASAN_INTERCEPT_STRNLEN
- if (REAL(strnlen) != 0) {
+ if (REAL(strnlen)) {
return REAL(strnlen)(s, maxlen);
}
#endif
@@ -123,7 +129,7 @@ int OnExit() {
return 0;
}
-} // namespace __asan
+} // namespace __asan
// ---------------------- Wrappers ---------------- {{{1
using namespace __asan; // NOLINT
@@ -172,7 +178,7 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
} while (false)
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
// Strict init-order checking is dlopen-hostile:
-// https://code.google.com/p/address-sanitizer/issues/detail?id=178
+// https://github.com/google/sanitizers/issues/178
#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
if (flags()->strict_init_order) { \
StopInitOrderChecking(); \
@@ -216,7 +222,7 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
AsanThread *t = nullptr;
while ((t = reinterpret_cast<AsanThread *>(
- atomic_load(&param->t, memory_order_acquire))) == 0)
+ atomic_load(&param->t, memory_order_acquire))) == nullptr)
internal_sched_yield();
SetCurrentThread(t);
return t->ThreadStart(GetTid(), &param->is_registered);
@@ -231,7 +237,7 @@ INTERCEPTOR(int, pthread_create, void *thread,
StopInitOrderChecking();
GET_STACK_TRACE_THREAD;
int detached = 0;
- if (attr != 0)
+ if (attr)
REAL(pthread_attr_getdetachstate)(attr, &detached);
ThreadStartParam param;
atomic_store(&param.t, 0, memory_order_relaxed);
@@ -270,14 +276,14 @@ INTERCEPTOR(void*, bsd_signal, int signum, void *handler) {
}
return 0;
}
-#else
+#endif
+
INTERCEPTOR(void*, signal, int signum, void *handler) {
if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {
return REAL(signal)(signum, handler);
}
- return 0;
+ return nullptr;
}
-#endif
INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
struct sigaction *oldact) {
@@ -292,7 +298,7 @@ int real_sigaction(int signum, const void *act, void *oldact) {
return REAL(sigaction)(signum, (const struct sigaction *)act,
(struct sigaction *)oldact);
}
-} // namespace __sanitizer
+} // namespace __sanitizer
#elif SANITIZER_POSIX
// We need to have defined REAL(sigaction) on posix systems.
@@ -363,40 +369,6 @@ INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
}
#endif
-static inline int CharCmp(unsigned char c1, unsigned char c2) {
- return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
-}
-
-INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, memcmp);
- if (UNLIKELY(!asan_inited)) return internal_memcmp(a1, a2, size);
- ENSURE_ASAN_INITED();
- if (flags()->replace_intrin) {
- if (flags()->strict_memcmp) {
- // Check the entire regions even if the first bytes of the buffers are
- // different.
- ASAN_READ_RANGE(ctx, a1, size);
- ASAN_READ_RANGE(ctx, a2, size);
- // Fallthrough to REAL(memcmp) below.
- } else {
- unsigned char c1 = 0, c2 = 0;
- const unsigned char *s1 = (const unsigned char*)a1;
- const unsigned char *s2 = (const unsigned char*)a2;
- uptr i;
- for (i = 0; i < size; i++) {
- c1 = s1[i];
- c2 = s2[i];
- if (c1 != c2) break;
- }
- ASAN_READ_RANGE(ctx, s1, Min(i + 1, size));
- ASAN_READ_RANGE(ctx, s2, Min(i + 1, size));
- return CharCmp(c1, c2);
- }
- }
- return REAL(memcmp(a1, a2, size));
-}
-
// memcpy is called during __asan_init() from the internals of printf(...).
// We do not treat memcpy with to==from as a bug.
// See http://llvm.org/bugs/show_bug.cgi?id=11763.
@@ -743,7 +715,7 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
#endif
ENSURE_ASAN_INITED();
int res = REAL(__cxa_atexit)(func, arg, dso_handle);
- REAL(__cxa_atexit)(AtCxaAtexit, 0, 0);
+ REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
return res;
}
#endif // ASAN_INTERCEPT___CXA_ATEXIT
@@ -767,7 +739,6 @@ void InitializeAsanInterceptors() {
InitializeCommonInterceptors();
// Intercept mem* functions.
- ASAN_INTERCEPT_FUNC(memcmp);
ASAN_INTERCEPT_FUNC(memmove);
ASAN_INTERCEPT_FUNC(memset);
if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
@@ -806,9 +777,8 @@ void InitializeAsanInterceptors() {
ASAN_INTERCEPT_FUNC(sigaction);
#if SANITIZER_ANDROID
ASAN_INTERCEPT_FUNC(bsd_signal);
-#else
- ASAN_INTERCEPT_FUNC(signal);
#endif
+ ASAN_INTERCEPT_FUNC(signal);
#endif
#if ASAN_INTERCEPT_SWAPCONTEXT
ASAN_INTERCEPT_FUNC(swapcontext);
@@ -827,7 +797,11 @@ void InitializeAsanInterceptors() {
// Intercept threading-related functions
#if ASAN_INTERCEPT_PTHREAD_CREATE
+#if defined(ASAN_PTHREAD_CREATE_VERSION)
+ ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION);
+#else
ASAN_INTERCEPT_FUNC(pthread_create);
+#endif
ASAN_INTERCEPT_FUNC(pthread_join);
#endif
@@ -845,4 +819,4 @@ void InitializeAsanInterceptors() {
VReport(1, "AddressSanitizer: libc interceptors initialized\n");
}
-} // namespace __asan
+} // namespace __asan
diff --git a/contrib/compiler-rt/lib/asan/asan_interceptors.h b/contrib/compiler-rt/lib/asan/asan_interceptors.h
index 488ada78ab8b..279c5f38451f 100644
--- a/contrib/compiler-rt/lib/asan/asan_interceptors.h
+++ b/contrib/compiler-rt/lib/asan/asan_interceptors.h
@@ -98,6 +98,12 @@ DECLARE_REAL(int, sigaction, int signum, const struct sigaction *act,
if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \
VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \
} while (0)
+#define ASAN_INTERCEPT_FUNC_VER(name, ver) \
+ do { \
+ if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \
+ VReport( \
+ 1, "AddressSanitizer: failed to intercept '" #name "@@" #ver "'\n"); \
+ } while (0)
#else
// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.
#define ASAN_INTERCEPT_FUNC(name)
diff --git a/contrib/compiler-rt/lib/asan/asan_interface_internal.h b/contrib/compiler-rt/lib/asan/asan_interface_internal.h
index ad8ebcd91ad9..9efddcbd42b2 100644
--- a/contrib/compiler-rt/lib/asan/asan_interface_internal.h
+++ b/contrib/compiler-rt/lib/asan/asan_interface_internal.h
@@ -27,10 +27,14 @@ using __sanitizer::uptr;
extern "C" {
// This function should be called at the very beginning of the process,
// before any instrumented code is executed and before any call to malloc.
- // Please note that __asan_init is a macro that is replaced with
- // __asan_init_vXXX at compile-time.
SANITIZER_INTERFACE_ATTRIBUTE void __asan_init();
+ // This function exists purely to get a linker/loader error when using
+ // incompatible versions of instrumentation and runtime library. Please note
+ // that __asan_version_mismatch_check is a macro that is replaced with
+ // __asan_version_mismatch_check_vXXX at compile-time.
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_version_mismatch_check();
+
// This structure is used to describe the source location of a place where
// global was defined.
struct __asan_global_source_location {
@@ -131,8 +135,6 @@ extern "C" {
uptr addr, int is_write, uptr access_size, u32 exp);
SANITIZER_INTERFACE_ATTRIBUTE
- int __asan_set_error_exit_code(int exit_code);
- SANITIZER_INTERFACE_ATTRIBUTE
void __asan_set_death_callback(void (*callback)(void));
SANITIZER_INTERFACE_ATTRIBUTE
void __asan_set_error_report_callback(void (*callback)(const char*));
@@ -165,6 +167,19 @@ extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN(uptr p, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN(uptr p, uptr size);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16_noabort(uptr p);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN_noabort(uptr p, uptr size);
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN_noabort(uptr p, uptr size);
+
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load1(uptr p, u32 exp);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load2(uptr p, u32 exp);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load4(uptr p, u32 exp);
diff --git a/contrib/compiler-rt/lib/asan/asan_internal.h b/contrib/compiler-rt/lib/asan/asan_internal.h
index 107e16ee31b9..0ef0d0eb5263 100644
--- a/contrib/compiler-rt/lib/asan/asan_internal.h
+++ b/contrib/compiler-rt/lib/asan/asan_internal.h
@@ -21,8 +21,6 @@
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "sanitizer_common/sanitizer_libc.h"
-#define ASAN_DEFAULT_FAILURE_EXITCODE 1
-
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# error "The AddressSanitizer run-time should not be"
" instrumented by AddressSanitizer"
@@ -75,12 +73,9 @@ void *AsanDoesNotSupportStaticLinkage();
void AsanCheckDynamicRTPrereqs();
void AsanCheckIncompatibleRT();
-void AsanOnSIGSEGV(int, void *siginfo, void *context);
+void AsanOnDeadlySignal(int, void *siginfo, void *context);
-void DisableReexec();
-void MaybeReexec();
void ReadContextStack(void *context, uptr *stack, uptr *ssize);
-void AsanPlatformThreadInit();
void StopInitOrderChecking();
// Wrapper for TLS/TSD.
diff --git a/contrib/compiler-rt/lib/asan/asan_linux.cc b/contrib/compiler-rt/lib/asan/asan_linux.cc
index 9580fc7c06d4..e26b400562df 100644
--- a/contrib/compiler-rt/lib/asan/asan_linux.cc
+++ b/contrib/compiler-rt/lib/asan/asan_linux.cc
@@ -70,14 +70,6 @@ namespace __asan {
void InitializePlatformInterceptors() {}
-void DisableReexec() {
- // No need to re-exec on Linux.
-}
-
-void MaybeReexec() {
- // No need to re-exec on Linux.
-}
-
void *AsanDoesNotSupportStaticLinkage() {
// This will fail to link with -static.
return &_DYNAMIC; // defined in link.h
@@ -117,7 +109,7 @@ void AsanCheckDynamicRTPrereqs() {
return;
// Ensure that dynamic RT is the first DSO in the list
- const char *first_dso_name = 0;
+ const char *first_dso_name = nullptr;
dl_iterate_phdr(FindFirstDSOCallback, &first_dso_name);
if (first_dso_name && !IsDynamicRTName(first_dso_name)) {
Report("ASan runtime does not come first in initial library list; "
@@ -142,7 +134,8 @@ void AsanCheckIncompatibleRT() {
// system libraries, causing crashes later in ASan initialization.
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
char filename[128];
- while (proc_maps.Next(0, 0, 0, filename, sizeof(filename), 0)) {
+ while (proc_maps.Next(nullptr, nullptr, nullptr, filename,
+ sizeof(filename), nullptr)) {
if (IsDynamicRTName(filename)) {
Report("Your application is linked against "
"incompatible ASan runtimes.\n");
@@ -155,11 +148,7 @@ void AsanCheckIncompatibleRT() {
}
}
}
-#endif // SANITIZER_ANDROID
-
-void AsanPlatformThreadInit() {
- // Nothing here for now.
-}
+#endif // SANITIZER_ANDROID
#if !SANITIZER_ANDROID
void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
@@ -177,6 +166,6 @@ void *AsanDlSymNext(const char *sym) {
return dlsym(RTLD_NEXT, sym);
}
-} // namespace __asan
+} // namespace __asan
-#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
+#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
diff --git a/contrib/compiler-rt/lib/asan/asan_mac.cc b/contrib/compiler-rt/lib/asan/asan_mac.cc
index 3e028378df28..f00d98f8e5e6 100644
--- a/contrib/compiler-rt/lib/asan/asan_mac.cc
+++ b/contrib/compiler-rt/lib/asan/asan_mac.cc
@@ -24,26 +24,17 @@
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_mac.h"
-#if !SANITIZER_IOS
-#include <crt_externs.h> // for _NSGetArgv and _NSGetEnviron
-#else
-extern "C" {
- extern char ***_NSGetArgv(void);
-}
-#endif
-
-#include <dlfcn.h> // for dladdr()
+#include <fcntl.h>
+#include <libkern/OSAtomic.h>
#include <mach-o/dyld.h>
#include <mach-o/loader.h>
+#include <pthread.h>
+#include <stdlib.h> // for free()
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <sys/ucontext.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdlib.h> // for free()
#include <unistd.h>
-#include <libkern/OSAtomic.h>
namespace __asan {
@@ -52,187 +43,12 @@ void InitializePlatformInterceptors() {}
bool PlatformHasDifferentMemcpyAndMemmove() {
// On OS X 10.7 memcpy() and memmove() are both resolved
// into memmove$VARIANT$sse42.
- // See also http://code.google.com/p/address-sanitizer/issues/detail?id=34.
+ // See also https://github.com/google/sanitizers/issues/34.
// TODO(glider): need to check dynamically that memcpy() and memmove() are
// actually the same function.
return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD;
}
-extern "C"
-void __asan_init();
-
-static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES";
-LowLevelAllocator allocator_for_env;
-
-// Change the value of the env var |name|, leaking the original value.
-// If |name_value| is NULL, the variable is deleted from the environment,
-// otherwise the corresponding "NAME=value" string is replaced with
-// |name_value|.
-void LeakyResetEnv(const char *name, const char *name_value) {
- char **env = GetEnviron();
- uptr name_len = internal_strlen(name);
- while (*env != 0) {
- uptr len = internal_strlen(*env);
- if (len > name_len) {
- const char *p = *env;
- if (!internal_memcmp(p, name, name_len) && p[name_len] == '=') {
- // Match.
- if (name_value) {
- // Replace the old value with the new one.
- *env = const_cast<char*>(name_value);
- } else {
- // Shift the subsequent pointers back.
- char **del = env;
- do {
- del[0] = del[1];
- } while (*del++);
- }
- }
- }
- env++;
- }
-}
-
-static bool reexec_disabled = false;
-
-void DisableReexec() {
- reexec_disabled = true;
-}
-
-bool DyldNeedsEnvVariable() {
-// If running on OS X 10.11+ or iOS 9.0+, dyld will interpose even if
-// DYLD_INSERT_LIBRARIES is not set.
-
-#if SANITIZER_IOSSIM
- // GetMacosVersion will not work for the simulator, whose kernel version
- // is tied to the host. Use a weak linking hack for the simulator.
- // This API was introduced in the same version of the OS as the dyld
- // optimization.
-
- // Check for presence of a symbol that is available on OS X 10.11+, iOS 9.0+.
- return (dlsym(RTLD_NEXT, "mach_memory_info") == nullptr);
-#else
- return (GetMacosVersion() <= MACOS_VERSION_YOSEMITE);
-#endif
-}
-
-void MaybeReexec() {
- if (reexec_disabled) return;
-
- // Make sure the dynamic ASan runtime library is preloaded so that the
- // wrappers work. If it is not, set DYLD_INSERT_LIBRARIES and re-exec
- // ourselves.
- Dl_info info;
- CHECK(dladdr((void*)((uptr)__asan_init), &info));
- char *dyld_insert_libraries =
- const_cast<char*>(GetEnv(kDyldInsertLibraries));
- uptr old_env_len = dyld_insert_libraries ?
- internal_strlen(dyld_insert_libraries) : 0;
- uptr fname_len = internal_strlen(info.dli_fname);
- const char *dylib_name = StripModuleName(info.dli_fname);
- uptr dylib_name_len = internal_strlen(dylib_name);
-
- bool lib_is_in_env =
- dyld_insert_libraries && REAL(strstr)(dyld_insert_libraries, dylib_name);
- if (DyldNeedsEnvVariable() && !lib_is_in_env) {
- // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime
- // library.
- char program_name[1024];
- uint32_t buf_size = sizeof(program_name);
- _NSGetExecutablePath(program_name, &buf_size);
- char *new_env = const_cast<char*>(info.dli_fname);
- if (dyld_insert_libraries) {
- // Append the runtime dylib name to the existing value of
- // DYLD_INSERT_LIBRARIES.
- new_env = (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2);
- internal_strncpy(new_env, dyld_insert_libraries, old_env_len);
- new_env[old_env_len] = ':';
- // Copy fname_len and add a trailing zero.
- internal_strncpy(new_env + old_env_len + 1, info.dli_fname,
- fname_len + 1);
- // Ok to use setenv() since the wrappers don't depend on the value of
- // asan_inited.
- setenv(kDyldInsertLibraries, new_env, /*overwrite*/1);
- } else {
- // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name.
- setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
- }
- VReport(1, "exec()-ing the program with\n");
- VReport(1, "%s=%s\n", kDyldInsertLibraries, new_env);
- VReport(1, "to enable ASan wrappers.\n");
- execv(program_name, *_NSGetArgv());
-
- // We get here only if execv() failed.
- Report("ERROR: The process is launched without DYLD_INSERT_LIBRARIES, "
- "which is required for ASan to work. ASan tried to set the "
- "environment variable and re-execute itself, but execv() failed, "
- "possibly because of sandbox restrictions. Make sure to launch the "
- "executable with:\n%s=%s\n", kDyldInsertLibraries, new_env);
- CHECK("execv failed" && 0);
- }
-
- if (!lib_is_in_env)
- return;
-
- // DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove
- // the dylib from the environment variable, because interceptors are installed
- // and we don't want our children to inherit the variable.
-
- uptr env_name_len = internal_strlen(kDyldInsertLibraries);
- // Allocate memory to hold the previous env var name, its value, the '='
- // sign and the '\0' char.
- char *new_env = (char*)allocator_for_env.Allocate(
- old_env_len + 2 + env_name_len);
- CHECK(new_env);
- internal_memset(new_env, '\0', old_env_len + 2 + env_name_len);
- internal_strncpy(new_env, kDyldInsertLibraries, env_name_len);
- new_env[env_name_len] = '=';
- char *new_env_pos = new_env + env_name_len + 1;
-
- // Iterate over colon-separated pieces of |dyld_insert_libraries|.
- char *piece_start = dyld_insert_libraries;
- char *piece_end = NULL;
- char *old_env_end = dyld_insert_libraries + old_env_len;
- do {
- if (piece_start[0] == ':') piece_start++;
- piece_end = REAL(strchr)(piece_start, ':');
- if (!piece_end) piece_end = dyld_insert_libraries + old_env_len;
- if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break;
- uptr piece_len = piece_end - piece_start;
-
- char *filename_start =
- (char *)internal_memrchr(piece_start, '/', piece_len);
- uptr filename_len = piece_len;
- if (filename_start) {
- filename_start += 1;
- filename_len = piece_len - (filename_start - piece_start);
- } else {
- filename_start = piece_start;
- }
-
- // If the current piece isn't the runtime library name,
- // append it to new_env.
- if ((dylib_name_len != filename_len) ||
- (internal_memcmp(filename_start, dylib_name, dylib_name_len) != 0)) {
- if (new_env_pos != new_env + env_name_len + 1) {
- new_env_pos[0] = ':';
- new_env_pos++;
- }
- internal_strncpy(new_env_pos, piece_start, piece_len);
- new_env_pos += piece_len;
- }
- // Move on to the next piece.
- piece_start = piece_end;
- } while (piece_start < old_env_end);
-
- // Can't use setenv() here, because it requires the allocator to be
- // initialized.
- // FIXME: instead of filtering DYLD_INSERT_LIBRARIES here, do it in
- // a separate function called after InitializeAllocator().
- if (new_env_pos == new_env + env_name_len + 1) new_env = NULL;
- LeakyResetEnv(kDyldInsertLibraries, new_env);
-}
-
// No-op. Mac does not support static linkage anyway.
void *AsanDoesNotSupportStaticLinkage() {
return 0;
@@ -244,9 +60,6 @@ void AsanCheckDynamicRTPrereqs() {}
// No-op. Mac does not support static linkage anyway.
void AsanCheckIncompatibleRT() {}
-void AsanPlatformThreadInit() {
-}
-
void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
UNIMPLEMENTED();
}
diff --git a/contrib/compiler-rt/lib/asan/asan_malloc_linux.cc b/contrib/compiler-rt/lib/asan/asan_malloc_linux.cc
index 46a6a9db4a81..d5089f9f7b36 100644
--- a/contrib/compiler-rt/lib/asan/asan_malloc_linux.cc
+++ b/contrib/compiler-rt/lib/asan/asan_malloc_linux.cc
@@ -26,13 +26,25 @@
// ---------------------- Replacement functions ---------------- {{{1
using namespace __asan; // NOLINT
+static const uptr kCallocPoolSize = 1024;
+static uptr calloc_memory_for_dlsym[kCallocPoolSize];
+
+static bool IsInCallocPool(const void *ptr) {
+ sptr off = (sptr)ptr - (sptr)calloc_memory_for_dlsym;
+ return 0 <= off && off < (sptr)kCallocPoolSize;
+}
+
INTERCEPTOR(void, free, void *ptr) {
GET_STACK_TRACE_FREE;
+ if (UNLIKELY(IsInCallocPool(ptr)))
+ return;
asan_free(ptr, &stack, FROM_MALLOC);
}
INTERCEPTOR(void, cfree, void *ptr) {
GET_STACK_TRACE_FREE;
+ if (UNLIKELY(IsInCallocPool(ptr)))
+ return;
asan_free(ptr, &stack, FROM_MALLOC);
}
@@ -44,8 +56,6 @@ INTERCEPTOR(void*, malloc, uptr size) {
INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
if (UNLIKELY(!asan_inited)) {
// Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
- const uptr kCallocPoolSize = 1024;
- static uptr calloc_memory_for_dlsym[kCallocPoolSize];
static uptr allocated;
uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
void *mem = (void*)&calloc_memory_for_dlsym[allocated];
@@ -59,6 +69,13 @@ INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
GET_STACK_TRACE_MALLOC;
+ if (UNLIKELY(IsInCallocPool(ptr))) {
+ uptr offset = (uptr)ptr - (uptr)calloc_memory_for_dlsym;
+ uptr copy_size = Min(size, kCallocPoolSize - offset);
+ void *new_ptr = asan_malloc(size, &stack);
+ internal_memcpy(new_ptr, ptr, copy_size);
+ return new_ptr;
+ }
return asan_realloc(ptr, size, &stack);
}
diff --git a/contrib/compiler-rt/lib/asan/asan_malloc_mac.cc b/contrib/compiler-rt/lib/asan/asan_malloc_mac.cc
index d7a6307c9bdc..744728d40df5 100644
--- a/contrib/compiler-rt/lib/asan/asan_malloc_mac.cc
+++ b/contrib/compiler-rt/lib/asan/asan_malloc_mac.cc
@@ -15,348 +15,47 @@
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_MAC
-#include <AvailabilityMacros.h>
-#include <CoreFoundation/CFBase.h>
-#include <dlfcn.h>
-#include <malloc/malloc.h>
-#include <sys/mman.h>
-
-#include "asan_allocator.h"
#include "asan_interceptors.h"
-#include "asan_internal.h"
#include "asan_report.h"
#include "asan_stack.h"
#include "asan_stats.h"
-#include "sanitizer_common/sanitizer_mac.h"
-
-// Similar code is used in Google Perftools,
-// http://code.google.com/p/google-perftools.
-
-// ---------------------- Replacement functions ---------------- {{{1
-using namespace __asan; // NOLINT
-
-// TODO(glider): do we need both zones?
-static malloc_zone_t *system_malloc_zone = 0;
-static malloc_zone_t asan_zone;
-
-INTERCEPTOR(malloc_zone_t *, malloc_create_zone,
- vm_size_t start_size, unsigned zone_flags) {
- ENSURE_ASAN_INITED();
- GET_STACK_TRACE_MALLOC;
- uptr page_size = GetPageSizeCached();
- uptr allocated_size = RoundUpTo(sizeof(asan_zone), page_size);
- malloc_zone_t *new_zone =
- (malloc_zone_t*)asan_memalign(page_size, allocated_size,
- &stack, FROM_MALLOC);
- internal_memcpy(new_zone, &asan_zone, sizeof(asan_zone));
- new_zone->zone_name = NULL; // The name will be changed anyway.
- if (GetMacosVersion() >= MACOS_VERSION_LION) {
- // Prevent the client app from overwriting the zone contents.
- // Library functions that need to modify the zone will set PROT_WRITE on it.
- // This matches the behavior of malloc_create_zone() on OSX 10.7 and higher.
- mprotect(new_zone, allocated_size, PROT_READ);
- }
- return new_zone;
-}
-
-INTERCEPTOR(malloc_zone_t *, malloc_default_zone, void) {
- ENSURE_ASAN_INITED();
- return &asan_zone;
-}
-
-INTERCEPTOR(malloc_zone_t *, malloc_default_purgeable_zone, void) {
- // FIXME: ASan should support purgeable allocations.
- // https://code.google.com/p/address-sanitizer/issues/detail?id=139
- ENSURE_ASAN_INITED();
- return &asan_zone;
-}
-
-INTERCEPTOR(void, malloc_make_purgeable, void *ptr) {
- // FIXME: ASan should support purgeable allocations. Ignoring them is fine
- // for now.
- ENSURE_ASAN_INITED();
-}
-
-INTERCEPTOR(int, malloc_make_nonpurgeable, void *ptr) {
- // FIXME: ASan should support purgeable allocations. Ignoring them is fine
- // for now.
- ENSURE_ASAN_INITED();
- // Must return 0 if the contents were not purged since the last call to
- // malloc_make_purgeable().
- return 0;
-}
-
-INTERCEPTOR(void, malloc_set_zone_name, malloc_zone_t *zone, const char *name) {
- ENSURE_ASAN_INITED();
- // Allocate |strlen("asan-") + 1 + internal_strlen(name)| bytes.
- size_t buflen = 6 + (name ? internal_strlen(name) : 0);
- InternalScopedString new_name(buflen);
- if (name && zone->introspect == asan_zone.introspect) {
- new_name.append("asan-%s", name);
- name = new_name.data();
- }
-
- // Call the system malloc's implementation for both external and our zones,
- // since that appropriately changes VM region protections on the zone.
- REAL(malloc_set_zone_name)(zone, name);
-}
-
-INTERCEPTOR(void *, malloc, size_t size) {
- ENSURE_ASAN_INITED();
- GET_STACK_TRACE_MALLOC;
- void *res = asan_malloc(size, &stack);
- return res;
-}
-INTERCEPTOR(void, free, void *ptr) {
- ENSURE_ASAN_INITED();
- if (!ptr) return;
- GET_STACK_TRACE_FREE;
+using namespace __asan;
+#define COMMON_MALLOC_ZONE_NAME "asan"
+#define COMMON_MALLOC_ENTER() ENSURE_ASAN_INITED()
+#define COMMON_MALLOC_SANITIZER_INITIALIZED asan_inited
+#define COMMON_MALLOC_FORCE_LOCK() asan_mz_force_lock()
+#define COMMON_MALLOC_FORCE_UNLOCK() asan_mz_force_unlock()
+#define COMMON_MALLOC_MEMALIGN(alignment, size) \
+ GET_STACK_TRACE_MALLOC; \
+ void *p = asan_memalign(alignment, size, &stack, FROM_MALLOC)
+#define COMMON_MALLOC_MALLOC(size) \
+ GET_STACK_TRACE_MALLOC; \
+ void *p = asan_malloc(size, &stack)
+#define COMMON_MALLOC_REALLOC(ptr, size) \
+ GET_STACK_TRACE_MALLOC; \
+ void *p = asan_realloc(ptr, size, &stack);
+#define COMMON_MALLOC_CALLOC(count, size) \
+ GET_STACK_TRACE_MALLOC; \
+ void *p = asan_calloc(count, size, &stack);
+#define COMMON_MALLOC_VALLOC(size) \
+ GET_STACK_TRACE_MALLOC; \
+ void *p = asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC);
+#define COMMON_MALLOC_FREE(ptr) \
+ GET_STACK_TRACE_FREE; \
asan_free(ptr, &stack, FROM_MALLOC);
-}
-
-INTERCEPTOR(void *, realloc, void *ptr, size_t size) {
- ENSURE_ASAN_INITED();
- GET_STACK_TRACE_MALLOC;
- return asan_realloc(ptr, size, &stack);
-}
-
-INTERCEPTOR(void *, calloc, size_t nmemb, size_t size) {
- ENSURE_ASAN_INITED();
- GET_STACK_TRACE_MALLOC;
- return asan_calloc(nmemb, size, &stack);
-}
-
-INTERCEPTOR(void *, valloc, size_t size) {
- ENSURE_ASAN_INITED();
- GET_STACK_TRACE_MALLOC;
- return asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC);
-}
-
-INTERCEPTOR(size_t, malloc_good_size, size_t size) {
- ENSURE_ASAN_INITED();
- return asan_zone.introspect->good_size(&asan_zone, size);
-}
-
-INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) {
- ENSURE_ASAN_INITED();
- CHECK(memptr);
- GET_STACK_TRACE_MALLOC;
- void *result = asan_memalign(alignment, size, &stack, FROM_MALLOC);
- if (result) {
- *memptr = result;
- return 0;
- }
- return -1;
-}
-
-namespace {
-
-// TODO(glider): the __asan_mz_* functions should be united with the Linux
-// wrappers, as they are basically copied from there.
-extern "C"
-SANITIZER_INTERFACE_ATTRIBUTE
-size_t __asan_mz_size(malloc_zone_t* zone, const void* ptr) {
- return asan_mz_size(ptr);
-}
-
-extern "C"
-SANITIZER_INTERFACE_ATTRIBUTE
-void *__asan_mz_malloc(malloc_zone_t *zone, uptr size) {
- if (UNLIKELY(!asan_inited)) {
- CHECK(system_malloc_zone);
- return malloc_zone_malloc(system_malloc_zone, size);
- }
- GET_STACK_TRACE_MALLOC;
- return asan_malloc(size, &stack);
-}
-
-extern "C"
-SANITIZER_INTERFACE_ATTRIBUTE
-void *__asan_mz_calloc(malloc_zone_t *zone, size_t nmemb, size_t size) {
- if (UNLIKELY(!asan_inited)) {
- // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
- const size_t kCallocPoolSize = 1024;
- static uptr calloc_memory_for_dlsym[kCallocPoolSize];
- static size_t allocated;
- size_t size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
- void *mem = (void*)&calloc_memory_for_dlsym[allocated];
- allocated += size_in_words;
- CHECK(allocated < kCallocPoolSize);
- return mem;
- }
- GET_STACK_TRACE_MALLOC;
- return asan_calloc(nmemb, size, &stack);
-}
-
-extern "C"
-SANITIZER_INTERFACE_ATTRIBUTE
-void *__asan_mz_valloc(malloc_zone_t *zone, size_t size) {
- if (UNLIKELY(!asan_inited)) {
- CHECK(system_malloc_zone);
- return malloc_zone_valloc(system_malloc_zone, size);
- }
- GET_STACK_TRACE_MALLOC;
- return asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC);
-}
-
-#define GET_ZONE_FOR_PTR(ptr) \
- malloc_zone_t *zone_ptr = malloc_zone_from_ptr(ptr); \
- const char *zone_name = (zone_ptr == 0) ? 0 : zone_ptr->zone_name
-
-void ALWAYS_INLINE free_common(void *context, void *ptr) {
- if (!ptr) return;
- GET_STACK_TRACE_FREE;
- // FIXME: need to retire this flag.
- if (!flags()->mac_ignore_invalid_free) {
- asan_free(ptr, &stack, FROM_MALLOC);
- } else {
- GET_ZONE_FOR_PTR(ptr);
- WarnMacFreeUnallocated((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);
- return;
- }
-}
-
-// TODO(glider): the allocation callbacks need to be refactored.
-extern "C"
-SANITIZER_INTERFACE_ATTRIBUTE
-void __asan_mz_free(malloc_zone_t *zone, void *ptr) {
- free_common(zone, ptr);
-}
-
-extern "C"
-SANITIZER_INTERFACE_ATTRIBUTE
-void *__asan_mz_realloc(malloc_zone_t *zone, void *ptr, size_t size) {
- if (!ptr) {
- GET_STACK_TRACE_MALLOC;
- return asan_malloc(size, &stack);
- } else {
- if (asan_mz_size(ptr)) {
- GET_STACK_TRACE_MALLOC;
- return asan_realloc(ptr, size, &stack);
- } else {
- // We can't recover from reallocating an unknown address, because
- // this would require reading at most |size| bytes from
- // potentially unaccessible memory.
- GET_STACK_TRACE_FREE;
- GET_ZONE_FOR_PTR(ptr);
- ReportMacMzReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);
- }
- }
-}
-
-extern "C"
-SANITIZER_INTERFACE_ATTRIBUTE
-void __asan_mz_destroy(malloc_zone_t* zone) {
- // A no-op -- we will not be destroyed!
- Report("__asan_mz_destroy() called -- ignoring\n");
-}
-
-extern "C"
-SANITIZER_INTERFACE_ATTRIBUTE
-void *__asan_mz_memalign(malloc_zone_t *zone, size_t align, size_t size) {
- if (UNLIKELY(!asan_inited)) {
- CHECK(system_malloc_zone);
- return malloc_zone_memalign(system_malloc_zone, align, size);
- }
- GET_STACK_TRACE_MALLOC;
- return asan_memalign(align, size, &stack, FROM_MALLOC);
-}
-
-// This function is currently unused, and we build with -Werror.
-#if 0
-void __asan_mz_free_definite_size(
- malloc_zone_t* zone, void *ptr, size_t size) {
- // TODO(glider): check that |size| is valid.
- UNIMPLEMENTED();
-}
-#endif
-
-kern_return_t mi_enumerator(task_t task, void *,
- unsigned type_mask, vm_address_t zone_address,
- memory_reader_t reader,
- vm_range_recorder_t recorder) {
- // Should enumerate all the pointers we have. Seems like a lot of work.
- return KERN_FAILURE;
-}
-
-size_t mi_good_size(malloc_zone_t *zone, size_t size) {
- // I think it's always safe to return size, but we maybe could do better.
- return size;
-}
-
-boolean_t mi_check(malloc_zone_t *zone) {
- UNIMPLEMENTED();
-}
-
-void mi_print(malloc_zone_t *zone, boolean_t verbose) {
- UNIMPLEMENTED();
-}
-
-void mi_log(malloc_zone_t *zone, void *address) {
- // I don't think we support anything like this
-}
-
-void mi_force_lock(malloc_zone_t *zone) {
- asan_mz_force_lock();
-}
-
-void mi_force_unlock(malloc_zone_t *zone) {
- asan_mz_force_unlock();
-}
-
-void mi_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) {
- AsanMallocStats malloc_stats;
- FillMallocStatistics(&malloc_stats);
- CHECK(sizeof(malloc_statistics_t) == sizeof(AsanMallocStats));
+#define COMMON_MALLOC_SIZE(ptr) \
+ uptr size = asan_mz_size(ptr);
+#define COMMON_MALLOC_FILL_STATS(zone, stats) \
+ AsanMallocStats malloc_stats; \
+ FillMallocStatistics(&malloc_stats); \
+ CHECK(sizeof(malloc_statistics_t) == sizeof(AsanMallocStats)); \
internal_memcpy(stats, &malloc_stats, sizeof(malloc_statistics_t));
-}
-
-boolean_t mi_zone_locked(malloc_zone_t *zone) {
- // UNIMPLEMENTED();
- return false;
-}
-
-} // unnamed namespace
-
-namespace __asan {
+#define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \
+ GET_STACK_TRACE_FREE; \
+ ReportMacMzReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);
+#define COMMON_MALLOC_NAMESPACE __asan
-void ReplaceSystemMalloc() {
- static malloc_introspection_t asan_introspection;
- // Ok to use internal_memset, these places are not performance-critical.
- internal_memset(&asan_introspection, 0, sizeof(asan_introspection));
+#include "sanitizer_common/sanitizer_malloc_mac.inc"
- asan_introspection.enumerator = &mi_enumerator;
- asan_introspection.good_size = &mi_good_size;
- asan_introspection.check = &mi_check;
- asan_introspection.print = &mi_print;
- asan_introspection.log = &mi_log;
- asan_introspection.force_lock = &mi_force_lock;
- asan_introspection.force_unlock = &mi_force_unlock;
- asan_introspection.statistics = &mi_statistics;
- asan_introspection.zone_locked = &mi_zone_locked;
-
- internal_memset(&asan_zone, 0, sizeof(malloc_zone_t));
-
- // Use version 6 for OSX >= 10.6.
- asan_zone.version = 6;
- asan_zone.zone_name = "asan";
- asan_zone.size = &__asan_mz_size;
- asan_zone.malloc = &__asan_mz_malloc;
- asan_zone.calloc = &__asan_mz_calloc;
- asan_zone.valloc = &__asan_mz_valloc;
- asan_zone.free = &__asan_mz_free;
- asan_zone.realloc = &__asan_mz_realloc;
- asan_zone.destroy = &__asan_mz_destroy;
- asan_zone.batch_malloc = 0;
- asan_zone.batch_free = 0;
- asan_zone.free_definite_size = 0;
- asan_zone.memalign = &__asan_mz_memalign;
- asan_zone.introspect = &asan_introspection;
-
- // Register the ASan zone.
- malloc_zone_register(&asan_zone);
-}
-} // namespace __asan
-
-#endif // SANITIZER_MAC
+#endif
diff --git a/contrib/compiler-rt/lib/asan/asan_mapping.h b/contrib/compiler-rt/lib/asan/asan_mapping.h
index f9e1a527de18..8fe347c8bad0 100644
--- a/contrib/compiler-rt/lib/asan/asan_mapping.h
+++ b/contrib/compiler-rt/lib/asan/asan_mapping.h
@@ -17,7 +17,7 @@
#include "asan_internal.h"
// The full explanation of the memory mapping could be found here:
-// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
+// https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm
//
// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
@@ -73,6 +73,20 @@
// || `[0x2000000000, 0x23ffffffff]` || LowShadow ||
// || `[0x0000000000, 0x1fffffffff]` || LowMem ||
//
+// Default Linux/AArch64 (39-bit VMA) mapping:
+// || `[0x2000000000, 0x7fffffffff]` || highmem ||
+// || `[0x1400000000, 0x1fffffffff]` || highshadow ||
+// || `[0x1200000000, 0x13ffffffff]` || shadowgap ||
+// || `[0x1000000000, 0x11ffffffff]` || lowshadow ||
+// || `[0x0000000000, 0x0fffffffff]` || lowmem ||
+//
+// Default Linux/AArch64 (42-bit VMA) mapping:
+// || `[0x10000000000, 0x3ffffffffff]` || highmem ||
+// || `[0x0a000000000, 0x0ffffffffff]` || highshadow ||
+// || `[0x09000000000, 0x09fffffffff]` || shadowgap ||
+// || `[0x08000000000, 0x08fffffffff]` || lowshadow ||
+// || `[0x00000000000, 0x07fffffffff]` || lowmem ||
+//
// Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
// || `[0x500000000000, 0x7fffffffffff]` || HighMem ||
// || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
@@ -113,11 +127,12 @@ static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000
static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000
#define SHADOW_SCALE kDefaultShadowScale
-#if SANITIZER_ANDROID
-# define SHADOW_OFFSET (0)
-#else
-# if SANITIZER_WORDSIZE == 32
-# if defined(__mips__)
+
+
+#if SANITIZER_WORDSIZE == 32
+# if SANITIZER_ANDROID
+# define SHADOW_OFFSET (0)
+# elif defined(__mips__)
# define SHADOW_OFFSET kMIPS32_ShadowOffset32
# elif SANITIZER_FREEBSD
# define SHADOW_OFFSET kFreeBSD_ShadowOffset32
@@ -130,7 +145,7 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000
# else
# define SHADOW_OFFSET kDefaultShadowOffset32
# endif
-# else
+#else
# if defined(__aarch64__)
# define SHADOW_OFFSET kAArch64_ShadowOffset64
# elif defined(__powerpc64__)
@@ -148,7 +163,6 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000
# else
# define SHADOW_OFFSET kDefaultShort64bitShadowOffset
# endif
-# endif
#endif
#define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE)
@@ -171,7 +185,8 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000
// With the zero shadow base we can not actually map pages starting from 0.
// This constant is somewhat arbitrary.
-#define kZeroBaseShadowStart (1 << 18)
+#define kZeroBaseShadowStart 0
+#define kZeroBaseMaxShadowStart (1 << 18)
#define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 \
: kZeroBaseShadowStart)
diff --git a/contrib/compiler-rt/lib/asan/asan_new_delete.cc b/contrib/compiler-rt/lib/asan/asan_new_delete.cc
index e48bdaf03dd3..b5ba13ef4055 100644
--- a/contrib/compiler-rt/lib/asan/asan_new_delete.cc
+++ b/contrib/compiler-rt/lib/asan/asan_new_delete.cc
@@ -30,7 +30,7 @@
using namespace __asan; // NOLINT
// This code has issues on OSX.
-// See https://code.google.com/p/address-sanitizer/issues/detail?id=131.
+// See https://github.com/google/sanitizers/issues/131.
// Fake std::nothrow_t to avoid including <new>.
namespace std {
@@ -90,11 +90,11 @@ INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
#if !SANITIZER_MAC
CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr) throw() {
+void operator delete(void *ptr) NOEXCEPT {
OPERATOR_DELETE_BODY(FROM_NEW);
}
CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr) throw() {
+void operator delete[](void *ptr) NOEXCEPT {
OPERATOR_DELETE_BODY(FROM_NEW_BR);
}
CXX_OPERATOR_ATTRIBUTE
@@ -106,12 +106,12 @@ void operator delete[](void *ptr, std::nothrow_t const&) {
OPERATOR_DELETE_BODY(FROM_NEW_BR);
}
CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr, size_t size) throw() {
+void operator delete(void *ptr, size_t size) NOEXCEPT {
GET_STACK_TRACE_FREE;
asan_sized_free(ptr, size, &stack, FROM_NEW);
}
CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr, size_t size) throw() {
+void operator delete[](void *ptr, size_t size) NOEXCEPT {
GET_STACK_TRACE_FREE;
asan_sized_free(ptr, size, &stack, FROM_NEW_BR);
}
diff --git a/contrib/compiler-rt/lib/asan/asan_poisoning.cc b/contrib/compiler-rt/lib/asan/asan_poisoning.cc
index 569d359aa425..f77ab8780bb7 100644
--- a/contrib/compiler-rt/lib/asan/asan_poisoning.cc
+++ b/contrib/compiler-rt/lib/asan/asan_poisoning.cc
@@ -102,7 +102,7 @@ using namespace __asan; // NOLINT
// that user program (un)poisons the memory it owns. It poisons memory
// conservatively, and unpoisons progressively to make sure asan shadow
// mapping invariant is preserved (see detailed mapping description here:
-// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm).
+// https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm).
//
// * if user asks to poison region [left, right), the program poisons
// at least [left, AlignDown(right)).
@@ -354,7 +354,7 @@ void __sanitizer_annotate_contiguous_container(const void *beg_p,
// Make a quick sanity check that we are indeed in this state.
//
// FIXME: Two of these three checks are disabled until we fix
- // https://code.google.com/p/address-sanitizer/issues/detail?id=258.
+ // https://github.com/google/sanitizers/issues/258.
// if (d1 != d2)
// CHECK_EQ(*(u8*)MemToShadow(d1), old_mid - d1);
if (a + granularity <= d1)
@@ -375,10 +375,10 @@ void __sanitizer_annotate_contiguous_container(const void *beg_p,
}
}
-int __sanitizer_verify_contiguous_container(const void *beg_p,
- const void *mid_p,
- const void *end_p) {
- if (!flags()->detect_container_overflow) return 1;
+const void *__sanitizer_contiguous_container_find_bad_address(
+ const void *beg_p, const void *mid_p, const void *end_p) {
+ if (!flags()->detect_container_overflow)
+ return nullptr;
uptr beg = reinterpret_cast<uptr>(beg_p);
uptr end = reinterpret_cast<uptr>(end_p);
uptr mid = reinterpret_cast<uptr>(mid_p);
@@ -395,17 +395,24 @@ int __sanitizer_verify_contiguous_container(const void *beg_p,
uptr r3_end = end;
for (uptr i = r1_beg; i < r1_end; i++)
if (AddressIsPoisoned(i))
- return 0;
+ return reinterpret_cast<const void *>(i);
for (uptr i = r2_beg; i < mid; i++)
if (AddressIsPoisoned(i))
- return 0;
+ return reinterpret_cast<const void *>(i);
for (uptr i = mid; i < r2_end; i++)
if (!AddressIsPoisoned(i))
- return 0;
+ return reinterpret_cast<const void *>(i);
for (uptr i = r3_beg; i < r3_end; i++)
if (!AddressIsPoisoned(i))
- return 0;
- return 1;
+ return reinterpret_cast<const void *>(i);
+ return nullptr;
+}
+
+int __sanitizer_verify_contiguous_container(const void *beg_p,
+ const void *mid_p,
+ const void *end_p) {
+ return __sanitizer_contiguous_container_find_bad_address(beg_p, mid_p,
+ end_p) == nullptr;
}
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
diff --git a/contrib/compiler-rt/lib/asan/asan_posix.cc b/contrib/compiler-rt/lib/asan/asan_posix.cc
index 2e857f6f624c..9e01bcd091bf 100644
--- a/contrib/compiler-rt/lib/asan/asan_posix.cc
+++ b/contrib/compiler-rt/lib/asan/asan_posix.cc
@@ -33,11 +33,11 @@
namespace __asan {
-void AsanOnSIGSEGV(int, void *siginfo, void *context) {
+void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
ScopedDeadlySignal signal_scope(GetCurrentThread());
int code = (int)((siginfo_t*)siginfo)->si_code;
// Write the first message using the bullet-proof write.
- if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die();
+ if (18 != internal_write(2, "ASAN:DEADLYSIGNAL\n", 18)) Die();
SignalContext sig = SignalContext::Create(siginfo, context);
// Access at a reasonable offset above SP, or slightly below it (to account
@@ -75,8 +75,12 @@ void AsanOnSIGSEGV(int, void *siginfo, void *context) {
// unaligned memory access.
if (IsStackAccess && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR))
ReportStackOverflow(sig);
+ else if (signo == SIGFPE)
+ ReportDeadlySignal("FPE", sig);
+ else if (signo == SIGILL)
+ ReportDeadlySignal("ILL", sig);
else
- ReportSIGSEGV("SEGV", sig);
+ ReportDeadlySignal("SEGV", sig);
}
// ---------------------- TSD ---------------- {{{1
diff --git a/contrib/compiler-rt/lib/asan/asan_report.cc b/contrib/compiler-rt/lib/asan/asan_report.cc
index c1681e644464..bb7e36e84652 100644
--- a/contrib/compiler-rt/lib/asan/asan_report.cc
+++ b/contrib/compiler-rt/lib/asan/asan_report.cc
@@ -11,6 +11,7 @@
//
// This file contains error reporting code.
//===----------------------------------------------------------------------===//
+
#include "asan_flags.h"
#include "asan_internal.h"
#include "asan_mapping.h"
@@ -27,9 +28,11 @@ namespace __asan {
// -------------------- User-specified callbacks ----------------- {{{1
static void (*error_report_callback)(const char*);
-static char *error_message_buffer = 0;
+static char *error_message_buffer = nullptr;
static uptr error_message_buffer_pos = 0;
-static uptr error_message_buffer_size = 0;
+static BlockingMutex error_message_buf_mutex(LINKER_INITIALIZED);
+static const unsigned kAsanBuggyPcPoolSize = 25;
+static __sanitizer::atomic_uintptr_t AsanBuggyPcPool[kAsanBuggyPcPoolSize];
struct ReportData {
uptr pc;
@@ -45,16 +48,20 @@ static bool report_happened = false;
static ReportData report_data = {};
void AppendToErrorMessageBuffer(const char *buffer) {
- if (error_message_buffer) {
- uptr length = internal_strlen(buffer);
- CHECK_GE(error_message_buffer_size, error_message_buffer_pos);
- uptr remaining = error_message_buffer_size - error_message_buffer_pos;
- internal_strncpy(error_message_buffer + error_message_buffer_pos,
- buffer, remaining);
- error_message_buffer[error_message_buffer_size - 1] = '\0';
- // FIXME: reallocate the buffer instead of truncating the message.
- error_message_buffer_pos += Min(remaining, length);
+ BlockingMutexLock l(&error_message_buf_mutex);
+ if (!error_message_buffer) {
+ error_message_buffer =
+ (char*)MmapOrDieQuietly(kErrorMessageBufferSize, __func__);
+ error_message_buffer_pos = 0;
}
+ uptr length = internal_strlen(buffer);
+ RAW_CHECK(kErrorMessageBufferSize >= error_message_buffer_pos);
+ uptr remaining = kErrorMessageBufferSize - error_message_buffer_pos;
+ internal_strncpy(error_message_buffer + error_message_buffer_pos,
+ buffer, remaining);
+ error_message_buffer[kErrorMessageBufferSize - 1] = '\0';
+ // FIXME: reallocate the buffer instead of truncating the message.
+ error_message_buffer_pos += Min(remaining, length);
}
// ---------------------- Decorator ------------------------------ {{{1
@@ -373,7 +380,7 @@ static void PrintAccessAndVarIntersection(const StackVarDescr &var, uptr addr,
uptr next_var_beg) {
uptr var_end = var.beg + var.size;
uptr addr_end = addr + access_size;
- const char *pos_descr = 0;
+ const char *pos_descr = nullptr;
// If the variable [var.beg, var_end) is the nearest variable to the
// current memory access, indicate it in the log.
if (addr >= var.beg) {
@@ -544,7 +551,7 @@ void DescribeHeapAddress(uptr addr, uptr access_size) {
StackTrace alloc_stack = chunk.GetAllocStack();
char tname[128];
Decorator d;
- AsanThreadContext *free_thread = 0;
+ AsanThreadContext *free_thread = nullptr;
if (chunk.FreeTid() != kInvalidTid) {
free_thread = GetThreadContextByTidLocked(chunk.FreeTid());
Printf("%sfreed by thread T%d%s here:%s\n", d.Allocation(),
@@ -621,26 +628,90 @@ void DescribeThread(AsanThreadContext *context) {
// immediately after printing error report.
class ScopedInErrorReport {
public:
- explicit ScopedInErrorReport(ReportData *report = nullptr) {
- static atomic_uint32_t num_calls;
- static u32 reporting_thread_tid;
- if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
+ explicit ScopedInErrorReport(ReportData *report = nullptr,
+ bool fatal = false) {
+ halt_on_error_ = fatal || flags()->halt_on_error;
+
+ if (lock_.TryLock()) {
+ StartReporting(report);
+ return;
+ }
+
+ // ASan found two bugs in different threads simultaneously.
+
+ u32 current_tid = GetCurrentTidOrInvalid();
+ if (reporting_thread_tid_ == current_tid ||
+ reporting_thread_tid_ == kInvalidTid) {
+ // This is either asynch signal or nested error during error reporting.
+ // Fail simple to avoid deadlocks in Report().
+
+ // Can't use Report() here because of potential deadlocks
+ // in nested signal handlers.
+ const char msg[] = "AddressSanitizer: nested bug in the same thread, "
+ "aborting.\n";
+ WriteToFile(kStderrFd, msg, sizeof(msg));
+
+ internal__exit(common_flags()->exitcode);
+ }
+
+ if (halt_on_error_) {
// Do not print more than one report, otherwise they will mix up.
// Error reporting functions shouldn't return at this situation, as
- // they are defined as no-return.
+ // they are effectively no-returns.
+
Report("AddressSanitizer: while reporting a bug found another one. "
- "Ignoring.\n");
- u32 current_tid = GetCurrentTidOrInvalid();
- if (current_tid != reporting_thread_tid) {
- // ASan found two bugs in different threads simultaneously. Sleep
- // long enough to make sure that the thread which started to print
- // an error report will finish doing it.
- SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));
- }
+ "Ignoring.\n");
+
+ // Sleep long enough to make sure that the thread which started
+ // to print an error report will finish doing it.
+ SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));
+
// If we're still not dead for some reason, use raw _exit() instead of
// Die() to bypass any additional checks.
- internal__exit(flags()->exitcode);
+ internal__exit(common_flags()->exitcode);
+ } else {
+ // The other thread will eventually finish reporting
+ // so it's safe to wait
+ lock_.Lock();
}
+
+ StartReporting(report);
+ }
+
+ ~ScopedInErrorReport() {
+ // Make sure the current thread is announced.
+ DescribeThread(GetCurrentThread());
+ // We may want to grab this lock again when printing stats.
+ asanThreadRegistry().Unlock();
+ // Print memory stats.
+ if (flags()->print_stats)
+ __asan_print_accumulated_stats();
+
+ // Copy the message buffer so that we could start logging without holding a
+ // lock that gets aquired during printing.
+ InternalScopedBuffer<char> buffer_copy(kErrorMessageBufferSize);
+ {
+ BlockingMutexLock l(&error_message_buf_mutex);
+ internal_memcpy(buffer_copy.data(),
+ error_message_buffer, kErrorMessageBufferSize);
+ }
+
+ LogFullErrorReport(buffer_copy.data());
+
+ if (error_report_callback) {
+ error_report_callback(buffer_copy.data());
+ }
+ CommonSanitizerReportMutex.Unlock();
+ reporting_thread_tid_ = kInvalidTid;
+ lock_.Unlock();
+ if (halt_on_error_) {
+ Report("ABORTING\n");
+ Die();
+ }
+ }
+
+ private:
+ void StartReporting(ReportData *report) {
if (report) report_data = *report;
report_happened = true;
ASAN_ON_ERROR();
@@ -650,27 +721,19 @@ class ScopedInErrorReport {
// recursive reports.
asanThreadRegistry().Lock();
CommonSanitizerReportMutex.Lock();
- reporting_thread_tid = GetCurrentTidOrInvalid();
+ reporting_thread_tid_ = GetCurrentTidOrInvalid();
Printf("===================================================="
"=============\n");
}
- // Destructor is NORETURN, as functions that report errors are.
- NORETURN ~ScopedInErrorReport() {
- // Make sure the current thread is announced.
- DescribeThread(GetCurrentThread());
- // We may want to grab this lock again when printing stats.
- asanThreadRegistry().Unlock();
- // Print memory stats.
- if (flags()->print_stats)
- __asan_print_accumulated_stats();
- if (error_report_callback) {
- error_report_callback(error_message_buffer);
- }
- Report("ABORTING\n");
- Die();
- }
+
+ static StaticSpinMutex lock_;
+ static u32 reporting_thread_tid_;
+ bool halt_on_error_;
};
+StaticSpinMutex ScopedInErrorReport::lock_;
+u32 ScopedInErrorReport::reporting_thread_tid_;
+
void ReportStackOverflow(const SignalContext &sig) {
ScopedInErrorReport in_report;
Decorator d;
@@ -686,8 +749,8 @@ void ReportStackOverflow(const SignalContext &sig) {
ReportErrorSummary("stack-overflow", &stack);
}
-void ReportSIGSEGV(const char *description, const SignalContext &sig) {
- ScopedInErrorReport in_report;
+void ReportDeadlySignal(const char *description, const SignalContext &sig) {
+ ScopedInErrorReport in_report(/*report*/nullptr, /*fatal*/true);
Decorator d;
Printf("%s", d.Warning());
Report(
@@ -703,7 +766,7 @@ void ReportSIGSEGV(const char *description, const SignalContext &sig) {
stack.Print();
MaybeDumpInstructionBytes(sig.pc);
Printf("AddressSanitizer can not provide additional info.\n");
- ReportErrorSummary("SEGV", &stack);
+ ReportErrorSummary(description, &stack);
}
void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) {
@@ -744,7 +807,7 @@ void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
stack.Print();
DescribeHeapAddress(addr, 1);
ReportErrorSummary("new-delete-type-mismatch", &stack);
- Report("HINT: if you don't care about these warnings you may set "
+ Report("HINT: if you don't care about these errors you may set "
"ASAN_OPTIONS=new_delete_type_mismatch=0\n");
}
@@ -784,7 +847,7 @@ void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
stack.Print();
DescribeHeapAddress(addr, 1);
ReportErrorSummary("alloc-dealloc-mismatch", &stack);
- Report("HINT: if you don't care about these warnings you may set "
+ Report("HINT: if you don't care about these errors you may set "
"ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
}
@@ -886,7 +949,7 @@ void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
Printf(" [2]:\n");
StackDepotGet(stack_id2).Print();
}
- Report("HINT: if you don't care about these warnings you may set "
+ Report("HINT: if you don't care about these errors you may set "
"ASAN_OPTIONS=detect_odr_violation=0\n");
InternalScopedString error_msg(256);
error_msg.append("odr-violation: global '%s' at %s",
@@ -925,17 +988,6 @@ static INLINE void CheckForInvalidPointerPair(void *p1, void *p2) {
}
// ----------------------- Mac-specific reports ----------------- {{{1
-void WarnMacFreeUnallocated(uptr addr, uptr zone_ptr, const char *zone_name,
- BufferedStackTrace *stack) {
- // Just print a warning here.
- Printf("free_common(%p) -- attempting to free unallocated memory.\n"
- "AddressSanitizer is ignoring this error on Mac OS now.\n",
- addr);
- PrintZoneForPointer(addr, zone_ptr, zone_name);
- stack->Print();
- DescribeHeapAddress(addr, 1);
-}
-
void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
BufferedStackTrace *stack) {
ScopedInErrorReport in_report;
@@ -947,24 +999,23 @@ void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
DescribeHeapAddress(addr, 1);
}
-void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report;
- Printf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n"
- "This is an unrecoverable problem, exiting now.\n",
- addr);
- PrintZoneForPointer(addr, zone_ptr, zone_name);
- stack->Print();
- DescribeHeapAddress(addr, 1);
+// -------------- SuppressErrorReport -------------- {{{1
+// Avoid error reports duplicating for ASan recover mode.
+static bool SuppressErrorReport(uptr pc) {
+ if (!common_flags()->suppress_equal_pcs) return false;
+ for (unsigned i = 0; i < kAsanBuggyPcPoolSize; i++) {
+ uptr cmp = atomic_load_relaxed(&AsanBuggyPcPool[i]);
+ if (cmp == 0 && atomic_compare_exchange_strong(&AsanBuggyPcPool[i], &cmp,
+ pc, memory_order_relaxed))
+ return false;
+ if (cmp == pc) return true;
+ }
+ Die();
}
-} // namespace __asan
-
-// --------------------------- Interface --------------------- {{{1
-using namespace __asan; // NOLINT
-
-void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
- uptr access_size, u32 exp) {
+void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
+ uptr access_size, u32 exp, bool fatal) {
+ if (!fatal && SuppressErrorReport(pc)) return;
ENABLE_FRAME_POINTER;
// Optimization experiments.
@@ -1033,7 +1084,7 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
ReportData report = { pc, sp, bp, addr, (bool)is_write, access_size,
bug_descr };
- ScopedInErrorReport in_report(&report);
+ ScopedInErrorReport in_report(&report, fatal);
Decorator d;
Printf("%s", d.Warning());
@@ -1059,14 +1110,21 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
PrintShadowMemoryForAddress(addr);
}
+} // namespace __asan
+
+// --------------------------- Interface --------------------- {{{1
+using namespace __asan; // NOLINT
+
+void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
+ uptr access_size, u32 exp) {
+ ENABLE_FRAME_POINTER;
+ bool fatal = flags()->halt_on_error;
+ ReportGenericError(pc, bp, sp, addr, is_write, access_size, exp, fatal);
+}
+
void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {
+ BlockingMutexLock l(&error_message_buf_mutex);
error_report_callback = callback;
- if (callback) {
- error_message_buffer_size = 1 << 16;
- error_message_buffer =
- (char*)MmapOrDie(error_message_buffer_size, __func__);
- error_message_buffer_pos = 0;
- }
}
void __asan_describe_address(uptr addr) {
@@ -1117,7 +1175,7 @@ SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_ptr_cmp(void *a, void *b) {
CheckForInvalidPointerPair(a, b);
}
-} // extern "C"
+} // extern "C"
#if !SANITIZER_SUPPORTS_WEAK_HOOKS
// Provide default implementation of __asan_on_error that does nothing
diff --git a/contrib/compiler-rt/lib/asan/asan_report.h b/contrib/compiler-rt/lib/asan/asan_report.h
index e2786b0f260c..559b8adfd51d 100644
--- a/contrib/compiler-rt/lib/asan/asan_report.h
+++ b/contrib/compiler-rt/lib/asan/asan_report.h
@@ -49,44 +49,39 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size);
void DescribeThread(AsanThreadContext *context);
// Different kinds of error reports.
-void NORETURN ReportStackOverflow(const SignalContext &sig);
-void NORETURN ReportSIGSEGV(const char *description, const SignalContext &sig);
-void NORETURN ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
- BufferedStackTrace *free_stack);
-void NORETURN ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
-void NORETURN ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);
-void NORETURN ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
- AllocType alloc_type,
- AllocType dealloc_type);
-void NORETURN
- ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
-void NORETURN
- ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
- BufferedStackTrace *stack);
-void NORETURN
- ReportStringFunctionMemoryRangesOverlap(const char *function,
- const char *offset1, uptr length1,
- const char *offset2, uptr length2,
- BufferedStackTrace *stack);
-void NORETURN ReportStringFunctionSizeOverflow(uptr offset, uptr size,
- BufferedStackTrace *stack);
-void NORETURN
- ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
- uptr old_mid, uptr new_mid,
- BufferedStackTrace *stack);
+void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
+ uptr access_size, u32 exp, bool fatal);
+void ReportStackOverflow(const SignalContext &sig);
+void ReportDeadlySignal(const char *description, const SignalContext &sig);
+void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
+ BufferedStackTrace *free_stack);
+void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
+void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);
+void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
+ AllocType alloc_type,
+ AllocType dealloc_type);
+void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
+void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
+ BufferedStackTrace *stack);
+void ReportStringFunctionMemoryRangesOverlap(const char *function,
+ const char *offset1, uptr length1,
+ const char *offset2, uptr length2,
+ BufferedStackTrace *stack);
+void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
+ BufferedStackTrace *stack);
+void ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
+ uptr old_mid, uptr new_mid,
+ BufferedStackTrace *stack);
-void NORETURN
-ReportODRViolation(const __asan_global *g1, u32 stack_id1,
- const __asan_global *g2, u32 stack_id2);
+void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
+ const __asan_global *g2, u32 stack_id2);
// Mac-specific errors and warnings.
-void WarnMacFreeUnallocated(uptr addr, uptr zone_ptr, const char *zone_name,
- BufferedStackTrace *stack);
-void NORETURN ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr,
- const char *zone_name,
- BufferedStackTrace *stack);
-void NORETURN ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr,
- const char *zone_name,
- BufferedStackTrace *stack);
+void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr,
+ const char *zone_name,
+ BufferedStackTrace *stack);
+void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr,
+ const char *zone_name,
+ BufferedStackTrace *stack);
} // namespace __asan
diff --git a/contrib/compiler-rt/lib/asan/asan_rtl.cc b/contrib/compiler-rt/lib/asan/asan_rtl.cc
index a8d92b915a9a..7b8b5dd9be1b 100644
--- a/contrib/compiler-rt/lib/asan/asan_rtl.cc
+++ b/contrib/compiler-rt/lib/asan/asan_rtl.cc
@@ -11,6 +11,7 @@
//
// Main file of the ASan run-time library.
//===----------------------------------------------------------------------===//
+
#include "asan_activation.h"
#include "asan_allocator.h"
#include "asan_interceptors.h"
@@ -56,11 +57,6 @@ static void AsanDie() {
UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
}
}
- if (common_flags()->coverage)
- __sanitizer_cov_dump();
- if (flags()->abort_on_error)
- Abort();
- internal__exit(flags()->exitcode);
}
static void AsanCheckFailed(const char *file, int line, const char *cond,
@@ -117,13 +113,18 @@ static void OnLowLevelAllocate(uptr ptr, uptr size) {
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_ ## type ## size(uptr addr) { \
GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, 0); \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
} \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \
GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, exp); \
-}
+ ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
+} \
+extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+void __asan_report_ ## type ## size ## _noabort(uptr addr) { \
+ GET_CALLER_PC_BP_SP; \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
+} \
ASAN_REPORT_ERROR(load, false, 1)
ASAN_REPORT_ERROR(load, false, 2)
@@ -136,22 +137,27 @@ ASAN_REPORT_ERROR(store, true, 4)
ASAN_REPORT_ERROR(store, true, 8)
ASAN_REPORT_ERROR(store, true, 16)
-#define ASAN_REPORT_ERROR_N(type, is_write) \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
-void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
- GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, 0); \
-} \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+#define ASAN_REPORT_ERROR_N(type, is_write) \
+extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
+ GET_CALLER_PC_BP_SP; \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
+} \
+extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \
GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, exp); \
-}
+ ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
+} \
+extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+void __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) { \
+ GET_CALLER_PC_BP_SP; \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
+} \
ASAN_REPORT_ERROR_N(load, false)
ASAN_REPORT_ERROR_N(store, true)
-#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg) \
+#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \
uptr sp = MEM_TO_SHADOW(addr); \
uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
: *reinterpret_cast<u16 *>(sp); \
@@ -163,7 +169,8 @@ ASAN_REPORT_ERROR_N(store, true)
*__asan_test_only_reported_buggy_pointer = addr; \
} else { \
GET_CALLER_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, addr, is_write, size, exp_arg); \
+ ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg, \
+ fatal); \
} \
} \
}
@@ -171,12 +178,16 @@ ASAN_REPORT_ERROR_N(store, true)
#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_##type##size(uptr addr) { \
- ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0) \
+ ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, true) \
} \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_exp_##type##size(uptr addr, u32 exp) { \
- ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp) \
- }
+ ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp, true) \
+ } \
+ extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+ void __asan_##type##size ## _noabort(uptr addr) { \
+ ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, false) \
+ } \
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
@@ -194,7 +205,7 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_loadN(uptr addr, uptr size) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
- __asan_report_error(pc, bp, sp, addr, false, size, 0);
+ ReportGenericError(pc, bp, sp, addr, false, size, 0, true);
}
}
@@ -203,7 +214,16 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_exp_loadN(uptr addr, uptr size, u32 exp) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
- __asan_report_error(pc, bp, sp, addr, false, size, exp);
+ ReportGenericError(pc, bp, sp, addr, false, size, exp, true);
+ }
+}
+
+extern "C"
+NOINLINE INTERFACE_ATTRIBUTE
+void __asan_loadN_noabort(uptr addr, uptr size) {
+ if (__asan_region_is_poisoned(addr, size)) {
+ GET_CALLER_PC_BP_SP;
+ ReportGenericError(pc, bp, sp, addr, false, size, 0, false);
}
}
@@ -212,7 +232,7 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_storeN(uptr addr, uptr size) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
- __asan_report_error(pc, bp, sp, addr, true, size, 0);
+ ReportGenericError(pc, bp, sp, addr, true, size, 0, true);
}
}
@@ -221,7 +241,16 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_exp_storeN(uptr addr, uptr size, u32 exp) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
- __asan_report_error(pc, bp, sp, addr, true, size, exp);
+ ReportGenericError(pc, bp, sp, addr, true, size, exp, true);
+ }
+}
+
+extern "C"
+NOINLINE INTERFACE_ATTRIBUTE
+void __asan_storeN_noabort(uptr addr, uptr size) {
+ if (__asan_region_is_poisoned(addr, size)) {
+ GET_CALLER_PC_BP_SP;
+ ReportGenericError(pc, bp, sp, addr, true, size, 0, false);
}
}
@@ -259,16 +288,15 @@ static NOINLINE void force_interface_symbols() {
case 22: __asan_report_exp_store8(0, 0); break;
case 23: __asan_report_exp_store16(0, 0); break;
case 24: __asan_report_exp_store_n(0, 0, 0); break;
- case 25: __asan_register_globals(0, 0); break;
- case 26: __asan_unregister_globals(0, 0); break;
- case 27: __asan_set_death_callback(0); break;
- case 28: __asan_set_error_report_callback(0); break;
+ case 25: __asan_register_globals(nullptr, 0); break;
+ case 26: __asan_unregister_globals(nullptr, 0); break;
+ case 27: __asan_set_death_callback(nullptr); break;
+ case 28: __asan_set_error_report_callback(nullptr); break;
case 29: __asan_handle_no_return(); break;
- case 30: __asan_address_is_poisoned(0); break;
- case 31: __asan_poison_memory_region(0, 0); break;
- case 32: __asan_unpoison_memory_region(0, 0); break;
- case 33: __asan_set_error_exit_code(0); break;
- case 34: __asan_before_dynamic_init(0); break;
+ case 30: __asan_address_is_poisoned(nullptr); break;
+ case 31: __asan_poison_memory_region(nullptr, 0); break;
+ case 32: __asan_unpoison_memory_region(nullptr, 0); break;
+ case 34: __asan_before_dynamic_init(nullptr); break;
case 35: __asan_after_dynamic_init(); break;
case 36: __asan_poison_stack_memory(0, 0); break;
case 37: __asan_unpoison_stack_memory(0, 0); break;
@@ -298,9 +326,25 @@ static void InitializeHighMemEnd() {
}
static void ProtectGap(uptr addr, uptr size) {
+ if (!flags()->protect_shadow_gap)
+ return;
void *res = MmapNoAccess(addr, size, "shadow gap");
if (addr == (uptr)res)
return;
+ // A few pages at the start of the address space can not be protected.
+ // But we really want to protect as much as possible, to prevent this memory
+ // being returned as a result of a non-FIXED mmap().
+ if (addr == kZeroBaseShadowStart) {
+ uptr step = GetPageSizeCached();
+ while (size > step && addr < kZeroBaseMaxShadowStart) {
+ addr += step;
+ size -= step;
+ void *res = MmapNoAccess(addr, size, "shadow gap");
+ if (addr == (uptr)res)
+ return;
+ }
+ }
+
Report("ERROR: Failed to protect the shadow gap. "
"ASan cannot proceed correctly. ABORTING.\n");
DumpProcessMap();
@@ -363,12 +407,12 @@ static void AsanInitInternal() {
CHECK(!asan_init_is_running && "ASan init calls itself!");
asan_init_is_running = true;
+ CacheBinaryName();
+
// Initialize flags. This must be done early, because most of the
// initialization steps look at flags().
InitializeFlags();
- CacheBinaryName();
-
AsanCheckIncompatibleRT();
AsanCheckDynamicRTPrereqs();
@@ -381,7 +425,7 @@ static void AsanInitInternal() {
AsanDoesNotSupportStaticLinkage();
// Install tool-specific callbacks in sanitizer_common.
- SetDieCallback(AsanDie);
+ AddDieCallback(AsanDie);
SetCheckFailedCallback(AsanCheckFailed);
SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
@@ -457,7 +501,7 @@ static void AsanInitInternal() {
}
AsanTSDInit(PlatformTSDDtor);
- InstallDeadlySignalHandlers(AsanOnSIGSEGV);
+ InstallDeadlySignalHandlers(AsanOnDeadlySignal);
AllocatorOptions allocator_options;
allocator_options.SetFrom(flags(), common_flags());
@@ -531,24 +575,26 @@ public: // NOLINT
static AsanInitializer asan_initializer;
#endif // ASAN_DYNAMIC
-} // namespace __asan
+} // namespace __asan
// ---------------------- Interface ---------------- {{{1
using namespace __asan; // NOLINT
-int NOINLINE __asan_set_error_exit_code(int exit_code) {
- int old = flags()->exitcode;
- flags()->exitcode = exit_code;
- return old;
-}
-
void NOINLINE __asan_handle_no_return() {
int local_stack;
AsanThread *curr_thread = GetCurrentThread();
- CHECK(curr_thread);
uptr PageSize = GetPageSizeCached();
- uptr top = curr_thread->stack_top();
- uptr bottom = ((uptr)&local_stack - PageSize) & ~(PageSize-1);
+ uptr top, bottom;
+ if (curr_thread) {
+ top = curr_thread->stack_top();
+ bottom = ((uptr)&local_stack - PageSize) & ~(PageSize - 1);
+ } else {
+ // If we haven't seen this thread, try asking the OS for stack bounds.
+ uptr tls_addr, tls_size, stack_size;
+ GetThreadStackAndTls(/*main=*/false, &bottom, &stack_size, &tls_addr,
+ &tls_size);
+ top = bottom + stack_size;
+ }
static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M
if (top - bottom > kMaxExpectedCleanupSize) {
static bool reported_warning = false;
@@ -559,12 +605,12 @@ void NOINLINE __asan_handle_no_return() {
"stack top: %p; bottom %p; size: %p (%zd)\n"
"False positive error reports may follow\n"
"For details see "
- "http://code.google.com/p/address-sanitizer/issues/detail?id=189\n",
+ "https://github.com/google/sanitizers/issues/189\n",
top, bottom, top - bottom, top - bottom);
return;
}
PoisonShadow(bottom, top - bottom, 0);
- if (curr_thread->has_fake_stack())
+ if (curr_thread && curr_thread->has_fake_stack())
curr_thread->fake_stack()->HandleNoReturn();
}
@@ -578,3 +624,7 @@ void __asan_init() {
AsanActivate();
AsanInitInternal();
}
+
+void __asan_version_mismatch_check() {
+ // Do nothing.
+}
diff --git a/contrib/compiler-rt/lib/asan/asan_stack.h b/contrib/compiler-rt/lib/asan/asan_stack.h
index 122967a152f8..5c5181509801 100644
--- a/contrib/compiler-rt/lib/asan/asan_stack.h
+++ b/contrib/compiler-rt/lib/asan/asan_stack.h
@@ -11,6 +11,7 @@
//
// ASan-private header for asan_stack.cc.
//===----------------------------------------------------------------------===//
+
#ifndef ASAN_STACK_H
#define ASAN_STACK_H
@@ -48,15 +49,15 @@ void GetStackTraceWithPcBpAndContext(BufferedStackTrace *stack, uptr max_depth,
uptr stack_bottom = t->stack_bottom();
ScopedUnwinding unwind_scope(t);
stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast);
- } else if (t == 0 && !fast) {
+ } else if (!t && !fast) {
/* If GetCurrentThread() has failed, try to do slow unwind anyways. */
stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
}
}
-#endif // SANITIZER_WINDOWS
+#endif // SANITIZER_WINDOWS
}
-} // namespace __asan
+} // namespace __asan
// NOTE: A Rule of thumb is to retrieve stack trace in the interceptors
// as early as possible (in functions exposed to the user), as we generally
@@ -115,4 +116,4 @@ void GetStackTraceWithPcBpAndContext(BufferedStackTrace *stack, uptr max_depth,
stack.Print(); \
}
-#endif // ASAN_STACK_H
+#endif // ASAN_STACK_H
diff --git a/contrib/compiler-rt/lib/asan/asan_thread.cc b/contrib/compiler-rt/lib/asan/asan_thread.cc
index 9af5706d86d0..69813546f551 100644
--- a/contrib/compiler-rt/lib/asan/asan_thread.cc
+++ b/contrib/compiler-rt/lib/asan/asan_thread.cc
@@ -42,7 +42,7 @@ void AsanThreadContext::OnCreated(void *arg) {
void AsanThreadContext::OnFinished() {
// Drop the link to the AsanThread object.
- thread = 0;
+ thread = nullptr;
}
// MIPS requires aligned address
@@ -125,7 +125,7 @@ void AsanThread::Destroy() {
FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
uptr stack_size = this->stack_size();
if (stack_size == 0) // stack_size is not yet available, don't use FakeStack.
- return 0;
+ return nullptr;
uptr old_val = 0;
// fake_stack_ has 3 states:
// 0 -- not initialized
@@ -146,11 +146,11 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
SetTLSFakeStack(fake_stack_);
return fake_stack_;
}
- return 0;
+ return nullptr;
}
void AsanThread::Init() {
- fake_stack_ = 0; // Will be initialized lazily if needed.
+ fake_stack_ = nullptr; // Will be initialized lazily if needed.
CHECK_EQ(this->stack_size(), 0U);
SetThreadStackAndTls();
CHECK_GT(this->stack_size(), 0U);
@@ -161,13 +161,12 @@ void AsanThread::Init() {
VReport(1, "T%d: stack [%p,%p) size 0x%zx; local=%p\n", tid(),
(void *)stack_bottom_, (void *)stack_top_, stack_top_ - stack_bottom_,
&local);
- AsanPlatformThreadInit();
}
thread_return_t AsanThread::ThreadStart(
uptr os_id, atomic_uintptr_t *signal_thread_is_registered) {
Init();
- asanThreadRegistry().StartThread(tid(), os_id, 0);
+ asanThreadRegistry().StartThread(tid(), os_id, nullptr);
if (signal_thread_is_registered)
atomic_store(signal_thread_is_registered, 1, memory_order_release);
@@ -277,7 +276,7 @@ AsanThread *GetCurrentThread() {
return tctx->thread;
}
}
- return 0;
+ return nullptr;
}
return context->thread;
}
@@ -302,7 +301,7 @@ AsanThread *FindThreadByStackAddress(uptr addr) {
AsanThreadContext *tctx = static_cast<AsanThreadContext *>(
asanThreadRegistry().FindThreadContextLocked(ThreadStackContainsAddress,
(void *)addr));
- return tctx ? tctx->thread : 0;
+ return tctx ? tctx->thread : nullptr;
}
void EnsureMainThreadIDIsCorrect() {
@@ -315,10 +314,10 @@ void EnsureMainThreadIDIsCorrect() {
__asan::AsanThread *GetAsanThreadByOsIDLocked(uptr os_id) {
__asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>(
__asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id));
- if (!context) return 0;
+ if (!context) return nullptr;
return context->thread;
}
-} // namespace __asan
+} // namespace __asan
// --- Implementation of LSan-specific functions --- {{{1
namespace __lsan {
@@ -355,4 +354,4 @@ void UnlockThreadRegistry() {
void EnsureMainThreadIDIsCorrect() {
__asan::EnsureMainThreadIDIsCorrect();
}
-} // namespace __lsan
+} // namespace __lsan
diff --git a/contrib/compiler-rt/lib/asan/asan_thread.h b/contrib/compiler-rt/lib/asan/asan_thread.h
index 50acfc42d6a2..ac35711f5794 100644
--- a/contrib/compiler-rt/lib/asan/asan_thread.h
+++ b/contrib/compiler-rt/lib/asan/asan_thread.h
@@ -11,6 +11,7 @@
//
// ASan-private header for asan_thread.cc.
//===----------------------------------------------------------------------===//
+
#ifndef ASAN_THREAD_H
#define ASAN_THREAD_H
@@ -36,7 +37,7 @@ class AsanThreadContext : public ThreadContextBase {
explicit AsanThreadContext(int tid)
: ThreadContextBase(tid), announced(false),
destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
- thread(0) {}
+ thread(nullptr) {}
bool announced;
u8 destructor_iterations;
u32 stack_id;
@@ -84,8 +85,8 @@ class AsanThread {
void DeleteFakeStack(int tid) {
if (!fake_stack_) return;
FakeStack *t = fake_stack_;
- fake_stack_ = 0;
- SetTLSFakeStack(0);
+ fake_stack_ = nullptr;
+ SetTLSFakeStack(nullptr);
t->Destroy(tid);
}
@@ -95,7 +96,7 @@ class AsanThread {
FakeStack *fake_stack() {
if (!__asan_option_detect_stack_use_after_return)
- return 0;
+ return nullptr;
if (!has_fake_stack())
return AsyncSignalSafeLazyInitFakeStack();
return fake_stack_;
@@ -179,6 +180,6 @@ AsanThread *FindThreadByStackAddress(uptr addr);
// Used to handle fork().
void EnsureMainThreadIDIsCorrect();
-} // namespace __asan
+} // namespace __asan
-#endif // ASAN_THREAD_H
+#endif // ASAN_THREAD_H
diff --git a/contrib/compiler-rt/lib/asan/asan_win.cc b/contrib/compiler-rt/lib/asan/asan_win.cc
index addb3d40a696..92bd893d10ef 100644
--- a/contrib/compiler-rt/lib/asan/asan_win.cc
+++ b/contrib/compiler-rt/lib/asan/asan_win.cc
@@ -14,9 +14,9 @@
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_WINDOWS
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#include <dbghelp.h>
#include <stdlib.h>
#include "asan_interceptors.h"
@@ -175,14 +175,6 @@ void PlatformTSDDtor(void *tsd) {
// }}}
// ---------------------- Various stuff ---------------- {{{
-void DisableReexec() {
- // No need to re-exec on Windows.
-}
-
-void MaybeReexec() {
- // No need to re-exec on Windows.
-}
-
void *AsanDoesNotSupportStaticLinkage() {
#if defined(_DEBUG)
#error Please build the runtime with a non-debug CRT: /MD or /MT
@@ -194,15 +186,11 @@ void AsanCheckDynamicRTPrereqs() {}
void AsanCheckIncompatibleRT() {}
-void AsanPlatformThreadInit() {
- // Nothing here for now.
-}
-
void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
UNIMPLEMENTED();
}
-void AsanOnSIGSEGV(int, void *siginfo, void *context) {
+void AsanOnDeadlySignal(int, void *siginfo, void *context) {
UNIMPLEMENTED();
}
@@ -219,7 +207,7 @@ static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
? "access-violation"
: "in-page-error";
SignalContext sig = SignalContext::Create(exception_record, context);
- ReportSIGSEGV(description, sig);
+ ReportDeadlySignal(description, sig);
}
// FIXME: Handle EXCEPTION_STACK_OVERFLOW here.
@@ -257,7 +245,7 @@ int __asan_set_seh_filter() {
// Put a pointer to __asan_set_seh_filter at the end of the global list
// of C initializers, after the default EH is set by the CRT.
#pragma section(".CRT$XIZ", long, read) // NOLINT
-static __declspec(allocate(".CRT$XIZ"))
+__declspec(allocate(".CRT$XIZ"))
int (*__intercept_seh)() = __asan_set_seh_filter;
#endif
// }}}
diff --git a/contrib/compiler-rt/lib/asan/asan_win_dll_thunk.cc b/contrib/compiler-rt/lib/asan/asan_win_dll_thunk.cc
index b77f18168ae5..672cabf43ec1 100644
--- a/contrib/compiler-rt/lib/asan/asan_win_dll_thunk.cc
+++ b/contrib/compiler-rt/lib/asan/asan_win_dll_thunk.cc
@@ -12,8 +12,7 @@
// This file defines a family of thunks that should be statically linked into
// the DLLs that have ASan instrumentation in order to delegate the calls to the
// shared runtime that lives in the main binary.
-// See https://code.google.com/p/address-sanitizer/issues/detail?id=209 for the
-// details.
+// See https://github.com/google/sanitizers/issues/209 for the details.
//===----------------------------------------------------------------------===//
// Only compile this code when buidling asan_dll_thunk.lib
@@ -30,8 +29,9 @@ void *__stdcall GetProcAddress(void *module, const char *proc_name);
void abort();
}
-static void *getRealProcAddressOrDie(const char *name) {
- void *ret = GetProcAddress(GetModuleHandleA(0), name);
+static uptr getRealProcAddressOrDie(const char *name) {
+ uptr ret =
+ __interception::InternalGetProcAddress((void *)GetModuleHandleA(0), name);
if (!ret)
abort();
return ret;
@@ -62,13 +62,12 @@ struct FunctionInterceptor<0> {
};
#define INTERCEPT_WHEN_POSSIBLE(main_function, dll_function) \
- template<> struct FunctionInterceptor<__LINE__> { \
+ template <> struct FunctionInterceptor<__LINE__> { \
static void Execute() { \
- void *wrapper = getRealProcAddressOrDie(main_function); \
- if (!__interception::OverrideFunction((uptr)dll_function, \
- (uptr)wrapper, 0)) \
+ uptr wrapper = getRealProcAddressOrDie(main_function); \
+ if (!__interception::OverrideFunction((uptr)dll_function, wrapper, 0)) \
abort(); \
- FunctionInterceptor<__LINE__-1>::Execute(); \
+ FunctionInterceptor<__LINE__ - 1>::Execute(); \
} \
};
@@ -210,7 +209,7 @@ extern "C" {
// __asan_init is expected to be called by only one thread.
if (fn) return;
- fn = (fntype)getRealProcAddressOrDie(__asan_init_name);
+ fn = (fntype)getRealProcAddressOrDie("__asan_init");
fn();
__asan_option_detect_stack_use_after_return =
(__asan_should_detect_stack_use_after_return() != 0);
@@ -219,6 +218,10 @@ extern "C" {
}
}
+extern "C" void __asan_version_mismatch_check() {
+ // Do nothing.
+}
+
INTERFACE_FUNCTION(__asan_handle_no_return)
INTERFACE_FUNCTION(__asan_report_store1)
@@ -253,6 +256,9 @@ INTERFACE_FUNCTION(__asan_memcpy);
INTERFACE_FUNCTION(__asan_memset);
INTERFACE_FUNCTION(__asan_memmove);
+INTERFACE_FUNCTION(__asan_alloca_poison);
+INTERFACE_FUNCTION(__asan_allocas_unpoison);
+
INTERFACE_FUNCTION(__asan_register_globals)
INTERFACE_FUNCTION(__asan_unregister_globals)
@@ -296,6 +302,7 @@ INTERFACE_FUNCTION(__asan_stack_free_10)
// FIXME: we might want to have a sanitizer_win_dll_thunk?
INTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container)
+INTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address)
INTERFACE_FUNCTION(__sanitizer_cov)
INTERFACE_FUNCTION(__sanitizer_cov_dump)
INTERFACE_FUNCTION(__sanitizer_cov_indir_call16)
@@ -304,14 +311,17 @@ INTERFACE_FUNCTION(__sanitizer_cov_module_init)
INTERFACE_FUNCTION(__sanitizer_cov_trace_basic_block)
INTERFACE_FUNCTION(__sanitizer_cov_trace_func_enter)
INTERFACE_FUNCTION(__sanitizer_cov_trace_cmp)
+INTERFACE_FUNCTION(__sanitizer_cov_trace_switch)
INTERFACE_FUNCTION(__sanitizer_cov_with_check)
INTERFACE_FUNCTION(__sanitizer_get_allocated_size)
INTERFACE_FUNCTION(__sanitizer_get_coverage_guards)
+INTERFACE_FUNCTION(__sanitizer_get_coverage_pc_buffer)
INTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes)
INTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size)
INTERFACE_FUNCTION(__sanitizer_get_free_bytes)
INTERFACE_FUNCTION(__sanitizer_get_heap_size)
INTERFACE_FUNCTION(__sanitizer_get_ownership)
+INTERFACE_FUNCTION(__sanitizer_get_total_unique_caller_callee_pairs)
INTERFACE_FUNCTION(__sanitizer_get_total_unique_coverage)
INTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes)
INTERFACE_FUNCTION(__sanitizer_maybe_open_cov_file)
diff --git a/contrib/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cc b/contrib/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cc
index d59f9f5768a0..73e5207bb334 100644
--- a/contrib/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cc
+++ b/contrib/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cc
@@ -24,6 +24,7 @@
// Using #ifdef rather than relying on Makefiles etc.
// simplifies the build procedure.
#ifdef ASAN_DYNAMIC_RUNTIME_THUNK
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// First, declare CRT sections we'll be using in this file
@@ -58,6 +59,7 @@ int __asan_option_detect_stack_use_after_return =
// using atexit() that calls a small subset of C terminators
// where LLVM global_dtors is placed. Fingers crossed, no other C terminators
// are there.
+extern "C" int __cdecl atexit(void (__cdecl *f)(void));
extern "C" void __cdecl _initterm(void *a, void *b);
namespace {
diff --git a/contrib/compiler-rt/lib/asan/scripts/asan_device_setup b/contrib/compiler-rt/lib/asan/scripts/asan_device_setup
deleted file mode 100755
index 104e07b722ca..000000000000
--- a/contrib/compiler-rt/lib/asan/scripts/asan_device_setup
+++ /dev/null
@@ -1,344 +0,0 @@
-#!/bin/bash
-#===- lib/asan/scripts/asan_device_setup -----------------------------------===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-# Prepare Android device to run ASan applications.
-#
-#===------------------------------------------------------------------------===#
-
-set -e
-
-HERE="$(cd "$(dirname "$0")" && pwd)"
-
-revert=no
-extra_options=
-device=
-lib=
-use_su=0
-
-function usage {
- echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]"
- echo " --revert: Uninstall ASan from the device."
- echo " --lib: Path to ASan runtime library."
- echo " --extra-options: Extra ASAN_OPTIONS."
- echo " --device: Install to the given device. Use 'adb devices' to find"
- echo " device-id."
- echo " --use-su: Use 'su -c' prefix for every adb command instead of using"
- echo " 'adb root' once."
- echo
- exit 1
-}
-
-function adb_push {
- if [ $use_su -eq 0 ]; then
- $ADB push "$1" "$2"
- else
- local FILENAME=$(basename $1)
- $ADB push "$1" "/data/local/tmp/$FILENAME"
- $ADB shell su -c "rm \\\"$2/$FILENAME\\\"" >&/dev/null
- $ADB shell su -c "cat \\\"/data/local/tmp/$FILENAME\\\" > \\\"$2/$FILENAME\\\""
- $ADB shell su -c "rm \\\"/data/local/tmp/$FILENAME\\\""
- fi
-}
-
-function adb_remount {
- if [ $use_su -eq 0 ]; then
- $ADB remount
- else
- local STORAGE=`$ADB shell mount | grep /system | cut -d ' ' -f1`
- if [ "$STORAGE" != "" ]; then
- echo Remounting $STORAGE at /system
- $ADB shell su -c "mount -o remount,rw $STORAGE /system"
- else
- echo Failed to get storage device name for "/system" mount point
- fi
- fi
-}
-
-function adb_shell {
- if [ $use_su -eq 0 ]; then
- $ADB shell $@
- else
- $ADB shell su -c "$*"
- fi
-}
-
-function adb_root {
- if [ $use_su -eq 0 ]; then
- $ADB root
- fi
-}
-
-function adb_wait_for_device {
- $ADB wait-for-device
-}
-
-function adb_pull {
- if [ $use_su -eq 0 ]; then
- $ADB pull "$1" "$2"
- else
- local FILENAME=$(basename $1)
- $ADB shell rm "/data/local/tmp/$FILENAME" >&/dev/null
- $ADB shell su -c "[ -f \\\"$1\\\" ] && cat \\\"$1\\\" > \\\"/data/local/tmp/$FILENAME\\\" && chown root.shell \\\"/data/local/tmp/$FILENAME\\\" && chmod 755 \\\"/data/local/tmp/$FILENAME\\\"" &&
- $ADB pull "/data/local/tmp/$FILENAME" "$2" >&/dev/null && $ADB shell "rm \"/data/local/tmp/$FILENAME\""
- fi
-}
-
-function get_device_arch { # OUTVAR
- local _outvar=$1
- local _ABI=$(adb_shell getprop ro.product.cpu.abi)
- local _ARCH=
- if [[ $_ABI == x86* ]]; then
- _ARCH=i686
- elif [[ $_ABI == armeabi* ]]; then
- _ARCH=arm
- else
- echo "Unrecognized device ABI: $_ABI"
- exit 1
- fi
- eval $_outvar=\$_ARCH
-}
-
-while [[ $# > 0 ]]; do
- case $1 in
- --revert)
- revert=yes
- ;;
- --extra-options)
- shift
- if [[ $# == 0 ]]; then
- echo "--extra-options requires an argument."
- exit 1
- fi
- extra_options="$1"
- ;;
- --lib)
- shift
- if [[ $# == 0 ]]; then
- echo "--lib requires an argument."
- exit 1
- fi
- lib="$1"
- ;;
- --device)
- shift
- if [[ $# == 0 ]]; then
- echo "--device requires an argument."
- exit 1
- fi
- device="$1"
- ;;
- --use-su)
- use_su=1
- ;;
- *)
- usage
- ;;
- esac
- shift
-done
-
-ADB=${ADB:-adb}
-if [[ x$device != x ]]; then
- ADB="$ADB -s $device"
-fi
-
-if [ $use_su -eq 1 ]; then
- # Test if 'su' is present on the device
- SU_TEST_OUT=`$ADB shell su -c "echo foo" 2>&1 | sed 's/\r$//'`
- if [ $? != 0 -o "$SU_TEST_OUT" != "foo" ]; then
- echo "ERROR: Cannot use 'su -c':"
- echo "$ adb shell su -c \"echo foo\""
- echo $SU_TEST_OUT
- echo "Check that 'su' binary is correctly installed on the device or omit"
- echo " --use-su flag"
- exit 1
- fi
-fi
-
-echo '>> Remounting /system rw'
-adb_wait_for_device
-adb_root
-adb_wait_for_device
-adb_remount
-adb_wait_for_device
-
-get_device_arch ARCH
-echo "Target architecture: $ARCH"
-ASAN_RT="libclang_rt.asan-$ARCH-android.so"
-
-if [[ x$revert == xyes ]]; then
- echo '>> Uninstalling ASan'
-
- if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
- echo '>> Pre-L device detected.'
- adb_shell mv /system/bin/app_process.real /system/bin/app_process
- adb_shell rm /system/bin/asanwrapper
- else
- adb_shell rm /system/bin/app_process.wrap
- adb_shell rm /system/bin/asanwrapper
- adb_shell rm /system/bin/app_process
- adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
- fi
-
- echo '>> Restarting shell'
- adb_shell stop
- adb_shell start
-
- # Remove the library on the last step to give a chance to the 'su' binary to
- # be executed without problem.
- adb_shell rm /system/lib/$ASAN_RT
-
- echo '>> Done'
- exit 0
-fi
-
-if [[ -d "$lib" ]]; then
- ASAN_RT_PATH="$lib"
-elif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then
- ASAN_RT_PATH=$(dirname "$lib")
-elif [[ -f "$HERE/$ASAN_RT" ]]; then
- ASAN_RT_PATH="$HERE"
-elif [[ $(basename "$HERE") == "bin" ]]; then
- # We could be in the toolchain's base directory.
- # Consider ../lib, ../lib/asan, ../lib/linux and ../lib/clang/$VERSION/lib/linux.
- P=$(ls "$HERE"/../lib/"$ASAN_RT" "$HERE"/../lib/asan/"$ASAN_RT" "$HERE"/../lib/linux/"$ASAN_RT" "$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1)
- if [[ -n "$P" ]]; then
- ASAN_RT_PATH="$(dirname "$P")"
- fi
-fi
-
-if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then
- echo ">> ASan runtime library not found"
- exit 1
-fi
-
-TMPDIRBASE=$(mktemp -d)
-TMPDIROLD="$TMPDIRBASE/old"
-TMPDIR="$TMPDIRBASE/new"
-mkdir "$TMPDIROLD"
-
-RELEASE=$(adb_shell getprop ro.build.version.release)
-PRE_L=0
-if echo "$RELEASE" | grep '^4\.' >&/dev/null; then
- PRE_L=1
-fi
-
-if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
-
- if adb_pull /system/bin/app_process.real /dev/null >&/dev/null; then
- echo '>> Old-style ASan installation detected. Reverting.'
- adb_shell mv /system/bin/app_process.real /system/bin/app_process
- fi
-
- echo '>> Pre-L device detected. Setting up app_process symlink.'
- adb_shell mv /system/bin/app_process /system/bin/app_process32
- adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
-fi
-
-echo '>> Copying files from the device'
-adb_pull /system/bin/app_process.wrap "$TMPDIROLD" || true
-adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
-adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
-cp -r "$TMPDIROLD" "$TMPDIR"
-
-if [[ -f "$TMPDIR/app_process.wrap" ]]; then
- echo ">> Previous installation detected"
-else
- echo ">> New installation"
-fi
-
-echo '>> Generating wrappers'
-
-cp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/"
-
-# FIXME: alloc_dealloc_mismatch=0 prevents a failure in libdvm startup,
-# which may or may not be a real bug (probably not).
-ASAN_OPTIONS=start_deactivated=1,alloc_dealloc_mismatch=0
-
-# On Android-L not allowing user segv handler breaks some applications.
-if [[ PRE_L -eq 0 ]]; then
- ASAN_OPTIONS="$ASAN_OPTIONS,allow_user_segv_handler=1"
-fi
-
-if [[ x$extra_options != x ]] ; then
- ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
-fi
-
-# Zygote wrapper.
-cat <<EOF >"$TMPDIR/app_process.wrap"
-#!/system/bin/sh-from-zygote
-ASAN_OPTIONS=$ASAN_OPTIONS \\
-LD_PRELOAD=\$LD_PRELOAD:$ASAN_RT \\
-exec /system/bin/app_process32 \$@
-
-EOF
-
-# General command-line tool wrapper (use for anything that's not started as
-# zygote).
-cat <<EOF >"$TMPDIR/asanwrapper"
-#!/system/bin/sh
-LD_PRELOAD=$ASAN_RT \\
-exec \$@
-
-EOF
-
-if ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then
- echo '>> Pushing files to the device'
- adb_push "$TMPDIR/$ASAN_RT" /system/lib/
- adb_push "$TMPDIR/app_process.wrap" /system/bin
- adb_push "$TMPDIR/asanwrapper" /system/bin
-
- adb_shell rm /system/bin/app_process
- adb_shell ln -s /system/bin/app_process.wrap /system/bin/app_process
-
- adb_shell chown root.shell \
- /system/lib/"$ASAN_RT" \
- /system/bin/app_process.wrap \
- /system/bin/asanwrapper
- adb_shell chmod 644 \
- /system/lib/"$ASAN_RT"
- adb_shell chmod 755 \
- /system/bin/app_process.wrap \
- /system/bin/asanwrapper
-
- # Make SELinux happy by keeping app_process wrapper and the shell
- # it runs on in zygote domain.
- ENFORCING=0
- if adb_shell getenforce | grep Enforcing >/dev/null; then
- # Sometimes shell is not allowed to change file contexts.
- # Temporarily switch to permissive.
- ENFORCING=1
- adb_shell setenforce 0
- fi
-
- adb_shell cp /system/bin/sh /system/bin/sh-from-zygote
-
- if [[ PRE_L -eq 1 ]]; then
- CTX=u:object_r:system_file:s0
- else
- CTX=u:object_r:zygote_exec:s0
- fi
- adb_shell chcon $CTX \
- /system/bin/sh-from-zygote \
- /system/bin/app_process.wrap \
- /system/bin/app_process32
-
- if [ $ENFORCING == 1 ]; then
- adb_shell setenforce 1
- fi
-
- echo '>> Restarting shell (asynchronous)'
- adb_shell stop
- adb_shell start
-
- echo '>> Please wait until the device restarts'
-else
- echo '>> Device is up to date'
-fi
-
-rm -r "$TMPDIRBASE"
diff --git a/contrib/compiler-rt/lib/asan/scripts/asan_symbolize.py b/contrib/compiler-rt/lib/asan/scripts/asan_symbolize.py
deleted file mode 100755
index b9d3ad3ad2fe..000000000000
--- a/contrib/compiler-rt/lib/asan/scripts/asan_symbolize.py
+++ /dev/null
@@ -1,482 +0,0 @@
-#!/usr/bin/env python
-#===- lib/asan/scripts/asan_symbolize.py -----------------------------------===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-import argparse
-import bisect
-import getopt
-import os
-import re
-import subprocess
-import sys
-
-symbolizers = {}
-DEBUG = False
-demangle = False
-binutils_prefix = None
-sysroot_path = None
-binary_name_filter = None
-fix_filename_patterns = None
-logfile = sys.stdin
-allow_system_symbolizer = True
-
-# FIXME: merge the code that calls fix_filename().
-def fix_filename(file_name):
- if fix_filename_patterns:
- for path_to_cut in fix_filename_patterns:
- file_name = re.sub('.*' + path_to_cut, '', file_name)
- file_name = re.sub('.*asan_[a-z_]*.cc:[0-9]*', '_asan_rtl_', file_name)
- file_name = re.sub('.*crtstuff.c:0', '???:0', file_name)
- return file_name
-
-def sysroot_path_filter(binary_name):
- return sysroot_path + binary_name
-
-def guess_arch(addr):
- # Guess which arch we're running. 10 = len('0x') + 8 hex digits.
- if len(addr) > 10:
- return 'x86_64'
- else:
- return 'i386'
-
-class Symbolizer(object):
- def __init__(self):
- pass
-
- def symbolize(self, addr, binary, offset):
- """Symbolize the given address (pair of binary and offset).
-
- Overriden in subclasses.
- Args:
- addr: virtual address of an instruction.
- binary: path to executable/shared object containing this instruction.
- offset: instruction offset in the @binary.
- Returns:
- list of strings (one string for each inlined frame) describing
- the code locations for this instruction (that is, function name, file
- name, line and column numbers).
- """
- return None
-
-
-class LLVMSymbolizer(Symbolizer):
- def __init__(self, symbolizer_path, default_arch, system, dsym_hints=[]):
- super(LLVMSymbolizer, self).__init__()
- self.symbolizer_path = symbolizer_path
- self.default_arch = default_arch
- self.system = system
- self.dsym_hints = dsym_hints
- self.pipe = self.open_llvm_symbolizer()
-
- def open_llvm_symbolizer(self):
- cmd = [self.symbolizer_path,
- '--use-symbol-table=true',
- '--demangle=%s' % demangle,
- '--functions=short',
- '--inlining=true',
- '--default-arch=%s' % self.default_arch]
- if self.system == 'Darwin':
- for hint in self.dsym_hints:
- cmd.append('--dsym-hint=%s' % hint)
- if DEBUG:
- print ' '.join(cmd)
- try:
- result = subprocess.Popen(cmd, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE)
- except OSError:
- result = None
- return result
-
- def symbolize(self, addr, binary, offset):
- """Overrides Symbolizer.symbolize."""
- if not self.pipe:
- return None
- result = []
- try:
- symbolizer_input = '"%s" %s' % (binary, offset)
- if DEBUG:
- print symbolizer_input
- print >> self.pipe.stdin, symbolizer_input
- while True:
- function_name = self.pipe.stdout.readline().rstrip()
- if not function_name:
- break
- file_name = self.pipe.stdout.readline().rstrip()
- file_name = fix_filename(file_name)
- if (not function_name.startswith('??') or
- not file_name.startswith('??')):
- # Append only non-trivial frames.
- result.append('%s in %s %s' % (addr, function_name,
- file_name))
- except Exception:
- result = []
- if not result:
- result = None
- return result
-
-
-def LLVMSymbolizerFactory(system, default_arch, dsym_hints=[]):
- symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH')
- if not symbolizer_path:
- symbolizer_path = os.getenv('ASAN_SYMBOLIZER_PATH')
- if not symbolizer_path:
- # Assume llvm-symbolizer is in PATH.
- symbolizer_path = 'llvm-symbolizer'
- return LLVMSymbolizer(symbolizer_path, default_arch, system, dsym_hints)
-
-
-class Addr2LineSymbolizer(Symbolizer):
- def __init__(self, binary):
- super(Addr2LineSymbolizer, self).__init__()
- self.binary = binary
- self.pipe = self.open_addr2line()
-
- def open_addr2line(self):
- addr2line_tool = 'addr2line'
- if binutils_prefix:
- addr2line_tool = binutils_prefix + addr2line_tool
- cmd = [addr2line_tool, '-f']
- if demangle:
- cmd += ['--demangle']
- cmd += ['-e', self.binary]
- if DEBUG:
- print ' '.join(cmd)
- return subprocess.Popen(cmd,
- stdin=subprocess.PIPE, stdout=subprocess.PIPE)
-
- def symbolize(self, addr, binary, offset):
- """Overrides Symbolizer.symbolize."""
- if self.binary != binary:
- return None
- try:
- print >> self.pipe.stdin, offset
- function_name = self.pipe.stdout.readline().rstrip()
- file_name = self.pipe.stdout.readline().rstrip()
- except Exception:
- function_name = ''
- file_name = ''
- file_name = fix_filename(file_name)
- return ['%s in %s %s' % (addr, function_name, file_name)]
-
-
-class UnbufferedLineConverter(object):
- """
- Wrap a child process that responds to each line of input with one line of
- output. Uses pty to trick the child into providing unbuffered output.
- """
- def __init__(self, args, close_stderr=False):
- # Local imports so that the script can start on Windows.
- import pty
- import termios
- pid, fd = pty.fork()
- if pid == 0:
- # We're the child. Transfer control to command.
- if close_stderr:
- dev_null = os.open('/dev/null', 0)
- os.dup2(dev_null, 2)
- os.execvp(args[0], args)
- else:
- # Disable echoing.
- attr = termios.tcgetattr(fd)
- attr[3] = attr[3] & ~termios.ECHO
- termios.tcsetattr(fd, termios.TCSANOW, attr)
- # Set up a file()-like interface to the child process
- self.r = os.fdopen(fd, "r", 1)
- self.w = os.fdopen(os.dup(fd), "w", 1)
-
- def convert(self, line):
- self.w.write(line + "\n")
- return self.readline()
-
- def readline(self):
- return self.r.readline().rstrip()
-
-
-class DarwinSymbolizer(Symbolizer):
- def __init__(self, addr, binary):
- super(DarwinSymbolizer, self).__init__()
- self.binary = binary
- self.arch = guess_arch(addr)
- self.open_atos()
-
- def open_atos(self):
- if DEBUG:
- print 'atos -o %s -arch %s' % (self.binary, self.arch)
- cmdline = ['atos', '-o', self.binary, '-arch', self.arch]
- self.atos = UnbufferedLineConverter(cmdline, close_stderr=True)
-
- def symbolize(self, addr, binary, offset):
- """Overrides Symbolizer.symbolize."""
- if self.binary != binary:
- return None
- atos_line = self.atos.convert('0x%x' % int(offset, 16))
- while "got symbolicator for" in atos_line:
- atos_line = self.atos.readline()
- # A well-formed atos response looks like this:
- # foo(type1, type2) (in object.name) (filename.cc:80)
- match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line)
- if DEBUG:
- print 'atos_line: ', atos_line
- if match:
- function_name = match.group(1)
- function_name = re.sub('\(.*?\)', '', function_name)
- file_name = fix_filename(match.group(3))
- return ['%s in %s %s' % (addr, function_name, file_name)]
- else:
- return ['%s in %s' % (addr, atos_line)]
-
-
-# Chain several symbolizers so that if one symbolizer fails, we fall back
-# to the next symbolizer in chain.
-class ChainSymbolizer(Symbolizer):
- def __init__(self, symbolizer_list):
- super(ChainSymbolizer, self).__init__()
- self.symbolizer_list = symbolizer_list
-
- def symbolize(self, addr, binary, offset):
- """Overrides Symbolizer.symbolize."""
- for symbolizer in self.symbolizer_list:
- if symbolizer:
- result = symbolizer.symbolize(addr, binary, offset)
- if result:
- return result
- return None
-
- def append_symbolizer(self, symbolizer):
- self.symbolizer_list.append(symbolizer)
-
-
-def BreakpadSymbolizerFactory(binary):
- suffix = os.getenv('BREAKPAD_SUFFIX')
- if suffix:
- filename = binary + suffix
- if os.access(filename, os.F_OK):
- return BreakpadSymbolizer(filename)
- return None
-
-
-def SystemSymbolizerFactory(system, addr, binary):
- if system == 'Darwin':
- return DarwinSymbolizer(addr, binary)
- elif system == 'Linux':
- return Addr2LineSymbolizer(binary)
-
-
-class BreakpadSymbolizer(Symbolizer):
- def __init__(self, filename):
- super(BreakpadSymbolizer, self).__init__()
- self.filename = filename
- lines = file(filename).readlines()
- self.files = []
- self.symbols = {}
- self.address_list = []
- self.addresses = {}
- # MODULE mac x86_64 A7001116478B33F18FF9BEDE9F615F190 t
- fragments = lines[0].rstrip().split()
- self.arch = fragments[2]
- self.debug_id = fragments[3]
- self.binary = ' '.join(fragments[4:])
- self.parse_lines(lines[1:])
-
- def parse_lines(self, lines):
- cur_function_addr = ''
- for line in lines:
- fragments = line.split()
- if fragments[0] == 'FILE':
- assert int(fragments[1]) == len(self.files)
- self.files.append(' '.join(fragments[2:]))
- elif fragments[0] == 'PUBLIC':
- self.symbols[int(fragments[1], 16)] = ' '.join(fragments[3:])
- elif fragments[0] in ['CFI', 'STACK']:
- pass
- elif fragments[0] == 'FUNC':
- cur_function_addr = int(fragments[1], 16)
- if not cur_function_addr in self.symbols.keys():
- self.symbols[cur_function_addr] = ' '.join(fragments[4:])
- else:
- # Line starting with an address.
- addr = int(fragments[0], 16)
- self.address_list.append(addr)
- # Tuple of symbol address, size, line, file number.
- self.addresses[addr] = (cur_function_addr,
- int(fragments[1], 16),
- int(fragments[2]),
- int(fragments[3]))
- self.address_list.sort()
-
- def get_sym_file_line(self, addr):
- key = None
- if addr in self.addresses.keys():
- key = addr
- else:
- index = bisect.bisect_left(self.address_list, addr)
- if index == 0:
- return None
- else:
- key = self.address_list[index - 1]
- sym_id, size, line_no, file_no = self.addresses[key]
- symbol = self.symbols[sym_id]
- filename = self.files[file_no]
- if addr < key + size:
- return symbol, filename, line_no
- else:
- return None
-
- def symbolize(self, addr, binary, offset):
- if self.binary != binary:
- return None
- res = self.get_sym_file_line(int(offset, 16))
- if res:
- function_name, file_name, line_no = res
- result = ['%s in %s %s:%d' % (
- addr, function_name, file_name, line_no)]
- print result
- return result
- else:
- return None
-
-
-class SymbolizationLoop(object):
- def __init__(self, binary_name_filter=None, dsym_hint_producer=None):
- if sys.platform == 'win32':
- # ASan on Windows uses dbghelp.dll to symbolize in-process, which works
- # even in sandboxed processes. Nothing needs to be done here.
- self.process_line = self.process_line_echo
- else:
- # Used by clients who may want to supply a different binary name.
- # E.g. in Chrome several binaries may share a single .dSYM.
- self.binary_name_filter = binary_name_filter
- self.dsym_hint_producer = dsym_hint_producer
- self.system = os.uname()[0]
- if self.system not in ['Linux', 'Darwin', 'FreeBSD']:
- raise Exception('Unknown system')
- self.llvm_symbolizers = {}
- self.last_llvm_symbolizer = None
- self.dsym_hints = set([])
- self.frame_no = 0
- self.process_line = self.process_line_posix
-
- def symbolize_address(self, addr, binary, offset):
- # On non-Darwin (i.e. on platforms without .dSYM debug info) always use
- # a single symbolizer binary.
- # On Darwin, if the dsym hint producer is present:
- # 1. check whether we've seen this binary already; if so,
- # use |llvm_symbolizers[binary]|, which has already loaded the debug
- # info for this binary (might not be the case for
- # |last_llvm_symbolizer|);
- # 2. otherwise check if we've seen all the hints for this binary already;
- # if so, reuse |last_llvm_symbolizer| which has the full set of hints;
- # 3. otherwise create a new symbolizer and pass all currently known
- # .dSYM hints to it.
- if not binary in self.llvm_symbolizers:
- use_new_symbolizer = True
- if self.system == 'Darwin' and self.dsym_hint_producer:
- dsym_hints_for_binary = set(self.dsym_hint_producer(binary))
- use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints)
- self.dsym_hints |= dsym_hints_for_binary
- if self.last_llvm_symbolizer and not use_new_symbolizer:
- self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
- else:
- self.last_llvm_symbolizer = LLVMSymbolizerFactory(
- self.system, guess_arch(addr), self.dsym_hints)
- self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
- # Use the chain of symbolizers:
- # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
- # (fall back to next symbolizer if the previous one fails).
- if not binary in symbolizers:
- symbolizers[binary] = ChainSymbolizer(
- [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])
- result = symbolizers[binary].symbolize(addr, binary, offset)
- if result is None:
- if not allow_system_symbolizer:
- raise Exception('Failed to launch or use llvm-symbolizer.')
- # Initialize system symbolizer only if other symbolizers failed.
- symbolizers[binary].append_symbolizer(
- SystemSymbolizerFactory(self.system, addr, binary))
- result = symbolizers[binary].symbolize(addr, binary, offset)
- # The system symbolizer must produce some result.
- assert result
- return result
-
- def get_symbolized_lines(self, symbolized_lines):
- if not symbolized_lines:
- return [self.current_line]
- else:
- result = []
- for symbolized_frame in symbolized_lines:
- result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstrip()))
- self.frame_no += 1
- return result
-
- def process_logfile(self):
- self.frame_no = 0
- for line in logfile:
- processed = self.process_line(line)
- print '\n'.join(processed)
-
- def process_line_echo(self, line):
- return [line.rstrip()]
-
- def process_line_posix(self, line):
- self.current_line = line.rstrip()
- #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45)
- stack_trace_line_format = (
- '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)')
- match = re.match(stack_trace_line_format, line)
- if not match:
- return [self.current_line]
- if DEBUG:
- print line
- _, frameno_str, addr, binary, offset = match.groups()
- if frameno_str == '0':
- # Assume that frame #0 is the first frame of new stack trace.
- self.frame_no = 0
- original_binary = binary
- if self.binary_name_filter:
- binary = self.binary_name_filter(binary)
- symbolized_line = self.symbolize_address(addr, binary, offset)
- if not symbolized_line:
- if original_binary != binary:
- symbolized_line = self.symbolize_address(addr, binary, offset)
- return self.get_symbolized_lines(symbolized_line)
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(
- formatter_class=argparse.RawDescriptionHelpFormatter,
- description='ASan symbolization script',
- epilog='Example of use:\n'
- 'asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" '
- '-s "$HOME/SymbolFiles" < asan.log')
- parser.add_argument('path_to_cut', nargs='*',
- help='pattern to be cut from the result file path ')
- parser.add_argument('-d','--demangle', action='store_true',
- help='demangle function names')
- parser.add_argument('-s', metavar='SYSROOT',
- help='set path to sysroot for sanitized binaries')
- parser.add_argument('-c', metavar='CROSS_COMPILE',
- help='set prefix for binutils')
- parser.add_argument('-l','--logfile', default=sys.stdin,
- type=argparse.FileType('r'),
- help='set log file name to parse, default is stdin')
- args = parser.parse_args()
- if args.path_to_cut:
- fix_filename_patterns = args.path_to_cut
- if args.demangle:
- demangle = True
- if args.s:
- binary_name_filter = sysroot_path_filter
- sysroot_path = args.s
- if args.c:
- binutils_prefix = args.c
- if args.logfile:
- logfile = args.logfile
- else:
- logfile = sys.stdin
- loop = SymbolizationLoop(binary_name_filter)
- loop.process_logfile()
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_asm_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_asm_test.cc
deleted file mode 100644
index 200de2c137a5..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_asm_test.cc
+++ /dev/null
@@ -1,267 +0,0 @@
-//===-- asan_asm_test.cc --------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-#if defined(__linux__)
-
-#if defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
-
-#include <emmintrin.h>
-
-namespace {
-
-template<typename T> void asm_write(T *ptr, T val);
-template<typename T> T asm_read(T *ptr);
-template<typename T> void asm_rep_movs(T *dst, T *src, size_t n);
-
-} // End of anonymous namespace
-
-#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
-
-#if defined(__x86_64__)
-
-namespace {
-
-#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \
-template<> void asm_write<Type>(Type *ptr, Type val) { \
- __asm__( \
- Mov " %[val], (%[ptr]) \n\t" \
- : \
- : [ptr] "r" (ptr), [val] Reg (val) \
- : "memory" \
- ); \
-}
-
-#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \
-template<> Type asm_read<Type>(Type *ptr) { \
- Type res; \
- __asm__( \
- Mov " (%[ptr]), %[res] \n\t" \
- : [res] Reg (res) \
- : [ptr] "r" (ptr) \
- : "memory" \
- ); \
- return res; \
-}
-
-#define DECLARE_ASM_REP_MOVS(Type, Movs) \
- template <> void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \
- __asm__("rep " Movs " \n\t" \
- : \
- : "D"(dst), "S"(src), "c"(size) \
- : "rsi", "rdi", "rcx", "memory"); \
- }
-
-DECLARE_ASM_WRITE(U8, "8", "movq", "r");
-DECLARE_ASM_READ(U8, "8", "movq", "=r");
-DECLARE_ASM_REP_MOVS(U8, "movsq");
-
-} // End of anonymous namespace
-
-#endif // defined(__x86_64__)
-
-#if defined(__i386__) && defined(__SSE2__)
-
-namespace {
-
-#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \
-template<> void asm_write<Type>(Type *ptr, Type val) { \
- __asm__( \
- Mov " %[val], (%[ptr]) \n\t" \
- : \
- : [ptr] "r" (ptr), [val] Reg (val) \
- : "memory" \
- ); \
-}
-
-#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \
-template<> Type asm_read<Type>(Type *ptr) { \
- Type res; \
- __asm__( \
- Mov " (%[ptr]), %[res] \n\t" \
- : [res] Reg (res) \
- : [ptr] "r" (ptr) \
- : "memory" \
- ); \
- return res; \
-}
-
-#define DECLARE_ASM_REP_MOVS(Type, Movs) \
- template <> void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \
- __asm__("rep " Movs " \n\t" \
- : \
- : "D"(dst), "S"(src), "c"(size) \
- : "esi", "edi", "ecx", "memory"); \
- }
-
-} // End of anonymous namespace
-
-#endif // defined(__i386__) && defined(__SSE2__)
-
-#if defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
-
-namespace {
-
-DECLARE_ASM_WRITE(U1, "1", "movb", "r");
-DECLARE_ASM_WRITE(U2, "2", "movw", "r");
-DECLARE_ASM_WRITE(U4, "4", "movl", "r");
-DECLARE_ASM_WRITE(__m128i, "16", "movaps", "x");
-
-DECLARE_ASM_READ(U1, "1", "movb", "=r");
-DECLARE_ASM_READ(U2, "2", "movw", "=r");
-DECLARE_ASM_READ(U4, "4", "movl", "=r");
-DECLARE_ASM_READ(__m128i, "16", "movaps", "=x");
-
-DECLARE_ASM_REP_MOVS(U1, "movsb");
-DECLARE_ASM_REP_MOVS(U2, "movsw");
-DECLARE_ASM_REP_MOVS(U4, "movsl");
-
-template<typename T> void TestAsmWrite(const char *DeathPattern) {
- T *buf = new T;
- EXPECT_DEATH(asm_write(&buf[1], static_cast<T>(0)), DeathPattern);
- T var = 0x12;
- asm_write(&var, static_cast<T>(0x21));
- ASSERT_EQ(static_cast<T>(0x21), var);
- delete buf;
-}
-
-template<> void TestAsmWrite<__m128i>(const char *DeathPattern) {
- char *buf = new char[16];
- char *p = buf + 16;
- if (((uintptr_t) p % 16) != 0)
- p = buf + 8;
- assert(((uintptr_t) p % 16) == 0);
- __m128i val = _mm_set1_epi16(0x1234);
- EXPECT_DEATH(asm_write<__m128i>((__m128i*) p, val), DeathPattern);
- __m128i var = _mm_set1_epi16(0x4321);
- asm_write(&var, val);
- ASSERT_EQ(0x1234, _mm_extract_epi16(var, 0));
- delete [] buf;
-}
-
-template<typename T> void TestAsmRead(const char *DeathPattern) {
- T *buf = new T;
- EXPECT_DEATH(asm_read(&buf[1]), DeathPattern);
- T var = 0x12;
- ASSERT_EQ(static_cast<T>(0x12), asm_read(&var));
- delete buf;
-}
-
-template<> void TestAsmRead<__m128i>(const char *DeathPattern) {
- char *buf = new char[16];
- char *p = buf + 16;
- if (((uintptr_t) p % 16) != 0)
- p = buf + 8;
- assert(((uintptr_t) p % 16) == 0);
- EXPECT_DEATH(asm_read<__m128i>((__m128i*) p), DeathPattern);
- __m128i val = _mm_set1_epi16(0x1234);
- ASSERT_EQ(0x1234, _mm_extract_epi16(asm_read(&val), 0));
- delete [] buf;
-}
-
-U4 AsmLoad(U4 *a) {
- U4 r;
- __asm__("movl (%[a]), %[r] \n\t" : [r] "=r" (r) : [a] "r" (a) : "memory");
- return r;
-}
-
-void AsmStore(U4 r, U4 *a) {
- __asm__("movl %[r], (%[a]) \n\t" : : [a] "r" (a), [r] "r" (r) : "memory");
-}
-
-template <typename T>
-void TestAsmRepMovs(const char *DeathPatternRead,
- const char *DeathPatternWrite) {
- T src_good[4] = { 0x0, 0x1, 0x2, 0x3 };
- T dst_good[4] = {};
- asm_rep_movs(dst_good, src_good, 4);
- ASSERT_EQ(static_cast<T>(0x0), dst_good[0]);
- ASSERT_EQ(static_cast<T>(0x1), dst_good[1]);
- ASSERT_EQ(static_cast<T>(0x2), dst_good[2]);
- ASSERT_EQ(static_cast<T>(0x3), dst_good[3]);
-
- T dst_bad[3];
- EXPECT_DEATH(asm_rep_movs(dst_bad, src_good, 4), DeathPatternWrite);
-
- T src_bad[3] = { 0x0, 0x1, 0x2 };
- EXPECT_DEATH(asm_rep_movs(dst_good, src_bad, 4), DeathPatternRead);
-
- T* dp = dst_bad + 4;
- T* sp = src_bad + 4;
- asm_rep_movs(dp, sp, 0);
-}
-
-} // End of anonymous namespace
-
-TEST(AddressSanitizer, asm_load_store) {
- U4* buf = new U4[2];
- EXPECT_DEATH(AsmLoad(&buf[3]), "READ of size 4");
- EXPECT_DEATH(AsmStore(0x1234, &buf[3]), "WRITE of size 4");
- delete [] buf;
-}
-
-TEST(AddressSanitizer, asm_rw) {
- TestAsmWrite<U1>("WRITE of size 1");
- TestAsmWrite<U2>("WRITE of size 2");
- TestAsmWrite<U4>("WRITE of size 4");
-#if defined(__x86_64__)
- TestAsmWrite<U8>("WRITE of size 8");
-#endif // defined(__x86_64__)
- TestAsmWrite<__m128i>("WRITE of size 16");
-
- TestAsmRead<U1>("READ of size 1");
- TestAsmRead<U2>("READ of size 2");
- TestAsmRead<U4>("READ of size 4");
-#if defined(__x86_64__)
- TestAsmRead<U8>("READ of size 8");
-#endif // defined(__x86_64__)
- TestAsmRead<__m128i>("READ of size 16");
-}
-
-TEST(AddressSanitizer, asm_flags) {
- long magic = 0x1234;
- long r = 0x0;
-
-#if defined(__x86_64__) && !defined(__ILP32__)
- __asm__("xorq %%rax, %%rax \n\t"
- "movq (%[p]), %%rax \n\t"
- "sete %%al \n\t"
- "movzbq %%al, %[r] \n\t"
- : [r] "=r"(r)
- : [p] "r"(&magic)
- : "rax", "memory");
-#else
- __asm__("xorl %%eax, %%eax \n\t"
- "movl (%[p]), %%eax \n\t"
- "sete %%al \n\t"
- "movzbl %%al, %[r] \n\t"
- : [r] "=r"(r)
- : [p] "r"(&magic)
- : "eax", "memory");
-#endif // defined(__x86_64__) && !defined(__ILP32__)
-
- ASSERT_EQ(0x1, r);
-}
-
-TEST(AddressSanitizer, asm_rep_movs) {
- TestAsmRepMovs<U1>("READ of size 1", "WRITE of size 1");
- TestAsmRepMovs<U2>("READ of size 2", "WRITE of size 2");
- TestAsmRepMovs<U4>("READ of size 4", "WRITE of size 4");
-#if defined(__x86_64__)
- TestAsmRepMovs<U8>("READ of size 8", "WRITE of size 8");
-#endif // defined(__x86_64__)
-}
-
-#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
-
-#endif // defined(__linux__)
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_benchmarks_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_benchmarks_test.cc
deleted file mode 100644
index fc522de475fa..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_benchmarks_test.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-//===-- asan_benchmarks_test.cc ----------------------===//
-//
-// 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.
-//
-// Some benchmarks for the instrumented code.
-//===----------------------------------------------------------------------===//
-
-#include "asan_test_utils.h"
-
-template<class T>
-__attribute__((noinline))
-static void ManyAccessFunc(T *x, size_t n_elements, size_t n_iter) {
- for (size_t iter = 0; iter < n_iter; iter++) {
- break_optimization(0);
- // hand unroll the loop to stress the reg alloc.
- for (size_t i = 0; i <= n_elements - 16; i += 16) {
- x[i + 0] = i;
- x[i + 1] = i;
- x[i + 2] = i;
- x[i + 3] = i;
- x[i + 4] = i;
- x[i + 5] = i;
- x[i + 6] = i;
- x[i + 7] = i;
- x[i + 8] = i;
- x[i + 9] = i;
- x[i + 10] = i;
- x[i + 11] = i;
- x[i + 12] = i;
- x[i + 13] = i;
- x[i + 14] = i;
- x[i + 15] = i;
- }
- }
-}
-
-TEST(AddressSanitizer, ManyAccessBenchmark) {
- size_t kLen = 1024;
- int *int_array = new int[kLen];
- ManyAccessFunc(int_array, kLen, 1 << 24);
- delete [] int_array;
-}
-
-// access 7 char elements in a 7 byte array (i.e. on the border).
-__attribute__((noinline))
-static void BorderAccessFunc(char *x, size_t n_iter) {
- for (size_t iter = 0; iter < n_iter; iter++) {
- break_optimization(x);
- x[0] = 0;
- x[1] = 0;
- x[2] = 0;
- x[3] = 0;
- x[4] = 0;
- x[5] = 0;
- x[6] = 0;
- }
-}
-
-TEST(AddressSanitizer, BorderAccessBenchmark) {
- char *char_7_array = new char[7];
- BorderAccessFunc(char_7_array, 1 << 30);
- delete [] char_7_array;
-}
-
-static void FunctionWithLargeStack() {
- int stack[1000];
- Ident(stack);
-}
-
-TEST(AddressSanitizer, FakeStackBenchmark) {
- for (int i = 0; i < 10000000; i++)
- Ident(&FunctionWithLargeStack)();
-}
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_exceptions_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_exceptions_test.cc
deleted file mode 100644
index ecd406de7561..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_exceptions_test.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// See http://llvm.org/bugs/show_bug.cgi?id=11468
-#include <stdio.h>
-#include <string>
-
-class Action {
- public:
- Action() {}
- void PrintString(const std::string& msg) const {
- fprintf(stderr, "%s\n", msg.c_str());
- }
- void Throw(const char& arg) const {
- PrintString("PrintString called!"); // this line is important
- throw arg;
- }
-};
-
-int main() {
- const Action a;
- fprintf(stderr, "&a before = %p\n", &a);
- try {
- a.Throw('c');
- } catch(const char&) {
- fprintf(stderr, "&a in catch = %p\n", &a);
- }
- fprintf(stderr, "&a final = %p\n", &a);
- return 0;
-}
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_fake_stack_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_fake_stack_test.cc
deleted file mode 100644
index 516142f0c3b7..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_fake_stack_test.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-//===-- asan_fake_stack_test.cc -------------------------------------------===//
-//
-// 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.
-//
-// Tests for FakeStack.
-// This test file should be compiled w/o asan instrumentation.
-//===----------------------------------------------------------------------===//
-
-#include "asan_fake_stack.h"
-#include "asan_test_utils.h"
-#include "sanitizer_common/sanitizer_common.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <map>
-
-namespace __asan {
-
-TEST(FakeStack, FlagsSize) {
- EXPECT_EQ(FakeStack::SizeRequiredForFlags(10), 1U << 5);
- EXPECT_EQ(FakeStack::SizeRequiredForFlags(11), 1U << 6);
- EXPECT_EQ(FakeStack::SizeRequiredForFlags(20), 1U << 15);
-}
-
-TEST(FakeStack, RequiredSize) {
- // for (int i = 15; i < 20; i++) {
- // uptr alloc_size = FakeStack::RequiredSize(i);
- // printf("%zdK ==> %zd\n", 1 << (i - 10), alloc_size);
- // }
- EXPECT_EQ(FakeStack::RequiredSize(15), 365568U);
- EXPECT_EQ(FakeStack::RequiredSize(16), 727040U);
- EXPECT_EQ(FakeStack::RequiredSize(17), 1449984U);
- EXPECT_EQ(FakeStack::RequiredSize(18), 2895872U);
- EXPECT_EQ(FakeStack::RequiredSize(19), 5787648U);
-}
-
-TEST(FakeStack, FlagsOffset) {
- for (uptr stack_size_log = 15; stack_size_log <= 20; stack_size_log++) {
- uptr stack_size = 1UL << stack_size_log;
- uptr offset = 0;
- for (uptr class_id = 0; class_id < FakeStack::kNumberOfSizeClasses;
- class_id++) {
- uptr frame_size = FakeStack::BytesInSizeClass(class_id);
- uptr num_flags = stack_size / frame_size;
- EXPECT_EQ(offset, FakeStack::FlagsOffset(stack_size_log, class_id));
- // printf("%zd: %zd => %zd %zd\n", stack_size_log, class_id, offset,
- // FakeStack::FlagsOffset(stack_size_log, class_id));
- offset += num_flags;
- }
- }
-}
-
-#if !defined(_WIN32) // FIXME: Fails due to OOM on Windows.
-TEST(FakeStack, CreateDestroy) {
- for (int i = 0; i < 1000; i++) {
- for (uptr stack_size_log = 20; stack_size_log <= 22; stack_size_log++) {
- FakeStack *fake_stack = FakeStack::Create(stack_size_log);
- fake_stack->Destroy(0);
- }
- }
-}
-#endif
-
-TEST(FakeStack, ModuloNumberOfFrames) {
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, 0), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<15)), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<10)), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<9)), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<8)), 1U<<8);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<15) + 1), 1U);
-
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 0), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 1<<9), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 1<<8), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 1<<7), 1U<<7);
-
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 0), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 1), 1U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 15), 15U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 16), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 17), 1U);
-}
-
-TEST(FakeStack, GetFrame) {
- const uptr stack_size_log = 20;
- const uptr stack_size = 1 << stack_size_log;
- FakeStack *fs = FakeStack::Create(stack_size_log);
- u8 *base = fs->GetFrame(stack_size_log, 0, 0);
- EXPECT_EQ(base, reinterpret_cast<u8 *>(fs) +
- fs->SizeRequiredForFlags(stack_size_log) + 4096);
- EXPECT_EQ(base + 0*stack_size + 64 * 7, fs->GetFrame(stack_size_log, 0, 7U));
- EXPECT_EQ(base + 1*stack_size + 128 * 3, fs->GetFrame(stack_size_log, 1, 3U));
- EXPECT_EQ(base + 2*stack_size + 256 * 5, fs->GetFrame(stack_size_log, 2, 5U));
- fs->Destroy(0);
-}
-
-TEST(FakeStack, Allocate) {
- const uptr stack_size_log = 19;
- FakeStack *fs = FakeStack::Create(stack_size_log);
- std::map<FakeFrame *, uptr> s;
- for (int iter = 0; iter < 2; iter++) {
- s.clear();
- for (uptr cid = 0; cid < FakeStack::kNumberOfSizeClasses; cid++) {
- uptr n = FakeStack::NumberOfFrames(stack_size_log, cid);
- uptr bytes_in_class = FakeStack::BytesInSizeClass(cid);
- for (uptr j = 0; j < n; j++) {
- FakeFrame *ff = fs->Allocate(stack_size_log, cid, 0);
- uptr x = reinterpret_cast<uptr>(ff);
- EXPECT_TRUE(s.insert(std::make_pair(ff, cid)).second);
- EXPECT_EQ(x, fs->AddrIsInFakeStack(x));
- EXPECT_EQ(x, fs->AddrIsInFakeStack(x + 1));
- EXPECT_EQ(x, fs->AddrIsInFakeStack(x + bytes_in_class - 1));
- EXPECT_NE(x, fs->AddrIsInFakeStack(x + bytes_in_class));
- }
- // We are out of fake stack, so Allocate should return 0.
- EXPECT_EQ(0UL, fs->Allocate(stack_size_log, cid, 0));
- }
- for (std::map<FakeFrame *, uptr>::iterator it = s.begin(); it != s.end();
- ++it) {
- fs->Deallocate(reinterpret_cast<uptr>(it->first), it->second);
- }
- }
- fs->Destroy(0);
-}
-
-static void RecursiveFunction(FakeStack *fs, int depth) {
- uptr class_id = depth / 3;
- FakeFrame *ff = fs->Allocate(fs->stack_size_log(), class_id, 0);
- if (depth) {
- RecursiveFunction(fs, depth - 1);
- RecursiveFunction(fs, depth - 1);
- }
- fs->Deallocate(reinterpret_cast<uptr>(ff), class_id);
-}
-
-TEST(FakeStack, RecursiveStressTest) {
- const uptr stack_size_log = 16;
- FakeStack *fs = FakeStack::Create(stack_size_log);
- RecursiveFunction(fs, 22); // with 26 runs for 2-3 seconds.
- fs->Destroy(0);
-}
-
-} // namespace __asan
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_globals_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_globals_test.cc
deleted file mode 100644
index 5042ef07378d..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_globals_test.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- asan_globals_test.cc ----------------------------------------------===//
-//
-// 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.
-//
-// Some globals in a separate file.
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-char glob1[1];
-char glob2[2];
-char glob3[3];
-char glob4[4];
-char glob5[5];
-char glob6[6];
-char glob7[7];
-char glob8[8];
-char glob9[9];
-char glob10[10];
-char glob11[11];
-char glob12[12];
-char glob13[13];
-char glob14[14];
-char glob15[15];
-char glob16[16];
-char glob17[17];
-char glob1000[1000];
-char glob10000[10000];
-char glob100000[100000];
-
-static char static10[10];
-
-int GlobalsTest(int zero) {
- static char func_static15[15];
- glob5[zero] = 0;
- static10[zero] = 0;
- func_static15[zero] = 0;
- return glob5[1] + func_static15[2];
-}
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_interface_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_interface_test.cc
deleted file mode 100644
index a34c8528eae0..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_interface_test.cc
+++ /dev/null
@@ -1,433 +0,0 @@
-//===-- asan_interface_test.cc --------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-#include <sanitizer/allocator_interface.h>
-#include <sanitizer/asan_interface.h>
-
-TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
- EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));
- const size_t sizes[] = { 1, 30, 1<<30 };
- for (size_t i = 0; i < 3; i++) {
- EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));
- }
-}
-
-static const char* kGetAllocatedSizeErrorMsg =
- "attempting to call __sanitizer_get_allocated_size";
-
-TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
- const size_t kArraySize = 100;
- char *array = Ident((char*)malloc(kArraySize));
- int *int_ptr = Ident(new int);
-
- // Allocated memory is owned by allocator. Allocated size should be
- // equal to requested size.
- EXPECT_EQ(true, __sanitizer_get_ownership(array));
- EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));
- EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));
- EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));
-
- // We cannot call GetAllocatedSize from the memory we didn't map,
- // and from the interior pointers (not returned by previous malloc).
- void *wild_addr = (void*)0x1;
- EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
- EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),
- kGetAllocatedSizeErrorMsg);
- EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));
- EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),
- kGetAllocatedSizeErrorMsg);
-
- // NULL is not owned, but is a valid argument for
- // __sanitizer_get_allocated_size().
- EXPECT_FALSE(__sanitizer_get_ownership(NULL));
- EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));
-
- // When memory is freed, it's not owned, and call to GetAllocatedSize
- // is forbidden.
- free(array);
- EXPECT_FALSE(__sanitizer_get_ownership(array));
- EXPECT_DEATH(__sanitizer_get_allocated_size(array),
- kGetAllocatedSizeErrorMsg);
- delete int_ptr;
-
- void *zero_alloc = Ident(malloc(0));
- if (zero_alloc != 0) {
- // If malloc(0) is not null, this pointer is owned and should have valid
- // allocated size.
- EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));
- // Allocated size is 0 or 1 depending on the allocator used.
- EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);
- }
- free(zero_alloc);
-}
-
-TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
- size_t before_malloc, after_malloc, after_free;
- char *array;
- const size_t kMallocSize = 100;
- before_malloc = __sanitizer_get_current_allocated_bytes();
-
- array = Ident((char*)malloc(kMallocSize));
- after_malloc = __sanitizer_get_current_allocated_bytes();
- EXPECT_EQ(before_malloc + kMallocSize, after_malloc);
-
- free(array);
- after_free = __sanitizer_get_current_allocated_bytes();
- EXPECT_EQ(before_malloc, after_free);
-}
-
-TEST(AddressSanitizerInterface, GetHeapSizeTest) {
- // ASan allocator does not keep huge chunks in free list, but unmaps them.
- // The chunk should be greater than the quarantine size,
- // otherwise it will be stuck in quarantine instead of being unmaped.
- static const size_t kLargeMallocSize = (1 << 28) + 1; // 256M
- free(Ident(malloc(kLargeMallocSize))); // Drain quarantine.
- size_t old_heap_size = __sanitizer_get_heap_size();
- for (int i = 0; i < 3; i++) {
- // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
- free(Ident(malloc(kLargeMallocSize)));
- EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());
- }
-}
-
-static const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};
-static const size_t kManyThreadsIterations = 250;
-static const size_t kManyThreadsNumThreads =
- (SANITIZER_WORDSIZE == 32) ? 40 : 200;
-
-static void *ManyThreadsWithStatsWorker(void *arg) {
- (void)arg;
- for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
- for (size_t size_index = 0; size_index < 4; size_index++) {
- free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
- }
- }
- // Just one large allocation.
- free(Ident(malloc(1 << 20)));
- return 0;
-}
-
-TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
- size_t before_test, after_test, i;
- pthread_t threads[kManyThreadsNumThreads];
- before_test = __sanitizer_get_current_allocated_bytes();
- for (i = 0; i < kManyThreadsNumThreads; i++) {
- PTHREAD_CREATE(&threads[i], 0,
- (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);
- }
- for (i = 0; i < kManyThreadsNumThreads; i++) {
- PTHREAD_JOIN(threads[i], 0);
- }
- after_test = __sanitizer_get_current_allocated_bytes();
- // ASan stats also reflect memory usage of internal ASan RTL structs,
- // so we can't check for equality here.
- EXPECT_LT(after_test, before_test + (1UL<<20));
-}
-
-static void DoDoubleFree() {
- int *x = Ident(new int);
- delete Ident(x);
- delete Ident(x);
-}
-
-TEST(AddressSanitizerInterface, ExitCode) {
- int original_exit_code = __asan_set_error_exit_code(7);
- EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(7), "");
- EXPECT_EQ(7, __asan_set_error_exit_code(8));
- EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(8), "");
- EXPECT_EQ(8, __asan_set_error_exit_code(original_exit_code));
- EXPECT_EXIT(DoDoubleFree(),
- ::testing::ExitedWithCode(original_exit_code), "");
-}
-
-static void MyDeathCallback() {
- fprintf(stderr, "MyDeathCallback\n");
- fflush(0); // On Windows, stderr doesn't flush on crash.
-}
-
-TEST(AddressSanitizerInterface, DeathCallbackTest) {
- __asan_set_death_callback(MyDeathCallback);
- EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback");
- __asan_set_death_callback(NULL);
-}
-
-static const char* kUseAfterPoisonErrorMessage = "use-after-poison";
-
-#define GOOD_ACCESS(ptr, offset) \
- EXPECT_FALSE(__asan_address_is_poisoned(ptr + offset))
-
-#define BAD_ACCESS(ptr, offset) \
- EXPECT_TRUE(__asan_address_is_poisoned(ptr + offset))
-
-TEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) {
- char *array = Ident((char*)malloc(120));
- // poison array[40..80)
- __asan_poison_memory_region(array + 40, 40);
- GOOD_ACCESS(array, 39);
- GOOD_ACCESS(array, 80);
- BAD_ACCESS(array, 40);
- BAD_ACCESS(array, 60);
- BAD_ACCESS(array, 79);
- char value;
- EXPECT_DEATH(value = Ident(array[40]), kUseAfterPoisonErrorMessage);
- __asan_unpoison_memory_region(array + 40, 40);
- // access previously poisoned memory.
- GOOD_ACCESS(array, 40);
- GOOD_ACCESS(array, 79);
- free(array);
-}
-
-TEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) {
- char *array = Ident((char*)malloc(120));
- // Poison [0..40) and [80..120)
- __asan_poison_memory_region(array, 40);
- __asan_poison_memory_region(array + 80, 40);
- BAD_ACCESS(array, 20);
- GOOD_ACCESS(array, 60);
- BAD_ACCESS(array, 100);
- // Poison whole array - [0..120)
- __asan_poison_memory_region(array, 120);
- BAD_ACCESS(array, 60);
- // Unpoison [24..96)
- __asan_unpoison_memory_region(array + 24, 72);
- BAD_ACCESS(array, 23);
- GOOD_ACCESS(array, 24);
- GOOD_ACCESS(array, 60);
- GOOD_ACCESS(array, 95);
- BAD_ACCESS(array, 96);
- free(array);
-}
-
-TEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) {
- // Vector of capacity 20
- char *vec = Ident((char*)malloc(20));
- __asan_poison_memory_region(vec, 20);
- for (size_t i = 0; i < 7; i++) {
- // Simulate push_back.
- __asan_unpoison_memory_region(vec + i, 1);
- GOOD_ACCESS(vec, i);
- BAD_ACCESS(vec, i + 1);
- }
- for (size_t i = 7; i > 0; i--) {
- // Simulate pop_back.
- __asan_poison_memory_region(vec + i - 1, 1);
- BAD_ACCESS(vec, i - 1);
- if (i > 1) GOOD_ACCESS(vec, i - 2);
- }
- free(vec);
-}
-
-// Make sure that each aligned block of size "2^granularity" doesn't have
-// "true" value before "false" value.
-static void MakeShadowValid(bool *shadow, int length, int granularity) {
- bool can_be_poisoned = true;
- for (int i = length - 1; i >= 0; i--) {
- if (!shadow[i])
- can_be_poisoned = false;
- if (!can_be_poisoned)
- shadow[i] = false;
- if (i % (1 << granularity) == 0) {
- can_be_poisoned = true;
- }
- }
-}
-
-TEST(AddressSanitizerInterface, PoisoningStressTest) {
- const size_t kSize = 24;
- bool expected[kSize];
- char *arr = Ident((char*)malloc(kSize));
- for (size_t l1 = 0; l1 < kSize; l1++) {
- for (size_t s1 = 1; l1 + s1 <= kSize; s1++) {
- for (size_t l2 = 0; l2 < kSize; l2++) {
- for (size_t s2 = 1; l2 + s2 <= kSize; s2++) {
- // Poison [l1, l1+s1), [l2, l2+s2) and check result.
- __asan_unpoison_memory_region(arr, kSize);
- __asan_poison_memory_region(arr + l1, s1);
- __asan_poison_memory_region(arr + l2, s2);
- memset(expected, false, kSize);
- memset(expected + l1, true, s1);
- MakeShadowValid(expected, kSize, /*granularity*/ 3);
- memset(expected + l2, true, s2);
- MakeShadowValid(expected, kSize, /*granularity*/ 3);
- for (size_t i = 0; i < kSize; i++) {
- ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
- }
- // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result.
- __asan_poison_memory_region(arr, kSize);
- __asan_unpoison_memory_region(arr + l1, s1);
- __asan_unpoison_memory_region(arr + l2, s2);
- memset(expected, true, kSize);
- memset(expected + l1, false, s1);
- MakeShadowValid(expected, kSize, /*granularity*/ 3);
- memset(expected + l2, false, s2);
- MakeShadowValid(expected, kSize, /*granularity*/ 3);
- for (size_t i = 0; i < kSize; i++) {
- ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
- }
- }
- }
- }
- }
- free(arr);
-}
-
-TEST(AddressSanitizerInterface, GlobalRedzones) {
- GOOD_ACCESS(glob1, 1 - 1);
- GOOD_ACCESS(glob2, 2 - 1);
- GOOD_ACCESS(glob3, 3 - 1);
- GOOD_ACCESS(glob4, 4 - 1);
- GOOD_ACCESS(glob5, 5 - 1);
- GOOD_ACCESS(glob6, 6 - 1);
- GOOD_ACCESS(glob7, 7 - 1);
- GOOD_ACCESS(glob8, 8 - 1);
- GOOD_ACCESS(glob9, 9 - 1);
- GOOD_ACCESS(glob10, 10 - 1);
- GOOD_ACCESS(glob11, 11 - 1);
- GOOD_ACCESS(glob12, 12 - 1);
- GOOD_ACCESS(glob13, 13 - 1);
- GOOD_ACCESS(glob14, 14 - 1);
- GOOD_ACCESS(glob15, 15 - 1);
- GOOD_ACCESS(glob16, 16 - 1);
- GOOD_ACCESS(glob17, 17 - 1);
- GOOD_ACCESS(glob1000, 1000 - 1);
- GOOD_ACCESS(glob10000, 10000 - 1);
- GOOD_ACCESS(glob100000, 100000 - 1);
-
- BAD_ACCESS(glob1, 1);
- BAD_ACCESS(glob2, 2);
- BAD_ACCESS(glob3, 3);
- BAD_ACCESS(glob4, 4);
- BAD_ACCESS(glob5, 5);
- BAD_ACCESS(glob6, 6);
- BAD_ACCESS(glob7, 7);
- BAD_ACCESS(glob8, 8);
- BAD_ACCESS(glob9, 9);
- BAD_ACCESS(glob10, 10);
- BAD_ACCESS(glob11, 11);
- BAD_ACCESS(glob12, 12);
- BAD_ACCESS(glob13, 13);
- BAD_ACCESS(glob14, 14);
- BAD_ACCESS(glob15, 15);
- BAD_ACCESS(glob16, 16);
- BAD_ACCESS(glob17, 17);
- BAD_ACCESS(glob1000, 1000);
- BAD_ACCESS(glob1000, 1100); // Redzone is at least 101 bytes.
- BAD_ACCESS(glob10000, 10000);
- BAD_ACCESS(glob10000, 11000); // Redzone is at least 1001 bytes.
- BAD_ACCESS(glob100000, 100000);
- BAD_ACCESS(glob100000, 110000); // Redzone is at least 10001 bytes.
-}
-
-TEST(AddressSanitizerInterface, PoisonedRegion) {
- size_t rz = 16;
- for (size_t size = 1; size <= 64; size++) {
- char *p = new char[size];
- for (size_t beg = 0; beg < size + rz; beg++) {
- for (size_t end = beg; end < size + rz; end++) {
- void *first_poisoned = __asan_region_is_poisoned(p + beg, end - beg);
- if (beg == end) {
- EXPECT_FALSE(first_poisoned);
- } else if (beg < size && end <= size) {
- EXPECT_FALSE(first_poisoned);
- } else if (beg >= size) {
- EXPECT_EQ(p + beg, first_poisoned);
- } else {
- EXPECT_GT(end, size);
- EXPECT_EQ(p + size, first_poisoned);
- }
- }
- }
- delete [] p;
- }
-}
-
-// This is a performance benchmark for manual runs.
-// asan's memset interceptor calls mem_is_zero for the entire shadow region.
-// the profile should look like this:
-// 89.10% [.] __memset_sse2
-// 10.50% [.] __sanitizer::mem_is_zero
-// I.e. mem_is_zero should consume ~ SHADOW_GRANULARITY less CPU cycles
-// than memset itself.
-TEST(AddressSanitizerInterface, DISABLED_StressLargeMemset) {
- size_t size = 1 << 20;
- char *x = new char[size];
- for (int i = 0; i < 100000; i++)
- Ident(memset)(x, 0, size);
- delete [] x;
-}
-
-// Same here, but we run memset with small sizes.
-TEST(AddressSanitizerInterface, DISABLED_StressSmallMemset) {
- size_t size = 32;
- char *x = new char[size];
- for (int i = 0; i < 100000000; i++)
- Ident(memset)(x, 0, size);
- delete [] x;
-}
-static const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
-static const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
-
-TEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {
- char *array = Ident((char*)malloc(120));
- __asan_unpoison_memory_region(array, 120);
- // Try to unpoison not owned memory
- EXPECT_DEATH(__asan_unpoison_memory_region(array, 121),
- kInvalidUnpoisonMessage);
- EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120),
- kInvalidUnpoisonMessage);
-
- __asan_poison_memory_region(array, 120);
- // Try to poison not owned memory.
- EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage);
- EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120),
- kInvalidPoisonMessage);
- free(array);
-}
-
-#if !defined(_WIN32) // FIXME: This should really be a lit test.
-static void ErrorReportCallbackOneToZ(const char *report) {
- int report_len = strlen(report);
- ASSERT_EQ(6, write(2, "ABCDEF", 6));
- ASSERT_EQ(report_len, write(2, report, report_len));
- ASSERT_EQ(6, write(2, "ABCDEF", 6));
- _exit(1);
-}
-
-TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) {
- __asan_set_error_report_callback(ErrorReportCallbackOneToZ);
- EXPECT_DEATH(__asan_report_error(0, 0, 0, 0, true, 1),
- ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF");
- __asan_set_error_report_callback(NULL);
-}
-#endif
-
-TEST(AddressSanitizerInterface, GetOwnershipStressTest) {
- std::vector<char *> pointers;
- std::vector<size_t> sizes;
- const size_t kNumMallocs = 1 << 9;
- for (size_t i = 0; i < kNumMallocs; i++) {
- size_t size = i * 100 + 1;
- pointers.push_back((char*)malloc(size));
- sizes.push_back(size);
- }
- for (size_t i = 0; i < 4000000; i++) {
- EXPECT_FALSE(__sanitizer_get_ownership(&pointers));
- EXPECT_FALSE(__sanitizer_get_ownership((void*)0x1234));
- size_t idx = i % kNumMallocs;
- EXPECT_TRUE(__sanitizer_get_ownership(pointers[idx]));
- EXPECT_EQ(sizes[idx], __sanitizer_get_allocated_size(pointers[idx]));
- }
- for (size_t i = 0, n = pointers.size(); i < n; i++)
- free(pointers[i]);
-}
-
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_mac_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_mac_test.cc
deleted file mode 100644
index cabdfd711ea2..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_mac_test.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-//===-- asan_test_mac.cc --------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-#include "asan_test_utils.h"
-
-#include "asan_mac_test.h"
-
-#include <malloc/malloc.h>
-#include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_*
-#include <CoreFoundation/CFString.h>
-
-TEST(AddressSanitizerMac, CFAllocatorDefaultDoubleFree) {
- EXPECT_DEATH(
- CFAllocatorDefaultDoubleFree(NULL),
- "attempting double-free");
-}
-
-void CFAllocator_DoubleFreeOnPthread() {
- pthread_t child;
- PTHREAD_CREATE(&child, NULL, CFAllocatorDefaultDoubleFree, NULL);
- PTHREAD_JOIN(child, NULL); // Shouldn't be reached.
-}
-
-TEST(AddressSanitizerMac, CFAllocatorDefaultDoubleFree_ChildPhread) {
- EXPECT_DEATH(CFAllocator_DoubleFreeOnPthread(), "attempting double-free");
-}
-
-namespace {
-
-void *GLOB;
-
-void *CFAllocatorAllocateToGlob(void *unused) {
- GLOB = CFAllocatorAllocate(NULL, 100, /*hint*/0);
- return NULL;
-}
-
-void *CFAllocatorDeallocateFromGlob(void *unused) {
- char *p = (char*)GLOB;
- p[100] = 'A'; // ASan should report an error here.
- CFAllocatorDeallocate(NULL, GLOB);
- return NULL;
-}
-
-void CFAllocator_PassMemoryToAnotherThread() {
- pthread_t th1, th2;
- PTHREAD_CREATE(&th1, NULL, CFAllocatorAllocateToGlob, NULL);
- PTHREAD_JOIN(th1, NULL);
- PTHREAD_CREATE(&th2, NULL, CFAllocatorDeallocateFromGlob, NULL);
- PTHREAD_JOIN(th2, NULL);
-}
-
-TEST(AddressSanitizerMac, CFAllocator_PassMemoryToAnotherThread) {
- EXPECT_DEATH(CFAllocator_PassMemoryToAnotherThread(),
- "heap-buffer-overflow");
-}
-
-} // namespace
-
-// TODO(glider): figure out whether we still need these tests. Is it correct
-// to intercept the non-default CFAllocators?
-TEST(AddressSanitizerMac, DISABLED_CFAllocatorSystemDefaultDoubleFree) {
- EXPECT_DEATH(
- CFAllocatorSystemDefaultDoubleFree(),
- "attempting double-free");
-}
-
-// We're intercepting malloc, so kCFAllocatorMalloc is routed to ASan.
-TEST(AddressSanitizerMac, CFAllocatorMallocDoubleFree) {
- EXPECT_DEATH(CFAllocatorMallocDoubleFree(), "attempting double-free");
-}
-
-TEST(AddressSanitizerMac, DISABLED_CFAllocatorMallocZoneDoubleFree) {
- EXPECT_DEATH(CFAllocatorMallocZoneDoubleFree(), "attempting double-free");
-}
-
-// For libdispatch tests below we check that ASan got to the shadow byte
-// legend, i.e. managed to print the thread stacks (this almost certainly
-// means that the libdispatch task creation has been intercepted correctly).
-TEST(AddressSanitizerMac, GCDDispatchAsync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDDispatchAsync(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDDispatchSync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDDispatchSync(), "Shadow byte legend");
-}
-
-
-TEST(AddressSanitizerMac, GCDReuseWqthreadsAsync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDReuseWqthreadsAsync(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDReuseWqthreadsSync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDReuseWqthreadsSync(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDDispatchAfter) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDDispatchAfter(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDSourceEvent) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDSourceEvent(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDSourceCancel) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDSourceCancel(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDGroupAsync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDGroupAsync(), "Shadow byte legend");
-}
-
-void *MallocIntrospectionLockWorker(void *_) {
- const int kNumPointers = 100;
- int i;
- void *pointers[kNumPointers];
- for (i = 0; i < kNumPointers; i++) {
- pointers[i] = malloc(i + 1);
- }
- for (i = 0; i < kNumPointers; i++) {
- free(pointers[i]);
- }
-
- return NULL;
-}
-
-void *MallocIntrospectionLockForker(void *_) {
- pid_t result = fork();
- if (result == -1) {
- perror("fork");
- }
- assert(result != -1);
- if (result == 0) {
- // Call malloc in the child process to make sure we won't deadlock.
- void *ptr = malloc(42);
- free(ptr);
- exit(0);
- } else {
- // Return in the parent process.
- return NULL;
- }
-}
-
-TEST(AddressSanitizerMac, MallocIntrospectionLock) {
- // Incorrect implementation of force_lock and force_unlock in our malloc zone
- // will cause forked processes to deadlock.
- // TODO(glider): need to detect that none of the child processes deadlocked.
- const int kNumWorkers = 5, kNumIterations = 100;
- int i, iter;
- for (iter = 0; iter < kNumIterations; iter++) {
- pthread_t workers[kNumWorkers], forker;
- for (i = 0; i < kNumWorkers; i++) {
- PTHREAD_CREATE(&workers[i], 0, MallocIntrospectionLockWorker, 0);
- }
- PTHREAD_CREATE(&forker, 0, MallocIntrospectionLockForker, 0);
- for (i = 0; i < kNumWorkers; i++) {
- PTHREAD_JOIN(workers[i], 0);
- }
- PTHREAD_JOIN(forker, 0);
- }
-}
-
-void *TSDAllocWorker(void *test_key) {
- if (test_key) {
- void *mem = malloc(10);
- pthread_setspecific(*(pthread_key_t*)test_key, mem);
- }
- return NULL;
-}
-
-TEST(AddressSanitizerMac, DISABLED_TSDWorkqueueTest) {
- pthread_t th;
- pthread_key_t test_key;
- pthread_key_create(&test_key, CallFreeOnWorkqueue);
- PTHREAD_CREATE(&th, NULL, TSDAllocWorker, &test_key);
- PTHREAD_JOIN(th, NULL);
- pthread_key_delete(test_key);
-}
-
-// Test that CFStringCreateCopy does not copy constant strings.
-TEST(AddressSanitizerMac, CFStringCreateCopy) {
- CFStringRef str = CFSTR("Hello world!\n");
- CFStringRef str2 = CFStringCreateCopy(0, str);
- EXPECT_EQ(str, str2);
-}
-
-TEST(AddressSanitizerMac, NSObjectOOB) {
- // Make sure that our allocators are used for NSObjects.
- EXPECT_DEATH(TestOOBNSObjects(), "heap-buffer-overflow");
-}
-
-// Make sure that correct pointer is passed to free() when deallocating a
-// NSURL object.
-// See http://code.google.com/p/address-sanitizer/issues/detail?id=70.
-TEST(AddressSanitizerMac, NSURLDeallocation) {
- TestNSURLDeallocation();
-}
-
-// See http://code.google.com/p/address-sanitizer/issues/detail?id=109.
-TEST(AddressSanitizerMac, Mstats) {
- malloc_statistics_t stats1, stats2;
- malloc_zone_statistics(/*all zones*/NULL, &stats1);
- const size_t kMallocSize = 100000;
- void *alloc = Ident(malloc(kMallocSize));
- malloc_zone_statistics(/*all zones*/NULL, &stats2);
- EXPECT_GT(stats2.blocks_in_use, stats1.blocks_in_use);
- EXPECT_GE(stats2.size_in_use - stats1.size_in_use, kMallocSize);
- free(alloc);
- // Even the default OSX allocator may not change the stats after free().
-}
-
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_mac_test.h b/contrib/compiler-rt/lib/asan/tests/asan_mac_test.h
deleted file mode 100644
index 441547a5a3dc..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_mac_test.h
+++ /dev/null
@@ -1,19 +0,0 @@
-extern "C" {
- void *CFAllocatorDefaultDoubleFree(void *unused);
- void CFAllocatorSystemDefaultDoubleFree();
- void CFAllocatorMallocDoubleFree();
- void CFAllocatorMallocZoneDoubleFree();
- void CallFreeOnWorkqueue(void *mem);
- void TestGCDDispatchAsync();
- void TestGCDDispatchSync();
- void TestGCDReuseWqthreadsAsync();
- void TestGCDReuseWqthreadsSync();
- void TestGCDDispatchAfter();
- void TestGCDInTSDDestructor();
- void TestGCDSourceEvent();
- void TestGCDSourceCancel();
- void TestGCDGroupAsync();
- void TestOOBNSObjects();
- void TestNSURLDeallocation();
- void TestPassCFMemoryToAnotherThread();
-}
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_mac_test_helpers.mm b/contrib/compiler-rt/lib/asan/tests/asan_mac_test_helpers.mm
deleted file mode 100644
index a7e4b9d1928b..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_mac_test_helpers.mm
+++ /dev/null
@@ -1,240 +0,0 @@
-// Mac OS X 10.6 or higher only.
-#include <dispatch/dispatch.h>
-#include <pthread.h> // for pthread_yield_np()
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#import <CoreFoundation/CFBase.h>
-#import <Foundation/NSObject.h>
-#import <Foundation/NSURL.h>
-
-// This is a (void*)(void*) function so it can be passed to pthread_create.
-void *CFAllocatorDefaultDoubleFree(void *unused) {
- void *mem = CFAllocatorAllocate(kCFAllocatorDefault, 5, 0);
- CFAllocatorDeallocate(kCFAllocatorDefault, mem);
- CFAllocatorDeallocate(kCFAllocatorDefault, mem);
- return 0;
-}
-
-void CFAllocatorSystemDefaultDoubleFree() {
- void *mem = CFAllocatorAllocate(kCFAllocatorSystemDefault, 5, 0);
- CFAllocatorDeallocate(kCFAllocatorSystemDefault, mem);
- CFAllocatorDeallocate(kCFAllocatorSystemDefault, mem);
-}
-
-void CFAllocatorMallocDoubleFree() {
- void *mem = CFAllocatorAllocate(kCFAllocatorMalloc, 5, 0);
- CFAllocatorDeallocate(kCFAllocatorMalloc, mem);
- CFAllocatorDeallocate(kCFAllocatorMalloc, mem);
-}
-
-void CFAllocatorMallocZoneDoubleFree() {
- void *mem = CFAllocatorAllocate(kCFAllocatorMallocZone, 5, 0);
- CFAllocatorDeallocate(kCFAllocatorMallocZone, mem);
- CFAllocatorDeallocate(kCFAllocatorMallocZone, mem);
-}
-
-__attribute__((noinline))
-void access_memory(char *a) {
- *a = 0;
-}
-
-// Test the +load instrumentation.
-// Because the +load methods are invoked before anything else is initialized,
-// it makes little sense to wrap the code below into a gTest test case.
-// If AddressSanitizer doesn't instrument the +load method below correctly,
-// everything will just crash.
-
-char kStartupStr[] =
- "If your test didn't crash, AddressSanitizer is instrumenting "
- "the +load methods correctly.";
-
-@interface LoadSomething : NSObject {
-}
-@end
-
-@implementation LoadSomething
-
-+(void) load {
- for (size_t i = 0; i < strlen(kStartupStr); i++) {
- access_memory(&kStartupStr[i]); // make sure no optimizations occur.
- }
- // Don't print anything here not to interfere with the death tests.
-}
-
-@end
-
-void worker_do_alloc(int size) {
- char * volatile mem = (char * volatile)malloc(size);
- mem[0] = 0; // Ok
- free(mem);
-}
-
-void worker_do_crash(int size) {
- char * volatile mem = (char * volatile)malloc(size);
- access_memory(&mem[size]); // BOOM
- free(mem);
-}
-
-// Used by the GCD tests to avoid a race between the worker thread reporting a
-// memory error and the main thread which may exit with exit code 0 before
-// that.
-void wait_forever() {
- volatile bool infinite = true;
- while (infinite) pthread_yield_np();
-}
-
-// Tests for the Grand Central Dispatch. See
-// http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
-// for the reference.
-void TestGCDDispatchAsync() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_block_t block = ^{ worker_do_crash(1024); };
- // dispatch_async() runs the task on a worker thread that does not go through
- // pthread_create(). We need to verify that AddressSanitizer notices that the
- // thread has started.
- dispatch_async(queue, block);
- wait_forever();
-}
-
-void TestGCDDispatchSync() {
- dispatch_queue_t queue = dispatch_get_global_queue(2, 0);
- dispatch_block_t block = ^{ worker_do_crash(1024); };
- // dispatch_sync() runs the task on a worker thread that does not go through
- // pthread_create(). We need to verify that AddressSanitizer notices that the
- // thread has started.
- dispatch_sync(queue, block);
- wait_forever();
-}
-
-// libdispatch spawns a rather small number of threads and reuses them. We need
-// to make sure AddressSanitizer handles the reusing correctly.
-void TestGCDReuseWqthreadsAsync() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_block_t block_alloc = ^{ worker_do_alloc(1024); };
- dispatch_block_t block_crash = ^{ worker_do_crash(1024); };
- for (int i = 0; i < 100; i++) {
- dispatch_async(queue, block_alloc);
- }
- dispatch_async(queue, block_crash);
- wait_forever();
-}
-
-// Try to trigger abnormal behaviour of dispatch_sync() being unhandled by us.
-void TestGCDReuseWqthreadsSync() {
- dispatch_queue_t queue[4];
- queue[0] = dispatch_get_global_queue(2, 0);
- queue[1] = dispatch_get_global_queue(0, 0);
- queue[2] = dispatch_get_global_queue(-2, 0);
- queue[3] = dispatch_queue_create("my_queue", NULL);
- dispatch_block_t block_alloc = ^{ worker_do_alloc(1024); };
- dispatch_block_t block_crash = ^{ worker_do_crash(1024); };
- for (int i = 0; i < 1000; i++) {
- dispatch_sync(queue[i % 4], block_alloc);
- }
- dispatch_sync(queue[3], block_crash);
- wait_forever();
-}
-
-void TestGCDDispatchAfter() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_block_t block_crash = ^{ worker_do_crash(1024); };
- // Schedule the event one second from the current time.
- dispatch_time_t milestone =
- dispatch_time(DISPATCH_TIME_NOW, 1LL * NSEC_PER_SEC);
- dispatch_after(milestone, queue, block_crash);
- wait_forever();
-}
-
-void worker_do_deallocate(void *ptr) {
- free(ptr);
-}
-
-void CallFreeOnWorkqueue(void *tsd) {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_block_t block_dealloc = ^{ worker_do_deallocate(tsd); };
- dispatch_async(queue, block_dealloc);
- // Do not wait for the worker to free the memory -- nobody is going to touch
- // it.
-}
-
-void TestGCDSourceEvent() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_source_t timer =
- dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
- // Schedule the timer one second from the current time.
- dispatch_time_t milestone =
- dispatch_time(DISPATCH_TIME_NOW, 1LL * NSEC_PER_SEC);
-
- dispatch_source_set_timer(timer, milestone, DISPATCH_TIME_FOREVER, 0);
- char * volatile mem = (char * volatile)malloc(10);
- dispatch_source_set_event_handler(timer, ^{
- access_memory(&mem[10]);
- });
- dispatch_resume(timer);
- wait_forever();
-}
-
-void TestGCDSourceCancel() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_source_t timer =
- dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
- // Schedule the timer one second from the current time.
- dispatch_time_t milestone =
- dispatch_time(DISPATCH_TIME_NOW, 1LL * NSEC_PER_SEC);
-
- dispatch_source_set_timer(timer, milestone, DISPATCH_TIME_FOREVER, 0);
- char * volatile mem = (char * volatile)malloc(10);
- // Both dispatch_source_set_cancel_handler() and
- // dispatch_source_set_event_handler() use dispatch_barrier_async_f().
- // It's tricky to test dispatch_source_set_cancel_handler() separately,
- // so we test both here.
- dispatch_source_set_event_handler(timer, ^{
- dispatch_source_cancel(timer);
- });
- dispatch_source_set_cancel_handler(timer, ^{
- access_memory(&mem[10]);
- });
- dispatch_resume(timer);
- wait_forever();
-}
-
-void TestGCDGroupAsync() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_group_t group = dispatch_group_create();
- char * volatile mem = (char * volatile)malloc(10);
- dispatch_group_async(group, queue, ^{
- access_memory(&mem[10]);
- });
- dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
- wait_forever();
-}
-
-@interface FixedArray : NSObject {
- int items[10];
-}
-@end
-
-@implementation FixedArray
--(int) access: (int)index {
- return items[index];
-}
-@end
-
-void TestOOBNSObjects() {
- id anObject = [FixedArray new];
- [anObject access:1];
- [anObject access:11];
- [anObject release];
-}
-
-void TestNSURLDeallocation() {
- NSURL *base =
- [[NSURL alloc] initWithString:@"file://localhost/Users/glider/Library/"];
- volatile NSURL *u =
- [[NSURL alloc] initWithString:@"Saved Application State"
- relativeToURL:base];
- [u release];
-}
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_mem_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_mem_test.cc
deleted file mode 100644
index 4a941faa0430..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_mem_test.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-//===-- asan_mem_test.cc --------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-template<typename T>
-void MemSetOOBTestTemplate(size_t length) {
- if (length == 0) return;
- size_t size = Ident(sizeof(T) * length);
- T *array = Ident((T*)malloc(size));
- int element = Ident(42);
- int zero = Ident(0);
- void *(*MEMSET)(void *s, int c, size_t n) = Ident(memset);
- // memset interval inside array
- MEMSET(array, element, size);
- MEMSET(array, element, size - 1);
- MEMSET(array + length - 1, element, sizeof(T));
- MEMSET(array, element, 1);
-
- // memset 0 bytes
- MEMSET(array - 10, element, zero);
- MEMSET(array - 1, element, zero);
- MEMSET(array, element, zero);
- MEMSET(array + length, 0, zero);
- MEMSET(array + length + 1, 0, zero);
-
- // try to memset bytes to the right of array
- EXPECT_DEATH(MEMSET(array, 0, size + 1),
- RightOOBWriteMessage(0));
- EXPECT_DEATH(MEMSET((char*)(array + length) - 1, element, 6),
- RightOOBWriteMessage(0));
- EXPECT_DEATH(MEMSET(array + 1, element, size + sizeof(T)),
- RightOOBWriteMessage(0));
- // whole interval is to the right
- EXPECT_DEATH(MEMSET(array + length + 1, 0, 10),
- RightOOBWriteMessage(sizeof(T)));
-
- // try to memset bytes to the left of array
- EXPECT_DEATH(MEMSET((char*)array - 1, element, size),
- LeftOOBWriteMessage(1));
- EXPECT_DEATH(MEMSET((char*)array - 5, 0, 6),
- LeftOOBWriteMessage(5));
- if (length >= 100) {
- // Large OOB, we find it only if the redzone is large enough.
- EXPECT_DEATH(memset(array - 5, element, size + 5 * sizeof(T)),
- LeftOOBWriteMessage(5 * sizeof(T)));
- }
- // whole interval is to the left
- EXPECT_DEATH(MEMSET(array - 2, 0, sizeof(T)),
- LeftOOBWriteMessage(2 * sizeof(T)));
-
- // try to memset bytes both to the left & to the right
- EXPECT_DEATH(MEMSET((char*)array - 2, element, size + 4),
- LeftOOBWriteMessage(2));
-
- free(array);
-}
-
-TEST(AddressSanitizer, MemSetOOBTest) {
- MemSetOOBTestTemplate<char>(100);
- MemSetOOBTestTemplate<int>(5);
- MemSetOOBTestTemplate<double>(256);
- // We can test arrays of structres/classes here, but what for?
-}
-
-// Try to allocate two arrays of 'size' bytes that are near each other.
-// Strictly speaking we are not guaranteed to find such two pointers,
-// but given the structure of asan's allocator we will.
-static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) {
- vector<uintptr_t> v;
- bool res = false;
- for (size_t i = 0; i < 1000U && !res; i++) {
- v.push_back(reinterpret_cast<uintptr_t>(new char[size]));
- if (i == 0) continue;
- sort(v.begin(), v.end());
- for (size_t j = 1; j < v.size(); j++) {
- assert(v[j] > v[j-1]);
- if ((size_t)(v[j] - v[j-1]) < size * 2) {
- *x2 = reinterpret_cast<char*>(v[j]);
- *x1 = reinterpret_cast<char*>(v[j-1]);
- res = true;
- break;
- }
- }
- }
-
- for (size_t i = 0; i < v.size(); i++) {
- char *p = reinterpret_cast<char *>(v[i]);
- if (res && p == *x1) continue;
- if (res && p == *x2) continue;
- delete [] p;
- }
- return res;
-}
-
-TEST(AddressSanitizer, LargeOOBInMemset) {
- for (size_t size = 200; size < 100000; size += size / 2) {
- char *x1, *x2;
- if (!Ident(AllocateTwoAdjacentArrays)(&x1, &x2, size))
- continue;
- // fprintf(stderr, " large oob memset: %p %p %zd\n", x1, x2, size);
- // Do a memset on x1 with huge out-of-bound access that will end up in x2.
- EXPECT_DEATH(Ident(memset)(x1, 0, size * 2),
- "is located 0 bytes to the right");
- delete [] x1;
- delete [] x2;
- return;
- }
- assert(0 && "Did not find two adjacent malloc-ed pointers");
-}
-
-// Same test for memcpy and memmove functions
-template <typename T, class M>
-void MemTransferOOBTestTemplate(size_t length) {
- if (length == 0) return;
- size_t size = Ident(sizeof(T) * length);
- T *src = Ident((T*)malloc(size));
- T *dest = Ident((T*)malloc(size));
- int zero = Ident(0);
-
- // valid transfer of bytes between arrays
- M::transfer(dest, src, size);
- M::transfer(dest + 1, src, size - sizeof(T));
- M::transfer(dest, src + length - 1, sizeof(T));
- M::transfer(dest, src, 1);
-
- // transfer zero bytes
- M::transfer(dest - 1, src, 0);
- M::transfer(dest + length, src, zero);
- M::transfer(dest, src - 1, zero);
- M::transfer(dest, src, zero);
-
- // try to change mem to the right of dest
- EXPECT_DEATH(M::transfer(dest + 1, src, size),
- RightOOBWriteMessage(0));
- EXPECT_DEATH(M::transfer((char*)(dest + length) - 1, src, 5),
- RightOOBWriteMessage(0));
-
- // try to change mem to the left of dest
- EXPECT_DEATH(M::transfer(dest - 2, src, size),
- LeftOOBWriteMessage(2 * sizeof(T)));
- EXPECT_DEATH(M::transfer((char*)dest - 3, src, 4),
- LeftOOBWriteMessage(3));
-
- // try to access mem to the right of src
- EXPECT_DEATH(M::transfer(dest, src + 2, size),
- RightOOBReadMessage(0));
- EXPECT_DEATH(M::transfer(dest, (char*)(src + length) - 3, 6),
- RightOOBReadMessage(0));
-
- // try to access mem to the left of src
- EXPECT_DEATH(M::transfer(dest, src - 1, size),
- LeftOOBReadMessage(sizeof(T)));
- EXPECT_DEATH(M::transfer(dest, (char*)src - 6, 7),
- LeftOOBReadMessage(6));
-
- // Generally we don't need to test cases where both accessing src and writing
- // to dest address to poisoned memory.
-
- T *big_src = Ident((T*)malloc(size * 2));
- T *big_dest = Ident((T*)malloc(size * 2));
- // try to change mem to both sides of dest
- EXPECT_DEATH(M::transfer(dest - 1, big_src, size * 2),
- LeftOOBWriteMessage(sizeof(T)));
- // try to access mem to both sides of src
- EXPECT_DEATH(M::transfer(big_dest, src - 2, size * 2),
- LeftOOBReadMessage(2 * sizeof(T)));
-
- free(src);
- free(dest);
- free(big_src);
- free(big_dest);
-}
-
-class MemCpyWrapper {
- public:
- static void* transfer(void *to, const void *from, size_t size) {
- return Ident(memcpy)(to, from, size);
- }
-};
-
-TEST(AddressSanitizer, MemCpyOOBTest) {
- MemTransferOOBTestTemplate<char, MemCpyWrapper>(100);
- MemTransferOOBTestTemplate<int, MemCpyWrapper>(1024);
-}
-
-class MemMoveWrapper {
- public:
- static void* transfer(void *to, const void *from, size_t size) {
- return Ident(memmove)(to, from, size);
- }
-};
-
-TEST(AddressSanitizer, MemMoveOOBTest) {
- MemTransferOOBTestTemplate<char, MemMoveWrapper>(100);
- MemTransferOOBTestTemplate<int, MemMoveWrapper>(1024);
-}
-
-
-TEST(AddressSanitizer, MemCmpOOBTest) {
- size_t size = Ident(100);
- char *s1 = MallocAndMemsetString(size);
- char *s2 = MallocAndMemsetString(size);
- // Normal memcmp calls.
- Ident(memcmp(s1, s2, size));
- Ident(memcmp(s1 + size - 1, s2 + size - 1, 1));
- Ident(memcmp(s1 - 1, s2 - 1, 0));
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(Ident(memcmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(memcmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(memcmp)(s1 + size, s2, 1), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(memcmp)(s1, s2 + size, 1), RightOOBReadMessage(0));
- // Hit unallocated memory and die.
- EXPECT_DEATH(Ident(memcmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(memcmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
- // Zero bytes are not terminators and don't prevent from OOB.
- s1[size - 1] = '\0';
- s2[size - 1] = '\0';
- EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
-
- // Even if the buffers differ in the first byte, we still assume that
- // memcmp may access the whole buffer and thus reporting the overflow here:
- s1[0] = 1;
- s2[0] = 123;
- EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
-
- free(s1);
- free(s2);
-}
-
-
-
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_noinst_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_noinst_test.cc
deleted file mode 100644
index 6a428fbbc2b9..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_noinst_test.cc
+++ /dev/null
@@ -1,263 +0,0 @@
-//===-- asan_noinst_test.cc -----------------------------------------------===//
-//
-// 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.
-//
-// This test file should be compiled w/o asan instrumentation.
-//===----------------------------------------------------------------------===//
-
-#include "asan_allocator.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "asan_test_utils.h"
-#include <sanitizer/allocator_interface.h>
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h> // for memset()
-#include <algorithm>
-#include <vector>
-#include <limits>
-
-// ATTENTION!
-// Please don't call intercepted functions (including malloc() and friends)
-// in this test. The static runtime library is linked explicitly (without
-// -fsanitize=address), thus the interceptors do not work correctly on OS X.
-
-// Make sure __asan_init is called before any test case is run.
-struct AsanInitCaller {
- AsanInitCaller() {
- __asan::DisableReexec();
- __asan_init();
- }
-};
-static AsanInitCaller asan_init_caller;
-
-TEST(AddressSanitizer, InternalSimpleDeathTest) {
- EXPECT_DEATH(exit(1), "");
-}
-
-static void MallocStress(size_t n) {
- u32 seed = my_rand();
- BufferedStackTrace stack1;
- stack1.trace_buffer[0] = 0xa123;
- stack1.trace_buffer[1] = 0xa456;
- stack1.size = 2;
-
- BufferedStackTrace stack2;
- stack2.trace_buffer[0] = 0xb123;
- stack2.trace_buffer[1] = 0xb456;
- stack2.size = 2;
-
- BufferedStackTrace stack3;
- stack3.trace_buffer[0] = 0xc123;
- stack3.trace_buffer[1] = 0xc456;
- stack3.size = 2;
-
- std::vector<void *> vec;
- for (size_t i = 0; i < n; i++) {
- if ((i % 3) == 0) {
- if (vec.empty()) continue;
- size_t idx = my_rand_r(&seed) % vec.size();
- void *ptr = vec[idx];
- vec[idx] = vec.back();
- vec.pop_back();
- __asan::asan_free(ptr, &stack1, __asan::FROM_MALLOC);
- } else {
- size_t size = my_rand_r(&seed) % 1000 + 1;
- switch ((my_rand_r(&seed) % 128)) {
- case 0: size += 1024; break;
- case 1: size += 2048; break;
- case 2: size += 4096; break;
- }
- size_t alignment = 1 << (my_rand_r(&seed) % 10 + 1);
- char *ptr = (char*)__asan::asan_memalign(alignment, size,
- &stack2, __asan::FROM_MALLOC);
- EXPECT_EQ(size, __asan::asan_malloc_usable_size(ptr, 0, 0));
- vec.push_back(ptr);
- ptr[0] = 0;
- ptr[size-1] = 0;
- ptr[size/2] = 0;
- }
- }
- for (size_t i = 0; i < vec.size(); i++)
- __asan::asan_free(vec[i], &stack3, __asan::FROM_MALLOC);
-}
-
-
-TEST(AddressSanitizer, NoInstMallocTest) {
- MallocStress(ASAN_LOW_MEMORY ? 300000 : 1000000);
-}
-
-TEST(AddressSanitizer, ThreadedMallocStressTest) {
- const int kNumThreads = 4;
- const int kNumIterations = (ASAN_LOW_MEMORY) ? 10000 : 100000;
- pthread_t t[kNumThreads];
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_CREATE(&t[i], 0, (void* (*)(void *x))MallocStress,
- (void*)kNumIterations);
- }
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_JOIN(t[i], 0);
- }
-}
-
-static void PrintShadow(const char *tag, uptr ptr, size_t size) {
- fprintf(stderr, "%s shadow: %lx size % 3ld: ", tag, (long)ptr, (long)size);
- uptr prev_shadow = 0;
- for (sptr i = -32; i < (sptr)size + 32; i++) {
- uptr shadow = __asan::MemToShadow(ptr + i);
- if (i == 0 || i == (sptr)size)
- fprintf(stderr, ".");
- if (shadow != prev_shadow) {
- prev_shadow = shadow;
- fprintf(stderr, "%02x", (int)*(u8*)shadow);
- }
- }
- fprintf(stderr, "\n");
-}
-
-TEST(AddressSanitizer, DISABLED_InternalPrintShadow) {
- for (size_t size = 1; size <= 513; size++) {
- char *ptr = new char[size];
- PrintShadow("m", (uptr)ptr, size);
- delete [] ptr;
- PrintShadow("f", (uptr)ptr, size);
- }
-}
-
-TEST(AddressSanitizer, QuarantineTest) {
- BufferedStackTrace stack;
- stack.trace_buffer[0] = 0x890;
- stack.size = 1;
-
- const int size = 1024;
- void *p = __asan::asan_malloc(size, &stack);
- __asan::asan_free(p, &stack, __asan::FROM_MALLOC);
- size_t i;
- size_t max_i = 1 << 30;
- for (i = 0; i < max_i; i++) {
- void *p1 = __asan::asan_malloc(size, &stack);
- __asan::asan_free(p1, &stack, __asan::FROM_MALLOC);
- if (p1 == p) break;
- }
- EXPECT_GE(i, 10000U);
- EXPECT_LT(i, max_i);
-}
-
-void *ThreadedQuarantineTestWorker(void *unused) {
- (void)unused;
- u32 seed = my_rand();
- BufferedStackTrace stack;
- stack.trace_buffer[0] = 0x890;
- stack.size = 1;
-
- for (size_t i = 0; i < 1000; i++) {
- void *p = __asan::asan_malloc(1 + (my_rand_r(&seed) % 4000), &stack);
- __asan::asan_free(p, &stack, __asan::FROM_MALLOC);
- }
- return NULL;
-}
-
-// Check that the thread local allocators are flushed when threads are
-// destroyed.
-TEST(AddressSanitizer, ThreadedQuarantineTest) {
- const int n_threads = 3000;
- size_t mmaped1 = __sanitizer_get_heap_size();
- for (int i = 0; i < n_threads; i++) {
- pthread_t t;
- PTHREAD_CREATE(&t, NULL, ThreadedQuarantineTestWorker, 0);
- PTHREAD_JOIN(t, 0);
- size_t mmaped2 = __sanitizer_get_heap_size();
- EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20));
- }
-}
-
-void *ThreadedOneSizeMallocStress(void *unused) {
- (void)unused;
- BufferedStackTrace stack;
- stack.trace_buffer[0] = 0x890;
- stack.size = 1;
- const size_t kNumMallocs = 1000;
- for (int iter = 0; iter < 1000; iter++) {
- void *p[kNumMallocs];
- for (size_t i = 0; i < kNumMallocs; i++) {
- p[i] = __asan::asan_malloc(32, &stack);
- }
- for (size_t i = 0; i < kNumMallocs; i++) {
- __asan::asan_free(p[i], &stack, __asan::FROM_MALLOC);
- }
- }
- return NULL;
-}
-
-TEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) {
- const int kNumThreads = 4;
- pthread_t t[kNumThreads];
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_CREATE(&t[i], 0, ThreadedOneSizeMallocStress, 0);
- }
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_JOIN(t[i], 0);
- }
-}
-
-TEST(AddressSanitizer, ShadowRegionIsPoisonedTest) {
- using __asan::kHighMemEnd;
- // Check that __asan_region_is_poisoned works for shadow regions.
- uptr ptr = kLowShadowBeg + 200;
- EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));
- ptr = kShadowGapBeg + 200;
- EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));
- ptr = kHighShadowBeg + 200;
- EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));
-}
-
-// Test __asan_load1 & friends.
-TEST(AddressSanitizer, LoadStoreCallbacks) {
- typedef void (*CB)(uptr p);
- CB cb[2][5] = {
- {
- __asan_load1, __asan_load2, __asan_load4, __asan_load8, __asan_load16,
- }, {
- __asan_store1, __asan_store2, __asan_store4, __asan_store8,
- __asan_store16,
- }
- };
-
- uptr buggy_ptr;
-
- __asan_test_only_reported_buggy_pointer = &buggy_ptr;
- BufferedStackTrace stack;
- stack.trace_buffer[0] = 0x890;
- stack.size = 1;
-
- for (uptr len = 16; len <= 32; len++) {
- char *ptr = (char*) __asan::asan_malloc(len, &stack);
- uptr p = reinterpret_cast<uptr>(ptr);
- for (uptr is_write = 0; is_write <= 1; is_write++) {
- for (uptr size_log = 0; size_log <= 4; size_log++) {
- uptr size = 1 << size_log;
- CB call = cb[is_write][size_log];
- // Iterate only size-aligned offsets.
- for (uptr offset = 0; offset <= len; offset += size) {
- buggy_ptr = 0;
- call(p + offset);
- if (offset + size <= len)
- EXPECT_EQ(buggy_ptr, 0U);
- else
- EXPECT_EQ(buggy_ptr, p + offset);
- }
- }
- }
- __asan::asan_free(ptr, &stack, __asan::FROM_MALLOC);
- }
- __asan_test_only_reported_buggy_pointer = 0;
-}
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_oob_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_oob_test.cc
deleted file mode 100644
index 0c6bea285864..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_oob_test.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-//===-- asan_oob_test.cc --------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-NOINLINE void asan_write_sized_aligned(uint8_t *p, size_t size) {
- EXPECT_EQ(0U, ((uintptr_t)p % size));
- if (size == 1) asan_write((uint8_t*)p);
- else if (size == 2) asan_write((uint16_t*)p);
- else if (size == 4) asan_write((uint32_t*)p);
- else if (size == 8) asan_write((uint64_t*)p);
-}
-
-template<typename T>
-NOINLINE void oob_test(int size, int off) {
- char *p = (char*)malloc_aaa(size);
- // fprintf(stderr, "writing %d byte(s) into [%p,%p) with offset %d\n",
- // sizeof(T), p, p + size, off);
- asan_write((T*)(p + off));
- free_aaa(p);
-}
-
-template<typename T>
-void OOBTest() {
- char expected_str[100];
- for (int size = sizeof(T); size < 20; size += 5) {
- for (int i = -5; i < 0; i++) {
- const char *str =
- "is located.*%d byte.*to the left";
- sprintf(expected_str, str, abs(i));
- EXPECT_DEATH(oob_test<T>(size, i), expected_str);
- }
-
- for (int i = 0; i < (int)(size - sizeof(T) + 1); i++)
- oob_test<T>(size, i);
-
- for (int i = size - sizeof(T) + 1; i <= (int)(size + 2 * sizeof(T)); i++) {
- const char *str =
- "is located.*%d byte.*to the right";
- int off = i >= size ? (i - size) : 0;
- // we don't catch unaligned partially OOB accesses.
- if (i % sizeof(T)) continue;
- sprintf(expected_str, str, off);
- EXPECT_DEATH(oob_test<T>(size, i), expected_str);
- }
- }
-
- EXPECT_DEATH(oob_test<T>(kLargeMalloc, -1),
- "is located.*1 byte.*to the left");
- EXPECT_DEATH(oob_test<T>(kLargeMalloc, kLargeMalloc),
- "is located.*0 byte.*to the right");
-}
-
-// TODO(glider): the following tests are EXTREMELY slow on Darwin:
-// AddressSanitizer.OOB_char (125503 ms)
-// AddressSanitizer.OOB_int (126890 ms)
-// AddressSanitizer.OOBRightTest (315605 ms)
-// AddressSanitizer.SimpleStackTest (366559 ms)
-
-TEST(AddressSanitizer, OOB_char) {
- OOBTest<U1>();
-}
-
-TEST(AddressSanitizer, OOB_int) {
- OOBTest<U4>();
-}
-
-TEST(AddressSanitizer, OOBRightTest) {
- size_t max_access_size = SANITIZER_WORDSIZE == 64 ? 8 : 4;
- for (size_t access_size = 1; access_size <= max_access_size;
- access_size *= 2) {
- for (size_t alloc_size = 1; alloc_size <= 8; alloc_size++) {
- for (size_t offset = 0; offset <= 8; offset += access_size) {
- void *p = malloc(alloc_size);
- // allocated: [p, p + alloc_size)
- // accessed: [p + offset, p + offset + access_size)
- uint8_t *addr = (uint8_t*)p + offset;
- if (offset + access_size <= alloc_size) {
- asan_write_sized_aligned(addr, access_size);
- } else {
- int outside_bytes = offset > alloc_size ? (offset - alloc_size) : 0;
- const char *str =
- "is located.%d *byte.*to the right";
- char expected_str[100];
- sprintf(expected_str, str, outside_bytes);
- EXPECT_DEATH(asan_write_sized_aligned(addr, access_size),
- expected_str);
- }
- free(p);
- }
- }
- }
-}
-
-TEST(AddressSanitizer, LargeOOBRightTest) {
- size_t large_power_of_two = 1 << 19;
- for (size_t i = 16; i <= 256; i *= 2) {
- size_t size = large_power_of_two - i;
- char *p = Ident(new char[size]);
- EXPECT_DEATH(p[size] = 0, "is located 0 bytes to the right");
- delete [] p;
- }
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOBLeftLow) {
- oob_test<U1>(10, -1);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOBLeftHigh) {
- oob_test<U1>(kLargeMalloc, -1);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOBRightLow) {
- oob_test<U1>(10, 10);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOBRightHigh) {
- oob_test<U1>(kLargeMalloc, kLargeMalloc);
-}
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_racy_double_free_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_racy_double_free_test.cc
deleted file mode 100644
index 23240e714d56..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_racy_double_free_test.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-const int N = 1000;
-void *x[N];
-
-void *Thread1(void *unused) {
- for (int i = 0; i < N; i++) {
- fprintf(stderr, "%s %d\n", __func__, i);
- free(x[i]);
- }
- return NULL;
-}
-
-void *Thread2(void *unused) {
- for (int i = 0; i < N; i++) {
- fprintf(stderr, "%s %d\n", __func__, i);
- free(x[i]);
- }
- return NULL;
-}
-
-int main() {
- for (int i = 0; i < N; i++)
- x[i] = malloc(128);
- pthread_t t[2];
- pthread_create(&t[0], 0, Thread1, 0);
- pthread_create(&t[1], 0, Thread2, 0);
- pthread_join(t[0], 0);
- pthread_join(t[1], 0);
-}
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_str_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_str_test.cc
deleted file mode 100644
index 89b0d3d2d0f9..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_str_test.cc
+++ /dev/null
@@ -1,573 +0,0 @@
-//=-- asan_str_test.cc ----------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-#if defined(__APPLE__)
-#include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_*
-#endif
-
-// Used for string functions tests
-static char global_string[] = "global";
-static size_t global_string_length = 6;
-
-// Input to a test is a zero-terminated string str with given length
-// Accesses to the bytes to the left and to the right of str
-// are presumed to produce OOB errors
-void StrLenOOBTestTemplate(char *str, size_t length, bool is_global) {
- // Normal strlen calls
- EXPECT_EQ(strlen(str), length);
- if (length > 0) {
- EXPECT_EQ(length - 1, strlen(str + 1));
- EXPECT_EQ(0U, strlen(str + length));
- }
- // Arg of strlen is not malloced, OOB access
- if (!is_global) {
- // We don't insert RedZones to the left of global variables
- EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(5));
- }
- EXPECT_DEATH(Ident(strlen(str + length + 1)), RightOOBReadMessage(0));
- // Overwrite terminator
- str[length] = 'a';
- // String is not zero-terminated, strlen will lead to OOB access
- EXPECT_DEATH(Ident(strlen(str)), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(strlen(str + length)), RightOOBReadMessage(0));
- // Restore terminator
- str[length] = 0;
-}
-TEST(AddressSanitizer, StrLenOOBTest) {
- // Check heap-allocated string
- size_t length = Ident(10);
- char *heap_string = Ident((char*)malloc(length + 1));
- char stack_string[10 + 1];
- break_optimization(&stack_string);
- for (size_t i = 0; i < length; i++) {
- heap_string[i] = 'a';
- stack_string[i] = 'b';
- }
- heap_string[length] = 0;
- stack_string[length] = 0;
- StrLenOOBTestTemplate(heap_string, length, false);
- // TODO(samsonov): Fix expected messages in StrLenOOBTestTemplate to
- // make test for stack_string work. Or move it to output tests.
- // StrLenOOBTestTemplate(stack_string, length, false);
- StrLenOOBTestTemplate(global_string, global_string_length, true);
- free(heap_string);
-}
-
-TEST(AddressSanitizer, WcsLenTest) {
- EXPECT_EQ(0U, wcslen(Ident(L"")));
- size_t hello_len = 13;
- size_t hello_size = (hello_len + 1) * sizeof(wchar_t);
- EXPECT_EQ(hello_len, wcslen(Ident(L"Hello, World!")));
- wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size));
- memcpy(heap_string, L"Hello, World!", hello_size);
- EXPECT_EQ(hello_len, Ident(wcslen(heap_string)));
- EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0));
- free(heap_string);
-}
-
-#if SANITIZER_TEST_HAS_STRNLEN
-TEST(AddressSanitizer, StrNLenOOBTest) {
- size_t size = Ident(123);
- char *str = MallocAndMemsetString(size);
- // Normal strnlen calls.
- Ident(strnlen(str - 1, 0));
- Ident(strnlen(str, size));
- Ident(strnlen(str + size - 1, 1));
- str[size - 1] = '\0';
- Ident(strnlen(str, 2 * size));
- // Argument points to not allocated memory.
- EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0));
- // Overwrite the terminating '\0' and hit unallocated memory.
- str[size - 1] = 'z';
- EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0));
- free(str);
-}
-#endif // SANITIZER_TEST_HAS_STRNLEN
-
-TEST(AddressSanitizer, StrDupOOBTest) {
- size_t size = Ident(42);
- char *str = MallocAndMemsetString(size);
- char *new_str;
- // Normal strdup calls.
- str[size - 1] = '\0';
- new_str = strdup(str);
- free(new_str);
- new_str = strdup(str + size - 1);
- free(new_str);
- // Argument points to not allocated memory.
- EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0));
- // Overwrite the terminating '\0' and hit unallocated memory.
- str[size - 1] = 'z';
- EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0));
- free(str);
-}
-
-TEST(AddressSanitizer, StrCpyOOBTest) {
- size_t to_size = Ident(30);
- size_t from_size = Ident(6); // less than to_size
- char *to = Ident((char*)malloc(to_size));
- char *from = Ident((char*)malloc(from_size));
- // Normal strcpy calls.
- strcpy(from, "hello");
- strcpy(to, from);
- strcpy(to + to_size - from_size, from);
- // Length of "from" is too small.
- EXPECT_DEATH(Ident(strcpy(from, "hello2")), RightOOBWriteMessage(0));
- // "to" or "from" points to not allocated memory.
- EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1));
- EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0));
- // Overwrite the terminating '\0' character and hit unallocated memory.
- from[from_size - 1] = '!';
- EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0));
- free(to);
- free(from);
-}
-
-TEST(AddressSanitizer, StrNCpyOOBTest) {
- size_t to_size = Ident(20);
- size_t from_size = Ident(6); // less than to_size
- char *to = Ident((char*)malloc(to_size));
- // From is a zero-terminated string "hello\0" of length 6
- char *from = Ident((char*)malloc(from_size));
- strcpy(from, "hello");
- // copy 0 bytes
- strncpy(to, from, 0);
- strncpy(to - 1, from - 1, 0);
- // normal strncpy calls
- strncpy(to, from, from_size);
- strncpy(to, from, to_size);
- strncpy(to, from + from_size - 1, to_size);
- strncpy(to + to_size - 1, from, 1);
- // One of {to, from} points to not allocated memory
- EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)),
- LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)),
- LeftOOBWriteMessage(1));
- EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)),
- RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)),
- RightOOBWriteMessage(0));
- // Length of "to" is too small
- EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)),
- RightOOBWriteMessage(0));
- EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)),
- RightOOBWriteMessage(0));
- // Overwrite terminator in from
- from[from_size - 1] = '!';
- // normal strncpy call
- strncpy(to, from, from_size);
- // Length of "from" is too small
- EXPECT_DEATH(Ident(strncpy(to, from, to_size)),
- RightOOBReadMessage(0));
- free(to);
- free(from);
-}
-
-// Users may have different definitions of "strchr" and "index", so provide
-// function pointer typedefs and overload RunStrChrTest implementation.
-// We can't use macro for RunStrChrTest body here, as this macro would
-// confuse EXPECT_DEATH gtest macro.
-typedef char*(*PointerToStrChr1)(const char*, int);
-typedef char*(*PointerToStrChr2)(char*, int);
-
-UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr) {
- size_t size = Ident(100);
- char *str = MallocAndMemsetString(size);
- str[10] = 'q';
- str[11] = '\0';
- EXPECT_EQ(str, StrChr(str, 'z'));
- EXPECT_EQ(str + 10, StrChr(str, 'q'));
- EXPECT_EQ(NULL, StrChr(str, 'a'));
- // StrChr argument points to not allocated memory.
- EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));
- // Overwrite the terminator and hit not allocated memory.
- str[11] = 'z';
- EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
- free(str);
-}
-UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr) {
- size_t size = Ident(100);
- char *str = MallocAndMemsetString(size);
- str[10] = 'q';
- str[11] = '\0';
- EXPECT_EQ(str, StrChr(str, 'z'));
- EXPECT_EQ(str + 10, StrChr(str, 'q'));
- EXPECT_EQ(NULL, StrChr(str, 'a'));
- // StrChr argument points to not allocated memory.
- EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));
- // Overwrite the terminator and hit not allocated memory.
- str[11] = 'z';
- EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
- free(str);
-}
-
-TEST(AddressSanitizer, StrChrAndIndexOOBTest) {
- RunStrChrTest(&strchr);
-// No index() on Windows and on Android L.
-#if !defined(_WIN32) && !defined(__ANDROID__)
- RunStrChrTest(&index);
-#endif
-}
-
-TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
- // strcmp
- EXPECT_EQ(0, strcmp("", ""));
- EXPECT_EQ(0, strcmp("abcd", "abcd"));
- EXPECT_GT(0, strcmp("ab", "ac"));
- EXPECT_GT(0, strcmp("abc", "abcd"));
- EXPECT_LT(0, strcmp("acc", "abc"));
- EXPECT_LT(0, strcmp("abcd", "abc"));
-
- // strncmp
- EXPECT_EQ(0, strncmp("a", "b", 0));
- EXPECT_EQ(0, strncmp("abcd", "abcd", 10));
- EXPECT_EQ(0, strncmp("abcd", "abcef", 3));
- EXPECT_GT(0, strncmp("abcde", "abcfa", 4));
- EXPECT_GT(0, strncmp("a", "b", 5));
- EXPECT_GT(0, strncmp("bc", "bcde", 4));
- EXPECT_LT(0, strncmp("xyz", "xyy", 10));
- EXPECT_LT(0, strncmp("baa", "aaa", 1));
- EXPECT_LT(0, strncmp("zyx", "", 2));
-
-#if !defined(_WIN32) // no str[n]casecmp on Windows.
- // strcasecmp
- EXPECT_EQ(0, strcasecmp("", ""));
- EXPECT_EQ(0, strcasecmp("zzz", "zzz"));
- EXPECT_EQ(0, strcasecmp("abCD", "ABcd"));
- EXPECT_GT(0, strcasecmp("aB", "Ac"));
- EXPECT_GT(0, strcasecmp("ABC", "ABCd"));
- EXPECT_LT(0, strcasecmp("acc", "abc"));
- EXPECT_LT(0, strcasecmp("ABCd", "abc"));
-
- // strncasecmp
- EXPECT_EQ(0, strncasecmp("a", "b", 0));
- EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10));
- EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3));
- EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4));
- EXPECT_GT(0, strncasecmp("a", "B", 5));
- EXPECT_GT(0, strncasecmp("bc", "BCde", 4));
- EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
- EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
- EXPECT_LT(0, strncasecmp("zyx", "", 2));
-#endif
-
- // memcmp
- EXPECT_EQ(0, memcmp("a", "b", 0));
- EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4));
- EXPECT_GT(0, memcmp("\0ab", "\0ac", 3));
- EXPECT_GT(0, memcmp("abb\0", "abba", 4));
- EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5));
- EXPECT_LT(0, memcmp("zza", "zyx", 3));
-}
-
-typedef int(*PointerToStrCmp)(const char*, const char*);
-void RunStrCmpTest(PointerToStrCmp StrCmp) {
- size_t size = Ident(100);
- int fill = 'o';
- char *s1 = MallocAndMemsetString(size, fill);
- char *s2 = MallocAndMemsetString(size, fill);
- s1[size - 1] = '\0';
- s2[size - 1] = '\0';
- // Normal StrCmp calls
- Ident(StrCmp(s1, s2));
- Ident(StrCmp(s1, s2 + size - 1));
- Ident(StrCmp(s1 + size - 1, s2 + size - 1));
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0));
- // Hit unallocated memory and die.
- s1[size - 1] = fill;
- EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0));
- free(s1);
- free(s2);
-}
-
-TEST(AddressSanitizer, StrCmpOOBTest) {
- RunStrCmpTest(&strcmp);
-}
-
-#if !defined(_WIN32) // no str[n]casecmp on Windows.
-TEST(AddressSanitizer, StrCaseCmpOOBTest) {
- RunStrCmpTest(&strcasecmp);
-}
-#endif
-
-typedef int(*PointerToStrNCmp)(const char*, const char*, size_t);
-void RunStrNCmpTest(PointerToStrNCmp StrNCmp) {
- size_t size = Ident(100);
- char *s1 = MallocAndMemsetString(size);
- char *s2 = MallocAndMemsetString(size);
- s1[size - 1] = '\0';
- s2[size - 1] = '\0';
- // Normal StrNCmp calls
- Ident(StrNCmp(s1, s2, size + 2));
- s1[size - 1] = 'z';
- s2[size - 1] = 'x';
- Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size));
- s2[size - 1] = 'z';
- Ident(StrNCmp(s1 - 1, s2 - 1, 0));
- Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1));
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0));
- // Hit unallocated memory and die.
- EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
- free(s1);
- free(s2);
-}
-
-TEST(AddressSanitizer, StrNCmpOOBTest) {
- RunStrNCmpTest(&strncmp);
-}
-
-#if !defined(_WIN32) // no str[n]casecmp on Windows.
-TEST(AddressSanitizer, StrNCaseCmpOOBTest) {
- RunStrNCmpTest(&strncasecmp);
-}
-#endif
-
-TEST(AddressSanitizer, StrCatOOBTest) {
- // strcat() reads strlen(to) bytes from |to| before concatenating.
- size_t to_size = Ident(100);
- char *to = MallocAndMemsetString(to_size);
- to[0] = '\0';
- size_t from_size = Ident(20);
- char *from = MallocAndMemsetString(from_size);
- from[from_size - 1] = '\0';
- // Normal strcat calls.
- strcat(to, from);
- strcat(to, from);
- strcat(to + from_size, from + from_size - 2);
- // Passing an invalid pointer is an error even when concatenating an empty
- // string.
- EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1));
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1));
- EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0));
-
- // "from" is not zero-terminated.
- from[from_size - 1] = 'z';
- EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0));
- from[from_size - 1] = '\0';
- // "to" is too short to fit "from".
- memset(to, 'z', to_size);
- to[to_size - from_size + 1] = '\0';
- EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0));
- // length of "to" is just enough.
- strcat(to, from + 1);
-
- free(to);
- free(from);
-}
-
-TEST(AddressSanitizer, StrNCatOOBTest) {
- // strncat() reads strlen(to) bytes from |to| before concatenating.
- size_t to_size = Ident(100);
- char *to = MallocAndMemsetString(to_size);
- to[0] = '\0';
- size_t from_size = Ident(20);
- char *from = MallocAndMemsetString(from_size);
- // Normal strncat calls.
- strncat(to, from, 0);
- strncat(to, from, from_size);
- from[from_size - 1] = '\0';
- strncat(to, from, 2 * from_size);
- // Catenating empty string with an invalid string is still an error.
- EXPECT_DEATH(strncat(to - 1, from, 0), LeftOOBAccessMessage(1));
- strncat(to, from + from_size - 1, 10);
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1));
- EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1));
- EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0));
-
- memset(from, 'z', from_size);
- memset(to, 'z', to_size);
- to[0] = '\0';
- // "from" is too short.
- EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0));
- // "to" is too short to fit "from".
- to[0] = 'z';
- to[to_size - from_size + 1] = '\0';
- EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0));
- // "to" is just enough.
- strncat(to, from, from_size - 2);
-
- free(to);
- free(from);
-}
-
-static string OverlapErrorMessage(const string &func) {
- return func + "-param-overlap";
-}
-
-TEST(AddressSanitizer, StrArgsOverlapTest) {
- size_t size = Ident(100);
- char *str = Ident((char*)malloc(size));
-
-// Do not check memcpy() on OS X 10.7 and later, where it actually aliases
-// memmove().
-#if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \
- (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
- // Check "memcpy". Use Ident() to avoid inlining.
- memset(str, 'z', size);
- Ident(memcpy)(str + 1, str + 11, 10);
- Ident(memcpy)(str, str, 0);
- EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage("memcpy"));
- EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage("memcpy"));
-#endif
-
- // We do not treat memcpy with to==from as a bug.
- // See http://llvm.org/bugs/show_bug.cgi?id=11763.
- // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1),
- // OverlapErrorMessage("memcpy"));
-
- // Check "strcpy".
- memset(str, 'z', size);
- str[9] = '\0';
- strcpy(str + 10, str);
- EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage("strcpy"));
- EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage("strcpy"));
- strcpy(str, str + 5);
-
- // Check "strncpy".
- memset(str, 'z', size);
- strncpy(str, str + 10, 10);
- EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage("strncpy"));
- EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage("strncpy"));
- str[10] = '\0';
- strncpy(str + 11, str, 20);
- EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage("strncpy"));
-
- // Check "strcat".
- memset(str, 'z', size);
- str[10] = '\0';
- str[20] = '\0';
- strcat(str, str + 10);
- EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage("strcat"));
- str[10] = '\0';
- strcat(str + 11, str);
- EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage("strcat"));
- EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat"));
- EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat"));
-
- // Check "strncat".
- memset(str, 'z', size);
- str[10] = '\0';
- strncat(str, str + 10, 10); // from is empty
- EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage("strncat"));
- str[10] = '\0';
- str[20] = '\0';
- strncat(str + 5, str, 5);
- str[10] = '\0';
- EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat"));
- EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat"));
-
- free(str);
-}
-
-typedef void(*PointerToCallAtoi)(const char*);
-
-void RunAtoiOOBTest(PointerToCallAtoi Atoi) {
- char *array = MallocAndMemsetString(10, '1');
- // Invalid pointer to the string.
- EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1));
- EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1));
- // Die if a buffer doesn't have terminating NULL.
- EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
- // Make last symbol a terminating NULL
- array[9] = '\0';
- Atoi(array);
- // Sometimes we need to detect overflow if no digits are found.
- memset(array, ' ', 10);
- EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
- array[9] = '-';
- EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
- EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0));
- free(array);
-}
-
-#if !defined(_WIN32) // FIXME: Fix and enable on Windows.
-void CallAtoi(const char *nptr) {
- Ident(atoi(nptr));
-}
-void CallAtol(const char *nptr) {
- Ident(atol(nptr));
-}
-void CallAtoll(const char *nptr) {
- Ident(atoll(nptr));
-}
-TEST(AddressSanitizer, AtoiAndFriendsOOBTest) {
- RunAtoiOOBTest(&CallAtoi);
- RunAtoiOOBTest(&CallAtol);
- RunAtoiOOBTest(&CallAtoll);
-}
-#endif
-
-typedef void(*PointerToCallStrtol)(const char*, char**, int);
-
-void RunStrtolOOBTest(PointerToCallStrtol Strtol) {
- char *array = MallocAndMemsetString(3);
- array[0] = '1';
- array[1] = '2';
- array[2] = '3';
- // Invalid pointer to the string.
- EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0));
- EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1));
- // Buffer overflow if there is no terminating null (depends on base).
- EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
- array[2] = 'z';
- EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0));
- // Add terminating zero to get rid of overflow.
- array[2] = '\0';
- Strtol(array, NULL, 36);
- // Sometimes we need to detect overflow if no digits are found.
- array[0] = array[1] = array[2] = ' ';
- EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
- array[2] = '+';
- EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
- array[2] = '-';
- EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
- free(array);
-}
-
-#if !defined(_WIN32) // FIXME: Fix and enable on Windows.
-void CallStrtol(const char *nptr, char **endptr, int base) {
- Ident(strtol(nptr, endptr, base));
-}
-void CallStrtoll(const char *nptr, char **endptr, int base) {
- Ident(strtoll(nptr, endptr, base));
-}
-TEST(AddressSanitizer, StrtollOOBTest) {
- RunStrtolOOBTest(&CallStrtoll);
-}
-TEST(AddressSanitizer, StrtolOOBTest) {
- RunStrtolOOBTest(&CallStrtol);
-}
-#endif
-
-
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_test.cc b/contrib/compiler-rt/lib/asan/tests/asan_test.cc
deleted file mode 100644
index 07d59e09a72f..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_test.cc
+++ /dev/null
@@ -1,1319 +0,0 @@
-//===-- asan_test.cc ------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-NOINLINE void *malloc_fff(size_t size) {
- void *res = malloc/**/(size); break_optimization(0); return res;}
-NOINLINE void *malloc_eee(size_t size) {
- void *res = malloc_fff(size); break_optimization(0); return res;}
-NOINLINE void *malloc_ddd(size_t size) {
- void *res = malloc_eee(size); break_optimization(0); return res;}
-NOINLINE void *malloc_ccc(size_t size) {
- void *res = malloc_ddd(size); break_optimization(0); return res;}
-NOINLINE void *malloc_bbb(size_t size) {
- void *res = malloc_ccc(size); break_optimization(0); return res;}
-NOINLINE void *malloc_aaa(size_t size) {
- void *res = malloc_bbb(size); break_optimization(0); return res;}
-
-NOINLINE void free_ccc(void *p) { free(p); break_optimization(0);}
-NOINLINE void free_bbb(void *p) { free_ccc(p); break_optimization(0);}
-NOINLINE void free_aaa(void *p) { free_bbb(p); break_optimization(0);}
-
-template<typename T>
-NOINLINE void uaf_test(int size, int off) {
- void *p = malloc_aaa(size);
- free_aaa(p);
- for (int i = 1; i < 100; i++)
- free_aaa(malloc_aaa(i));
- fprintf(stderr, "writing %ld byte(s) at %p with offset %d\n",
- (long)sizeof(T), p, off);
- asan_write((T *)((char *)p + off));
-}
-
-TEST(AddressSanitizer, HasFeatureAddressSanitizerTest) {
-#if defined(__has_feature) && __has_feature(address_sanitizer)
- bool asan = 1;
-#elif defined(__SANITIZE_ADDRESS__)
- bool asan = 1;
-#else
- bool asan = 0;
-#endif
- EXPECT_EQ(true, asan);
-}
-
-TEST(AddressSanitizer, SimpleDeathTest) {
- EXPECT_DEATH(exit(1), "");
-}
-
-TEST(AddressSanitizer, VariousMallocsTest) {
- int *a = (int*)malloc(100 * sizeof(int));
- a[50] = 0;
- free(a);
-
- int *r = (int*)malloc(10);
- r = (int*)realloc(r, 2000 * sizeof(int));
- r[1000] = 0;
- free(r);
-
- int *b = new int[100];
- b[50] = 0;
- delete [] b;
-
- int *c = new int;
- *c = 0;
- delete c;
-
-#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
- int *pm;
- int pm_res = posix_memalign((void**)&pm, kPageSize, kPageSize);
- EXPECT_EQ(0, pm_res);
- free(pm);
-#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
-
-#if SANITIZER_TEST_HAS_MEMALIGN
- int *ma = (int*)memalign(kPageSize, kPageSize);
- EXPECT_EQ(0U, (uintptr_t)ma % kPageSize);
- ma[123] = 0;
- free(ma);
-#endif // SANITIZER_TEST_HAS_MEMALIGN
-}
-
-TEST(AddressSanitizer, CallocTest) {
- int *a = (int*)calloc(100, sizeof(int));
- EXPECT_EQ(0, a[10]);
- free(a);
-}
-
-TEST(AddressSanitizer, CallocReturnsZeroMem) {
- size_t sizes[] = {16, 1000, 10000, 100000, 2100000};
- for (size_t s = 0; s < sizeof(sizes)/sizeof(sizes[0]); s++) {
- size_t size = sizes[s];
- for (size_t iter = 0; iter < 5; iter++) {
- char *x = Ident((char*)calloc(1, size));
- EXPECT_EQ(x[0], 0);
- EXPECT_EQ(x[size - 1], 0);
- EXPECT_EQ(x[size / 2], 0);
- EXPECT_EQ(x[size / 3], 0);
- EXPECT_EQ(x[size / 4], 0);
- memset(x, 0x42, size);
- free(Ident(x));
-#if !defined(_WIN32)
- // FIXME: OOM on Windows. We should just make this a lit test
- // with quarantine size set to 1.
- free(Ident(malloc(Ident(1 << 27)))); // Try to drain the quarantine.
-#endif
- }
- }
-}
-
-// No valloc on Windows or Android.
-#if !defined(_WIN32) && !defined(__ANDROID__)
-TEST(AddressSanitizer, VallocTest) {
- void *a = valloc(100);
- EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
- free(a);
-}
-#endif
-
-#if SANITIZER_TEST_HAS_PVALLOC
-TEST(AddressSanitizer, PvallocTest) {
- char *a = (char*)pvalloc(kPageSize + 100);
- EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
- a[kPageSize + 101] = 1; // we should not report an error here.
- free(a);
-
- a = (char*)pvalloc(0); // pvalloc(0) should allocate at least one page.
- EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
- a[101] = 1; // we should not report an error here.
- free(a);
-}
-#endif // SANITIZER_TEST_HAS_PVALLOC
-
-#if !defined(_WIN32)
-// FIXME: Use an equivalent of pthread_setspecific on Windows.
-void *TSDWorker(void *test_key) {
- if (test_key) {
- pthread_setspecific(*(pthread_key_t*)test_key, (void*)0xfeedface);
- }
- return NULL;
-}
-
-void TSDDestructor(void *tsd) {
- // Spawning a thread will check that the current thread id is not -1.
- pthread_t th;
- PTHREAD_CREATE(&th, NULL, TSDWorker, NULL);
- PTHREAD_JOIN(th, NULL);
-}
-
-// This tests triggers the thread-specific data destruction fiasco which occurs
-// if we don't manage the TSD destructors ourselves. We create a new pthread
-// key with a non-NULL destructor which is likely to be put after the destructor
-// of AsanThread in the list of destructors.
-// In this case the TSD for AsanThread will be destroyed before TSDDestructor
-// is called for the child thread, and a CHECK will fail when we call
-// pthread_create() to spawn the grandchild.
-TEST(AddressSanitizer, DISABLED_TSDTest) {
- pthread_t th;
- pthread_key_t test_key;
- pthread_key_create(&test_key, TSDDestructor);
- PTHREAD_CREATE(&th, NULL, TSDWorker, &test_key);
- PTHREAD_JOIN(th, NULL);
- pthread_key_delete(test_key);
-}
-#endif
-
-TEST(AddressSanitizer, UAF_char) {
- const char *uaf_string = "AddressSanitizer:.*heap-use-after-free";
- EXPECT_DEATH(uaf_test<U1>(1, 0), uaf_string);
- EXPECT_DEATH(uaf_test<U1>(10, 0), uaf_string);
- EXPECT_DEATH(uaf_test<U1>(10, 10), uaf_string);
- EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, 0), uaf_string);
- EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string);
-}
-
-TEST(AddressSanitizer, UAF_long_double) {
- if (sizeof(long double) == sizeof(double)) return;
- long double *p = Ident(new long double[10]);
- EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[026]");
- EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[026]");
- delete [] Ident(p);
-}
-
-#if !defined(_WIN32)
-struct Packed5 {
- int x;
- char c;
-} __attribute__((packed));
-#else
-# pragma pack(push, 1)
-struct Packed5 {
- int x;
- char c;
-};
-# pragma pack(pop)
-#endif
-
-TEST(AddressSanitizer, UAF_Packed5) {
- static_assert(sizeof(Packed5) == 5, "Please check the keywords used");
- Packed5 *p = Ident(new Packed5[2]);
- EXPECT_DEATH(p[0] = p[3], "READ of size 5");
- EXPECT_DEATH(p[3] = p[0], "WRITE of size 5");
- delete [] Ident(p);
-}
-
-#if ASAN_HAS_BLACKLIST
-TEST(AddressSanitizer, IgnoreTest) {
- int *x = Ident(new int);
- delete Ident(x);
- *x = 0;
-}
-#endif // ASAN_HAS_BLACKLIST
-
-struct StructWithBitField {
- int bf1:1;
- int bf2:1;
- int bf3:1;
- int bf4:29;
-};
-
-TEST(AddressSanitizer, BitFieldPositiveTest) {
- StructWithBitField *x = new StructWithBitField;
- delete Ident(x);
- EXPECT_DEATH(x->bf1 = 0, "use-after-free");
- EXPECT_DEATH(x->bf2 = 0, "use-after-free");
- EXPECT_DEATH(x->bf3 = 0, "use-after-free");
- EXPECT_DEATH(x->bf4 = 0, "use-after-free");
-}
-
-struct StructWithBitFields_8_24 {
- int a:8;
- int b:24;
-};
-
-TEST(AddressSanitizer, BitFieldNegativeTest) {
- StructWithBitFields_8_24 *x = Ident(new StructWithBitFields_8_24);
- x->a = 0;
- x->b = 0;
- delete Ident(x);
-}
-
-#if ASAN_NEEDS_SEGV
-namespace {
-
-const char kUnknownCrash[] = "AddressSanitizer: SEGV on unknown address";
-const char kOverriddenHandler[] = "ASan signal handler has been overridden\n";
-
-TEST(AddressSanitizer, WildAddressTest) {
- char *c = (char*)0x123;
- EXPECT_DEATH(*c = 0, kUnknownCrash);
-}
-
-void my_sigaction_sighandler(int, siginfo_t*, void*) {
- fprintf(stderr, kOverriddenHandler);
- exit(1);
-}
-
-void my_signal_sighandler(int signum) {
- fprintf(stderr, kOverriddenHandler);
- exit(1);
-}
-
-TEST(AddressSanitizer, SignalTest) {
- struct sigaction sigact;
- memset(&sigact, 0, sizeof(sigact));
- sigact.sa_sigaction = my_sigaction_sighandler;
- sigact.sa_flags = SA_SIGINFO;
- // ASan should silently ignore sigaction()...
- EXPECT_EQ(0, sigaction(SIGSEGV, &sigact, 0));
-#ifdef __APPLE__
- EXPECT_EQ(0, sigaction(SIGBUS, &sigact, 0));
-#endif
- char *c = (char*)0x123;
- EXPECT_DEATH(*c = 0, kUnknownCrash);
- // ... and signal().
- EXPECT_EQ(0, signal(SIGSEGV, my_signal_sighandler));
- EXPECT_DEATH(*c = 0, kUnknownCrash);
-}
-} // namespace
-#endif
-
-static void TestLargeMalloc(size_t size) {
- char buff[1024];
- sprintf(buff, "is located 1 bytes to the left of %lu-byte", (long)size);
- EXPECT_DEATH(Ident((char*)malloc(size))[-1] = 0, buff);
-}
-
-TEST(AddressSanitizer, LargeMallocTest) {
- const int max_size = (SANITIZER_WORDSIZE == 32) ? 1 << 26 : 1 << 28;
- for (int i = 113; i < max_size; i = i * 2 + 13) {
- TestLargeMalloc(i);
- }
-}
-
-TEST(AddressSanitizer, HugeMallocTest) {
- if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return;
- size_t n_megs = 4100;
- EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0,
- "is located 1 bytes to the left|"
- "AddressSanitizer failed to allocate");
-}
-
-#if SANITIZER_TEST_HAS_MEMALIGN
-void MemalignRun(size_t align, size_t size, int idx) {
- char *p = (char *)memalign(align, size);
- Ident(p)[idx] = 0;
- free(p);
-}
-
-TEST(AddressSanitizer, memalign) {
- for (int align = 16; align <= (1 << 23); align *= 2) {
- size_t size = align * 5;
- EXPECT_DEATH(MemalignRun(align, size, -1),
- "is located 1 bytes to the left");
- EXPECT_DEATH(MemalignRun(align, size, size + 1),
- "is located 1 bytes to the right");
- }
-}
-#endif // SANITIZER_TEST_HAS_MEMALIGN
-
-void *ManyThreadsWorker(void *a) {
- for (int iter = 0; iter < 100; iter++) {
- for (size_t size = 100; size < 2000; size *= 2) {
- free(Ident(malloc(size)));
- }
- }
- return 0;
-}
-
-TEST(AddressSanitizer, ManyThreadsTest) {
- const size_t kNumThreads =
- (SANITIZER_WORDSIZE == 32 || ASAN_AVOID_EXPENSIVE_TESTS) ? 30 : 1000;
- pthread_t t[kNumThreads];
- for (size_t i = 0; i < kNumThreads; i++) {
- PTHREAD_CREATE(&t[i], 0, ManyThreadsWorker, (void*)i);
- }
- for (size_t i = 0; i < kNumThreads; i++) {
- PTHREAD_JOIN(t[i], 0);
- }
-}
-
-TEST(AddressSanitizer, ReallocTest) {
- const int kMinElem = 5;
- int *ptr = (int*)malloc(sizeof(int) * kMinElem);
- ptr[3] = 3;
- for (int i = 0; i < 10000; i++) {
- ptr = (int*)realloc(ptr,
- (my_rand() % 1000 + kMinElem) * sizeof(int));
- EXPECT_EQ(3, ptr[3]);
- }
- free(ptr);
- // Realloc pointer returned by malloc(0).
- int *ptr2 = Ident((int*)malloc(0));
- ptr2 = Ident((int*)realloc(ptr2, sizeof(*ptr2)));
- *ptr2 = 42;
- EXPECT_EQ(42, *ptr2);
- free(ptr2);
-}
-
-TEST(AddressSanitizer, ReallocFreedPointerTest) {
- void *ptr = Ident(malloc(42));
- ASSERT_TRUE(NULL != ptr);
- free(ptr);
- EXPECT_DEATH(ptr = realloc(ptr, 77), "attempting double-free");
-}
-
-TEST(AddressSanitizer, ReallocInvalidPointerTest) {
- void *ptr = Ident(malloc(42));
- EXPECT_DEATH(ptr = realloc((int*)ptr + 1, 77), "attempting free.*not malloc");
- free(ptr);
-}
-
-TEST(AddressSanitizer, ZeroSizeMallocTest) {
- // Test that malloc(0) and similar functions don't return NULL.
- void *ptr = Ident(malloc(0));
- EXPECT_TRUE(NULL != ptr);
- free(ptr);
-#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
- int pm_res = posix_memalign(&ptr, 1<<20, 0);
- EXPECT_EQ(0, pm_res);
- EXPECT_TRUE(NULL != ptr);
- free(ptr);
-#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
- int *int_ptr = new int[0];
- int *int_ptr2 = new int[0];
- EXPECT_TRUE(NULL != int_ptr);
- EXPECT_TRUE(NULL != int_ptr2);
- EXPECT_NE(int_ptr, int_ptr2);
- delete[] int_ptr;
- delete[] int_ptr2;
-}
-
-#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
-static const char *kMallocUsableSizeErrorMsg =
- "AddressSanitizer: attempting to call malloc_usable_size()";
-
-TEST(AddressSanitizer, MallocUsableSizeTest) {
- const size_t kArraySize = 100;
- char *array = Ident((char*)malloc(kArraySize));
- int *int_ptr = Ident(new int);
- EXPECT_EQ(0U, malloc_usable_size(NULL));
- EXPECT_EQ(kArraySize, malloc_usable_size(array));
- EXPECT_EQ(sizeof(int), malloc_usable_size(int_ptr));
- EXPECT_DEATH(malloc_usable_size((void*)0x123), kMallocUsableSizeErrorMsg);
- EXPECT_DEATH(malloc_usable_size(array + kArraySize / 2),
- kMallocUsableSizeErrorMsg);
- free(array);
- EXPECT_DEATH(malloc_usable_size(array), kMallocUsableSizeErrorMsg);
- delete int_ptr;
-}
-#endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
-
-void WrongFree() {
- int *x = (int*)malloc(100 * sizeof(int));
- // Use the allocated memory, otherwise Clang will optimize it out.
- Ident(x);
- free(x + 1);
-}
-
-#if !defined(_WIN32) // FIXME: This should be a lit test.
-TEST(AddressSanitizer, WrongFreeTest) {
- EXPECT_DEATH(WrongFree(), ASAN_PCRE_DOTALL
- "ERROR: AddressSanitizer: attempting free.*not malloc"
- ".*is located 4 bytes inside of 400-byte region"
- ".*allocated by thread");
-}
-#endif
-
-void DoubleFree() {
- int *x = (int*)malloc(100 * sizeof(int));
- fprintf(stderr, "DoubleFree: x=%p\n", (void *)x);
- free(x);
- free(x);
- fprintf(stderr, "should have failed in the second free(%p)\n", (void *)x);
- abort();
-}
-
-#if !defined(_WIN32) // FIXME: This should be a lit test.
-TEST(AddressSanitizer, DoubleFreeTest) {
- EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL
- "ERROR: AddressSanitizer: attempting double-free"
- ".*is located 0 bytes inside of 400-byte region"
- ".*freed by thread T0 here"
- ".*previously allocated by thread T0 here");
-}
-#endif
-
-template<int kSize>
-NOINLINE void SizedStackTest() {
- char a[kSize];
- char *A = Ident((char*)&a);
- const char *expected_death = "AddressSanitizer: stack-buffer-";
- for (size_t i = 0; i < kSize; i++)
- A[i] = i;
- EXPECT_DEATH(A[-1] = 0, expected_death);
- EXPECT_DEATH(A[-5] = 0, expected_death);
- EXPECT_DEATH(A[kSize] = 0, expected_death);
- EXPECT_DEATH(A[kSize + 1] = 0, expected_death);
- EXPECT_DEATH(A[kSize + 5] = 0, expected_death);
- if (kSize > 16)
- EXPECT_DEATH(A[kSize + 31] = 0, expected_death);
-}
-
-TEST(AddressSanitizer, SimpleStackTest) {
- SizedStackTest<1>();
- SizedStackTest<2>();
- SizedStackTest<3>();
- SizedStackTest<4>();
- SizedStackTest<5>();
- SizedStackTest<6>();
- SizedStackTest<7>();
- SizedStackTest<16>();
- SizedStackTest<25>();
- SizedStackTest<34>();
- SizedStackTest<43>();
- SizedStackTest<51>();
- SizedStackTest<62>();
- SizedStackTest<64>();
- SizedStackTest<128>();
-}
-
-#if !defined(_WIN32)
-// FIXME: It's a bit hard to write multi-line death test expectations
-// in a portable way. Anyways, this should just be turned into a lit test.
-TEST(AddressSanitizer, ManyStackObjectsTest) {
- char XXX[10];
- char YYY[20];
- char ZZZ[30];
- Ident(XXX);
- Ident(YYY);
- EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL "XXX.*YYY.*ZZZ");
-}
-#endif
-
-#if 0 // This test requires online symbolizer.
-// Moved to lit_tests/stack-oob-frames.cc.
-// Reenable here once we have online symbolizer by default.
-NOINLINE static void Frame0(int frame, char *a, char *b, char *c) {
- char d[4] = {0};
- char *D = Ident(d);
- switch (frame) {
- case 3: a[5]++; break;
- case 2: b[5]++; break;
- case 1: c[5]++; break;
- case 0: D[5]++; break;
- }
-}
-NOINLINE static void Frame1(int frame, char *a, char *b) {
- char c[4] = {0}; Frame0(frame, a, b, c);
- break_optimization(0);
-}
-NOINLINE static void Frame2(int frame, char *a) {
- char b[4] = {0}; Frame1(frame, a, b);
- break_optimization(0);
-}
-NOINLINE static void Frame3(int frame) {
- char a[4] = {0}; Frame2(frame, a);
- break_optimization(0);
-}
-
-TEST(AddressSanitizer, GuiltyStackFrame0Test) {
- EXPECT_DEATH(Frame3(0), "located .*in frame <.*Frame0");
-}
-TEST(AddressSanitizer, GuiltyStackFrame1Test) {
- EXPECT_DEATH(Frame3(1), "located .*in frame <.*Frame1");
-}
-TEST(AddressSanitizer, GuiltyStackFrame2Test) {
- EXPECT_DEATH(Frame3(2), "located .*in frame <.*Frame2");
-}
-TEST(AddressSanitizer, GuiltyStackFrame3Test) {
- EXPECT_DEATH(Frame3(3), "located .*in frame <.*Frame3");
-}
-#endif
-
-NOINLINE void LongJmpFunc1(jmp_buf buf) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- longjmp(buf, 1);
-}
-
-NOINLINE void TouchStackFunc() {
- int a[100]; // long array will intersect with redzones from LongJmpFunc1.
- int *A = Ident(a);
- for (int i = 0; i < 100; i++)
- A[i] = i*i;
-}
-
-// Test that we handle longjmp and do not report false positives on stack.
-TEST(AddressSanitizer, LongJmpTest) {
- static jmp_buf buf;
- if (!setjmp(buf)) {
- LongJmpFunc1(buf);
- } else {
- TouchStackFunc();
- }
-}
-
-#if !defined(_WIN32) // Only basic longjmp is available on Windows.
-NOINLINE void UnderscopeLongJmpFunc1(jmp_buf buf) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- _longjmp(buf, 1);
-}
-
-NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- siglongjmp(buf, 1);
-}
-
-#if !defined(__ANDROID__) && !defined(__arm__) && \
- !defined(__powerpc64__) && !defined(__powerpc__) && \
- !defined(__aarch64__) && !defined(__mips__) && \
- !defined(__mips64)
-NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- __builtin_longjmp((void**)buf, 1);
-}
-
-// Does not work on Power and ARM:
-// https://code.google.com/p/address-sanitizer/issues/detail?id=185
-TEST(AddressSanitizer, BuiltinLongJmpTest) {
- static jmp_buf buf;
- if (!__builtin_setjmp((void**)buf)) {
- BuiltinLongJmpFunc1(buf);
- } else {
- TouchStackFunc();
- }
-}
-#endif // !defined(__ANDROID__) && !defined(__powerpc64__) &&
- // !defined(__powerpc__) && !defined(__arm__) &&
- // !defined(__mips__) && !defined(__mips64)
-
-TEST(AddressSanitizer, UnderscopeLongJmpTest) {
- static jmp_buf buf;
- if (!_setjmp(buf)) {
- UnderscopeLongJmpFunc1(buf);
- } else {
- TouchStackFunc();
- }
-}
-
-TEST(AddressSanitizer, SigLongJmpTest) {
- static sigjmp_buf buf;
- if (!sigsetjmp(buf, 1)) {
- SigLongJmpFunc1(buf);
- } else {
- TouchStackFunc();
- }
-}
-#endif
-
-// FIXME: Why does clang-cl define __EXCEPTIONS?
-#if defined(__EXCEPTIONS) && !defined(_WIN32)
-NOINLINE void ThrowFunc() {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- ASAN_THROW(1);
-}
-
-TEST(AddressSanitizer, CxxExceptionTest) {
- if (ASAN_UAR) return;
- // TODO(kcc): this test crashes on 32-bit for some reason...
- if (SANITIZER_WORDSIZE == 32) return;
- try {
- ThrowFunc();
- } catch(...) {}
- TouchStackFunc();
-}
-#endif
-
-void *ThreadStackReuseFunc1(void *unused) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- pthread_exit(0);
- return 0;
-}
-
-void *ThreadStackReuseFunc2(void *unused) {
- TouchStackFunc();
- return 0;
-}
-
-TEST(AddressSanitizer, ThreadStackReuseTest) {
- pthread_t t;
- PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc1, 0);
- PTHREAD_JOIN(t, 0);
- PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc2, 0);
- PTHREAD_JOIN(t, 0);
-}
-
-#if defined(__i686__) || defined(__x86_64__)
-#include <emmintrin.h>
-TEST(AddressSanitizer, Store128Test) {
- char *a = Ident((char*)malloc(Ident(12)));
- char *p = a;
- if (((uintptr_t)a % 16) != 0)
- p = a + 8;
- assert(((uintptr_t)p % 16) == 0);
- __m128i value_wide = _mm_set1_epi16(0x1234);
- EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
- "AddressSanitizer: heap-buffer-overflow");
- EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
- "WRITE of size 16");
- EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
- "located 0 bytes to the right of 12-byte");
- free(a);
-}
-#endif
-
-// FIXME: All tests that use this function should be turned into lit tests.
-string RightOOBErrorMessage(int oob_distance, bool is_write) {
- assert(oob_distance >= 0);
- char expected_str[100];
- sprintf(expected_str, ASAN_PCRE_DOTALL
-#if !GTEST_USES_SIMPLE_RE
- "buffer-overflow.*%s.*"
-#endif
- "located %d bytes to the right",
-#if !GTEST_USES_SIMPLE_RE
- is_write ? "WRITE" : "READ",
-#endif
- oob_distance);
- return string(expected_str);
-}
-
-string RightOOBWriteMessage(int oob_distance) {
- return RightOOBErrorMessage(oob_distance, /*is_write*/true);
-}
-
-string RightOOBReadMessage(int oob_distance) {
- return RightOOBErrorMessage(oob_distance, /*is_write*/false);
-}
-
-// FIXME: All tests that use this function should be turned into lit tests.
-string LeftOOBErrorMessage(int oob_distance, bool is_write) {
- assert(oob_distance > 0);
- char expected_str[100];
- sprintf(expected_str,
-#if !GTEST_USES_SIMPLE_RE
- ASAN_PCRE_DOTALL "%s.*"
-#endif
- "located %d bytes to the left",
-#if !GTEST_USES_SIMPLE_RE
- is_write ? "WRITE" : "READ",
-#endif
- oob_distance);
- return string(expected_str);
-}
-
-string LeftOOBWriteMessage(int oob_distance) {
- return LeftOOBErrorMessage(oob_distance, /*is_write*/true);
-}
-
-string LeftOOBReadMessage(int oob_distance) {
- return LeftOOBErrorMessage(oob_distance, /*is_write*/false);
-}
-
-string LeftOOBAccessMessage(int oob_distance) {
- assert(oob_distance > 0);
- char expected_str[100];
- sprintf(expected_str, "located %d bytes to the left", oob_distance);
- return string(expected_str);
-}
-
-char* MallocAndMemsetString(size_t size, char ch) {
- char *s = Ident((char*)malloc(size));
- memset(s, ch, size);
- return s;
-}
-
-char* MallocAndMemsetString(size_t size) {
- return MallocAndMemsetString(size, 'z');
-}
-
-#if defined(__linux__) && !defined(__ANDROID__)
-#define READ_TEST(READ_N_BYTES) \
- char *x = new char[10]; \
- int fd = open("/proc/self/stat", O_RDONLY); \
- ASSERT_GT(fd, 0); \
- EXPECT_DEATH(READ_N_BYTES, \
- ASAN_PCRE_DOTALL \
- "AddressSanitizer: heap-buffer-overflow" \
- ".* is located 0 bytes to the right of 10-byte region"); \
- close(fd); \
- delete [] x; \
-
-TEST(AddressSanitizer, pread) {
- READ_TEST(pread(fd, x, 15, 0));
-}
-
-TEST(AddressSanitizer, pread64) {
- READ_TEST(pread64(fd, x, 15, 0));
-}
-
-TEST(AddressSanitizer, read) {
- READ_TEST(read(fd, x, 15));
-}
-#endif // defined(__linux__) && !defined(__ANDROID__)
-
-// This test case fails
-// Clang optimizes memcpy/memset calls which lead to unaligned access
-TEST(AddressSanitizer, DISABLED_MemIntrinsicUnalignedAccessTest) {
- int size = Ident(4096);
- char *s = Ident((char*)malloc(size));
- EXPECT_DEATH(memset(s + size - 1, 0, 2), RightOOBWriteMessage(0));
- free(s);
-}
-
-// TODO(samsonov): Add a test with malloc(0)
-// TODO(samsonov): Add tests for str* and mem* functions.
-
-NOINLINE static int LargeFunction(bool do_bad_access) {
- int *x = new int[100];
- x[0]++;
- x[1]++;
- x[2]++;
- x[3]++;
- x[4]++;
- x[5]++;
- x[6]++;
- x[7]++;
- x[8]++;
- x[9]++;
-
- x[do_bad_access ? 100 : 0]++; int res = __LINE__;
-
- x[10]++;
- x[11]++;
- x[12]++;
- x[13]++;
- x[14]++;
- x[15]++;
- x[16]++;
- x[17]++;
- x[18]++;
- x[19]++;
-
- delete[] x;
- return res;
-}
-
-// Test the we have correct debug info for the failing instruction.
-// This test requires the in-process symbolizer to be enabled by default.
-TEST(AddressSanitizer, DISABLED_LargeFunctionSymbolizeTest) {
- int failing_line = LargeFunction(false);
- char expected_warning[128];
- sprintf(expected_warning, "LargeFunction.*asan_test.*:%d", failing_line);
- EXPECT_DEATH(LargeFunction(true), expected_warning);
-}
-
-// Check that we unwind and symbolize correctly.
-TEST(AddressSanitizer, DISABLED_MallocFreeUnwindAndSymbolizeTest) {
- int *a = (int*)malloc_aaa(sizeof(int));
- *a = 1;
- free_aaa(a);
- EXPECT_DEATH(*a = 1, "free_ccc.*free_bbb.*free_aaa.*"
- "malloc_fff.*malloc_eee.*malloc_ddd");
-}
-
-static bool TryToSetThreadName(const char *name) {
-#if defined(__linux__) && defined(PR_SET_NAME)
- return 0 == prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
-#else
- return false;
-#endif
-}
-
-void *ThreadedTestAlloc(void *a) {
- EXPECT_EQ(true, TryToSetThreadName("AllocThr"));
- int **p = (int**)a;
- *p = new int;
- return 0;
-}
-
-void *ThreadedTestFree(void *a) {
- EXPECT_EQ(true, TryToSetThreadName("FreeThr"));
- int **p = (int**)a;
- delete *p;
- return 0;
-}
-
-void *ThreadedTestUse(void *a) {
- EXPECT_EQ(true, TryToSetThreadName("UseThr"));
- int **p = (int**)a;
- **p = 1;
- return 0;
-}
-
-void ThreadedTestSpawn() {
- pthread_t t;
- int *x;
- PTHREAD_CREATE(&t, 0, ThreadedTestAlloc, &x);
- PTHREAD_JOIN(t, 0);
- PTHREAD_CREATE(&t, 0, ThreadedTestFree, &x);
- PTHREAD_JOIN(t, 0);
- PTHREAD_CREATE(&t, 0, ThreadedTestUse, &x);
- PTHREAD_JOIN(t, 0);
-}
-
-#if !defined(_WIN32) // FIXME: This should be a lit test.
-TEST(AddressSanitizer, ThreadedTest) {
- EXPECT_DEATH(ThreadedTestSpawn(),
- ASAN_PCRE_DOTALL
- "Thread T.*created"
- ".*Thread T.*created"
- ".*Thread T.*created");
-}
-#endif
-
-void *ThreadedTestFunc(void *unused) {
- // Check if prctl(PR_SET_NAME) is supported. Return if not.
- if (!TryToSetThreadName("TestFunc"))
- return 0;
- EXPECT_DEATH(ThreadedTestSpawn(),
- ASAN_PCRE_DOTALL
- "WRITE .*thread T. .UseThr."
- ".*freed by thread T. .FreeThr. here:"
- ".*previously allocated by thread T. .AllocThr. here:"
- ".*Thread T. .UseThr. created by T.*TestFunc"
- ".*Thread T. .FreeThr. created by T"
- ".*Thread T. .AllocThr. created by T"
- "");
- return 0;
-}
-
-TEST(AddressSanitizer, ThreadNamesTest) {
- // Run ThreadedTestFunc in a separate thread because it tries to set a
- // thread name and we don't want to change the main thread's name.
- pthread_t t;
- PTHREAD_CREATE(&t, 0, ThreadedTestFunc, 0);
- PTHREAD_JOIN(t, 0);
-}
-
-#if ASAN_NEEDS_SEGV
-TEST(AddressSanitizer, ShadowGapTest) {
-#if SANITIZER_WORDSIZE == 32
- char *addr = (char*)0x22000000;
-#else
-# if defined(__powerpc64__)
- char *addr = (char*)0x024000800000;
-# else
- char *addr = (char*)0x0000100000080000;
-# endif
-#endif
- EXPECT_DEATH(*addr = 1, "AddressSanitizer: SEGV on unknown");
-}
-#endif // ASAN_NEEDS_SEGV
-
-extern "C" {
-NOINLINE static void UseThenFreeThenUse() {
- char *x = Ident((char*)malloc(8));
- *x = 1;
- free_aaa(x);
- *x = 2;
-}
-}
-
-TEST(AddressSanitizer, UseThenFreeThenUseTest) {
- EXPECT_DEATH(UseThenFreeThenUse(), "freed by thread");
-}
-
-TEST(AddressSanitizer, StrDupTest) {
- free(strdup(Ident("123")));
-}
-
-// Currently we create and poison redzone at right of global variables.
-static char static110[110];
-const char ConstGlob[7] = {1, 2, 3, 4, 5, 6, 7};
-static const char StaticConstGlob[3] = {9, 8, 7};
-
-TEST(AddressSanitizer, GlobalTest) {
- static char func_static15[15];
-
- static char fs1[10];
- static char fs2[10];
- static char fs3[10];
-
- glob5[Ident(0)] = 0;
- glob5[Ident(1)] = 0;
- glob5[Ident(2)] = 0;
- glob5[Ident(3)] = 0;
- glob5[Ident(4)] = 0;
-
- EXPECT_DEATH(glob5[Ident(5)] = 0,
- "0 bytes to the right of global variable.*glob5.* size 5");
- EXPECT_DEATH(glob5[Ident(5+6)] = 0,
- "6 bytes to the right of global variable.*glob5.* size 5");
- Ident(static110); // avoid optimizations
- static110[Ident(0)] = 0;
- static110[Ident(109)] = 0;
- EXPECT_DEATH(static110[Ident(110)] = 0,
- "0 bytes to the right of global variable");
- EXPECT_DEATH(static110[Ident(110+7)] = 0,
- "7 bytes to the right of global variable");
-
- Ident(func_static15); // avoid optimizations
- func_static15[Ident(0)] = 0;
- EXPECT_DEATH(func_static15[Ident(15)] = 0,
- "0 bytes to the right of global variable");
- EXPECT_DEATH(func_static15[Ident(15 + 9)] = 0,
- "9 bytes to the right of global variable");
-
- Ident(fs1);
- Ident(fs2);
- Ident(fs3);
-
- // We don't create left redzones, so this is not 100% guaranteed to fail.
- // But most likely will.
- EXPECT_DEATH(fs2[Ident(-1)] = 0, "is located.*of global variable");
-
- EXPECT_DEATH(Ident(Ident(ConstGlob)[8]),
- "is located 1 bytes to the right of .*ConstGlob");
- EXPECT_DEATH(Ident(Ident(StaticConstGlob)[5]),
- "is located 2 bytes to the right of .*StaticConstGlob");
-
- // call stuff from another file.
- GlobalsTest(0);
-}
-
-TEST(AddressSanitizer, GlobalStringConstTest) {
- static const char *zoo = "FOOBAR123";
- const char *p = Ident(zoo);
- EXPECT_DEATH(Ident(p[15]), "is ascii string 'FOOBAR123'");
-}
-
-TEST(AddressSanitizer, FileNameInGlobalReportTest) {
- static char zoo[10];
- const char *p = Ident(zoo);
- // The file name should be present in the report.
- EXPECT_DEATH(Ident(p[15]), "zoo.*asan_test.");
-}
-
-int *ReturnsPointerToALocalObject() {
- int a = 0;
- return Ident(&a);
-}
-
-#if ASAN_UAR == 1
-TEST(AddressSanitizer, LocalReferenceReturnTest) {
- int *(*f)() = Ident(ReturnsPointerToALocalObject);
- int *p = f();
- // Call 'f' a few more times, 'p' should still be poisoned.
- for (int i = 0; i < 32; i++)
- f();
- EXPECT_DEATH(*p = 1, "AddressSanitizer: stack-use-after-return");
- EXPECT_DEATH(*p = 1, "is located.*in frame .*ReturnsPointerToALocal");
-}
-#endif
-
-template <int kSize>
-NOINLINE static void FuncWithStack() {
- char x[kSize];
- Ident(x)[0] = 0;
- Ident(x)[kSize-1] = 0;
-}
-
-static void LotsOfStackReuse() {
- int LargeStack[10000];
- Ident(LargeStack)[0] = 0;
- for (int i = 0; i < 10000; i++) {
- FuncWithStack<128 * 1>();
- FuncWithStack<128 * 2>();
- FuncWithStack<128 * 4>();
- FuncWithStack<128 * 8>();
- FuncWithStack<128 * 16>();
- FuncWithStack<128 * 32>();
- FuncWithStack<128 * 64>();
- FuncWithStack<128 * 128>();
- FuncWithStack<128 * 256>();
- FuncWithStack<128 * 512>();
- Ident(LargeStack)[0] = 0;
- }
-}
-
-TEST(AddressSanitizer, StressStackReuseTest) {
- LotsOfStackReuse();
-}
-
-TEST(AddressSanitizer, ThreadedStressStackReuseTest) {
- const int kNumThreads = 20;
- pthread_t t[kNumThreads];
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_CREATE(&t[i], 0, (void* (*)(void *x))LotsOfStackReuse, 0);
- }
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_JOIN(t[i], 0);
- }
-}
-
-static void *PthreadExit(void *a) {
- pthread_exit(0);
- return 0;
-}
-
-TEST(AddressSanitizer, PthreadExitTest) {
- pthread_t t;
- for (int i = 0; i < 1000; i++) {
- PTHREAD_CREATE(&t, 0, PthreadExit, 0);
- PTHREAD_JOIN(t, 0);
- }
-}
-
-// FIXME: Why does clang-cl define __EXCEPTIONS?
-#if defined(__EXCEPTIONS) && !defined(_WIN32)
-NOINLINE static void StackReuseAndException() {
- int large_stack[1000];
- Ident(large_stack);
- ASAN_THROW(1);
-}
-
-// TODO(kcc): support exceptions with use-after-return.
-TEST(AddressSanitizer, DISABLED_StressStackReuseAndExceptionsTest) {
- for (int i = 0; i < 10000; i++) {
- try {
- StackReuseAndException();
- } catch(...) {
- }
- }
-}
-#endif
-
-#if !defined(_WIN32)
-TEST(AddressSanitizer, MlockTest) {
- EXPECT_EQ(0, mlockall(MCL_CURRENT));
- EXPECT_EQ(0, mlock((void*)0x12345, 0x5678));
- EXPECT_EQ(0, munlockall());
- EXPECT_EQ(0, munlock((void*)0x987, 0x654));
-}
-#endif
-
-struct LargeStruct {
- int foo[100];
-};
-
-// Test for bug http://llvm.org/bugs/show_bug.cgi?id=11763.
-// Struct copy should not cause asan warning even if lhs == rhs.
-TEST(AddressSanitizer, LargeStructCopyTest) {
- LargeStruct a;
- *Ident(&a) = *Ident(&a);
-}
-
-ATTRIBUTE_NO_SANITIZE_ADDRESS
-static void NoSanitizeAddress() {
- char *foo = new char[10];
- Ident(foo)[10] = 0;
- delete [] foo;
-}
-
-TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {
- Ident(NoSanitizeAddress)();
-}
-
-// The new/delete/etc mismatch checks don't work on Android,
-// as calls to new/delete go through malloc/free.
-// OS X support is tracked here:
-// https://code.google.com/p/address-sanitizer/issues/detail?id=131
-// Windows support is tracked here:
-// https://code.google.com/p/address-sanitizer/issues/detail?id=309
-#if !defined(__ANDROID__) && \
- !defined(__APPLE__) && \
- !defined(_WIN32)
-static string MismatchStr(const string &str) {
- return string("AddressSanitizer: alloc-dealloc-mismatch \\(") + str;
-}
-
-TEST(AddressSanitizer, AllocDeallocMismatch) {
- EXPECT_DEATH(free(Ident(new int)),
- MismatchStr("operator new vs free"));
- EXPECT_DEATH(free(Ident(new int[2])),
- MismatchStr("operator new \\[\\] vs free"));
- EXPECT_DEATH(delete (Ident(new int[2])),
- MismatchStr("operator new \\[\\] vs operator delete"));
- EXPECT_DEATH(delete (Ident((int*)malloc(2 * sizeof(int)))),
- MismatchStr("malloc vs operator delete"));
- EXPECT_DEATH(delete [] (Ident(new int)),
- MismatchStr("operator new vs operator delete \\[\\]"));
- EXPECT_DEATH(delete [] (Ident((int*)malloc(2 * sizeof(int)))),
- MismatchStr("malloc vs operator delete \\[\\]"));
-}
-#endif
-
-// ------------------ demo tests; run each one-by-one -------------
-// e.g. --gtest_filter=*DemoOOBLeftHigh --gtest_also_run_disabled_tests
-TEST(AddressSanitizer, DISABLED_DemoThreadedTest) {
- ThreadedTestSpawn();
-}
-
-void *SimpleBugOnSTack(void *x = 0) {
- char a[20];
- Ident(a)[20] = 0;
- return 0;
-}
-
-TEST(AddressSanitizer, DISABLED_DemoStackTest) {
- SimpleBugOnSTack();
-}
-
-TEST(AddressSanitizer, DISABLED_DemoThreadStackTest) {
- pthread_t t;
- PTHREAD_CREATE(&t, 0, SimpleBugOnSTack, 0);
- PTHREAD_JOIN(t, 0);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoUAFLowIn) {
- uaf_test<U1>(10, 0);
-}
-TEST(AddressSanitizer, DISABLED_DemoUAFLowLeft) {
- uaf_test<U1>(10, -2);
-}
-TEST(AddressSanitizer, DISABLED_DemoUAFLowRight) {
- uaf_test<U1>(10, 10);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoUAFHigh) {
- uaf_test<U1>(kLargeMalloc, 0);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOM) {
- size_t size = SANITIZER_WORDSIZE == 64 ? (size_t)(1ULL << 40) : (0xf0000000);
- printf("%p\n", malloc(size));
-}
-
-TEST(AddressSanitizer, DISABLED_DemoDoubleFreeTest) {
- DoubleFree();
-}
-
-TEST(AddressSanitizer, DISABLED_DemoNullDerefTest) {
- int *a = 0;
- Ident(a)[10] = 0;
-}
-
-TEST(AddressSanitizer, DISABLED_DemoFunctionStaticTest) {
- static char a[100];
- static char b[100];
- static char c[100];
- Ident(a);
- Ident(b);
- Ident(c);
- Ident(a)[5] = 0;
- Ident(b)[105] = 0;
- Ident(a)[5] = 0;
-}
-
-TEST(AddressSanitizer, DISABLED_DemoTooMuchMemoryTest) {
- const size_t kAllocSize = (1 << 28) - 1024;
- size_t total_size = 0;
- while (true) {
- void *x = malloc(kAllocSize);
- memset(x, 0, kAllocSize);
- total_size += kAllocSize;
- fprintf(stderr, "total: %ldM %p\n", (long)total_size >> 20, x);
- }
-}
-
-// http://code.google.com/p/address-sanitizer/issues/detail?id=66
-TEST(AddressSanitizer, BufferOverflowAfterManyFrees) {
- for (int i = 0; i < 1000000; i++) {
- delete [] (Ident(new char [8644]));
- }
- char *x = new char[8192];
- EXPECT_DEATH(x[Ident(8192)] = 0, "AddressSanitizer: heap-buffer-overflow");
- delete [] Ident(x);
-}
-
-
-// Test that instrumentation of stack allocations takes into account
-// AllocSize of a type, and not its StoreSize (16 vs 10 bytes for long double).
-// See http://llvm.org/bugs/show_bug.cgi?id=12047 for more details.
-TEST(AddressSanitizer, LongDoubleNegativeTest) {
- long double a, b;
- static long double c;
- memcpy(Ident(&a), Ident(&b), sizeof(long double));
- memcpy(Ident(&c), Ident(&b), sizeof(long double));
-}
-
-#if !defined(_WIN32)
-TEST(AddressSanitizer, pthread_getschedparam) {
- int policy;
- struct sched_param param;
- EXPECT_DEATH(
- pthread_getschedparam(pthread_self(), &policy, Ident(&param) + 2),
- "AddressSanitizer: stack-buffer-.*flow");
- EXPECT_DEATH(
- pthread_getschedparam(pthread_self(), Ident(&policy) - 1, &param),
- "AddressSanitizer: stack-buffer-.*flow");
- int res = pthread_getschedparam(pthread_self(), &policy, &param);
- ASSERT_EQ(0, res);
-}
-#endif
-
-#if SANITIZER_TEST_HAS_PRINTF_L
-static int vsnprintf_l_wrapper(char *s, size_t n,
- locale_t l, const char *format, ...) {
- va_list va;
- va_start(va, format);
- int res = vsnprintf_l(s, n , l, format, va);
- va_end(va);
- return res;
-}
-
-TEST(AddressSanitizer, snprintf_l) {
- char buff[5];
- // Check that snprintf_l() works fine with Asan.
- int res = snprintf_l(buff, 5,
- _LIBCPP_GET_C_LOCALE, "%s", "snprintf_l()");
- EXPECT_EQ(12, res);
- // Check that vsnprintf_l() works fine with Asan.
- res = vsnprintf_l_wrapper(buff, 5,
- _LIBCPP_GET_C_LOCALE, "%s", "vsnprintf_l()");
- EXPECT_EQ(13, res);
-
- EXPECT_DEATH(snprintf_l(buff, 10,
- _LIBCPP_GET_C_LOCALE, "%s", "snprintf_l()"),
- "AddressSanitizer: stack-buffer-overflow");
- EXPECT_DEATH(vsnprintf_l_wrapper(buff, 10,
- _LIBCPP_GET_C_LOCALE, "%s", "vsnprintf_l()"),
- "AddressSanitizer: stack-buffer-overflow");
-}
-#endif
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_test.ignore b/contrib/compiler-rt/lib/asan/tests/asan_test.ignore
deleted file mode 100644
index ea5c26099e75..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_test.ignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# blacklisted functions for instrumented ASan unit test
-fun:*IgnoreTest*
-fun:*SomeOtherFunc*
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_test_config.h b/contrib/compiler-rt/lib/asan/tests/asan_test_config.h
deleted file mode 100644
index 92f276307481..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_test_config.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===-- asan_test_config.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.
-//
-//===----------------------------------------------------------------------===//
-#if !defined(INCLUDED_FROM_ASAN_TEST_UTILS_H)
-# error "This file should be included into asan_test_utils.h only"
-#endif
-
-#ifndef ASAN_TEST_CONFIG_H
-#define ASAN_TEST_CONFIG_H
-
-#include <vector>
-#include <string>
-#include <map>
-
-using std::string;
-using std::vector;
-using std::map;
-
-#ifndef ASAN_UAR
-# error "please define ASAN_UAR"
-#endif
-
-#ifndef ASAN_HAS_EXCEPTIONS
-# error "please define ASAN_HAS_EXCEPTIONS"
-#endif
-
-#ifndef ASAN_HAS_BLACKLIST
-# error "please define ASAN_HAS_BLACKLIST"
-#endif
-
-#ifndef ASAN_NEEDS_SEGV
-# if defined(_WIN32)
-# define ASAN_NEEDS_SEGV 0
-# else
-# define ASAN_NEEDS_SEGV 1
-# endif
-#endif
-
-#ifndef ASAN_AVOID_EXPENSIVE_TESTS
-# define ASAN_AVOID_EXPENSIVE_TESTS 0
-#endif
-
-#define ASAN_PCRE_DOTALL ""
-
-#endif // ASAN_TEST_CONFIG_H
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_test_main.cc b/contrib/compiler-rt/lib/asan/tests/asan_test_main.cc
deleted file mode 100644
index 1746c5f4837b..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_test_main.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-//===-- asan_test_main.cc -------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-int main(int argc, char **argv) {
- testing::GTEST_FLAG(death_test_style) = "threadsafe";
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/contrib/compiler-rt/lib/asan/tests/asan_test_utils.h b/contrib/compiler-rt/lib/asan/tests/asan_test_utils.h
deleted file mode 100644
index 03d17cfb26a7..000000000000
--- a/contrib/compiler-rt/lib/asan/tests/asan_test_utils.h
+++ /dev/null
@@ -1,107 +0,0 @@
-//===-- asan_test_utils.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.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_TEST_UTILS_H
-#define ASAN_TEST_UTILS_H
-
-#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)
-# define INCLUDED_FROM_ASAN_TEST_UTILS_H
-# include "asan_test_config.h"
-# undef INCLUDED_FROM_ASAN_TEST_UTILS_H
-#endif
-
-#include "sanitizer_test_utils.h"
-#include "sanitizer_pthread_wrappers.h"
-
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <assert.h>
-#include <algorithm>
-
-#if !defined(_WIN32)
-# include <strings.h>
-# include <sys/mman.h>
-# include <setjmp.h>
-#endif
-
-#ifdef __linux__
-# include <sys/prctl.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#if !defined(__APPLE__) && !defined(__FreeBSD__)
-#include <malloc.h>
-#endif
-
-#if ASAN_HAS_EXCEPTIONS
-# define ASAN_THROW(x) throw (x)
-#else
-# define ASAN_THROW(x)
-#endif
-
-typedef uint8_t U1;
-typedef uint16_t U2;
-typedef uint32_t U4;
-typedef uint64_t U8;
-
-static const int kPageSize = 4096;
-
-const size_t kLargeMalloc = 1 << 24;
-
-extern void free_aaa(void *p);
-extern void *malloc_aaa(size_t size);
-
-template<typename T>
-NOINLINE void asan_write(T *a) {
- *a = 0;
-}
-
-string RightOOBErrorMessage(int oob_distance, bool is_write);
-string RightOOBWriteMessage(int oob_distance);
-string RightOOBReadMessage(int oob_distance);
-string LeftOOBErrorMessage(int oob_distance, bool is_write);
-string LeftOOBWriteMessage(int oob_distance);
-string LeftOOBReadMessage(int oob_distance);
-string LeftOOBAccessMessage(int oob_distance);
-char* MallocAndMemsetString(size_t size, char ch);
-char* MallocAndMemsetString(size_t size);
-
-extern char glob1[1];
-extern char glob2[2];
-extern char glob3[3];
-extern char glob4[4];
-extern char glob5[5];
-extern char glob6[6];
-extern char glob7[7];
-extern char glob8[8];
-extern char glob9[9];
-extern char glob10[10];
-extern char glob11[11];
-extern char glob12[12];
-extern char glob13[13];
-extern char glob14[14];
-extern char glob15[15];
-extern char glob16[16];
-extern char glob17[17];
-extern char glob1000[1000];
-extern char glob10000[10000];
-extern char glob100000[100000];
-extern int GlobalsTest(int x);
-
-#endif // ASAN_TEST_UTILS_H