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