diff options
Diffstat (limited to 'lib/msan/msan.cc')
-rw-r--r-- | lib/msan/msan.cc | 152 |
1 files changed, 73 insertions, 79 deletions
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc index 853e448fab8ea..4adcc9eb8e6a0 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cc @@ -16,16 +16,17 @@ #include "msan_chained_origin_depot.h" #include "msan_origin.h" #include "msan_thread.h" +#include "msan_poisoning.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_flag_parser.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_procmaps.h" #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_symbolizer.h" #include "sanitizer_common/sanitizer_stackdepot.h" - // ACHTUNG! No system header includes in this file. using namespace __sanitizer; @@ -96,19 +97,78 @@ static const char *StackOriginDescr[kNumStackOriginDescrs]; static uptr StackOriginPC[kNumStackOriginDescrs]; static atomic_uint32_t NumStackOriginDescrs; -static void ParseFlagsFromString(Flags *f, const char *str) { - CommonFlags *cf = common_flags(); - ParseCommonFlagsFromString(cf, str); - ParseFlag(str, &f->poison_heap_with_zeroes, "poison_heap_with_zeroes", ""); - ParseFlag(str, &f->poison_stack_with_zeroes, "poison_stack_with_zeroes", ""); - ParseFlag(str, &f->poison_in_malloc, "poison_in_malloc", ""); - ParseFlag(str, &f->poison_in_free, "poison_in_free", ""); - ParseFlag(str, &f->exit_code, "exit_code", ""); +void Flags::SetDefaults() { +#define MSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; +#include "msan_flags.inc" +#undef MSAN_FLAG +} + +// keep_going is an old name for halt_on_error, +// and it has inverse meaning. +class FlagHandlerKeepGoing : public FlagHandlerBase { + bool *halt_on_error_; + + public: + explicit FlagHandlerKeepGoing(bool *halt_on_error) + : halt_on_error_(halt_on_error) {} + bool Parse(const char *value) { + bool tmp; + FlagHandler<bool> h(&tmp); + if (!h.Parse(value)) return false; + *halt_on_error_ = !tmp; + return true; + } +}; + +void RegisterMsanFlags(FlagParser *parser, Flags *f) { +#define MSAN_FLAG(Type, Name, DefaultValue, Description) \ + RegisterFlag(parser, #Name, Description, &f->Name); +#include "msan_flags.inc" +#undef MSAN_FLAG + + FlagHandlerKeepGoing *fh_keep_going = new (FlagParser::Alloc) // NOLINT + FlagHandlerKeepGoing(&f->halt_on_error); + parser->RegisterHandler("keep_going", fh_keep_going, + "deprecated, use halt_on_error"); +} + +static void InitializeFlags(Flags *f, const char *options) { + FlagParser parser; + RegisterMsanFlags(&parser, f); + RegisterCommonFlags(&parser); + + SetCommonFlagsDefaults(); + { + CommonFlags cf; + cf.CopyFrom(*common_flags()); + cf.external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH"); + cf.malloc_context_size = 20; + cf.handle_ioctl = true; + // FIXME: test and enable. + cf.check_printf = false; + cf.intercept_tls_get_addr = true; + OverrideCommonFlags(cf); + } + + f->SetDefaults(); + + // Override from user-specified string. + if (__msan_default_options) + parser.ParseString(__msan_default_options()); + + parser.ParseString(options); + + SetVerbosity(common_flags()->verbosity); + + if (Verbosity()) ReportUnrecognizedFlags(); + + if (common_flags()->help) parser.PrintFlagDescriptions(); + + // Check flag values: if (f->exit_code < 0 || f->exit_code > 127) { Printf("Exit code not in [0, 128) range: %d\n", f->exit_code); Die(); } - ParseFlag(str, &f->origin_history_size, "origin_history_size", ""); if (f->origin_history_size < 0 || f->origin_history_size > Origin::kMaxDepth) { Printf( @@ -117,8 +177,6 @@ static void ParseFlagsFromString(Flags *f, const char *str) { f->origin_history_size, Origin::kMaxDepth); Die(); } - ParseFlag(str, &f->origin_history_per_stack_limit, - "origin_history_per_stack_limit", ""); // Limiting to kStackDepotMaxUseCount / 2 to avoid overflow in // StackDepotHandle::inc_use_count_unsafe. if (f->origin_history_per_stack_limit < 0 || @@ -129,51 +187,7 @@ static void ParseFlagsFromString(Flags *f, const char *str) { f->origin_history_per_stack_limit, kStackDepotMaxUseCount / 2); Die(); } - - ParseFlag(str, &f->report_umrs, "report_umrs", ""); - ParseFlag(str, &f->wrap_signals, "wrap_signals", ""); - ParseFlag(str, &f->print_stats, "print_stats", ""); - ParseFlag(str, &f->atexit, "atexit", ""); - ParseFlag(str, &f->store_context_size, "store_context_size", ""); if (f->store_context_size < 1) f->store_context_size = 1; - - // keep_going is an old name for halt_on_error, - // and it has inverse meaning. - f->halt_on_error = !f->halt_on_error; - ParseFlag(str, &f->halt_on_error, "keep_going", ""); - f->halt_on_error = !f->halt_on_error; - ParseFlag(str, &f->halt_on_error, "halt_on_error", ""); -} - -static void InitializeFlags(Flags *f, const char *options) { - CommonFlags *cf = common_flags(); - SetCommonFlagsDefaults(cf); - cf->external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH"); - cf->malloc_context_size = 20; - cf->handle_ioctl = true; - // FIXME: test and enable. - cf->check_printf = false; - cf->intercept_tls_get_addr = true; - - internal_memset(f, 0, sizeof(*f)); - f->poison_heap_with_zeroes = false; - f->poison_stack_with_zeroes = false; - f->poison_in_malloc = true; - f->poison_in_free = true; - f->exit_code = 77; - f->origin_history_size = Origin::kMaxDepth; - f->origin_history_per_stack_limit = 20000; - f->report_umrs = true; - f->wrap_signals = true; - f->print_stats = false; - f->atexit = false; - f->halt_on_error = !&__msan_keep_going; - f->store_context_size = 20; - - // Override from user-specified string. - if (__msan_default_options) - ParseFlagsFromString(f, __msan_default_options()); - ParseFlagsFromString(f, options); } void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp, @@ -259,6 +273,7 @@ u32 ChainOrigin(u32 id, StackTrace *stack) { return id; Origin o = Origin::FromRawId(id); + stack->tag = StackTrace::TAG_UNKNOWN; Origin chained = Origin::CreateChainedOrigin(o, stack); return chained.raw_id(); } @@ -338,7 +353,6 @@ void __msan_init() { const char *msan_options = GetEnv("MSAN_OPTIONS"); InitializeFlags(&msan_flags, msan_options); - if (common_flags()->help) PrintFlagDescriptions(); __sanitizer_set_report_path(common_flags()->log_path); InitializeInterceptors(); @@ -372,10 +386,7 @@ void __msan_init() { Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); - if (common_flags()->coverage) { - __sanitizer_cov_init(); - Atexit(__sanitizer_cov_dump); - } + InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); MsanTSDInit(MsanTSDDtor); @@ -485,24 +496,7 @@ void __msan_load_unpoisoned(void *src, uptr size, void *dst) { } void __msan_set_origin(const void *a, uptr size, u32 origin) { - // Origin mapping is 4 bytes per 4 bytes of application memory. - // Here we extend the range such that its left and right bounds are both - // 4 byte aligned. - if (!__msan_get_track_origins()) return; - uptr x = MEM_TO_ORIGIN((uptr)a); - uptr beg = x & ~3UL; // align down. - uptr end = (x + size + 3) & ~3UL; // align up. - u64 origin64 = ((u64)origin << 32) | origin; - // This is like memset, but the value is 32-bit. We unroll by 2 to write - // 64 bits at once. May want to unroll further to get 128-bit stores. - if (beg & 7ULL) { - *(u32*)beg = origin; - beg += 4; - } - for (uptr addr = beg; addr < (end & ~7UL); addr += 8) - *(u64*)addr = origin64; - if (end & 7ULL) - *(u32*)(end - 4) = origin; + if (__msan_get_track_origins()) SetOrigin(a, size, origin); } // 'descr' is created at compile time and contains '----' in the beginning. |