1 //===-- sanitizer_rtems.cc ------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is shared between various sanitizers' runtime libraries and
11 // implements RTEMS-specific functions.
12 //===----------------------------------------------------------------------===//
14 #include "sanitizer_rtems.h"
17 #define posix_memalign __real_posix_memalign
18 #define free __real_free
19 #define memset __real_memset
21 #include "sanitizer_file.h"
22 #include "sanitizer_symbolizer.h"
32 // There is no mmap on RTEMS. Use memalign, etc.
33 #define __mmap_alloc_aligned posix_memalign
34 #define __mmap_free free
35 #define __mmap_memset memset
37 namespace __sanitizer {
39 #include "sanitizer_syscall_generic.inc"
41 void NORETURN internal__exit(int exitcode) {
45 uptr internal_sched_yield() {
49 uptr internal_getpid() {
53 bool FileExists(const char *filename) {
55 if (stat(filename, &st))
57 // Sanity check: filename is a regular file.
58 return S_ISREG(st.st_mode);
61 uptr GetThreadSelf() { return static_cast<uptr>(pthread_self()); }
63 tid_t GetTid() { return GetThreadSelf(); }
65 void Abort() { abort(); }
67 int Atexit(void (*function)(void)) { return atexit(function); }
69 void SleepForSeconds(int seconds) { sleep(seconds); }
71 void SleepForMillis(int millis) { usleep(millis * 1000); }
73 bool SupportsColoredOutput(fd_t fd) { return false; }
75 void GetThreadStackTopAndBottom(bool at_initialization,
76 uptr *stack_top, uptr *stack_bottom) {
78 pthread_attr_init(&attr);
79 CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
82 CHECK_EQ(pthread_attr_getstack(&attr, &base, &size), 0);
83 CHECK_EQ(pthread_attr_destroy(&attr), 0);
85 *stack_bottom = reinterpret_cast<uptr>(base);
86 *stack_top = *stack_bottom + size;
89 void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
90 uptr *tls_addr, uptr *tls_size) {
91 uptr stack_top, stack_bottom;
92 GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
93 *stk_addr = stack_bottom;
94 *stk_size = stack_top - stack_bottom;
95 *tls_addr = *tls_size = 0;
98 void InitializePlatformEarly() {}
101 void CheckMPROTECT() {}
102 void DisableCoreDumperIfNecessary() {}
103 void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
104 void SetAlternateSignalStack() {}
105 void UnsetAlternateSignalStack() {}
106 void InitTlsSize() {}
108 void PrintModuleMap() {}
110 void SignalContext::DumpAllRegisters(void *context) {}
111 const char *DescribeSignalOrException(int signo) { UNIMPLEMENTED(); }
113 enum MutexState { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 };
115 BlockingMutex::BlockingMutex() {
116 internal_memset(this, 0, sizeof(*this));
119 void BlockingMutex::Lock() {
121 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
122 if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked)
124 while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) {
125 internal_sched_yield();
129 void BlockingMutex::Unlock() {
130 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
131 u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release);
132 CHECK_NE(v, MtxUnlocked);
135 void BlockingMutex::CheckLocked() {
136 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
137 CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed));
140 uptr GetPageSize() { return getpagesize(); }
142 uptr GetMmapGranularity() { return GetPageSize(); }
144 uptr GetMaxVirtualAddress() {
145 return (1ULL << 32) - 1; // 0xffffffff
148 void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {
150 int res = __mmap_alloc_aligned(&ptr, GetPageSize(), size);
152 ReportMmapFailureAndDie(size, mem_type, "allocate", res, raw_report);
153 __mmap_memset(ptr, 0, size);
154 IncreaseTotalMmap(size);
158 void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
160 int res = __mmap_alloc_aligned(&ptr, GetPageSize(), size);
164 ReportMmapFailureAndDie(size, mem_type, "allocate", false);
166 __mmap_memset(ptr, 0, size);
167 IncreaseTotalMmap(size);
171 void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
172 const char *mem_type) {
173 CHECK(IsPowerOfTwo(size));
174 CHECK(IsPowerOfTwo(alignment));
176 int res = __mmap_alloc_aligned(&ptr, alignment, size);
178 ReportMmapFailureAndDie(size, mem_type, "align allocate", res, false);
179 __mmap_memset(ptr, 0, size);
180 IncreaseTotalMmap(size);
184 void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
185 return MmapOrDie(size, mem_type, false);
188 void UnmapOrDie(void *addr, uptr size) {
189 if (!addr || !size) return;
191 DecreaseTotalMmap(size);
194 fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {
197 case RdOnly: flags = O_RDONLY; break;
198 case WrOnly: flags = O_WRONLY | O_CREAT | O_TRUNC; break;
199 case RdWr: flags = O_RDWR | O_CREAT; break;
201 fd_t res = open(filename, flags, 0660);
202 if (internal_iserror(res, errno_p))
207 void CloseFile(fd_t fd) {
211 bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read,
213 uptr res = read(fd, buff, buff_size);
214 if (internal_iserror(res, error_p))
221 bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,
223 uptr res = write(fd, buff, buff_size);
224 if (internal_iserror(res, error_p))
227 *bytes_written = res;
231 void ReleaseMemoryPagesToOS(uptr beg, uptr end) {}
232 void DumpProcessMap() {}
234 // There is no page protection so everything is "accessible."
235 bool IsAccessibleMemoryRange(uptr beg, uptr size) {
239 char **GetArgv() { return nullptr; }
240 char **GetEnviron() { return nullptr; }
242 const char *GetEnv(const char *name) {
246 uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
247 internal_strncpy(buf, "StubBinaryName", buf_len);
248 return internal_strlen(buf);
251 uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
252 internal_strncpy(buf, "StubProcessName", buf_len);
253 return internal_strlen(buf);
256 bool IsPathSeparator(const char c) {
260 bool IsAbsolutePath(const char *path) {
261 return path != nullptr && IsPathSeparator(path[0]);
264 void ReportFile::Write(const char *buffer, uptr length) {
266 static const char *kWriteError =
267 "ReportFile::Write() can't output requested buffer!\n";
269 if (length != write(fd, buffer, length)) {
270 write(fd, kWriteError, internal_strlen(kWriteError));
275 uptr MainThreadStackBase, MainThreadStackSize;
276 uptr MainThreadTlsBase, MainThreadTlsSize;
278 } // namespace __sanitizer
280 #endif // SANITIZER_RTEMS