blob: 8ca39927fd49ea961ea3865534e57bfd58c63da8 [file] [log] [blame]
Alexey Samsonov9edf7502012-06-06 06:47:26 +00001//===-- 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//
Stephen Hines86277eb2015-03-23 12:06:32 -070010// This file is shared between run-time libraries of sanitizers.
11//
Alexey Samsonov230c3be2012-06-06 09:26:25 +000012// It declares common functions and classes that are used in both runtimes.
Alexey Samsonov9edf7502012-06-06 06:47:26 +000013// 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
Stephen Hines86277eb2015-03-23 12:06:32 -070019#include "sanitizer_flags.h"
20#include "sanitizer_interface_internal.h"
Alexey Samsonov9edf7502012-06-06 06:47:26 +000021#include "sanitizer_internal_defs.h"
Kostya Serebryanyb5f95212013-02-26 13:30:27 +000022#include "sanitizer_libc.h"
Stephen Hines86277eb2015-03-23 12:06:32 -070023#include "sanitizer_list.h"
Alexey Samsonov7ed46ff2013-04-05 07:30:29 +000024#include "sanitizer_mutex.h"
Alexey Samsonov9edf7502012-06-06 06:47:26 +000025
26namespace __sanitizer {
Kostya Serebryany2673fd82013-02-06 12:36:49 +000027struct StackTrace;
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -070028struct AddressInfo;
Alexey Samsonov9edf7502012-06-06 06:47:26 +000029
Alexey Samsonov230c3be2012-06-06 09:26:25 +000030// Constants.
Kostya Serebryany5af39e52012-11-21 12:38:58 +000031const uptr kWordSize = SANITIZER_WORDSIZE / 8;
Alexey Samsonov230c3be2012-06-06 09:26:25 +000032const uptr kWordSizeInBits = 8 * kWordSize;
Kostya Serebryanye89f1842012-11-24 05:03:11 +000033
Stephen Hines6a211c52014-07-21 00:49:56 -070034#if defined(__powerpc__) || defined(__powerpc64__)
35 const uptr kCacheLineSize = 128;
36#else
37 const uptr kCacheLineSize = 64;
38#endif
Alexey Samsonov230c3be2012-06-06 09:26:25 +000039
Stephen Hines86277eb2015-03-23 12:06:32 -070040const uptr kMaxPathLength = 4096;
Alexey Samsonovd64bcf42013-06-11 08:13:36 +000041
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -070042// 16K loaded modules should be enough for everyone.
43static const uptr kMaxNumberOfModules = 1 << 14;
44
Stephen Hines2d1fdb22014-05-28 23:58:16 -070045const uptr kMaxThreadStackSize = 1 << 30; // 1Gb
46
Kostya Serebryany859778a2013-01-31 14:11:21 +000047extern const char *SanitizerToolName; // Can be changed by the tool.
48
Stephen Hines86277eb2015-03-23 12:06:32 -070049extern atomic_uint32_t current_verbosity;
50INLINE void SetVerbosity(int verbosity) {
51 atomic_store(&current_verbosity, verbosity, memory_order_relaxed);
52}
53INLINE int Verbosity() {
54 return atomic_load(&current_verbosity, memory_order_relaxed);
55}
56
Kostya Serebryanyf67ec2b2012-11-23 15:38:49 +000057uptr GetPageSize();
58uptr GetPageSizeCached();
59uptr GetMmapGranularity();
Timur Iskhodzhanovbb7f2d82013-07-16 09:47:39 +000060uptr GetMaxVirtualAddress();
Alexey Samsonove5931fd2012-06-07 07:13:46 +000061// Threads
Dmitry Vyukove0023f72012-10-02 12:58:14 +000062uptr GetTid();
Alexey Samsonovfa3daaf2012-06-15 06:37:34 +000063uptr GetThreadSelf();
Alexey Samsonoved996f72012-06-07 07:32:00 +000064void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
Alexey Samsonove5931fd2012-06-07 07:13:46 +000065 uptr *stack_bottom);
Sergey Matveev24323de2013-05-07 14:41:43 +000066void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
67 uptr *tls_addr, uptr *tls_size);
Alexey Samsonova25b3462012-06-06 16:15:07 +000068
69// Memory management
70void *MmapOrDie(uptr size, const char *mem_type);
Alexey Samsonov230c3be2012-06-06 09:26:25 +000071void UnmapOrDie(void *addr, uptr size);
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070072void *MmapFixedNoReserve(uptr fixed_addr, uptr size,
73 const char *name = nullptr);
Stephen Hines2d1fdb22014-05-28 23:58:16 -070074void *MmapNoReserveOrDie(uptr size, const char *mem_type);
Kostya Serebryany9bfe78f2012-12-13 05:36:00 +000075void *MmapFixedOrDie(uptr fixed_addr, uptr size);
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070076void *MmapNoAccess(uptr fixed_addr, uptr size, const char *name = nullptr);
Kostya Serebryanycc752592012-12-06 06:10:31 +000077// Map aligned chunk of address space; size and alignment are powers of two.
78void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type);
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -070079// Disallow access to a memory range. Use MmapNoAccess to allocate an
80// unaccessible memory.
81bool MprotectNoAccess(uptr addr, uptr size);
82
Alexey Samsonovdd3a9112012-06-15 07:29:14 +000083// Used to check if we can map shadow memory to a fixed location.
84bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
Kostya Serebryanya54aec82012-12-27 07:37:24 +000085void FlushUnneededShadowMemory(uptr addr, uptr size);
Stephen Hines2d1fdb22014-05-28 23:58:16 -070086void IncreaseTotalMmap(uptr size);
87void DecreaseTotalMmap(uptr size);
Stephen Hines86277eb2015-03-23 12:06:32 -070088uptr GetRSS();
89void NoHugePagesInRegion(uptr addr, uptr length);
90void DontDumpShadowMemory(uptr addr, uptr length);
Alexey Samsonovf607fc12012-06-14 14:42:58 +000091
Alexey Samsonov6611abe2012-08-21 08:13:37 +000092// InternalScopedBuffer can be used instead of large stack arrays to
93// keep frame size low.
Kostya Serebryany4fa111c2012-08-29 08:40:36 +000094// FIXME: use InternalAlloc instead of MmapOrDie once
95// InternalAlloc is made libc-free.
Alexey Samsonov6611abe2012-08-21 08:13:37 +000096template<typename T>
97class InternalScopedBuffer {
98 public:
99 explicit InternalScopedBuffer(uptr cnt) {
100 cnt_ = cnt;
Kostya Serebryany4fa111c2012-08-29 08:40:36 +0000101 ptr_ = (T*)MmapOrDie(cnt * sizeof(T), "InternalScopedBuffer");
Alexey Samsonov6611abe2012-08-21 08:13:37 +0000102 }
103 ~InternalScopedBuffer() {
Kostya Serebryany4fa111c2012-08-29 08:40:36 +0000104 UnmapOrDie(ptr_, cnt_ * sizeof(T));
Alexey Samsonov6611abe2012-08-21 08:13:37 +0000105 }
106 T &operator[](uptr i) { return ptr_[i]; }
107 T *data() { return ptr_; }
108 uptr size() { return cnt_ * sizeof(T); }
109
110 private:
111 T *ptr_;
112 uptr cnt_;
113 // Disallow evil constructors.
114 InternalScopedBuffer(const InternalScopedBuffer&);
115 void operator=(const InternalScopedBuffer&);
116};
117
Alexey Samsonovbb4697f2013-11-14 09:41:24 +0000118class InternalScopedString : public InternalScopedBuffer<char> {
119 public:
120 explicit InternalScopedString(uptr max_length)
121 : InternalScopedBuffer<char>(max_length), length_(0) {
122 (*this)[0] = '\0';
123 }
124 uptr length() { return length_; }
125 void clear() {
126 (*this)[0] = '\0';
127 length_ = 0;
128 }
129 void append(const char *format, ...);
130
131 private:
132 uptr length_;
133};
134
Alexey Samsonovd883c802012-08-27 14:51:36 +0000135// Simple low-level (mmap-based) allocator for internal use. Doesn't have
136// constructor, so all instances of LowLevelAllocator should be
137// linker initialized.
Alexey Samsonov70e177e2012-08-27 09:30:58 +0000138class LowLevelAllocator {
139 public:
Alexey Samsonovd883c802012-08-27 14:51:36 +0000140 // Requires an external lock.
Alexey Samsonov70e177e2012-08-27 09:30:58 +0000141 void *Allocate(uptr size);
142 private:
143 char *allocated_end_;
144 char *allocated_current_;
145};
146typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);
147// Allows to register tool-specific callbacks for LowLevelAllocator.
148// Passing NULL removes the callback.
149void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback);
150
Alexey Samsonovf607fc12012-06-14 14:42:58 +0000151// IO
Alexey Samsonove5931fd2012-06-07 07:13:46 +0000152void RawWrite(const char *buffer);
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700153bool ColorizeReports();
Alexey Samsonov7fdcdf52012-06-06 13:58:39 +0000154void Printf(const char *format, ...);
Alexey Samsonov7fdcdf52012-06-06 13:58:39 +0000155void Report(const char *format, ...);
Kostya Serebryany283c2962012-08-28 11:34:40 +0000156void SetPrintfAndReportCallback(void (*callback)(const char *));
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700157#define VReport(level, ...) \
158 do { \
Stephen Hines86277eb2015-03-23 12:06:32 -0700159 if ((uptr)Verbosity() >= (level)) Report(__VA_ARGS__); \
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700160 } while (0)
161#define VPrintf(level, ...) \
162 do { \
Stephen Hines86277eb2015-03-23 12:06:32 -0700163 if ((uptr)Verbosity() >= (level)) Printf(__VA_ARGS__); \
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700164 } while (0)
Alexey Samsonovbb4697f2013-11-14 09:41:24 +0000165
Alexey Samsonov7ed46ff2013-04-05 07:30:29 +0000166// Can be used to prevent mixing error reports from different sanitizers.
167extern StaticSpinMutex CommonSanitizerReportMutex;
Stephen Hines86277eb2015-03-23 12:06:32 -0700168
169struct ReportFile {
170 void Write(const char *buffer, uptr length);
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700171 bool SupportsColors();
Stephen Hines86277eb2015-03-23 12:06:32 -0700172 void SetReportPath(const char *path);
173
174 // Don't use fields directly. They are only declared public to allow
175 // aggregate initialization.
176
177 // Protects fields below.
178 StaticSpinMutex *mu;
179 // Opened file descriptor. Defaults to stderr. It may be equal to
180 // kInvalidFd, in which case new file will be opened when necessary.
181 fd_t fd;
182 // Path prefix of report file, set via __sanitizer_set_report_path.
183 char path_prefix[kMaxPathLength];
184 // Full path to report, obtained as <path_prefix>.PID
185 char full_path[kMaxPathLength];
186 // PID of the process that opened fd. If a fork() occurs,
187 // the PID of child will be different from fd_pid.
188 uptr fd_pid;
189
190 private:
191 void ReopenIfNecessary();
192};
193extern ReportFile report_file;
194
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700195extern uptr stoptheworld_tracer_pid;
196extern uptr stoptheworld_tracer_ppid;
Alexey Samsonove9541012012-06-06 13:11:29 +0000197
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700198enum FileAccessMode {
199 RdOnly,
200 WrOnly,
201 RdWr
202};
203
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700204// Returns kInvalidFd on error.
205fd_t OpenFile(const char *filename, FileAccessMode mode,
206 error_t *errno_p = nullptr);
207void CloseFile(fd_t);
208
209// Return true on success, false on error.
210bool ReadFromFile(fd_t fd, void *buff, uptr buff_size,
211 uptr *bytes_read = nullptr, error_t *error_p = nullptr);
212bool WriteToFile(fd_t fd, const void *buff, uptr buff_size,
213 uptr *bytes_written = nullptr, error_t *error_p = nullptr);
214
215bool RenameFile(const char *oldpath, const char *newpath,
216 error_t *error_p = nullptr);
217
218bool SupportsColoredOutput(fd_t fd);
219
Alexey Samsonovcffe2f52012-06-07 05:38:26 +0000220// Opens the file 'file_name" and reads up to 'max_len' bytes.
221// The resulting buffer is mmaped and stored in '*buff'.
222// The size of the mmaped region is stored in '*buff_size',
223// Returns the number of read bytes or 0 if file can not be opened.
Stephen Hines86277eb2015-03-23 12:06:32 -0700224uptr ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700225 uptr max_len, error_t *errno_p = nullptr);
Alexey Samsonova68633f2012-07-03 08:24:14 +0000226// Maps given file to virtual memory, and returns pointer to it
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700227// (or NULL if mapping fails). Stores the size of mmaped region
Alexey Samsonova68633f2012-07-03 08:24:14 +0000228// in '*buff_size'.
229void *MapFileToMemory(const char *file_name, uptr *buff_size);
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700230void *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, uptr offset);
Alexey Samsonova68633f2012-07-03 08:24:14 +0000231
Stephen Hines6d186232014-11-26 17:56:19 -0800232bool IsAccessibleMemoryRange(uptr beg, uptr size);
233
Alexey Samsonov90b0f1e2013-10-04 08:55:03 +0000234// Error report formatting.
235const char *StripPathPrefix(const char *filepath,
236 const char *strip_file_prefix);
Stephen Hines6d186232014-11-26 17:56:19 -0800237// Strip the directories from the module name.
238const char *StripModuleName(const char *module);
Alexey Samsonov90b0f1e2013-10-04 08:55:03 +0000239
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000240// OS
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -0700241uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
242const char *GetBinaryName();
243const char *GetBinaryBasename();
244void CacheBinaryName();
Stephen Hines6d186232014-11-26 17:56:19 -0800245void DisableCoreDumperIfNecessary();
Alexey Samsonovbe7420c2012-06-15 06:08:19 +0000246void DumpProcessMap();
Alexey Samsonov93b4caf2012-11-09 14:45:30 +0000247bool FileExists(const char *filename);
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000248const char *GetEnv(const char *name);
Alexey Samsonovff7c14f2013-04-23 12:49:12 +0000249bool SetEnv(const char *name, const char *value);
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000250const char *GetPwd();
Alexey Samsonov1dcd1d92013-09-03 13:20:48 +0000251char *FindPathToBinary(const char *name);
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700252bool IsPathSeparator(const char c);
253bool IsAbsolutePath(const char *path);
254
Alexey Samsonov0fa691b2013-02-18 07:17:12 +0000255u32 GetUid();
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000256void ReExec();
257bool StackSizeIsUnlimited();
258void SetStackSizeLimitInBytes(uptr limit);
Stephen Hines6d186232014-11-26 17:56:19 -0800259bool AddressSpaceIsUnlimited();
260void SetAddressSpaceUnlimited();
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700261void AdjustStackSize(void *attr);
262void PrepareForSandboxing(__sanitizer_sandbox_arguments *args);
263void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args);
264void SetSandboxingCallback(void (*f)());
265
Stephen Hines86277eb2015-03-23 12:06:32 -0700266void CoverageUpdateMapping();
Stephen Hines6a211c52014-07-21 00:49:56 -0700267void CovBeforeFork();
268void CovAfterFork(int child_pid);
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000269
Stephen Hines86277eb2015-03-23 12:06:32 -0700270void InitializeCoverage(bool enabled, const char *coverage_dir);
271void ReInitializeCoverage(bool enabled, const char *coverage_dir);
272
Evgeniy Stepanovb114ed82013-03-13 08:19:53 +0000273void InitTlsSize();
274uptr GetTlsSize();
275
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000276// Other
Alexey Samsonovfa3daaf2012-06-15 06:37:34 +0000277void SleepForSeconds(int seconds);
Alexey Samsonov0969bcf2012-06-18 08:44:30 +0000278void SleepForMillis(int millis);
Dmitry Vyukov4bebe7b2013-03-21 06:24:31 +0000279u64 NanoTime();
Alexey Samsonovfa3daaf2012-06-15 06:37:34 +0000280int Atexit(void (*function)(void));
Alexey Samsonov4c496662012-06-15 07:00:31 +0000281void SortArray(uptr *array, uptr size);
Stephen Hines86277eb2015-03-23 12:06:32 -0700282bool TemplateMatch(const char *templ, const char *str);
Alexey Samsonovbe7420c2012-06-15 06:08:19 +0000283
Alexey Samsonov591616d2012-09-11 09:44:48 +0000284// Exit
285void NORETURN Abort();
Alexey Samsonov591616d2012-09-11 09:44:48 +0000286void NORETURN Die();
Timur Iskhodzhanov3c80c6c2013-08-13 11:42:45 +0000287void NORETURN
Alexey Samsonov591616d2012-09-11 09:44:48 +0000288CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
289
Kostya Serebryanydddb18b2012-12-07 11:27:24 +0000290// Set the name of the current thread to 'name', return true on succees.
291// The name may be truncated to a system-dependent limit.
292bool SanitizerSetThreadName(const char *name);
293// Get the name of the current thread (no more than max_len bytes),
294// return true on succees. name should have space for at least max_len+1 bytes.
295bool SanitizerGetThreadName(char *name, int max_len);
296
Alexey Samsonov591616d2012-09-11 09:44:48 +0000297// Specific tools may override behavior of "Die" and "CheckFailed" functions
298// to do tool-specific job.
Sergey Matveev90629fb2013-08-26 13:20:31 +0000299typedef void (*DieCallbackType)(void);
300void SetDieCallback(DieCallbackType);
Stephen Hines86277eb2015-03-23 12:06:32 -0700301void SetUserDieCallback(DieCallbackType);
Sergey Matveev90629fb2013-08-26 13:20:31 +0000302DieCallbackType GetDieCallback();
Alexey Samsonov591616d2012-09-11 09:44:48 +0000303typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
304 u64, u64);
305void SetCheckFailedCallback(CheckFailedCallbackType callback);
306
Stephen Hines86277eb2015-03-23 12:06:32 -0700307// Callback will be called if soft_rss_limit_mb is given and the limit is
308// exceeded (exceeded==true) or if rss went down below the limit
309// (exceeded==false).
310// The callback should be registered once at the tool init time.
311void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded));
312
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700313// Functions related to signal handling.
314typedef void (*SignalHandlerType)(int, void *, void *);
315bool IsDeadlySignal(int signum);
316void InstallDeadlySignalHandlers(SignalHandlerType handler);
317// Alternative signal stack (POSIX-only).
318void SetAlternateSignalStack();
319void UnsetAlternateSignalStack();
320
Alexey Samsonov2fb08722013-11-01 17:02:14 +0000321// We don't want a summary too long.
322const int kMaxSummaryLength = 1024;
323// Construct a one-line string:
324// SUMMARY: SanitizerToolName: error_message
325// and pass it to __sanitizer_report_error_summary.
326void ReportErrorSummary(const char *error_message);
327// Same as above, but construct error_message as:
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700328// error_type file:line[:column][ function]
329void ReportErrorSummary(const char *error_type, const AddressInfo &info);
330// Same as above, but obtains AddressInfo by symbolizing top stack trace frame.
Alexey Samsonov2fb08722013-11-01 17:02:14 +0000331void ReportErrorSummary(const char *error_type, StackTrace *trace);
Kostya Serebryany2673fd82013-02-06 12:36:49 +0000332
Alexey Samsonov4c496662012-06-15 07:00:31 +0000333// Math
Dmitry Vyukovc5288672013-06-10 10:02:02 +0000334#if SANITIZER_WINDOWS && !defined(__clang__) && !defined(__GNUC__)
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000335extern "C" {
336unsigned char _BitScanForward(unsigned long *index, unsigned long mask); // NOLINT
337unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); // NOLINT
338#if defined(_WIN64)
339unsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask); // NOLINT
340unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask); // NOLINT
341#endif
342}
343#endif
344
345INLINE uptr MostSignificantSetBitIndex(uptr x) {
Kostya Serebryanyf155fcc2013-02-26 12:59:06 +0000346 CHECK_NE(x, 0U);
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000347 unsigned long up; // NOLINT
Dmitry Vyukovc5288672013-06-10 10:02:02 +0000348#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000349 up = SANITIZER_WORDSIZE - 1 - __builtin_clzl(x);
350#elif defined(_WIN64)
351 _BitScanReverse64(&up, x);
352#else
353 _BitScanReverse(&up, x);
354#endif
355 return up;
356}
357
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700358INLINE uptr LeastSignificantSetBitIndex(uptr x) {
359 CHECK_NE(x, 0U);
360 unsigned long up; // NOLINT
361#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
362 up = __builtin_ctzl(x);
363#elif defined(_WIN64)
364 _BitScanForward64(&up, x);
365#else
366 _BitScanForward(&up, x);
367#endif
368 return up;
369}
370
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000371INLINE bool IsPowerOfTwo(uptr x) {
Alexey Samsonov230c3be2012-06-06 09:26:25 +0000372 return (x & (x - 1)) == 0;
373}
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000374
375INLINE uptr RoundUpToPowerOfTwo(uptr size) {
376 CHECK(size);
377 if (IsPowerOfTwo(size)) return size;
378
379 uptr up = MostSignificantSetBitIndex(size);
380 CHECK(size < (1ULL << (up + 1)));
381 CHECK(size > (1ULL << up));
382 return 1UL << (up + 1);
383}
384
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000385INLINE uptr RoundUpTo(uptr size, uptr boundary) {
Alexey Samsonov4c496662012-06-15 07:00:31 +0000386 CHECK(IsPowerOfTwo(boundary));
Alexey Samsonov230c3be2012-06-06 09:26:25 +0000387 return (size + boundary - 1) & ~(boundary - 1);
388}
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000389
Kostya Serebryanybc9940e2012-12-14 12:15:09 +0000390INLINE uptr RoundDownTo(uptr x, uptr boundary) {
391 return x & ~(boundary - 1);
392}
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000393
Kostya Serebryany84a996f2012-12-11 14:41:31 +0000394INLINE bool IsAligned(uptr a, uptr alignment) {
395 return (a & (alignment - 1)) == 0;
396}
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000397
398INLINE uptr Log2(uptr x) {
399 CHECK(IsPowerOfTwo(x));
Dmitry Vyukovc5288672013-06-10 10:02:02 +0000400#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000401 return __builtin_ctzl(x);
402#elif defined(_WIN64)
403 unsigned long ret; // NOLINT
404 _BitScanForward64(&ret, x);
405 return ret;
406#else
407 unsigned long ret; // NOLINT
408 _BitScanForward(&ret, x);
409 return ret;
410#endif
411}
412
Alexey Samsonov0dc31772012-07-16 11:27:17 +0000413// Don't use std::min, std::max or std::swap, to minimize dependency
414// on libstdc++.
Alexey Samsonov4c496662012-06-15 07:00:31 +0000415template<class T> T Min(T a, T b) { return a < b ? a : b; }
416template<class T> T Max(T a, T b) { return a > b ? a : b; }
Alexey Samsonov0dc31772012-07-16 11:27:17 +0000417template<class T> void Swap(T& a, T& b) {
418 T tmp = a;
419 a = b;
420 b = tmp;
421}
Alexey Samsonov9edf7502012-06-06 06:47:26 +0000422
Alexey Samsonovc9256972012-06-15 13:09:52 +0000423// Char handling
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000424INLINE bool IsSpace(int c) {
Alexey Samsonovc9256972012-06-15 13:09:52 +0000425 return (c == ' ') || (c == '\n') || (c == '\t') ||
426 (c == '\f') || (c == '\r') || (c == '\v');
427}
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000428INLINE bool IsDigit(int c) {
Alexey Samsonovc9256972012-06-15 13:09:52 +0000429 return (c >= '0') && (c <= '9');
430}
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000431INLINE int ToLower(int c) {
Alexey Samsonovc9256972012-06-15 13:09:52 +0000432 return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
433}
434
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000435// A low-level vector based on mmap. May incur a significant memory overhead for
436// small vectors.
437// WARNING: The current implementation supports only POD types.
438template<typename T>
Stephen Hines86277eb2015-03-23 12:06:32 -0700439class InternalMmapVectorNoCtor {
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000440 public:
Stephen Hines86277eb2015-03-23 12:06:32 -0700441 void Initialize(uptr initial_capacity) {
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700442 capacity_ = Max(initial_capacity, (uptr)1);
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000443 size_ = 0;
Stephen Hines86277eb2015-03-23 12:06:32 -0700444 data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalMmapVectorNoCtor");
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000445 }
Stephen Hines86277eb2015-03-23 12:06:32 -0700446 void Destroy() {
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000447 UnmapOrDie(data_, capacity_ * sizeof(T));
448 }
449 T &operator[](uptr i) {
Alexey Samsonov96950032013-03-29 08:03:01 +0000450 CHECK_LT(i, size_);
Alexey Samsonovca280f22013-03-28 15:37:11 +0000451 return data_[i];
452 }
453 const T &operator[](uptr i) const {
Alexey Samsonov96950032013-03-29 08:03:01 +0000454 CHECK_LT(i, size_);
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000455 return data_[i];
456 }
457 void push_back(const T &element) {
458 CHECK_LE(size_, capacity_);
459 if (size_ == capacity_) {
460 uptr new_capacity = RoundUpToPowerOfTwo(size_ + 1);
461 Resize(new_capacity);
462 }
463 data_[size_++] = element;
464 }
Alexey Samsonov352b2452013-03-05 11:58:25 +0000465 T &back() {
466 CHECK_GT(size_, 0);
467 return data_[size_ - 1];
468 }
469 void pop_back() {
470 CHECK_GT(size_, 0);
471 size_--;
472 }
Alexey Samsonovca280f22013-03-28 15:37:11 +0000473 uptr size() const {
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000474 return size_;
475 }
Alexander Potapenkoe5b398f2013-04-01 13:55:34 +0000476 const T *data() const {
477 return data_;
478 }
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700479 T *data() {
480 return data_;
481 }
Alexander Potapenkoe5b398f2013-04-01 13:55:34 +0000482 uptr capacity() const {
483 return capacity_;
484 }
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000485
Bob Wilsondbd69cc2013-11-15 07:18:15 +0000486 void clear() { size_ = 0; }
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700487 bool empty() const { return size() == 0; }
Bob Wilsondbd69cc2013-11-15 07:18:15 +0000488
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000489 private:
490 void Resize(uptr new_capacity) {
491 CHECK_GT(new_capacity, 0);
492 CHECK_LE(size_, new_capacity);
493 T *new_data = (T *)MmapOrDie(new_capacity * sizeof(T),
Alexey Samsonova64d4352013-06-14 09:59:40 +0000494 "InternalMmapVector");
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000495 internal_memcpy(new_data, data_, size_ * sizeof(T));
496 T *old_data = data_;
497 data_ = new_data;
498 UnmapOrDie(old_data, capacity_ * sizeof(T));
499 capacity_ = new_capacity;
500 }
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000501
502 T *data_;
503 uptr capacity_;
504 uptr size_;
505};
Sergey Matveev15bb32b2013-05-13 11:58:48 +0000506
Stephen Hines86277eb2015-03-23 12:06:32 -0700507template<typename T>
508class InternalMmapVector : public InternalMmapVectorNoCtor<T> {
509 public:
510 explicit InternalMmapVector(uptr initial_capacity) {
511 InternalMmapVectorNoCtor<T>::Initialize(initial_capacity);
512 }
513 ~InternalMmapVector() { InternalMmapVectorNoCtor<T>::Destroy(); }
514 // Disallow evil constructors.
515 InternalMmapVector(const InternalMmapVector&);
516 void operator=(const InternalMmapVector&);
517};
518
Alexey Samsonova64d4352013-06-14 09:59:40 +0000519// HeapSort for arrays and InternalMmapVector.
Sergey Matveev15bb32b2013-05-13 11:58:48 +0000520template<class Container, class Compare>
521void InternalSort(Container *v, uptr size, Compare comp) {
522 if (size < 2)
523 return;
524 // Stage 1: insert elements to the heap.
525 for (uptr i = 1; i < size; i++) {
526 uptr j, p;
527 for (j = i; j > 0; j = p) {
528 p = (j - 1) / 2;
529 if (comp((*v)[p], (*v)[j]))
530 Swap((*v)[j], (*v)[p]);
531 else
532 break;
533 }
534 }
535 // Stage 2: swap largest element with the last one,
536 // and sink the new top.
537 for (uptr i = size - 1; i > 0; i--) {
538 Swap((*v)[0], (*v)[i]);
539 uptr j, max_ind;
540 for (j = 0; j < i; j = max_ind) {
541 uptr left = 2 * j + 1;
542 uptr right = 2 * j + 2;
543 max_ind = j;
544 if (left < i && comp((*v)[max_ind], (*v)[left]))
545 max_ind = left;
546 if (right < i && comp((*v)[max_ind], (*v)[right]))
547 max_ind = right;
548 if (max_ind != j)
549 Swap((*v)[j], (*v)[max_ind]);
550 else
551 break;
552 }
553 }
554}
555
Sergey Matveev384a4482013-08-26 13:24:43 +0000556template<class Container, class Value, class Compare>
557uptr InternalBinarySearch(const Container &v, uptr first, uptr last,
558 const Value &val, Compare comp) {
559 uptr not_found = last + 1;
560 while (last >= first) {
561 uptr mid = (first + last) / 2;
562 if (comp(v[mid], val))
563 first = mid + 1;
564 else if (comp(val, v[mid]))
565 last = mid - 1;
566 else
567 return mid;
568 }
569 return not_found;
570}
571
Alexey Samsonov7847d772013-09-10 14:36:16 +0000572// Represents a binary loaded into virtual memory (e.g. this can be an
573// executable or a shared object).
574class LoadedModule {
575 public:
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700576 LoadedModule() : full_name_(nullptr), base_address_(0) { ranges_.clear(); }
577 void set(const char *module_name, uptr base_address);
Stephen Hines86277eb2015-03-23 12:06:32 -0700578 void clear();
Stephen Hines6a211c52014-07-21 00:49:56 -0700579 void addAddressRange(uptr beg, uptr end, bool executable);
Alexey Samsonov7847d772013-09-10 14:36:16 +0000580 bool containsAddress(uptr address) const;
581
582 const char *full_name() const { return full_name_; }
583 uptr base_address() const { return base_address_; }
584
Alexey Samsonov7847d772013-09-10 14:36:16 +0000585 struct AddressRange {
Stephen Hines86277eb2015-03-23 12:06:32 -0700586 AddressRange *next;
Alexey Samsonov7847d772013-09-10 14:36:16 +0000587 uptr beg;
588 uptr end;
Stephen Hines86277eb2015-03-23 12:06:32 -0700589 bool executable;
590
591 AddressRange(uptr beg, uptr end, bool executable)
592 : next(nullptr), beg(beg), end(end), executable(executable) {}
Alexey Samsonov7847d772013-09-10 14:36:16 +0000593 };
Stephen Hines86277eb2015-03-23 12:06:32 -0700594
595 typedef IntrusiveList<AddressRange>::ConstIterator Iterator;
596 Iterator ranges() const { return Iterator(&ranges_); }
597
598 private:
599 char *full_name_; // Owned.
Alexey Samsonov7847d772013-09-10 14:36:16 +0000600 uptr base_address_;
Stephen Hines86277eb2015-03-23 12:06:32 -0700601 IntrusiveList<AddressRange> ranges_;
Alexey Samsonov7847d772013-09-10 14:36:16 +0000602};
603
604// OS-dependent function that fills array with descriptions of at most
605// "max_modules" currently loaded modules. Returns the number of
606// initialized modules. If filter is nonzero, ignores modules for which
607// filter(full_name) is false.
608typedef bool (*string_predicate_t)(const char *);
609uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
610 string_predicate_t filter);
611
Sergey Matveev70db33e2013-10-11 14:19:14 +0000612#if SANITIZER_POSIX
613const uptr kPthreadDestructorIterations = 4;
614#else
615// Unused on Windows.
616const uptr kPthreadDestructorIterations = 0;
617#endif
Sergey Matveevc5193352013-10-14 14:04:50 +0000618
619// Callback type for iterating over a set of memory ranges.
620typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700621
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700622#if SANITIZER_ANDROID
Evgeniy Stepanovaafc5c82014-09-15 11:37:40 +0000623// Initialize Android logging. Any writes before this are silently lost.
624void AndroidLogInit();
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700625void AndroidLogWrite(const char *buffer);
626void GetExtraActivationFlags(char *buf, uptr size);
627void SanitizerInitializeUnwinder();
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -0700628u32 AndroidGetApiLevel();
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700629#else
Evgeniy Stepanovaafc5c82014-09-15 11:37:40 +0000630INLINE void AndroidLogInit() {}
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700631INLINE void AndroidLogWrite(const char *buffer_unused) {}
632INLINE void GetExtraActivationFlags(char *buf, uptr size) { *buf = '\0'; }
633INLINE void SanitizerInitializeUnwinder() {}
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -0700634INLINE u32 AndroidGetApiLevel() { return 0; }
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700635#endif
Stephen Hines86277eb2015-03-23 12:06:32 -0700636
637void *internal_start_thread(void(*func)(void*), void *arg);
638void internal_join_thread(void *th);
639void MaybeStartBackgroudThread();
640
641// Make the compiler think that something is going on there.
642// Use this inside a loop that looks like memset/memcpy/etc to prevent the
643// compiler from recognising it and turning it into an actual call to
644// memset/memcpy/etc.
645static inline void SanitizerBreakOptimization(void *arg) {
646#if _MSC_VER
647 // FIXME: make sure this is actually enough.
648 __asm;
649#else
650 __asm__ __volatile__("" : : "r" (arg) : "memory");
651#endif
652}
653
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700654struct SignalContext {
655 void *context;
656 uptr addr;
657 uptr pc;
658 uptr sp;
659 uptr bp;
660
661 SignalContext(void *context, uptr addr, uptr pc, uptr sp, uptr bp) :
662 context(context), addr(addr), pc(pc), sp(sp), bp(bp) {
663 }
664
665 // Creates signal context in a platform-specific manner.
666 static SignalContext Create(void *siginfo, void *context);
667};
668
669void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
670
Alexey Samsonov9edf7502012-06-06 06:47:26 +0000671} // namespace __sanitizer
672
Peter Collingbourne53177242013-10-24 06:23:39 +0000673inline void *operator new(__sanitizer::operator_new_size_type size,
674 __sanitizer::LowLevelAllocator &alloc) {
675 return alloc.Allocate(size);
676}
677
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700678struct StackDepotStats {
679 uptr n_uniq_ids;
680 uptr allocated;
681};
682
Alexey Samsonov9edf7502012-06-06 06:47:26 +0000683#endif // SANITIZER_COMMON_H