brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · 849a122 Raw
140 lines · cpp
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-exception6//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 21namespace __sanitizer {22 23CommonFlags common_flags_dont_use;24 25void CommonFlags::SetDefaults() {26#define COMMON_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;27#include "sanitizer_flags.inc"28#undef COMMON_FLAG29}30 31void 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 basename37// %p = pid38// %d = binary directory39void 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 83class 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 onto105    // mmap'ed memory.106    return FormatString(buffer, size, original_path_);107  }108};109 110void 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 122void 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_FLAG127 128  RegisterIncludeFlags(parser, cf);129}130 131void 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 __sanitizer140