sanitizer_common.h revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
1//===-- sanitizer_common.h --------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is shared between AddressSanitizer and ThreadSanitizer 11// run-time libraries. 12// It declares common functions and classes that are used in both runtimes. 13// Implementation of some functions are provided in sanitizer_common, while 14// others must be defined by run-time library itself. 15//===----------------------------------------------------------------------===// 16#ifndef SANITIZER_COMMON_H 17#define SANITIZER_COMMON_H 18 19#include "sanitizer_internal_defs.h" 20#include "sanitizer_libc.h" 21#include "sanitizer_mutex.h" 22#include "sanitizer_flags.h" 23 24namespace __sanitizer { 25struct StackTrace; 26 27// Constants. 28const uptr kWordSize = SANITIZER_WORDSIZE / 8; 29const uptr kWordSizeInBits = 8 * kWordSize; 30 31const uptr kCacheLineSize = 64; 32 33const uptr kMaxPathLength = 512; 34 35const uptr kMaxThreadStackSize = 1 << 30; // 1Gb 36 37extern const char *SanitizerToolName; // Can be changed by the tool. 38 39uptr GetPageSize(); 40uptr GetPageSizeCached(); 41uptr GetMmapGranularity(); 42uptr GetMaxVirtualAddress(); 43// Threads 44uptr GetTid(); 45uptr GetThreadSelf(); 46void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, 47 uptr *stack_bottom); 48void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, 49 uptr *tls_addr, uptr *tls_size); 50 51// Memory management 52void *MmapOrDie(uptr size, const char *mem_type); 53void UnmapOrDie(void *addr, uptr size); 54void *MmapFixedNoReserve(uptr fixed_addr, uptr size); 55void *MmapNoReserveOrDie(uptr size, const char *mem_type); 56void *MmapFixedOrDie(uptr fixed_addr, uptr size); 57void *Mprotect(uptr fixed_addr, uptr size); 58// Map aligned chunk of address space; size and alignment are powers of two. 59void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type); 60// Used to check if we can map shadow memory to a fixed location. 61bool MemoryRangeIsAvailable(uptr range_start, uptr range_end); 62void FlushUnneededShadowMemory(uptr addr, uptr size); 63void IncreaseTotalMmap(uptr size); 64void DecreaseTotalMmap(uptr size); 65 66// InternalScopedBuffer can be used instead of large stack arrays to 67// keep frame size low. 68// FIXME: use InternalAlloc instead of MmapOrDie once 69// InternalAlloc is made libc-free. 70template<typename T> 71class InternalScopedBuffer { 72 public: 73 explicit InternalScopedBuffer(uptr cnt) { 74 cnt_ = cnt; 75 ptr_ = (T*)MmapOrDie(cnt * sizeof(T), "InternalScopedBuffer"); 76 } 77 ~InternalScopedBuffer() { 78 UnmapOrDie(ptr_, cnt_ * sizeof(T)); 79 } 80 T &operator[](uptr i) { return ptr_[i]; } 81 T *data() { return ptr_; } 82 uptr size() { return cnt_ * sizeof(T); } 83 84 private: 85 T *ptr_; 86 uptr cnt_; 87 // Disallow evil constructors. 88 InternalScopedBuffer(const InternalScopedBuffer&); 89 void operator=(const InternalScopedBuffer&); 90}; 91 92class InternalScopedString : public InternalScopedBuffer<char> { 93 public: 94 explicit InternalScopedString(uptr max_length) 95 : InternalScopedBuffer<char>(max_length), length_(0) { 96 (*this)[0] = '\0'; 97 } 98 uptr length() { return length_; } 99 void clear() { 100 (*this)[0] = '\0'; 101 length_ = 0; 102 } 103 void append(const char *format, ...); 104 105 private: 106 uptr length_; 107}; 108 109// Simple low-level (mmap-based) allocator for internal use. Doesn't have 110// constructor, so all instances of LowLevelAllocator should be 111// linker initialized. 112class LowLevelAllocator { 113 public: 114 // Requires an external lock. 115 void *Allocate(uptr size); 116 private: 117 char *allocated_end_; 118 char *allocated_current_; 119}; 120typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size); 121// Allows to register tool-specific callbacks for LowLevelAllocator. 122// Passing NULL removes the callback. 123void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback); 124 125// IO 126void RawWrite(const char *buffer); 127bool PrintsToTty(); 128// Caching version of PrintsToTty(). Not thread-safe. 129bool PrintsToTtyCached(); 130bool ColorizeReports(); 131void Printf(const char *format, ...); 132void Report(const char *format, ...); 133void SetPrintfAndReportCallback(void (*callback)(const char *)); 134#define VReport(level, ...) \ 135 do { \ 136 if ((uptr)common_flags()->verbosity >= (level)) Report(__VA_ARGS__); \ 137 } while (0) 138#define VPrintf(level, ...) \ 139 do { \ 140 if ((uptr)common_flags()->verbosity >= (level)) Printf(__VA_ARGS__); \ 141 } while (0) 142 143// Can be used to prevent mixing error reports from different sanitizers. 144extern StaticSpinMutex CommonSanitizerReportMutex; 145void MaybeOpenReportFile(); 146extern fd_t report_fd; 147extern bool log_to_file; 148extern char report_path_prefix[4096]; 149extern uptr report_fd_pid; 150extern uptr stoptheworld_tracer_pid; 151extern uptr stoptheworld_tracer_ppid; 152 153uptr OpenFile(const char *filename, bool write); 154// Opens the file 'file_name" and reads up to 'max_len' bytes. 155// The resulting buffer is mmaped and stored in '*buff'. 156// The size of the mmaped region is stored in '*buff_size', 157// Returns the number of read bytes or 0 if file can not be opened. 158uptr ReadFileToBuffer(const char *file_name, char **buff, 159 uptr *buff_size, uptr max_len); 160// Maps given file to virtual memory, and returns pointer to it 161// (or NULL if the mapping failes). Stores the size of mmaped region 162// in '*buff_size'. 163void *MapFileToMemory(const char *file_name, uptr *buff_size); 164void *MapWritableFileToMemory(void *addr, uptr size, uptr fd, uptr offset); 165 166// Error report formatting. 167const char *StripPathPrefix(const char *filepath, 168 const char *strip_file_prefix); 169void PrintSourceLocation(InternalScopedString *buffer, const char *file, 170 int line, int column); 171void PrintModuleAndOffset(InternalScopedString *buffer, 172 const char *module, uptr offset); 173 174// OS 175void DisableCoreDumper(); 176void DumpProcessMap(); 177bool FileExists(const char *filename); 178const char *GetEnv(const char *name); 179bool SetEnv(const char *name, const char *value); 180const char *GetPwd(); 181char *FindPathToBinary(const char *name); 182u32 GetUid(); 183void ReExec(); 184bool StackSizeIsUnlimited(); 185void SetStackSizeLimitInBytes(uptr limit); 186void AdjustStackSize(void *attr); 187void PrepareForSandboxing(__sanitizer_sandbox_arguments *args); 188void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args); 189void SetSandboxingCallback(void (*f)()); 190 191void CovUpdateMapping(); 192 193void InitTlsSize(); 194uptr GetTlsSize(); 195 196// Other 197void SleepForSeconds(int seconds); 198void SleepForMillis(int millis); 199u64 NanoTime(); 200int Atexit(void (*function)(void)); 201void SortArray(uptr *array, uptr size); 202// Strip the directories from the module name, return a new string allocated 203// with internal_strdup. 204char *StripModuleName(const char *module); 205 206// Exit 207void NORETURN Abort(); 208void NORETURN Die(); 209void NORETURN 210CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2); 211 212// Set the name of the current thread to 'name', return true on succees. 213// The name may be truncated to a system-dependent limit. 214bool SanitizerSetThreadName(const char *name); 215// Get the name of the current thread (no more than max_len bytes), 216// return true on succees. name should have space for at least max_len+1 bytes. 217bool SanitizerGetThreadName(char *name, int max_len); 218 219// Specific tools may override behavior of "Die" and "CheckFailed" functions 220// to do tool-specific job. 221typedef void (*DieCallbackType)(void); 222void SetDieCallback(DieCallbackType); 223DieCallbackType GetDieCallback(); 224typedef void (*CheckFailedCallbackType)(const char *, int, const char *, 225 u64, u64); 226void SetCheckFailedCallback(CheckFailedCallbackType callback); 227 228// Functions related to signal handling. 229typedef void (*SignalHandlerType)(int, void *, void *); 230bool IsDeadlySignal(int signum); 231void InstallDeadlySignalHandlers(SignalHandlerType handler); 232// Alternative signal stack (POSIX-only). 233void SetAlternateSignalStack(); 234void UnsetAlternateSignalStack(); 235 236// We don't want a summary too long. 237const int kMaxSummaryLength = 1024; 238// Construct a one-line string: 239// SUMMARY: SanitizerToolName: error_message 240// and pass it to __sanitizer_report_error_summary. 241void ReportErrorSummary(const char *error_message); 242// Same as above, but construct error_message as: 243// error_type: file:line function 244void ReportErrorSummary(const char *error_type, const char *file, 245 int line, const char *function); 246void ReportErrorSummary(const char *error_type, StackTrace *trace); 247 248// Math 249#if SANITIZER_WINDOWS && !defined(__clang__) && !defined(__GNUC__) 250extern "C" { 251unsigned char _BitScanForward(unsigned long *index, unsigned long mask); // NOLINT 252unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); // NOLINT 253#if defined(_WIN64) 254unsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask); // NOLINT 255unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask); // NOLINT 256#endif 257} 258#endif 259 260INLINE uptr MostSignificantSetBitIndex(uptr x) { 261 CHECK_NE(x, 0U); 262 unsigned long up; // NOLINT 263#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__) 264 up = SANITIZER_WORDSIZE - 1 - __builtin_clzl(x); 265#elif defined(_WIN64) 266 _BitScanReverse64(&up, x); 267#else 268 _BitScanReverse(&up, x); 269#endif 270 return up; 271} 272 273INLINE uptr LeastSignificantSetBitIndex(uptr x) { 274 CHECK_NE(x, 0U); 275 unsigned long up; // NOLINT 276#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__) 277 up = __builtin_ctzl(x); 278#elif defined(_WIN64) 279 _BitScanForward64(&up, x); 280#else 281 _BitScanForward(&up, x); 282#endif 283 return up; 284} 285 286INLINE bool IsPowerOfTwo(uptr x) { 287 return (x & (x - 1)) == 0; 288} 289 290INLINE uptr RoundUpToPowerOfTwo(uptr size) { 291 CHECK(size); 292 if (IsPowerOfTwo(size)) return size; 293 294 uptr up = MostSignificantSetBitIndex(size); 295 CHECK(size < (1ULL << (up + 1))); 296 CHECK(size > (1ULL << up)); 297 return 1UL << (up + 1); 298} 299 300INLINE uptr RoundUpTo(uptr size, uptr boundary) { 301 CHECK(IsPowerOfTwo(boundary)); 302 return (size + boundary - 1) & ~(boundary - 1); 303} 304 305INLINE uptr RoundDownTo(uptr x, uptr boundary) { 306 return x & ~(boundary - 1); 307} 308 309INLINE bool IsAligned(uptr a, uptr alignment) { 310 return (a & (alignment - 1)) == 0; 311} 312 313INLINE uptr Log2(uptr x) { 314 CHECK(IsPowerOfTwo(x)); 315#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__) 316 return __builtin_ctzl(x); 317#elif defined(_WIN64) 318 unsigned long ret; // NOLINT 319 _BitScanForward64(&ret, x); 320 return ret; 321#else 322 unsigned long ret; // NOLINT 323 _BitScanForward(&ret, x); 324 return ret; 325#endif 326} 327 328// Don't use std::min, std::max or std::swap, to minimize dependency 329// on libstdc++. 330template<class T> T Min(T a, T b) { return a < b ? a : b; } 331template<class T> T Max(T a, T b) { return a > b ? a : b; } 332template<class T> void Swap(T& a, T& b) { 333 T tmp = a; 334 a = b; 335 b = tmp; 336} 337 338// Char handling 339INLINE bool IsSpace(int c) { 340 return (c == ' ') || (c == '\n') || (c == '\t') || 341 (c == '\f') || (c == '\r') || (c == '\v'); 342} 343INLINE bool IsDigit(int c) { 344 return (c >= '0') && (c <= '9'); 345} 346INLINE int ToLower(int c) { 347 return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c; 348} 349 350// A low-level vector based on mmap. May incur a significant memory overhead for 351// small vectors. 352// WARNING: The current implementation supports only POD types. 353template<typename T> 354class InternalMmapVector { 355 public: 356 explicit InternalMmapVector(uptr initial_capacity) { 357 capacity_ = Max(initial_capacity, (uptr)1); 358 size_ = 0; 359 data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalMmapVector"); 360 } 361 ~InternalMmapVector() { 362 UnmapOrDie(data_, capacity_ * sizeof(T)); 363 } 364 T &operator[](uptr i) { 365 CHECK_LT(i, size_); 366 return data_[i]; 367 } 368 const T &operator[](uptr i) const { 369 CHECK_LT(i, size_); 370 return data_[i]; 371 } 372 void push_back(const T &element) { 373 CHECK_LE(size_, capacity_); 374 if (size_ == capacity_) { 375 uptr new_capacity = RoundUpToPowerOfTwo(size_ + 1); 376 Resize(new_capacity); 377 } 378 data_[size_++] = element; 379 } 380 T &back() { 381 CHECK_GT(size_, 0); 382 return data_[size_ - 1]; 383 } 384 void pop_back() { 385 CHECK_GT(size_, 0); 386 size_--; 387 } 388 uptr size() const { 389 return size_; 390 } 391 const T *data() const { 392 return data_; 393 } 394 uptr capacity() const { 395 return capacity_; 396 } 397 398 void clear() { size_ = 0; } 399 400 private: 401 void Resize(uptr new_capacity) { 402 CHECK_GT(new_capacity, 0); 403 CHECK_LE(size_, new_capacity); 404 T *new_data = (T *)MmapOrDie(new_capacity * sizeof(T), 405 "InternalMmapVector"); 406 internal_memcpy(new_data, data_, size_ * sizeof(T)); 407 T *old_data = data_; 408 data_ = new_data; 409 UnmapOrDie(old_data, capacity_ * sizeof(T)); 410 capacity_ = new_capacity; 411 } 412 // Disallow evil constructors. 413 InternalMmapVector(const InternalMmapVector&); 414 void operator=(const InternalMmapVector&); 415 416 T *data_; 417 uptr capacity_; 418 uptr size_; 419}; 420 421// HeapSort for arrays and InternalMmapVector. 422template<class Container, class Compare> 423void InternalSort(Container *v, uptr size, Compare comp) { 424 if (size < 2) 425 return; 426 // Stage 1: insert elements to the heap. 427 for (uptr i = 1; i < size; i++) { 428 uptr j, p; 429 for (j = i; j > 0; j = p) { 430 p = (j - 1) / 2; 431 if (comp((*v)[p], (*v)[j])) 432 Swap((*v)[j], (*v)[p]); 433 else 434 break; 435 } 436 } 437 // Stage 2: swap largest element with the last one, 438 // and sink the new top. 439 for (uptr i = size - 1; i > 0; i--) { 440 Swap((*v)[0], (*v)[i]); 441 uptr j, max_ind; 442 for (j = 0; j < i; j = max_ind) { 443 uptr left = 2 * j + 1; 444 uptr right = 2 * j + 2; 445 max_ind = j; 446 if (left < i && comp((*v)[max_ind], (*v)[left])) 447 max_ind = left; 448 if (right < i && comp((*v)[max_ind], (*v)[right])) 449 max_ind = right; 450 if (max_ind != j) 451 Swap((*v)[j], (*v)[max_ind]); 452 else 453 break; 454 } 455 } 456} 457 458template<class Container, class Value, class Compare> 459uptr InternalBinarySearch(const Container &v, uptr first, uptr last, 460 const Value &val, Compare comp) { 461 uptr not_found = last + 1; 462 while (last >= first) { 463 uptr mid = (first + last) / 2; 464 if (comp(v[mid], val)) 465 first = mid + 1; 466 else if (comp(val, v[mid])) 467 last = mid - 1; 468 else 469 return mid; 470 } 471 return not_found; 472} 473 474// Represents a binary loaded into virtual memory (e.g. this can be an 475// executable or a shared object). 476class LoadedModule { 477 public: 478 LoadedModule(const char *module_name, uptr base_address); 479 void addAddressRange(uptr beg, uptr end); 480 bool containsAddress(uptr address) const; 481 482 const char *full_name() const { return full_name_; } 483 uptr base_address() const { return base_address_; } 484 485 uptr n_ranges() const { return n_ranges_; } 486 uptr address_range_start(int i) const { return ranges_[i].beg; } 487 uptr address_range_end(int i) const { return ranges_[i].end; } 488 489 private: 490 struct AddressRange { 491 uptr beg; 492 uptr end; 493 }; 494 char *full_name_; 495 uptr base_address_; 496 static const uptr kMaxNumberOfAddressRanges = 6; 497 AddressRange ranges_[kMaxNumberOfAddressRanges]; 498 uptr n_ranges_; 499}; 500 501// OS-dependent function that fills array with descriptions of at most 502// "max_modules" currently loaded modules. Returns the number of 503// initialized modules. If filter is nonzero, ignores modules for which 504// filter(full_name) is false. 505typedef bool (*string_predicate_t)(const char *); 506uptr GetListOfModules(LoadedModule *modules, uptr max_modules, 507 string_predicate_t filter); 508 509#if SANITIZER_POSIX 510const uptr kPthreadDestructorIterations = 4; 511#else 512// Unused on Windows. 513const uptr kPthreadDestructorIterations = 0; 514#endif 515 516// Callback type for iterating over a set of memory ranges. 517typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg); 518 519#if (SANITIZER_FREEBSD || SANITIZER_LINUX) && !defined(SANITIZER_GO) 520extern uptr indirect_call_wrapper; 521void SetIndirectCallWrapper(uptr wrapper); 522 523template <typename F> 524F IndirectExternCall(F f) { 525 typedef F (*WrapF)(F); 526 return indirect_call_wrapper ? ((WrapF)indirect_call_wrapper)(f) : f; 527} 528#else 529INLINE void SetIndirectCallWrapper(uptr wrapper) {} 530template <typename F> 531F IndirectExternCall(F f) { 532 return f; 533} 534#endif 535 536#if SANITIZER_ANDROID 537void AndroidLogWrite(const char *buffer); 538void GetExtraActivationFlags(char *buf, uptr size); 539void SanitizerInitializeUnwinder(); 540#else 541INLINE void AndroidLogWrite(const char *buffer_unused) {} 542INLINE void GetExtraActivationFlags(char *buf, uptr size) { *buf = '\0'; } 543INLINE void SanitizerInitializeUnwinder() {} 544#endif 545} // namespace __sanitizer 546 547inline void *operator new(__sanitizer::operator_new_size_type size, 548 __sanitizer::LowLevelAllocator &alloc) { 549 return alloc.Allocate(size); 550} 551 552struct StackDepotStats { 553 uptr n_uniq_ids; 554 uptr allocated; 555}; 556 557#endif // SANITIZER_COMMON_H 558