summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/asan/asan_rtl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/asan/asan_rtl.cc')
-rw-r--r--compiler-rt/lib/asan/asan_rtl.cc242
1 files changed, 110 insertions, 132 deletions
diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc
index 616266cf68c..89f46b1ef86 100644
--- a/compiler-rt/lib/asan/asan_rtl.cc
+++ b/compiler-rt/lib/asan/asan_rtl.cc
@@ -22,6 +22,7 @@
#include "asan_thread.h"
#include "asan_thread_registry.h"
#include "sanitizer_common/sanitizer_atomic.h"
+#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_libc.h"
namespace __sanitizer {
@@ -33,17 +34,17 @@ void Die() {
// Don't die twice - run a busy loop.
while (1) { }
}
- if (FLAG_sleep_before_dying) {
- Report("Sleeping for %zd second(s)\n", FLAG_sleep_before_dying);
- SleepForSeconds(FLAG_sleep_before_dying);
+ if (flags()->sleep_before_dying) {
+ Report("Sleeping for %zd second(s)\n", flags()->sleep_before_dying);
+ SleepForSeconds(flags()->sleep_before_dying);
}
- if (FLAG_unmap_shadow_on_exit)
+ if (flags()->unmap_shadow_on_exit)
UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
if (death_callback)
death_callback();
- if (FLAG_abort_on_error)
+ if (flags()->abort_on_error)
Abort();
- Exit(FLAG_exitcode);
+ Exit(flags()->exitcode);
}
void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) {
@@ -60,31 +61,97 @@ namespace __asan {
// -------------------------- Flags ------------------------- {{{1
static const uptr kMallocContextSize = 30;
-uptr FLAG_malloc_context_size = kMallocContextSize;
-uptr FLAG_max_malloc_fill_size = 0;
-s64 FLAG_v = 0;
-uptr FLAG_redzone = (ASAN_LOW_MEMORY) ? 64 : 128; // power of two, >= 32
-uptr FLAG_quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 24 : 1UL << 28;
-static s64 FLAG_atexit = 0;
-bool FLAG_poison_shadow = 1;
-s64 FLAG_report_globals = 1;
-bool FLAG_handle_segv = ASAN_NEEDS_SEGV;
-bool FLAG_use_sigaltstack = 0;
-bool FLAG_symbolize = 0;
-s64 FLAG_demangle = 1;
-s64 FLAG_debug = 0;
-bool FLAG_replace_cfallocator = 1; // Used on Mac only.
-bool FLAG_mac_ignore_invalid_free = 0; // Used on Mac only.
-bool FLAG_replace_str = 1;
-bool FLAG_replace_intrin = 1;
-bool FLAG_use_fake_stack = 1;
-s64 FLAG_exitcode = ASAN_DEFAULT_FAILURE_EXITCODE;
-bool FLAG_allow_user_poisoning = 1;
-s64 FLAG_sleep_before_dying = 0;
-bool FLAG_abort_on_error = 0;
-bool FLAG_unmap_shadow_on_exit = 0;
-bool FLAG_disable_core = __WORDSIZE == 64;
-bool FLAG_check_malloc_usable_size = 1;
+static Flags asan_flags;
+
+Flags *flags() {
+ return &asan_flags;
+}
+
+// Can be overriden in frontend.
+void WEAK OverrideFlags(Flags *f) {
+ (void)f;
+}
+
+static void ParseFlagsFromString(Flags *f, const char *str) {
+ ParseFlag(str, &f->quarantine_size, "quarantine_size");
+ ParseFlag(str, &f->symbolize, "symbolize");
+ ParseFlag(str, &f->verbosity, "verbosity");
+ ParseFlag(str, &f->redzone, "redzone");
+ CHECK(f->redzone >= 16);
+ CHECK(IsPowerOfTwo(f->redzone));
+
+ ParseFlag(str, &f->debug, "debug");
+ ParseFlag(str, &f->poison_shadow, "poison_shadow");
+ ParseFlag(str, &f->report_globals, "report_globals");
+ ParseFlag(str, &f->malloc_context_size, "malloc_context_size");
+ CHECK(f->malloc_context_size <= kMallocContextSize);
+
+ ParseFlag(str, &f->replace_str, "replace_str");
+ ParseFlag(str, &f->replace_intrin, "replace_intrin");
+ ParseFlag(str, &f->replace_cfallocator, "replace_cfallocator");
+ ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free");
+ ParseFlag(str, &f->use_fake_stack, "use_fake_stack");
+ ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size");
+ ParseFlag(str, &f->exitcode, "exitcode");
+ ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning");
+ ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying");
+ ParseFlag(str, &f->handle_segv, "handle_segv");
+ ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack");
+ // Allow the users to work around the bug in Nvidia drivers prior to 295.*.
+ ParseFlag(str, &f->check_malloc_usable_size, "check_malloc_usable_size");
+ ParseFlag(str, &f->unmap_shadow_on_exit, "unmap_shadow_on_exit");
+ ParseFlag(str, &f->abort_on_error, "abort_on_error");
+ ParseFlag(str, &f->atexit, "atexit");
+ // By default, disable core dumper on 64-bit --
+ // it makes little sense to dump 16T+ core.
+ ParseFlag(str, &f->disable_core, "disable_core");
+}
+
+void InitializeFlags(Flags *f, const char *env) {
+ internal_memset(f, 0, sizeof(*f));
+
+ f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 24 : 1UL << 28;
+ f->symbolize = false;
+ f->verbosity = 0;
+ f->redzone = (ASAN_LOW_MEMORY) ? 64 : 128; // power of two, >= 32.
+ f->debug = 0;
+ f->poison_shadow = true;
+ f->report_globals = 1;
+ f->malloc_context_size = kMallocContextSize;
+ f->replace_str = true;
+ f->replace_intrin = true;
+ f->replace_cfallocator = true; // Used on Mac only.
+ f->mac_ignore_invalid_free = false; // Used on Mac only.
+ f->use_fake_stack = true;
+ f->max_malloc_fill_size = 0;
+ f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE;
+ f->allow_user_poisoning = true;
+ f->sleep_before_dying = 0;
+ f->handle_segv = ASAN_NEEDS_SEGV;
+ f->use_sigaltstack = false;
+ f->check_malloc_usable_size = true;
+ f->unmap_shadow_on_exit = false;
+ f->abort_on_error = false;
+ f->atexit = false;
+ f->disable_core = (__WORDSIZE == 64);
+
+ // Let a frontend override.
+ OverrideFlags(f);
+
+ // Override from user-specified string.
+#if !defined(_WIN32)
+ if (__asan_default_options) {
+ ParseFlagsFromString(f, __asan_default_options);
+ if (flags()->verbosity) {
+ Report("Using the defaults from __asan_default_options: %s\n",
+ __asan_default_options);
+ }
+ }
+#endif
+
+ // Override from command line.
+ ParseFlagsFromString(f, env);
+}
// -------------------------- Globals --------------------- {{{1
int asan_inited;
@@ -264,44 +331,6 @@ static NOINLINE void force_interface_symbols() {
}
// -------------------------- Init ------------------- {{{1
-static void IntFlagValue(const char *flags, const char *flag,
- s64 *out_val) {
- if (!flags) return;
- const char *str = internal_strstr(flags, flag);
- if (!str) return;
- *out_val = internal_atoll(str + internal_strlen(flag));
-}
-
-static void BoolFlagValue(const char *flags, const char *flag,
- bool *out_val) {
- if (!flags) return;
- const char *str = internal_strstr(flags, flag);
- if (!str) return;
- const char *suffix = str + internal_strlen(flag);
- if (!internal_atoll(str + internal_strlen(flag))) {
- if (suffix[0] == '0') {
- *out_val = false;
- return;
- }
- } else {
- *out_val = true;
- return;
- }
- switch (suffix[0]) {
- case 'y':
- case 't': {
- *out_val = true;
- break;
- }
- case 'n':
- case 'f': {
- *out_val = false;
- break;
- }
- default: return;
- }
-}
-
static void asan_atexit() {
AsanPrintf("AddressSanitizer exit stats:\n");
__asan_print_accumulated_stats();
@@ -313,8 +342,8 @@ static void asan_atexit() {
using namespace __asan; // NOLINT
int __asan_set_error_exit_code(int exit_code) {
- int old = FLAG_exitcode;
- FLAG_exitcode = exit_code;
+ int old = flags()->exitcode;
+ flags()->exitcode = exit_code;
return old;
}
@@ -403,7 +432,7 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp,
access_size ? (is_write ? "WRITE" : "READ") : "ACCESS",
access_size, (void*)addr, curr_tid);
- if (FLAG_debug) {
+ if (flags()->debug) {
PrintBytes("PC: ", (uptr*)pc);
}
@@ -437,48 +466,6 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp,
Die();
}
-static void ParseAsanOptions(const char *options) {
- IntFlagValue(options, "malloc_context_size=",
- (s64*)&FLAG_malloc_context_size);
- CHECK(FLAG_malloc_context_size <= kMallocContextSize);
-
- IntFlagValue(options, "max_malloc_fill_size=",
- (s64*)&FLAG_max_malloc_fill_size);
-
- IntFlagValue(options, "verbosity=", &FLAG_v);
-
- IntFlagValue(options, "redzone=", (s64*)&FLAG_redzone);
- CHECK(FLAG_redzone >= 16);
- CHECK(IsPowerOfTwo(FLAG_redzone));
- IntFlagValue(options, "quarantine_size=", (s64*)&FLAG_quarantine_size);
-
- IntFlagValue(options, "atexit=", &FLAG_atexit);
- BoolFlagValue(options, "poison_shadow=", &FLAG_poison_shadow);
- IntFlagValue(options, "report_globals=", &FLAG_report_globals);
- BoolFlagValue(options, "handle_segv=", &FLAG_handle_segv);
- BoolFlagValue(options, "use_sigaltstack=", &FLAG_use_sigaltstack);
- BoolFlagValue(options, "symbolize=", &FLAG_symbolize);
- IntFlagValue(options, "demangle=", &FLAG_demangle);
- IntFlagValue(options, "debug=", &FLAG_debug);
- BoolFlagValue(options, "replace_cfallocator=", &FLAG_replace_cfallocator);
- BoolFlagValue(options, "mac_ignore_invalid_free=",
- &FLAG_mac_ignore_invalid_free);
- BoolFlagValue(options, "replace_str=", &FLAG_replace_str);
- BoolFlagValue(options, "replace_intrin=", &FLAG_replace_intrin);
- BoolFlagValue(options, "use_fake_stack=", &FLAG_use_fake_stack);
- IntFlagValue(options, "exitcode=", &FLAG_exitcode);
- BoolFlagValue(options, "allow_user_poisoning=", &FLAG_allow_user_poisoning);
- IntFlagValue(options, "sleep_before_dying=", &FLAG_sleep_before_dying);
- BoolFlagValue(options, "abort_on_error=", &FLAG_abort_on_error);
- BoolFlagValue(options, "unmap_shadow_on_exit=", &FLAG_unmap_shadow_on_exit);
- // By default, disable core dumper on 64-bit --
- // it makes little sense to dump 16T+ core.
- BoolFlagValue(options, "disable_core=", &FLAG_disable_core);
-
- // Allow the users to work around the bug in Nvidia drivers prior to 295.*.
- BoolFlagValue(options, "check_malloc_usable_size=",
- &FLAG_check_malloc_usable_size);
-}
void __asan_init() {
if (asan_inited) return;
@@ -487,24 +474,15 @@ void __asan_init() {
// Make sure we are not statically linked.
AsanDoesNotSupportStaticLinkage();
-#if !defined(_WIN32)
- if (__asan_default_options) {
- ParseAsanOptions(__asan_default_options);
- if (FLAG_v) {
- Report("Using the defaults from __asan_default_options: %s\n",
- __asan_default_options);
- }
- }
-#endif
- // flags
+ // Initialize flags.
const char *options = GetEnv("ASAN_OPTIONS");
- ParseAsanOptions(options);
+ InitializeFlags(flags(), options);
- if (FLAG_v && options) {
+ if (flags()->verbosity && options) {
Report("Parsed ASAN_OPTIONS: %s\n", options);
}
- if (FLAG_atexit) {
+ if (flags()->atexit) {
Atexit(asan_atexit);
}
@@ -514,7 +492,7 @@ void __asan_init() {
ReplaceSystemMalloc();
ReplaceOperatorsNewAndDelete();
- if (FLAG_v) {
+ if (flags()->verbosity) {
Printf("|| `[%p, %p]` || HighMem ||\n",
(void*)kHighMemBeg, (void*)kHighMemEnd);
Printf("|| `[%p, %p]` || HighShadow ||\n",
@@ -530,8 +508,8 @@ void __asan_init() {
(void*)MEM_TO_SHADOW(kLowShadowEnd),
(void*)MEM_TO_SHADOW(kHighShadowBeg),
(void*)MEM_TO_SHADOW(kHighShadowEnd));
- Printf("red_zone=%zu\n", (uptr)FLAG_redzone);
- Printf("malloc_context_size=%zu\n", (uptr)FLAG_malloc_context_size);
+ Printf("red_zone=%zu\n", (uptr)flags()->redzone);
+ Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
@@ -539,7 +517,7 @@ void __asan_init() {
CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
}
- if (FLAG_disable_core) {
+ if (flags()->disable_core) {
DisableCoreDumper();
}
@@ -574,7 +552,7 @@ void __asan_init() {
asanThreadRegistry().GetMain()->ThreadStart();
force_interface_symbols(); // no-op.
- if (FLAG_v) {
+ if (flags()->verbosity) {
Report("AddressSanitizer Init done\n");
}
}
OpenPOWER on IntegriCloud