blob: 0585f6b15b87b225b0edf5aef1820e68e037f1ec [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
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080026#ifdef _MSC_VER
27extern "C" void _ReadWriteBarrier();
28#pragma intrinsic(_ReadWriteBarrier)
29#endif
30
Alexey Samsonov9edf7502012-06-06 06:47:26 +000031namespace __sanitizer {
Kostya Serebryany2673fd82013-02-06 12:36:49 +000032struct StackTrace;
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -070033struct AddressInfo;
Alexey Samsonov9edf7502012-06-06 06:47:26 +000034
Alexey Samsonov230c3be2012-06-06 09:26:25 +000035// Constants.
Kostya Serebryany5af39e52012-11-21 12:38:58 +000036const uptr kWordSize = SANITIZER_WORDSIZE / 8;
Alexey Samsonov230c3be2012-06-06 09:26:25 +000037const uptr kWordSizeInBits = 8 * kWordSize;
Kostya Serebryanye89f1842012-11-24 05:03:11 +000038
Stephen Hines6a211c52014-07-21 00:49:56 -070039#if defined(__powerpc__) || defined(__powerpc64__)
40 const uptr kCacheLineSize = 128;
41#else
42 const uptr kCacheLineSize = 64;
43#endif
Alexey Samsonov230c3be2012-06-06 09:26:25 +000044
Stephen Hines86277eb2015-03-23 12:06:32 -070045const uptr kMaxPathLength = 4096;
Alexey Samsonovd64bcf42013-06-11 08:13:36 +000046
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -070047// 16K loaded modules should be enough for everyone.
48static const uptr kMaxNumberOfModules = 1 << 14;
49
Stephen Hines2d1fdb22014-05-28 23:58:16 -070050const uptr kMaxThreadStackSize = 1 << 30; // 1Gb
51
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080052static const uptr kErrorMessageBufferSize = 1 << 16;
53
54// Denotes fake PC values that come from JIT/JAVA/etc.
55// For such PC values __tsan_symbolize_external() will be called.
56const u64 kExternalPCBit = 1ULL << 60;
57
Kostya Serebryany859778a2013-01-31 14:11:21 +000058extern const char *SanitizerToolName; // Can be changed by the tool.
59
Stephen Hines86277eb2015-03-23 12:06:32 -070060extern atomic_uint32_t current_verbosity;
61INLINE void SetVerbosity(int verbosity) {
62 atomic_store(&current_verbosity, verbosity, memory_order_relaxed);
63}
64INLINE int Verbosity() {
65 return atomic_load(&current_verbosity, memory_order_relaxed);
66}
67
Kostya Serebryanyf67ec2b2012-11-23 15:38:49 +000068uptr GetPageSize();
69uptr GetPageSizeCached();
70uptr GetMmapGranularity();
Timur Iskhodzhanovbb7f2d82013-07-16 09:47:39 +000071uptr GetMaxVirtualAddress();
Alexey Samsonove5931fd2012-06-07 07:13:46 +000072// Threads
Dmitry Vyukove0023f72012-10-02 12:58:14 +000073uptr GetTid();
Alexey Samsonovfa3daaf2012-06-15 06:37:34 +000074uptr GetThreadSelf();
Alexey Samsonoved996f72012-06-07 07:32:00 +000075void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
Alexey Samsonove5931fd2012-06-07 07:13:46 +000076 uptr *stack_bottom);
Sergey Matveev24323de2013-05-07 14:41:43 +000077void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
78 uptr *tls_addr, uptr *tls_size);
Alexey Samsonova25b3462012-06-06 16:15:07 +000079
80// Memory management
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080081void *MmapOrDie(uptr size, const char *mem_type, bool raw_report = false);
82INLINE void *MmapOrDieQuietly(uptr size, const char *mem_type) {
83 return MmapOrDie(size, mem_type, /*raw_report*/ true);
84}
Alexey Samsonov230c3be2012-06-06 09:26:25 +000085void UnmapOrDie(void *addr, uptr size);
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070086void *MmapFixedNoReserve(uptr fixed_addr, uptr size,
87 const char *name = nullptr);
Stephen Hines2d1fdb22014-05-28 23:58:16 -070088void *MmapNoReserveOrDie(uptr size, const char *mem_type);
Kostya Serebryany9bfe78f2012-12-13 05:36:00 +000089void *MmapFixedOrDie(uptr fixed_addr, uptr size);
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070090void *MmapNoAccess(uptr fixed_addr, uptr size, const char *name = nullptr);
Kostya Serebryanycc752592012-12-06 06:10:31 +000091// Map aligned chunk of address space; size and alignment are powers of two.
92void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type);
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -070093// Disallow access to a memory range. Use MmapNoAccess to allocate an
94// unaccessible memory.
95bool MprotectNoAccess(uptr addr, uptr size);
96
Alexey Samsonovdd3a9112012-06-15 07:29:14 +000097// Used to check if we can map shadow memory to a fixed location.
98bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
Kostya Serebryanya54aec82012-12-27 07:37:24 +000099void FlushUnneededShadowMemory(uptr addr, uptr size);
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700100void IncreaseTotalMmap(uptr size);
101void DecreaseTotalMmap(uptr size);
Stephen Hines86277eb2015-03-23 12:06:32 -0700102uptr GetRSS();
103void NoHugePagesInRegion(uptr addr, uptr length);
104void DontDumpShadowMemory(uptr addr, uptr length);
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800105// Check if the built VMA size matches the runtime one.
106void CheckVMASize();
Alexey Samsonovf607fc12012-06-14 14:42:58 +0000107
Alexey Samsonov6611abe2012-08-21 08:13:37 +0000108// InternalScopedBuffer can be used instead of large stack arrays to
109// keep frame size low.
Kostya Serebryany4fa111c2012-08-29 08:40:36 +0000110// FIXME: use InternalAlloc instead of MmapOrDie once
111// InternalAlloc is made libc-free.
Alexey Samsonov6611abe2012-08-21 08:13:37 +0000112template<typename T>
113class InternalScopedBuffer {
114 public:
115 explicit InternalScopedBuffer(uptr cnt) {
116 cnt_ = cnt;
Kostya Serebryany4fa111c2012-08-29 08:40:36 +0000117 ptr_ = (T*)MmapOrDie(cnt * sizeof(T), "InternalScopedBuffer");
Alexey Samsonov6611abe2012-08-21 08:13:37 +0000118 }
119 ~InternalScopedBuffer() {
Kostya Serebryany4fa111c2012-08-29 08:40:36 +0000120 UnmapOrDie(ptr_, cnt_ * sizeof(T));
Alexey Samsonov6611abe2012-08-21 08:13:37 +0000121 }
122 T &operator[](uptr i) { return ptr_[i]; }
123 T *data() { return ptr_; }
124 uptr size() { return cnt_ * sizeof(T); }
125
126 private:
127 T *ptr_;
128 uptr cnt_;
129 // Disallow evil constructors.
130 InternalScopedBuffer(const InternalScopedBuffer&);
131 void operator=(const InternalScopedBuffer&);
132};
133
Alexey Samsonovbb4697f2013-11-14 09:41:24 +0000134class InternalScopedString : public InternalScopedBuffer<char> {
135 public:
136 explicit InternalScopedString(uptr max_length)
137 : InternalScopedBuffer<char>(max_length), length_(0) {
138 (*this)[0] = '\0';
139 }
140 uptr length() { return length_; }
141 void clear() {
142 (*this)[0] = '\0';
143 length_ = 0;
144 }
145 void append(const char *format, ...);
146
147 private:
148 uptr length_;
149};
150
Alexey Samsonovd883c802012-08-27 14:51:36 +0000151// Simple low-level (mmap-based) allocator for internal use. Doesn't have
152// constructor, so all instances of LowLevelAllocator should be
153// linker initialized.
Alexey Samsonov70e177e2012-08-27 09:30:58 +0000154class LowLevelAllocator {
155 public:
Alexey Samsonovd883c802012-08-27 14:51:36 +0000156 // Requires an external lock.
Alexey Samsonov70e177e2012-08-27 09:30:58 +0000157 void *Allocate(uptr size);
158 private:
159 char *allocated_end_;
160 char *allocated_current_;
161};
162typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);
163// Allows to register tool-specific callbacks for LowLevelAllocator.
164// Passing NULL removes the callback.
165void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback);
166
Alexey Samsonovf607fc12012-06-14 14:42:58 +0000167// IO
Alexey Samsonove5931fd2012-06-07 07:13:46 +0000168void RawWrite(const char *buffer);
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700169bool ColorizeReports();
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800170void RemoveANSIEscapeSequencesFromString(char *buffer);
Alexey Samsonov7fdcdf52012-06-06 13:58:39 +0000171void Printf(const char *format, ...);
Alexey Samsonov7fdcdf52012-06-06 13:58:39 +0000172void Report(const char *format, ...);
Kostya Serebryany283c2962012-08-28 11:34:40 +0000173void SetPrintfAndReportCallback(void (*callback)(const char *));
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700174#define VReport(level, ...) \
175 do { \
Stephen Hines86277eb2015-03-23 12:06:32 -0700176 if ((uptr)Verbosity() >= (level)) Report(__VA_ARGS__); \
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700177 } while (0)
178#define VPrintf(level, ...) \
179 do { \
Stephen Hines86277eb2015-03-23 12:06:32 -0700180 if ((uptr)Verbosity() >= (level)) Printf(__VA_ARGS__); \
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700181 } while (0)
Alexey Samsonovbb4697f2013-11-14 09:41:24 +0000182
Alexey Samsonov7ed46ff2013-04-05 07:30:29 +0000183// Can be used to prevent mixing error reports from different sanitizers.
184extern StaticSpinMutex CommonSanitizerReportMutex;
Stephen Hines86277eb2015-03-23 12:06:32 -0700185
186struct ReportFile {
187 void Write(const char *buffer, uptr length);
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700188 bool SupportsColors();
Stephen Hines86277eb2015-03-23 12:06:32 -0700189 void SetReportPath(const char *path);
190
191 // Don't use fields directly. They are only declared public to allow
192 // aggregate initialization.
193
194 // Protects fields below.
195 StaticSpinMutex *mu;
196 // Opened file descriptor. Defaults to stderr. It may be equal to
197 // kInvalidFd, in which case new file will be opened when necessary.
198 fd_t fd;
199 // Path prefix of report file, set via __sanitizer_set_report_path.
200 char path_prefix[kMaxPathLength];
201 // Full path to report, obtained as <path_prefix>.PID
202 char full_path[kMaxPathLength];
203 // PID of the process that opened fd. If a fork() occurs,
204 // the PID of child will be different from fd_pid.
205 uptr fd_pid;
206
207 private:
208 void ReopenIfNecessary();
209};
210extern ReportFile report_file;
211
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700212extern uptr stoptheworld_tracer_pid;
213extern uptr stoptheworld_tracer_ppid;
Alexey Samsonove9541012012-06-06 13:11:29 +0000214
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700215enum FileAccessMode {
216 RdOnly,
217 WrOnly,
218 RdWr
219};
220
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700221// Returns kInvalidFd on error.
222fd_t OpenFile(const char *filename, FileAccessMode mode,
223 error_t *errno_p = nullptr);
224void CloseFile(fd_t);
225
226// Return true on success, false on error.
227bool ReadFromFile(fd_t fd, void *buff, uptr buff_size,
228 uptr *bytes_read = nullptr, error_t *error_p = nullptr);
229bool WriteToFile(fd_t fd, const void *buff, uptr buff_size,
230 uptr *bytes_written = nullptr, error_t *error_p = nullptr);
231
232bool RenameFile(const char *oldpath, const char *newpath,
233 error_t *error_p = nullptr);
234
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800235// Scoped file handle closer.
236struct FileCloser {
237 explicit FileCloser(fd_t fd) : fd(fd) {}
238 ~FileCloser() { CloseFile(fd); }
239 fd_t fd;
240};
241
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700242bool SupportsColoredOutput(fd_t fd);
243
Alexey Samsonovcffe2f52012-06-07 05:38:26 +0000244// Opens the file 'file_name" and reads up to 'max_len' bytes.
245// The resulting buffer is mmaped and stored in '*buff'.
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800246// The size of the mmaped region is stored in '*buff_size'.
247// The total number of read bytes is stored in '*read_len'.
248// Returns true if file was successfully opened and read.
249bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
250 uptr *read_len, uptr max_len = 1 << 26,
251 error_t *errno_p = nullptr);
Alexey Samsonova68633f2012-07-03 08:24:14 +0000252// Maps given file to virtual memory, and returns pointer to it
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700253// (or NULL if mapping fails). Stores the size of mmaped region
Alexey Samsonova68633f2012-07-03 08:24:14 +0000254// in '*buff_size'.
255void *MapFileToMemory(const char *file_name, uptr *buff_size);
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800256void *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, OFF_T offset);
Alexey Samsonova68633f2012-07-03 08:24:14 +0000257
Stephen Hines6d186232014-11-26 17:56:19 -0800258bool IsAccessibleMemoryRange(uptr beg, uptr size);
259
Alexey Samsonov90b0f1e2013-10-04 08:55:03 +0000260// Error report formatting.
261const char *StripPathPrefix(const char *filepath,
262 const char *strip_file_prefix);
Stephen Hines6d186232014-11-26 17:56:19 -0800263// Strip the directories from the module name.
264const char *StripModuleName(const char *module);
Alexey Samsonov90b0f1e2013-10-04 08:55:03 +0000265
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000266// OS
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -0700267uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800268uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len);
269uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len);
270const char *GetProcessName();
271void UpdateProcessName();
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -0700272void CacheBinaryName();
Stephen Hines6d186232014-11-26 17:56:19 -0800273void DisableCoreDumperIfNecessary();
Alexey Samsonovbe7420c2012-06-15 06:08:19 +0000274void DumpProcessMap();
Alexey Samsonov93b4caf2012-11-09 14:45:30 +0000275bool FileExists(const char *filename);
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000276const char *GetEnv(const char *name);
Alexey Samsonovff7c14f2013-04-23 12:49:12 +0000277bool SetEnv(const char *name, const char *value);
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000278const char *GetPwd();
Alexey Samsonov1dcd1d92013-09-03 13:20:48 +0000279char *FindPathToBinary(const char *name);
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700280bool IsPathSeparator(const char c);
281bool IsAbsolutePath(const char *path);
282
Alexey Samsonov0fa691b2013-02-18 07:17:12 +0000283u32 GetUid();
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000284void ReExec();
285bool StackSizeIsUnlimited();
286void SetStackSizeLimitInBytes(uptr limit);
Stephen Hines6d186232014-11-26 17:56:19 -0800287bool AddressSpaceIsUnlimited();
288void SetAddressSpaceUnlimited();
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700289void AdjustStackSize(void *attr);
290void PrepareForSandboxing(__sanitizer_sandbox_arguments *args);
291void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args);
292void SetSandboxingCallback(void (*f)());
293
Stephen Hines86277eb2015-03-23 12:06:32 -0700294void CoverageUpdateMapping();
Stephen Hines6a211c52014-07-21 00:49:56 -0700295void CovBeforeFork();
296void CovAfterFork(int child_pid);
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000297
Stephen Hines86277eb2015-03-23 12:06:32 -0700298void InitializeCoverage(bool enabled, const char *coverage_dir);
299void ReInitializeCoverage(bool enabled, const char *coverage_dir);
300
Evgeniy Stepanovb114ed82013-03-13 08:19:53 +0000301void InitTlsSize();
302uptr GetTlsSize();
303
Alexey Samsonovd7e5bb42012-09-17 09:12:39 +0000304// Other
Alexey Samsonovfa3daaf2012-06-15 06:37:34 +0000305void SleepForSeconds(int seconds);
Alexey Samsonov0969bcf2012-06-18 08:44:30 +0000306void SleepForMillis(int millis);
Dmitry Vyukov4bebe7b2013-03-21 06:24:31 +0000307u64 NanoTime();
Alexey Samsonovfa3daaf2012-06-15 06:37:34 +0000308int Atexit(void (*function)(void));
Alexey Samsonov4c496662012-06-15 07:00:31 +0000309void SortArray(uptr *array, uptr size);
Stephen Hines86277eb2015-03-23 12:06:32 -0700310bool TemplateMatch(const char *templ, const char *str);
Alexey Samsonovbe7420c2012-06-15 06:08:19 +0000311
Alexey Samsonov591616d2012-09-11 09:44:48 +0000312// Exit
313void NORETURN Abort();
Alexey Samsonov591616d2012-09-11 09:44:48 +0000314void NORETURN Die();
Timur Iskhodzhanov3c80c6c2013-08-13 11:42:45 +0000315void NORETURN
Alexey Samsonov591616d2012-09-11 09:44:48 +0000316CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800317void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,
318 const char *mmap_type, error_t err,
319 bool raw_report = false);
Alexey Samsonov591616d2012-09-11 09:44:48 +0000320
Kostya Serebryanydddb18b2012-12-07 11:27:24 +0000321// Set the name of the current thread to 'name', return true on succees.
322// The name may be truncated to a system-dependent limit.
323bool SanitizerSetThreadName(const char *name);
324// Get the name of the current thread (no more than max_len bytes),
325// return true on succees. name should have space for at least max_len+1 bytes.
326bool SanitizerGetThreadName(char *name, int max_len);
327
Alexey Samsonov591616d2012-09-11 09:44:48 +0000328// Specific tools may override behavior of "Die" and "CheckFailed" functions
329// to do tool-specific job.
Sergey Matveev90629fb2013-08-26 13:20:31 +0000330typedef void (*DieCallbackType)(void);
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800331
332// It's possible to add several callbacks that would be run when "Die" is
333// called. The callbacks will be run in the opposite order. The tools are
334// strongly recommended to setup all callbacks during initialization, when there
335// is only a single thread.
336bool AddDieCallback(DieCallbackType callback);
337bool RemoveDieCallback(DieCallbackType callback);
338
339void SetUserDieCallback(DieCallbackType callback);
340
Alexey Samsonov591616d2012-09-11 09:44:48 +0000341typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
342 u64, u64);
343void SetCheckFailedCallback(CheckFailedCallbackType callback);
344
Stephen Hines86277eb2015-03-23 12:06:32 -0700345// Callback will be called if soft_rss_limit_mb is given and the limit is
346// exceeded (exceeded==true) or if rss went down below the limit
347// (exceeded==false).
348// The callback should be registered once at the tool init time.
349void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded));
350
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700351// Functions related to signal handling.
352typedef void (*SignalHandlerType)(int, void *, void *);
353bool IsDeadlySignal(int signum);
354void InstallDeadlySignalHandlers(SignalHandlerType handler);
355// Alternative signal stack (POSIX-only).
356void SetAlternateSignalStack();
357void UnsetAlternateSignalStack();
358
Alexey Samsonov2fb08722013-11-01 17:02:14 +0000359// We don't want a summary too long.
360const int kMaxSummaryLength = 1024;
361// Construct a one-line string:
362// SUMMARY: SanitizerToolName: error_message
363// and pass it to __sanitizer_report_error_summary.
364void ReportErrorSummary(const char *error_message);
365// Same as above, but construct error_message as:
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700366// error_type file:line[:column][ function]
367void ReportErrorSummary(const char *error_type, const AddressInfo &info);
368// Same as above, but obtains AddressInfo by symbolizing top stack trace frame.
Alexey Samsonov2fb08722013-11-01 17:02:14 +0000369void ReportErrorSummary(const char *error_type, StackTrace *trace);
Kostya Serebryany2673fd82013-02-06 12:36:49 +0000370
Alexey Samsonov4c496662012-06-15 07:00:31 +0000371// Math
Dmitry Vyukovc5288672013-06-10 10:02:02 +0000372#if SANITIZER_WINDOWS && !defined(__clang__) && !defined(__GNUC__)
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000373extern "C" {
374unsigned char _BitScanForward(unsigned long *index, unsigned long mask); // NOLINT
375unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); // NOLINT
376#if defined(_WIN64)
377unsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask); // NOLINT
378unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask); // NOLINT
379#endif
380}
381#endif
382
383INLINE uptr MostSignificantSetBitIndex(uptr x) {
Kostya Serebryanyf155fcc2013-02-26 12:59:06 +0000384 CHECK_NE(x, 0U);
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000385 unsigned long up; // NOLINT
Dmitry Vyukovc5288672013-06-10 10:02:02 +0000386#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800387# ifdef _WIN64
388 up = SANITIZER_WORDSIZE - 1 - __builtin_clzll(x);
389# else
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000390 up = SANITIZER_WORDSIZE - 1 - __builtin_clzl(x);
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800391# endif
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000392#elif defined(_WIN64)
393 _BitScanReverse64(&up, x);
394#else
395 _BitScanReverse(&up, x);
396#endif
397 return up;
398}
399
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700400INLINE uptr LeastSignificantSetBitIndex(uptr x) {
401 CHECK_NE(x, 0U);
402 unsigned long up; // NOLINT
403#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800404# ifdef _WIN64
405 up = __builtin_ctzll(x);
406# else
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700407 up = __builtin_ctzl(x);
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800408# endif
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700409#elif defined(_WIN64)
410 _BitScanForward64(&up, x);
411#else
412 _BitScanForward(&up, x);
413#endif
414 return up;
415}
416
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000417INLINE bool IsPowerOfTwo(uptr x) {
Alexey Samsonov230c3be2012-06-06 09:26:25 +0000418 return (x & (x - 1)) == 0;
419}
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000420
421INLINE uptr RoundUpToPowerOfTwo(uptr size) {
422 CHECK(size);
423 if (IsPowerOfTwo(size)) return size;
424
425 uptr up = MostSignificantSetBitIndex(size);
426 CHECK(size < (1ULL << (up + 1)));
427 CHECK(size > (1ULL << up));
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800428 return 1ULL << (up + 1);
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000429}
430
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000431INLINE uptr RoundUpTo(uptr size, uptr boundary) {
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800432 RAW_CHECK(IsPowerOfTwo(boundary));
Alexey Samsonov230c3be2012-06-06 09:26:25 +0000433 return (size + boundary - 1) & ~(boundary - 1);
434}
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000435
Kostya Serebryanybc9940e2012-12-14 12:15:09 +0000436INLINE uptr RoundDownTo(uptr x, uptr boundary) {
437 return x & ~(boundary - 1);
438}
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000439
Kostya Serebryany84a996f2012-12-11 14:41:31 +0000440INLINE bool IsAligned(uptr a, uptr alignment) {
441 return (a & (alignment - 1)) == 0;
442}
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000443
444INLINE uptr Log2(uptr x) {
445 CHECK(IsPowerOfTwo(x));
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800446 return LeastSignificantSetBitIndex(x);
Timur Iskhodzhanov400a9462013-02-08 11:45:04 +0000447}
448
Alexey Samsonov0dc31772012-07-16 11:27:17 +0000449// Don't use std::min, std::max or std::swap, to minimize dependency
450// on libstdc++.
Alexey Samsonov4c496662012-06-15 07:00:31 +0000451template<class T> T Min(T a, T b) { return a < b ? a : b; }
452template<class T> T Max(T a, T b) { return a > b ? a : b; }
Alexey Samsonov0dc31772012-07-16 11:27:17 +0000453template<class T> void Swap(T& a, T& b) {
454 T tmp = a;
455 a = b;
456 b = tmp;
457}
Alexey Samsonov9edf7502012-06-06 06:47:26 +0000458
Alexey Samsonovc9256972012-06-15 13:09:52 +0000459// Char handling
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000460INLINE bool IsSpace(int c) {
Alexey Samsonovc9256972012-06-15 13:09:52 +0000461 return (c == ' ') || (c == '\n') || (c == '\t') ||
462 (c == '\f') || (c == '\r') || (c == '\v');
463}
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000464INLINE bool IsDigit(int c) {
Alexey Samsonovc9256972012-06-15 13:09:52 +0000465 return (c >= '0') && (c <= '9');
466}
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000467INLINE int ToLower(int c) {
Alexey Samsonovc9256972012-06-15 13:09:52 +0000468 return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
469}
470
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000471// A low-level vector based on mmap. May incur a significant memory overhead for
472// small vectors.
473// WARNING: The current implementation supports only POD types.
474template<typename T>
Stephen Hines86277eb2015-03-23 12:06:32 -0700475class InternalMmapVectorNoCtor {
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000476 public:
Stephen Hines86277eb2015-03-23 12:06:32 -0700477 void Initialize(uptr initial_capacity) {
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700478 capacity_ = Max(initial_capacity, (uptr)1);
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000479 size_ = 0;
Stephen Hines86277eb2015-03-23 12:06:32 -0700480 data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalMmapVectorNoCtor");
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000481 }
Stephen Hines86277eb2015-03-23 12:06:32 -0700482 void Destroy() {
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000483 UnmapOrDie(data_, capacity_ * sizeof(T));
484 }
485 T &operator[](uptr i) {
Alexey Samsonov96950032013-03-29 08:03:01 +0000486 CHECK_LT(i, size_);
Alexey Samsonovca280f22013-03-28 15:37:11 +0000487 return data_[i];
488 }
489 const T &operator[](uptr i) const {
Alexey Samsonov96950032013-03-29 08:03:01 +0000490 CHECK_LT(i, size_);
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000491 return data_[i];
492 }
493 void push_back(const T &element) {
494 CHECK_LE(size_, capacity_);
495 if (size_ == capacity_) {
496 uptr new_capacity = RoundUpToPowerOfTwo(size_ + 1);
497 Resize(new_capacity);
498 }
499 data_[size_++] = element;
500 }
Alexey Samsonov352b2452013-03-05 11:58:25 +0000501 T &back() {
502 CHECK_GT(size_, 0);
503 return data_[size_ - 1];
504 }
505 void pop_back() {
506 CHECK_GT(size_, 0);
507 size_--;
508 }
Alexey Samsonovca280f22013-03-28 15:37:11 +0000509 uptr size() const {
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000510 return size_;
511 }
Alexander Potapenkoe5b398f2013-04-01 13:55:34 +0000512 const T *data() const {
513 return data_;
514 }
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700515 T *data() {
516 return data_;
517 }
Alexander Potapenkoe5b398f2013-04-01 13:55:34 +0000518 uptr capacity() const {
519 return capacity_;
520 }
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000521
Bob Wilsondbd69cc2013-11-15 07:18:15 +0000522 void clear() { size_ = 0; }
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700523 bool empty() const { return size() == 0; }
Bob Wilsondbd69cc2013-11-15 07:18:15 +0000524
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000525 private:
526 void Resize(uptr new_capacity) {
527 CHECK_GT(new_capacity, 0);
528 CHECK_LE(size_, new_capacity);
529 T *new_data = (T *)MmapOrDie(new_capacity * sizeof(T),
Alexey Samsonova64d4352013-06-14 09:59:40 +0000530 "InternalMmapVector");
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000531 internal_memcpy(new_data, data_, size_ * sizeof(T));
532 T *old_data = data_;
533 data_ = new_data;
534 UnmapOrDie(old_data, capacity_ * sizeof(T));
535 capacity_ = new_capacity;
536 }
Kostya Serebryanyb5f95212013-02-26 13:30:27 +0000537
538 T *data_;
539 uptr capacity_;
540 uptr size_;
541};
Sergey Matveev15bb32b2013-05-13 11:58:48 +0000542
Stephen Hines86277eb2015-03-23 12:06:32 -0700543template<typename T>
544class InternalMmapVector : public InternalMmapVectorNoCtor<T> {
545 public:
546 explicit InternalMmapVector(uptr initial_capacity) {
547 InternalMmapVectorNoCtor<T>::Initialize(initial_capacity);
548 }
549 ~InternalMmapVector() { InternalMmapVectorNoCtor<T>::Destroy(); }
550 // Disallow evil constructors.
551 InternalMmapVector(const InternalMmapVector&);
552 void operator=(const InternalMmapVector&);
553};
554
Alexey Samsonova64d4352013-06-14 09:59:40 +0000555// HeapSort for arrays and InternalMmapVector.
Sergey Matveev15bb32b2013-05-13 11:58:48 +0000556template<class Container, class Compare>
557void InternalSort(Container *v, uptr size, Compare comp) {
558 if (size < 2)
559 return;
560 // Stage 1: insert elements to the heap.
561 for (uptr i = 1; i < size; i++) {
562 uptr j, p;
563 for (j = i; j > 0; j = p) {
564 p = (j - 1) / 2;
565 if (comp((*v)[p], (*v)[j]))
566 Swap((*v)[j], (*v)[p]);
567 else
568 break;
569 }
570 }
571 // Stage 2: swap largest element with the last one,
572 // and sink the new top.
573 for (uptr i = size - 1; i > 0; i--) {
574 Swap((*v)[0], (*v)[i]);
575 uptr j, max_ind;
576 for (j = 0; j < i; j = max_ind) {
577 uptr left = 2 * j + 1;
578 uptr right = 2 * j + 2;
579 max_ind = j;
580 if (left < i && comp((*v)[max_ind], (*v)[left]))
581 max_ind = left;
582 if (right < i && comp((*v)[max_ind], (*v)[right]))
583 max_ind = right;
584 if (max_ind != j)
585 Swap((*v)[j], (*v)[max_ind]);
586 else
587 break;
588 }
589 }
590}
591
Sergey Matveev384a4482013-08-26 13:24:43 +0000592template<class Container, class Value, class Compare>
593uptr InternalBinarySearch(const Container &v, uptr first, uptr last,
594 const Value &val, Compare comp) {
595 uptr not_found = last + 1;
596 while (last >= first) {
597 uptr mid = (first + last) / 2;
598 if (comp(v[mid], val))
599 first = mid + 1;
600 else if (comp(val, v[mid]))
601 last = mid - 1;
602 else
603 return mid;
604 }
605 return not_found;
606}
607
Alexey Samsonov7847d772013-09-10 14:36:16 +0000608// Represents a binary loaded into virtual memory (e.g. this can be an
609// executable or a shared object).
610class LoadedModule {
611 public:
Pirama Arumuga Nainar259f7062015-05-06 11:49:53 -0700612 LoadedModule() : full_name_(nullptr), base_address_(0) { ranges_.clear(); }
613 void set(const char *module_name, uptr base_address);
Stephen Hines86277eb2015-03-23 12:06:32 -0700614 void clear();
Stephen Hines6a211c52014-07-21 00:49:56 -0700615 void addAddressRange(uptr beg, uptr end, bool executable);
Alexey Samsonov7847d772013-09-10 14:36:16 +0000616 bool containsAddress(uptr address) const;
617
618 const char *full_name() const { return full_name_; }
619 uptr base_address() const { return base_address_; }
620
Alexey Samsonov7847d772013-09-10 14:36:16 +0000621 struct AddressRange {
Stephen Hines86277eb2015-03-23 12:06:32 -0700622 AddressRange *next;
Alexey Samsonov7847d772013-09-10 14:36:16 +0000623 uptr beg;
624 uptr end;
Stephen Hines86277eb2015-03-23 12:06:32 -0700625 bool executable;
626
627 AddressRange(uptr beg, uptr end, bool executable)
628 : next(nullptr), beg(beg), end(end), executable(executable) {}
Alexey Samsonov7847d772013-09-10 14:36:16 +0000629 };
Stephen Hines86277eb2015-03-23 12:06:32 -0700630
631 typedef IntrusiveList<AddressRange>::ConstIterator Iterator;
632 Iterator ranges() const { return Iterator(&ranges_); }
633
634 private:
635 char *full_name_; // Owned.
Alexey Samsonov7847d772013-09-10 14:36:16 +0000636 uptr base_address_;
Stephen Hines86277eb2015-03-23 12:06:32 -0700637 IntrusiveList<AddressRange> ranges_;
Alexey Samsonov7847d772013-09-10 14:36:16 +0000638};
639
640// OS-dependent function that fills array with descriptions of at most
641// "max_modules" currently loaded modules. Returns the number of
642// initialized modules. If filter is nonzero, ignores modules for which
643// filter(full_name) is false.
644typedef bool (*string_predicate_t)(const char *);
645uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
646 string_predicate_t filter);
647
Sergey Matveevc5193352013-10-14 14:04:50 +0000648// Callback type for iterating over a set of memory ranges.
649typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700650
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800651enum AndroidApiLevel {
652 ANDROID_NOT_ANDROID = 0,
653 ANDROID_KITKAT = 19,
654 ANDROID_LOLLIPOP_MR1 = 22,
655 ANDROID_POST_LOLLIPOP = 23
656};
657
658void WriteToSyslog(const char *buffer);
659
660#if SANITIZER_MAC
661void LogFullErrorReport(const char *buffer);
662#else
663INLINE void LogFullErrorReport(const char *buffer) {}
664#endif
665
666#if SANITIZER_LINUX || SANITIZER_MAC
667void WriteOneLineToSyslog(const char *s);
668#else
669INLINE void WriteOneLineToSyslog(const char *s) {}
670#endif
671
672#if SANITIZER_LINUX
Evgeniy Stepanovaafc5c82014-09-15 11:37:40 +0000673// Initialize Android logging. Any writes before this are silently lost.
674void AndroidLogInit();
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800675bool ShouldLogAfterPrintf();
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700676#else
Evgeniy Stepanovaafc5c82014-09-15 11:37:40 +0000677INLINE void AndroidLogInit() {}
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800678INLINE bool ShouldLogAfterPrintf() { return false; }
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700679#endif
Stephen Hines86277eb2015-03-23 12:06:32 -0700680
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800681#if SANITIZER_ANDROID
682void SanitizerInitializeUnwinder();
683AndroidApiLevel AndroidGetApiLevel();
684#else
685INLINE void AndroidLogWrite(const char *buffer_unused) {}
686INLINE void SanitizerInitializeUnwinder() {}
687INLINE AndroidApiLevel AndroidGetApiLevel() { return ANDROID_NOT_ANDROID; }
688#endif
689
690INLINE uptr GetPthreadDestructorIterations() {
691#if SANITIZER_ANDROID
692 return (AndroidGetApiLevel() == ANDROID_LOLLIPOP_MR1) ? 8 : 4;
693#elif SANITIZER_POSIX
694 return 4;
695#else
696// Unused on Windows.
697 return 0;
698#endif
699}
700
Stephen Hines86277eb2015-03-23 12:06:32 -0700701void *internal_start_thread(void(*func)(void*), void *arg);
702void internal_join_thread(void *th);
703void MaybeStartBackgroudThread();
704
705// Make the compiler think that something is going on there.
706// Use this inside a loop that looks like memset/memcpy/etc to prevent the
707// compiler from recognising it and turning it into an actual call to
708// memset/memcpy/etc.
709static inline void SanitizerBreakOptimization(void *arg) {
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800710#if _MSC_VER && !defined(__clang__)
711 _ReadWriteBarrier();
Stephen Hines86277eb2015-03-23 12:06:32 -0700712#else
713 __asm__ __volatile__("" : : "r" (arg) : "memory");
714#endif
715}
716
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -0700717struct SignalContext {
718 void *context;
719 uptr addr;
720 uptr pc;
721 uptr sp;
722 uptr bp;
723
724 SignalContext(void *context, uptr addr, uptr pc, uptr sp, uptr bp) :
725 context(context), addr(addr), pc(pc), sp(sp), bp(bp) {
726 }
727
728 // Creates signal context in a platform-specific manner.
729 static SignalContext Create(void *siginfo, void *context);
730};
731
732void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
733
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800734void DisableReexec();
735void MaybeReexec();
736
Alexey Samsonov9edf7502012-06-06 06:47:26 +0000737} // namespace __sanitizer
738
Peter Collingbourne53177242013-10-24 06:23:39 +0000739inline void *operator new(__sanitizer::operator_new_size_type size,
740 __sanitizer::LowLevelAllocator &alloc) {
741 return alloc.Allocate(size);
742}
743
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700744struct StackDepotStats {
745 uptr n_uniq_ids;
746 uptr allocated;
747};
748
Alexey Samsonov9edf7502012-06-06 06:47:26 +0000749#endif // SANITIZER_COMMON_H