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