diff options
Diffstat (limited to 'lib/sanitizer_common/sanitizer_common.h')
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.h | 156 |
1 files changed, 126 insertions, 30 deletions
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index cf8a12d65a091..c00dce66bb077 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -19,6 +19,7 @@ #include "sanitizer_internal_defs.h" #include "sanitizer_libc.h" #include "sanitizer_mutex.h" +#include "sanitizer_flags.h" namespace __sanitizer { struct StackTrace; @@ -28,12 +29,14 @@ const uptr kWordSize = SANITIZER_WORDSIZE / 8; const uptr kWordSizeInBits = 8 * kWordSize; #if defined(__powerpc__) || defined(__powerpc64__) -const uptr kCacheLineSize = 128; + const uptr kCacheLineSize = 128; #else -const uptr kCacheLineSize = 64; + const uptr kCacheLineSize = 64; #endif -const uptr kMaxPathLength = 512; +const uptr kMaxPathLength = 4096; + +const uptr kMaxThreadStackSize = 1 << 30; // 1Gb extern const char *SanitizerToolName; // Can be changed by the tool. @@ -53,6 +56,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, void *MmapOrDie(uptr size, const char *mem_type); void UnmapOrDie(void *addr, uptr size); void *MmapFixedNoReserve(uptr fixed_addr, uptr size); +void *MmapNoReserveOrDie(uptr size, const char *mem_type); void *MmapFixedOrDie(uptr fixed_addr, uptr size); void *Mprotect(uptr fixed_addr, uptr size); // Map aligned chunk of address space; size and alignment are powers of two. @@ -60,6 +64,9 @@ void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type); // Used to check if we can map shadow memory to a fixed location. bool MemoryRangeIsAvailable(uptr range_start, uptr range_end); void FlushUnneededShadowMemory(uptr addr, uptr size); +void IncreaseTotalMmap(uptr size); +void DecreaseTotalMmap(uptr size); +uptr GetRSS(); // InternalScopedBuffer can be used instead of large stack arrays to // keep frame size low. @@ -122,20 +129,50 @@ void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback); // IO void RawWrite(const char *buffer); -bool PrintsToTty(); -// Caching version of PrintsToTty(). Not thread-safe. -bool PrintsToTtyCached(); +bool ColorizeReports(); void Printf(const char *format, ...); void Report(const char *format, ...); void SetPrintfAndReportCallback(void (*callback)(const char *)); +#define VReport(level, ...) \ + do { \ + if ((uptr)common_flags()->verbosity >= (level)) Report(__VA_ARGS__); \ + } while (0) +#define VPrintf(level, ...) \ + do { \ + if ((uptr)common_flags()->verbosity >= (level)) Printf(__VA_ARGS__); \ + } while (0) // Can be used to prevent mixing error reports from different sanitizers. extern StaticSpinMutex CommonSanitizerReportMutex; -void MaybeOpenReportFile(); -extern fd_t report_fd; -extern bool log_to_file; -extern char report_path_prefix[4096]; -extern uptr report_fd_pid; + +struct ReportFile { + void Write(const char *buffer, uptr length); + bool PrintsToTty(); + void SetReportPath(const char *path); + + // Don't use fields directly. They are only declared public to allow + // aggregate initialization. + + // Protects fields below. + StaticSpinMutex *mu; + // Opened file descriptor. Defaults to stderr. It may be equal to + // kInvalidFd, in which case new file will be opened when necessary. + fd_t fd; + // Path prefix of report file, set via __sanitizer_set_report_path. + char path_prefix[kMaxPathLength]; + // Full path to report, obtained as <path_prefix>.PID + char full_path[kMaxPathLength]; + // PID of the process that opened fd. If a fork() occurs, + // the PID of child will be different from fd_pid. + uptr fd_pid; + + private: + void ReopenIfNecessary(); +}; +extern ReportFile report_file; + +extern uptr stoptheworld_tracer_pid; +extern uptr stoptheworld_tracer_ppid; uptr OpenFile(const char *filename, bool write); // Opens the file 'file_name" and reads up to 'max_len' bytes. @@ -148,17 +185,18 @@ uptr ReadFileToBuffer(const char *file_name, char **buff, // (or NULL if the mapping failes). Stores the size of mmaped region // in '*buff_size'. void *MapFileToMemory(const char *file_name, uptr *buff_size); +void *MapWritableFileToMemory(void *addr, uptr size, uptr fd, uptr offset); + +bool IsAccessibleMemoryRange(uptr beg, uptr size); // Error report formatting. const char *StripPathPrefix(const char *filepath, const char *strip_file_prefix); -void PrintSourceLocation(InternalScopedString *buffer, const char *file, - int line, int column); -void PrintModuleAndOffset(InternalScopedString *buffer, - const char *module, uptr offset); +// Strip the directories from the module name. +const char *StripModuleName(const char *module); // OS -void DisableCoreDumper(); +void DisableCoreDumperIfNecessary(); void DumpProcessMap(); bool FileExists(const char *filename); const char *GetEnv(const char *name); @@ -169,7 +207,16 @@ u32 GetUid(); void ReExec(); bool StackSizeIsUnlimited(); void SetStackSizeLimitInBytes(uptr limit); -void PrepareForSandboxing(); +bool AddressSpaceIsUnlimited(); +void SetAddressSpaceUnlimited(); +void AdjustStackSize(void *attr); +void PrepareForSandboxing(__sanitizer_sandbox_arguments *args); +void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args); +void SetSandboxingCallback(void (*f)()); + +void CovUpdateMapping(uptr caller_pc = 0); +void CovBeforeFork(); +void CovAfterFork(int child_pid); void InitTlsSize(); uptr GetTlsSize(); @@ -180,9 +227,6 @@ void SleepForMillis(int millis); u64 NanoTime(); int Atexit(void (*function)(void)); void SortArray(uptr *array, uptr size); -// Strip the directories from the module name, return a new string allocated -// with internal_strdup. -char *StripModuleName(const char *module); // Exit void NORETURN Abort(); @@ -206,6 +250,14 @@ typedef void (*CheckFailedCallbackType)(const char *, int, const char *, u64, u64); void SetCheckFailedCallback(CheckFailedCallbackType callback); +// Functions related to signal handling. +typedef void (*SignalHandlerType)(int, void *, void *); +bool IsDeadlySignal(int signum); +void InstallDeadlySignalHandlers(SignalHandlerType handler); +// Alternative signal stack (POSIX-only). +void SetAlternateSignalStack(); +void UnsetAlternateSignalStack(); + // We don't want a summary too long. const int kMaxSummaryLength = 1024; // Construct a one-line string: @@ -213,7 +265,7 @@ const int kMaxSummaryLength = 1024; // and pass it to __sanitizer_report_error_summary. void ReportErrorSummary(const char *error_message); // Same as above, but construct error_message as: -// error_type: file:line function +// error_type file:line function void ReportErrorSummary(const char *error_type, const char *file, int line, const char *function); void ReportErrorSummary(const char *error_type, StackTrace *trace); @@ -243,6 +295,19 @@ INLINE uptr MostSignificantSetBitIndex(uptr x) { return up; } +INLINE uptr LeastSignificantSetBitIndex(uptr x) { + CHECK_NE(x, 0U); + unsigned long up; // NOLINT +#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__) + up = __builtin_ctzl(x); +#elif defined(_WIN64) + _BitScanForward64(&up, x); +#else + _BitScanForward(&up, x); +#endif + return up; +} + INLINE bool IsPowerOfTwo(uptr x) { return (x & (x - 1)) == 0; } @@ -307,12 +372,6 @@ INLINE int ToLower(int c) { return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c; } -#if SANITIZER_WORDSIZE == 64 -# define FIRST_32_SECOND_64(a, b) (b) -#else -# define FIRST_32_SECOND_64(a, b) (a) -#endif - // A low-level vector based on mmap. May incur a significant memory overhead for // small vectors. // WARNING: The current implementation supports only POD types. @@ -320,8 +379,7 @@ template<typename T> class InternalMmapVector { public: explicit InternalMmapVector(uptr initial_capacity) { - CHECK_GT(initial_capacity, 0); - capacity_ = initial_capacity; + capacity_ = Max(initial_capacity, (uptr)1); size_ = 0; data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalMmapVector"); } @@ -443,12 +501,17 @@ uptr InternalBinarySearch(const Container &v, uptr first, uptr last, class LoadedModule { public: LoadedModule(const char *module_name, uptr base_address); - void addAddressRange(uptr beg, uptr end); + void addAddressRange(uptr beg, uptr end, bool executable); bool containsAddress(uptr address) const; const char *full_name() const { return full_name_; } uptr base_address() const { return base_address_; } + uptr n_ranges() const { return n_ranges_; } + uptr address_range_start(int i) const { return ranges_[i].beg; } + uptr address_range_end(int i) const { return ranges_[i].end; } + bool address_range_executable(int i) const { return exec_[i]; } + private: struct AddressRange { uptr beg; @@ -458,6 +521,7 @@ class LoadedModule { uptr base_address_; static const uptr kMaxNumberOfAddressRanges = 6; AddressRange ranges_[kMaxNumberOfAddressRanges]; + bool exec_[kMaxNumberOfAddressRanges]; uptr n_ranges_; }; @@ -478,6 +542,33 @@ const uptr kPthreadDestructorIterations = 0; // Callback type for iterating over a set of memory ranges. typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg); + +#if SANITIZER_ANDROID +// Initialize Android logging. Any writes before this are silently lost. +void AndroidLogInit(); +void AndroidLogWrite(const char *buffer); +void GetExtraActivationFlags(char *buf, uptr size); +void SanitizerInitializeUnwinder(); +#else +INLINE void AndroidLogInit() {} +INLINE void AndroidLogWrite(const char *buffer_unused) {} +INLINE void GetExtraActivationFlags(char *buf, uptr size) { *buf = '\0'; } +INLINE void SanitizerInitializeUnwinder() {} +#endif + +// Make the compiler think that something is going on there. +// Use this inside a loop that looks like memset/memcpy/etc to prevent the +// compiler from recognising it and turning it into an actual call to +// memset/memcpy/etc. +static inline void SanitizerBreakOptimization(void *arg) { +#if _MSC_VER + // FIXME: make sure this is actually enough. + __asm; +#else + __asm__ __volatile__("" : : "r" (arg) : "memory"); +#endif +} + } // namespace __sanitizer inline void *operator new(__sanitizer::operator_new_size_type size, @@ -485,4 +576,9 @@ inline void *operator new(__sanitizer::operator_new_size_type size, return alloc.Allocate(size); } +struct StackDepotStats { + uptr n_uniq_ids; + uptr allocated; +}; + #endif // SANITIZER_COMMON_H |