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 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 InitializeCommonFlags(); 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 if (!f->replace_str && common_flags()->intercept_strlen) { 163 Report("WARNING: strlen interceptor is enabled even though replace_str=0. " 164 "Use intercept_strlen=0 to disable it."); 165 } 166 if (!f->replace_str && common_flags()->intercept_strchr) { 167 Report("WARNING: strchr* interceptors are enabled even though " 168 "replace_str=0. Use intercept_strchr=0 to disable them."); 169 } 170} 171 172} // namespace __asan 173 174#if !SANITIZER_SUPPORTS_WEAK_HOOKS 175extern "C" { 176SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE 177const char* __asan_default_options() { return ""; } 178} // extern "C" 179#endif 180