summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common
diff options
context:
space:
mode:
authorWalter Lee <waltl@google.com>2018-05-18 04:10:12 +0000
committerWalter Lee <waltl@google.com>2018-05-18 04:10:12 +0000
commit884c5285a6c545aeaaed63d3d72988df4a8d09a5 (patch)
treefeb409160290ea46f7cbad201d25bde654c8cab0 /lib/sanitizer_common
parent1394070245396b7bb503ee5c55d176f677ceb71b (diff)
[asan] Add target-specific files for Myriad RTEMS port
Differential Revision: https://reviews.llvm.org/D46468 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@332691 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common')
-rw-r--r--lib/sanitizer_common/CMakeLists.txt2
-rw-r--r--lib/sanitizer_common/sanitizer_rtems.cc288
-rw-r--r--lib/sanitizer_common/sanitizer_rtems.h28
3 files changed, 318 insertions, 0 deletions
diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt
index 43f84d4ab..47a7c4509 100644
--- a/lib/sanitizer_common/CMakeLists.txt
+++ b/lib/sanitizer_common/CMakeLists.txt
@@ -30,6 +30,7 @@ set(SANITIZER_SOURCES_NOTERMINATION
sanitizer_procmaps_linux.cc
sanitizer_procmaps_mac.cc
sanitizer_procmaps_solaris.cc
+ sanitizer_rtems.cc
sanitizer_solaris.cc
sanitizer_stoptheworld_mac.cc
sanitizer_suppressions.cc
@@ -140,6 +141,7 @@ set(SANITIZER_HEADERS
sanitizer_procmaps.h
sanitizer_quarantine.h
sanitizer_report_decorator.h
+ sanitizer_rtems.h
sanitizer_stackdepot.h
sanitizer_stackdepotbase.h
sanitizer_stacktrace.h
diff --git a/lib/sanitizer_common/sanitizer_rtems.cc b/lib/sanitizer_common/sanitizer_rtems.cc
new file mode 100644
index 000000000..56bc9b040
--- /dev/null
+++ b/lib/sanitizer_common/sanitizer_rtems.cc
@@ -0,0 +1,288 @@
+//===-- sanitizer_rtems.cc ------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between various sanitizers' runtime libraries and
+// implements RTEMS-specific functions.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_rtems.h"
+#if SANITIZER_RTEMS
+
+#define posix_memalign __real_posix_memalign
+#define free __real_free
+#define memset __real_memset
+
+#include "sanitizer_file.h"
+#include "sanitizer_symbolizer.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+// There is no mmap on RTEMS. Use memalign, etc.
+#define __mmap_alloc_aligned posix_memalign
+#define __mmap_free free
+#define __mmap_memset memset
+
+namespace __sanitizer {
+
+#include "sanitizer_syscall_generic.inc"
+
+void NORETURN internal__exit(int exitcode) {
+ _exit(exitcode);
+}
+
+uptr internal_sched_yield() {
+ return sched_yield();
+}
+
+uptr internal_getpid() {
+ return getpid();
+}
+
+bool FileExists(const char *filename) {
+ struct stat st;
+ if (stat(filename, &st))
+ return false;
+ // Sanity check: filename is a regular file.
+ return S_ISREG(st.st_mode);
+}
+
+uptr GetThreadSelf() { return static_cast<uptr>(pthread_self()); }
+
+tid_t GetTid() { return GetThreadSelf(); }
+
+void Abort() { abort(); }
+
+int Atexit(void (*function)(void)) { return atexit(function); }
+
+void SleepForSeconds(int seconds) { sleep(seconds); }
+
+void SleepForMillis(int millis) { usleep(millis * 1000); }
+
+bool SupportsColoredOutput(fd_t fd) { return false; }
+
+void GetThreadStackTopAndBottom(bool at_initialization,
+ uptr *stack_top, uptr *stack_bottom) {
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
+ void *base = nullptr;
+ size_t size = 0;
+ CHECK_EQ(pthread_attr_getstack(&attr, &base, &size), 0);
+ CHECK_EQ(pthread_attr_destroy(&attr), 0);
+
+ *stack_bottom = reinterpret_cast<uptr>(base);
+ *stack_top = *stack_bottom + size;
+}
+
+void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
+ uptr *tls_addr, uptr *tls_size) {
+ uptr stack_top, stack_bottom;
+ GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
+ *stk_addr = stack_bottom;
+ *stk_size = stack_top - stack_bottom;
+ *tls_addr = *tls_size = 0;
+}
+
+void MaybeReexec() {}
+void DisableCoreDumperIfNecessary() {}
+void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
+void SetAlternateSignalStack() {}
+void UnsetAlternateSignalStack() {}
+void InitTlsSize() {}
+
+void PrintModuleMap() {}
+
+void SignalContext::DumpAllRegisters(void *context) {}
+const char *DescribeSignalOrException(int signo) { UNIMPLEMENTED(); }
+
+enum MutexState { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 };
+
+BlockingMutex::BlockingMutex() {
+ internal_memset(this, 0, sizeof(*this));
+}
+
+void BlockingMutex::Lock() {
+ CHECK_EQ(owner_, 0);
+ atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
+ if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked)
+ return;
+ while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) {
+ internal_sched_yield();
+ }
+}
+
+void BlockingMutex::Unlock() {
+ atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
+ u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release);
+ CHECK_NE(v, MtxUnlocked);
+}
+
+void BlockingMutex::CheckLocked() {
+ atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
+ CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed));
+}
+
+uptr GetPageSize() { return getpagesize(); }
+
+uptr GetMmapGranularity() { return GetPageSize(); }
+
+uptr GetMaxVirtualAddress() {
+ return (1ULL << 32) - 1; // 0xffffffff
+}
+
+void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {
+ void* ptr = 0;
+ int res = __mmap_alloc_aligned(&ptr, GetPageSize(), size);
+ if (UNLIKELY(res))
+ ReportMmapFailureAndDie(size, mem_type, "allocate", res, raw_report);
+ __mmap_memset(ptr, 0, size);
+ IncreaseTotalMmap(size);
+ return ptr;
+}
+
+void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
+ void* ptr = 0;
+ int res = __mmap_alloc_aligned(&ptr, GetPageSize(), size);
+ if (UNLIKELY(res)) {
+ if (res == ENOMEM)
+ return nullptr;
+ ReportMmapFailureAndDie(size, mem_type, "allocate", false);
+ }
+ __mmap_memset(ptr, 0, size);
+ IncreaseTotalMmap(size);
+ return ptr;
+}
+
+void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
+ const char *mem_type) {
+ CHECK(IsPowerOfTwo(size));
+ CHECK(IsPowerOfTwo(alignment));
+ void* ptr = 0;
+ int res = __mmap_alloc_aligned(&ptr, alignment, size);
+ if (res)
+ ReportMmapFailureAndDie(size, mem_type, "align allocate", res, false);
+ __mmap_memset(ptr, 0, size);
+ IncreaseTotalMmap(size);
+ return ptr;
+}
+
+void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
+ return MmapOrDie(size, mem_type, false);
+}
+
+void UnmapOrDie(void *addr, uptr size) {
+ if (!addr || !size) return;
+ __mmap_free(addr);
+ DecreaseTotalMmap(size);
+}
+
+fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {
+ int flags;
+ switch (mode) {
+ case RdOnly: flags = O_RDONLY; break;
+ case WrOnly: flags = O_WRONLY | O_CREAT; break;
+ case RdWr: flags = O_RDWR | O_CREAT; break;
+ }
+ fd_t res = open(filename, flags, 0660);
+ if (internal_iserror(res, errno_p))
+ return kInvalidFd;
+ return res;
+}
+
+void CloseFile(fd_t fd) {
+ close(fd);
+}
+
+bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read,
+ error_t *error_p) {
+ uptr res = read(fd, buff, buff_size);
+ if (internal_iserror(res, error_p))
+ return false;
+ if (bytes_read)
+ *bytes_read = res;
+ return true;
+}
+
+bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,
+ error_t *error_p) {
+ uptr res = write(fd, buff, buff_size);
+ if (internal_iserror(res, error_p))
+ return false;
+ if (bytes_written)
+ *bytes_written = res;
+ return true;
+}
+
+bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) {
+ uptr res = rename(oldpath, newpath);
+ return !internal_iserror(res, error_p);
+}
+
+void ReleaseMemoryPagesToOS(uptr beg, uptr end) {}
+void DumpProcessMap() {}
+
+// There is no page protection so everything is "accessible."
+bool IsAccessibleMemoryRange(uptr beg, uptr size) {
+ return true;
+}
+
+char **GetArgv() { return NULL; }
+const char *GetEnv(const char *name) { return NULL; }
+
+uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
+ internal_strncpy(buf, "StubBinaryName", buf_len);
+ return internal_strlen(buf);
+}
+
+uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
+ internal_strncpy(buf, "StubProcessName", buf_len);
+ return internal_strlen(buf);
+}
+
+bool IsPathSeparator(const char c) {
+ return c == '/';
+}
+
+bool IsAbsolutePath(const char *path) {
+ return path != nullptr && IsPathSeparator(path[0]);
+}
+
+void ReportFile::Write(const char *buffer, uptr length) {
+ SpinMutexLock l(mu);
+ static const char *kWriteError =
+ "ReportFile::Write() can't output requested buffer!\n";
+ ReopenIfNecessary();
+ if (length != write(fd, buffer, length)) {
+ write(fd, kWriteError, internal_strlen(kWriteError));
+ Die();
+ }
+}
+
+uptr MainThreadStackBase, MainThreadStackSize;
+uptr MainThreadTlsBase, MainThreadTlsSize;
+
+} // namespace __sanitizer
+
+extern "C" {
+void __sanitizer_startup_hook(void *stack_base, size_t stack_size,
+ void *tls_base, size_t tls_size) {
+ __sanitizer::MainThreadStackBase = reinterpret_cast<uintptr_t>(stack_base);
+ __sanitizer::MainThreadStackSize = stack_size;
+ __sanitizer::MainThreadTlsBase = reinterpret_cast<uintptr_t>(tls_base);
+ __sanitizer::MainThreadTlsSize = tls_size;
+}
+} // extern "C"
+
+#endif // SANITIZER_RTEMS
diff --git a/lib/sanitizer_common/sanitizer_rtems.h b/lib/sanitizer_common/sanitizer_rtems.h
new file mode 100644
index 000000000..e2f668ff9
--- /dev/null
+++ b/lib/sanitizer_common/sanitizer_rtems.h
@@ -0,0 +1,28 @@
+//===-- sanitizer_rtems.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between various sanitizers' runtime libraries and
+// provides definitions for RTEMS-specific functions.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_RTEMS_H
+#define SANITIZER_RTEMS_H
+
+#include "sanitizer_platform.h"
+#if SANITIZER_RTEMS
+#include "sanitizer_common.h"
+
+namespace __sanitizer {
+
+extern uptr MainThreadStackBase, MainThreadStackSize;
+extern uptr MainThreadTlsBase, MainThreadTlsSize;
+
+} // namespace __sanitizer
+
+#endif // SANITIZER_RTEMS
+#endif // SANITIZER_RTEMS_H