1//===-- options_parser.cpp --------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "gwp_asan/optional/options_parser.h"
10
11#include <stdarg.h>
12#include <stdint.h>
13#include <stdlib.h>
14#include <string.h>
15
16#include "gwp_asan/options.h"
17#include "sanitizer_common/sanitizer_common.h"
18#include "sanitizer_common/sanitizer_flag_parser.h"
19#include "sanitizer_common/sanitizer_flags.h"
20
21namespace gwp_asan {
22namespace options {
23namespace {
24void registerGwpAsanFlags(__sanitizer::FlagParser *parser, Options *o) {
25#define GWP_ASAN_OPTION(Type, Name, DefaultValue, Description)                 \
26  RegisterFlag(parser, #Name, Description, &o->Name);
27#include "gwp_asan/options.inc"
28#undef GWP_ASAN_OPTION
29}
30
31const char *getCompileDefinitionGwpAsanDefaultOptions() {
32#ifdef GWP_ASAN_DEFAULT_OPTIONS
33  return SANITIZER_STRINGIFY(GWP_ASAN_DEFAULT_OPTIONS);
34#else
35  return "";
36#endif
37}
38
39const char *getGwpAsanDefaultOptions() {
40  return (__gwp_asan_default_options) ? __gwp_asan_default_options() : "";
41}
42
43Options *getOptionsInternal() {
44  static Options GwpAsanFlags;
45  return &GwpAsanFlags;
46}
47} // anonymous namespace
48
49void initOptions() {
50  __sanitizer::SetCommonFlagsDefaults();
51
52  Options *o = getOptionsInternal();
53  o->setDefaults();
54
55  __sanitizer::FlagParser Parser;
56  registerGwpAsanFlags(&Parser, o);
57
58  // Override from compile definition.
59  Parser.ParseString(getCompileDefinitionGwpAsanDefaultOptions());
60
61  // Override from user-specified string.
62  Parser.ParseString(getGwpAsanDefaultOptions());
63
64  // Override from environment.
65  Parser.ParseString(__sanitizer::GetEnv("GWP_ASAN_OPTIONS"));
66
67  __sanitizer::InitializeCommonFlags();
68  if (__sanitizer::Verbosity())
69    __sanitizer::ReportUnrecognizedFlags();
70
71  if (!o->Enabled)
72    return;
73
74  // Sanity checks for the parameters.
75  if (o->MaxSimultaneousAllocations <= 0) {
76    __sanitizer::Printf("GWP-ASan ERROR: MaxSimultaneousAllocations must be > "
77                        "0 when GWP-ASan is enabled.\n");
78    exit(EXIT_FAILURE);
79  }
80
81  if (o->SampleRate < 1) {
82    __sanitizer::Printf(
83        "GWP-ASan ERROR: SampleRate must be > 0 when GWP-ASan is enabled.\n");
84    exit(EXIT_FAILURE);
85  }
86
87  o->Printf = __sanitizer::Printf;
88}
89
90Options &getOptions() { return *getOptionsInternal(); }
91
92} // namespace options
93} // namespace gwp_asan
94