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