]> git.proxmox.com Git - rustc.git/blame - src/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc
Imported Upstream version 1.0.0~0alpha
[rustc.git] / src / compiler-rt / lib / sanitizer_common / sanitizer_posix_libcdep.cc
CommitLineData
1a4d82fc
JJ
1//===-- sanitizer_posix_libcdep.cc ----------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is shared between AddressSanitizer and ThreadSanitizer
11// run-time libraries and implements libc-dependent POSIX-specific functions
12// from sanitizer_libc.h.
13//===----------------------------------------------------------------------===//
14
15#include "sanitizer_platform.h"
16
17#if SANITIZER_POSIX
18#include "sanitizer_common.h"
19#include "sanitizer_flags.h"
20#include "sanitizer_platform_limits_posix.h"
21#include "sanitizer_stacktrace.h"
22
23#include <errno.h>
24#include <pthread.h>
25#include <signal.h>
26#include <stdlib.h>
27#include <sys/mman.h>
28#include <sys/resource.h>
29#include <sys/time.h>
30#include <sys/types.h>
31#include <unistd.h>
32
33namespace __sanitizer {
34
35u32 GetUid() {
36 return getuid();
37}
38
39uptr GetThreadSelf() {
40 return (uptr)pthread_self();
41}
42
43void FlushUnneededShadowMemory(uptr addr, uptr size) {
44 madvise((void*)addr, size, MADV_DONTNEED);
45}
46
47void DisableCoreDumper() {
48 struct rlimit nocore;
49 nocore.rlim_cur = 0;
50 nocore.rlim_max = 0;
51 setrlimit(RLIMIT_CORE, &nocore);
52}
53
54bool StackSizeIsUnlimited() {
55 struct rlimit rlim;
56 CHECK_EQ(0, getrlimit(RLIMIT_STACK, &rlim));
57 return ((uptr)rlim.rlim_cur == (uptr)-1);
58}
59
60void SetStackSizeLimitInBytes(uptr limit) {
61 struct rlimit rlim;
62 rlim.rlim_cur = limit;
63 rlim.rlim_max = limit;
64 if (setrlimit(RLIMIT_STACK, &rlim)) {
65 Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno);
66 Die();
67 }
68 CHECK(!StackSizeIsUnlimited());
69}
70
71void SleepForSeconds(int seconds) {
72 sleep(seconds);
73}
74
75void SleepForMillis(int millis) {
76 usleep(millis * 1000);
77}
78
79void Abort() {
80 abort();
81}
82
83int Atexit(void (*function)(void)) {
84#ifndef SANITIZER_GO
85 return atexit(function);
86#else
87 return 0;
88#endif
89}
90
91int internal_isatty(fd_t fd) {
92 return isatty(fd);
93}
94
95#ifndef SANITIZER_GO
96// TODO(glider): different tools may require different altstack size.
97static const uptr kAltStackSize = SIGSTKSZ * 4; // SIGSTKSZ is not enough.
98
99void SetAlternateSignalStack() {
100 stack_t altstack, oldstack;
101 CHECK_EQ(0, sigaltstack(0, &oldstack));
102 // If the alternate stack is already in place, do nothing.
103 // Android always sets an alternate stack, but it's too small for us.
104 if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return;
105 // TODO(glider): the mapped stack should have the MAP_STACK flag in the
106 // future. It is not required by man 2 sigaltstack now (they're using
107 // malloc()).
108 void* base = MmapOrDie(kAltStackSize, __func__);
109 altstack.ss_sp = (char*) base;
110 altstack.ss_flags = 0;
111 altstack.ss_size = kAltStackSize;
112 CHECK_EQ(0, sigaltstack(&altstack, 0));
113}
114
115void UnsetAlternateSignalStack() {
116 stack_t altstack, oldstack;
117 altstack.ss_sp = 0;
118 altstack.ss_flags = SS_DISABLE;
119 altstack.ss_size = kAltStackSize; // Some sane value required on Darwin.
120 CHECK_EQ(0, sigaltstack(&altstack, &oldstack));
121 UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
122}
123
124typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
125static void MaybeInstallSigaction(int signum,
126 SignalHandlerType handler) {
127 if (!IsDeadlySignal(signum))
128 return;
129 struct sigaction sigact;
130 internal_memset(&sigact, 0, sizeof(sigact));
131 sigact.sa_sigaction = (sa_sigaction_t)handler;
132 sigact.sa_flags = SA_SIGINFO;
133 if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;
134 CHECK_EQ(0, internal_sigaction(signum, &sigact, 0));
135 VReport(1, "Installed the sigaction for signal %d\n", signum);
136}
137
138void InstallDeadlySignalHandlers(SignalHandlerType handler) {
139 // Set the alternate signal stack for the main thread.
140 // This will cause SetAlternateSignalStack to be called twice, but the stack
141 // will be actually set only once.
142 if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
143 MaybeInstallSigaction(SIGSEGV, handler);
144 MaybeInstallSigaction(SIGBUS, handler);
145}
146#endif // SANITIZER_GO
147
148} // namespace __sanitizer
149
150#endif // SANITIZER_POSIX