1*e8d8bef9SDimitry Andric //===-- memprof_flags.cpp --------------------------------------*- C++ -*-===//
2*e8d8bef9SDimitry Andric //
3*e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e8d8bef9SDimitry Andric //
7*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8*e8d8bef9SDimitry Andric //
9*e8d8bef9SDimitry Andric // This file is a part of MemProfiler, a memory profiler.
10*e8d8bef9SDimitry Andric //
11*e8d8bef9SDimitry Andric // MemProf flag parsing logic.
12*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
13*e8d8bef9SDimitry Andric 
14*e8d8bef9SDimitry Andric #include "memprof_flags.h"
15*e8d8bef9SDimitry Andric #include "memprof_interface_internal.h"
16*e8d8bef9SDimitry Andric #include "memprof_stack.h"
17*e8d8bef9SDimitry Andric #include "sanitizer_common/sanitizer_common.h"
18*e8d8bef9SDimitry Andric #include "sanitizer_common/sanitizer_flag_parser.h"
19*e8d8bef9SDimitry Andric #include "sanitizer_common/sanitizer_flags.h"
20*e8d8bef9SDimitry Andric 
21*e8d8bef9SDimitry Andric namespace __memprof {
22*e8d8bef9SDimitry Andric 
23*e8d8bef9SDimitry Andric Flags memprof_flags_dont_use_directly; // use via flags().
24*e8d8bef9SDimitry Andric 
MaybeUseMemprofDefaultOptionsCompileDefinition()25*e8d8bef9SDimitry Andric static const char *MaybeUseMemprofDefaultOptionsCompileDefinition() {
26*e8d8bef9SDimitry Andric #ifdef MEMPROF_DEFAULT_OPTIONS
27*e8d8bef9SDimitry Andric   return SANITIZER_STRINGIFY(MEMPROF_DEFAULT_OPTIONS);
28*e8d8bef9SDimitry Andric #else
29*e8d8bef9SDimitry Andric   return "";
30*e8d8bef9SDimitry Andric #endif
31*e8d8bef9SDimitry Andric }
32*e8d8bef9SDimitry Andric 
SetDefaults()33*e8d8bef9SDimitry Andric void Flags::SetDefaults() {
34*e8d8bef9SDimitry Andric #define MEMPROF_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
35*e8d8bef9SDimitry Andric #include "memprof_flags.inc"
36*e8d8bef9SDimitry Andric #undef MEMPROF_FLAG
37*e8d8bef9SDimitry Andric }
38*e8d8bef9SDimitry Andric 
RegisterMemprofFlags(FlagParser * parser,Flags * f)39*e8d8bef9SDimitry Andric static void RegisterMemprofFlags(FlagParser *parser, Flags *f) {
40*e8d8bef9SDimitry Andric #define MEMPROF_FLAG(Type, Name, DefaultValue, Description)                    \
41*e8d8bef9SDimitry Andric   RegisterFlag(parser, #Name, Description, &f->Name);
42*e8d8bef9SDimitry Andric #include "memprof_flags.inc"
43*e8d8bef9SDimitry Andric #undef MEMPROF_FLAG
44*e8d8bef9SDimitry Andric }
45*e8d8bef9SDimitry Andric 
InitializeFlags()46*e8d8bef9SDimitry Andric void InitializeFlags() {
47*e8d8bef9SDimitry Andric   // Set the default values and prepare for parsing MemProf and common flags.
48*e8d8bef9SDimitry Andric   SetCommonFlagsDefaults();
49*e8d8bef9SDimitry Andric   {
50*e8d8bef9SDimitry Andric     CommonFlags cf;
51*e8d8bef9SDimitry Andric     cf.CopyFrom(*common_flags());
52*e8d8bef9SDimitry Andric     cf.external_symbolizer_path = GetEnv("MEMPROF_SYMBOLIZER_PATH");
53*e8d8bef9SDimitry Andric     cf.malloc_context_size = kDefaultMallocContextSize;
54*e8d8bef9SDimitry Andric     cf.intercept_tls_get_addr = true;
55*e8d8bef9SDimitry Andric     cf.exitcode = 1;
56*e8d8bef9SDimitry Andric     OverrideCommonFlags(cf);
57*e8d8bef9SDimitry Andric   }
58*e8d8bef9SDimitry Andric   Flags *f = flags();
59*e8d8bef9SDimitry Andric   f->SetDefaults();
60*e8d8bef9SDimitry Andric 
61*e8d8bef9SDimitry Andric   FlagParser memprof_parser;
62*e8d8bef9SDimitry Andric   RegisterMemprofFlags(&memprof_parser, f);
63*e8d8bef9SDimitry Andric   RegisterCommonFlags(&memprof_parser);
64*e8d8bef9SDimitry Andric 
65*e8d8bef9SDimitry Andric   // Override from MemProf compile definition.
66*e8d8bef9SDimitry Andric   const char *memprof_compile_def =
67*e8d8bef9SDimitry Andric       MaybeUseMemprofDefaultOptionsCompileDefinition();
68*e8d8bef9SDimitry Andric   memprof_parser.ParseString(memprof_compile_def);
69*e8d8bef9SDimitry Andric 
70*e8d8bef9SDimitry Andric   // Override from user-specified string.
71*e8d8bef9SDimitry Andric   const char *memprof_default_options = __memprof_default_options();
72*e8d8bef9SDimitry Andric   memprof_parser.ParseString(memprof_default_options);
73*e8d8bef9SDimitry Andric 
74*e8d8bef9SDimitry Andric   // Override from command line.
75*e8d8bef9SDimitry Andric   memprof_parser.ParseStringFromEnv("MEMPROF_OPTIONS");
76*e8d8bef9SDimitry Andric 
77*e8d8bef9SDimitry Andric   InitializeCommonFlags();
78*e8d8bef9SDimitry Andric 
79*e8d8bef9SDimitry Andric   if (Verbosity())
80*e8d8bef9SDimitry Andric     ReportUnrecognizedFlags();
81*e8d8bef9SDimitry Andric 
82*e8d8bef9SDimitry Andric   if (common_flags()->help) {
83*e8d8bef9SDimitry Andric     memprof_parser.PrintFlagDescriptions();
84*e8d8bef9SDimitry Andric   }
85*e8d8bef9SDimitry Andric 
86*e8d8bef9SDimitry Andric   CHECK_LE((uptr)common_flags()->malloc_context_size, kStackTraceMax);
87*e8d8bef9SDimitry Andric }
88*e8d8bef9SDimitry Andric 
89*e8d8bef9SDimitry Andric } // namespace __memprof
90*e8d8bef9SDimitry Andric 
SANITIZER_INTERFACE_WEAK_DEF(const char *,__memprof_default_options,void)91*e8d8bef9SDimitry Andric SANITIZER_INTERFACE_WEAK_DEF(const char *, __memprof_default_options, void) {
92*e8d8bef9SDimitry Andric   return "";
93*e8d8bef9SDimitry Andric }
94