[PR67828] don't unswitch on default defs of non-parms
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_posix_libcdep.cc
blobb4e42c724625055fe3bdfcbf97193c9bb5c992f4
1 //===-- sanitizer_posix_libcdep.cc ----------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is shared between AddressSanitizer and ThreadSanitizer
9 // run-time libraries and implements libc-dependent POSIX-specific functions
10 // from sanitizer_libc.h.
11 //===----------------------------------------------------------------------===//
13 #include "sanitizer_platform.h"
15 #if SANITIZER_POSIX
16 #include "sanitizer_common.h"
17 #include "sanitizer_flags.h"
18 #include "sanitizer_platform_limits_posix.h"
19 #include "sanitizer_stacktrace.h"
21 #include <errno.h>
22 #include <pthread.h>
23 #include <signal.h>
24 #include <stdlib.h>
25 #include <sys/mman.h>
26 #include <sys/resource.h>
27 #include <sys/time.h>
28 #include <sys/types.h>
29 #include <unistd.h>
31 namespace __sanitizer {
33 u32 GetUid() {
34 return getuid();
37 uptr GetThreadSelf() {
38 return (uptr)pthread_self();
41 void FlushUnneededShadowMemory(uptr addr, uptr size) {
42 madvise((void*)addr, size, MADV_DONTNEED);
45 static rlim_t getlim(int res) {
46 rlimit rlim;
47 CHECK_EQ(0, getrlimit(res, &rlim));
48 return rlim.rlim_cur;
51 static void setlim(int res, rlim_t lim) {
52 // The following magic is to prevent clang from replacing it with memset.
53 volatile struct rlimit rlim;
54 rlim.rlim_cur = lim;
55 rlim.rlim_max = lim;
56 if (setrlimit(res, (struct rlimit*)&rlim)) {
57 Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno);
58 Die();
62 void DisableCoreDumperIfNecessary() {
63 if (common_flags()->disable_coredump) {
64 setlim(RLIMIT_CORE, 0);
68 bool StackSizeIsUnlimited() {
69 rlim_t stack_size = getlim(RLIMIT_STACK);
70 return (stack_size == RLIM_INFINITY);
73 void SetStackSizeLimitInBytes(uptr limit) {
74 setlim(RLIMIT_STACK, (rlim_t)limit);
75 CHECK(!StackSizeIsUnlimited());
78 bool AddressSpaceIsUnlimited() {
79 rlim_t as_size = getlim(RLIMIT_AS);
80 return (as_size == RLIM_INFINITY);
83 void SetAddressSpaceUnlimited() {
84 setlim(RLIMIT_AS, RLIM_INFINITY);
85 CHECK(AddressSpaceIsUnlimited());
88 void SleepForSeconds(int seconds) {
89 sleep(seconds);
92 void SleepForMillis(int millis) {
93 usleep(millis * 1000);
96 void Abort() {
97 abort();
100 int Atexit(void (*function)(void)) {
101 #ifndef SANITIZER_GO
102 return atexit(function);
103 #else
104 return 0;
105 #endif
108 int internal_isatty(fd_t fd) {
109 return isatty(fd);
112 #ifndef SANITIZER_GO
113 // TODO(glider): different tools may require different altstack size.
114 static const uptr kAltStackSize = SIGSTKSZ * 4; // SIGSTKSZ is not enough.
116 void SetAlternateSignalStack() {
117 stack_t altstack, oldstack;
118 CHECK_EQ(0, sigaltstack(0, &oldstack));
119 // If the alternate stack is already in place, do nothing.
120 // Android always sets an alternate stack, but it's too small for us.
121 if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return;
122 // TODO(glider): the mapped stack should have the MAP_STACK flag in the
123 // future. It is not required by man 2 sigaltstack now (they're using
124 // malloc()).
125 void* base = MmapOrDie(kAltStackSize, __func__);
126 altstack.ss_sp = (char*) base;
127 altstack.ss_flags = 0;
128 altstack.ss_size = kAltStackSize;
129 CHECK_EQ(0, sigaltstack(&altstack, 0));
132 void UnsetAlternateSignalStack() {
133 stack_t altstack, oldstack;
134 altstack.ss_sp = 0;
135 altstack.ss_flags = SS_DISABLE;
136 altstack.ss_size = kAltStackSize; // Some sane value required on Darwin.
137 CHECK_EQ(0, sigaltstack(&altstack, &oldstack));
138 UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
141 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
142 static void MaybeInstallSigaction(int signum,
143 SignalHandlerType handler) {
144 if (!IsDeadlySignal(signum))
145 return;
146 struct sigaction sigact;
147 internal_memset(&sigact, 0, sizeof(sigact));
148 sigact.sa_sigaction = (sa_sigaction_t)handler;
149 // Do not block the signal from being received in that signal's handler.
150 // Clients are responsible for handling this correctly.
151 sigact.sa_flags = SA_SIGINFO | SA_NODEFER;
152 if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;
153 CHECK_EQ(0, internal_sigaction(signum, &sigact, 0));
154 VReport(1, "Installed the sigaction for signal %d\n", signum);
157 void InstallDeadlySignalHandlers(SignalHandlerType handler) {
158 // Set the alternate signal stack for the main thread.
159 // This will cause SetAlternateSignalStack to be called twice, but the stack
160 // will be actually set only once.
161 if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
162 MaybeInstallSigaction(SIGSEGV, handler);
163 MaybeInstallSigaction(SIGBUS, handler);
165 #endif // SANITIZER_GO
167 bool IsAccessibleMemoryRange(uptr beg, uptr size) {
168 uptr page_size = GetPageSizeCached();
169 // Checking too large memory ranges is slow.
170 CHECK_LT(size, page_size * 10);
171 int sock_pair[2];
172 if (pipe(sock_pair))
173 return false;
174 uptr bytes_written =
175 internal_write(sock_pair[1], reinterpret_cast<void *>(beg), size);
176 int write_errno;
177 bool result;
178 if (internal_iserror(bytes_written, &write_errno)) {
179 CHECK_EQ(EFAULT, write_errno);
180 result = false;
181 } else {
182 result = (bytes_written == size);
184 internal_close(sock_pair[0]);
185 internal_close(sock_pair[1]);
186 return result;
189 } // namespace __sanitizer
191 #endif // SANITIZER_POSIX