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