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 
     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 extern const char *SanitizerToolName;  // Can be changed by the tool.
     36 extern uptr SanitizerVerbosity;
     37 
     38 uptr GetPageSize();
     39 uptr GetPageSizeCached();
     40 uptr GetMmapGranularity();
     41 // Threads
     42 int GetPid();
     43 uptr GetTid();
     44 uptr GetThreadSelf();
     45 void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
     46                                 uptr *stack_bottom);
     47 
     48 // Memory management
     49 void *MmapOrDie(uptr size, const char *mem_type);
     50 void UnmapOrDie(void *addr, uptr size);
     51 void *MmapFixedNoReserve(uptr fixed_addr, uptr size);
     52 void *MmapFixedOrDie(uptr fixed_addr, uptr size);
     53 void *Mprotect(uptr fixed_addr, uptr size);
     54 // Map aligned chunk of address space; size and alignment are powers of two.
     55 void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type);
     56 // Used to check if we can map shadow memory to a fixed location.
     57 bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
     58 void FlushUnneededShadowMemory(uptr addr, uptr size);
     59 
     60 // Internal allocator
     61 void *InternalAlloc(uptr size);
     62 void InternalFree(void *p);
     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.
     68 template<typename T>
     69 class 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 
     90 // Simple low-level (mmap-based) allocator for internal use. Doesn't have
     91 // constructor, so all instances of LowLevelAllocator should be
     92 // linker initialized.
     93 class LowLevelAllocator {
     94  public:
     95   // Requires an external lock.
     96   void *Allocate(uptr size);
     97  private:
     98   char *allocated_end_;
     99   char *allocated_current_;
    100 };
    101 typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);
    102 // Allows to register tool-specific callbacks for LowLevelAllocator.
    103 // Passing NULL removes the callback.
    104 void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback);
    105 
    106 // IO
    107 void RawWrite(const char *buffer);
    108 bool PrintsToTty();
    109 void Printf(const char *format, ...);
    110 void Report(const char *format, ...);
    111 void SetPrintfAndReportCallback(void (*callback)(const char *));
    112 
    113 fd_t OpenFile(const char *filename, bool write);
    114 // Opens the file 'file_name" and reads up to 'max_len' bytes.
    115 // The resulting buffer is mmaped and stored in '*buff'.
    116 // The size of the mmaped region is stored in '*buff_size',
    117 // Returns the number of read bytes or 0 if file can not be opened.
    118 uptr ReadFileToBuffer(const char *file_name, char **buff,
    119                       uptr *buff_size, uptr max_len);
    120 // Maps given file to virtual memory, and returns pointer to it
    121 // (or NULL if the mapping failes). Stores the size of mmaped region
    122 // in '*buff_size'.
    123 void *MapFileToMemory(const char *file_name, uptr *buff_size);
    124 
    125 // OS
    126 void DisableCoreDumper();
    127 void DumpProcessMap();
    128 bool FileExists(const char *filename);
    129 const char *GetEnv(const char *name);
    130 const char *GetPwd();
    131 u32 GetUid();
    132 void ReExec();
    133 bool StackSizeIsUnlimited();
    134 void SetStackSizeLimitInBytes(uptr limit);
    135 void PrepareForSandboxing();
    136 
    137 void InitTlsSize();
    138 uptr GetTlsSize();
    139 
    140 // Other
    141 void SleepForSeconds(int seconds);
    142 void SleepForMillis(int millis);
    143 int Atexit(void (*function)(void));
    144 void SortArray(uptr *array, uptr size);
    145 
    146 // Exit
    147 void NORETURN Abort();
    148 void NORETURN Die();
    149 void NORETURN SANITIZER_INTERFACE_ATTRIBUTE
    150 CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
    151 
    152 // Set the name of the current thread to 'name', return true on succees.
    153 // The name may be truncated to a system-dependent limit.
    154 bool SanitizerSetThreadName(const char *name);
    155 // Get the name of the current thread (no more than max_len bytes),
    156 // return true on succees. name should have space for at least max_len+1 bytes.
    157 bool SanitizerGetThreadName(char *name, int max_len);
    158 
    159 // Specific tools may override behavior of "Die" and "CheckFailed" functions
    160 // to do tool-specific job.
    161 void SetDieCallback(void (*callback)(void));
    162 typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
    163                                        u64, u64);
    164 void SetCheckFailedCallback(CheckFailedCallbackType callback);
    165 
    166 // Construct a one-line string like
    167 //  SanitizerToolName: error_type file:line function
    168 // and call __sanitizer_report_error_summary on it.
    169 void ReportErrorSummary(const char *error_type, const char *file,
    170                         int line, const char *function);
    171 
    172 // Math
    173 #if defined(_WIN32) && !defined(__clang__)
    174 extern "C" {
    175 unsigned char _BitScanForward(unsigned long *index, unsigned long mask);  // NOLINT
    176 unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);  // NOLINT
    177 #if defined(_WIN64)
    178 unsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask);  // NOLINT
    179 unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask);  // NOLINT
    180 #endif
    181 }
    182 #endif
    183 
    184 INLINE uptr MostSignificantSetBitIndex(uptr x) {
    185   CHECK_NE(x, 0U);
    186   unsigned long up;  // NOLINT
    187 #if !defined(_WIN32) || defined(__clang__)
    188   up = SANITIZER_WORDSIZE - 1 - __builtin_clzl(x);
    189 #elif defined(_WIN64)
    190   _BitScanReverse64(&up, x);
    191 #else
    192   _BitScanReverse(&up, x);
    193 #endif
    194   return up;
    195 }
    196 
    197 INLINE bool IsPowerOfTwo(uptr x) {
    198   return (x & (x - 1)) == 0;
    199 }
    200 
    201 INLINE uptr RoundUpToPowerOfTwo(uptr size) {
    202   CHECK(size);
    203   if (IsPowerOfTwo(size)) return size;
    204 
    205   uptr up = MostSignificantSetBitIndex(size);
    206   CHECK(size < (1ULL << (up + 1)));
    207   CHECK(size > (1ULL << up));
    208   return 1UL << (up + 1);
    209 }
    210 
    211 INLINE uptr RoundUpTo(uptr size, uptr boundary) {
    212   CHECK(IsPowerOfTwo(boundary));
    213   return (size + boundary - 1) & ~(boundary - 1);
    214 }
    215 
    216 INLINE uptr RoundDownTo(uptr x, uptr boundary) {
    217   return x & ~(boundary - 1);
    218 }
    219 
    220 INLINE bool IsAligned(uptr a, uptr alignment) {
    221   return (a & (alignment - 1)) == 0;
    222 }
    223 
    224 INLINE uptr Log2(uptr x) {
    225   CHECK(IsPowerOfTwo(x));
    226 #if !defined(_WIN32) || defined(__clang__)
    227   return __builtin_ctzl(x);
    228 #elif defined(_WIN64)
    229   unsigned long ret;  // NOLINT
    230   _BitScanForward64(&ret, x);
    231   return ret;
    232 #else
    233   unsigned long ret;  // NOLINT
    234   _BitScanForward(&ret, x);
    235   return ret;
    236 #endif
    237 }
    238 
    239 // Don't use std::min, std::max or std::swap, to minimize dependency
    240 // on libstdc++.
    241 template<class T> T Min(T a, T b) { return a < b ? a : b; }
    242 template<class T> T Max(T a, T b) { return a > b ? a : b; }
    243 template<class T> void Swap(T& a, T& b) {
    244   T tmp = a;
    245   a = b;
    246   b = tmp;
    247 }
    248 
    249 // Char handling
    250 INLINE bool IsSpace(int c) {
    251   return (c == ' ') || (c == '\n') || (c == '\t') ||
    252          (c == '\f') || (c == '\r') || (c == '\v');
    253 }
    254 INLINE bool IsDigit(int c) {
    255   return (c >= '0') && (c <= '9');
    256 }
    257 INLINE int ToLower(int c) {
    258   return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
    259 }
    260 
    261 #if SANITIZER_WORDSIZE == 64
    262 # define FIRST_32_SECOND_64(a, b) (b)
    263 #else
    264 # define FIRST_32_SECOND_64(a, b) (a)
    265 #endif
    266 
    267 // A low-level vector based on mmap. May incur a significant memory overhead for
    268 // small vectors.
    269 // WARNING: The current implementation supports only POD types.
    270 template<typename T>
    271 class InternalVector {
    272  public:
    273   explicit InternalVector(uptr initial_capacity) {
    274     CHECK_GT(initial_capacity, 0);
    275     capacity_ = initial_capacity;
    276     size_ = 0;
    277     data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalVector");
    278   }
    279   ~InternalVector() {
    280     UnmapOrDie(data_, capacity_ * sizeof(T));
    281   }
    282   T &operator[](uptr i) {
    283     CHECK_LT(i, size_);
    284     return data_[i];
    285   }
    286   void push_back(const T &element) {
    287     CHECK_LE(size_, capacity_);
    288     if (size_ == capacity_) {
    289       uptr new_capacity = RoundUpToPowerOfTwo(size_ + 1);
    290       Resize(new_capacity);
    291     }
    292     data_[size_++] = element;
    293   }
    294   T &back() {
    295     CHECK_GT(size_, 0);
    296     return data_[size_ - 1];
    297   }
    298   void pop_back() {
    299     CHECK_GT(size_, 0);
    300     size_--;
    301   }
    302   uptr size() {
    303     return size_;
    304   }
    305 
    306  private:
    307   void Resize(uptr new_capacity) {
    308     CHECK_GT(new_capacity, 0);
    309     CHECK_LE(size_, new_capacity);
    310     T *new_data = (T *)MmapOrDie(new_capacity * sizeof(T),
    311                                  "InternalVector");
    312     internal_memcpy(new_data, data_, size_ * sizeof(T));
    313     T *old_data = data_;
    314     data_ = new_data;
    315     UnmapOrDie(old_data, capacity_ * sizeof(T));
    316     capacity_ = new_capacity;
    317   }
    318   // Disallow evil constructors.
    319   InternalVector(const InternalVector&);
    320   void operator=(const InternalVector&);
    321 
    322   T *data_;
    323   uptr capacity_;
    324   uptr size_;
    325 };
    326 }  // namespace __sanitizer
    327 
    328 #endif  // SANITIZER_COMMON_H
    329