xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_flags.cpp (revision 68d75eff68281c1b445e3010bb975eae07aac225)
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