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