authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-07-16 11:22:46+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-08-30 06:36:41+02:00
logac2050609055d76a58b058b064f0b0c4d54e2faa
tree54855b2bde3e1eed89d870251b044e93972f6c5c
parent85438e75e04b356ca319051c33e0987a9958ad4a
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

libtsan: update to LLVM 21


58 files changed, 1898 insertions(+), 842 deletions(-)

lib/libtsan/builtins/assembly.h+42-15
......@@ -61,7 +61,7 @@
6161#define LOCAL_LABEL(name) .L ## name
6262#define FILE_LEVEL_DIRECTIVE
6363#define SYMBOL_IS_FUNC(name) \
64 .def name SEPARATOR \
64 .def FUNC_SYMBOL(name) SEPARATOR \
6565 .scl 2 SEPARATOR \
6666 .type 32 SEPARATOR \
6767 .endef
......@@ -71,7 +71,7 @@
7171
7272#endif
7373
74#if defined(__arm__) || defined(__aarch64__)
74#if defined(__arm__) || defined(__aarch64__) || defined(__arm64ec__)
7575#define FUNC_ALIGN \
7676 .text SEPARATOR \
7777 .balign 16 SEPARATOR
......@@ -194,6 +194,23 @@
194194#else
195195#define WIDE(op) op
196196#endif
197
198#if defined(__ARM_FEATURE_PAC_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT)
199#define PACBTI_LANDING pacbti r12, lr, sp
200#elif defined(__ARM_FEATURE_PAC_DEFAULT)
201#define PACBTI_LANDING pac r12, lr, sp
202#elif defined(__ARM_FEATURE_BTI_DEFAULT)
203#define PACBTI_LANDING bti
204#else
205#define PACBTI_LANDING
206#endif
207
208#if defined(__ARM_FEATURE_PAUTH)
209#define PAC_RETURN bxaut r12, lr, sp
210#else
211#define PAC_RETURN aut r12, lr, sp SEPARATOR bx lr
212#endif
213
197214#else // !defined(__arm)
198215#define DECLARE_FUNC_ENCODING
199216#define DEFINE_CODE_STATE
......@@ -208,6 +225,16 @@
208225#define GLUE4(a, b, c, d) GLUE4_(a, b, c, d)
209226
210227#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
228#ifndef __arm64ec__
229#define FUNC_SYMBOL(name) name
230#else
231// On ARM64EC, function names and calls (but not address-taking or data symbol
232// references) use symbols prefixed with "#".
233#define QUOTE(a) #a
234#define STR(a) QUOTE(a)
235#define HASH #
236#define FUNC_SYMBOL(name) STR(GLUE2(HASH, name))
237#endif
211238
212239#ifdef VISIBILITY_HIDDEN
213240#define DECLARE_SYMBOL_VISIBILITY(name) \
......@@ -222,54 +249,54 @@
222249#define DEFINE_COMPILERRT_FUNCTION(name) \
223250 DEFINE_CODE_STATE \
224251 FILE_LEVEL_DIRECTIVE SEPARATOR \
225 .globl SYMBOL_NAME(name) SEPARATOR \
252 .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
226253 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
227254 DECLARE_SYMBOL_VISIBILITY(name) \
228255 DECLARE_FUNC_ENCODING \
229 SYMBOL_NAME(name):
256 FUNC_SYMBOL(SYMBOL_NAME(name)):
230257
231258#define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \
232259 DEFINE_CODE_STATE \
233260 FILE_LEVEL_DIRECTIVE SEPARATOR \
234 .globl SYMBOL_NAME(name) SEPARATOR \
261 .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
235262 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
236263 DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \
237264 .thumb_func SEPARATOR \
238 SYMBOL_NAME(name):
265 FUNC_SYMBOL(SYMBOL_NAME(name)):
239266
240267#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \
241268 DEFINE_CODE_STATE \
242269 FILE_LEVEL_DIRECTIVE SEPARATOR \
243 .globl SYMBOL_NAME(name) SEPARATOR \
270 .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
244271 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
245272 HIDDEN(SYMBOL_NAME(name)) SEPARATOR \
246273 DECLARE_FUNC_ENCODING \
247 SYMBOL_NAME(name):
274 FUNC_SYMBOL(SYMBOL_NAME(name)):
248275
249276#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \
250277 DEFINE_CODE_STATE \
251 .globl name SEPARATOR \
278 .globl FUNC_SYMBOL(name) SEPARATOR \
252279 SYMBOL_IS_FUNC(name) SEPARATOR \
253280 HIDDEN(name) SEPARATOR \
254281 DECLARE_FUNC_ENCODING \
255 name:
282 FUNC_SYMBOL(name):
256283
257284#define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \
258285 DEFINE_CODE_STATE \
259286 FUNC_ALIGN \
260 .globl name SEPARATOR \
287 .globl FUNC_SYMBOL(name) SEPARATOR \
261288 SYMBOL_IS_FUNC(name) SEPARATOR \
262 DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) SEPARATOR \
289 DECLARE_SYMBOL_VISIBILITY_UNMANGLED(FUNC_SYMBOL(name)) SEPARATOR \
263290 DECLARE_FUNC_ENCODING \
264 name: \
291 FUNC_SYMBOL(name): \
265292 SEPARATOR CFI_START \
266293 SEPARATOR BTI_C
267294
268295#define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \
269 .globl SYMBOL_NAME(name) SEPARATOR \
296 .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
270297 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
271298 DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \
272 .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR
299 .set FUNC_SYMBOL(SYMBOL_NAME(name)), FUNC_SYMBOL(target) SEPARATOR
273300
274301#if defined(__ARM_EABI__)
275302#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \
lib/libtsan/interception/interception.h+21-6
......@@ -19,7 +19,7 @@
1919
2020#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \
2121 !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
22 !SANITIZER_SOLARIS
22 !SANITIZER_SOLARIS && !SANITIZER_HAIKU && !SANITIZER_AIX
2323# error "Interception doesn't work on this operating system."
2424#endif
2525
......@@ -168,6 +168,16 @@ const interpose_substitution substitution_##func_name[] \
168168 extern "C" ret_type func(__VA_ARGS__);
169169# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \
170170 extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
171#elif SANITIZER_AIX
172# define WRAP(x) __interceptor_##x
173# define TRAMPOLINE(x) WRAP(x)
174// # define WRAPPER_NAME(x) "__interceptor_" #x
175# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
176// AIX's linker will not select the weak symbol, so don't use weak for the
177// interceptors.
178# define DECLARE_WRAPPER(ret_type, func, ...) \
179 extern "C" ret_type func(__VA_ARGS__) \
180 __attribute__((alias("__interceptor_" #func), visibility("default")));
171181#elif !SANITIZER_FUCHSIA // LINUX, FREEBSD, NETBSD, SOLARIS
172182# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
173183# if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT
......@@ -367,12 +377,17 @@ inline void DoesNotSupportStaticLinking() {}
367377
368378#define INCLUDED_FROM_INTERCEPTION_LIB
369379
370#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
371 SANITIZER_SOLARIS
380#if SANITIZER_AIX
381# include "interception_aix.h"
382# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_AIX(func)
383# define INTERCEPT_FUNCTION_VER(func, symver) INTERCEPT_FUNCTION_AIX(func)
372384
373# include "interception_linux.h"
374# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
375# define INTERCEPT_FUNCTION_VER(func, symver) \
385#elif SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
386 SANITIZER_SOLARIS || SANITIZER_HAIKU
387
388# include "interception_linux.h"
389# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
390# define INTERCEPT_FUNCTION_VER(func, symver) \
376391 INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver)
377392#elif SANITIZER_APPLE
378393# include "interception_mac.h"
lib/libtsan/interception/interception_aix.cpp created+45
......@@ -0,0 +1,45 @@
1//===-- interception_aix.cpp ------------------------------------*- 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 a part of AddressSanitizer, an address sanity checker.
10//
11// AIX-specific interception methods.
12//===----------------------------------------------------------------------===//
13
14#include "interception.h"
15#include "sanitizer_common/sanitizer_common.h"
16
17#if SANITIZER_AIX
18
19# include <dlfcn.h> // for dlsym()
20
21namespace __interception {
22
23static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
24 // AIX dlsym can only defect the functions that are exported, so
25 // on AIX, we can not intercept some basic functions like memcpy.
26 // FIXME: if we are going to ship dynamic asan library, we may need to search
27 // all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed.
28 void *addr = dlsym(RTLD_NEXT, name);
29
30 // In case `name' is not loaded, dlsym ends up finding the actual wrapper.
31 // We don't want to intercept the wrapper and have it point to itself.
32 if ((uptr)addr == wrapper_addr)
33 addr = nullptr;
34 return addr;
35}
36
37bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
38 uptr wrapper) {
39 void *addr = GetFuncAddr(name, wrapper);
40 *ptr_to_real = (uptr)addr;
41 return addr && (func == wrapper);
42}
43
44} // namespace __interception
45#endif // SANITIZER_AIX
lib/libtsan/interception/interception_aix.h created+36
......@@ -0,0 +1,36 @@
1//===-- interception_aix.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 a part of AddressSanitizer, an address sanity checker.
10//
11// AIX-specific interception methods.
12//===----------------------------------------------------------------------===//
13
14#if SANITIZER_AIX
15
16# if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
17# error \
18 "interception_aix.h should be included from interception library only"
19# endif
20
21# ifndef INTERCEPTION_AIX_H
22# define INTERCEPTION_AIX_H
23
24namespace __interception {
25bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
26 uptr wrapper);
27} // namespace __interception
28
29# define INTERCEPT_FUNCTION_AIX(func) \
30 ::__interception::InterceptFunction( \
31 #func, (::__interception::uptr *)&REAL(func), \
32 (::__interception::uptr) & (func), \
33 (::__interception::uptr) & WRAP(func))
34
35# endif // INTERCEPTION_AIX_H
36#endif // SANITIZER_AIX
lib/libtsan/interception/interception_linux.cpp+2-2
......@@ -14,7 +14,7 @@
1414#include "interception.h"
1515
1616#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
17 SANITIZER_SOLARIS
17 SANITIZER_SOLARIS || SANITIZER_HAIKU
1818
1919#include <dlfcn.h> // for dlsym() and dlvsym()
2020
......@@ -80,4 +80,4 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
8080} // namespace __interception
8181
8282#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
83 // SANITIZER_SOLARIS
83 // SANITIZER_SOLARIS || SANITIZER_HAIKU
lib/libtsan/interception/interception_linux.h+2-2
......@@ -12,7 +12,7 @@
1212//===----------------------------------------------------------------------===//
1313
1414#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
15 SANITIZER_SOLARIS
15 SANITIZER_SOLARIS || SANITIZER_HAIKU
1616
1717#if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
1818# error interception_linux.h should be included from interception library only
......@@ -52,4 +52,4 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
5252
5353#endif // INTERCEPTION_LINUX_H
5454#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
55 // SANITIZER_SOLARIS
55 // SANITIZER_SOLARIS || SANITIZER_HAIKU
lib/libtsan/interception/interception_win.cpp+8-1
......@@ -646,6 +646,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
646646 case 0xC033: // 33 C0 : xor eax, eax
647647 case 0xC933: // 33 C9 : xor ecx, ecx
648648 case 0xD233: // 33 D2 : xor edx, edx
649 case 0x9066: // 66 90 : xchg %ax,%ax (Two-byte NOP)
649650 case 0xDB84: // 84 DB : test bl,bl
650651 case 0xC084: // 84 C0 : test al,al
651652 case 0xC984: // 84 C9 : test cl,cl
......@@ -726,7 +727,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
726727 case 0x5541: // push r13
727728 case 0x5641: // push r14
728729 case 0x5741: // push r15
729 case 0x9066: // Two-byte NOP
730730 case 0xc084: // test al, al
731731 case 0x018a: // mov al, byte ptr [rcx]
732732 return 2;
......@@ -743,6 +743,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
743743 case 0x058B: // 8B 05 XX XX XX XX : mov eax, dword ptr [XX XX XX XX]
744744 if (rel_offset)
745745 *rel_offset = 2;
746 FALLTHROUGH;
746747 case 0xB841: // 41 B8 XX XX XX XX : mov r8d, XX XX XX XX
747748 return 6;
748749
......@@ -753,6 +754,12 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
753754 case 0x7B81: // 81 7B YY XX XX XX XX cmp DWORD PTR [rbx+YY], XX XX XX XX
754755 case 0x7981: // 81 79 YY XX XX XX XX cmp dword ptr [rcx+YY], XX XX XX XX
755756 return 7;
757
758 case 0xb848: // 48 b8 XX XX XX XX XX XX XX XX :
759 // movabsq XX XX XX XX XX XX XX XX, rax
760 case 0xba48: // 48 ba XX XX XX XX XX XX XX XX :
761 // movabsq XX XX XX XX XX XX XX XX, rdx
762 return 10;
756763 }
757764
758765 switch (0x00FFFFFF & *(u32 *)address) {
lib/libtsan/sanitizer_common/sanitizer_allocator_internal.h+1-1
......@@ -23,7 +23,7 @@ namespace __sanitizer {
2323typedef CompactSizeClassMap InternalSizeClassMap;
2424
2525struct AP32 {
26 static const uptr kSpaceBeg = 0;
26 static const uptr kSpaceBeg = SANITIZER_MMAP_BEGIN;
2727 static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
2828 static const uptr kMetadataSize = 0;
2929 typedef InternalSizeClassMap SizeClassMap;
lib/libtsan/sanitizer_common/sanitizer_allocator_local_cache.h+1-1
......@@ -166,7 +166,7 @@ struct SizeClassAllocator32LocalCache {
166166 DCHECK_GT(c->count, 0);
167167 }
168168 void *res = c->batch[--c->count];
169 PREFETCH(c->batch[c->count - 1]);
169 PREFETCH(c->batch[c->count > 0 ? c->count - 1 : 0]);
170170 stats_.Add(AllocatorStatAllocated, c->class_size);
171171 return res;
172172 }
lib/libtsan/sanitizer_common/sanitizer_atomic_clang.h+15
......@@ -14,6 +14,18 @@
1414#ifndef SANITIZER_ATOMIC_CLANG_H
1515#define SANITIZER_ATOMIC_CLANG_H
1616
17// Helper to suppress warnings related to 8-byte atomic accesses when the target
18// is 32-bit AIX (where such accesses use libatomic).
19#if defined(_AIX) && !defined(__powerpc64__) && defined(__clang__)
20# define SANITIZER_IGNORE_ATOMIC_ALIGNMENT_BEGIN \
21 _Pragma("clang diagnostic push") \
22 _Pragma("clang diagnostic ignored \"-Watomic-alignment\"")
23# define SANITIZER_IGNORE_ATOMIC_ALIGNMENT_END _Pragma("clang diagnostic pop")
24#else
25# define SANITIZER_IGNORE_ATOMIC_ALIGNMENT_BEGIN
26# define SANITIZER_IGNORE_ATOMIC_ALIGNMENT_END
27#endif
28
1729namespace __sanitizer {
1830
1931// We use the compiler builtin atomic operations for loads and stores, which
......@@ -35,6 +47,7 @@ inline void proc_yield(int cnt) {
3547#endif
3648}
3749
50SANITIZER_IGNORE_ATOMIC_ALIGNMENT_BEGIN
3851template <typename T>
3952inline typename T::Type atomic_load(const volatile T *a, memory_order mo) {
4053 DCHECK(mo == memory_order_relaxed || mo == memory_order_consume ||
......@@ -92,6 +105,8 @@ inline bool atomic_compare_exchange_weak(volatile T *a, typename T::Type *cmp,
92105 return atomic_compare_exchange_strong(a, cmp, xchg, mo);
93106}
94107
108SANITIZER_IGNORE_ATOMIC_ALIGNMENT_END
109
95110} // namespace __sanitizer
96111
97112#undef ATOMIC_ORDER
lib/libtsan/sanitizer_common/sanitizer_common.h+2-19
......@@ -166,7 +166,7 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
166166
167167// Used to check if we can map shadow memory to a fixed location.
168168bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
169// Releases memory pages entirely within the [beg, end] address range. Noop if
169// Releases memory pages entirely within the [beg, end) address range. Noop if
170170// the provided range does not contain at least one entire page.
171171void ReleaseMemoryPagesToOS(uptr beg, uptr end);
172172void IncreaseTotalMmap(uptr size);
......@@ -925,12 +925,6 @@ class ListOfModules {
925925// Callback type for iterating over a set of memory ranges.
926926typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
927927
928enum AndroidApiLevel {
929 ANDROID_NOT_ANDROID = 0,
930 ANDROID_LOLLIPOP_MR1 = 22,
931 ANDROID_POST_LOLLIPOP = 23
932};
933
934928void WriteToSyslog(const char *buffer);
935929
936930#if defined(SANITIZER_WINDOWS) && defined(_MSC_VER) && !defined(__clang__)
......@@ -963,19 +957,8 @@ inline void AndroidLogInit() {}
963957inline void SetAbortMessage(const char *) {}
964958#endif
965959
966#if SANITIZER_ANDROID
967void SanitizerInitializeUnwinder();
968AndroidApiLevel AndroidGetApiLevel();
969#else
970inline void AndroidLogWrite(const char *buffer_unused) {}
971inline void SanitizerInitializeUnwinder() {}
972inline AndroidApiLevel AndroidGetApiLevel() { return ANDROID_NOT_ANDROID; }
973#endif
974
975960inline uptr GetPthreadDestructorIterations() {
976#if SANITIZER_ANDROID
977 return (AndroidGetApiLevel() == ANDROID_LOLLIPOP_MR1) ? 8 : 4;
978#elif SANITIZER_POSIX
961#if SANITIZER_POSIX
979962 return 4;
980963#else
981964// Unused on Windows.
lib/libtsan/sanitizer_common/sanitizer_common_interceptors.inc+127-24
......@@ -481,7 +481,8 @@ INTERCEPTOR(char*, textdomain, const char *domainname) {
481481#endif
482482
483483#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP
484static inline int CharCmpX(unsigned char c1, unsigned char c2) {
484[[maybe_unused]] static inline int CharCmpX(unsigned char c1,
485 unsigned char c2) {
485486 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
486487}
487488#endif
......@@ -953,7 +954,7 @@ INTERCEPTOR(double, frexp, double x, int *exp) {
953954#define INIT_FREXP
954955#endif // SANITIZER_INTERCEPT_FREXP
955956
956#if SANITIZER_INTERCEPT_FREXPF_FREXPL
957#if SANITIZER_INTERCEPT_FREXPF
957958INTERCEPTOR(float, frexpf, float x, int *exp) {
958959 void *ctx;
959960 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
......@@ -963,6 +964,12 @@ INTERCEPTOR(float, frexpf, float x, int *exp) {
963964 return res;
964965}
965966
967# define INIT_FREXPF COMMON_INTERCEPT_FUNCTION(frexpf);
968#else
969# define INIT_FREXPF
970#endif
971
972#if SANITIZER_INTERCEPT_FREXPL
966973INTERCEPTOR(long double, frexpl, long double x, int *exp) {
967974 void *ctx;
968975 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
......@@ -972,12 +979,10 @@ INTERCEPTOR(long double, frexpl, long double x, int *exp) {
972979 return res;
973980}
974981
975#define INIT_FREXPF_FREXPL \
976 COMMON_INTERCEPT_FUNCTION(frexpf); \
977 COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
982# define INIT_FREXPL COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
978983#else
979#define INIT_FREXPF_FREXPL
980#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
984# define INIT_FREXPL
985#endif
981986
982987#if SI_POSIX
983988static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
......@@ -1346,7 +1351,8 @@ INTERCEPTOR(unsigned long, time, unsigned long *t) {
13461351#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
13471352static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
13481353 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1349#if !SANITIZER_SOLARIS
1354// AIX tm struct does not have tm_zone field.
1355# if !SANITIZER_SOLARIS && !SANITIZER_AIX
13501356 if (tm->tm_zone) {
13511357 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
13521358 // can point to shared memory and tsan would report a data race.
......@@ -1731,10 +1737,12 @@ INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
17311737VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
17321738#endif
17331739
1740# if SANITIZER_INTERCEPT_VASPRINTF
17341741INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
17351742VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
1743# endif
17361744
1737#if SANITIZER_INTERCEPT_ISOC99_PRINTF
1745# if SANITIZER_INTERCEPT_ISOC99_PRINTF
17381746INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
17391747VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
17401748
......@@ -1783,10 +1791,12 @@ INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
17831791FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)
17841792#endif
17851793
1794# if SANITIZER_INTERCEPT_ASPRINTF
17861795INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
17871796FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
1797# endif
17881798
1789#if SANITIZER_INTERCEPT_ISOC99_PRINTF
1799# if SANITIZER_INTERCEPT_ISOC99_PRINTF
17901800INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
17911801FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
17921802
......@@ -1807,17 +1817,24 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
18071817#endif // SANITIZER_INTERCEPT_PRINTF
18081818
18091819#if SANITIZER_INTERCEPT_PRINTF
1810#define INIT_PRINTF \
1811 COMMON_INTERCEPT_FUNCTION_LDBL(printf); \
1812 COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \
1813 COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \
1814 COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \
1815 COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \
1816 COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \
1817 COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \
1818 COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
1819 COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \
1820 COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
1820# define INIT_PRINTF_COMMON \
1821 COMMON_INTERCEPT_FUNCTION_LDBL(printf); \
1822 COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \
1823 COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \
1824 COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \
1825 COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \
1826 COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \
1827 COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
1828 COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
1829# if !SANITIZER_AIX
1830// AIX does not have [v]asprintf.
1831# define INIT_PRINTF_EXTRA \
1832 COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \
1833 COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf);
1834# else
1835# define INIT_PRINTF_EXTRA
1836# endif
1837# define INIT_PRINTF INIT_PRINTF_COMMON INIT_PRINTF_EXTRA
18211838#else
18221839#define INIT_PRINTF
18231840#endif
......@@ -1855,6 +1872,22 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
18551872#define INIT_ISOC99_PRINTF
18561873#endif
18571874
1875#if SANITIZER_INTERCEPT_SETPROCTITLE
1876INTERCEPTOR(void, setproctitle, const char *fmt, ...) {
1877 void *ctx;
1878 va_list ap;
1879 va_start(ap, fmt);
1880 COMMON_INTERCEPTOR_ENTER(ctx, setproctitle, fmt, ap);
1881 if (common_flags()->check_printf)
1882 printf_common(ctx, fmt, ap);
1883 REAL(setproctitle)(fmt, ap);
1884 va_end(ap);
1885}
1886# define INIT_SETPROCTITLE COMMON_INTERCEPT_FUNCTION(setproctitle);
1887#else
1888# define INIT_SETPROCTITLE
1889#endif
1890
18581891#if SANITIZER_INTERCEPT_IOCTL
18591892#include "sanitizer_common_interceptors_ioctl.inc"
18601893#include "sanitizer_interceptors_ioctl_netbsd.inc"
......@@ -3901,7 +3934,7 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
39013934 if (res != ((SIZE_T)-1)) {
39023935 CHECK_LE(res, sizeof(local_dest));
39033936 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3904 REAL(memcpy)(dest, local_dest, res);
3937 internal_memcpy(dest, local_dest, res);
39053938 }
39063939 return res;
39073940}
......@@ -3923,7 +3956,7 @@ INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
39233956 if (res != -1) {
39243957 CHECK_LE(res, sizeof(local_dest));
39253958 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3926 REAL(memcpy)(dest, local_dest, res);
3959 internal_memcpy(dest, local_dest, res);
39273960 }
39283961 return res;
39293962}
......@@ -10263,6 +10296,71 @@ INTERCEPTOR(SSIZE_T, freadlink, int fd, char *buf, SIZE_T bufsiz) {
1026310296# define INIT_FREADLINK
1026410297#endif
1026510298
10299#if SANITIZER_INTERCEPT_GETSERVENT_R || SANITIZER_INTERCEPT_GETSERVBYNAME_R || \
10300 SANITIZER_INTERCEPT_GETSERVBYPORT_R
10301
10302UNUSED static void HandleGetServentReentrantResult(
10303 void *ctx, int res, struct __sanitizer_servent *result_buf, char *buf,
10304 SIZE_T buflen, struct __sanitizer_servent **result) {
10305 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)result, sizeof(void *));
10306 if (res)
10307 return;
10308 if (*result) {
10309 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)*result,
10310 sizeof(__sanitizer_servent));
10311 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
10312 }
10313}
10314
10315#endif
10316
10317#if SANITIZER_INTERCEPT_GETSERVENT_R
10318INTERCEPTOR(int, getservent_r, struct __sanitizer_servent *result_buf,
10319 char *buf, SIZE_T buflen, struct __sanitizer_servent **result) {
10320 void *ctx;
10321 COMMON_INTERCEPTOR_ENTER(ctx, getservent_r, result_buf, buf, buflen, result);
10322 int res = REAL(getservent_r)(result_buf, buf, buflen, result);
10323 HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);
10324 return res;
10325}
10326# define INIT_GETSERVENT_R COMMON_INTERCEPT_FUNCTION(getservent_r)
10327#else
10328# define INIT_GETSERVENT_R
10329#endif
10330
10331#if SANITIZER_INTERCEPT_GETSERVBYNAME_R
10332INTERCEPTOR(int, getservbyname_r, const char *name, const char *proto,
10333 struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,
10334 struct __sanitizer_servent **result) {
10335 void *ctx;
10336 COMMON_INTERCEPTOR_ENTER(ctx, getservbyname_r, name, proto, result_buf, buf,
10337 buflen, result);
10338 COMMON_INTERCEPTOR_READ_STRING(ctx, name, internal_strlen(name));
10339 int res = REAL(getservbyname_r)(name, proto, result_buf, buf, buflen, result);
10340 HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);
10341 return res;
10342}
10343# define INIT_GETSERVBYNAME_R COMMON_INTERCEPT_FUNCTION(getservbyname_r)
10344#else
10345# define INIT_GETSERVBYNAME_R
10346#endif
10347
10348#if SANITIZER_INTERCEPT_GETSERVBYPORT_R
10349INTERCEPTOR(int, getservbyport_r, int port, const char *proto,
10350 struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,
10351 struct __sanitizer_servent **result) {
10352 void *ctx;
10353 COMMON_INTERCEPTOR_ENTER(ctx, getservbyport_r, port, proto, result_buf, buf,
10354 buflen, result);
10355 int res = REAL(getservbyport_r)(port, proto, result_buf, buf, buflen, result);
10356 HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);
10357 return res;
10358}
10359# define INIT_GETSERVBYPORT_R COMMON_INTERCEPT_FUNCTION(getservbyport_r)
10360#else
10361# define INIT_GETSERVBYPORT_R
10362#endif
10363
1026610364#include "sanitizer_common_interceptors_netbsd_compat.inc"
1026710365
1026810366namespace __sanitizer {
......@@ -10328,8 +10426,10 @@ static void InitializeCommonInterceptors() {
1032810426 INIT_PRINTF;
1032910427 INIT_PRINTF_L;
1033010428 INIT_ISOC99_PRINTF;
10429 INIT_SETPROCTITLE;
1033110430 INIT_FREXP;
10332 INIT_FREXPF_FREXPL;
10431 INIT_FREXPF;
10432 INIT_FREXPL;
1033310433 INIT_GETPWNAM_AND_FRIENDS;
1033410434 INIT_GETPWNAM_R_AND_FRIENDS;
1033510435 INIT_GETPWENT;
......@@ -10587,4 +10687,7 @@ static void InitializeCommonInterceptors() {
1058710687 INIT_FREADLINK;
1058810688
1058910689 INIT___PRINTF_CHK;
10690 INIT_GETSERVENT_R;
10691 INIT_GETSERVBYNAME_R;
10692 INIT_GETSERVBYPORT_R;
1059010693}
lib/libtsan/sanitizer_common/sanitizer_common_interceptors_format.inc+4
......@@ -67,6 +67,10 @@ static const char *maybe_parse_length_modifier(const char *p, char ll[2]) {
6767
6868// Returns true if the character is an integer conversion specifier.
6969static bool format_is_integer_conv(char c) {
70#if SANITIZER_GLIBC
71 if (char_is_one_of(c, "bB"))
72 return true;
73#endif
7074 return char_is_one_of(c, "diouxXn");
7175}
7276
lib/libtsan/sanitizer_common/sanitizer_common_interceptors_ioctl.inc+13-7
......@@ -48,35 +48,41 @@ static void ioctl_table_fill() {
4848 ++ioctl_table_size; \
4949 }
5050
51 _(FIONBIO, READ, sizeof(int));
52#if !SANITIZER_HAIKU
5153 _(FIOASYNC, READ, sizeof(int));
5254 _(FIOCLEX, NONE, 0);
5355 _(FIOGETOWN, WRITE, sizeof(int));
54 _(FIONBIO, READ, sizeof(int));
5556 _(FIONCLEX, NONE, 0);
5657 _(FIOSETOWN, READ, sizeof(int));
58#endif
5759 _(SIOCATMARK, WRITE, sizeof(int));
5860 _(SIOCGIFCONF, CUSTOM, 0);
5961 _(SIOCGPGRP, WRITE, sizeof(int));
6062 _(SIOCSPGRP, READ, sizeof(int));
61#if !SANITIZER_SOLARIS
63#if !SANITIZER_SOLARIS && !SANITIZER_HAIKU
6264 _(TIOCCONS, NONE, 0);
6365#endif
64 _(TIOCEXCL, NONE, 0);
66#if !SANITIZER_HAIKU
6567 _(TIOCGETD, WRITE, sizeof(int));
68 _(TIOCNOTTY, NONE, 0);
69 _(TIOCPKT, READ, sizeof(int));
70 _(TIOCSETD, READ, sizeof(int));
71 _(TIOCSTI, READ, sizeof(char));
72#endif
73 _(TIOCEXCL, NONE, 0);
6674 _(TIOCGPGRP, WRITE, pid_t_sz);
6775 _(TIOCGWINSZ, WRITE, struct_winsize_sz);
6876 _(TIOCMBIC, READ, sizeof(int));
6977 _(TIOCMBIS, READ, sizeof(int));
7078 _(TIOCMGET, WRITE, sizeof(int));
7179 _(TIOCMSET, READ, sizeof(int));
72 _(TIOCNOTTY, NONE, 0);
7380 _(TIOCNXCL, NONE, 0);
7481 _(TIOCOUTQ, WRITE, sizeof(int));
75 _(TIOCPKT, READ, sizeof(int));
82# if !SANITIZER_AIX
7683 _(TIOCSCTTY, NONE, 0);
77 _(TIOCSETD, READ, sizeof(int));
84# endif
7885 _(TIOCSPGRP, READ, pid_t_sz);
79 _(TIOCSTI, READ, sizeof(char));
8086 _(TIOCSWINSZ, READ, struct_winsize_sz);
8187
8288#if !SANITIZER_IOS
lib/libtsan/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc+5-3
......@@ -33,11 +33,13 @@
3333
3434// Platform-specific options.
3535#if SANITIZER_APPLE
36#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
36# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
3737#elif SANITIZER_WINDOWS64
38#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
38# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
39#elif SANITIZER_AIX
40# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
3941#else
40#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
42# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
4143#endif // SANITIZER_APPLE
4244
4345#ifndef COMMON_INTERCEPTOR_MEMSET_IMPL
lib/libtsan/sanitizer_common/sanitizer_common_syscalls.inc+22
......@@ -3205,6 +3205,28 @@ POST_SYSCALL(futex)
32053205 COMMON_SYSCALL_BLOCKING_END();
32063206}
32073207
3208PRE_SYSCALL(copy_file_range)
3209(int fdin, __sanitizer___kernel_off_t *offin, int fdout,
3210 __sanitizer___kernel_off_t *offout, SIZE_T size, unsigned int flags) {
3211 if (offin != nullptr) {
3212 PRE_READ(offin, sizeof(*offin));
3213 }
3214 if (offout != nullptr) {
3215 PRE_READ(offout, sizeof(*offout));
3216 }
3217}
3218
3219POST_SYSCALL(copy_file_range)
3220(SSIZE_T, int fdin, __sanitizer___kernel_off_t *offin, int fdout,
3221 __sanitizer___kernel_off_t *offout, SIZE_T size, unsigned int flags) {
3222 if (offin != nullptr) {
3223 POST_WRITE(offin, sizeof(*offin));
3224 }
3225 if (offout != nullptr) {
3226 POST_WRITE(offout, sizeof(*offout));
3227 }
3228}
3229
32083230} // extern "C"
32093231
32103232# undef PRE_SYSCALL
lib/libtsan/sanitizer_common/sanitizer_errno.h+2
......@@ -29,6 +29,8 @@
2929# define __errno_location ___errno
3030#elif SANITIZER_WINDOWS
3131# define __errno_location _errno
32#elif SANITIZER_HAIKU
33# define __errno_location _errnop
3234#endif
3335
3436extern "C" int *__errno_location();
lib/libtsan/sanitizer_common/sanitizer_errno_codes.h+15-6
......@@ -21,12 +21,21 @@
2121
2222namespace __sanitizer {
2323
24#define errno_ENOMEM 12
25#define errno_EBUSY 16
26#define errno_EINVAL 22
27#define errno_ERANGE 34
28#define errno_ENAMETOOLONG 36
29#define errno_ENOSYS 38
24#ifdef __HAIKU__
25# define errno_ENOMEM (0x80000000)
26# define errno_EBUSY (0x80000000 + 14)
27# define errno_EINVAL (0x80000000 + 5)
28# define errno_ERANGE (0x80007000 + 17)
29# define errno_ENAMETOOLONG (0x80000000 + 0x6004)
30# define errno_ENOSYS (0x80007009)
31#else
32# define errno_ENOMEM 12
33# define errno_EBUSY 16
34# define errno_EINVAL 22
35# define errno_ERANGE 34
36# define errno_ENAMETOOLONG 36
37# define errno_ENOSYS 38
38#endif
3039
3140// Those might not present or their value differ on different platforms.
3241extern const int errno_EOWNERDEAD;
lib/libtsan/sanitizer_common/sanitizer_file.cpp+67-3
......@@ -96,12 +96,76 @@ static void RecursiveCreateParentDirs(char *path) {
9696 }
9797}
9898
99/// Parse the report path \p pattern and copy the parsed path to \p dest.
100///
101/// * `%%` becomes `%`
102/// * `%H` expands to the environment variable `HOME`
103/// * `%t` expands to the environment variable `TMPDIR`
104/// * `%p` expands to the process ID (PID)
105static void ParseAndSetPath(const char *pattern, char *dest,
106 const uptr dest_size) {
107 CHECK(pattern);
108 CHECK(dest);
109 CHECK_GE(dest_size, 1);
110 dest[0] = '\0';
111 uptr next_substr_start_idx = 0;
112 for (uptr i = 0; i < internal_strlen(pattern) - 1; i++) {
113 if (pattern[i] != '%')
114 continue;
115 int bytes_to_copy = i - next_substr_start_idx;
116 // Copy over previous substring.
117 CHECK_LT(internal_strlcat(dest, pattern + next_substr_start_idx,
118 internal_strlen(dest) + bytes_to_copy + 1),
119 dest_size);
120 const char *str_to_concat;
121 switch (pattern[++i]) {
122 case '%':
123 str_to_concat = "%";
124 break;
125 case 'H':
126 str_to_concat = GetEnv("HOME");
127 break;
128 case 't':
129 str_to_concat = GetEnv("TMPDIR");
130 break;
131 case 'p': {
132 // Use printf directly to write the PID since it's not a static string.
133 int remaining_capacity = dest_size - internal_strlen(dest);
134 int bytes_copied =
135 internal_snprintf(dest + internal_strlen(dest), remaining_capacity,
136 "%ld", internal_getpid());
137 CHECK_GT(bytes_copied, 0);
138 CHECK_LT(bytes_copied, remaining_capacity);
139 str_to_concat = "";
140 break;
141 }
142 default: {
143 // Invalid pattern: fallback to original pattern.
144 const char *message = "ERROR: Unexpected pattern: ";
145 WriteToFile(kStderrFd, message, internal_strlen(message));
146 WriteToFile(kStderrFd, pattern, internal_strlen(pattern));
147 WriteToFile(kStderrFd, "\n", internal_strlen("\n"));
148 CHECK_LT(internal_strlcpy(dest, pattern, dest_size), dest_size);
149 return;
150 }
151 }
152 CHECK(str_to_concat);
153 CHECK_LT(internal_strlcat(dest, str_to_concat, dest_size), dest_size);
154 next_substr_start_idx = i + 1;
155 }
156 CHECK_LT(internal_strlcat(dest, pattern + next_substr_start_idx, dest_size),
157 dest_size);
158}
159
99160void ReportFile::SetReportPath(const char *path) {
100161 if (path) {
101162 uptr len = internal_strlen(path);
102163 if (len > sizeof(path_prefix) - 100) {
103 Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n", path[0], path[1],
104 path[2], path[3], path[4], path[5], path[6], path[7]);
164 const char *message = "ERROR: Path is too long: ";
165 WriteToFile(kStderrFd, message, internal_strlen(message));
166 WriteToFile(kStderrFd, path, 8);
167 message = "...\n";
168 WriteToFile(kStderrFd, message, internal_strlen(message));
105169 Die();
106170 }
107171 }
......@@ -115,7 +179,7 @@ void ReportFile::SetReportPath(const char *path) {
115179 } else if (internal_strcmp(path, "stdout") == 0) {
116180 fd = kStdoutFd;
117181 } else {
118 internal_snprintf(path_prefix, kMaxPathLength, "%s", path);
182 ParseAndSetPath(path, path_prefix, kMaxPathLength);
119183 RecursiveCreateParentDirs(path_prefix);
120184 }
121185}
lib/libtsan/sanitizer_common/sanitizer_fuchsia.cpp+2
......@@ -547,6 +547,8 @@ void __sanitizer_startup_hook(int argc, char **argv, char **envp,
547547 __sanitizer::StoredEnviron = envp;
548548 __sanitizer::MainThreadStackBase = reinterpret_cast<uintptr_t>(stack_base);
549549 __sanitizer::MainThreadStackSize = stack_size;
550
551 EarlySanitizerInit();
550552}
551553
552554void __sanitizer_set_report_path(const char *path) {
lib/libtsan/sanitizer_common/sanitizer_fuchsia.h+7
......@@ -32,6 +32,13 @@ struct MemoryMappingLayoutData {
3232
3333void InitShadowBounds();
3434
35// Individual sanitizers can define this to explicitly run something at the end
36// of `__sanitizer_startup_hook`. This can be useful if a sanitizer needs to do
37// extra work after the common startup hook code is called and before module
38// ctors are invoked. For example, hwasan can explicitly call its initializing
39// function here so it can be set up before libc extensions are initialized.
40void EarlySanitizerInit();
41
3542} // namespace __sanitizer
3643
3744#endif // SANITIZER_FUCHSIA
lib/libtsan/sanitizer_common/sanitizer_haiku.cpp created+361
......@@ -0,0 +1,361 @@
1//===-- sanitizer_haiku.cpp -----------------------------------------------===//
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 Sanitizer run-time libraries and implements
10// Haiku-specific functions from sanitizer_libc.h.
11//===----------------------------------------------------------------------===//
12
13#include "sanitizer_platform.h"
14
15#if SANITIZER_HAIKU
16
17# include "sanitizer_common.h"
18# include "sanitizer_flags.h"
19# include "sanitizer_getauxval.h"
20# include "sanitizer_internal_defs.h"
21# include "sanitizer_libc.h"
22# include "sanitizer_linux.h"
23# include "sanitizer_mutex.h"
24# include "sanitizer_placement_new.h"
25# include "sanitizer_procmaps.h"
26
27# include <sys/param.h>
28# include <sys/types.h>
29
30# include <sys/mman.h>
31# include <sys/resource.h>
32# include <sys/stat.h>
33# include <sys/time.h>
34
35# include <dlfcn.h>
36# include <errno.h>
37# include <fcntl.h>
38# include <limits.h>
39# include <link.h>
40# include <pthread.h>
41# include <sched.h>
42# include <signal.h>
43# include <unistd.h>
44
45# include "system/vm_defs.h"
46# include "system/syscalls.h"
47# include "shared/syscall_utils.h"
48
49namespace __sanitizer {
50
51static void *GetRealLibcAddress(const char *symbol) {
52 void *real = dlsym(RTLD_NEXT, symbol);
53 if (!real)
54 real = dlsym(RTLD_DEFAULT, symbol);
55 if (!real) {
56 Printf("GetRealLibcAddress failed for symbol=%s", symbol);
57 Die();
58 }
59 return real;
60}
61
62# define _REAL(func, ...) real##_##func(__VA_ARGS__)
63# define DEFINE__REAL(ret_type, func, ...) \
64 static ret_type (*real_##func)(__VA_ARGS__) = NULL; \
65 if (!real_##func) { \
66 real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \
67 } \
68 CHECK(real_##func);
69
70// --------------- sanitizer_libc.h
71uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
72 u64 offset) {
73 if ((flags & MAP_ANONYMOUS) != 0)
74 fd = -1;
75
76 int mapping =
77 (flags & MAP_SHARED) != 0 ? REGION_NO_PRIVATE_MAP : REGION_PRIVATE_MAP;
78
79 uint32 addressSpec;
80 if ((flags & MAP_FIXED) != 0)
81 addressSpec = B_EXACT_ADDRESS;
82 else if (addr != NULL)
83 addressSpec = B_BASE_ADDRESS;
84 else
85 addressSpec = B_RANDOMIZED_ANY_ADDRESS;
86
87 uint32 areaProtection = 0;
88 if ((prot & PROT_READ) != 0)
89 areaProtection |= B_READ_AREA;
90 if ((prot & PROT_WRITE) != 0)
91 areaProtection |= B_WRITE_AREA;
92 if ((prot & PROT_EXEC) != 0)
93 areaProtection |= B_EXECUTE_AREA;
94
95 if ((flags & MAP_NORESERVE) != 0)
96 areaProtection |= B_OVERCOMMITTING_AREA;
97
98 area_id area = _kern_map_file("sanitizer mmap", &addr, addressSpec, length,
99 areaProtection, mapping, true, fd, offset);
100 if (area < 0)
101 RETURN_AND_SET_ERRNO(area);
102 return (uptr)addr;
103}
104
105uptr internal_munmap(void *addr, uptr length) {
106 DEFINE__REAL(int, munmap, void *a, uptr b);
107 return _REAL(munmap, addr, length);
108}
109
110uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags,
111 void *new_address) {
112 CHECK(false && "internal_mremap is unimplemented on Haiku");
113 return 0;
114}
115
116int internal_mprotect(void *addr, uptr length, int prot) {
117 DEFINE__REAL(int, mprotect, void *a, uptr b, int c);
118 return _REAL(mprotect, addr, length, prot);
119}
120
121int internal_madvise(uptr addr, uptr length, int advice) {
122 DEFINE__REAL(int, madvise, void *a, uptr b, int c);
123 return _REAL(madvise, (void *)addr, length, advice);
124}
125
126uptr internal_close(fd_t fd) {
127 CHECK(&_kern_close);
128 RETURN_AND_SET_ERRNO(_kern_close(fd));
129}
130
131uptr internal_open(const char *filename, int flags) {
132 CHECK(&_kern_open);
133 RETURN_AND_SET_ERRNO(_kern_open(-1, filename, flags, 0));
134}
135
136uptr internal_open(const char *filename, int flags, u32 mode) {
137 CHECK(&_kern_open);
138 RETURN_AND_SET_ERRNO(_kern_open(-1, filename, flags, mode));
139}
140
141uptr internal_read(fd_t fd, void *buf, uptr count) {
142 sptr res;
143 CHECK(&_kern_read);
144 HANDLE_EINTR(res, (sptr)_kern_read(fd, -1, buf, (size_t)count));
145 RETURN_AND_SET_ERRNO(res);
146 return res;
147}
148
149uptr internal_write(fd_t fd, const void *buf, uptr count) {
150 sptr res;
151 CHECK(&_kern_write);
152 HANDLE_EINTR(res, (sptr)_kern_write(fd, -1, buf, count));
153 RETURN_AND_SET_ERRNO(res);
154 return res;
155}
156
157uptr internal_ftruncate(fd_t fd, uptr size) {
158 sptr res;
159 DEFINE__REAL(int, ftruncate, int, off_t);
160 return _REAL(ftruncate, fd, size);
161 return res;
162}
163
164uptr internal_stat(const char *path, void *buf) {
165 DEFINE__REAL(int, _stat_current, const char *a, void *b);
166 return _REAL(_stat_current, path, buf);
167}
168
169uptr internal_lstat(const char *path, void *buf) {
170 DEFINE__REAL(int, _lstat_current, const char *a, void *b);
171 return _REAL(_lstat_current, path, buf);
172}
173
174uptr internal_fstat(fd_t fd, void *buf) {
175 DEFINE__REAL(int, _fstat_current, int a, void *b);
176 return _REAL(_fstat_current, fd, buf);
177}
178
179uptr internal_filesize(fd_t fd) {
180 struct stat st;
181 if (internal_fstat(fd, &st))
182 return -1;
183 return (uptr)st.st_size;
184}
185
186uptr internal_dup(int oldfd) {
187 DEFINE__REAL(int, dup, int a);
188 return _REAL(dup, oldfd);
189}
190
191uptr internal_dup2(int oldfd, int newfd) {
192 DEFINE__REAL(int, dup2, int a, int b);
193 return _REAL(dup2, oldfd, newfd);
194}
195
196uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
197 CHECK(&_kern_read_link);
198 RETURN_AND_SET_ERRNO(_kern_read_link(-1, path, buf, &bufsize));
199}
200
201uptr internal_unlink(const char *path) {
202 DEFINE__REAL(int, unlink, const char *a);
203 return _REAL(unlink, path);
204}
205
206uptr internal_rename(const char *oldpath, const char *newpath) {
207 DEFINE__REAL(int, rename, const char *a, const char *b);
208 return _REAL(rename, oldpath, newpath);
209}
210
211uptr internal_sched_yield() {
212 CHECK(&_kern_thread_yield);
213 _kern_thread_yield();
214 return 0;
215}
216
217void internal__exit(int exitcode) {
218 DEFINE__REAL(void, _exit, int a);
219 _REAL(_exit, exitcode);
220 Die(); // Unreachable.
221}
222
223void internal_usleep(u64 useconds) {
224 _kern_snooze_etc(useconds, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT, NULL);
225}
226
227uptr internal_execve(const char *filename, char *const argv[],
228 char *const envp[]) {
229 DEFINE__REAL(int, execve, const char *, char *const[], char *const[]);
230 return _REAL(execve, filename, argv, envp);
231}
232
233# if 0
234tid_t GetTid() {
235 DEFINE__REAL(int, _lwp_self);
236 return _REAL(_lwp_self);
237}
238
239int TgKill(pid_t pid, tid_t tid, int sig) {
240 DEFINE__REAL(int, _lwp_kill, int a, int b);
241 (void)pid;
242 return _REAL(_lwp_kill, tid, sig);
243}
244
245u64 NanoTime() {
246 timeval tv;
247 DEFINE__REAL(int, __gettimeofday50, void *a, void *b);
248 internal_memset(&tv, 0, sizeof(tv));
249 _REAL(__gettimeofday50, &tv, 0);
250 return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000;
251}
252# endif
253
254uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
255 DEFINE__REAL(int, __clock_gettime50, __sanitizer_clockid_t a, void *b);
256 return _REAL(__clock_gettime50, clk_id, tp);
257}
258
259uptr internal_ptrace(int request, int pid, void *addr, int data) {
260 DEFINE__REAL(int, ptrace, int a, int b, void *c, int d);
261 return _REAL(ptrace, request, pid, addr, data);
262}
263
264uptr internal_waitpid(int pid, int *status, int options) {
265 DEFINE__REAL(int, waitpid, pid_t, int *, int);
266 return _REAL(waitpid, pid, status, options);
267}
268
269uptr internal_getpid() {
270 DEFINE__REAL(int, getpid);
271 return _REAL(getpid);
272}
273
274uptr internal_getppid() {
275 DEFINE__REAL(int, getppid);
276 return _REAL(getppid);
277}
278
279int internal_dlinfo(void *handle, int request, void *p) {
280 DEFINE__REAL(int, dlinfo, void *a, int b, void *c);
281 return _REAL(dlinfo, handle, request, p);
282}
283
284uptr internal_getdents(fd_t fd, void *dirp, unsigned int count) {
285 DEFINE__REAL(int, __getdents30, int a, void *b, size_t c);
286 return _REAL(__getdents30, fd, dirp, count);
287}
288
289uptr internal_lseek(fd_t fd, OFF_T offset, int whence) {
290 CHECK(&_kern_seek);
291 off_t result = _kern_seek(fd, offset, whence);
292 if (result < 0) {
293 errno = result;
294 return -1;
295 }
296 return result;
297}
298
299uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) {
300 Printf("internal_prctl not implemented for Haiku");
301 Die();
302 return 0;
303}
304
305uptr internal_sigaltstack(const void *ss, void *oss) {
306 DEFINE__REAL(int, __sigaltstack14, const void *a, void *b);
307 return _REAL(__sigaltstack14, ss, oss);
308}
309
310int internal_fork() {
311 DEFINE__REAL(int, fork);
312 return _REAL(fork);
313}
314
315# if 0
316int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
317 uptr *oldlenp, const void *newp, uptr newlen) {
318 CHECK(&__sysctl);
319 return __sysctl(name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
320}
321# endif
322
323int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
324 const void *newp, uptr newlen) {
325 DEFINE__REAL(int, sysctlbyname, const char *a, void *b, size_t *c,
326 const void *d, size_t e);
327 return _REAL(sysctlbyname, sname, oldp, (size_t *)oldlenp, newp,
328 (size_t)newlen);
329}
330
331uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
332 __sanitizer_sigset_t *oldset) {
333 CHECK(&_kern_set_signal_mask);
334 return _kern_set_signal_mask(how, set, oldset);
335}
336
337void internal_sigfillset(__sanitizer_sigset_t *set) {
338 DEFINE__REAL(int, __sigfillset14, const void *a);
339 (void)_REAL(__sigfillset14, set);
340}
341
342void internal_sigemptyset(__sanitizer_sigset_t *set) {
343 DEFINE__REAL(int, __sigemptyset14, const void *a);
344 (void)_REAL(__sigemptyset14, set);
345}
346
347void internal_sigdelset(__sanitizer_sigset_t *set, int signo) {
348 DEFINE__REAL(int, __sigdelset14, const void *a, int b);
349 (void)_REAL(__sigdelset14, set, signo);
350}
351
352uptr internal_clone(int (*fn)(void *), void *child_stack, int flags,
353 void *arg) {
354 DEFINE__REAL(int, clone, int (*a)(void *b), void *c, int d, void *e);
355
356 return _REAL(clone, fn, child_stack, flags, arg);
357}
358
359} // namespace __sanitizer
360
361#endif
lib/libtsan/sanitizer_common/sanitizer_linux.cpp+75-68
......@@ -14,7 +14,7 @@
1414#include "sanitizer_platform.h"
1515
1616#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
17 SANITIZER_SOLARIS
17 SANITIZER_SOLARIS || SANITIZER_HAIKU
1818
1919# include "sanitizer_common.h"
2020# include "sanitizer_flags.h"
......@@ -63,15 +63,17 @@
6363# include <sched.h>
6464# include <signal.h>
6565# include <sys/mman.h>
66# if !SANITIZER_SOLARIS
66# if !SANITIZER_SOLARIS && !SANITIZER_HAIKU
6767# include <sys/ptrace.h>
6868# endif
6969# include <sys/resource.h>
7070# include <sys/stat.h>
71# include <sys/syscall.h>
71# if !SANITIZER_HAIKU
72# include <sys/syscall.h>
73# include <ucontext.h>
74# endif
7275# include <sys/time.h>
7376# include <sys/types.h>
74# include <ucontext.h>
7577# include <unistd.h>
7678
7779# if SANITIZER_LINUX
......@@ -82,6 +84,12 @@
8284# include <sys/personality.h>
8385# endif
8486
87# if SANITIZER_ANDROID && __ANDROID_API__ < 35
88// The weak `strerrorname_np` (introduced in API level 35) definition,
89// allows for checking the API level at runtime.
90extern "C" SANITIZER_WEAK_ATTRIBUTE const char *strerrorname_np(int);
91# endif
92
8593# if SANITIZER_LINUX && defined(__loongarch__)
8694# include <sys/sysmacros.h>
8795# endif
......@@ -118,6 +126,13 @@ extern struct ps_strings *__ps_strings;
118126# define environ _environ
119127# endif
120128
129# if SANITIZER_HAIKU
130# include <OS.h>
131# include <elf.h>
132# include <image.h>
133extern "C" char **__libc_argv;
134# endif
135
121136extern char **environ;
122137
123138# if SANITIZER_LINUX
......@@ -246,7 +261,7 @@ ScopedBlockSignals::~ScopedBlockSignals() { SetSigProcMask(&saved_, nullptr); }
246261# endif
247262
248263// --------------- sanitizer_libc.h
249# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
264# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_HAIKU
250265# if !SANITIZER_S390
251266uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
252267 u64 offset) {
......@@ -591,9 +606,9 @@ uptr internal_execve(const char *filename, char *const argv[],
591606 return internal_syscall(SYSCALL(execve), (uptr)filename, (uptr)argv,
592607 (uptr)envp);
593608}
594# endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
609# endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_HAIKU
595610
596# if !SANITIZER_NETBSD
611# if !SANITIZER_NETBSD && !SANITIZER_HAIKU
597612void internal__exit(int exitcode) {
598613# if SANITIZER_FREEBSD || SANITIZER_SOLARIS
599614 internal_syscall(SYSCALL(exit), exitcode);
......@@ -602,7 +617,7 @@ void internal__exit(int exitcode) {
602617# endif
603618 Die(); // Unreachable.
604619}
605# endif // !SANITIZER_NETBSD
620# endif // !SANITIZER_NETBSD && !SANITIZER_HAIKU
606621
607622// ----------------- sanitizer_common.h
608623bool FileExists(const char *filename) {
......@@ -630,6 +645,8 @@ tid_t GetTid() {
630645 return Tid;
631646# elif SANITIZER_SOLARIS
632647 return thr_self();
648# elif SANITIZER_HAIKU
649 return find_thread(NULL);
633650# else
634651 return internal_syscall(SYSCALL(gettid));
635652# endif
......@@ -645,6 +662,8 @@ int TgKill(pid_t pid, tid_t tid, int sig) {
645662 errno = thr_kill(tid, sig);
646663 // TgKill is expected to return -1 on error, not an errno.
647664 return errno != 0 ? -1 : 0;
665# elif SANITIZER_HAIKU
666 return kill_thread(tid);
648667# endif
649668}
650669# endif
......@@ -672,7 +691,8 @@ u64 NanoTime() {
672691// 'environ' array (on some others) and does not use libc. This function
673692// should be called first inside __asan_init.
674693const char *GetEnv(const char *name) {
675# if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_SOLARIS
694# if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_SOLARIS || \
695 SANITIZER_HAIKU
676696 if (::environ != 0) {
677697 uptr NameLen = internal_strlen(name);
678698 for (char **Env = ::environ; *Env != 0; Env++) {
......@@ -710,13 +730,14 @@ const char *GetEnv(const char *name) {
710730# endif
711731}
712732
713# if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_GO
733# if !SANITIZER_HAIKU && !SANITIZER_FREEBSD && !SANITIZER_NETBSD && \
734 !SANITIZER_GO
714735extern "C" {
715736SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
716737}
717738# endif
718739
719# if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
740# if !SANITIZER_HAIKU && !SANITIZER_FREEBSD && !SANITIZER_NETBSD
720741static void ReadNullSepFileToArray(const char *path, char ***arr,
721742 int arr_size) {
722743 char *buff;
......@@ -743,7 +764,10 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
743764# endif
744765
745766static void GetArgsAndEnv(char ***argv, char ***envp) {
746# if SANITIZER_FREEBSD
767# if SANITIZER_HAIKU
768 *argv = __libc_argv;
769 *envp = environ;
770# elif SANITIZER_FREEBSD
747771 // On FreeBSD, retrieving the argument and environment arrays is done via the
748772 // kern.ps_strings sysctl, which returns a pointer to a structure containing
749773 // this information. See also <sys/exec.h>.
......@@ -783,7 +807,7 @@ static void GetArgsAndEnv(char ***argv, char ***envp) {
783807# if !SANITIZER_GO
784808 }
785809# endif // !SANITIZER_GO
786# endif // SANITIZER_FREEBSD
810# endif // SANITIZER_HAIKU
787811}
788812
789813char **GetArgv() {
......@@ -802,7 +826,7 @@ char **GetEnviron() {
802826void FutexWait(atomic_uint32_t *p, u32 cmp) {
803827# if SANITIZER_FREEBSD
804828 _umtx_op(p, UMTX_OP_WAIT_UINT, cmp, 0, 0);
805# elif SANITIZER_NETBSD
829# elif SANITIZER_NETBSD || SANITIZER_HAIKU
806830 sched_yield(); /* No userspace futex-like synchronization */
807831# else
808832 internal_syscall(SYSCALL(futex), (uptr)p, FUTEX_WAIT_PRIVATE, cmp, 0, 0, 0);
......@@ -812,7 +836,7 @@ void FutexWait(atomic_uint32_t *p, u32 cmp) {
812836void FutexWake(atomic_uint32_t *p, u32 count) {
813837# if SANITIZER_FREEBSD
814838 _umtx_op(p, UMTX_OP_WAKE, count, 0, 0);
815# elif SANITIZER_NETBSD
839# elif SANITIZER_NETBSD || SANITIZER_HAIKU
816840 /* No userspace futex-like synchronization */
817841# else
818842 internal_syscall(SYSCALL(futex), (uptr)p, FUTEX_WAKE_PRIVATE, count, 0, 0, 0);
......@@ -844,7 +868,7 @@ struct linux_dirent {
844868};
845869# endif
846870
847# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
871# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_HAIKU
848872// Syscall wrappers.
849873uptr internal_ptrace(int request, int pid, void *addr, void *data) {
850874 return internal_syscall(SYSCALL(ptrace), request, pid, (uptr)addr,
......@@ -1058,7 +1082,7 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
10581082# endif
10591083# endif // !SANITIZER_SOLARIS
10601084
1061# if !SANITIZER_NETBSD
1085# if !SANITIZER_NETBSD && !SANITIZER_HAIKU
10621086// ThreadLister implementation.
10631087ThreadLister::ThreadLister(pid_t pid) : buffer_(4096) {
10641088 task_path_.AppendF("/proc/%d/task", pid);
......@@ -1244,6 +1268,16 @@ uptr GetPageSize() {
12441268 CHECK_EQ(rv, 0);
12451269 return (uptr)pz;
12461270# elif SANITIZER_USE_GETAUXVAL
1271# if SANITIZER_ANDROID && __ANDROID_API__ < 35
1272 // The 16 KB page size was introduced in Android 15 (API level 35), while
1273 // earlier versions of Android always used a 4 KB page size.
1274 // We are checking the weak definition of `strerrorname_np` (introduced in API
1275 // level 35) because some earlier API levels crashed when
1276 // `getauxval(AT_PAGESZ)` was called from the `.preinit_array`.
1277 if (!strerrorname_np)
1278 return 4096;
1279# endif
1280
12471281 return getauxval(AT_PAGESZ);
12481282# else
12491283 return sysconf(_SC_PAGESIZE); // EXEC_PAGESIZE may not be trustworthy.
......@@ -1252,7 +1286,19 @@ uptr GetPageSize() {
12521286# endif
12531287
12541288uptr ReadBinaryName(/*out*/ char *buf, uptr buf_len) {
1255# if SANITIZER_SOLARIS
1289# if SANITIZER_HAIKU
1290 int cookie = 0;
1291 image_info info;
1292 const char *argv0 = "<UNKNOWN>";
1293 while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
1294 if (info.type != B_APP_IMAGE)
1295 continue;
1296 argv0 = info.name;
1297 break;
1298 }
1299 internal_strncpy(buf, argv0, buf_len);
1300 return internal_strlen(buf);
1301# elif SANITIZER_SOLARIS
12561302 const char *default_module_name = getexecname();
12571303 CHECK_NE(default_module_name, NULL);
12581304 return internal_snprintf(buf, buf_len, "%s", default_module_name);
......@@ -1318,11 +1364,11 @@ bool LibraryNameIs(const char *full_name, const char *base_name) {
13181364 return (name[base_name_length] == '-' || name[base_name_length] == '.');
13191365}
13201366
1321# if !SANITIZER_ANDROID
1367# if !SANITIZER_ANDROID && !SANITIZER_HAIKU
13221368// Call cb for each region mapped by map.
13231369void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) {
13241370 CHECK_NE(map, nullptr);
1325# if !SANITIZER_FREEBSD
1371# if !SANITIZER_FREEBSD && !SANITIZER_HAIKU
13261372 typedef ElfW(Phdr) Elf_Phdr;
13271373 typedef ElfW(Ehdr) Elf_Ehdr;
13281374# endif // !SANITIZER_FREEBSD
......@@ -1855,54 +1901,6 @@ int internal_uname(struct utsname *buf) {
18551901}
18561902# endif
18571903
1858# if SANITIZER_ANDROID
1859static int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,
1860 void *data) {
1861 // Any name starting with "lib" indicates a bug in L where library base names
1862 // are returned instead of paths.
1863 if (info->dlpi_name && info->dlpi_name[0] == 'l' &&
1864 info->dlpi_name[1] == 'i' && info->dlpi_name[2] == 'b') {
1865 *(bool *)data = true;
1866 return 1;
1867 }
1868 return 0;
1869}
1870
1871static atomic_uint32_t android_api_level;
1872
1873static AndroidApiLevel AndroidDetectApiLevelStatic() {
1874# if __ANDROID_API__ <= 22
1875 return ANDROID_LOLLIPOP_MR1;
1876# else
1877 return ANDROID_POST_LOLLIPOP;
1878# endif
1879}
1880
1881static AndroidApiLevel AndroidDetectApiLevel() {
1882 bool base_name_seen = false;
1883 dl_iterate_phdr(dl_iterate_phdr_test_cb, &base_name_seen);
1884 if (base_name_seen)
1885 return ANDROID_LOLLIPOP_MR1; // L MR1
1886 return ANDROID_POST_LOLLIPOP; // post-L
1887 // Plain L (API level 21) is completely broken wrt ASan and not very
1888 // interesting to detect.
1889}
1890
1891extern "C" __attribute__((weak)) void *_DYNAMIC;
1892
1893AndroidApiLevel AndroidGetApiLevel() {
1894 AndroidApiLevel level =
1895 (AndroidApiLevel)atomic_load(&android_api_level, memory_order_relaxed);
1896 if (level)
1897 return level;
1898 level = &_DYNAMIC == nullptr ? AndroidDetectApiLevelStatic()
1899 : AndroidDetectApiLevel();
1900 atomic_store(&android_api_level, level, memory_order_relaxed);
1901 return level;
1902}
1903
1904# endif
1905
19061904static HandleSignalMode GetHandleSignalModeImpl(int signum) {
19071905 switch (signum) {
19081906 case SIGABRT:
......@@ -1981,11 +1979,15 @@ using Context = ucontext_t;
19811979SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
19821980 Context *ucontext = (Context *)context;
19831981# if defined(__x86_64__) || defined(__i386__)
1982# if !SANITIZER_HAIKU
19841983 static const uptr PF_WRITE = 1U << 1;
1984# endif
19851985# if SANITIZER_FREEBSD
19861986 uptr err = ucontext->uc_mcontext.mc_err;
19871987# elif SANITIZER_NETBSD
19881988 uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR];
1989# elif SANITIZER_HAIKU
1990 uptr err = ucontext->uc_mcontext.r13;
19891991# elif SANITIZER_SOLARIS && defined(__i386__)
19901992 const int Err = 13;
19911993 uptr err = ucontext->uc_mcontext.gregs[Err];
......@@ -2598,6 +2600,11 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
25982600 *pc = ucontext->uc_mcontext.mc_rip;
25992601 *bp = ucontext->uc_mcontext.mc_rbp;
26002602 *sp = ucontext->uc_mcontext.mc_rsp;
2603# elif SANITIZER_HAIKU
2604 ucontext_t *ucontext = (ucontext_t *)context;
2605 *pc = ucontext->uc_mcontext.rip;
2606 *bp = ucontext->uc_mcontext.rbp;
2607 *sp = ucontext->uc_mcontext.rsp;
26012608# else
26022609 ucontext_t *ucontext = (ucontext_t *)context;
26032610 *pc = ucontext->uc_mcontext.gregs[REG_RIP];
lib/libtsan/sanitizer_common/sanitizer_linux.h+8-2
......@@ -14,7 +14,7 @@
1414
1515#include "sanitizer_platform.h"
1616#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
17 SANITIZER_SOLARIS
17 SANITIZER_SOLARIS || SANITIZER_HAIKU
1818# include "sanitizer_common.h"
1919# include "sanitizer_internal_defs.h"
2020# include "sanitizer_platform_limits_freebsd.h"
......@@ -31,6 +31,11 @@ namespace __sanitizer {
3131// the one in <dirent.h>, which is used by readdir().
3232struct linux_dirent;
3333
34# if SANITIZER_HAIKU
35struct MemoryMappingLayoutData {
36 long signed int cookie;
37};
38# else
3439struct ProcSelfMapsBuff {
3540 char *data;
3641 uptr mmaped_size;
......@@ -43,6 +48,7 @@ struct MemoryMappingLayoutData {
4348};
4449
4550void ReadProcMaps(ProcSelfMapsBuff *proc_maps);
51# endif // SANITIZER_HAIKU
4652
4753// Syscall wrappers.
4854uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count);
......@@ -124,7 +130,7 @@ bool LibraryNameIs(const char *full_name, const char *base_name);
124130// Call cb for each region mapped by map.
125131void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
126132
127// Releases memory pages entirely within the [beg, end] address range.
133// Releases memory pages entirely within the [beg, end) address range.
128134// The pages no longer count toward RSS; reads are guaranteed to return 0.
129135// Requires (but does not verify!) that pages are MAP_PRIVATE.
130136inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) {
lib/libtsan/sanitizer_common/sanitizer_linux_libcdep.cpp+33-82
......@@ -14,7 +14,7 @@
1414#include "sanitizer_platform.h"
1515
1616#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
17 SANITIZER_SOLARIS
17 SANITIZER_SOLARIS || SANITIZER_HAIKU
1818
1919# include "sanitizer_allocator_internal.h"
2020# include "sanitizer_atomic.h"
......@@ -28,8 +28,19 @@
2828# include "sanitizer_procmaps.h"
2929# include "sanitizer_solaris.h"
3030
31# if SANITIZER_HAIKU
32# define _DEFAULT_SOURCE
33# endif
34
3135# if SANITIZER_NETBSD
32# define _RTLD_SOURCE // for __lwp_gettcb_fast() / __lwp_getprivate_fast()
36# // for __lwp_gettcb_fast() / __lwp_getprivate_fast()
37# define _RTLD_SOURCE
38# include <machine/mcontext.h>
39# undef _RTLD_SOURCE
40# include <sys/param.h>
41# if __NetBSD_Version__ >= 1099001200
42# include <machine/lwp_private.h>
43# endif
3344# endif
3445
3546# include <dlfcn.h> // for dlsym()
......@@ -74,18 +85,9 @@ extern "C" int __sys_sigaction(int signum, const struct sigaction *act,
7485# include <thread.h>
7586# endif
7687
77# if SANITIZER_ANDROID
78# include <android/api-level.h>
79# if !defined(CPU_COUNT) && !defined(__aarch64__)
80# include <dirent.h>
81# include <fcntl.h>
82struct __sanitizer::linux_dirent {
83 long d_ino;
84 off_t d_off;
85 unsigned short d_reclen;
86 char d_name[];
87};
88# endif
88# if SANITIZER_HAIKU
89# include <kernel/OS.h>
90# include <sys/link_elf.h>
8991# endif
9092
9193# if !SANITIZER_ANDROID
......@@ -651,6 +653,7 @@ static void GetTls(uptr *addr, uptr *size) {
651653 *addr = (uptr)tcb->tcb_dtv[1];
652654 }
653655 }
656# elif SANITIZER_HAIKU
654657# else
655658# error "Unknown OS"
656659# endif
......@@ -721,8 +724,13 @@ static int AddModuleSegments(const char *module_name, dl_phdr_info *info,
721724 if (phdr->p_type == PT_LOAD) {
722725 uptr cur_beg = info->dlpi_addr + phdr->p_vaddr;
723726 uptr cur_end = cur_beg + phdr->p_memsz;
727# if SANITIZER_HAIKU
728 bool executable = phdr->p_flags & PF_EXECUTE;
729 bool writable = phdr->p_flags & PF_WRITE;
730# else
724731 bool executable = phdr->p_flags & PF_X;
725732 bool writable = phdr->p_flags & PF_W;
733# endif
726734 cur_module.addAddressRange(cur_beg, cur_end, executable, writable);
727735 } else if (phdr->p_type == PT_NOTE) {
728736# ifdef NT_GNU_BUILD_ID
......@@ -774,42 +782,13 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
774782 return 0;
775783}
776784
777static bool requiresProcmaps() {
778# if SANITIZER_ANDROID && __ANDROID_API__ <= 22
779 // Fall back to /proc/maps if dl_iterate_phdr is unavailable or broken.
780 // The runtime check allows the same library to work with
781 // both K and L (and future) Android releases.
782 return AndroidGetApiLevel() <= ANDROID_LOLLIPOP_MR1;
783# else
784 return false;
785# endif
786}
787
788static void procmapsInit(InternalMmapVectorNoCtor<LoadedModule> *modules) {
789 MemoryMappingLayout memory_mapping(/*cache_enabled*/ true);
790 memory_mapping.DumpListOfModules(modules);
791}
792
793785void ListOfModules::init() {
794786 clearOrInit();
795 if (requiresProcmaps()) {
796 procmapsInit(&modules_);
797 } else {
798 DlIteratePhdrData data = {&modules_, true};
799 dl_iterate_phdr(dl_iterate_phdr_cb, &data);
800 }
787 DlIteratePhdrData data = {&modules_, true};
788 dl_iterate_phdr(dl_iterate_phdr_cb, &data);
801789}
802790
803// When a custom loader is used, dl_iterate_phdr may not contain the full
804// list of modules. Allow callers to fall back to using procmaps.
805void ListOfModules::fallbackInit() {
806 if (!requiresProcmaps()) {
807 clearOrInit();
808 procmapsInit(&modules_);
809 } else {
810 clear();
811 }
812}
791void ListOfModules::fallbackInit() { clear(); }
813792
814793// getrusage does not give us the current RSS, only the max RSS.
815794// Still, this is better than nothing if /proc/self/statm is not available
......@@ -855,45 +834,17 @@ u32 GetNumberOfCPUs() {
855834 int req[2];
856835 uptr len = sizeof(ncpu);
857836 req[0] = CTL_HW;
837# ifdef HW_NCPUONLINE
838 req[1] = HW_NCPUONLINE;
839# else
858840 req[1] = HW_NCPU;
841# endif
859842 CHECK_EQ(internal_sysctl(req, 2, &ncpu, &len, NULL, 0), 0);
860843 return ncpu;
861# elif SANITIZER_ANDROID && !defined(CPU_COUNT) && !defined(__aarch64__)
862 // Fall back to /sys/devices/system/cpu on Android when cpu_set_t doesn't
863 // exist in sched.h. That is the case for toolchains generated with older
864 // NDKs.
865 // This code doesn't work on AArch64 because internal_getdents makes use of
866 // the 64bit getdents syscall, but cpu_set_t seems to always exist on AArch64.
867 uptr fd = internal_open("/sys/devices/system/cpu", O_RDONLY | O_DIRECTORY);
868 if (internal_iserror(fd))
869 return 0;
870 InternalMmapVector<u8> buffer(4096);
871 uptr bytes_read = buffer.size();
872 uptr n_cpus = 0;
873 u8 *d_type;
874 struct linux_dirent *entry = (struct linux_dirent *)&buffer[bytes_read];
875 while (true) {
876 if ((u8 *)entry >= &buffer[bytes_read]) {
877 bytes_read = internal_getdents(fd, (struct linux_dirent *)buffer.data(),
878 buffer.size());
879 if (internal_iserror(bytes_read) || !bytes_read)
880 break;
881 entry = (struct linux_dirent *)buffer.data();
882 }
883 d_type = (u8 *)entry + entry->d_reclen - 1;
884 if (d_type >= &buffer[bytes_read] ||
885 (u8 *)&entry->d_name[3] >= &buffer[bytes_read])
886 break;
887 if (entry->d_ino != 0 && *d_type == DT_DIR) {
888 if (entry->d_name[0] == 'c' && entry->d_name[1] == 'p' &&
889 entry->d_name[2] == 'u' && entry->d_name[3] >= '0' &&
890 entry->d_name[3] <= '9')
891 n_cpus++;
892 }
893 entry = (struct linux_dirent *)(((u8 *)entry) + entry->d_reclen);
894 }
895 internal_close(fd);
896 return n_cpus;
844# elif SANITIZER_HAIKU
845 system_info info;
846 get_system_info(&info);
847 return info.cpu_count;
897848# elif SANITIZER_SOLARIS
898849 return sysconf(_SC_NPROCESSORS_ONLN);
899850# else
lib/libtsan/sanitizer_common/sanitizer_mac.cpp+29-38
......@@ -38,13 +38,6 @@
3838extern char **environ;
3939# endif
4040
41# if defined(__has_include) && __has_include(<os/trace.h>)
42# define SANITIZER_OS_TRACE 1
43# include <os/trace.h>
44# else
45# define SANITIZER_OS_TRACE 0
46# endif
47
4841// Integrate with CrashReporter library if available
4942# if defined(__has_include) && __has_include(<CrashReporterClient.h>)
5043# define HAVE_CRASHREPORTERCLIENT_H 1
......@@ -843,31 +836,23 @@ void LogMessageOnPrintf(const char *str) {
843836}
844837
845838void LogFullErrorReport(const char *buffer) {
846#if !SANITIZER_GO
847 // Log with os_trace. This will make it into the crash log.
848#if SANITIZER_OS_TRACE
849#pragma clang diagnostic push
850// os_trace is deprecated.
851#pragma clang diagnostic ignored "-Wdeprecated-declarations"
852 if (GetMacosAlignedVersion() >= MacosVersion(10, 10)) {
853 // os_trace requires the message (format parameter) to be a string literal.
854 if (internal_strncmp(SanitizerToolName, "AddressSanitizer",
855 sizeof("AddressSanitizer") - 1) == 0)
856 os_trace("Address Sanitizer reported a failure.");
857 else if (internal_strncmp(SanitizerToolName, "UndefinedBehaviorSanitizer",
858 sizeof("UndefinedBehaviorSanitizer") - 1) == 0)
859 os_trace("Undefined Behavior Sanitizer reported a failure.");
860 else if (internal_strncmp(SanitizerToolName, "ThreadSanitizer",
861 sizeof("ThreadSanitizer") - 1) == 0)
862 os_trace("Thread Sanitizer reported a failure.");
863 else
864 os_trace("Sanitizer tool reported a failure.");
865
866 if (common_flags()->log_to_syslog)
867 os_trace("Consult syslog for more information.");
868 }
869#pragma clang diagnostic pop
870#endif
839# if !SANITIZER_GO
840 // Log with os_log_error. This will make it into the crash log.
841 if (internal_strncmp(SanitizerToolName, "AddressSanitizer",
842 sizeof("AddressSanitizer") - 1) == 0)
843 os_log_error(OS_LOG_DEFAULT, "Address Sanitizer reported a failure.");
844 else if (internal_strncmp(SanitizerToolName, "UndefinedBehaviorSanitizer",
845 sizeof("UndefinedBehaviorSanitizer") - 1) == 0)
846 os_log_error(OS_LOG_DEFAULT,
847 "Undefined Behavior Sanitizer reported a failure.");
848 else if (internal_strncmp(SanitizerToolName, "ThreadSanitizer",
849 sizeof("ThreadSanitizer") - 1) == 0)
850 os_log_error(OS_LOG_DEFAULT, "Thread Sanitizer reported a failure.");
851 else
852 os_log_error(OS_LOG_DEFAULT, "Sanitizer tool reported a failure.");
853
854 if (common_flags()->log_to_syslog)
855 os_log_error(OS_LOG_DEFAULT, "Consult syslog for more information.");
871856
872857 // Log to syslog.
873858 // The logging on OS X may call pthread_create so we need the threading
......@@ -881,7 +866,7 @@ void LogFullErrorReport(const char *buffer) {
881866 WriteToSyslog(buffer);
882867
883868 // The report is added to CrashLog as part of logging all of Printf output.
884#endif
869# endif // !SANITIZER_GO
885870}
886871
887872SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
......@@ -1203,13 +1188,14 @@ uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
12031188 const uptr left_padding =
12041189 Max<uptr>(granularity, 1ULL << min_shadow_base_alignment);
12051190
1206 uptr space_size = shadow_size_bytes + left_padding;
1191 uptr space_size = shadow_size_bytes;
12071192
12081193 uptr largest_gap_found = 0;
12091194 uptr max_occupied_addr = 0;
1195
12101196 VReport(2, "FindDynamicShadowStart, space_size = %p\n", (void *)space_size);
12111197 uptr shadow_start =
1212 FindAvailableMemoryRange(space_size, alignment, granularity,
1198 FindAvailableMemoryRange(space_size, alignment, left_padding,
12131199 &largest_gap_found, &max_occupied_addr);
12141200 // If the shadow doesn't fit, restrict the address space to make it fit.
12151201 if (shadow_start == 0) {
......@@ -1229,9 +1215,9 @@ uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
12291215 }
12301216 RestrictMemoryToMaxAddress(new_max_vm);
12311217 high_mem_end = new_max_vm - 1;
1232 space_size = (high_mem_end >> shadow_scale) + left_padding;
1218 space_size = (high_mem_end >> shadow_scale);
12331219 VReport(2, "FindDynamicShadowStart, space_size = %p\n", (void *)space_size);
1234 shadow_start = FindAvailableMemoryRange(space_size, alignment, granularity,
1220 shadow_start = FindAvailableMemoryRange(space_size, alignment, left_padding,
12351221 nullptr, nullptr);
12361222 if (shadow_start == 0) {
12371223 Report("Unable to find a memory range after restricting VM.\n");
......@@ -1272,10 +1258,15 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
12721258 mach_msg_type_number_t count = kRegionInfoSize;
12731259 kr = mach_vm_region_recurse(mach_task_self(), &address, &vmsize, &depth,
12741260 (vm_region_info_t)&vminfo, &count);
1275 if (kr == KERN_INVALID_ADDRESS) {
1261
1262 // There are cases where going beyond the processes' max vm does
1263 // not return KERN_INVALID_ADDRESS so we check for going beyond that
1264 // max address as well.
1265 if (kr == KERN_INVALID_ADDRESS || address > max_vm_address) {
12761266 // No more regions beyond "address", consider the gap at the end of VM.
12771267 address = max_vm_address;
12781268 vmsize = 0;
1269 kr = -1; // break after this iteration.
12791270 } else {
12801271 if (max_occupied_addr) *max_occupied_addr = address + vmsize;
12811272 }
lib/libtsan/sanitizer_common/sanitizer_mac.h+6-3
......@@ -37,9 +37,6 @@ struct VersionBase {
3737
3838 VersionBase(u16 major, u16 minor) : major(major), minor(minor) {}
3939
40 bool operator==(const VersionType &other) const {
41 return major == other.major && minor == other.minor;
42 }
4340 bool operator>=(const VersionType &other) const {
4441 return major > other.major ||
4542 (major == other.major && minor >= other.minor);
......@@ -47,6 +44,12 @@ struct VersionBase {
4744 bool operator<(const VersionType &other) const { return !(*this >= other); }
4845};
4946
47template <typename VersionType>
48bool operator==(const VersionBase<VersionType> &self,
49 const VersionBase<VersionType> &other) {
50 return self.major == other.major && self.minor == other.minor;
51}
52
5053struct MacosVersion : VersionBase<MacosVersion> {
5154 MacosVersion(u16 major, u16 minor) : VersionBase(major, minor) {}
5255};
lib/libtsan/sanitizer_common/sanitizer_malloc_mac.inc+16
......@@ -144,6 +144,22 @@ INTERCEPTOR(void, free, void *ptr) {
144144 COMMON_MALLOC_FREE(ptr);
145145}
146146
147#if SANITIZER_INTERCEPT_FREE_SIZED && defined(COMMON_MALLOC_FREE_SIZED)
148INTERCEPTOR(void, free_sized, void *ptr, size_t size) {
149 COMMON_MALLOC_ENTER();
150 COMMON_MALLOC_FREE_SIZED(ptr, size);
151}
152#endif
153
154#if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED && \
155 defined(COMMON_MALLOC_FREE_ALIGNED_SIZED)
156INTERCEPTOR(void, free_aligned_sized, void *ptr, size_t alignment,
157 size_t size) {
158 COMMON_MALLOC_ENTER();
159 COMMON_MALLOC_FREE_ALIGNED_SIZED(ptr, alignment, size);
160}
161#endif
162
147163INTERCEPTOR(void *, realloc, void *ptr, size_t size) {
148164 COMMON_MALLOC_ENTER();
149165 COMMON_MALLOC_REALLOC(ptr, size);
lib/libtsan/sanitizer_common/sanitizer_platform.h+21-4
......@@ -14,7 +14,8 @@
1414
1515#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
1616 !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \
17 !(defined(__sun__) && defined(__svr4__))
17 !(defined(__sun__) && defined(__svr4__)) && !defined(__HAIKU__) && \
18 !defined(__wasi__)
1819# error "This operating system is not supported"
1920#endif
2021
......@@ -55,6 +56,18 @@
5556# define SANITIZER_SOLARIS 0
5657#endif
5758
59#if defined(__HAIKU__)
60# define SANITIZER_HAIKU 1
61#else
62# define SANITIZER_HAIKU 0
63#endif
64
65#if defined(__wasi__)
66# define SANITIZER_WASI 1
67#else
68# define SANITIZER_WASI 0
69#endif
70
5871// - SANITIZER_APPLE: all Apple code
5972// - TARGET_OS_OSX: macOS
6073// - SANITIZER_IOS: devices (iOS and iOS-like)
......@@ -136,9 +149,9 @@
136149# define SANITIZER_MUSL 0
137150#endif
138151
139#define SANITIZER_POSIX \
152#define SANITIZER_POSIX \
140153 (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \
141 SANITIZER_NETBSD || SANITIZER_SOLARIS)
154 SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU)
142155
143156#if __LP64__ || defined(_WIN64)
144157# define SANITIZER_WORDSIZE 64
......@@ -305,6 +318,9 @@
305318# endif
306319#endif
307320
321// The first address that can be returned by mmap.
322#define SANITIZER_MMAP_BEGIN 0
323
308324// The range of addresses which can be returned my mmap.
309325// FIXME: this value should be different on different platforms. Larger values
310326// will still work but will consume more memory for TwoLevelByteMap.
......@@ -410,7 +426,8 @@
410426# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0
411427#endif
412428
413#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD || SANITIZER_SOLARIS
429#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD || \
430 SANITIZER_SOLARIS || SANITIZER_HAIKU
414431# define SANITIZER_MADVISE_DONTNEED MADV_FREE
415432#else
416433# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED
lib/libtsan/sanitizer_common/sanitizer_platform_interceptors.h+59-25
......@@ -129,8 +129,10 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
129129
130130#if SANITIZER_FUCHSIA
131131#define SI_NOT_FUCHSIA 0
132#define SI_FUCHSIA 1
132133#else
133134#define SI_NOT_FUCHSIA 1
135#define SI_FUCHSIA 0
134136#endif
135137
136138#if SANITIZER_SOLARIS
......@@ -139,6 +141,12 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
139141#define SI_SOLARIS 0
140142#endif
141143
144#if SANITIZER_AIX
145# define SI_NOT_AIX 0
146#else
147# define SI_NOT_AIX 1
148#endif
149
142150#if SANITIZER_SOLARIS32
143151#define SI_SOLARIS32 1
144152#else
......@@ -159,20 +167,20 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
159167
160168#define SANITIZER_INTERCEPT_STRLEN SI_NOT_FUCHSIA
161169#define SANITIZER_INTERCEPT_STRNLEN (SI_NOT_MAC && SI_NOT_FUCHSIA)
162#define SANITIZER_INTERCEPT_STRCMP SI_NOT_FUCHSIA
170#define SANITIZER_INTERCEPT_STRCMP (SI_NOT_FUCHSIA && SI_NOT_AIX)
163171#define SANITIZER_INTERCEPT_STRSTR SI_NOT_FUCHSIA
164#define SANITIZER_INTERCEPT_STRCASESTR SI_POSIX
172#define SANITIZER_INTERCEPT_STRCASESTR (SI_POSIX && SI_NOT_AIX)
165173#define SANITIZER_INTERCEPT_STRTOK SI_NOT_FUCHSIA
166174#define SANITIZER_INTERCEPT_STRCHR SI_NOT_FUCHSIA
167#define SANITIZER_INTERCEPT_STRCHRNUL SI_POSIX_NOT_MAC
175#define SANITIZER_INTERCEPT_STRCHRNUL (SI_POSIX_NOT_MAC && SI_NOT_AIX)
168176#define SANITIZER_INTERCEPT_STRRCHR SI_NOT_FUCHSIA
169177#define SANITIZER_INTERCEPT_STRSPN SI_NOT_FUCHSIA
170178#define SANITIZER_INTERCEPT_STRPBRK SI_NOT_FUCHSIA
171179#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID || SI_SOLARIS
172180#define SANITIZER_INTERCEPT_STRCASECMP SI_POSIX
173181#define SANITIZER_INTERCEPT_MEMSET 1
174#define SANITIZER_INTERCEPT_MEMMOVE 1
175#define SANITIZER_INTERCEPT_MEMCPY 1
182#define SANITIZER_INTERCEPT_MEMMOVE SI_NOT_AIX
183#define SANITIZER_INTERCEPT_MEMCPY SI_NOT_AIX
176184#define SANITIZER_INTERCEPT_MEMCMP SI_NOT_FUCHSIA
177185#define SANITIZER_INTERCEPT_BCMP \
178186 SANITIZER_INTERCEPT_MEMCMP && \
......@@ -231,16 +239,22 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
231239#define SANITIZER_INTERCEPT_ISOC99_SCANF SI_GLIBC
232240
233241#ifndef SANITIZER_INTERCEPT_PRINTF
234#define SANITIZER_INTERCEPT_PRINTF SI_POSIX
235#define SANITIZER_INTERCEPT_PRINTF_L (SI_FREEBSD || SI_NETBSD)
236#define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_GLIBC
242# define SANITIZER_INTERCEPT_ASPRINTF SI_NOT_AIX
243# define SANITIZER_INTERCEPT_VASPRINTF SI_NOT_AIX
244# define SANITIZER_INTERCEPT_PRINTF SI_POSIX
245# define SANITIZER_INTERCEPT_PRINTF_L (SI_FREEBSD || SI_NETBSD)
246# define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_GLIBC
237247#endif
238248
249#define SANITIZER_INTERCEPT_SETPROCTITLE (SI_FREEBSD || SI_NETBSD)
250
239251#define SANITIZER_INTERCEPT___PRINTF_CHK \
240252 (SANITIZER_INTERCEPT_PRINTF && SI_GLIBC)
241253
242#define SANITIZER_INTERCEPT_FREXP SI_NOT_FUCHSIA
243#define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_POSIX
254// AIX libc does not export FREXP and FREXPF.
255#define SANITIZER_INTERCEPT_FREXP (SI_NOT_FUCHSIA && SI_NOT_AIX)
256#define SANITIZER_INTERCEPT_FREXPF (SI_POSIX && SI_NOT_AIX)
257#define SANITIZER_INTERCEPT_FREXPL SI_POSIX
244258
245259#define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX
246260#define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \
......@@ -289,7 +303,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
289303#define SANITIZER_INTERCEPT_ACCEPT4 \
290304 (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_FREEBSD)
291305#define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD
292#define SANITIZER_INTERCEPT_MODF SI_POSIX
306#define SANITIZER_INTERCEPT_MODF (SI_POSIX && SI_NOT_AIX)
293307#define SANITIZER_INTERCEPT_RECVMSG SI_POSIX
294308#define SANITIZER_INTERCEPT_SENDMSG SI_POSIX
295309#define SANITIZER_INTERCEPT_RECVMMSG SI_LINUX
......@@ -324,8 +338,9 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
324338#define SANITIZER_INTERCEPT___WCSXFRM_L SI_LINUX
325339#define SANITIZER_INTERCEPT_WCSNRTOMBS \
326340 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
327#define SANITIZER_INTERCEPT_WCRTOMB \
328 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
341#define SANITIZER_INTERCEPT_WCRTOMB \
342 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS || \
343 !SI_NOT_AIX)
329344#define SANITIZER_INTERCEPT_WCTOMB \
330345 (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
331346#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS
......@@ -365,7 +380,8 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
365380#define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID
366381#define SANITIZER_INTERCEPT_STATFS \
367382 (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
368#define SANITIZER_INTERCEPT_STATFS64 SI_GLIBC && SANITIZER_HAS_STATFS64
383#define SANITIZER_INTERCEPT_STATFS64 \
384 ((SI_GLIBC || !SI_NOT_AIX) && SANITIZER_HAS_STATFS64)
369385#define SANITIZER_INTERCEPT_STATVFS \
370386 (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
371387#define SANITIZER_INTERCEPT_STATVFS64 SI_GLIBC
......@@ -414,10 +430,10 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
414430#define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX
415431#define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX
416432#define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS
417#define SANITIZER_INTERCEPT_REMQUO SI_POSIX
418#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD)
419#define SANITIZER_INTERCEPT_LGAMMA SI_POSIX
420#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD)
433#define SANITIZER_INTERCEPT_REMQUO (SI_POSIX && SI_NOT_AIX)
434#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD && SI_NOT_AIX)
435#define SANITIZER_INTERCEPT_LGAMMA (SI_POSIX && SI_NOT_AIX)
436#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD && SI_NOT_AIX)
421437#define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX || SI_SOLARIS)
422438#define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
423439#define SANITIZER_INTERCEPT_DRAND48_R SI_GLIBC
......@@ -500,11 +516,13 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
500516#define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE (SI_LINUX || SI_FREEBSD)
501517
502518#define SI_STAT_LINUX (SI_LINUX && __GLIBC_PREREQ(2, 33))
503#define SANITIZER_INTERCEPT_STAT \
504 (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS || \
505 SI_STAT_LINUX)
506#define SANITIZER_INTERCEPT_STAT64 SI_STAT_LINUX && SANITIZER_HAS_STAT64
507#define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX)
519#define SANITIZER_INTERCEPT_STAT \
520 (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS || \
521 SI_STAT_LINUX || !SI_NOT_AIX)
522#define SANITIZER_INTERCEPT_STAT64 \
523 ((SI_STAT_LINUX || !SI_NOT_AIX) && SANITIZER_HAS_STAT64)
524#define SANITIZER_INTERCEPT_LSTAT \
525 (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX || !SI_NOT_AIX)
508526#define SANITIZER_INTERCEPT___XSTAT \
509527 ((!SANITIZER_INTERCEPT_STAT && SI_POSIX) || SI_STAT_LINUX)
510528#define SANITIZER_INTERCEPT___XSTAT64 SI_GLIBC
......@@ -521,7 +539,8 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
521539
522540#define SANITIZER_INTERCEPT_MMAP SI_POSIX
523541#define SANITIZER_INTERCEPT_MMAP64 SI_GLIBC || SI_SOLARIS
524#define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO (SI_GLIBC || SI_ANDROID)
542#define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO \
543 (SI_GLIBC || SI_ANDROID || SI_FUCHSIA)
525544#define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC && !SI_NETBSD)
526545#define SANITIZER_INTERCEPT___LIBC_MEMALIGN SI_GLIBC
527546#define SANITIZER_INTERCEPT_PVALLOC (SI_GLIBC || SI_ANDROID)
......@@ -572,7 +591,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
572591#define SANITIZER_INTERCEPT_PROTOENT_R SI_GLIBC
573592#define SANITIZER_INTERCEPT_NETENT (SI_LINUX || SI_NETBSD || SI_FREEBSD)
574593#define SANITIZER_INTERCEPT_SETVBUF \
575 (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC)
594 (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC || !SI_NOT_AIX)
576595#define SANITIZER_INTERCEPT_GETMNTINFO (SI_NETBSD || SI_FREEBSD || SI_MAC)
577596#define SANITIZER_INTERCEPT_MI_VECTOR_HASH SI_NETBSD
578597#define SANITIZER_INTERCEPT_GETVFSSTAT SI_NETBSD
......@@ -640,6 +659,21 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
640659# define SI_MAC_OS_DEPLOYMENT_MIN_13_00 0
641660#endif
642661#define SANITIZER_INTERCEPT_FREADLINK (SI_MAC && SI_MAC_OS_DEPLOYMENT_MIN_13_00)
662#define SANITIZER_INTERCEPT_GETSERVENT_R SI_GLIBC
663#define SANITIZER_INTERCEPT_GETSERVBYNAME_R SI_GLIBC
664#define SANITIZER_INTERCEPT_GETSERVBYPORT_R SI_GLIBC
665
666// Until free_sized and free_aligned_sized are more generally available,
667// we can only unconditionally intercept on ELF-based platforms where it
668// is okay to have undefined weak symbols.
669#ifdef __ELF__
670# define SANITIZER_INTERCEPT_FREE_SIZED 1
671# define SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED 1
672#else
673# define SANITIZER_INTERCEPT_FREE_SIZED 0
674# define SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED 0
675#endif
676
643677// This macro gives a way for downstream users to override the above
644678// interceptor macros irrespective of the platform they are on. They have
645679// to do two things:
lib/libtsan/sanitizer_common/sanitizer_platform_limits_freebsd.cpp+1-9
......@@ -29,6 +29,7 @@
2929#include <sys/mtio.h>
3030#include <sys/ptrace.h>
3131#include <sys/resource.h>
32#include <sys/shm.h>
3233#include <sys/signal.h>
3334#include <sys/socket.h>
3435#include <sys/sockio.h>
......@@ -81,10 +82,6 @@
8182#include <wchar.h>
8283#include <wordexp.h>
8384
84#define _KERNEL // to declare 'shminfo' structure
85#include <sys/shm.h>
86#undef _KERNEL
87
8885#undef IOC_DIRMASK
8986
9087// Include these after system headers to avoid name clashes and ambiguities.
......@@ -135,8 +132,6 @@ unsigned struct_timeb_sz = sizeof(struct timeb);
135132unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds);
136133unsigned struct_mq_attr_sz = sizeof(struct mq_attr);
137134unsigned struct_statvfs_sz = sizeof(struct statvfs);
138unsigned struct_shminfo_sz = sizeof(struct shminfo);
139unsigned struct_shm_info_sz = sizeof(struct shm_info);
140135unsigned struct_regmatch_sz = sizeof(regmatch_t);
141136unsigned struct_regex_sz = sizeof(regex_t);
142137unsigned struct_fstab_sz = sizeof(struct fstab);
......@@ -150,9 +145,6 @@ const uptr sig_err = (uptr)SIG_ERR;
150145const uptr sa_siginfo = (uptr)SA_SIGINFO;
151146
152147int shmctl_ipc_stat = (int)IPC_STAT;
153int shmctl_ipc_info = (int)IPC_INFO;
154int shmctl_shm_info = (int)SHM_INFO;
155int shmctl_shm_stat = (int)SHM_STAT;
156148unsigned struct_utmpx_sz = sizeof(struct utmpx);
157149
158150int map_fixed = MAP_FIXED;
lib/libtsan/sanitizer_common/sanitizer_platform_limits_freebsd.h+7-5
......@@ -419,12 +419,14 @@ struct __sanitizer_wordexp_t {
419419
420420typedef void __sanitizer_FILE;
421421
422extern unsigned struct_shminfo_sz;
423extern unsigned struct_shm_info_sz;
424422extern int shmctl_ipc_stat;
425extern int shmctl_ipc_info;
426extern int shmctl_shm_info;
427extern int shmctl_shm_stat;
423
424// This simplifies generic code
425#define struct_shminfo_sz -1
426#define struct_shm_info_sz -1
427#define shmctl_shm_stat -1
428#define shmctl_ipc_info -1
429#define shmctl_shm_info -1
428430
429431extern unsigned struct_utmpx_sz;
430432
lib/libtsan/sanitizer_common/sanitizer_platform_limits_posix.cpp+36-17
......@@ -24,7 +24,7 @@
2424// Must go after undef _FILE_OFFSET_BITS.
2525#include "sanitizer_platform.h"
2626
27#if SANITIZER_LINUX || SANITIZER_APPLE
27#if SANITIZER_LINUX || SANITIZER_APPLE || SANITIZER_HAIKU
2828// Must go after undef _FILE_OFFSET_BITS.
2929#include "sanitizer_glibc_version.h"
3030
......@@ -52,7 +52,7 @@
5252#include <time.h>
5353#include <wchar.h>
5454#include <regex.h>
55#if !SANITIZER_APPLE
55#if !SANITIZER_APPLE && !SANITIZER_HAIKU
5656#include <utmp.h>
5757#endif
5858
......@@ -61,7 +61,9 @@
6161#endif
6262
6363#if !SANITIZER_ANDROID
64#if !SANITIZER_HAIKU
6465#include <sys/mount.h>
66#endif
6567#include <sys/timeb.h>
6668#include <utmpx.h>
6769#endif
......@@ -111,9 +113,11 @@ typedef struct user_fpregs elf_fpregset_t;
111113
112114#if !SANITIZER_ANDROID
113115#include <ifaddrs.h>
116#if !SANITIZER_HAIKU
114117#include <sys/ucontext.h>
115118#include <wordexp.h>
116119#endif
120#endif
117121
118122#if SANITIZER_LINUX
119123#if SANITIZER_GLIBC
......@@ -163,7 +167,7 @@ typedef struct user_fpregs elf_fpregset_t;
163167#include <sys/vfs.h>
164168#include <sys/epoll.h>
165169#include <linux/capability.h>
166#else
170#elif !SANITIZER_HAIKU
167171#include <fstab.h>
168172#endif // SANITIZER_LINUX
169173
......@@ -173,6 +177,11 @@ typedef struct user_fpregs elf_fpregset_t;
173177#include <sys/sockio.h>
174178#endif
175179
180#if SANITIZER_HAIKU
181#include <sys/sockio.h>
182#include <sys/ioctl.h>
183#endif
184
176185// Include these after system headers to avoid name clashes and ambiguities.
177186# include "sanitizer_common.h"
178187# include "sanitizer_internal_defs.h"
......@@ -217,7 +226,7 @@ namespace __sanitizer {
217226 unsigned struct_fstab_sz = sizeof(struct fstab);
218227#endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
219228 // SANITIZER_APPLE
220#if !SANITIZER_ANDROID
229#if !SANITIZER_ANDROID && !SANITIZER_HAIKU
221230 unsigned struct_statfs_sz = sizeof(struct statfs);
222231 unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
223232
......@@ -324,7 +333,7 @@ namespace __sanitizer {
324333 int shmctl_shm_stat = (int)SHM_STAT;
325334#endif
326335
327#if !SANITIZER_APPLE && !SANITIZER_FREEBSD
336#if !SANITIZER_APPLE && !SANITIZER_FREEBSD && !SANITIZER_HAIKU
328337 unsigned struct_utmp_sz = sizeof(struct utmp);
329338#endif
330339#if !SANITIZER_ANDROID
......@@ -356,9 +365,9 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
356365 int glob_altdirfunc = GLOB_ALTDIRFUNC;
357366#endif
358367
359# if !SANITIZER_ANDROID
368# if !SANITIZER_ANDROID && !SANITIZER_HAIKU
360369 const int wordexp_wrde_dooffs = WRDE_DOOFFS;
361# endif // !SANITIZER_ANDROID
370# endif // !SANITIZER_ANDROID && !SANITIZER_HAIKU
362371
363372# if SANITIZER_LINUX && !SANITIZER_ANDROID && \
364373 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
......@@ -537,7 +546,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
537546 unsigned struct_sock_fprog_sz = sizeof(struct sock_fprog);
538547# endif // SANITIZER_GLIBC
539548
540# if !SANITIZER_ANDROID && !SANITIZER_APPLE
549# if !SANITIZER_ANDROID && !SANITIZER_APPLE && !SANITIZER_HAIKU
541550 unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req);
542551 unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req);
543552#endif
......@@ -548,12 +557,14 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
548557
549558 const unsigned IOCTL_NOT_PRESENT = 0;
550559
560 unsigned IOCTL_FIONBIO = FIONBIO;
561#if !SANITIZER_HAIKU
551562 unsigned IOCTL_FIOASYNC = FIOASYNC;
552563 unsigned IOCTL_FIOCLEX = FIOCLEX;
553564 unsigned IOCTL_FIOGETOWN = FIOGETOWN;
554 unsigned IOCTL_FIONBIO = FIONBIO;
555565 unsigned IOCTL_FIONCLEX = FIONCLEX;
556566 unsigned IOCTL_FIOSETOWN = FIOSETOWN;
567#endif
557568 unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI;
558569 unsigned IOCTL_SIOCATMARK = SIOCATMARK;
559570 unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI;
......@@ -574,23 +585,27 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
574585 unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU;
575586 unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK;
576587 unsigned IOCTL_SIOCSPGRP = SIOCSPGRP;
588
589#if !SANITIZER_HAIKU
577590 unsigned IOCTL_TIOCCONS = TIOCCONS;
578 unsigned IOCTL_TIOCEXCL = TIOCEXCL;
579591 unsigned IOCTL_TIOCGETD = TIOCGETD;
592 unsigned IOCTL_TIOCNOTTY = TIOCNOTTY;
593 unsigned IOCTL_TIOCPKT = TIOCPKT;
594 unsigned IOCTL_TIOCSETD = TIOCSETD;
595 unsigned IOCTL_TIOCSTI = TIOCSTI;
596#endif
597
598 unsigned IOCTL_TIOCEXCL = TIOCEXCL;
580599 unsigned IOCTL_TIOCGPGRP = TIOCGPGRP;
581600 unsigned IOCTL_TIOCGWINSZ = TIOCGWINSZ;
582601 unsigned IOCTL_TIOCMBIC = TIOCMBIC;
583602 unsigned IOCTL_TIOCMBIS = TIOCMBIS;
584603 unsigned IOCTL_TIOCMGET = TIOCMGET;
585604 unsigned IOCTL_TIOCMSET = TIOCMSET;
586 unsigned IOCTL_TIOCNOTTY = TIOCNOTTY;
587605 unsigned IOCTL_TIOCNXCL = TIOCNXCL;
588606 unsigned IOCTL_TIOCOUTQ = TIOCOUTQ;
589 unsigned IOCTL_TIOCPKT = TIOCPKT;
590607 unsigned IOCTL_TIOCSCTTY = TIOCSCTTY;
591 unsigned IOCTL_TIOCSETD = TIOCSETD;
592608 unsigned IOCTL_TIOCSPGRP = TIOCSPGRP;
593 unsigned IOCTL_TIOCSTI = TIOCSTI;
594609 unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ;
595610#if SANITIZER_LINUX && !SANITIZER_ANDROID
596611 unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT;
......@@ -1100,7 +1115,7 @@ COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent));
11001115CHECK_SIZE_AND_OFFSET(dirent, d_ino);
11011116#if SANITIZER_APPLE
11021117CHECK_SIZE_AND_OFFSET(dirent, d_seekoff);
1103#elif SANITIZER_FREEBSD
1118#elif SANITIZER_FREEBSD || SANITIZER_HAIKU
11041119// There is no 'd_off' field on FreeBSD.
11051120#else
11061121CHECK_SIZE_AND_OFFSET(dirent, d_off);
......@@ -1116,7 +1131,9 @@ CHECK_SIZE_AND_OFFSET(dirent64, d_reclen);
11161131
11171132CHECK_TYPE_SIZE(ifconf);
11181133CHECK_SIZE_AND_OFFSET(ifconf, ifc_len);
1134#if !SANITIZER_HAIKU
11191135CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu);
1136#endif
11201137
11211138CHECK_TYPE_SIZE(pollfd);
11221139CHECK_SIZE_AND_OFFSET(pollfd, fd);
......@@ -1171,7 +1188,7 @@ CHECK_TYPE_SIZE(__kernel_loff_t);
11711188CHECK_TYPE_SIZE(__kernel_fd_set);
11721189#endif
11731190
1174#if !SANITIZER_ANDROID
1191#if !SANITIZER_ANDROID && !SANITIZER_HAIKU
11751192CHECK_TYPE_SIZE(wordexp_t);
11761193CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc);
11771194CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv);
......@@ -1201,7 +1218,9 @@ CHECK_SIZE_AND_OFFSET(mntent, mnt_freq);
12011218CHECK_SIZE_AND_OFFSET(mntent, mnt_passno);
12021219#endif
12031220
1221#if !SANITIZER_HAIKU
12041222CHECK_TYPE_SIZE(ether_addr);
1223#endif
12051224
12061225#if SANITIZER_GLIBC || SANITIZER_FREEBSD
12071226CHECK_TYPE_SIZE(ipc_perm);
......@@ -1239,7 +1258,7 @@ CHECK_TYPE_SIZE(clock_t);
12391258CHECK_TYPE_SIZE(clockid_t);
12401259#endif
12411260
1242#if !SANITIZER_ANDROID
1261#if !SANITIZER_ANDROID && !SANITIZER_HAIKU
12431262CHECK_TYPE_SIZE(ifaddrs);
12441263CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next);
12451264CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name);
lib/libtsan/sanitizer_common/sanitizer_platform_limits_posix.h+320-288
......@@ -14,39 +14,39 @@
1414#ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H
1515#define SANITIZER_PLATFORM_LIMITS_POSIX_H
1616
17#if SANITIZER_LINUX || SANITIZER_APPLE
18
19#include "sanitizer_internal_defs.h"
20#include "sanitizer_platform.h"
21#include "sanitizer_mallinfo.h"
22
23#if SANITIZER_APPLE
24#include <sys/cdefs.h>
25#if !__DARWIN_ONLY_64_BIT_INO_T
26#define SANITIZER_HAS_STAT64 1
27#define SANITIZER_HAS_STATFS64 1
28#else
29#define SANITIZER_HAS_STAT64 0
30#define SANITIZER_HAS_STATFS64 0
31#endif
32#elif SANITIZER_GLIBC || SANITIZER_ANDROID
33#define SANITIZER_HAS_STAT64 1
34#define SANITIZER_HAS_STATFS64 1
35#endif
17#if SANITIZER_LINUX || SANITIZER_APPLE || SANITIZER_HAIKU
18
19# include "sanitizer_internal_defs.h"
20# include "sanitizer_mallinfo.h"
21# include "sanitizer_platform.h"
22
23# if SANITIZER_APPLE
24# include <sys/cdefs.h>
25# if !__DARWIN_ONLY_64_BIT_INO_T
26# define SANITIZER_HAS_STAT64 1
27# define SANITIZER_HAS_STATFS64 1
28# else
29# define SANITIZER_HAS_STAT64 0
30# define SANITIZER_HAS_STATFS64 0
31# endif
32# elif SANITIZER_GLIBC || SANITIZER_ANDROID
33# define SANITIZER_HAS_STAT64 1
34# define SANITIZER_HAS_STATFS64 1
35# endif
3636
37#if defined(__sparc__)
37# if defined(__sparc__)
3838// FIXME: This can't be included from tsan which does not support sparc yet.
39#include "sanitizer_glibc_version.h"
40#endif
39# include "sanitizer_glibc_version.h"
40# endif
4141
42# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) ((link_map*)(handle))
42# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) ((link_map *)(handle))
4343
4444namespace __sanitizer {
4545extern unsigned struct_utsname_sz;
4646extern unsigned struct_stat_sz;
47#if SANITIZER_HAS_STAT64
47# if SANITIZER_HAS_STAT64
4848extern unsigned struct_stat64_sz;
49#endif
49# endif
5050extern unsigned struct_rusage_sz;
5151extern unsigned siginfo_t_sz;
5252extern unsigned struct_itimerval_sz;
......@@ -64,13 +64,13 @@ extern unsigned struct_itimerspec_sz;
6464extern unsigned struct_sigevent_sz;
6565extern unsigned struct_stack_t_sz;
6666extern unsigned struct_sched_param_sz;
67#if SANITIZER_HAS_STATFS64
67# if SANITIZER_HAS_STATFS64
6868extern unsigned struct_statfs64_sz;
69#endif
69# endif
7070extern unsigned struct_regex_sz;
7171extern unsigned struct_regmatch_sz;
7272
73#if !SANITIZER_ANDROID
73# if !SANITIZER_ANDROID
7474extern unsigned struct_fstab_sz;
7575extern unsigned struct_statfs_sz;
7676extern unsigned struct_sockaddr_sz;
......@@ -82,22 +82,22 @@ unsigned ucontext_t_sz(void *uctx);
8282# if defined(__x86_64__)
8383const unsigned struct_kernel_stat_sz = 144;
8484const unsigned struct_kernel_stat64_sz = 0;
85#elif defined(__i386__)
85# elif defined(__i386__)
8686const unsigned struct_kernel_stat_sz = 64;
8787const unsigned struct_kernel_stat64_sz = 96;
88#elif defined(__arm__)
88# elif defined(__arm__)
8989const unsigned struct_kernel_stat_sz = 64;
9090const unsigned struct_kernel_stat64_sz = 104;
91#elif defined(__aarch64__)
91# elif defined(__aarch64__)
9292const unsigned struct_kernel_stat_sz = 128;
9393const unsigned struct_kernel_stat64_sz = 104;
94#elif defined(__powerpc__) && !defined(__powerpc64__)
94# elif defined(__powerpc__) && !defined(__powerpc64__)
9595const unsigned struct_kernel_stat_sz = 72;
9696const unsigned struct_kernel_stat64_sz = 104;
97#elif defined(__powerpc64__)
97# elif defined(__powerpc64__)
9898const unsigned struct_kernel_stat_sz = 144;
9999const unsigned struct_kernel_stat64_sz = 104;
100#elif defined(__mips__)
100# elif defined(__mips__)
101101const unsigned struct_kernel_stat_sz = SANITIZER_ANDROID
102102 ? FIRST_32_SECOND_64(104, 128)
103103# if defined(_ABIN32) && _MIPS_SIM == _ABIN32
......@@ -106,21 +106,21 @@ const unsigned struct_kernel_stat_sz = SANITIZER_ANDROID
106106 : FIRST_32_SECOND_64(160, 216);
107107# endif
108108const unsigned struct_kernel_stat64_sz = 104;
109#elif defined(__s390__) && !defined(__s390x__)
109# elif defined(__s390__) && !defined(__s390x__)
110110const unsigned struct_kernel_stat_sz = 64;
111111const unsigned struct_kernel_stat64_sz = 104;
112#elif defined(__s390x__)
112# elif defined(__s390x__)
113113const unsigned struct_kernel_stat_sz = 144;
114114const unsigned struct_kernel_stat64_sz = 0;
115#elif defined(__sparc__) && defined(__arch64__)
115# elif defined(__sparc__) && defined(__arch64__)
116116const unsigned struct___old_kernel_stat_sz = 0;
117117const unsigned struct_kernel_stat_sz = 104;
118118const unsigned struct_kernel_stat64_sz = 144;
119#elif defined(__sparc__) && !defined(__arch64__)
119# elif defined(__sparc__) && !defined(__arch64__)
120120const unsigned struct___old_kernel_stat_sz = 0;
121121const unsigned struct_kernel_stat_sz = 64;
122122const unsigned struct_kernel_stat64_sz = 104;
123#elif SANITIZER_RISCV64
123# elif SANITIZER_RISCV64
124124const unsigned struct_kernel_stat_sz = 128;
125125const unsigned struct_kernel_stat64_sz = 0; // RISCV64 does not use stat64
126126# elif defined(__hexagon__)
......@@ -145,15 +145,15 @@ extern unsigned struct_old_utsname_sz;
145145extern unsigned struct_oldold_utsname_sz;
146146
147147const unsigned struct_kexec_segment_sz = 4 * sizeof(unsigned long);
148#endif // SANITIZER_LINUX
148# endif // SANITIZER_LINUX
149149
150#if SANITIZER_LINUX
150# if SANITIZER_LINUX
151151
152#if defined(__powerpc64__) || defined(__s390__) || defined(__loongarch__)
152# if defined(__powerpc64__) || defined(__s390__) || defined(__loongarch__)
153153const unsigned struct___old_kernel_stat_sz = 0;
154#elif !defined(__sparc__)
154# elif !defined(__sparc__)
155155const unsigned struct___old_kernel_stat_sz = 32;
156#endif
156# endif
157157
158158extern unsigned struct_rlimit_sz;
159159extern unsigned struct_utimbuf_sz;
......@@ -198,17 +198,17 @@ struct __sanitizer___sysctl_args {
198198const unsigned old_sigset_t_sz = sizeof(unsigned long);
199199
200200struct __sanitizer_sem_t {
201#if SANITIZER_ANDROID && defined(_LP64)
201# if SANITIZER_ANDROID && defined(_LP64)
202202 int data[4];
203#elif SANITIZER_ANDROID && !defined(_LP64)
203# elif SANITIZER_ANDROID && !defined(_LP64)
204204 int data;
205#elif SANITIZER_LINUX
205# elif SANITIZER_LINUX
206206 uptr data[4];
207#endif
207# endif
208208};
209#endif // SANITIZER_LINUX
209# endif // SANITIZER_LINUX
210210
211#if SANITIZER_LINUX && !SANITIZER_ANDROID
211# if SANITIZER_LINUX && !SANITIZER_ANDROID
212212extern unsigned struct_ustat_sz;
213213extern unsigned struct_rlimit64_sz;
214214extern unsigned struct_statvfs64_sz;
......@@ -219,45 +219,45 @@ struct __sanitizer_ipc_perm {
219219 int gid;
220220 int cuid;
221221 int cgid;
222#ifdef __powerpc__
222# ifdef __powerpc__
223223 unsigned mode;
224224 unsigned __seq;
225225 u64 __unused1;
226226 u64 __unused2;
227#elif defined(__sparc__)
227# elif defined(__sparc__)
228228 unsigned mode;
229229 unsigned short __pad2;
230230 unsigned short __seq;
231231 unsigned long long __unused1;
232232 unsigned long long __unused2;
233#else
233# else
234234 unsigned int mode;
235235 unsigned short __seq;
236236 unsigned short __pad2;
237#if defined(__x86_64__) && !defined(_LP64)
237# if defined(__x86_64__) && !defined(_LP64)
238238 u64 __unused1;
239239 u64 __unused2;
240#else
240# else
241241 unsigned long __unused1;
242242 unsigned long __unused2;
243#endif
244#endif
243# endif
244# endif
245245};
246246
247247struct __sanitizer_shmid_ds {
248248 __sanitizer_ipc_perm shm_perm;
249#if defined(__sparc__)
250#if !defined(__arch64__)
249# if defined(__sparc__)
250# if !defined(__arch64__)
251251 u32 __pad1;
252#endif
252# endif
253253 long shm_atime;
254#if !defined(__arch64__)
254# if !defined(__arch64__)
255255 u32 __pad2;
256#endif
256# endif
257257 long shm_dtime;
258#if !defined(__arch64__)
258# if !defined(__arch64__)
259259 u32 __pad3;
260#endif
260# endif
261261 long shm_ctime;
262262 uptr shm_segsz;
263263 int shm_cpid;
......@@ -265,61 +265,61 @@ struct __sanitizer_shmid_ds {
265265 unsigned long shm_nattch;
266266 unsigned long __glibc_reserved1;
267267 unsigned long __glibc_reserved2;
268#else
269#ifndef __powerpc__
268# else
269# ifndef __powerpc__
270270 uptr shm_segsz;
271#elif !defined(__powerpc64__)
271# elif !defined(__powerpc64__)
272272 uptr __unused0;
273#endif
274#if defined(__x86_64__) && !defined(_LP64)
273# endif
274# if defined(__x86_64__) && !defined(_LP64)
275275 u64 shm_atime;
276276 u64 shm_dtime;
277277 u64 shm_ctime;
278#else
278# else
279279 uptr shm_atime;
280#if !defined(_LP64) && !defined(__mips__)
280# if !defined(_LP64) && !defined(__mips__)
281281 uptr __unused1;
282#endif
282# endif
283283 uptr shm_dtime;
284#if !defined(_LP64) && !defined(__mips__)
284# if !defined(_LP64) && !defined(__mips__)
285285 uptr __unused2;
286#endif
286# endif
287287 uptr shm_ctime;
288#if !defined(_LP64) && !defined(__mips__)
288# if !defined(_LP64) && !defined(__mips__)
289289 uptr __unused3;
290#endif
291#endif
292#ifdef __powerpc__
290# endif
291# endif
292# ifdef __powerpc__
293293 uptr shm_segsz;
294#endif
294# endif
295295 int shm_cpid;
296296 int shm_lpid;
297#if defined(__x86_64__) && !defined(_LP64)
297# if defined(__x86_64__) && !defined(_LP64)
298298 u64 shm_nattch;
299299 u64 __unused4;
300300 u64 __unused5;
301#else
301# else
302302 uptr shm_nattch;
303303 uptr __unused4;
304304 uptr __unused5;
305#endif
306#endif
305# endif
306# endif
307307};
308#endif
308# endif
309309
310#if SANITIZER_LINUX && !SANITIZER_ANDROID
310# if SANITIZER_LINUX && !SANITIZER_ANDROID
311311extern unsigned struct_msqid_ds_sz;
312312extern unsigned struct_mq_attr_sz;
313313extern unsigned struct_timex_sz;
314314extern unsigned struct_statvfs_sz;
315#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
315# endif // SANITIZER_LINUX && !SANITIZER_ANDROID
316316
317317struct __sanitizer_iovec {
318318 void *iov_base;
319319 usize iov_len;
320320};
321321
322#if !SANITIZER_ANDROID
322# if !SANITIZER_ANDROID
323323struct __sanitizer_ifaddrs {
324324 struct __sanitizer_ifaddrs *ifa_next;
325325 char *ifa_name;
......@@ -327,21 +327,21 @@ struct __sanitizer_ifaddrs {
327327 void *ifa_addr; // (struct sockaddr *)
328328 void *ifa_netmask; // (struct sockaddr *)
329329 // This is a union on Linux.
330# ifdef ifa_dstaddr
331# undef ifa_dstaddr
332# endif
330# ifdef ifa_dstaddr
331# undef ifa_dstaddr
332# endif
333333 void *ifa_dstaddr; // (struct sockaddr *)
334334 void *ifa_data;
335335};
336#endif // !SANITIZER_ANDROID
336# endif // !SANITIZER_ANDROID
337337
338#if SANITIZER_APPLE
338# if SANITIZER_APPLE
339339typedef unsigned long __sanitizer_pthread_key_t;
340#else
340# else
341341typedef unsigned __sanitizer_pthread_key_t;
342#endif
342# endif
343343
344#if SANITIZER_LINUX && !SANITIZER_ANDROID
344# if SANITIZER_LINUX && !SANITIZER_ANDROID
345345
346346struct __sanitizer_XDR {
347347 int x_op;
......@@ -355,25 +355,28 @@ struct __sanitizer_XDR {
355355const int __sanitizer_XDR_ENCODE = 0;
356356const int __sanitizer_XDR_DECODE = 1;
357357const int __sanitizer_XDR_FREE = 2;
358#endif
358# endif
359359
360360struct __sanitizer_passwd {
361361 char *pw_name;
362362 char *pw_passwd;
363363 int pw_uid;
364364 int pw_gid;
365#if SANITIZER_APPLE
365# if SANITIZER_APPLE
366366 long pw_change;
367367 char *pw_class;
368#endif
369#if !(SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32))
368# endif
369# if !(SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32)) && !SANITIZER_HAIKU
370370 char *pw_gecos;
371#endif
371# endif
372372 char *pw_dir;
373373 char *pw_shell;
374#if SANITIZER_APPLE
374# if SANITIZER_APPLE
375375 long pw_expire;
376#endif
376# endif
377# if SANITIZER_HAIKU
378 char *pw_gecos;
379# endif
377380};
378381
379382struct __sanitizer_group {
......@@ -386,9 +389,9 @@ struct __sanitizer_group {
386389# if (SANITIZER_LINUX && !SANITIZER_GLIBC && !SANITIZER_ANDROID) || \
387390 (defined(__x86_64__) && !defined(_LP64)) || defined(__hexagon__)
388391typedef long long __sanitizer_time_t;
389#else
392# else
390393typedef long __sanitizer_time_t;
391#endif
394# endif
392395
393396typedef long __sanitizer_suseconds_t;
394397
......@@ -433,11 +436,15 @@ struct __sanitizer_tm {
433436 int tm_wday;
434437 int tm_yday;
435438 int tm_isdst;
439# if SANITIZER_HAIKU
440 int tm_gmtoff;
441# else
436442 long int tm_gmtoff;
443# endif
437444 const char *tm_zone;
438445};
439446
440#if SANITIZER_LINUX
447# if SANITIZER_LINUX
441448struct __sanitizer_mntent {
442449 char *mnt_fsname;
443450 char *mnt_dir;
......@@ -452,9 +459,9 @@ struct __sanitizer_file_handle {
452459 int handle_type;
453460 unsigned char f_handle[1]; // variable sized
454461};
455#endif
462# endif
456463
457#if SANITIZER_APPLE
464# if SANITIZER_APPLE || SANITIZER_HAIKU
458465struct __sanitizer_msghdr {
459466 void *msg_name;
460467 unsigned msg_namelen;
......@@ -469,7 +476,7 @@ struct __sanitizer_cmsghdr {
469476 int cmsg_level;
470477 int cmsg_type;
471478};
472#else
479# else
473480// In POSIX, int msg_iovlen; socklen_t msg_controllen; socklen_t cmsg_len; but
474481// many implementations don't conform to the standard.
475482struct __sanitizer_msghdr {
......@@ -486,22 +493,31 @@ struct __sanitizer_cmsghdr {
486493 int cmsg_level;
487494 int cmsg_type;
488495};
489#endif
496# endif
490497
491#if SANITIZER_LINUX
498# if SANITIZER_LINUX
492499struct __sanitizer_mmsghdr {
493500 __sanitizer_msghdr msg_hdr;
494501 unsigned int msg_len;
495502};
496#endif
503# endif
497504
498#if SANITIZER_APPLE
505# if SANITIZER_APPLE
499506struct __sanitizer_dirent {
500507 unsigned long long d_ino;
501508 unsigned long long d_seekoff;
502509 unsigned short d_reclen;
503510 // more fields that we don't care about
504511};
512# elif SANITIZER_HAIKU
513struct __sanitizer_dirent {
514 int d_dev;
515 int d_pdev;
516 unsigned long long d_ino;
517 unsigned long long d_pino;
518 unsigned short d_reclen;
519 // more fields that we don't care about
520};
505521# elif (SANITIZER_LINUX && !SANITIZER_GLIBC) || defined(__x86_64__) || \
506522 defined(__hexagon__)
507523struct __sanitizer_dirent {
......@@ -527,47 +543,49 @@ struct __sanitizer_dirent64 {
527543 // more fields that we don't care about
528544};
529545extern unsigned struct_sock_fprog_sz;
530#endif
546# endif
531547
532#if defined(__x86_64__) && !defined(_LP64)
548# if SANITIZER_HAIKU
549typedef int __sanitizer_clock_t;
550# elif defined(__x86_64__) && !defined(_LP64)
533551typedef long long __sanitizer_clock_t;
534#else
552# else
535553typedef long __sanitizer_clock_t;
536#endif
554# endif
537555
538#if SANITIZER_LINUX
556# if SANITIZER_LINUX || SANITIZER_HAIKU
539557typedef int __sanitizer_clockid_t;
540558typedef unsigned long long __sanitizer_eventfd_t;
541#endif
559# endif
542560
543#if SANITIZER_LINUX
561# if SANITIZER_LINUX
544562# if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \
545563 defined(__mips__) || defined(__hexagon__)
546564typedef unsigned __sanitizer___kernel_uid_t;
547565typedef unsigned __sanitizer___kernel_gid_t;
548#else
566# else
549567typedef unsigned short __sanitizer___kernel_uid_t;
550568typedef unsigned short __sanitizer___kernel_gid_t;
551#endif
552#if defined(__x86_64__) && !defined(_LP64)
569# endif
570# if defined(__x86_64__) && !defined(_LP64)
553571typedef long long __sanitizer___kernel_off_t;
554#else
572# else
555573typedef long __sanitizer___kernel_off_t;
556#endif
574# endif
557575
558#if defined(__powerpc__) || defined(__mips__)
576# if defined(__powerpc__) || defined(__mips__)
559577typedef unsigned int __sanitizer___kernel_old_uid_t;
560578typedef unsigned int __sanitizer___kernel_old_gid_t;
561#else
579# else
562580typedef unsigned short __sanitizer___kernel_old_uid_t;
563581typedef unsigned short __sanitizer___kernel_old_gid_t;
564#endif
582# endif
565583
566584typedef long long __sanitizer___kernel_loff_t;
567585typedef struct {
568586 unsigned long fds_bits[1024 / (8 * sizeof(long))];
569587} __sanitizer___kernel_fd_set;
570#endif
588# endif
571589
572590// This thing depends on the platform. We are only interested in the upper
573591// limit. Verified with a compiler assert in .cpp.
......@@ -576,50 +594,52 @@ union __sanitizer_pthread_attr_t {
576594 void *align;
577595};
578596
579#if SANITIZER_ANDROID
580# if SANITIZER_MIPS
597# if SANITIZER_ANDROID
598# if SANITIZER_MIPS
581599typedef unsigned long __sanitizer_sigset_t[16 / sizeof(unsigned long)];
582# else
600# else
583601typedef unsigned long __sanitizer_sigset_t;
584# endif
585#elif SANITIZER_APPLE
602# endif
603# elif SANITIZER_APPLE
586604typedef unsigned __sanitizer_sigset_t;
587#elif SANITIZER_LINUX
605# elif SANITIZER_HAIKU
606typedef unsigned long __sanitizer_sigset_t;
607# elif SANITIZER_LINUX
588608struct __sanitizer_sigset_t {
589609 // The size is determined by looking at sizeof of real sigset_t on linux.
590610 uptr val[128 / sizeof(uptr)];
591611};
592#endif
612# endif
593613
594614struct __sanitizer_siginfo_pad {
595#if SANITIZER_X32
615# if SANITIZER_X32
596616 // x32 siginfo_t is aligned to 8 bytes.
597617 u64 pad[128 / sizeof(u64)];
598#else
618# else
599619 // Require uptr, because siginfo_t is always pointer-size aligned on Linux.
600620 uptr pad[128 / sizeof(uptr)];
601#endif
621# endif
602622};
603623
604#if SANITIZER_LINUX
605# define SANITIZER_HAS_SIGINFO 1
624# if SANITIZER_LINUX
625# define SANITIZER_HAS_SIGINFO 1
606626union __sanitizer_siginfo {
607627 __extension__ struct {
608628 int si_signo;
609# if SANITIZER_MIPS
629# if SANITIZER_MIPS
610630 int si_code;
611631 int si_errno;
612# else
632# else
613633 int si_errno;
614634 int si_code;
615# endif
635# endif
616636 };
617637 __sanitizer_siginfo_pad pad;
618638};
619#else
620# define SANITIZER_HAS_SIGINFO 0
639# else
640# define SANITIZER_HAS_SIGINFO 0
621641typedef __sanitizer_siginfo_pad __sanitizer_siginfo;
622#endif
642# endif
623643
624644using __sanitizer_sighandler_ptr = void (*)(int sig);
625645using __sanitizer_sigactionhandler_ptr = void (*)(int sig,
......@@ -627,7 +647,7 @@ using __sanitizer_sigactionhandler_ptr = void (*)(int sig,
627647 void *uctx);
628648
629649// Linux system headers define the 'sa_handler' and 'sa_sigaction' macros.
630#if SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 64)
650# if SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 64)
631651struct __sanitizer_sigaction {
632652 unsigned sa_flags;
633653 union {
......@@ -637,7 +657,8 @@ struct __sanitizer_sigaction {
637657 __sanitizer_sigset_t sa_mask;
638658 void (*sa_restorer)();
639659};
640#elif SANITIZER_ANDROID && SANITIZER_MIPS32 // check this before WORDSIZE == 32
660# elif SANITIZER_ANDROID && \
661 SANITIZER_MIPS32 // check this before WORDSIZE == 32
641662struct __sanitizer_sigaction {
642663 unsigned sa_flags;
643664 union {
......@@ -646,7 +667,7 @@ struct __sanitizer_sigaction {
646667 };
647668 __sanitizer_sigset_t sa_mask;
648669};
649#elif SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32)
670# elif SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32)
650671struct __sanitizer_sigaction {
651672 union {
652673 __sanitizer_sigactionhandler_ptr sigaction;
......@@ -656,66 +677,66 @@ struct __sanitizer_sigaction {
656677 uptr sa_flags;
657678 void (*sa_restorer)();
658679};
659#else // !SANITIZER_ANDROID
680# else // !SANITIZER_ANDROID
660681struct __sanitizer_sigaction {
661#if defined(__mips__) && !SANITIZER_FREEBSD
682# if defined(__mips__) && !SANITIZER_FREEBSD && !SANITIZER_MUSL
662683 unsigned int sa_flags;
663#endif
684# endif
664685 union {
665686 __sanitizer_sigactionhandler_ptr sigaction;
666687 __sanitizer_sighandler_ptr handler;
667688 };
668#if SANITIZER_FREEBSD
689# if SANITIZER_FREEBSD
669690 int sa_flags;
670691 __sanitizer_sigset_t sa_mask;
671#else
672#if defined(__s390x__)
692# else
693# if defined(__s390x__)
673694 int sa_resv;
674#else
695# else
675696 __sanitizer_sigset_t sa_mask;
676#endif
677#ifndef __mips__
678#if defined(__sparc__)
679#if __GLIBC_PREREQ (2, 20)
697# endif
698# if !defined(__mips__) || SANITIZER_MUSL
699# if defined(__sparc__)
700# if __GLIBC_PREREQ(2, 20)
680701 // On sparc glibc 2.19 and earlier sa_flags was unsigned long.
681#if defined(__arch64__)
702# if defined(__arch64__)
682703 // To maintain ABI compatibility on sparc64 when switching to an int,
683704 // __glibc_reserved0 was added.
684705 int __glibc_reserved0;
685#endif
706# endif
686707 int sa_flags;
687#else
708# else
688709 unsigned long sa_flags;
689#endif
690#else
710# endif
711# else
691712 int sa_flags;
692#endif
693#endif
694#endif
695#if SANITIZER_LINUX
713# endif
714# endif
715# endif
716# if SANITIZER_LINUX || SANITIZER_HAIKU
696717 void (*sa_restorer)();
697#endif
698#if defined(__mips__) && (SANITIZER_WORDSIZE == 32)
718# endif
719# if defined(__mips__) && (SANITIZER_WORDSIZE == 32) && !SANITIZER_MUSL
699720 int sa_resv[1];
700#endif
701#if defined(__s390x__)
721# endif
722# if defined(__s390x__)
702723 __sanitizer_sigset_t sa_mask;
703#endif
724# endif
704725};
705#endif // !SANITIZER_ANDROID
726# endif // !SANITIZER_ANDROID
706727
707#if defined(__mips__)
708#define __SANITIZER_KERNEL_NSIG 128
709#else
710#define __SANITIZER_KERNEL_NSIG 64
711#endif
728# if defined(__mips__)
729# define __SANITIZER_KERNEL_NSIG 128
730# else
731# define __SANITIZER_KERNEL_NSIG 64
732# endif
712733
713734struct __sanitizer_kernel_sigset_t {
714735 uptr sig[__SANITIZER_KERNEL_NSIG / (sizeof(uptr) * 8)];
715736};
716737
717738// Linux system headers define the 'sa_handler' and 'sa_sigaction' macros.
718#if SANITIZER_MIPS
739# if SANITIZER_MIPS
719740struct __sanitizer_kernel_sigaction_t {
720741 unsigned int sa_flags;
721742 union {
......@@ -725,7 +746,7 @@ struct __sanitizer_kernel_sigaction_t {
725746 __sanitizer_kernel_sigset_t sa_mask;
726747 void (*sa_restorer)(void);
727748};
728#else
749# else
729750struct __sanitizer_kernel_sigaction_t {
730751 union {
731752 void (*handler)(int signo);
......@@ -735,22 +756,22 @@ struct __sanitizer_kernel_sigaction_t {
735756 void (*sa_restorer)(void);
736757 __sanitizer_kernel_sigset_t sa_mask;
737758};
738#endif
759# endif
739760
740761extern const uptr sig_ign;
741762extern const uptr sig_dfl;
742763extern const uptr sig_err;
743764extern const uptr sa_siginfo;
744765
745#if SANITIZER_LINUX
766# if SANITIZER_LINUX
746767extern int e_tabsz;
747#endif
768# endif
748769
749770extern int af_inet;
750771extern int af_inet6;
751772uptr __sanitizer_in_addr_sz(int af);
752773
753#if SANITIZER_LINUX
774# if SANITIZER_LINUX
754775struct __sanitizer_dl_phdr_info {
755776 uptr dlpi_addr;
756777 const char *dlpi_name;
......@@ -759,7 +780,7 @@ struct __sanitizer_dl_phdr_info {
759780};
760781
761782extern unsigned struct_ElfW_Phdr_sz;
762#endif
783# endif
763784
764785struct __sanitizer_protoent {
765786 char *p_name;
......@@ -779,15 +800,15 @@ struct __sanitizer_addrinfo {
779800 int ai_family;
780801 int ai_socktype;
781802 int ai_protocol;
782#if SANITIZER_ANDROID || SANITIZER_APPLE
803# if SANITIZER_ANDROID || SANITIZER_APPLE || SANITIZER_HAIKU
783804 unsigned ai_addrlen;
784805 char *ai_canonname;
785806 void *ai_addr;
786#else // LINUX
807# else // LINUX
787808 unsigned ai_addrlen;
788809 void *ai_addr;
789810 char *ai_canonname;
790#endif
811# endif
791812 struct __sanitizer_addrinfo *ai_next;
792813};
793814
......@@ -805,14 +826,14 @@ struct __sanitizer_pollfd {
805826 short revents;
806827};
807828
808#if SANITIZER_ANDROID || SANITIZER_APPLE
829# if SANITIZER_ANDROID || SANITIZER_APPLE
809830typedef unsigned __sanitizer_nfds_t;
810#else
831# else
811832typedef unsigned long __sanitizer_nfds_t;
812#endif
833# endif
813834
814#if !SANITIZER_ANDROID
815# if SANITIZER_LINUX
835# if !SANITIZER_ANDROID
836# if SANITIZER_LINUX
816837struct __sanitizer_glob_t {
817838 uptr gl_pathc;
818839 char **gl_pathv;
......@@ -825,13 +846,13 @@ struct __sanitizer_glob_t {
825846 int (*gl_lstat)(const char *, void *);
826847 int (*gl_stat)(const char *, void *);
827848};
828# endif // SANITIZER_LINUX
849# endif // SANITIZER_LINUX
829850
830# if SANITIZER_LINUX
851# if SANITIZER_LINUX
831852extern int glob_nomatch;
832853extern int glob_altdirfunc;
833# endif
834#endif // !SANITIZER_ANDROID
854# endif
855# endif // !SANITIZER_ANDROID
835856
836857extern unsigned path_max;
837858
......@@ -845,7 +866,7 @@ struct __sanitizer_wordexp_t {
845866 uptr we_offs;
846867};
847868
848#if SANITIZER_LINUX && !SANITIZER_ANDROID
869# if SANITIZER_LINUX && !SANITIZER_ANDROID
849870struct __sanitizer_FILE {
850871 int _flags;
851872 char *_IO_read_ptr;
......@@ -863,11 +884,11 @@ struct __sanitizer_FILE {
863884 __sanitizer_FILE *_chain;
864885 int _fileno;
865886};
866# define SANITIZER_HAS_STRUCT_FILE 1
867#else
887# define SANITIZER_HAS_STRUCT_FILE 1
888# else
868889typedef void __sanitizer_FILE;
869# define SANITIZER_HAS_STRUCT_FILE 0
870#endif
890# define SANITIZER_HAS_STRUCT_FILE 0
891# endif
871892
872893# if SANITIZER_LINUX && !SANITIZER_ANDROID && \
873894 (defined(__i386) || defined(__x86_64) || defined(__mips64) || \
......@@ -919,14 +940,14 @@ extern int shmctl_ipc_stat;
919940extern int shmctl_ipc_info;
920941extern int shmctl_shm_info;
921942extern int shmctl_shm_stat;
922#endif
943# endif
923944
924#if !SANITIZER_APPLE && !SANITIZER_FREEBSD
945# if !SANITIZER_APPLE && !SANITIZER_FREEBSD
925946extern unsigned struct_utmp_sz;
926#endif
927#if !SANITIZER_ANDROID
947# endif
948# if !SANITIZER_ANDROID
928949extern unsigned struct_utmpx_sz;
929#endif
950# endif
930951
931952extern int map_fixed;
932953
......@@ -936,13 +957,13 @@ struct __sanitizer_ifconf {
936957 union {
937958 void *ifcu_req;
938959 } ifc_ifcu;
939#if SANITIZER_APPLE
960# if SANITIZER_APPLE
940961} __attribute__((packed));
941#else
962# else
942963};
943#endif
964# endif
944965
945#if SANITIZER_LINUX && !SANITIZER_ANDROID
966# if SANITIZER_LINUX && !SANITIZER_ANDROID
946967struct __sanitizer__obstack_chunk {
947968 char *limit;
948969 struct __sanitizer__obstack_chunk *prev;
......@@ -969,57 +990,57 @@ struct __sanitizer_cookie_io_functions_t {
969990 __sanitizer_cookie_io_seek seek;
970991 __sanitizer_cookie_io_close close;
971992};
972#endif
993# endif
973994
974#define IOC_NRBITS 8
975#define IOC_TYPEBITS 8
976#if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) || \
977 defined(__sparc__)
978#define IOC_SIZEBITS 13
979#define IOC_DIRBITS 3
980#define IOC_NONE 1U
981#define IOC_WRITE 4U
982#define IOC_READ 2U
983#else
984#define IOC_SIZEBITS 14
985#define IOC_DIRBITS 2
986#define IOC_NONE 0U
987#define IOC_WRITE 1U
988#define IOC_READ 2U
989#endif
990#define IOC_NRMASK ((1 << IOC_NRBITS) - 1)
991#define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1)
992#define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1)
993#if defined(IOC_DIRMASK)
994#undef IOC_DIRMASK
995#endif
996#define IOC_DIRMASK ((1 << IOC_DIRBITS) - 1)
997#define IOC_NRSHIFT 0
998#define IOC_TYPESHIFT (IOC_NRSHIFT + IOC_NRBITS)
999#define IOC_SIZESHIFT (IOC_TYPESHIFT + IOC_TYPEBITS)
1000#define IOC_DIRSHIFT (IOC_SIZESHIFT + IOC_SIZEBITS)
1001#define EVIOC_EV_MAX 0x1f
1002#define EVIOC_ABS_MAX 0x3f
1003
1004#define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK)
1005#define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK)
1006#define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK)
1007
1008#if defined(__sparc__)
995# define IOC_NRBITS 8
996# define IOC_TYPEBITS 8
997# if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) || \
998 defined(__sparc__)
999# define IOC_SIZEBITS 13
1000# define IOC_DIRBITS 3
1001# define IOC_NONE 1U
1002# define IOC_WRITE 4U
1003# define IOC_READ 2U
1004# else
1005# define IOC_SIZEBITS 14
1006# define IOC_DIRBITS 2
1007# define IOC_NONE 0U
1008# define IOC_WRITE 1U
1009# define IOC_READ 2U
1010# endif
1011# define IOC_NRMASK ((1 << IOC_NRBITS) - 1)
1012# define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1)
1013# define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1)
1014# if defined(IOC_DIRMASK)
1015# undef IOC_DIRMASK
1016# endif
1017# define IOC_DIRMASK ((1 << IOC_DIRBITS) - 1)
1018# define IOC_NRSHIFT 0
1019# define IOC_TYPESHIFT (IOC_NRSHIFT + IOC_NRBITS)
1020# define IOC_SIZESHIFT (IOC_TYPESHIFT + IOC_TYPEBITS)
1021# define IOC_DIRSHIFT (IOC_SIZESHIFT + IOC_SIZEBITS)
1022# define EVIOC_EV_MAX 0x1f
1023# define EVIOC_ABS_MAX 0x3f
1024
1025# define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK)
1026# define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK)
1027# define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK)
1028
1029# if defined(__sparc__)
10091030// In sparc the 14 bits SIZE field overlaps with the
10101031// least significant bit of DIR, so either IOC_READ or
10111032// IOC_WRITE shall be 1 in order to get a non-zero SIZE.
1012#define IOC_SIZE(nr) \
1013 ((((((nr) >> 29) & 0x7) & (4U | 2U)) == 0) ? 0 : (((nr) >> 16) & 0x3fff))
1014#else
1015#define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK)
1016#endif
1033# define IOC_SIZE(nr) \
1034 ((((((nr) >> 29) & 0x7) & (4U | 2U)) == 0) ? 0 : (((nr) >> 16) & 0x3fff))
1035# else
1036# define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK)
1037# endif
10171038
10181039extern unsigned struct_ifreq_sz;
10191040extern unsigned struct_termios_sz;
10201041extern unsigned struct_winsize_sz;
10211042
1022#if SANITIZER_LINUX
1043# if SANITIZER_LINUX
10231044extern unsigned struct_arpreq_sz;
10241045extern unsigned struct_cdrom_msf_sz;
10251046extern unsigned struct_cdrom_multisession_sz;
......@@ -1046,9 +1067,9 @@ extern unsigned struct_mtpos_sz;
10461067extern unsigned struct_vt_consize_sz;
10471068extern unsigned struct_vt_sizes_sz;
10481069extern unsigned struct_vt_stat_sz;
1049#endif // SANITIZER_LINUX
1070# endif // SANITIZER_LINUX
10501071
1051#if SANITIZER_LINUX
1072# if SANITIZER_LINUX
10521073extern unsigned struct_copr_buffer_sz;
10531074extern unsigned struct_copr_debug_buf_sz;
10541075extern unsigned struct_copr_msg_sz;
......@@ -1060,9 +1081,9 @@ extern unsigned struct_sbi_instrument_sz;
10601081extern unsigned struct_seq_event_rec_sz;
10611082extern unsigned struct_synth_info_sz;
10621083extern unsigned struct_vt_mode_sz;
1063#endif // SANITIZER_LINUX
1084# endif // SANITIZER_LINUX
10641085
1065#if SANITIZER_LINUX && !SANITIZER_ANDROID
1086# if SANITIZER_LINUX && !SANITIZER_ANDROID
10661087extern unsigned struct_ax25_parms_struct_sz;
10671088extern unsigned struct_input_keymap_entry_sz;
10681089extern unsigned struct_ipx_config_data_sz;
......@@ -1083,15 +1104,15 @@ extern unsigned struct_unimapinit_sz;
10831104
10841105extern const unsigned long __sanitizer_bufsiz;
10851106
1086#if SANITIZER_LINUX && !SANITIZER_ANDROID
1107# if SANITIZER_LINUX && !SANITIZER_ANDROID
10871108extern unsigned struct_audio_buf_info_sz;
10881109extern unsigned struct_ppp_stats_sz;
1089#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
1110# endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
10901111
1091#if !SANITIZER_ANDROID && !SANITIZER_APPLE
1112# if !SANITIZER_ANDROID && !SANITIZER_APPLE
10921113extern unsigned struct_sioc_sg_req_sz;
10931114extern unsigned struct_sioc_vif_req_sz;
1094#endif
1115# endif
10951116
10961117extern unsigned fpos_t_sz;
10971118
......@@ -1127,29 +1148,31 @@ extern unsigned IOCTL_SIOCSIFMETRIC;
11271148extern unsigned IOCTL_SIOCSIFMTU;
11281149extern unsigned IOCTL_SIOCSIFNETMASK;
11291150extern unsigned IOCTL_SIOCSPGRP;
1151# if !SANITIZER_HAIKU
11301152extern unsigned IOCTL_TIOCCONS;
1131extern unsigned IOCTL_TIOCEXCL;
11321153extern unsigned IOCTL_TIOCGETD;
1154extern unsigned IOCTL_TIOCNOTTY;
1155extern unsigned IOCTL_TIOCPKT;
1156extern unsigned IOCTL_TIOCSETD;
1157extern unsigned IOCTL_TIOCSTI;
1158# endif
1159extern unsigned IOCTL_TIOCEXCL;
11331160extern unsigned IOCTL_TIOCGPGRP;
11341161extern unsigned IOCTL_TIOCGWINSZ;
11351162extern unsigned IOCTL_TIOCMBIC;
11361163extern unsigned IOCTL_TIOCMBIS;
11371164extern unsigned IOCTL_TIOCMGET;
11381165extern unsigned IOCTL_TIOCMSET;
1139extern unsigned IOCTL_TIOCNOTTY;
11401166extern unsigned IOCTL_TIOCNXCL;
11411167extern unsigned IOCTL_TIOCOUTQ;
1142extern unsigned IOCTL_TIOCPKT;
11431168extern unsigned IOCTL_TIOCSCTTY;
1144extern unsigned IOCTL_TIOCSETD;
11451169extern unsigned IOCTL_TIOCSPGRP;
1146extern unsigned IOCTL_TIOCSTI;
11471170extern unsigned IOCTL_TIOCSWINSZ;
1148#if SANITIZER_LINUX && !SANITIZER_ANDROID
1171# if SANITIZER_LINUX && !SANITIZER_ANDROID
11491172extern unsigned IOCTL_SIOCGETSGCNT;
11501173extern unsigned IOCTL_SIOCGETVIFCNT;
1151#endif
1152#if SANITIZER_LINUX
1174# endif
1175# if SANITIZER_LINUX
11531176extern unsigned IOCTL_EVIOCGABS;
11541177extern unsigned IOCTL_EVIOCGBIT;
11551178extern unsigned IOCTL_EVIOCGEFFECTS;
......@@ -1415,9 +1438,9 @@ extern unsigned IOCTL_VT_OPENQRY;
14151438extern unsigned IOCTL_VT_RELDISP;
14161439extern unsigned IOCTL_VT_SETMODE;
14171440extern unsigned IOCTL_VT_WAITACTIVE;
1418#endif // SANITIZER_LINUX
1441# endif // SANITIZER_LINUX
14191442
1420#if SANITIZER_LINUX && !SANITIZER_ANDROID
1443# if SANITIZER_LINUX && !SANITIZER_ANDROID
14211444extern unsigned IOCTL_EQL_EMANCIPATE;
14221445extern unsigned IOCTL_EQL_ENSLAVE;
14231446extern unsigned IOCTL_EQL_GETMASTRCFG;
......@@ -1506,35 +1529,44 @@ extern unsigned IOCTL_KDSETMODE;
15061529extern unsigned IOCTL_KDSKBMODE;
15071530extern unsigned IOCTL_KIOCSOUND;
15081531extern unsigned IOCTL_PIO_SCRNMAP;
1509#endif
1532# endif
1533
1534# if SANITIZER_GLIBC
1535struct __sanitizer_servent {
1536 char *s_name;
1537 char **s_aliases;
1538 int s_port;
1539 char *s_proto;
1540};
1541# endif
15101542
15111543extern const int si_SEGV_MAPERR;
15121544extern const int si_SEGV_ACCERR;
15131545} // namespace __sanitizer
15141546
1515#define CHECK_TYPE_SIZE(TYPE) \
1516 COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE))
1547# define CHECK_TYPE_SIZE(TYPE) \
1548 COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE))
15171549
1518#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \
1519 COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *)NULL)->MEMBER) == \
1520 sizeof(((CLASS *)NULL)->MEMBER)); \
1521 COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \
1522 offsetof(CLASS, MEMBER))
1550# define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \
1551 COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *)NULL)->MEMBER) == \
1552 sizeof(((CLASS *)NULL)->MEMBER)); \
1553 COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \
1554 offsetof(CLASS, MEMBER))
15231555
15241556// For sigaction, which is a function and struct at the same time,
15251557// and thus requires explicit "struct" in sizeof() expression.
1526#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \
1527 COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *)NULL)->MEMBER) == \
1528 sizeof(((struct CLASS *)NULL)->MEMBER)); \
1529 COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \
1530 offsetof(struct CLASS, MEMBER))
1558# define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \
1559 COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *)NULL)->MEMBER) == \
1560 sizeof(((struct CLASS *)NULL)->MEMBER)); \
1561 COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \
1562 offsetof(struct CLASS, MEMBER))
15311563
1532#define SIGACTION_SYMNAME sigaction
1564# define SIGACTION_SYMNAME sigaction
15331565
15341566# if SANITIZER_LINUX
15351567typedef void *__sanitizer_timer_t;
15361568# endif
15371569
1538#endif // SANITIZER_LINUX || SANITIZER_APPLE
1570#endif // SANITIZER_LINUX || SANITIZER_APPLE || SANITIZER_HAIKU
15391571
15401572#endif
lib/libtsan/sanitizer_common/sanitizer_procmaps.h+1-1
......@@ -16,7 +16,7 @@
1616#include "sanitizer_platform.h"
1717
1818#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
19 SANITIZER_APPLE || SANITIZER_SOLARIS || \
19 SANITIZER_APPLE || SANITIZER_SOLARIS || SANITIZER_HAIKU || \
2020 SANITIZER_FUCHSIA
2121
2222#include "sanitizer_common.h"
lib/libtsan/sanitizer_common/sanitizer_procmaps_haiku.cpp created+94
......@@ -0,0 +1,94 @@
1//===-- sanitizer_procmaps_haiku.cpp --------------------------------------===//
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// Information about the process mappings
10// (Haiku-specific parts).
11//===----------------------------------------------------------------------===//
12
13#include "sanitizer_platform.h"
14#if SANITIZER_HAIKU
15# include "sanitizer_common.h"
16# include "sanitizer_procmaps.h"
17
18# include <kernel/OS.h>
19
20namespace __sanitizer {
21
22void MemoryMappedSegment::AddAddressRanges(LoadedModule *module) {
23 // data_ should be unused on this platform
24 CHECK(!data_);
25 module->addAddressRange(start, end, IsExecutable(), IsWritable());
26}
27
28MemoryMappingLayout::MemoryMappingLayout(bool) { Reset(); }
29
30void MemoryMappingLayout::Reset() { data_.cookie = 0; }
31
32MemoryMappingLayout::~MemoryMappingLayout() {}
33
34// static
35void MemoryMappingLayout::CacheMemoryMappings() {}
36
37bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
38 area_info info;
39 if (get_next_area_info(B_CURRENT_TEAM, &data_.cookie, &info) != B_OK)
40 return false;
41
42 segment->start = (uptr)info.address;
43 segment->end = (uptr)info.address + info.size;
44 segment->offset = 0;
45 segment->protection = 0;
46 if (info.protection & B_READ_AREA)
47 segment->protection |= kProtectionRead;
48 if (info.protection & B_WRITE_AREA)
49 segment->protection |= kProtectionWrite;
50 if (info.protection & B_EXECUTE_AREA)
51 segment->protection |= kProtectionExecute;
52 if (segment->filename) {
53 uptr len = Min((uptr)B_OS_NAME_LENGTH, segment->filename_size - 1);
54 internal_strncpy(segment->filename, info.name, len);
55 segment->filename[len] = 0;
56 }
57 return true;
58}
59
60bool MemoryMappingLayout::Error() const { return false; }
61
62void MemoryMappingLayout::DumpListOfModules(
63 InternalMmapVectorNoCtor<LoadedModule> *modules) {
64 Reset();
65 InternalMmapVector<char> module_name(kMaxPathLength);
66 MemoryMappedSegment segment(module_name.data(), module_name.size());
67 for (uptr i = 0; Next(&segment); i++) {
68 const char *cur_name = segment.filename;
69 if (cur_name[0] == '\0')
70 continue;
71 // Don't subtract 'cur_beg' from the first entry:
72 // * If a binary is compiled w/o -pie, then the first entry in
73 // process maps is likely the binary itself (all dynamic libs
74 // are mapped higher in address space). For such a binary,
75 // instruction offset in binary coincides with the actual
76 // instruction address in virtual memory (as code section
77 // is mapped to a fixed memory range).
78 // * If a binary is compiled with -pie, all the modules are
79 // mapped high at address space (in particular, higher than
80 // shadow memory of the tool), so the module can't be the
81 // first entry.
82 uptr base_address = (i ? segment.start : 0) - segment.offset;
83 LoadedModule cur_module;
84 cur_module.set(cur_name, base_address);
85 segment.AddAddressRanges(&cur_module);
86 modules->push_back(cur_module);
87 }
88}
89
90void GetMemoryProfile(fill_profile_f cb, uptr *stats) {}
91
92} // namespace __sanitizer
93
94#endif
lib/libtsan/sanitizer_common/sanitizer_procmaps_mac.cpp+28-8
......@@ -334,9 +334,22 @@ static const load_command *NextCommand(const load_command *lc) {
334334 return (const load_command *)((const char *)lc + lc->cmdsize);
335335}
336336
337static void FindUUID(const load_command *first_lc, u8 *uuid_output) {
338 for (const load_command *lc = first_lc; lc->cmd != 0; lc = NextCommand(lc)) {
339 if (lc->cmd != LC_UUID) continue;
337# ifdef MH_MAGIC_64
338static constexpr size_t header_size = sizeof(mach_header_64);
339# else
340static constexpr size_t header_size = sizeof(mach_header);
341# endif
342
343static void FindUUID(const load_command *first_lc, const mach_header *hdr,
344 u8 *uuid_output) {
345 uint32_t curcmd = 0;
346 for (const load_command *lc = first_lc; curcmd < hdr->ncmds;
347 curcmd++, lc = NextCommand(lc)) {
348 CHECK_LT((const char *)lc,
349 (const char *)hdr + header_size + hdr->sizeofcmds);
350
351 if (lc->cmd != LC_UUID)
352 continue;
340353
341354 const uuid_command *uuid_lc = (const uuid_command *)lc;
342355 const uint8_t *uuid = &uuid_lc->uuid[0];
......@@ -345,9 +358,16 @@ static void FindUUID(const load_command *first_lc, u8 *uuid_output) {
345358 }
346359}
347360
348static bool IsModuleInstrumented(const load_command *first_lc) {
349 for (const load_command *lc = first_lc; lc->cmd != 0; lc = NextCommand(lc)) {
350 if (lc->cmd != LC_LOAD_DYLIB) continue;
361static bool IsModuleInstrumented(const load_command *first_lc,
362 const mach_header *hdr) {
363 uint32_t curcmd = 0;
364 for (const load_command *lc = first_lc; curcmd < hdr->ncmds;
365 curcmd++, lc = NextCommand(lc)) {
366 CHECK_LT((const char *)lc,
367 (const char *)hdr + header_size + hdr->sizeofcmds);
368
369 if (lc->cmd != LC_LOAD_DYLIB)
370 continue;
351371
352372 const dylib_command *dylib_lc = (const dylib_command *)lc;
353373 uint32_t dylib_name_offset = dylib_lc->dylib.name.offset;
......@@ -393,10 +413,10 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
393413 continue;
394414 }
395415 }
396 FindUUID((const load_command *)data_.current_load_cmd_addr,
416 FindUUID((const load_command *)data_.current_load_cmd_addr, hdr,
397417 data_.current_uuid);
398418 data_.current_instrumented = IsModuleInstrumented(
399 (const load_command *)data_.current_load_cmd_addr);
419 (const load_command *)data_.current_load_cmd_addr, hdr);
400420 }
401421
402422 while (data_.current_load_cmd_count > 0) {
lib/libtsan/sanitizer_common/sanitizer_procmaps_solaris.cpp-3
......@@ -9,9 +9,6 @@
99// Information about the process mappings (Solaris-specific parts).
1010//===----------------------------------------------------------------------===//
1111
12// Before Solaris 11.4, <procfs.h> doesn't work in a largefile environment.
13#undef _FILE_OFFSET_BITS
14
1512// Avoid conflict between `_TIME_BITS` defined vs. `_FILE_OFFSET_BITS`
1613// undefined in some Linux configurations.
1714#undef _TIME_BITS
lib/libtsan/sanitizer_common/sanitizer_redefine_builtins.h+1-1
......@@ -15,7 +15,7 @@
1515# define SANITIZER_REDEFINE_BUILTINS_H
1616
1717// The asm hack only works with GCC and Clang.
18# if !defined(_WIN32)
18# if !defined(_WIN32) && !defined(_AIX)
1919
2020asm(R"(
2121 .set memcpy, __sanitizer_internal_memcpy
lib/libtsan/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp+23-24
......@@ -38,25 +38,28 @@
3838# include <asm/ptrace.h>
3939#endif
4040#include <sys/user.h> // for user_regs_struct
41#if SANITIZER_ANDROID && SANITIZER_MIPS
42# include <asm/reg.h> // for mips SP register in sys/user.h
43#endif
44#include <sys/wait.h> // for signal-related stuff
45
46#ifdef sa_handler
47# undef sa_handler
48#endif
49
50#ifdef sa_sigaction
51# undef sa_sigaction
52#endif
53
54#include "sanitizer_common.h"
55#include "sanitizer_flags.h"
56#include "sanitizer_libc.h"
57#include "sanitizer_linux.h"
58#include "sanitizer_mutex.h"
59#include "sanitizer_placement_new.h"
41# if SANITIZER_MIPS
42// clang-format off
43# include <asm/sgidefs.h> // <asm/sgidefs.h> must be included before <asm/reg.h>
44# include <asm/reg.h> // for mips SP register
45// clang-format on
46# endif
47# include <sys/wait.h> // for signal-related stuff
48
49# ifdef sa_handler
50# undef sa_handler
51# endif
52
53# ifdef sa_sigaction
54# undef sa_sigaction
55# endif
56
57# include "sanitizer_common.h"
58# include "sanitizer_flags.h"
59# include "sanitizer_libc.h"
60# include "sanitizer_linux.h"
61# include "sanitizer_mutex.h"
62# include "sanitizer_placement_new.h"
6063
6164// Sufficiently old kernel headers don't provide this value, but we can still
6265// call prctl with it. If the runtime kernel is new enough, the prctl call will
......@@ -511,11 +514,7 @@ typedef pt_regs regs_struct;
511514
512515#elif defined(__mips__)
513516typedef struct user regs_struct;
514# if SANITIZER_ANDROID
515# define REG_SP regs[EF_R29]
516# else
517# define REG_SP regs[EF_REG29]
518# endif
517# define REG_SP regs[EF_R29]
519518
520519#elif defined(__aarch64__)
521520typedef struct user_pt_regs regs_struct;
lib/libtsan/sanitizer_common/sanitizer_stoptheworld_win.cpp+2
......@@ -49,6 +49,8 @@ struct SuspendedThreadsListWindows final : public SuspendedThreadsList {
4949# define SP_REG Esp
5050# elif SANITIZER_ARM | SANITIZER_ARM64
5151# define SP_REG Sp
52# elif SANITIZER_MIPS32
53# define SP_REG IntSp
5254# else
5355# error Architecture not supported!
5456# endif
lib/libtsan/sanitizer_common/sanitizer_symbolizer_libcdep.cpp+45-41
......@@ -31,11 +31,12 @@ Symbolizer *Symbolizer::GetOrInit() {
3131
3232const char *ExtractToken(const char *str, const char *delims, char **result) {
3333 uptr prefix_len = internal_strcspn(str, delims);
34 *result = (char*)InternalAlloc(prefix_len + 1);
34 *result = (char *)InternalAlloc(prefix_len + 1);
3535 internal_memcpy(*result, str, prefix_len);
3636 (*result)[prefix_len] = '\0';
3737 const char *prefix_end = str + prefix_len;
38 if (*prefix_end != '\0') prefix_end++;
38 if (*prefix_end != '\0')
39 prefix_end++;
3940 return prefix_end;
4041}
4142
......@@ -78,7 +79,8 @@ const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter,
7879 internal_memcpy(*result, str, prefix_len);
7980 (*result)[prefix_len] = '\0';
8081 const char *prefix_end = str + prefix_len;
81 if (*prefix_end != '\0') prefix_end += internal_strlen(delimiter);
82 if (*prefix_end != '\0')
83 prefix_end += internal_strlen(delimiter);
8284 return prefix_end;
8385}
8486
......@@ -215,18 +217,20 @@ const LoadedModule *Symbolizer::FindModuleForAddress(uptr address) {
215217 modules_were_reloaded = true;
216218 }
217219 const LoadedModule *module = SearchForModule(modules_, address);
218 if (module) return module;
220 if (module)
221 return module;
219222
220223 // dlopen/dlclose interceptors invalidate the module list, but when
221224 // interception is disabled, we need to retry if the lookup fails in
222225 // case the module list changed.
223#if !SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
226# if !SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
224227 if (!modules_were_reloaded) {
225228 RefreshModules();
226229 module = SearchForModule(modules_, address);
227 if (module) return module;
230 if (module)
231 return module;
228232 }
229#endif
233# endif
230234
231235 if (fallback_modules_.size()) {
232236 module = SearchForModule(fallback_modules_, address);
......@@ -260,31 +264,31 @@ class LLVMSymbolizerProcess final : public SymbolizerProcess {
260264 // script/asan_symbolize.py and sanitizer_common.h.
261265 void GetArgV(const char *path_to_binary,
262266 const char *(&argv)[kArgVMax]) const override {
263#if defined(__x86_64h__)
264 const char* const kSymbolizerArch = "--default-arch=x86_64h";
265#elif defined(__x86_64__)
266 const char* const kSymbolizerArch = "--default-arch=x86_64";
267#elif defined(__i386__)
268 const char* const kSymbolizerArch = "--default-arch=i386";
269#elif SANITIZER_LOONGARCH64
267# if defined(__x86_64h__)
268 const char *const kSymbolizerArch = "--default-arch=x86_64h";
269# elif defined(__x86_64__)
270 const char *const kSymbolizerArch = "--default-arch=x86_64";
271# elif defined(__i386__)
272 const char *const kSymbolizerArch = "--default-arch=i386";
273# elif SANITIZER_LOONGARCH64
270274 const char *const kSymbolizerArch = "--default-arch=loongarch64";
271#elif SANITIZER_RISCV64
275# elif SANITIZER_RISCV64
272276 const char *const kSymbolizerArch = "--default-arch=riscv64";
273#elif defined(__aarch64__)
274 const char* const kSymbolizerArch = "--default-arch=arm64";
275#elif defined(__arm__)
276 const char* const kSymbolizerArch = "--default-arch=arm";
277#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
278 const char* const kSymbolizerArch = "--default-arch=powerpc64";
279#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
280 const char* const kSymbolizerArch = "--default-arch=powerpc64le";
281#elif defined(__s390x__)
282 const char* const kSymbolizerArch = "--default-arch=s390x";
283#elif defined(__s390__)
284 const char* const kSymbolizerArch = "--default-arch=s390";
285#else
286 const char* const kSymbolizerArch = "--default-arch=unknown";
287#endif
277# elif defined(__aarch64__)
278 const char *const kSymbolizerArch = "--default-arch=arm64";
279# elif defined(__arm__)
280 const char *const kSymbolizerArch = "--default-arch=arm";
281# elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
282 const char *const kSymbolizerArch = "--default-arch=powerpc64";
283# elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
284 const char *const kSymbolizerArch = "--default-arch=powerpc64le";
285# elif defined(__s390x__)
286 const char *const kSymbolizerArch = "--default-arch=s390x";
287# elif defined(__s390__)
288 const char *const kSymbolizerArch = "--default-arch=s390";
289# else
290 const char *const kSymbolizerArch = "--default-arch=unknown";
291# endif
288292
289293 const char *const demangle_flag =
290294 common_flags()->demangle ? "--demangle" : "--no-demangle";
......@@ -315,7 +319,8 @@ static const char *ParseFileLineInfo(AddressInfo *info, const char *str) {
315319 char *back = file_line_info + size - 1;
316320 for (int i = 0; i < 2; ++i) {
317321 while (back > file_line_info && IsDigit(*back)) --back;
318 if (*back != ':' || !IsDigit(back[1])) break;
322 if (*back != ':' || !IsDigit(back[1]))
323 break;
319324 info->column = info->line;
320325 info->line = internal_atoll(back + 1);
321326 // Truncate the string at the colon to keep only filename.
......@@ -436,7 +441,7 @@ bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
436441 if (!buf)
437442 return false;
438443 ParseSymbolizeDataOutput(buf, info);
439 info->start += (addr - info->module_offset); // Add the base address.
444 info->start += (addr - info->module_offset); // Add the base address.
440445 return true;
441446}
442447
......@@ -459,10 +464,9 @@ const char *LLVMSymbolizer::FormatAndSendCommand(const char *command_prefix,
459464 size_needed = internal_snprintf(buffer_, kBufferSize, "%s \"%s\" 0x%zx\n",
460465 command_prefix, module_name, module_offset);
461466 else
462 size_needed = internal_snprintf(buffer_, kBufferSize,
463 "%s \"%s:%s\" 0x%zx\n", command_prefix,
464 module_name, ModuleArchToString(arch),
465 module_offset);
467 size_needed = internal_snprintf(
468 buffer_, kBufferSize, "%s \"%s:%s\" 0x%zx\n", command_prefix,
469 module_name, ModuleArchToString(arch), module_offset);
466470
467471 if (size_needed >= static_cast<int>(kBufferSize)) {
468472 Report("WARNING: Command buffer too small");
......@@ -484,9 +488,9 @@ SymbolizerProcess::SymbolizerProcess(const char *path, bool use_posix_spawn)
484488 CHECK_NE(path_[0], '\0');
485489}
486490
487static bool IsSameModule(const char* path) {
488 if (const char* ProcessName = GetProcessName()) {
489 if (const char* SymbolizerName = StripModuleName(path)) {
491static bool IsSameModule(const char *path) {
492 if (const char *ProcessName = GetProcessName()) {
493 if (const char *SymbolizerName = StripModuleName(path)) {
490494 return !internal_strcmp(ProcessName, SymbolizerName);
491495 }
492496 }
......@@ -516,9 +520,9 @@ const char *SymbolizerProcess::SendCommand(const char *command) {
516520
517521const char *SymbolizerProcess::SendCommandImpl(const char *command) {
518522 if (input_fd_ == kInvalidFd || output_fd_ == kInvalidFd)
519 return nullptr;
523 return nullptr;
520524 if (!WriteToSymbolizer(command, internal_strlen(command)))
521 return nullptr;
525 return nullptr;
522526 if (!ReadFromSymbolizer())
523527 return nullptr;
524528 return buffer_.data();
lib/libtsan/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp+56-44
......@@ -38,9 +38,10 @@
3838// because we do not require a C++ ABI library to be linked to a program
3939// using sanitizers; if it's not present, we'll just use the mangled name.
4040namespace __cxxabiv1 {
41 extern "C" SANITIZER_WEAK_ATTRIBUTE
42 char *__cxa_demangle(const char *mangled, char *buffer,
43 size_t *length, int *status);
41extern "C" SANITIZER_WEAK_ATTRIBUTE char *__cxa_demangle(const char *mangled,
42 char *buffer,
43 size_t *length,
44 int *status);
4445}
4546
4647namespace __sanitizer {
......@@ -53,8 +54,7 @@ const char *DemangleCXXABI(const char *name) {
5354 // it does not allocate). For now, we just call it anyway, and we leak
5455 // the returned value.
5556 if (&__cxxabiv1::__cxa_demangle)
56 if (const char *demangled_name =
57 __cxxabiv1::__cxa_demangle(name, 0, 0, 0))
57 if (const char *demangled_name = __cxxabiv1::__cxa_demangle(name, 0, 0, 0))
5858 return demangled_name;
5959
6060 return nullptr;
......@@ -85,7 +85,8 @@ const char *DemangleSwift(const char *name) {
8585}
8686
8787const char *DemangleSwiftAndCXX(const char *name) {
88 if (!name) return nullptr;
88 if (!name)
89 return nullptr;
8990 if (const char *swift_demangled_name = DemangleSwift(name))
9091 return swift_demangled_name;
9192 return DemangleCXXABI(name);
......@@ -114,7 +115,8 @@ static bool CreateTwoHighNumberedPipes(int *infd_, int *outfd_) {
114115 } else {
115116 outfd = sock_pair[i];
116117 for (int j = 0; j < i; j++) {
117 if (sock_pair[j] == infd) continue;
118 if (sock_pair[j] == infd)
119 continue;
118120 internal_close(sock_pair[j][0]);
119121 internal_close(sock_pair[j][1]);
120122 }
......@@ -155,7 +157,7 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() {
155157 }
156158
157159 if (use_posix_spawn_) {
158#if SANITIZER_APPLE
160# if SANITIZER_APPLE
159161 fd_t fd = internal_spawn(argv, const_cast<const char **>(GetEnvP()), &pid);
160162 if (fd == kInvalidFd) {
161163 Report("WARNING: failed to spawn external symbolizer (errno: %d)\n",
......@@ -165,14 +167,16 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() {
165167
166168 input_fd_ = fd;
167169 output_fd_ = fd;
168#else // SANITIZER_APPLE
170# else // SANITIZER_APPLE
169171 UNIMPLEMENTED();
170#endif // SANITIZER_APPLE
172# endif // SANITIZER_APPLE
171173 } else {
172174 fd_t infd[2] = {}, outfd[2] = {};
173175 if (!CreateTwoHighNumberedPipes(infd, outfd)) {
174 Report("WARNING: Can't create a socket pair to start "
175 "external symbolizer (errno: %d)\n", errno);
176 Report(
177 "WARNING: Can't create a socket pair to start "
178 "external symbolizer (errno: %d)\n",
179 errno);
176180 return false;
177181 }
178182
......@@ -260,10 +264,11 @@ bool Addr2LineProcess::ReachedEndOfOutput(const char *buffer,
260264 // 1. First one, corresponding to given offset to be symbolized
261265 // (may be equal to output_terminator_, if offset is not valid).
262266 // 2. Second one for output_terminator_, itself to mark the end of output.
263 if (length <= kTerminatorLen) return false;
267 if (length <= kTerminatorLen)
268 return false;
264269 // Addr2Line output should end up with output_terminator_.
265 return !internal_memcmp(buffer + length - kTerminatorLen,
266 output_terminator_, kTerminatorLen);
270 return !internal_memcmp(buffer + length - kTerminatorLen, output_terminator_,
271 kTerminatorLen);
267272}
268273
269274class Addr2LinePool final : public SymbolizerTool {
......@@ -283,9 +288,7 @@ class Addr2LinePool final : public SymbolizerTool {
283288 return false;
284289 }
285290
286 bool SymbolizeData(uptr addr, DataInfo *info) override {
287 return false;
288 }
291 bool SymbolizeData(uptr addr, DataInfo *info) override { return false; }
289292
290293 private:
291294 const char *SendCommand(const char *module_name, uptr module_offset) {
......@@ -299,22 +302,21 @@ class Addr2LinePool final : public SymbolizerTool {
299302 }
300303 if (!addr2line) {
301304 addr2line =
302 new(*allocator_) Addr2LineProcess(addr2line_path_, module_name);
305 new (*allocator_) Addr2LineProcess(addr2line_path_, module_name);
303306 addr2line_pool_.push_back(addr2line);
304307 }
305308 CHECK_EQ(0, internal_strcmp(module_name, addr2line->module_name()));
306309 char buffer[kBufferSize];
307 internal_snprintf(buffer, kBufferSize, "0x%zx\n0x%zx\n",
308 module_offset, dummy_address_);
310 internal_snprintf(buffer, kBufferSize, "0x%zx\n0x%zx\n", module_offset,
311 dummy_address_);
309312 return addr2line->SendCommand(buffer);
310313 }
311314
312315 static const uptr kBufferSize = 64;
313316 const char *addr2line_path_;
314317 LowLevelAllocator *allocator_;
315 InternalMmapVector<Addr2LineProcess*> addr2line_pool_;
316 static const uptr dummy_address_ =
317 FIRST_32_SECOND_64(UINT32_MAX, UINT64_MAX);
318 InternalMmapVector<Addr2LineProcess *> addr2line_pool_;
319 static const uptr dummy_address_ = FIRST_32_SECOND_64(UINT32_MAX, UINT64_MAX);
318320};
319321
320322# if SANITIZER_SUPPORTS_WEAK_HOOKS
......@@ -352,8 +354,9 @@ class InternalSymbolizer final : public SymbolizerTool {
352354 }
353355
354356 bool SymbolizePC(uptr addr, SymbolizedStack *stack) override {
355 bool result = __sanitizer_symbolize_code(
356 stack->info.module, stack->info.module_offset, buffer_, sizeof(buffer_));
357 bool result = __sanitizer_symbolize_code(stack->info.module,
358 stack->info.module_offset, buffer_,
359 sizeof(buffer_));
357360 if (result)
358361 ParseSymbolizePCOutput(buffer_, stack);
359362 return result;
......@@ -423,44 +426,53 @@ static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) {
423426 } else if (!internal_strncmp(binary_name, kLLVMSymbolizerPrefix,
424427 internal_strlen(kLLVMSymbolizerPrefix))) {
425428 VReport(2, "Using llvm-symbolizer at user-specified path: %s\n", path);
426 return new(*allocator) LLVMSymbolizer(path, allocator);
429 return new (*allocator) LLVMSymbolizer(path, allocator);
427430 } else if (!internal_strcmp(binary_name, "atos")) {
428#if SANITIZER_APPLE
431# if SANITIZER_APPLE
429432 VReport(2, "Using atos at user-specified path: %s\n", path);
430 return new(*allocator) AtosSymbolizer(path, allocator);
431#else // SANITIZER_APPLE
433 return new (*allocator) AtosSymbolizer(path, allocator);
434# else // SANITIZER_APPLE
432435 Report("ERROR: Using `atos` is only supported on Darwin.\n");
433436 Die();
434#endif // SANITIZER_APPLE
437# endif // SANITIZER_APPLE
435438 } else if (!internal_strcmp(binary_name, "addr2line")) {
436439 VReport(2, "Using addr2line at user-specified path: %s\n", path);
437 return new(*allocator) Addr2LinePool(path, allocator);
440 return new (*allocator) Addr2LinePool(path, allocator);
438441 } else if (path) {
439 Report("ERROR: External symbolizer path is set to '%s' which isn't "
440 "a known symbolizer. Please set the path to the llvm-symbolizer "
441 "binary or other known tool.\n", path);
442 Report(
443 "ERROR: External symbolizer path is set to '%s' which isn't "
444 "a known symbolizer. Please set the path to the llvm-symbolizer "
445 "binary or other known tool.\n",
446 path);
442447 Die();
443448 }
444449
445450 // Otherwise symbolizer program is unknown, let's search $PATH
451# ifdef SANITIZER_DISABLE_SYMBOLIZER_PATH_SEARCH
452 VReport(2,
453 "Symbolizer path search is disabled in the runtime "
454 "build configuration.\n");
455 return nullptr;
456# else
446457 CHECK(path == nullptr);
447#if SANITIZER_APPLE
458# if SANITIZER_APPLE
448459 if (const char *found_path = FindPathToBinary("atos")) {
449460 VReport(2, "Using atos found at: %s\n", found_path);
450 return new(*allocator) AtosSymbolizer(found_path, allocator);
461 return new (*allocator) AtosSymbolizer(found_path, allocator);
451462 }
452#endif // SANITIZER_APPLE
463# endif // SANITIZER_APPLE
453464 if (const char *found_path = FindPathToBinary("llvm-symbolizer")) {
454465 VReport(2, "Using llvm-symbolizer found at: %s\n", found_path);
455 return new(*allocator) LLVMSymbolizer(found_path, allocator);
466 return new (*allocator) LLVMSymbolizer(found_path, allocator);
456467 }
457468 if (common_flags()->allow_addr2line) {
458469 if (const char *found_path = FindPathToBinary("addr2line")) {
459470 VReport(2, "Using addr2line found at: %s\n", found_path);
460 return new(*allocator) Addr2LinePool(found_path, allocator);
471 return new (*allocator) Addr2LinePool(found_path, allocator);
461472 }
462473 }
463474 return nullptr;
475# endif // SANITIZER_DISABLE_SYMBOLIZER_PATH_SEARCH
464476}
465477
466478static void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,
......@@ -492,17 +504,17 @@ static void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,
492504 list->push_back(tool);
493505 }
494506
495#if SANITIZER_APPLE
507# if SANITIZER_APPLE
496508 VReport(2, "Using dladdr symbolizer.\n");
497 list->push_back(new(*allocator) DlAddrSymbolizer());
498#endif // SANITIZER_APPLE
509 list->push_back(new (*allocator) DlAddrSymbolizer());
510# endif // SANITIZER_APPLE
499511}
500512
501513Symbolizer *Symbolizer::PlatformInit() {
502514 IntrusiveList<SymbolizerTool> list;
503515 list.clear();
504516 ChooseSymbolizerTools(&list, &symbolizer_allocator_);
505 return new(symbolizer_allocator_) Symbolizer(list);
517 return new (symbolizer_allocator_) Symbolizer(list);
506518}
507519
508520void Symbolizer::LateInitialize() {
lib/libtsan/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp+2-34
......@@ -12,7 +12,7 @@
1212
1313#include "sanitizer_platform.h"
1414#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
15 SANITIZER_SOLARIS
15 SANITIZER_SOLARIS || SANITIZER_HAIKU
1616#include "sanitizer_common.h"
1717#include "sanitizer_stacktrace.h"
1818
......@@ -91,38 +91,6 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
9191
9292} // namespace
9393
94#if SANITIZER_ANDROID
95void SanitizerInitializeUnwinder() {
96 if (AndroidGetApiLevel() >= ANDROID_LOLLIPOP_MR1) return;
97
98 // Pre-lollipop Android can not unwind through signal handler frames with
99 // libgcc unwinder, but it has a libcorkscrew.so library with the necessary
100 // workarounds.
101 void *p = dlopen("libcorkscrew.so", RTLD_LAZY);
102 if (!p) {
103 VReport(1,
104 "Failed to open libcorkscrew.so. You may see broken stack traces "
105 "in SEGV reports.");
106 return;
107 }
108 acquire_my_map_info_list =
109 (acquire_my_map_info_list_func)(uptr)dlsym(p, "acquire_my_map_info_list");
110 release_my_map_info_list =
111 (release_my_map_info_list_func)(uptr)dlsym(p, "release_my_map_info_list");
112 unwind_backtrace_signal_arch = (unwind_backtrace_signal_arch_func)(uptr)dlsym(
113 p, "unwind_backtrace_signal_arch");
114 if (!acquire_my_map_info_list || !release_my_map_info_list ||
115 !unwind_backtrace_signal_arch) {
116 VReport(1,
117 "Failed to find one of the required symbols in libcorkscrew.so. "
118 "You may see broken stack traces in SEGV reports.");
119 acquire_my_map_info_list = 0;
120 unwind_backtrace_signal_arch = 0;
121 release_my_map_info_list = 0;
122 }
123}
124#endif
125
12694void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
12795 CHECK_GE(max_depth, 2);
12896 size = 0;
......@@ -171,4 +139,4 @@ void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
171139} // namespace __sanitizer
172140
173141#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
174 // SANITIZER_SOLARIS
142 // SANITIZER_SOLARIS || SANITIZER_HAIKU
lib/libtsan/sanitizer_common/sanitizer_unwind_win.cpp+5
......@@ -75,6 +75,11 @@ void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
7575 stack_frame.AddrPC.Offset = ctx.Pc;
7676 stack_frame.AddrFrame.Offset = ctx.R11;
7777 stack_frame.AddrStack.Offset = ctx.Sp;
78# elif SANITIZER_MIPS32
79 int machine_type = IMAGE_FILE_MACHINE_R4000;
80 stack_frame.AddrPC.Offset = ctx.Fir;
81 stack_frame.AddrFrame.Offset = ctx.IntS8;
82 stack_frame.AddrStack.Offset = ctx.IntSp;
7883# else
7984 int machine_type = IMAGE_FILE_MACHINE_I386;
8085 stack_frame.AddrPC.Offset = ctx.Eip;
lib/libtsan/sanitizer_common/sanitizer_win.cpp+3
......@@ -1011,6 +1011,9 @@ void SignalContext::InitPcSpBp() {
10111011# if SANITIZER_ARM
10121012 bp = (uptr)context_record->R11;
10131013 sp = (uptr)context_record->Sp;
1014# elif SANITIZER_MIPS32
1015 bp = (uptr)context_record->IntS8;
1016 sp = (uptr)context_record->IntSp;
10141017# else
10151018 bp = (uptr)context_record->Ebp;
10161019 sp = (uptr)context_record->Esp;
lib/libtsan/tsan_interceptors_posix.cpp+72-15
......@@ -12,6 +12,9 @@
1212// sanitizer_common/sanitizer_common_interceptors.inc
1313//===----------------------------------------------------------------------===//
1414
15#include <stdarg.h>
16
17#include "interception/interception.h"
1518#include "sanitizer_common/sanitizer_allocator_dlsym.h"
1619#include "sanitizer_common/sanitizer_atomic.h"
1720#include "sanitizer_common/sanitizer_errno.h"
......@@ -19,21 +22,20 @@
1922#include "sanitizer_common/sanitizer_internal_defs.h"
2023#include "sanitizer_common/sanitizer_libc.h"
2124#include "sanitizer_common/sanitizer_linux.h"
25#include "sanitizer_common/sanitizer_platform_interceptors.h"
2226#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
2327#include "sanitizer_common/sanitizer_platform_limits_posix.h"
2428#include "sanitizer_common/sanitizer_posix.h"
2529#include "sanitizer_common/sanitizer_stacktrace.h"
2630#include "sanitizer_common/sanitizer_tls_get_addr.h"
27#include "interception/interception.h"
31#include "sanitizer_common/sanitizer_vector.h"
32#include "tsan_fd.h"
2833#include "tsan_interceptors.h"
2934#include "tsan_interface.h"
35#include "tsan_mman.h"
3036#include "tsan_platform.h"
31#include "tsan_suppressions.h"
3237#include "tsan_rtl.h"
33#include "tsan_mman.h"
34#include "tsan_fd.h"
35
36#include <stdarg.h>
38#include "tsan_suppressions.h"
3739
3840using namespace __tsan;
3941
......@@ -177,7 +179,7 @@ struct ThreadSignalContext {
177179 SignalDesc pending_signals[kSigCount];
178180 // emptyset and oldset are too big for stack.
179181 __sanitizer_sigset_t emptyset;
180 __sanitizer_sigset_t oldset;
182 __sanitizer::Vector<__sanitizer_sigset_t> oldset;
181183};
182184
183185void EnterBlockingFunc(ThreadState *thr) {
......@@ -558,6 +560,7 @@ static void SetJmp(ThreadState *thr, uptr sp) {
558560 buf->shadow_stack_pos = thr->shadow_stack_pos;
559561 ThreadSignalContext *sctx = SigCtx(thr);
560562 buf->int_signal_send = sctx ? sctx->int_signal_send : 0;
563 buf->oldset_stack_size = sctx ? sctx->oldset.Size() : 0;
561564 buf->in_blocking_func = atomic_load(&thr->in_blocking_func, memory_order_relaxed);
562565 buf->in_signal_handler = atomic_load(&thr->in_signal_handler,
563566 memory_order_relaxed);
......@@ -574,8 +577,11 @@ static void LongJmp(ThreadState *thr, uptr *env) {
574577 while (thr->shadow_stack_pos > buf->shadow_stack_pos)
575578 FuncExit(thr);
576579 ThreadSignalContext *sctx = SigCtx(thr);
577 if (sctx)
580 if (sctx) {
578581 sctx->int_signal_send = buf->int_signal_send;
582 while (sctx->oldset.Size() > buf->oldset_stack_size)
583 sctx->oldset.PopBack();
584 }
579585 atomic_store(&thr->in_blocking_func, buf->in_blocking_func,
580586 memory_order_relaxed);
581587 atomic_store(&thr->in_signal_handler, buf->in_signal_handler,
......@@ -742,6 +748,41 @@ TSAN_INTERCEPTOR(void, free, void *p) {
742748 user_free(thr, pc, p);
743749}
744750
751# if SANITIZER_INTERCEPT_FREE_SIZED
752TSAN_INTERCEPTOR(void, free_sized, void *p, uptr size) {
753 if (UNLIKELY(!p))
754 return;
755 if (in_symbolizer())
756 return InternalFree(p);
757 if (DlsymAlloc::PointerIsMine(p))
758 return DlsymAlloc::Free(p);
759 invoke_free_hook(p);
760 SCOPED_INTERCEPTOR_RAW(free_sized, p, size);
761 user_free(thr, pc, p);
762}
763# define TSAN_MAYBE_INTERCEPT_FREE_SIZED INTERCEPT_FUNCTION(free_sized)
764# else
765# define TSAN_MAYBE_INTERCEPT_FREE_SIZED
766# endif
767
768# if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED
769TSAN_INTERCEPTOR(void, free_aligned_sized, void *p, uptr alignment, uptr size) {
770 if (UNLIKELY(!p))
771 return;
772 if (in_symbolizer())
773 return InternalFree(p);
774 if (DlsymAlloc::PointerIsMine(p))
775 return DlsymAlloc::Free(p);
776 invoke_free_hook(p);
777 SCOPED_INTERCEPTOR_RAW(free_aligned_sized, p, alignment, size);
778 user_free(thr, pc, p);
779}
780# define TSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED \
781 INTERCEPT_FUNCTION(free_aligned_sized)
782# else
783# define TSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED
784# endif
785
745786TSAN_INTERCEPTOR(void, cfree, void *p) {
746787 if (UNLIKELY(!p))
747788 return;
......@@ -758,6 +799,9 @@ TSAN_INTERCEPTOR(uptr, malloc_usable_size, void *p) {
758799 SCOPED_INTERCEPTOR_RAW(malloc_usable_size, p);
759800 return user_alloc_usable_size(p);
760801}
802#else
803# define TSAN_MAYBE_INTERCEPT_FREE_SIZED
804# define TSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED
761805#endif
762806
763807TSAN_INTERCEPTOR(char *, strcpy, char *dst, const char *src) {
......@@ -892,10 +936,9 @@ constexpr u32 kGuardWaiter = 1 << 17;
892936
893937static int guard_acquire(ThreadState *thr, uptr pc, atomic_uint32_t *g,
894938 bool blocking_hooks = true) {
895 if (blocking_hooks)
896 OnPotentiallyBlockingRegionBegin();
897 auto on_exit = at_scope_exit([blocking_hooks] {
898 if (blocking_hooks)
939 bool in_potentially_blocking_region = false;
940 auto on_exit = at_scope_exit([&] {
941 if (in_potentially_blocking_region)
899942 OnPotentiallyBlockingRegionEnd();
900943 });
901944
......@@ -912,8 +955,13 @@ static int guard_acquire(ThreadState *thr, uptr pc, atomic_uint32_t *g,
912955 } else {
913956 if ((cmp & kGuardWaiter) ||
914957 atomic_compare_exchange_strong(g, &cmp, cmp | kGuardWaiter,
915 memory_order_relaxed))
958 memory_order_relaxed)) {
959 if (blocking_hooks && !in_potentially_blocking_region) {
960 in_potentially_blocking_region = true;
961 OnPotentiallyBlockingRegionBegin();
962 }
916963 FutexWait(g, cmp | kGuardWaiter);
964 }
917965 }
918966 }
919967}
......@@ -976,6 +1024,7 @@ void PlatformCleanUpThreadState(ThreadState *thr) {
9761024 &thr->signal_ctx, memory_order_relaxed);
9771025 if (sctx) {
9781026 atomic_store(&thr->signal_ctx, 0, memory_order_relaxed);
1027 sctx->oldset.Reset();
9791028 UnmapOrDie(sctx, sizeof(*sctx));
9801029 }
9811030}
......@@ -2172,7 +2221,8 @@ void ProcessPendingSignalsImpl(ThreadState *thr) {
21722221 return;
21732222 atomic_fetch_add(&thr->in_signal_handler, 1, memory_order_relaxed);
21742223 internal_sigfillset(&sctx->emptyset);
2175 int res = REAL(pthread_sigmask)(SIG_SETMASK, &sctx->emptyset, &sctx->oldset);
2224 __sanitizer_sigset_t *oldset = sctx->oldset.PushBack();
2225 int res = REAL(pthread_sigmask)(SIG_SETMASK, &sctx->emptyset, oldset);
21762226 CHECK_EQ(res, 0);
21772227 for (int sig = 0; sig < kSigCount; sig++) {
21782228 SignalDesc *signal = &sctx->pending_signals[sig];
......@@ -2182,8 +2232,9 @@ void ProcessPendingSignalsImpl(ThreadState *thr) {
21822232 &signal->ctx);
21832233 }
21842234 }
2185 res = REAL(pthread_sigmask)(SIG_SETMASK, &sctx->oldset, 0);
2235 res = REAL(pthread_sigmask)(SIG_SETMASK, oldset, 0);
21862236 CHECK_EQ(res, 0);
2237 sctx->oldset.PopBack();
21872238 atomic_fetch_add(&thr->in_signal_handler, -1, memory_order_relaxed);
21882239}
21892240
......@@ -2951,6 +3002,8 @@ void InitializeInterceptors() {
29513002 TSAN_INTERCEPT(realloc);
29523003 TSAN_INTERCEPT(reallocarray);
29533004 TSAN_INTERCEPT(free);
3005 TSAN_MAYBE_INTERCEPT_FREE_SIZED;
3006 TSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED;
29543007 TSAN_INTERCEPT(cfree);
29553008 TSAN_INTERCEPT(munmap);
29563009 TSAN_MAYBE_INTERCEPT_MEMALIGN;
......@@ -3073,6 +3126,10 @@ void InitializeInterceptors() {
30733126#if !SANITIZER_ANDROID
30743127 TSAN_INTERCEPT(dl_iterate_phdr);
30753128#endif
3129
3130 // Symbolization indirectly calls dl_iterate_phdr
3131 ready_to_symbolize = true;
3132
30763133 TSAN_MAYBE_INTERCEPT_ON_EXIT;
30773134 TSAN_INTERCEPT(__cxa_atexit);
30783135 TSAN_INTERCEPT(_exit);
lib/libtsan/tsan_interface_java.cpp-1
......@@ -122,7 +122,6 @@ void __tsan_java_move(jptr src, jptr dst, jptr size) {
122122 DCHECK_GE(dst, jctx->heap_begin);
123123 DCHECK_LE(dst + size, jctx->heap_begin + jctx->heap_size);
124124 DCHECK_NE(dst, src);
125 DCHECK_NE(size, 0);
126125
127126 // Assuming it's not running concurrently with threads that do
128127 // memory accesses and mutex operations (stop-the-world phase).
lib/libtsan/tsan_malloc_mac.cpp+13-9
......@@ -73,15 +73,19 @@ using namespace __tsan;
7373 invoke_free_hook(ptr); \
7474 SCOPED_INTERCEPTOR_RAW(free, ptr); \
7575 user_free(thr, pc, ptr)
76#define COMMON_MALLOC_SIZE(ptr) uptr size = user_alloc_usable_size(ptr);
77#define COMMON_MALLOC_FILL_STATS(zone, stats)
78#define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \
79 (void)zone_name; \
80 Report("mz_realloc(%p) -- attempting to realloc unallocated memory.\n", ptr);
81#define COMMON_MALLOC_NAMESPACE __tsan
82#define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0
83#define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 0
76# define COMMON_MALLOC_FREE_SIZED(ptr, size) COMMON_MALLOC_FREE(ptr)
77# define COMMON_MALLOC_FREE_ALIGNED_SIZED(ptr, alignment, size) \
78 COMMON_MALLOC_FREE(ptr)
79# define COMMON_MALLOC_SIZE(ptr) uptr size = user_alloc_usable_size(ptr);
80# define COMMON_MALLOC_FILL_STATS(zone, stats)
81# define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \
82 (void)zone_name; \
83 Report("mz_realloc(%p) -- attempting to realloc unallocated memory.\n", \
84 ptr);
85# define COMMON_MALLOC_NAMESPACE __tsan
86# define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0
87# define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 0
8488
85#include "sanitizer_common/sanitizer_malloc_mac.inc"
89# include "sanitizer_common/sanitizer_malloc_mac.inc"
8690
8791#endif
lib/libtsan/tsan_platform.h+32-2
......@@ -681,6 +681,33 @@ struct MappingGoMips64_47 {
681681 static const uptr kShadowAdd = 0x200000000000ull;
682682};
683683
684/* Go on linux/riscv64 (48-bit VMA)
6850000 0001 0000 - 00e0 0000 0000: executable and heap (896 GiB)
68600e0 0000 0000 - 2000 0000 0000: -
6872000 0000 0000 - 2400 0000 0000: shadow - 4 TiB ( ~ 4 * app)
6882400 0000 0000 - 3000 0000 0000: -
6893000 0000 0000 - 3100 0000 0000: metainfo - 1 TiB ( ~ 1 * app)
6903100 0000 0000 - 8000 0000 0000: -
691*/
692struct MappingGoRiscv64 {
693 static const uptr kMetaShadowBeg = 0x300000000000ull;
694 static const uptr kMetaShadowEnd = 0x310000000000ull;
695 static const uptr kShadowBeg = 0x200000000000ull;
696 static const uptr kShadowEnd = 0x240000000000ull;
697 static const uptr kLoAppMemBeg = 0x000000010000ull;
698 static const uptr kLoAppMemEnd = 0x000e00000000ull;
699 static const uptr kMidAppMemBeg = 0;
700 static const uptr kMidAppMemEnd = 0;
701 static const uptr kHiAppMemBeg = 0;
702 static const uptr kHiAppMemEnd = 0;
703 static const uptr kHeapMemBeg = 0;
704 static const uptr kHeapMemEnd = 0;
705 static const uptr kVdsoBeg = 0;
706 static const uptr kShadowMsk = 0;
707 static const uptr kShadowXor = 0;
708 static const uptr kShadowAdd = 0x200000000000ull;
709};
710
684711/*
685712Go on linux/s390x
6867130000 0000 1000 - 1000 0000 0000: executable and heap - 16 TiB
......@@ -728,6 +755,8 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) {
728755 return Func::template Apply<MappingGoAarch64>(arg);
729756# elif defined(__loongarch_lp64)
730757 return Func::template Apply<MappingGoLoongArch64_47>(arg);
758# elif SANITIZER_RISCV64
759 return Func::template Apply<MappingGoRiscv64>(arg);
731760# elif SANITIZER_WINDOWS
732761 return Func::template Apply<MappingGoWindows>(arg);
733762# else
......@@ -798,6 +827,7 @@ void ForEachMapping() {
798827 Func::template Apply<MappingGoAarch64>();
799828 Func::template Apply<MappingGoLoongArch64_47>();
800829 Func::template Apply<MappingGoMips64_47>();
830 Func::template Apply<MappingGoRiscv64>();
801831 Func::template Apply<MappingGoS390x>();
802832}
803833
......@@ -901,7 +931,7 @@ bool IsAppMem(uptr mem) { return SelectMapping<IsAppMemImpl>(mem); }
901931struct IsShadowMemImpl {
902932 template <typename Mapping>
903933 static bool Apply(uptr mem) {
904 return mem >= Mapping::kShadowBeg && mem <= Mapping::kShadowEnd;
934 return mem >= Mapping::kShadowBeg && mem < Mapping::kShadowEnd;
905935 }
906936};
907937
......@@ -913,7 +943,7 @@ bool IsShadowMem(RawShadow *p) {
913943struct IsMetaMemImpl {
914944 template <typename Mapping>
915945 static bool Apply(uptr mem) {
916 return mem >= Mapping::kMetaShadowBeg && mem <= Mapping::kMetaShadowEnd;
946 return mem >= Mapping::kMetaShadowBeg && mem < Mapping::kMetaShadowEnd;
917947 }
918948};
919949
lib/libtsan/tsan_platform_linux.cpp+27-2
......@@ -259,7 +259,15 @@ static void ReExecIfNeeded(bool ignore_heap) {
259259 "WARNING: Program is run with randomized virtual address "
260260 "space, which wouldn't work with ThreadSanitizer on Android.\n"
261261 "Re-execing with fixed virtual address space.\n");
262 CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1);
262
263 if (personality(old_personality | ADDR_NO_RANDOMIZE) == -1) {
264 Printf(
265 "FATAL: ThreadSanitizer: unable to disable ASLR (perhaps "
266 "sandboxing is enabled?).\n");
267 Printf("FATAL: Please rerun without sandboxing and/or ASLR.\n");
268 Die();
269 }
270
263271 reexec = true;
264272 }
265273# endif
......@@ -287,7 +295,18 @@ static void ReExecIfNeeded(bool ignore_heap) {
287295 "possibly due to high-entropy ASLR.\n"
288296 "Re-execing with fixed virtual address space.\n"
289297 "N.B. reducing ASLR entropy is preferable.\n");
290 CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1);
298
299 if (personality(old_personality | ADDR_NO_RANDOMIZE) == -1) {
300 Printf(
301 "FATAL: ThreadSanitizer: encountered an incompatible memory "
302 "layout but was unable to disable ASLR (perhaps sandboxing is "
303 "enabled?).\n");
304 Printf(
305 "FATAL: Please rerun with lower ASLR entropy, ASLR disabled, "
306 "and/or sandboxing disabled.\n");
307 Die();
308 }
309
291310 reexec = true;
292311 } else {
293312 Printf(
......@@ -373,6 +392,12 @@ void InitializePlatformEarly() {
373392 Printf("FATAL: Found %zd - Supported 39 and 48\n", vmaSize);
374393 Die();
375394 }
395# else
396 if (vmaSize != 48) {
397 Printf("FATAL: ThreadSanitizer: unsupported VMA range\n");
398 Printf("FATAL: Found %zd - Supported 48\n", vmaSize);
399 Die();
400 }
376401# endif
377402# endif
378403
lib/libtsan/tsan_rtl.cpp+25-6
......@@ -566,17 +566,32 @@ static bool IsValidMmapRange(uptr addr, uptr size) {
566566 return false;
567567}
568568
569void UnmapShadow(ThreadState *thr, uptr addr, uptr size) {
569void UnmapShadow(ThreadState* thr, uptr addr, uptr size) {
570570 if (size == 0 || !IsValidMmapRange(addr, size))
571571 return;
572 DontNeedShadowFor(addr, size);
572 // unmap shadow is related to semantic of mmap/munmap, so we
573 // should clear the whole shadow range, including the tail shadow
574 // while addr + size % kShadowCell != 0.
575 uptr rounded_size_shadow = RoundUp(addr + size, kShadowCell) - addr;
576 DontNeedShadowFor(addr, rounded_size_shadow);
573577 ScopedGlobalProcessor sgp;
574578 SlotLocker locker(thr, true);
575 ctx->metamap.ResetRange(thr->proc(), addr, size, true);
579 uptr rounded_size_meta = RoundUp(addr + size, kMetaShadowCell) - addr;
580 ctx->metamap.ResetRange(thr->proc(), addr, rounded_size_meta, true);
576581}
577582#endif
578583
579584void MapShadow(uptr addr, uptr size) {
585 // Although named MapShadow, this function's semantic is unrelated to
586 // UnmapShadow. This function currently only used for Go's lazy allocation
587 // of shadow, whose targets are program section (e.g., bss, data, etc.).
588 // Therefore, we can guarantee that the addr and size align to kShadowCell
589 // and kMetaShadowCell by the following assertions.
590 DCHECK_EQ(addr % kShadowCell, 0);
591 DCHECK_EQ(size % kShadowCell, 0);
592 DCHECK_EQ(addr % kMetaShadowCell, 0);
593 DCHECK_EQ(size % kMetaShadowCell, 0);
594
580595 // Ensure thead registry lock held, so as to synchronize
581596 // with DoReset, which also access the mapped_shadow_* ctxt fields.
582597 ThreadRegistryLock lock0(&ctx->thread_registry);
......@@ -624,6 +639,7 @@ void MapShadow(uptr addr, uptr size) {
624639 static uptr mapped_meta_end = 0;
625640 uptr meta_begin = (uptr)MemToMeta(addr);
626641 uptr meta_end = (uptr)MemToMeta(addr + size);
642 // Windows wants 64K alignment.
627643 meta_begin = RoundDownTo(meta_begin, 64 << 10);
628644 meta_end = RoundUpTo(meta_end, 64 << 10);
629645 if (!data_mapped) {
......@@ -634,9 +650,6 @@ void MapShadow(uptr addr, uptr size) {
634650 Die();
635651 } else {
636652 // Mapping continuous heap.
637 // Windows wants 64K alignment.
638 meta_begin = RoundDownTo(meta_begin, 64 << 10);
639 meta_end = RoundUpTo(meta_end, 64 << 10);
640653 CHECK_GT(meta_end, mapped_meta_end);
641654 if (meta_begin < mapped_meta_end)
642655 meta_begin = mapped_meta_end;
......@@ -679,6 +692,12 @@ void CheckUnwind() {
679692
680693bool is_initialized;
681694
695// Symbolization indirectly calls dl_iterate_phdr. If a CHECK() fails early on
696// (prior to the dl_iterate_phdr interceptor setup), resulting in an attempted
697// symbolization, it will segfault.
698// dl_iterate_phdr is not intercepted for Android.
699bool ready_to_symbolize = SANITIZER_ANDROID;
700
682701void Initialize(ThreadState *thr) {
683702 // Thread safe because done before all threads exist.
684703 if (is_initialized)
lib/libtsan/tsan_rtl.h+4-1
......@@ -54,13 +54,15 @@
5454
5555namespace __tsan {
5656
57extern bool ready_to_symbolize;
58
5759#if !SANITIZER_GO
5860struct MapUnmapCallback;
5961# if defined(__mips64) || defined(__aarch64__) || defined(__loongarch__) || \
6062 defined(__powerpc__) || SANITIZER_RISCV64
6163
6264struct AP32 {
63 static const uptr kSpaceBeg = 0;
65 static const uptr kSpaceBeg = SANITIZER_MMAP_BEGIN;
6466 static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
6567 static const uptr kMetadataSize = 0;
6668 typedef __sanitizer::CompactSizeClassMap SizeClassMap;
......@@ -98,6 +100,7 @@ struct JmpBuf {
98100 uptr sp;
99101 int int_signal_send;
100102 bool in_blocking_func;
103 uptr oldset_stack_size;
101104 uptr in_signal_handler;
102105 uptr *shadow_stack_pos;
103106};
lib/libtsan/tsan_rtl_access.cpp+18-12
......@@ -523,9 +523,9 @@ SECOND:
523523}
524524
525525void ShadowSet(RawShadow* p, RawShadow* end, RawShadow v) {
526 DCHECK_LE(p, end);
526 DCHECK_LT(p, end);
527527 DCHECK(IsShadowMem(p));
528 DCHECK(IsShadowMem(end));
528 DCHECK(IsShadowMem(end - 1));
529529 UNUSED const uptr kAlign = kShadowCnt * kShadowSize;
530530 DCHECK_EQ(reinterpret_cast<uptr>(p) % kAlign, 0);
531531 DCHECK_EQ(reinterpret_cast<uptr>(end) % kAlign, 0);
......@@ -569,6 +569,7 @@ static void MemoryRangeSet(uptr addr, uptr size, RawShadow val) {
569569 RawShadow* mid1 =
570570 Min(end, reinterpret_cast<RawShadow*>(RoundUp(
571571 reinterpret_cast<uptr>(begin) + kPageSize / 2, kPageSize)));
572 // begin must < mid1
572573 ShadowSet(begin, mid1, val);
573574 // Reset middle part.
574575 RawShadow* mid2 = RoundDown(end, kPageSize);
......@@ -577,7 +578,10 @@ static void MemoryRangeSet(uptr addr, uptr size, RawShadow val) {
577578 Die();
578579 }
579580 // Set the ending.
580 ShadowSet(mid2, end, val);
581 if (mid2 < end)
582 ShadowSet(mid2, end, val);
583 else
584 DCHECK_EQ(mid2, end);
581585}
582586
583587void MemoryResetRange(ThreadState* thr, uptr pc, uptr addr, uptr size) {
......@@ -669,7 +673,7 @@ void MemoryAccessRangeT(ThreadState* thr, uptr pc, uptr addr, uptr size) {
669673 RawShadow* shadow_mem = MemToShadow(addr);
670674 DPrintf2("#%d: MemoryAccessRange: @%p %p size=%d is_read=%d\n", thr->tid,
671675 (void*)pc, (void*)addr, (int)size, is_read);
672
676 DCHECK_NE(size, 0);
673677#if SANITIZER_DEBUG
674678 if (!IsAppMem(addr)) {
675679 Printf("Access to non app mem start: %p\n", (void*)addr);
......@@ -684,16 +688,18 @@ void MemoryAccessRangeT(ThreadState* thr, uptr pc, uptr addr, uptr size) {
684688 DCHECK(IsShadowMem(shadow_mem));
685689 }
686690
687 RawShadow* shadow_mem_end = reinterpret_cast<RawShadow*>(
688 reinterpret_cast<uptr>(shadow_mem) + size * kShadowMultiplier - 1);
689 if (!IsShadowMem(shadow_mem_end)) {
690 Printf("Bad shadow end addr: %p (%p)\n", shadow_mem_end,
691 uptr rounded_size =
692 (RoundUpTo(addr + size, kShadowCell) - RoundDownTo(addr, kShadowCell));
693 RawShadow* shadow_mem_end =
694 shadow_mem + rounded_size / kShadowCell * kShadowCnt;
695 if (!IsShadowMem(shadow_mem_end - 1)) {
696 Printf("Bad shadow end addr: %p (%p)\n", shadow_mem_end - 1,
691697 (void*)(addr + size - 1));
692698 Printf(
693 "Shadow start addr (ok): %p (%p); size: 0x%zx; kShadowMultiplier: "
694 "%zx\n",
695 shadow_mem, (void*)addr, size, kShadowMultiplier);
696 DCHECK(IsShadowMem(shadow_mem_end));
699 "Shadow start addr (ok): %p (%p); size: 0x%zx; rounded_size: 0x%zx; "
700 "kShadowMultiplier: %zx\n",
701 shadow_mem, (void*)addr, size, rounded_size, kShadowMultiplier);
702 DCHECK(IsShadowMem(shadow_mem_end - 1));
697703 }
698704#endif
699705
lib/libtsan/tsan_rtl_report.cpp+10-1
......@@ -846,7 +846,16 @@ ALWAYS_INLINE USED void PrintCurrentStack(uptr pc, bool fast) {
846846 ptrace->trace_buffer[i] = ptrace->trace_buffer[ptrace->size - i - 1];
847847 ptrace->trace_buffer[ptrace->size - i - 1] = tmp;
848848 }
849 PrintStack(SymbolizeStack(*ptrace));
849
850 if (ready_to_symbolize) {
851 PrintStack(SymbolizeStack(*ptrace));
852 } else {
853 Printf(
854 "WARNING: PrintCurrentStack() has been called too early, before "
855 "symbolization is possible. Printing unsymbolized stack trace:\n");
856 for (unsigned int i = 0; i < ptrace->size; i++)
857 Printf(" #%u: 0x%zx\n", i, ptrace->trace[i]);
858 }
850859#endif
851860}
852861
lib/libtsan/tsan_sync.cpp+22-5
......@@ -246,12 +246,29 @@ void MetaMap::MoveMemory(uptr src, uptr dst, uptr sz) {
246246 // there are no concurrent accesses to the regions (e.g. stop-the-world).
247247 CHECK_NE(src, dst);
248248 CHECK_NE(sz, 0);
249
250 // The current MoveMemory implementation behaves incorrectly when src, dst,
251 // and sz are not aligned to kMetaShadowCell.
252 // For example, with kMetaShadowCell == 8:
253 // - src = 4: unexpectedly clears the metadata for the range [0, 4).
254 // - src = 16, dst = 4, size = 8: A sync variable for addr = 20, which should
255 // be moved to the metadata for address 8, is incorrectly moved to the
256 // metadata for address 0 instead.
257 // - src = 0, sz = 4: fails to move the tail metadata.
258 // Therefore, the following assertions is needed.
259 DCHECK_EQ(src % kMetaShadowCell, 0);
260 DCHECK_EQ(dst % kMetaShadowCell, 0);
261 DCHECK_EQ(sz % kMetaShadowCell, 0);
262
249263 uptr diff = dst - src;
250 u32 *src_meta = MemToMeta(src);
251 u32 *dst_meta = MemToMeta(dst);
252 u32 *src_meta_end = MemToMeta(src + sz);
253 uptr inc = 1;
254 if (dst > src) {
264 u32 *src_meta, *dst_meta, *src_meta_end;
265 uptr inc;
266 if (dst < src) {
267 src_meta = MemToMeta(src);
268 dst_meta = MemToMeta(dst);
269 src_meta_end = MemToMeta(src + sz);
270 inc = 1;
271 } else {
255272 src_meta = MemToMeta(src + sz) - 1;
256273 dst_meta = MemToMeta(dst + sz) - 1;
257274 src_meta_end = MemToMeta(src) - 1;
lib/libtsan/ubsan/ubsan_platform.h+1-1
......@@ -16,7 +16,7 @@
1616#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
1717 defined(__NetBSD__) || defined(__DragonFly__) || \
1818 (defined(__sun__) && defined(__svr4__)) || defined(_WIN32) || \
19 defined(__Fuchsia__)
19 defined(__Fuchsia__) || defined(__HAIKU__)
2020#define CAN_SANITIZE_UB 1
2121#else
2222# define CAN_SANITIZE_UB 0
src/libs/libtsan.zig+3
......@@ -403,6 +403,7 @@ const sanitizer_common_sources = [_][]const u8{
403403 "sanitizer_flag_parser.cpp",
404404 "sanitizer_flags.cpp",
405405 "sanitizer_fuchsia.cpp",
406 "sanitizer_haiku.cpp",
406407 "sanitizer_libc.cpp",
407408 "sanitizer_libignore.cpp",
408409 "sanitizer_linux.cpp",
......@@ -420,6 +421,7 @@ const sanitizer_common_sources = [_][]const u8{
420421 "sanitizer_procmaps_bsd.cpp",
421422 "sanitizer_procmaps_common.cpp",
422423 "sanitizer_procmaps_fuchsia.cpp",
424 "sanitizer_procmaps_haiku.cpp",
423425 "sanitizer_procmaps_linux.cpp",
424426 "sanitizer_procmaps_mac.cpp",
425427 "sanitizer_procmaps_solaris.cpp",
......@@ -478,6 +480,7 @@ const sanitizer_symbolizer_sources = [_][]const u8{
478480};
479481
480482const interception_sources = [_][]const u8{
483 "interception_aix.cpp",
481484 "interception_linux.cpp",
482485 "interception_mac.cpp",
483486 "interception_win.cpp",