diff options
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r-- | compiler-rt/lib/msan/msan.cpp | 4 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp | 11 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h | 49 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp | 10 |
4 files changed, 71 insertions, 3 deletions
diff --git a/compiler-rt/lib/msan/msan.cpp b/compiler-rt/lib/msan/msan.cpp index 6ea63cb2c48..7095ee1bf20 100644 --- a/compiler-rt/lib/msan/msan.cpp +++ b/compiler-rt/lib/msan/msan.cpp @@ -122,6 +122,10 @@ class FlagHandlerKeepGoing : public FlagHandlerBase { *halt_on_error_ = !tmp; return true; } + bool Format(char *buffer, uptr size) final { + const char *keep_going_str = (*halt_on_error_) ? "false" : "true"; + return FormatString(buffer, size, keep_going_str); + } }; static void RegisterMsanFlags(FlagParser *parser, Flags *f) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp index 1e2bc665261..9e274268bf2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp @@ -56,9 +56,16 @@ char *FlagParser::ll_strndup(const char *s, uptr n) { } void FlagParser::PrintFlagDescriptions() { + char buffer[128]; + buffer[sizeof(buffer) - 1] = '\0'; Printf("Available flags for %s:\n", SanitizerToolName); - for (int i = 0; i < n_flags_; ++i) - Printf("\t%s\n\t\t- %s\n", flags_[i].name, flags_[i].desc); + for (int i = 0; i < n_flags_; ++i) { + bool truncated = !(flags_[i].handler->Format(buffer, sizeof(buffer))); + CHECK_EQ(buffer[sizeof(buffer) - 1], '\0'); + const char *truncation_str = truncated ? " Truncated" : ""; + Printf("\t%s\n\t\t- %s (Current Value%s: %s)\n", flags_[i].name, + flags_[i].desc, truncation_str, buffer); + } } void FlagParser::fatal_error(const char *err) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h index c24ad25626b..fac5dff3463 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h @@ -22,9 +22,23 @@ namespace __sanitizer { class FlagHandlerBase { public: virtual bool Parse(const char *value) { return false; } + // 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() {} + + 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> @@ -34,6 +48,7 @@ class FlagHandler : public FlagHandlerBase { public: explicit FlagHandler(T *t) : t_(t) {} bool Parse(const char *value) final; + bool Format(char *buffer, uptr size) final; }; inline bool ParseBool(const char *value, bool *b) { @@ -60,6 +75,11 @@ inline bool FlagHandler<bool>::Parse(const char *value) { } 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)) { @@ -76,12 +96,23 @@ inline bool FlagHandler<HandleSignalMode>::Parse(const char *value) { } 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; } 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); @@ -91,6 +122,12 @@ inline bool FlagHandler<int>::Parse(const char *value) { } 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); @@ -100,6 +137,12 @@ inline bool FlagHandler<uptr>::Parse(const char *value) { } template <> +inline bool FlagHandler<uptr>::Format(char *buffer, uptr size) { + uptr num_symbols_should_write = internal_snprintf(buffer, size, "%p", *t_); + 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); @@ -108,6 +151,12 @@ inline bool FlagHandler<s64>::Parse(const char *value) { return ok; } +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 { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp index 66a0a5579ed..684ee1e0b99 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp @@ -75,11 +75,13 @@ void SubstituteForFlagValue(const char *s, char *out, uptr out_size) { class FlagHandlerInclude : public FlagHandlerBase { FlagParser *parser_; bool ignore_missing_; + const char *original_path_; public: explicit FlagHandlerInclude(FlagParser *parser, bool ignore_missing) - : parser_(parser), ignore_missing_(ignore_missing) {} + : parser_(parser), ignore_missing_(ignore_missing), original_path_("") {} bool Parse(const char *value) final { + original_path_ = value; if (internal_strchr(value, '%')) { char *buf = (char *)MmapOrDie(kMaxPathLength, "FlagHandlerInclude"); SubstituteForFlagValue(value, buf, kMaxPathLength); @@ -89,6 +91,12 @@ class FlagHandlerInclude : public FlagHandlerBase { } return parser_->ParseFile(value, ignore_missing_); } + bool Format(char *buffer, uptr size) { + // Note `original_path_` isn't actually what's parsed due to `%` + // substitutions. Printing the substituted path would require holding onto + // mmap'ed memory. + return FormatString(buffer, size, original_path_); + } }; void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf) { |