llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

205 lines
5.7 KiB
C
Raw Normal View History

//===-- sanitizer_flag_parser.h ---------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
//
//===----------------------------------------------------------------------===//
#ifndef SANITIZER_FLAG_REGISTRY_H
#define SANITIZER_FLAG_REGISTRY_H
#include "sanitizer_internal_defs.h"
#include "sanitizer_libc.h"
#include "sanitizer_common.h"
namespace __sanitizer {
class FlagHandlerBase {
public:
virtual bool Parse(const char *value) { return false; }
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
// Write the C string representation of the current value (truncated to fit)
// into the buffer of size `size`. Returns false if truncation occurred and
// returns true otherwise.
virtual bool Format(char *buffer, uptr size) {
if (size > 0)
buffer[0] = '\0';
return false;
}
protected:
~FlagHandlerBase() {}
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
inline bool FormatString(char *buffer, uptr size, const char *str_to_use) {
uptr num_symbols_should_write =
internal_snprintf(buffer, size, "%s", str_to_use);
return num_symbols_should_write < size;
}
};
template <typename T>
class FlagHandler final : public FlagHandlerBase {
T *t_;
public:
explicit FlagHandler(T *t) : t_(t) {}
bool Parse(const char *value) final;
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
bool Format(char *buffer, uptr size) final;
};
inline bool ParseBool(const char *value, bool *b) {
if (internal_strcmp(value, "0") == 0 ||
internal_strcmp(value, "no") == 0 ||
internal_strcmp(value, "false") == 0) {
*b = false;
return true;
}
if (internal_strcmp(value, "1") == 0 ||
internal_strcmp(value, "yes") == 0 ||
internal_strcmp(value, "true") == 0) {
*b = true;
return true;
}
return false;
}
template <>
inline bool FlagHandler<bool>::Parse(const char *value) {
if (ParseBool(value, t_)) return true;
Printf("ERROR: Invalid value for bool option: '%s'\n", value);
return false;
}
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
template <>
inline bool FlagHandler<bool>::Format(char *buffer, uptr size) {
return FormatString(buffer, size, *t_ ? "true" : "false");
}
template <>
inline bool FlagHandler<HandleSignalMode>::Parse(const char *value) {
bool b;
if (ParseBool(value, &b)) {
*t_ = b ? kHandleSignalYes : kHandleSignalNo;
return true;
}
if (internal_strcmp(value, "2") == 0 ||
internal_strcmp(value, "exclusive") == 0) {
*t_ = kHandleSignalExclusive;
return true;
}
Printf("ERROR: Invalid value for signal handler option: '%s'\n", value);
return false;
}
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
template <>
inline bool FlagHandler<HandleSignalMode>::Format(char *buffer, uptr size) {
uptr num_symbols_should_write = internal_snprintf(buffer, size, "%d", *t_);
return num_symbols_should_write < size;
}
template <>
inline bool FlagHandler<const char *>::Parse(const char *value) {
*t_ = value;
return true;
}
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
template <>
inline bool FlagHandler<const char *>::Format(char *buffer, uptr size) {
return FormatString(buffer, size, *t_);
}
template <>
inline bool FlagHandler<int>::Parse(const char *value) {
const char *value_end;
*t_ = internal_simple_strtoll(value, &value_end, 10);
bool ok = *value_end == 0;
if (!ok) Printf("ERROR: Invalid value for int option: '%s'\n", value);
return ok;
}
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
template <>
inline bool FlagHandler<int>::Format(char *buffer, uptr size) {
uptr num_symbols_should_write = internal_snprintf(buffer, size, "%d", *t_);
return num_symbols_should_write < size;
}
template <>
inline bool FlagHandler<uptr>::Parse(const char *value) {
const char *value_end;
*t_ = internal_simple_strtoll(value, &value_end, 10);
bool ok = *value_end == 0;
if (!ok) Printf("ERROR: Invalid value for uptr option: '%s'\n", value);
return ok;
}
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
template <>
inline bool FlagHandler<uptr>::Format(char *buffer, uptr size) {
uptr num_symbols_should_write = internal_snprintf(buffer, size, "0x%zx", *t_);
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
return num_symbols_should_write < size;
}
template <>
inline bool FlagHandler<s64>::Parse(const char *value) {
const char *value_end;
*t_ = internal_simple_strtoll(value, &value_end, 10);
bool ok = *value_end == 0;
if (!ok) Printf("ERROR: Invalid value for s64 option: '%s'\n", value);
return ok;
}
[SanitizerCommon] Print the current value of options when printing out help. Summary: Previously it wasn't obvious what the default value of various sanitizer options were. A very close approximation of the "default values" for the options are the current value of the options at the time of printing the help output. In the case that no other options are provided then the current values are the default values (apart from `help`). ``` ASAN_OPTIONS=help=1 ./program ``` This patch causes the current option values to be printed when the `help` output is enabled. The original intention for this patch was to append `(Default: <value>)` to an option's help text. However because this is technically wrong (and misleading) I've opted to append `(Current Value: <value>)` instead. When trying to implement a way of displaying the default value of the options I tried another solution where the default value used in `*.inc` files were used to create compile time strings that where used when printing the help output. This solution was not satisfactory for several reasons: * Stringifying the default values with the preprocessor did not work very well in several cases. Some options contain boolean operators which no amount of macro expansion can get rid of. * It was much more invasive than this patch. Every sanitizer had to be changed. * The settings of `__<sanitizer>_default_options()` are ignored. For those reasons I opted for the solution in this patch. rdar://problem/42567204 Reviewers: kubamracek, yln, kcc, dvyukov, vitalybuka, cryptoad, eugenis, samsonov Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69546
2019-10-29 08:53:38 +08:00
template <>
inline bool FlagHandler<s64>::Format(char *buffer, uptr size) {
uptr num_symbols_should_write = internal_snprintf(buffer, size, "%lld", *t_);
return num_symbols_should_write < size;
}
class FlagParser {
static const int kMaxFlags = 200;
struct Flag {
const char *name;
const char *desc;
FlagHandlerBase *handler;
} *flags_;
int n_flags_;
const char *buf_;
uptr pos_;
public:
FlagParser();
void RegisterHandler(const char *name, FlagHandlerBase *handler,
const char *desc);
void ParseString(const char *s, const char *env_name = 0);
void ParseStringFromEnv(const char *env_name);
bool ParseFile(const char *path, bool ignore_missing);
void PrintFlagDescriptions();
static LowLevelAllocator Alloc;
private:
void fatal_error(const char *err);
bool is_space(char c);
void skip_whitespace();
void parse_flags(const char *env_option_name);
void parse_flag(const char *env_option_name);
bool run_handler(const char *name, const char *value);
char *ll_strndup(const char *s, uptr n);
};
template <typename T>
static void RegisterFlag(FlagParser *parser, const char *name, const char *desc,
T *var) {
FlagHandler<T> *fh = new (FlagParser::Alloc) FlagHandler<T>(var);
parser->RegisterHandler(name, fh, desc);
}
void ReportUnrecognizedFlags();
} // namespace __sanitizer
#endif // SANITIZER_FLAG_REGISTRY_H