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 26namespace __asan { 27 28Flags asan_flags_dont_use_directly; // use via flags(). 29 30static const char *MaybeCallAsanDefaultOptions() { 31 return (&__asan_default_options) ? __asan_default_options() : ""; 32} 33 34static 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 45void Flags::SetDefaults() { 46#define ASAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 47#include "asan_flags.inc" 48#undef ASAN_FLAG 49} 50 51static 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 58void 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 OverrideCommonFlags(cf); 69 } 70 Flags *f = flags(); 71 f->SetDefaults(); 72 73 FlagParser asan_parser; 74 RegisterAsanFlags(&asan_parser, f); 75 RegisterCommonFlags(&asan_parser); 76 77 // Set the default values and prepare for parsing LSan and UBSan flags 78 // (which can also overwrite common flags). 79#if CAN_SANITIZE_LEAKS 80 __lsan::Flags *lf = __lsan::flags(); 81 lf->SetDefaults(); 82 83 FlagParser lsan_parser; 84 __lsan::RegisterLsanFlags(&lsan_parser, lf); 85 RegisterCommonFlags(&lsan_parser); 86#endif 87 88#if CAN_SANITIZE_UB 89 __ubsan::Flags *uf = __ubsan::flags(); 90 uf->SetDefaults(); 91 92 FlagParser ubsan_parser; 93 __ubsan::RegisterUbsanFlags(&ubsan_parser, uf); 94 RegisterCommonFlags(&ubsan_parser); 95#endif 96 97 // Override from ASan compile definition. 98 const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition(); 99 asan_parser.ParseString(asan_compile_def); 100 101 // Override from user-specified string. 102 const char *asan_default_options = MaybeCallAsanDefaultOptions(); 103 asan_parser.ParseString(asan_default_options); 104#if CAN_SANITIZE_UB 105 const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions(); 106 ubsan_parser.ParseString(ubsan_default_options); 107#endif 108 109 // Override from command line. 110 asan_parser.ParseString(GetEnv("ASAN_OPTIONS")); 111#if CAN_SANITIZE_LEAKS 112 lsan_parser.ParseString(GetEnv("LSAN_OPTIONS")); 113#endif 114#if CAN_SANITIZE_UB 115 ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); 116#endif 117 118 // Let activation flags override current settings. On Android they come 119 // from a system property. On other platforms this is no-op. 120 if (!flags()->start_deactivated) { 121 char buf[100]; 122 GetExtraActivationFlags(buf, sizeof(buf)); 123 asan_parser.ParseString(buf); 124 } 125 126 SetVerbosity(common_flags()->verbosity); 127 128 // TODO(eugenis): dump all flags at verbosity>=2? 129 if (Verbosity()) ReportUnrecognizedFlags(); 130 131 if (common_flags()->help) { 132 // TODO(samsonov): print all of the flags (ASan, LSan, common). 133 asan_parser.PrintFlagDescriptions(); 134 } 135 136 // Flag validation: 137 if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) { 138 Report("%s: detect_leaks is not supported on this platform.\n", 139 SanitizerToolName); 140 Die(); 141 } 142 // Make "strict_init_order" imply "check_initialization_order". 143 // TODO(samsonov): Use a single runtime flag for an init-order checker. 144 if (f->strict_init_order) { 145 f->check_initialization_order = true; 146 } 147 CHECK_LE((uptr)common_flags()->malloc_context_size, kStackTraceMax); 148 CHECK_LE(f->min_uar_stack_size_log, f->max_uar_stack_size_log); 149 CHECK_GE(f->redzone, 16); 150 CHECK_GE(f->max_redzone, f->redzone); 151 CHECK_LE(f->max_redzone, 2048); 152 CHECK(IsPowerOfTwo(f->redzone)); 153 CHECK(IsPowerOfTwo(f->max_redzone)); 154 155 // quarantine_size is deprecated but we still honor it. 156 // quarantine_size can not be used together with quarantine_size_mb. 157 if (f->quarantine_size >= 0 && f->quarantine_size_mb >= 0) { 158 Report("%s: please use either 'quarantine_size' (deprecated) or " 159 "quarantine_size_mb, but not both\n", SanitizerToolName); 160 Die(); 161 } 162 if (f->quarantine_size >= 0) 163 f->quarantine_size_mb = f->quarantine_size >> 20; 164 if (f->quarantine_size_mb < 0) { 165 const int kDefaultQuarantineSizeMb = 166 (ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8; 167 f->quarantine_size_mb = kDefaultQuarantineSizeMb; 168 } 169} 170 171} // namespace __asan 172 173#if !SANITIZER_SUPPORTS_WEAK_HOOKS 174extern "C" { 175SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE 176const char* __asan_default_options() { return ""; } 177} // extern "C" 178#endif 179