1*68d75effSDimitry Andric //===-- ubsan_flags.cpp ---------------------------------------------------===// 2*68d75effSDimitry Andric // 3*68d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*68d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*68d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*68d75effSDimitry Andric // 7*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 8*68d75effSDimitry Andric // 9*68d75effSDimitry Andric // Runtime flags for UndefinedBehaviorSanitizer. 10*68d75effSDimitry Andric // 11*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 12*68d75effSDimitry Andric 13*68d75effSDimitry Andric #include "ubsan_platform.h" 14*68d75effSDimitry Andric #if CAN_SANITIZE_UB 15*68d75effSDimitry Andric #include "ubsan_flags.h" 16*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_common.h" 17*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_flags.h" 18*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_flag_parser.h" 19*68d75effSDimitry Andric 20*68d75effSDimitry Andric #include <stdlib.h> 21*68d75effSDimitry Andric 22*68d75effSDimitry Andric namespace __ubsan { 23*68d75effSDimitry Andric 24*68d75effSDimitry Andric const char *MaybeCallUbsanDefaultOptions() { 25*68d75effSDimitry Andric return (&__ubsan_default_options) ? __ubsan_default_options() : ""; 26*68d75effSDimitry Andric } 27*68d75effSDimitry Andric 28*68d75effSDimitry Andric static const char *GetFlag(const char *flag) { 29*68d75effSDimitry Andric // We cannot call getenv() from inside a preinit array initializer 30*68d75effSDimitry Andric if (SANITIZER_CAN_USE_PREINIT_ARRAY) { 31*68d75effSDimitry Andric return GetEnv(flag); 32*68d75effSDimitry Andric } else { 33*68d75effSDimitry Andric return getenv(flag); 34*68d75effSDimitry Andric } 35*68d75effSDimitry Andric } 36*68d75effSDimitry Andric 37*68d75effSDimitry Andric Flags ubsan_flags; 38*68d75effSDimitry Andric 39*68d75effSDimitry Andric void Flags::SetDefaults() { 40*68d75effSDimitry Andric #define UBSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 41*68d75effSDimitry Andric #include "ubsan_flags.inc" 42*68d75effSDimitry Andric #undef UBSAN_FLAG 43*68d75effSDimitry Andric } 44*68d75effSDimitry Andric 45*68d75effSDimitry Andric void RegisterUbsanFlags(FlagParser *parser, Flags *f) { 46*68d75effSDimitry Andric #define UBSAN_FLAG(Type, Name, DefaultValue, Description) \ 47*68d75effSDimitry Andric RegisterFlag(parser, #Name, Description, &f->Name); 48*68d75effSDimitry Andric #include "ubsan_flags.inc" 49*68d75effSDimitry Andric #undef UBSAN_FLAG 50*68d75effSDimitry Andric } 51*68d75effSDimitry Andric 52*68d75effSDimitry Andric void InitializeFlags() { 53*68d75effSDimitry Andric SetCommonFlagsDefaults(); 54*68d75effSDimitry Andric { 55*68d75effSDimitry Andric CommonFlags cf; 56*68d75effSDimitry Andric cf.CopyFrom(*common_flags()); 57*68d75effSDimitry Andric cf.external_symbolizer_path = GetFlag("UBSAN_SYMBOLIZER_PATH"); 58*68d75effSDimitry Andric OverrideCommonFlags(cf); 59*68d75effSDimitry Andric } 60*68d75effSDimitry Andric 61*68d75effSDimitry Andric Flags *f = flags(); 62*68d75effSDimitry Andric f->SetDefaults(); 63*68d75effSDimitry Andric 64*68d75effSDimitry Andric FlagParser parser; 65*68d75effSDimitry Andric RegisterCommonFlags(&parser); 66*68d75effSDimitry Andric RegisterUbsanFlags(&parser, f); 67*68d75effSDimitry Andric 68*68d75effSDimitry Andric // Override from user-specified string. 69*68d75effSDimitry Andric parser.ParseString(MaybeCallUbsanDefaultOptions()); 70*68d75effSDimitry Andric // Override from environment variable. 71*68d75effSDimitry Andric parser.ParseStringFromEnv("UBSAN_OPTIONS"); 72*68d75effSDimitry Andric InitializeCommonFlags(); 73*68d75effSDimitry Andric if (Verbosity()) ReportUnrecognizedFlags(); 74*68d75effSDimitry Andric 75*68d75effSDimitry Andric if (common_flags()->help) parser.PrintFlagDescriptions(); 76*68d75effSDimitry Andric } 77*68d75effSDimitry Andric 78*68d75effSDimitry Andric } // namespace __ubsan 79*68d75effSDimitry Andric 80*68d75effSDimitry Andric SANITIZER_INTERFACE_WEAK_DEF(const char *, __ubsan_default_options, void) { 81*68d75effSDimitry Andric return ""; 82*68d75effSDimitry Andric } 83*68d75effSDimitry Andric 84*68d75effSDimitry Andric #endif // CAN_SANITIZE_UB 85