1//===-- sanitizer_common.h --------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is shared between run-time libraries of sanitizers.
10//
11// It declares common functions and classes that are used in both runtimes.
12// Implementation of some functions are provided in sanitizer_common, while
13// others must be defined by run-time library itself.
14//===----------------------------------------------------------------------===//
15#ifndef SANITIZER_COMMON_H
16#define SANITIZER_COMMON_H
17
18#include "sanitizer_flags.h"
19#include "sanitizer_internal_defs.h"
20#include "sanitizer_libc.h"
21#include "sanitizer_list.h"
22#include "sanitizer_mutex.h"
23
24#if defined(_MSC_VER) && !defined(__clang__)
25extern "C" void _ReadWriteBarrier();
26#pragma intrinsic(_ReadWriteBarrier)
27#endif
28
29namespace __sanitizer {
30
31struct AddressInfo;
32struct BufferedStackTrace;
33struct SignalContext;
34struct StackTrace;
35struct SymbolizedStack;
36
37// Constants.
38const uptr kWordSize = SANITIZER_WORDSIZE / 8;
39const uptr kWordSizeInBits = 8 * kWordSize;
40
41const uptr kCacheLineSize = SANITIZER_CACHE_LINE_SIZE;
42
43const uptr kMaxPathLength = 4096;
44
45const uptr kMaxThreadStackSize = 1 << 30; // 1Gb
46
47const uptr kErrorMessageBufferSize = 1 << 16;
48
49// Denotes fake PC values that come from JIT/JAVA/etc.
50// For such PC values __tsan_symbolize_external_ex() will be called.
51const u64 kExternalPCBit = 1ULL << 60;
52
53extern const char *SanitizerToolName; // Can be changed by the tool.
54
55extern atomic_uint32_t current_verbosity;
56inline void SetVerbosity(int verbosity) {
57 atomic_store(a: &current_verbosity, v: verbosity, mo: memory_order_relaxed);
58}
59inline int Verbosity() {
60 return atomic_load(a: &current_verbosity, mo: memory_order_relaxed);
61}
62
63#if SANITIZER_ANDROID && !defined(__aarch64__)
64// 32-bit Android only has 4k pages.
65inline uptr GetPageSize() { return 4096; }
66inline uptr GetPageSizeCached() { return 4096; }
67#else
68uptr GetPageSize();
69extern uptr PageSizeCached;
70inline uptr GetPageSizeCached() {
71 if (!PageSizeCached)
72 PageSizeCached = GetPageSize();
73 return PageSizeCached;
74}
75#endif
76
77uptr GetMmapGranularity();
78uptr GetMaxVirtualAddress();
79uptr GetMaxUserVirtualAddress();
80// Threads
81ThreadID GetTid();
82int TgKill(pid_t pid, ThreadID tid, int sig);
83uptr GetThreadSelf();
84void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
85 uptr *stack_bottom);
86void GetThreadStackAndTls(bool main, uptr *stk_begin, uptr *stk_end,
87 uptr *tls_begin, uptr *tls_end);
88
89// Memory management
90void *MmapOrDie(uptr size, const char *mem_type, bool raw_report = false);
91
92inline void *MmapOrDieQuietly(uptr size, const char *mem_type) {
93 return MmapOrDie(size, mem_type, /*raw_report*/ raw_report: true);
94}
95void UnmapOrDie(void *addr, uptr size, bool raw_report = false);
96// Behaves just like MmapOrDie, but tolerates out of memory condition, in that
97// case returns nullptr.
98void *MmapOrDieOnFatalError(uptr size, const char *mem_type);
99bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name = nullptr)
100 WARN_UNUSED_RESULT;
101bool MmapFixedSuperNoReserve(uptr fixed_addr, uptr size,
102 const char *name = nullptr) WARN_UNUSED_RESULT;
103void *MmapNoReserveOrDie(uptr size, const char *mem_type);
104void *MmapFixedOrDie(uptr fixed_addr, uptr size, const char *name = nullptr);
105// Behaves just like MmapFixedOrDie, but tolerates out of memory condition, in
106// that case returns nullptr.
107void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size,
108 const char *name = nullptr);
109void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name = nullptr);
110void *MmapNoAccess(uptr size);
111// Map aligned chunk of address space; size and alignment are powers of two.
112// Dies on all but out of memory errors, in the latter case returns nullptr.
113void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
114 const char *mem_type);
115// Disallow access to a memory range. Use MmapFixedNoAccess to allocate an
116// unaccessible memory.
117bool MprotectNoAccess(uptr addr, uptr size);
118bool MprotectReadOnly(uptr addr, uptr size);
119bool MprotectReadWrite(uptr addr, uptr size);
120
121void MprotectMallocZones(void *addr, int prot);
122
123#if SANITIZER_WINDOWS
124// Zero previously mmap'd memory. Currently used only on Windows.
125bool ZeroMmapFixedRegion(uptr fixed_addr, uptr size) WARN_UNUSED_RESULT;
126#endif
127
128#if SANITIZER_LINUX
129// Unmap memory. Currently only used on Linux.
130void UnmapFromTo(uptr from, uptr to);
131#endif
132
133// Maps shadow_size_bytes of shadow memory and returns shadow address. It will
134// be aligned to the mmap granularity * 2^shadow_scale, or to
135// 2^min_shadow_base_alignment if that is larger. The returned address will
136// have max(2^min_shadow_base_alignment, mmap granularity) on the left, and
137// shadow_size_bytes bytes on the right, which on linux is mapped no access.
138// The high_mem_end may be updated if the original shadow size doesn't fit.
139uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
140 uptr min_shadow_base_alignment, uptr &high_mem_end,
141 uptr granularity);
142
143// Let S = max(shadow_size, num_aliases * alias_size, ring_buffer_size).
144// Reserves 2*S bytes of address space to the right of the returned address and
145// ring_buffer_size bytes to the left. The returned address is aligned to 2*S.
146// Also creates num_aliases regions of accessible memory starting at offset S
147// from the returned address. Each region has size alias_size and is backed by
148// the same physical memory.
149uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size,
150 uptr num_aliases, uptr ring_buffer_size);
151
152// Reserve memory range [beg, end]. If madvise_shadow is true then apply
153// madvise (e.g. hugepages, core dumping) requested by options.
154void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name,
155 bool madvise_shadow = true);
156
157// Protect size bytes of memory starting at addr. Also try to protect
158// several pages at the start of the address space as specified by
159// zero_base_shadow_start, at most up to the size or zero_base_max_shadow_start.
160void ProtectGap(uptr addr, uptr size, uptr zero_base_shadow_start,
161 uptr zero_base_max_shadow_start);
162
163// Used to check if we can map shadow memory to a fixed location.
164bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
165// Releases memory pages entirely within the [beg, end) address range. Noop if
166// the provided range does not contain at least one entire page.
167void ReleaseMemoryPagesToOS(uptr beg, uptr end);
168void IncreaseTotalMmap(uptr size);
169void DecreaseTotalMmap(uptr size);
170uptr GetRSS();
171void SetShadowRegionHugePageMode(uptr addr, uptr length);
172bool DontDumpShadowMemory(uptr addr, uptr length);
173// Check if the built VMA size matches the runtime one.
174void CheckVMASize();
175void RunMallocHooks(void *ptr, uptr size);
176int RunFreeHooks(void *ptr);
177
178class ReservedAddressRange {
179 public:
180 uptr Init(uptr size, const char *name = nullptr, uptr fixed_addr = 0);
181 uptr InitAligned(uptr size, uptr align, const char *name = nullptr);
182 uptr Map(uptr fixed_addr, uptr size, const char *name = nullptr);
183 uptr MapOrDie(uptr fixed_addr, uptr size, const char *name = nullptr);
184 void Unmap(uptr addr, uptr size);
185 void *base() const { return base_; }
186 uptr size() const { return size_; }
187
188 private:
189 void* base_;
190 uptr size_;
191 const char* name_;
192 uptr os_handle_;
193};
194
195typedef void (*fill_profile_f)(uptr start, uptr rss, bool file,
196 /*out*/ uptr *stats);
197
198// Parse the contents of /proc/self/smaps and generate a memory profile.
199// |cb| is a tool-specific callback that fills the |stats| array.
200void GetMemoryProfile(fill_profile_f cb, uptr *stats);
201void ParseUnixMemoryProfile(fill_profile_f cb, uptr *stats, char *smaps,
202 uptr smaps_len);
203
204// Simple low-level (mmap-based) allocator for internal use. Doesn't have
205// constructor, so all instances of LowLevelAllocator should be
206// linker initialized.
207//
208// NOTE: Users should instead use the singleton provided via
209// `GetGlobalLowLevelAllocator()` rather than create a new one. This way, the
210// number of mmap fragments can be reduced and use the same contiguous mmap
211// provided by this singleton.
212class LowLevelAllocator {
213 public:
214 // Requires an external lock.
215 void *Allocate(uptr size);
216
217 private:
218 char *allocated_end_;
219 char *allocated_current_;
220};
221// Set the min alignment of LowLevelAllocator to at least alignment.
222void SetLowLevelAllocateMinAlignment(uptr alignment);
223typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);
224// Allows to register tool-specific callbacks for LowLevelAllocator.
225// Passing NULL removes the callback.
226void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback);
227
228LowLevelAllocator &GetGlobalLowLevelAllocator();
229
230// IO
231void CatastrophicErrorWrite(const char *buffer, uptr length);
232void RawWrite(const char *buffer);
233bool ColorizeReports();
234void RemoveANSIEscapeSequencesFromString(char *buffer);
235void Printf(const char *format, ...) FORMAT(1, 2);
236void Report(const char *format, ...) FORMAT(1, 2);
237void SetPrintfAndReportCallback(void (*callback)(const char *));
238#define VReport(level, ...) \
239 do { \
240 if (UNLIKELY((uptr)Verbosity() >= (level))) \
241 Report(__VA_ARGS__); \
242 } while (0)
243#define VPrintf(level, ...) \
244 do { \
245 if (UNLIKELY((uptr)Verbosity() >= (level))) \
246 Printf(__VA_ARGS__); \
247 } while (0)
248
249// Lock sanitizer error reporting and protects against nested errors.
250class ScopedErrorReportLock {
251 public:
252 ScopedErrorReportLock() SANITIZER_ACQUIRE(mutex_) { Lock(); }
253 ~ScopedErrorReportLock() SANITIZER_RELEASE(mutex_) { Unlock(); }
254
255 static void Lock() SANITIZER_ACQUIRE(mutex_);
256 static void Unlock() SANITIZER_RELEASE(mutex_);
257 static void CheckLocked() SANITIZER_CHECK_LOCKED(mutex_);
258
259 private:
260 static atomic_uintptr_t reporting_thread_;
261 static StaticSpinMutex mutex_;
262};
263
264extern uptr stoptheworld_tracer_pid;
265extern uptr stoptheworld_tracer_ppid;
266
267// Returns true if the entire range can be read.
268bool IsAccessibleMemoryRange(uptr beg, uptr size);
269// Attempts to copy `n` bytes from memory range starting at `src` to `dest`.
270// Returns true if the entire range can be read. Returns `false` if any part of
271// the source range cannot be read, in which case the contents of `dest` are
272// undefined.
273bool TryMemCpy(void *dest, const void *src, uptr n);
274// Copies accessible memory, and zero fill inaccessible.
275void MemCpyAccessible(void *dest, const void *src, uptr n);
276
277// Error report formatting.
278const char *StripPathPrefix(const char *filepath,
279 const char *strip_file_prefix);
280// Strip the directories from the module name.
281const char *StripModuleName(const char *module);
282
283// OS
284uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
285uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len);
286uptr ReadBinaryDir(/*out*/ char *buf, uptr buf_len);
287uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len);
288const char *GetProcessName();
289void UpdateProcessName();
290void CacheBinaryName();
291void DisableCoreDumperIfNecessary();
292void DumpProcessMap();
293const char *GetEnv(const char *name);
294bool SetEnv(const char *name, const char *value);
295
296u32 GetUid();
297void ReExec();
298void CheckASLR();
299void CheckMPROTECT();
300char **GetArgv();
301char **GetEnviron();
302void PrintCmdline();
303bool StackSizeIsUnlimited();
304void SetStackSizeLimitInBytes(uptr limit);
305bool AddressSpaceIsUnlimited();
306void SetAddressSpaceUnlimited();
307void AdjustStackSize(void *attr);
308void PlatformPrepareForSandboxing(void *args);
309void SetSandboxingCallback(void (*f)());
310
311void InitializeCoverage(bool enabled, const char *coverage_dir);
312
313void InitTlsSize();
314uptr GetTlsSize();
315
316// Other
317void WaitForDebugger(unsigned seconds, const char *label);
318void SleepForSeconds(unsigned seconds);
319void SleepForMillis(unsigned millis);
320u64 NanoTime();
321u64 MonotonicNanoTime();
322int Atexit(void (*function)(void));
323bool TemplateMatch(const char *templ, const char *str);
324
325// Exit
326void NORETURN Abort();
327void NORETURN Die();
328void NORETURN
329CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
330void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,
331 const char *mmap_type, error_t err,
332 bool raw_report = false);
333void NORETURN ReportMunmapFailureAndDie(void *ptr, uptr size, error_t err,
334 bool raw_report = false);
335
336// Returns true if the platform-specific error reported is an OOM error.
337bool ErrorIsOOM(error_t err);
338
339// This reports an error in the form:
340//
341// `ERROR: {{SanitizerToolName}}: out of memory: {{err_msg}}`
342//
343// Downstream tools that read sanitizer output will know that errors starting
344// in this format are specifically OOM errors.
345#define ERROR_OOM(err_msg, ...) \
346 Report("ERROR: %s: out of memory: " err_msg, SanitizerToolName, __VA_ARGS__)
347
348// Specific tools may override behavior of "Die" function to do tool-specific
349// job.
350typedef void (*DieCallbackType)(void);
351
352// It's possible to add several callbacks that would be run when "Die" is
353// called. The callbacks will be run in the opposite order. The tools are
354// strongly recommended to setup all callbacks during initialization, when there
355// is only a single thread.
356bool AddDieCallback(DieCallbackType callback);
357bool RemoveDieCallback(DieCallbackType callback);
358
359void SetUserDieCallback(DieCallbackType callback);
360
361void SetCheckUnwindCallback(void (*callback)());
362
363// Functions related to signal handling.
364typedef void (*SignalHandlerType)(int, void *, void *);
365HandleSignalMode GetHandleSignalMode(int signum);
366void InstallDeadlySignalHandlers(SignalHandlerType handler);
367
368// Signal reporting.
369// Each sanitizer uses slightly different implementation of stack unwinding.
370typedef void (*UnwindSignalStackCallbackType)(const SignalContext &sig,
371 const void *callback_context,
372 BufferedStackTrace *stack);
373// Print deadly signal report and die.
374void HandleDeadlySignal(void *siginfo, void *context, u32 tid,
375 UnwindSignalStackCallbackType unwind,
376 const void *unwind_context);
377
378// Part of HandleDeadlySignal, exposed for asan.
379void StartReportDeadlySignal();
380// Part of HandleDeadlySignal, exposed for asan.
381void ReportDeadlySignal(const SignalContext &sig, u32 tid,
382 UnwindSignalStackCallbackType unwind,
383 const void *unwind_context);
384
385// Alternative signal stack (POSIX-only).
386void* SetAlternateSignalStack();
387void UnsetAlternateSignalStack(void* altstack_base);
388
389bool IsSignalHandlerFromSanitizer(int signum);
390bool SetSignalHandlerFromSanitizer(int signum, bool new_state);
391
392// Construct a one-line string:
393// SUMMARY: SanitizerToolName: error_message
394// and pass it to __sanitizer_report_error_summary.
395// If alt_tool_name is provided, it's used in place of SanitizerToolName.
396void ReportErrorSummary(const char *error_message,
397 const char *alt_tool_name = nullptr);
398// Same as above, but construct error_message as:
399// error_type file:line[:column][ function]
400void ReportErrorSummary(const char *error_type, const AddressInfo &info,
401 const char *alt_tool_name = nullptr);
402// Same as above, but obtains AddressInfo by symbolizing top stack trace frame.
403void ReportErrorSummary(const char *error_type, const StackTrace *trace,
404 const char *alt_tool_name = nullptr);
405// Skips frames which we consider internal and not usefull to the users.
406const SymbolizedStack *SkipInternalFrames(const SymbolizedStack *frames);
407
408void ReportMmapWriteExec(int prot, int mflags);
409
410// Math
411#if SANITIZER_WINDOWS && !defined(__clang__) && !defined(__GNUC__)
412extern "C" {
413unsigned char _BitScanForward(unsigned long *index, unsigned long mask);
414unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
415#if defined(_WIN64)
416unsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask);
417unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask);
418#endif
419}
420#endif
421
422inline uptr MostSignificantSetBitIndex(uptr x) {
423 CHECK_NE(x, 0U);
424 unsigned long up;
425#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
426# ifdef _WIN64
427 up = SANITIZER_WORDSIZE - 1 - __builtin_clzll(x);
428# else
429 up = SANITIZER_WORDSIZE - 1 - __builtin_clzl(x);
430# endif
431#elif defined(_WIN64)
432 _BitScanReverse64(&up, x);
433#else
434 _BitScanReverse(&up, x);
435#endif
436 return up;
437}
438
439inline uptr LeastSignificantSetBitIndex(uptr x) {
440 CHECK_NE(x, 0U);
441 unsigned long up;
442#if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
443# ifdef _WIN64
444 up = __builtin_ctzll(x);
445# else
446 up = __builtin_ctzl(x);
447# endif
448#elif defined(_WIN64)
449 _BitScanForward64(&up, x);
450#else
451 _BitScanForward(&up, x);
452#endif
453 return up;
454}
455
456inline constexpr bool IsPowerOfTwo(uptr x) { return (x & (x - 1)) == 0; }
457
458inline uptr RoundUpToPowerOfTwo(uptr size) {
459 CHECK(size);
460 if (IsPowerOfTwo(x: size)) return size;
461
462 uptr up = MostSignificantSetBitIndex(x: size);
463 CHECK_LT(size, (1ULL << (up + 1)));
464 CHECK_GT(size, (1ULL << up));
465 return 1ULL << (up + 1);
466}
467
468inline constexpr uptr RoundUpTo(uptr size, uptr boundary) {
469 RAW_CHECK(IsPowerOfTwo(boundary));
470 return (size + boundary - 1) & ~(boundary - 1);
471}
472
473inline constexpr uptr RoundDownTo(uptr x, uptr boundary) {
474 return x & ~(boundary - 1);
475}
476
477inline constexpr bool IsAligned(uptr a, uptr alignment) {
478 return (a & (alignment - 1)) == 0;
479}
480
481inline uptr Log2(uptr x) {
482 CHECK(IsPowerOfTwo(x));
483 return LeastSignificantSetBitIndex(x);
484}
485
486inline bool IntervalsAreSeparate(uptr start1, uptr end1, uptr start2,
487 uptr end2) {
488 CHECK_LE(start1, end1);
489 CHECK_LE(start2, end2);
490 return (end1 < start2) || (end2 < start1);
491}
492
493// Don't use std::min, std::max or std::swap, to minimize dependency
494// on libstdc++.
495template <class T>
496constexpr T Min(T a, T b) {
497 return a < b ? a : b;
498}
499template <class T>
500constexpr T Max(T a, T b) {
501 return a > b ? a : b;
502}
503template <class T>
504constexpr T Abs(T a) {
505 return a < 0 ? -a : a;
506}
507template<class T> void Swap(T& a, T& b) {
508 T tmp = a;
509 a = b;
510 b = tmp;
511}
512
513// Char handling
514inline bool IsSpace(int c) {
515 return (c == ' ') || (c == '\n') || (c == '\t') ||
516 (c == '\f') || (c == '\r') || (c == '\v');
517}
518inline bool IsDigit(int c) {
519 return (c >= '0') && (c <= '9');
520}
521inline int ToLower(int c) {
522 return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
523}
524
525// A low-level vector based on mmap. May incur a significant memory overhead for
526// small vectors.
527// WARNING: The current implementation supports only POD types.
528template <typename T, bool raw_report = false>
529class InternalMmapVectorNoCtor {
530 public:
531 using value_type = T;
532 void Initialize(uptr initial_capacity) {
533 capacity_bytes_ = 0;
534 size_ = 0;
535 data_ = 0;
536 reserve(new_size: initial_capacity);
537 }
538 void Destroy() { UnmapOrDie(data_, capacity_bytes_, raw_report); }
539 T &operator[](uptr i) {
540 CHECK_LT(i, size_);
541 return data_[i];
542 }
543 const T &operator[](uptr i) const {
544 CHECK_LT(i, size_);
545 return data_[i];
546 }
547 void push_back(const T &element) {
548 if (UNLIKELY(size_ >= capacity())) {
549 CHECK_EQ(size_, capacity());
550 uptr new_capacity = RoundUpToPowerOfTwo(size: size_ + 1);
551 Realloc(new_capacity);
552 }
553 internal_memcpy(&data_[size_++], &element, sizeof(T));
554 }
555 T &back() {
556 CHECK_GT(size_, 0);
557 return data_[size_ - 1];
558 }
559 void pop_back() {
560 CHECK_GT(size_, 0);
561 size_--;
562 }
563 uptr size() const {
564 return size_;
565 }
566 const T *data() const {
567 return data_;
568 }
569 T *data() {
570 return data_;
571 }
572 uptr capacity() const { return capacity_bytes_ / sizeof(T); }
573 void reserve(uptr new_size) {
574 // Never downsize internal buffer.
575 if (new_size > capacity())
576 Realloc(new_capacity: new_size);
577 }
578 void resize(uptr new_size) {
579 if (new_size > size_) {
580 reserve(new_size);
581 internal_memset(&data_[size_], 0, sizeof(T) * (new_size - size_));
582 }
583 size_ = new_size;
584 }
585
586 void clear() { size_ = 0; }
587 bool empty() const { return size() == 0; }
588
589 const T *begin() const {
590 return data();
591 }
592 T *begin() {
593 return data();
594 }
595 const T *end() const {
596 return data() + size();
597 }
598 T *end() {
599 return data() + size();
600 }
601
602 void swap(InternalMmapVectorNoCtor &other) {
603 Swap(data_, other.data_);
604 Swap(a&: capacity_bytes_, b&: other.capacity_bytes_);
605 Swap(a&: size_, b&: other.size_);
606 }
607
608 private:
609 NOINLINE void Realloc(uptr new_capacity) {
610 CHECK_GT(new_capacity, 0);
611 CHECK_LE(size_, new_capacity);
612 uptr new_capacity_bytes =
613 RoundUpTo(size: new_capacity * sizeof(T), boundary: GetPageSizeCached());
614 T *new_data =
615 (T *)MmapOrDie(size: new_capacity_bytes, mem_type: "InternalMmapVector", raw_report);
616 internal_memcpy(new_data, data_, size_ * sizeof(T));
617 UnmapOrDie(data_, capacity_bytes_, raw_report);
618 data_ = new_data;
619 capacity_bytes_ = new_capacity_bytes;
620 }
621
622 T *data_;
623 uptr capacity_bytes_;
624 uptr size_;
625};
626
627template <typename T>
628bool operator==(const InternalMmapVectorNoCtor<T> &lhs,
629 const InternalMmapVectorNoCtor<T> &rhs) {
630 if (lhs.size() != rhs.size()) return false;
631 return internal_memcmp(lhs.data(), rhs.data(), lhs.size() * sizeof(T)) == 0;
632}
633
634template <typename T>
635bool operator!=(const InternalMmapVectorNoCtor<T> &lhs,
636 const InternalMmapVectorNoCtor<T> &rhs) {
637 return !(lhs == rhs);
638}
639
640template<typename T>
641class InternalMmapVector : public InternalMmapVectorNoCtor<T> {
642 public:
643 InternalMmapVector() { InternalMmapVectorNoCtor<T>::Initialize(0); }
644 explicit InternalMmapVector(uptr cnt) {
645 InternalMmapVectorNoCtor<T>::Initialize(cnt);
646 this->resize(cnt);
647 }
648 ~InternalMmapVector() { InternalMmapVectorNoCtor<T>::Destroy(); }
649 // Disallow copies and moves.
650 InternalMmapVector(const InternalMmapVector &) = delete;
651 InternalMmapVector &operator=(const InternalMmapVector &) = delete;
652 InternalMmapVector(InternalMmapVector &&) = delete;
653 InternalMmapVector &operator=(InternalMmapVector &&) = delete;
654};
655
656class InternalScopedString {
657 public:
658 InternalScopedString() : buffer_(1) { buffer_[0] = '\0'; }
659
660 uptr length() const { return buffer_.size() - 1; }
661 void clear() {
662 buffer_.resize(new_size: 1);
663 buffer_[0] = '\0';
664 }
665 void Append(const char *str);
666 void AppendF(const char *format, ...) FORMAT(2, 3);
667 const char *data() const { return buffer_.data(); }
668 char *data() { return buffer_.data(); }
669
670 private:
671 InternalMmapVector<char> buffer_;
672};
673
674template <class T>
675struct CompareLess {
676 bool operator()(const T &a, const T &b) const { return a < b; }
677};
678
679// HeapSort for arrays and InternalMmapVector.
680template <class T, class Compare = CompareLess<T>>
681void Sort(T *v, uptr size, Compare comp = {}) {
682 if (size < 2)
683 return;
684 // Stage 1: insert elements to the heap.
685 for (uptr i = 1; i < size; i++) {
686 uptr j, p;
687 for (j = i; j > 0; j = p) {
688 p = (j - 1) / 2;
689 if (comp(v[p], v[j]))
690 Swap(v[j], v[p]);
691 else
692 break;
693 }
694 }
695 // Stage 2: swap largest element with the last one,
696 // and sink the new top.
697 for (uptr i = size - 1; i > 0; i--) {
698 Swap(v[0], v[i]);
699 uptr j, max_ind;
700 for (j = 0; j < i; j = max_ind) {
701 uptr left = 2 * j + 1;
702 uptr right = 2 * j + 2;
703 max_ind = j;
704 if (left < i && comp(v[max_ind], v[left]))
705 max_ind = left;
706 if (right < i && comp(v[max_ind], v[right]))
707 max_ind = right;
708 if (max_ind != j)
709 Swap(v[j], v[max_ind]);
710 else
711 break;
712 }
713 }
714}
715
716// Works like std::lower_bound: finds the first element that is not less
717// than the val.
718template <class Container, class T,
719 class Compare = CompareLess<typename Container::value_type>>
720uptr InternalLowerBound(const Container &v, const T &val, Compare comp = {}) {
721 uptr first = 0;
722 uptr last = v.size();
723 while (last > first) {
724 uptr mid = (first + last) / 2;
725 if (comp(v[mid], val))
726 first = mid + 1;
727 else
728 last = mid;
729 }
730 return first;
731}
732
733enum ModuleArch {
734 kModuleArchUnknown,
735 kModuleArchI386,
736 kModuleArchX86_64,
737 kModuleArchX86_64H,
738 kModuleArchARMV6,
739 kModuleArchARMV7,
740 kModuleArchARMV7S,
741 kModuleArchARMV7K,
742 kModuleArchARM64,
743 kModuleArchARM64E,
744 kModuleArchLoongArch64,
745 kModuleArchRISCV64,
746 kModuleArchHexagon
747};
748
749// Sorts and removes duplicates from the container.
750template <class Container,
751 class Compare = CompareLess<typename Container::value_type>>
752void SortAndDedup(Container &v, Compare comp = {}) {
753 Sort(v.data(), v.size(), comp);
754 uptr size = v.size();
755 if (size < 2)
756 return;
757 uptr last = 0;
758 for (uptr i = 1; i < size; ++i) {
759 if (comp(v[last], v[i])) {
760 ++last;
761 if (last != i)
762 v[last] = v[i];
763 } else {
764 CHECK(!comp(v[i], v[last]));
765 }
766 }
767 v.resize(last + 1);
768}
769
770constexpr uptr kDefaultFileMaxSize = FIRST_32_SECOND_64(1 << 26, 1 << 28);
771
772// Opens the file 'file_name" and reads up to 'max_len' bytes.
773// The resulting buffer is mmaped and stored in '*buff'.
774// Returns true if file was successfully opened and read.
775bool ReadFileToVector(const char *file_name,
776 InternalMmapVectorNoCtor<char> *buff,
777 uptr max_len = kDefaultFileMaxSize,
778 error_t *errno_p = nullptr);
779
780// Opens the file 'file_name" and reads up to 'max_len' bytes.
781// This function is less I/O efficient than ReadFileToVector as it may reread
782// file multiple times to avoid mmap during read attempts. It's used to read
783// procmap, so short reads with mmap in between can produce inconsistent result.
784// The resulting buffer is mmaped and stored in '*buff'.
785// The size of the mmaped region is stored in '*buff_size'.
786// The total number of read bytes is stored in '*read_len'.
787// Returns true if file was successfully opened and read.
788bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
789 uptr *read_len, uptr max_len = kDefaultFileMaxSize,
790 error_t *errno_p = nullptr);
791
792int GetModuleAndOffsetForPc(uptr pc, char *module_name, uptr module_name_len,
793 uptr *pc_offset);
794
795// When adding a new architecture, don't forget to also update
796// script/asan_symbolize.py and sanitizer_symbolizer_libcdep.cpp.
797inline const char *ModuleArchToString(ModuleArch arch) {
798 switch (arch) {
799 case kModuleArchUnknown:
800 return "";
801 case kModuleArchI386:
802 return "i386";
803 case kModuleArchX86_64:
804 return "x86_64";
805 case kModuleArchX86_64H:
806 return "x86_64h";
807 case kModuleArchARMV6:
808 return "armv6";
809 case kModuleArchARMV7:
810 return "armv7";
811 case kModuleArchARMV7S:
812 return "armv7s";
813 case kModuleArchARMV7K:
814 return "armv7k";
815 case kModuleArchARM64:
816 return "arm64";
817 case kModuleArchARM64E:
818 return "arm64e";
819 case kModuleArchLoongArch64:
820 return "loongarch64";
821 case kModuleArchRISCV64:
822 return "riscv64";
823 case kModuleArchHexagon:
824 return "hexagon";
825 }
826 CHECK(0 && "Invalid module arch");
827 return "";
828}
829
830#if SANITIZER_APPLE
831const uptr kModuleUUIDSize = 16;
832#else
833const uptr kModuleUUIDSize = 32;
834#endif
835const uptr kMaxSegName = 16;
836
837// Represents a binary loaded into virtual memory (e.g. this can be an
838// executable or a shared object).
839class LoadedModule {
840 public:
841 LoadedModule()
842 : full_name_(nullptr),
843 base_address_(0),
844 max_address_(0),
845 arch_(kModuleArchUnknown),
846 uuid_size_(0),
847 instrumented_(false) {
848 internal_memset(s: uuid_, c: 0, n: kModuleUUIDSize);
849 ranges_.clear();
850 }
851 void set(const char *module_name, uptr base_address);
852 void set(const char *module_name, uptr base_address, ModuleArch arch,
853 u8 uuid[kModuleUUIDSize], bool instrumented);
854 void setUuid(const char *uuid, uptr size);
855 void clear();
856 void addAddressRange(uptr beg, uptr end, bool executable, bool writable,
857 const char *name = nullptr);
858 bool containsAddress(uptr address) const;
859
860 const char *full_name() const { return full_name_; }
861 uptr base_address() const { return base_address_; }
862 uptr max_address() const { return max_address_; }
863 ModuleArch arch() const { return arch_; }
864 const u8 *uuid() const { return uuid_; }
865 uptr uuid_size() const { return uuid_size_; }
866 bool instrumented() const { return instrumented_; }
867
868 struct AddressRange {
869 AddressRange *next;
870 uptr beg;
871 uptr end;
872 bool executable;
873 bool writable;
874 char name[kMaxSegName];
875
876 AddressRange(uptr beg, uptr end, bool executable, bool writable,
877 const char *name)
878 : next(nullptr),
879 beg(beg),
880 end(end),
881 executable(executable),
882 writable(writable) {
883 internal_strncpy(dst: this->name, src: (name ? name : ""), ARRAY_SIZE(this->name));
884 }
885 };
886
887 const IntrusiveList<AddressRange> &ranges() const { return ranges_; }
888
889 private:
890 char *full_name_; // Owned.
891 uptr base_address_;
892 uptr max_address_;
893 ModuleArch arch_;
894 uptr uuid_size_;
895 u8 uuid_[kModuleUUIDSize];
896 bool instrumented_;
897 IntrusiveList<AddressRange> ranges_;
898};
899
900// List of LoadedModules. OS-dependent implementation is responsible for
901// filling this information.
902class ListOfModules {
903 public:
904 ListOfModules() : initialized(false) {}
905 ~ListOfModules() {
906 clear();
907 if (initialized)
908 modules_.Destroy();
909 }
910 ListOfModules(const ListOfModules&) = delete;
911 ListOfModules& operator=(const ListOfModules&) = delete;
912
913 void init();
914 void fallbackInit(); // Uses fallback init if available, otherwise clears
915 const LoadedModule *begin() const { return modules_.begin(); }
916 LoadedModule *begin() { return modules_.begin(); }
917 const LoadedModule *end() const { return modules_.end(); }
918 LoadedModule *end() { return modules_.end(); }
919 uptr size() const { return modules_.size(); }
920 const LoadedModule &operator[](uptr i) const {
921 CHECK_LT(i, modules_.size());
922 return modules_[i];
923 }
924
925 private:
926 void clear() {
927 for (auto &module : modules_) module.clear();
928 modules_.clear();
929 }
930 void clearOrInit() {
931 initialized ? clear() : modules_.Initialize(initial_capacity: kInitialCapacity);
932 initialized = true;
933 }
934
935 InternalMmapVectorNoCtor<LoadedModule> modules_;
936 // We rarely have more than 16K loaded modules.
937 static const uptr kInitialCapacity = 1 << 14;
938 bool initialized;
939};
940
941// Callback type for iterating over a set of memory ranges.
942typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
943
944void WriteToSyslog(const char *buffer);
945
946#if defined(SANITIZER_WINDOWS) && defined(_MSC_VER) && !defined(__clang__)
947#define SANITIZER_WIN_TRACE 1
948#else
949#define SANITIZER_WIN_TRACE 0
950#endif
951
952#if SANITIZER_APPLE || SANITIZER_WIN_TRACE
953void LogFullErrorReport(const char *buffer);
954#else
955inline void LogFullErrorReport(const char *buffer) {}
956#endif
957
958#if SANITIZER_LINUX || SANITIZER_APPLE
959void WriteOneLineToSyslog(const char *s);
960void LogMessageOnPrintf(const char *str);
961#else
962inline void WriteOneLineToSyslog(const char *s) {}
963inline void LogMessageOnPrintf(const char *str) {}
964#endif
965
966#if SANITIZER_LINUX || SANITIZER_WIN_TRACE
967// Initialize Android logging. Any writes before this are silently lost.
968void AndroidLogInit();
969void SetAbortMessage(const char *);
970#else
971inline void AndroidLogInit() {}
972// FIXME: MacOS implementation could use CRSetCrashLogMessage.
973inline void SetAbortMessage(const char *) {}
974#endif
975
976inline uptr GetPthreadDestructorIterations() {
977#if SANITIZER_POSIX
978 return 4;
979#else
980// Unused on Windows.
981 return 0;
982#endif
983}
984
985void *internal_start_thread(void *(*func)(void*), void *arg);
986void internal_join_thread(void *th);
987void MaybeStartBackgroudThread();
988
989// Make the compiler think that something is going on there.
990// Use this inside a loop that looks like memset/memcpy/etc to prevent the
991// compiler from recognising it and turning it into an actual call to
992// memset/memcpy/etc.
993static inline void SanitizerBreakOptimization(void *arg) {
994#if defined(_MSC_VER) && !defined(__clang__)
995 _ReadWriteBarrier();
996#else
997 __asm__ __volatile__("" : : "r" (arg) : "memory");
998#endif
999}
1000
1001struct SignalContext {
1002 void *siginfo;
1003 void *context;
1004 uptr addr;
1005 uptr pc;
1006 uptr sp;
1007 uptr bp;
1008 bool is_memory_access;
1009 enum WriteFlag { Unknown, Read, Write } write_flag;
1010
1011 // In some cases the kernel cannot provide the true faulting address; `addr`
1012 // will be zero then. This field allows to distinguish between these cases
1013 // and dereferences of null.
1014 bool is_true_faulting_addr;
1015
1016 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
1017 // constructor
1018 SignalContext() = default;
1019
1020 // Creates signal context in a platform-specific manner.
1021 // SignalContext is going to keep pointers to siginfo and context without
1022 // owning them.
1023 SignalContext(void *siginfo, void *context)
1024 : siginfo(siginfo),
1025 context(context),
1026 addr(GetAddress()),
1027 is_memory_access(IsMemoryAccess()),
1028 write_flag(GetWriteFlag()),
1029 is_true_faulting_addr(IsTrueFaultingAddress()) {
1030 InitPcSpBp();
1031 }
1032
1033 static void DumpAllRegisters(void *context);
1034
1035 // Type of signal e.g. SIGSEGV or EXCEPTION_ACCESS_VIOLATION.
1036 int GetType() const;
1037
1038 // String description of the signal.
1039 const char *Describe() const;
1040
1041 // Returns true if signal is stack overflow.
1042 bool IsStackOverflow() const;
1043
1044 private:
1045 // Platform specific initialization.
1046 void InitPcSpBp();
1047 uptr GetAddress() const;
1048 WriteFlag GetWriteFlag() const;
1049 bool IsMemoryAccess() const;
1050 bool IsTrueFaultingAddress() const;
1051};
1052
1053void InitializePlatformEarly();
1054
1055template <typename Fn>
1056class RunOnDestruction {
1057 public:
1058 explicit RunOnDestruction(Fn fn) : fn_(fn) {}
1059 ~RunOnDestruction() { fn_(); }
1060
1061 private:
1062 Fn fn_;
1063};
1064
1065// A simple scope guard. Usage:
1066// auto cleanup = at_scope_exit([]{ do_cleanup; });
1067template <typename Fn>
1068RunOnDestruction<Fn> at_scope_exit(Fn fn) {
1069 return RunOnDestruction<Fn>(fn);
1070}
1071
1072// Linux on 64-bit s390 had a nasty bug that crashes the whole machine
1073// if a process uses virtual memory over 4TB (as many sanitizers like
1074// to do). This function will abort the process if running on a kernel
1075// that looks vulnerable.
1076#if SANITIZER_LINUX && SANITIZER_S390_64
1077void AvoidCVE_2016_2143();
1078#else
1079inline void AvoidCVE_2016_2143() {}
1080#endif
1081
1082struct StackDepotStats {
1083 uptr n_uniq_ids;
1084 uptr allocated;
1085};
1086
1087// The default value for allocator_release_to_os_interval_ms common flag to
1088// indicate that sanitizer allocator should not attempt to release memory to OS.
1089const s32 kReleaseToOSIntervalNever = -1;
1090
1091// Platform hook invoked before dlopen. Performs platform-specific dlopen flag
1092// checks (e.g. RTLD_DEEPBIND on Linux).
1093void OnDlOpen(const char* filename, int flag);
1094
1095// Returns the requested amount of random data (up to 256 bytes) that can then
1096// be used to seed a PRNG. Defaults to blocking like the underlying syscall.
1097bool GetRandom(void *buffer, uptr length, bool blocking = true);
1098
1099// Returns the number of logical processors on the system.
1100u32 GetNumberOfCPUs();
1101extern u32 NumberOfCPUsCached;
1102inline u32 GetNumberOfCPUsCached() {
1103 if (!NumberOfCPUsCached)
1104 NumberOfCPUsCached = GetNumberOfCPUs();
1105 return NumberOfCPUsCached;
1106}
1107
1108inline u32 Rand(u32* state) { // ANSI C linear congruential PRNG.
1109 return (*state = *state * 1103515245 + 12345) >> 16;
1110}
1111
1112inline u32 RandN(u32* state, u32 n) { return Rand(state) % n; } // [0, n)
1113
1114} // namespace __sanitizer
1115
1116inline void *operator new(__sanitizer::usize size,
1117 __sanitizer::LowLevelAllocator &alloc) {
1118 return alloc.Allocate(size);
1119}
1120
1121#endif // SANITIZER_COMMON_H
1122