Home | History | Annotate | Line # | Download | only in sanitizer_common
sanitizer_common.h revision 1.1
      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 
     19 namespace __sanitizer {
     20 struct StackTrace;
     21 
     22 // Constants.
     23 const uptr kWordSize = SANITIZER_WORDSIZE / 8;
     24 const uptr kWordSizeInBits = 8 * kWordSize;
     25 
     26 #if defined(__powerpc__) || defined(__powerpc64__)
     27 const uptr kCacheLineSize = 128;
     28 #else
     29 const uptr kCacheLineSize = 64;
     30 #endif
     31 
     32 extern const char *SanitizerToolName;  // Can be changed by the tool.
     33 
     34 uptr GetPageSize();
     35 uptr GetPageSizeCached();
     36 uptr GetMmapGranularity();
     37 // Threads
     38 int GetPid();
     39 uptr GetTid();
     40 uptr GetThreadSelf();
     41 void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
     42                                 uptr *stack_bottom);
     43 
     44 // Memory management
     45 void *MmapOrDie(uptr size, const char *mem_type);
     46 void UnmapOrDie(void *addr, uptr size);
     47 void *MmapFixedNoReserve(uptr fixed_addr, uptr size);
     48 void *MmapFixedOrDie(uptr fixed_addr, uptr size);
     49 void *Mprotect(uptr fixed_addr, uptr size);
     50 // Map aligned chunk of address space; size and alignment are powers of two.
     51 void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type);
     52 // Used to check if we can map shadow memory to a fixed location.
     53 bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
     54 void FlushUnneededShadowMemory(uptr addr, uptr size);
     55 
     56 // Internal allocator
     57 void *InternalAlloc(uptr size);
     58 void InternalFree(void *p);
     59 
     60 // InternalScopedBuffer can be used instead of large stack arrays to
     61 // keep frame size low.
     62 // FIXME: use InternalAlloc instead of MmapOrDie once
     63 // InternalAlloc is made libc-free.
     64 template<typename T>
     65 class InternalScopedBuffer {
     66  public:
     67   explicit InternalScopedBuffer(uptr cnt) {
     68     cnt_ = cnt;
     69     ptr_ = (T*)MmapOrDie(cnt * sizeof(T), "InternalScopedBuffer");
     70   }
     71   ~InternalScopedBuffer() {
     72     UnmapOrDie(ptr_, cnt_ * sizeof(T));
     73   }
     74   T &operator[](uptr i) { return ptr_[i]; }
     75   T *data() { return ptr_; }
     76   uptr size() { return cnt_ * sizeof(T); }
     77 
     78  private:
     79   T *ptr_;
     80   uptr cnt_;
     81   // Disallow evil constructors.
     82   InternalScopedBuffer(const InternalScopedBuffer&);
     83   void operator=(const InternalScopedBuffer&);
     84 };
     85 
     86 // Simple low-level (mmap-based) allocator for internal use. Doesn't have
     87 // constructor, so all instances of LowLevelAllocator should be
     88 // linker initialized.
     89 class LowLevelAllocator {
     90  public:
     91   // Requires an external lock.
     92   void *Allocate(uptr size);
     93  private:
     94   char *allocated_end_;
     95   char *allocated_current_;
     96 };
     97 typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);
     98 // Allows to register tool-specific callbacks for LowLevelAllocator.
     99 // Passing NULL removes the callback.
    100 void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback);
    101 
    102 // IO
    103 void RawWrite(const char *buffer);
    104 bool PrintsToTty();
    105 void Printf(const char *format, ...);
    106 void Report(const char *format, ...);
    107 void SetPrintfAndReportCallback(void (*callback)(const char *));
    108 
    109 fd_t OpenFile(const char *filename, bool write);
    110 // Opens the file 'file_name" and reads up to 'max_len' bytes.
    111 // The resulting buffer is mmaped and stored in '*buff'.
    112 // The size of the mmaped region is stored in '*buff_size',
    113 // Returns the number of read bytes or 0 if file can not be opened.
    114 uptr ReadFileToBuffer(const char *file_name, char **buff,
    115                       uptr *buff_size, uptr max_len);
    116 // Maps given file to virtual memory, and returns pointer to it
    117 // (or NULL if the mapping failes). Stores the size of mmaped region
    118 // in '*buff_size'.
    119 void *MapFileToMemory(const char *file_name, uptr *buff_size);
    120 
    121 // OS
    122 void DisableCoreDumper();
    123 void DumpProcessMap();
    124 bool FileExists(const char *filename);
    125 const char *GetEnv(const char *name);
    126 const char *GetPwd();
    127 u32 GetUid();
    128 void ReExec();
    129 bool StackSizeIsUnlimited();
    130 void SetStackSizeLimitInBytes(uptr limit);
    131 void PrepareForSandboxing();
    132 
    133 // Other
    134 void SleepForSeconds(int seconds);
    135 void SleepForMillis(int millis);
    136 int Atexit(void (*function)(void));
    137 void SortArray(uptr *array, uptr size);
    138 
    139 // Exit
    140 void NORETURN Abort();
    141 void NORETURN Die();
    142 void NORETURN SANITIZER_INTERFACE_ATTRIBUTE
    143 CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
    144 
    145 // Set the name of the current thread to 'name', return true on succees.
    146 // The name may be truncated to a system-dependent limit.
    147 bool SanitizerSetThreadName(const char *name);
    148 // Get the name of the current thread (no more than max_len bytes),
    149 // return true on succees. name should have space for at least max_len+1 bytes.
    150 bool SanitizerGetThreadName(char *name, int max_len);
    151 
    152 // Specific tools may override behavior of "Die" and "CheckFailed" functions
    153 // to do tool-specific job.
    154 void SetDieCallback(void (*callback)(void));
    155 typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
    156                                        u64, u64);
    157 void SetCheckFailedCallback(CheckFailedCallbackType callback);
    158 
    159 // Construct a one-line string like
    160 //  SanitizerToolName: error_type file:line function
    161 // and call __sanitizer_report_error_summary on it.
    162 void ReportErrorSummary(const char *error_type, const char *file,
    163                         int line, const char *function);
    164 
    165 // Math
    166 #if defined(_WIN32) && !defined(__clang__)
    167 extern "C" {
    168 unsigned char _BitScanForward(unsigned long *index, unsigned long mask);  // NOLINT
    169 unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);  // NOLINT
    170 #if defined(_WIN64)
    171 unsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask);  // NOLINT
    172 unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask);  // NOLINT
    173 #endif
    174 }
    175 #endif
    176 
    177 INLINE uptr MostSignificantSetBitIndex(uptr x) {
    178   CHECK(x != 0);
    179   unsigned long up;  // NOLINT
    180 #if !defined(_WIN32) || defined(__clang__)
    181   up = SANITIZER_WORDSIZE - 1 - __builtin_clzl(x);
    182 #elif defined(_WIN64)
    183   _BitScanReverse64(&up, x);
    184 #else
    185   _BitScanReverse(&up, x);
    186 #endif
    187   return up;
    188 }
    189 
    190 INLINE bool IsPowerOfTwo(uptr x) {
    191   return (x & (x - 1)) == 0;
    192 }
    193 
    194 INLINE uptr RoundUpToPowerOfTwo(uptr size) {
    195   CHECK(size);
    196   if (IsPowerOfTwo(size)) return size;
    197 
    198   uptr up = MostSignificantSetBitIndex(size);
    199   CHECK(size < (1ULL << (up + 1)));
    200   CHECK(size > (1ULL << up));
    201   return 1UL << (up + 1);
    202 }
    203 
    204 INLINE uptr RoundUpTo(uptr size, uptr boundary) {
    205   CHECK(IsPowerOfTwo(boundary));
    206   return (size + boundary - 1) & ~(boundary - 1);
    207 }
    208 
    209 INLINE uptr RoundDownTo(uptr x, uptr boundary) {
    210   return x & ~(boundary - 1);
    211 }
    212 
    213 INLINE bool IsAligned(uptr a, uptr alignment) {
    214   return (a & (alignment - 1)) == 0;
    215 }
    216 
    217 INLINE uptr Log2(uptr x) {
    218   CHECK(IsPowerOfTwo(x));
    219 #if !defined(_WIN32) || defined(__clang__)
    220   return __builtin_ctzl(x);
    221 #elif defined(_WIN64)
    222   unsigned long ret;  // NOLINT
    223   _BitScanForward64(&ret, x);
    224   return ret;
    225 #else
    226   unsigned long ret;  // NOLINT
    227   _BitScanForward(&ret, x);
    228   return ret;
    229 #endif
    230 }
    231 
    232 // Don't use std::min, std::max or std::swap, to minimize dependency
    233 // on libstdc++.
    234 template<class T> T Min(T a, T b) { return a < b ? a : b; }
    235 template<class T> T Max(T a, T b) { return a > b ? a : b; }
    236 template<class T> void Swap(T& a, T& b) {
    237   T tmp = a;
    238   a = b;
    239   b = tmp;
    240 }
    241 
    242 // Char handling
    243 INLINE bool IsSpace(int c) {
    244   return (c == ' ') || (c == '\n') || (c == '\t') ||
    245          (c == '\f') || (c == '\r') || (c == '\v');
    246 }
    247 INLINE bool IsDigit(int c) {
    248   return (c >= '0') && (c <= '9');
    249 }
    250 INLINE int ToLower(int c) {
    251   return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
    252 }
    253 
    254 #if SANITIZER_WORDSIZE == 64
    255 # define FIRST_32_SECOND_64(a, b) (b)
    256 #else
    257 # define FIRST_32_SECOND_64(a, b) (a)
    258 #endif
    259 
    260 }  // namespace __sanitizer
    261 
    262 #endif  // SANITIZER_COMMON_H
    263