]>
Commit | Line | Data |
---|---|---|
549e2197 | 1 | //===-- sanitizer_flags.cc ------------------------------------------------===// |
2 | // | |
3 | // This file is distributed under the University of Illinois Open Source | |
4 | // License. See LICENSE.TXT for details. | |
5 | // | |
6 | //===----------------------------------------------------------------------===// | |
7 | // | |
8 | // This file is a part of ThreadSanitizer/AddressSanitizer runtime. | |
9 | // | |
10 | //===----------------------------------------------------------------------===// | |
11 | ||
12 | #include "sanitizer_flags.h" | |
13 | ||
14 | #include "sanitizer_common.h" | |
15 | #include "sanitizer_libc.h" | |
7d752f28 | 16 | #include "sanitizer_list.h" |
5645a48f | 17 | #include "sanitizer_flag_parser.h" |
549e2197 | 18 | |
19 | namespace __sanitizer { | |
20 | ||
7d752f28 | 21 | CommonFlags common_flags_dont_use; |
22 | ||
5645a48f | 23 | void CommonFlags::SetDefaults() { |
24 | #define COMMON_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; | |
25 | #include "sanitizer_flags.inc" | |
26 | #undef COMMON_FLAG | |
4fc7b5ac | 27 | } |
1e80ce41 | 28 | |
5645a48f | 29 | void CommonFlags::CopyFrom(const CommonFlags &other) { |
30 | internal_memcpy(this, &other, sizeof(*this)); | |
549e2197 | 31 | } |
32 | ||
23e39437 | 33 | // Copy the string from "s" to "out", making the following substitutions: |
34 | // %b = binary basename | |
35 | // %p = pid | |
36 | void SubstituteForFlagValue(const char *s, char *out, uptr out_size) { | |
5645a48f | 37 | char *out_end = out + out_size; |
38 | while (*s && out < out_end - 1) { | |
23e39437 | 39 | if (s[0] != '%') { |
40 | *out++ = *s++; | |
41 | continue; | |
42 | } | |
43 | switch (s[1]) { | |
44 | case 'b': { | |
45 | const char *base = GetProcessName(); | |
46 | CHECK(base); | |
47 | while (*base && out < out_end - 1) | |
48 | *out++ = *base++; | |
49 | s += 2; // skip "%b" | |
50 | break; | |
51 | } | |
52 | case 'p': { | |
53 | int pid = internal_getpid(); | |
54 | char buf[32]; | |
55 | char *buf_pos = buf + 32; | |
56 | do { | |
57 | *--buf_pos = (pid % 10) + '0'; | |
58 | pid /= 10; | |
59 | } while (pid); | |
60 | while (buf_pos < buf + 32 && out < out_end - 1) | |
61 | *out++ = *buf_pos++; | |
62 | s += 2; // skip "%p" | |
63 | break; | |
64 | } | |
65 | default: | |
66 | *out++ = *s++; | |
67 | break; | |
68 | } | |
7d752f28 | 69 | } |
23e39437 | 70 | CHECK(out < out_end - 1); |
5645a48f | 71 | *out = '\0'; |
7d752f28 | 72 | } |
73 | ||
5645a48f | 74 | class FlagHandlerInclude : public FlagHandlerBase { |
75 | FlagParser *parser_; | |
76 | bool ignore_missing_; | |
77 | ||
78 | public: | |
79 | explicit FlagHandlerInclude(FlagParser *parser, bool ignore_missing) | |
80 | : parser_(parser), ignore_missing_(ignore_missing) {} | |
81 | bool Parse(const char *value) final { | |
82 | if (internal_strchr(value, '%')) { | |
83 | char *buf = (char *)MmapOrDie(kMaxPathLength, "FlagHandlerInclude"); | |
23e39437 | 84 | SubstituteForFlagValue(value, buf, kMaxPathLength); |
5645a48f | 85 | bool res = parser_->ParseFile(buf, ignore_missing_); |
86 | UnmapOrDie(buf, kMaxPathLength); | |
87 | return res; | |
88 | } | |
89 | return parser_->ParseFile(value, ignore_missing_); | |
7d752f28 | 90 | } |
5645a48f | 91 | }; |
549e2197 | 92 | |
5645a48f | 93 | void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf) { |
94 | FlagHandlerInclude *fh_include = new (FlagParser::Alloc) // NOLINT | |
95 | FlagHandlerInclude(parser, /*ignore_missing*/ false); | |
96 | parser->RegisterHandler("include", fh_include, | |
97 | "read more options from the given file"); | |
98 | FlagHandlerInclude *fh_include_if_exists = new (FlagParser::Alloc) // NOLINT | |
99 | FlagHandlerInclude(parser, /*ignore_missing*/ true); | |
100 | parser->RegisterHandler( | |
101 | "include_if_exists", fh_include_if_exists, | |
102 | "read more options from the given file (if it exists)"); | |
549e2197 | 103 | } |
104 | ||
5645a48f | 105 | void RegisterCommonFlags(FlagParser *parser, CommonFlags *cf) { |
106 | #define COMMON_FLAG(Type, Name, DefaultValue, Description) \ | |
107 | RegisterFlag(parser, #Name, Description, &cf->Name); | |
108 | #include "sanitizer_flags.inc" | |
109 | #undef COMMON_FLAG | |
549e2197 | 110 | |
5645a48f | 111 | RegisterIncludeFlags(parser, cf); |
549e2197 | 112 | } |
113 | ||
23e39437 | 114 | void InitializeCommonFlags(CommonFlags *cf) { |
115 | // need to record coverage to generate coverage report. | |
116 | cf->coverage |= cf->html_cov_report; | |
117 | SetVerbosity(cf->verbosity); | |
118 | } | |
119 | ||
549e2197 | 120 | } // namespace __sanitizer |