1 //===-- asan_flags.cc -------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of AddressSanitizer, an address sanity checker. 11 // 12 // ASan flag parsing logic. 13 //===----------------------------------------------------------------------===// 14 15 #include "asan_activation.h" 16 #include "asan_flags.h" 17 #include "asan_interface_internal.h" 18 #include "asan_stack.h" 19 #include "lsan/lsan_common.h" 20 #include "sanitizer_common/sanitizer_common.h" 21 #include "sanitizer_common/sanitizer_flags.h" 22 #include "sanitizer_common/sanitizer_flag_parser.h" 23 #include "ubsan/ubsan_flags.h" 24 #include "ubsan/ubsan_platform.h" 25 26 namespace __asan { 27 28 Flags asan_flags_dont_use_directly; // use via flags(). 29 30 static const char *MaybeCallAsanDefaultOptions() { 31 return (&__asan_default_options) ? __asan_default_options() : ""; 32 } 33 34 static const char *MaybeUseAsanDefaultOptionsCompileDefinition() { 35 #ifdef ASAN_DEFAULT_OPTIONS 36 // Stringize the macro value. 37 # define ASAN_STRINGIZE(x) #x 38 # define ASAN_STRINGIZE_OPTIONS(options) ASAN_STRINGIZE(options) 39 return ASAN_STRINGIZE_OPTIONS(ASAN_DEFAULT_OPTIONS); 40 #else 41 return ""; 42 #endif 43 } 44 45 void Flags::SetDefaults() { 46 #define ASAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 47 #include "asan_flags.inc" 48 #undef ASAN_FLAG 49 } 50 51 static void RegisterAsanFlags(FlagParser *parser, Flags *f) { 52 #define ASAN_FLAG(Type, Name, DefaultValue, Description) \ 53 RegisterFlag(parser, #Name, Description, &f->Name); 54 #include "asan_flags.inc" 55 #undef ASAN_FLAG 56 } 57 58 void InitializeFlags() { 59 // Set the default values and prepare for parsing ASan and common flags. 60 SetCommonFlagsDefaults(); 61 { 62 CommonFlags cf; 63 cf.CopyFrom(*common_flags()); 64 cf.detect_leaks = CAN_SANITIZE_LEAKS; 65 cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH"); 66 cf.malloc_context_size = kDefaultMallocContextSize; 67 cf.intercept_tls_get_addr = true; 68 cf.exitcode = 1; 69 OverrideCommonFlags(cf); 70 } 71 Flags *f = flags(); 72 f->SetDefaults(); 73 74 FlagParser asan_parser; 75 RegisterAsanFlags(&asan_parser, f); 76 RegisterCommonFlags(&asan_parser); 77 78 // Set the default values and prepare for parsing LSan and UBSan flags 79 // (which can also overwrite common flags). 80 #if CAN_SANITIZE_LEAKS 81 __lsan::Flags *lf = __lsan::flags(); 82 lf->SetDefaults(); 83 84 FlagParser lsan_parser; 85 __lsan::RegisterLsanFlags(&lsan_parser, lf); 86 RegisterCommonFlags(&lsan_parser); 87 #endif 88 89 #if CAN_SANITIZE_UB 90 __ubsan::Flags *uf = __ubsan::flags(); 91 uf->SetDefaults(); 92 93 FlagParser ubsan_parser; 94 __ubsan::RegisterUbsanFlags(&ubsan_parser, uf); 95 RegisterCommonFlags(&ubsan_parser); 96 #endif 97 98 // Override from ASan compile definition. 99 const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition(); 100 asan_parser.ParseString(asan_compile_def); 101 102 // Override from user-specified string. 103 const char *asan_default_options = MaybeCallAsanDefaultOptions(); 104 asan_parser.ParseString(asan_default_options); 105 #if CAN_SANITIZE_UB 106 const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions(); 107 ubsan_parser.ParseString(ubsan_default_options); 108 #endif 109 110 // Override from command line. 111 asan_parser.ParseString(GetEnv("ASAN_OPTIONS")); 112 #if CAN_SANITIZE_LEAKS 113 lsan_parser.ParseString(GetEnv("LSAN_OPTIONS")); 114 #endif 115 #if CAN_SANITIZE_UB 116 ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); 117 #endif 118 119 SetVerbosity(common_flags()->verbosity); 120 121 // TODO(eugenis): dump all flags at verbosity>=2? 122 if (Verbosity()) ReportUnrecognizedFlags(); 123 124 if (common_flags()->help) { 125 // TODO(samsonov): print all of the flags (ASan, LSan, common). 126 asan_parser.PrintFlagDescriptions(); 127 } 128 129 // Flag validation: 130 if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) { 131 Report("%s: detect_leaks is not supported on this platform.\n", 132 SanitizerToolName); 133 Die(); 134 } 135 // Make "strict_init_order" imply "check_initialization_order". 136 // TODO(samsonov): Use a single runtime flag for an init-order checker. 137 if (f->strict_init_order) { 138 f->check_initialization_order = true; 139 } 140 CHECK_LE((uptr)common_flags()->malloc_context_size, kStackTraceMax); 141 CHECK_LE(f->min_uar_stack_size_log, f->max_uar_stack_size_log); 142 CHECK_GE(f->redzone, 16); 143 CHECK_GE(f->max_redzone, f->redzone); 144 CHECK_LE(f->max_redzone, 2048); 145 CHECK(IsPowerOfTwo(f->redzone)); 146 CHECK(IsPowerOfTwo(f->max_redzone)); 147 148 // quarantine_size is deprecated but we still honor it. 149 // quarantine_size can not be used together with quarantine_size_mb. 150 if (f->quarantine_size >= 0 && f->quarantine_size_mb >= 0) { 151 Report("%s: please use either 'quarantine_size' (deprecated) or " 152 "quarantine_size_mb, but not both\n", SanitizerToolName); 153 Die(); 154 } 155 if (f->quarantine_size >= 0) 156 f->quarantine_size_mb = f->quarantine_size >> 20; 157 if (f->quarantine_size_mb < 0) { 158 const int kDefaultQuarantineSizeMb = 159 (ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8; 160 f->quarantine_size_mb = kDefaultQuarantineSizeMb; 161 } 162 } 163 164 } // namespace __asan 165 166 #if !SANITIZER_SUPPORTS_WEAK_HOOKS 167 extern "C" { 168 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE 169 const char* __asan_default_options() { return ""; } 170 } // extern "C" 171 #endif 172