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