]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/scudo/scudo_flags.cpp
Merge ^/head r327341 through r327623.
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / scudo / scudo_flags.cpp
1 //===-- scudo_flags.cpp -----------------------------------------*- 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 /// Hardened Allocator flag parsing logic.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "scudo_flags.h"
15 #include "scudo_utils.h"
16
17 #include "sanitizer_common/sanitizer_flags.h"
18 #include "sanitizer_common/sanitizer_flag_parser.h"
19
20 SANITIZER_INTERFACE_WEAK_DEF(const char*, __scudo_default_options, void);
21
22 namespace __scudo {
23
24 static Flags ScudoFlags;  // Use via getFlags().
25
26 void Flags::setDefaults() {
27 #define SCUDO_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
28 #include "scudo_flags.inc"
29 #undef SCUDO_FLAG
30 }
31
32 static void RegisterScudoFlags(FlagParser *parser, Flags *f) {
33 #define SCUDO_FLAG(Type, Name, DefaultValue, Description) \
34   RegisterFlag(parser, #Name, Description, &f->Name);
35 #include "scudo_flags.inc"
36 #undef SCUDO_FLAG
37 }
38
39 static const char *getScudoDefaultOptions() {
40   return (&__scudo_default_options) ? __scudo_default_options() : "";
41 }
42
43 void initFlags() {
44   SetCommonFlagsDefaults();
45   {
46     CommonFlags cf;
47     cf.CopyFrom(*common_flags());
48     cf.exitcode = 1;
49     OverrideCommonFlags(cf);
50   }
51   Flags *f = getFlags();
52   f->setDefaults();
53
54   FlagParser ScudoParser;
55   RegisterScudoFlags(&ScudoParser, f);
56   RegisterCommonFlags(&ScudoParser);
57
58   // Override from user-specified string.
59   ScudoParser.ParseString(getScudoDefaultOptions());
60
61   // Override from environment.
62   ScudoParser.ParseString(GetEnv("SCUDO_OPTIONS"));
63
64   InitializeCommonFlags();
65
66   // Sanity checks and default settings for the Quarantine parameters.
67
68   if (f->QuarantineSizeMb >= 0) {
69     // Backward compatible logic if QuarantineSizeMb is set.
70     if (f->QuarantineSizeKb >= 0) {
71       dieWithMessage("ERROR: please use either QuarantineSizeMb (deprecated) "
72           "or QuarantineSizeKb, but not both\n");
73     }
74     if (f->QuarantineChunksUpToSize >= 0) {
75       dieWithMessage("ERROR: QuarantineChunksUpToSize cannot be used in "
76           " conjunction with the deprecated QuarantineSizeMb option\n");
77     }
78     // If everything is in order, update QuarantineSizeKb accordingly.
79     f->QuarantineSizeKb = f->QuarantineSizeMb * 1024;
80   } else {
81     // Otherwise proceed with the new options.
82     if (f->QuarantineSizeKb < 0) {
83       const int DefaultQuarantineSizeKb = FIRST_32_SECOND_64(64, 256);
84       f->QuarantineSizeKb = DefaultQuarantineSizeKb;
85     }
86     if (f->QuarantineChunksUpToSize < 0) {
87       const int DefaultQuarantineChunksUpToSize = FIRST_32_SECOND_64(512, 2048);
88       f->QuarantineChunksUpToSize = DefaultQuarantineChunksUpToSize;
89     }
90   }
91
92   // We enforce an upper limit for the chunk quarantine threshold of 4Mb.
93   if (f->QuarantineChunksUpToSize > (4 * 1024 * 1024)) {
94     dieWithMessage("ERROR: the chunk quarantine threshold is too large\n");
95   }
96
97   // We enforce an upper limit for the quarantine size of 32Mb.
98   if (f->QuarantineSizeKb > (32 * 1024)) {
99     dieWithMessage("ERROR: the quarantine size is too large\n");
100   }
101
102   if (f->ThreadLocalQuarantineSizeKb < 0) {
103     const int DefaultThreadLocalQuarantineSizeKb = FIRST_32_SECOND_64(16, 64);
104     f->ThreadLocalQuarantineSizeKb = DefaultThreadLocalQuarantineSizeKb;
105   }
106   // And an upper limit of 8Mb for the thread quarantine cache.
107   if (f->ThreadLocalQuarantineSizeKb > (8 * 1024)) {
108     dieWithMessage("ERROR: the per thread quarantine cache size is too "
109         "large\n");
110   }
111   if (f->ThreadLocalQuarantineSizeKb == 0 && f->QuarantineSizeKb > 0) {
112     dieWithMessage("ERROR: ThreadLocalQuarantineSizeKb can be set to 0 only "
113         "when QuarantineSizeKb is set to 0\n");
114   }
115 }
116
117 Flags *getFlags() {
118   return &ScudoFlags;
119 }
120
121 }  // namespace __scudo