llvm-project

Форк
0
139 строк · 4.2 Кб
1
//===-- sanitizer_flags.cpp -----------------------------------------------===//
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
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
10
//
11
//===----------------------------------------------------------------------===//
12

13
#include "sanitizer_flags.h"
14

15
#include "sanitizer_common.h"
16
#include "sanitizer_flag_parser.h"
17
#include "sanitizer_libc.h"
18
#include "sanitizer_linux.h"
19
#include "sanitizer_list.h"
20

21
namespace __sanitizer {
22

23
CommonFlags common_flags_dont_use;
24

25
void CommonFlags::SetDefaults() {
26
#define COMMON_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
27
#include "sanitizer_flags.inc"
28
#undef COMMON_FLAG
29
}
30

31
void CommonFlags::CopyFrom(const CommonFlags &other) {
32
  internal_memcpy(this, &other, sizeof(*this));
33
}
34

35
// Copy the string from "s" to "out", making the following substitutions:
36
// %b = binary basename
37
// %p = pid
38
// %d = binary directory
39
void SubstituteForFlagValue(const char *s, char *out, uptr out_size) {
40
  char *out_end = out + out_size;
41
  while (*s && out < out_end - 1) {
42
    if (s[0] != '%') {
43
      *out++ = *s++;
44
      continue;
45
    }
46
    switch (s[1]) {
47
      case 'b': {
48
        const char *base = GetProcessName();
49
        CHECK(base);
50
        while (*base && out < out_end - 1)
51
          *out++ = *base++;
52
        s += 2; // skip "%b"
53
        break;
54
      }
55
      case 'p': {
56
        int pid = internal_getpid();
57
        char buf[32];
58
        char *buf_pos = buf + 32;
59
        do {
60
          *--buf_pos = (pid % 10) + '0';
61
          pid /= 10;
62
        } while (pid);
63
        while (buf_pos < buf + 32 && out < out_end - 1)
64
          *out++ = *buf_pos++;
65
        s += 2; // skip "%p"
66
        break;
67
      }
68
      case 'd': {
69
        uptr len = ReadBinaryDir(out, out_end - out);
70
        out += len;
71
        s += 2;  // skip "%d"
72
        break;
73
      }
74
      default:
75
        *out++ = *s++;
76
        break;
77
    }
78
  }
79
  CHECK(out < out_end - 1);
80
  *out = '\0';
81
}
82

83
class FlagHandlerInclude final : public FlagHandlerBase {
84
  FlagParser *parser_;
85
  bool ignore_missing_;
86
  const char *original_path_;
87

88
 public:
89
  explicit FlagHandlerInclude(FlagParser *parser, bool ignore_missing)
90
      : parser_(parser), ignore_missing_(ignore_missing), original_path_("") {}
91
  bool Parse(const char *value) final {
92
    original_path_ = value;
93
    if (internal_strchr(value, '%')) {
94
      char *buf = (char *)MmapOrDie(kMaxPathLength, "FlagHandlerInclude");
95
      SubstituteForFlagValue(value, buf, kMaxPathLength);
96
      bool res = parser_->ParseFile(buf, ignore_missing_);
97
      UnmapOrDie(buf, kMaxPathLength);
98
      return res;
99
    }
100
    return parser_->ParseFile(value, ignore_missing_);
101
  }
102
  bool Format(char *buffer, uptr size) override {
103
    // Note `original_path_` isn't actually what's parsed due to `%`
104
    // substitutions. Printing the substituted path would require holding onto
105
    // mmap'ed memory.
106
    return FormatString(buffer, size, original_path_);
107
  }
108
};
109

110
void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf) {
111
  FlagHandlerInclude *fh_include = new (GetGlobalLowLevelAllocator())
112
      FlagHandlerInclude(parser, /*ignore_missing*/ false);
113
  parser->RegisterHandler("include", fh_include,
114
                          "read more options from the given file");
115
  FlagHandlerInclude *fh_include_if_exists = new (GetGlobalLowLevelAllocator())
116
      FlagHandlerInclude(parser, /*ignore_missing*/ true);
117
  parser->RegisterHandler(
118
      "include_if_exists", fh_include_if_exists,
119
      "read more options from the given file (if it exists)");
120
}
121

122
void RegisterCommonFlags(FlagParser *parser, CommonFlags *cf) {
123
#define COMMON_FLAG(Type, Name, DefaultValue, Description) \
124
  RegisterFlag(parser, #Name, Description, &cf->Name);
125
#include "sanitizer_flags.inc"
126
#undef COMMON_FLAG
127

128
  RegisterIncludeFlags(parser, cf);
129
}
130

131
void InitializeCommonFlags(CommonFlags *cf) {
132
  // need to record coverage to generate coverage report.
133
  cf->coverage |= cf->html_cov_report;
134
  SetVerbosity(cf->verbosity);
135

136
  InitializePlatformCommonFlags(cf);
137
}
138

139
}  // namespace __sanitizer
140

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.