Add hppa*-*-* to dg-error targets at line 5
[official-gcc.git] / libsanitizer / tsan / tsan_platform_posix.cpp
blobe7dcd664dc0d20713ab9bfb10fe4b5806609692a
1 //===-- tsan_platform_posix.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 a part of ThreadSanitizer (TSan), a race detector.
11 // POSIX-specific code.
12 //===----------------------------------------------------------------------===//
14 #include "sanitizer_common/sanitizer_platform.h"
15 #if SANITIZER_POSIX
17 # include <dlfcn.h>
19 # include "sanitizer_common/sanitizer_common.h"
20 # include "sanitizer_common/sanitizer_errno.h"
21 # include "sanitizer_common/sanitizer_libc.h"
22 # include "sanitizer_common/sanitizer_procmaps.h"
23 # include "tsan_platform.h"
24 # include "tsan_rtl.h"
26 namespace __tsan {
28 static const char kShadowMemoryMappingWarning[] =
29 "FATAL: %s can not madvise shadow region [%zx, %zx] with %s (errno: %d)\n";
30 static const char kShadowMemoryMappingHint[] =
31 "HINT: if %s is not supported in your environment, you may set "
32 "TSAN_OPTIONS=%s=0\n";
34 # if !SANITIZER_GO
35 void DontDumpShadow(uptr addr, uptr size) {
36 if (common_flags()->use_madv_dontdump)
37 if (!DontDumpShadowMemory(addr, size)) {
38 Printf(kShadowMemoryMappingWarning, SanitizerToolName, addr, addr + size,
39 "MADV_DONTDUMP", errno);
40 Printf(kShadowMemoryMappingHint, "MADV_DONTDUMP", "use_madv_dontdump");
41 Die();
45 void InitializeShadowMemory() {
46 // Map memory shadow.
47 if (!MmapFixedSuperNoReserve(ShadowBeg(), ShadowEnd() - ShadowBeg(),
48 "shadow")) {
49 Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");
50 Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
51 Die();
53 // This memory range is used for thread stacks and large user mmaps.
54 // Frequently a thread uses only a small part of stack and similarly
55 // a program uses a small part of large mmap. On some programs
56 // we see 20% memory usage reduction without huge pages for this range.
57 DontDumpShadow(ShadowBeg(), ShadowEnd() - ShadowBeg());
58 DPrintf("memory shadow: %zx-%zx (%zuGB)\n",
59 ShadowBeg(), ShadowEnd(),
60 (ShadowEnd() - ShadowBeg()) >> 30);
62 // Map meta shadow.
63 const uptr meta = MetaShadowBeg();
64 const uptr meta_size = MetaShadowEnd() - meta;
65 if (!MmapFixedSuperNoReserve(meta, meta_size, "meta shadow")) {
66 Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");
67 Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
68 Die();
70 DontDumpShadow(meta, meta_size);
71 DPrintf("meta shadow: %zx-%zx (%zuGB)\n",
72 meta, meta + meta_size, meta_size >> 30);
74 InitializeShadowMemoryPlatform();
76 on_initialize = reinterpret_cast<void (*)(void)>(
77 dlsym(RTLD_DEFAULT, "__tsan_on_initialize"));
78 on_finalize =
79 reinterpret_cast<int (*)(int)>(dlsym(RTLD_DEFAULT, "__tsan_on_finalize"));
82 static bool TryProtectRange(uptr beg, uptr end) {
83 CHECK_LE(beg, end);
84 if (beg == end)
85 return true;
86 return beg == (uptr)MmapFixedNoAccess(beg, end - beg);
89 static void ProtectRange(uptr beg, uptr end) {
90 if (!TryProtectRange(beg, end)) {
91 Printf("FATAL: ThreadSanitizer can not protect [%zx,%zx]\n", beg, end);
92 Printf("FATAL: Make sure you are not using unlimited stack\n");
93 Die();
97 void CheckAndProtect() {
98 // Ensure that the binary is indeed compiled with -pie.
99 MemoryMappingLayout proc_maps(true);
100 MemoryMappedSegment segment;
101 while (proc_maps.Next(&segment)) {
102 if (IsAppMem(segment.start)) continue;
103 if (segment.start >= HeapMemEnd() && segment.start < HeapEnd()) continue;
104 if (segment.protection == 0) // Zero page or mprotected.
105 continue;
106 if (segment.start >= VdsoBeg()) // vdso
107 break;
108 Printf("FATAL: ThreadSanitizer: unexpected memory mapping 0x%zx-0x%zx\n",
109 segment.start, segment.end);
110 Die();
113 # if SANITIZER_IOS && !SANITIZER_IOSSIM
114 ProtectRange(HeapMemEnd(), ShadowBeg());
115 ProtectRange(ShadowEnd(), MetaShadowBeg());
116 ProtectRange(MetaShadowEnd(), HiAppMemBeg());
117 # else
118 ProtectRange(LoAppMemEnd(), ShadowBeg());
119 ProtectRange(ShadowEnd(), MetaShadowBeg());
120 if (MidAppMemBeg()) {
121 ProtectRange(MetaShadowEnd(), MidAppMemBeg());
122 ProtectRange(MidAppMemEnd(), HeapMemBeg());
123 } else {
124 ProtectRange(MetaShadowEnd(), HeapMemBeg());
126 ProtectRange(HeapEnd(), HiAppMemBeg());
127 # endif
129 # if defined(__s390x__)
130 // Protect the rest of the address space.
131 const uptr user_addr_max_l4 = 0x0020000000000000ull;
132 const uptr user_addr_max_l5 = 0xfffffffffffff000ull;
133 // All the maintained s390x kernels support at least 4-level page tables.
134 ProtectRange(HiAppMemEnd(), user_addr_max_l4);
135 // Older s390x kernels may not support 5-level page tables.
136 TryProtectRange(user_addr_max_l4, user_addr_max_l5);
137 #endif
139 #endif
141 } // namespace __tsan
143 #endif // SANITIZER_POSIX