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