[compiler-rt] r332691 - [asan] Add target-specific files for Myriad RTEMS port

Walter Lee via llvm-commits llvm-commits at lists.llvm.org
Thu May 17 21:10:12 PDT 2018


Author: waltl
Date: Thu May 17 21:10:12 2018
New Revision: 332691

URL: http://llvm.org/viewvc/llvm-project?rev=332691&view=rev
Log:
[asan] Add target-specific files for Myriad RTEMS port

Differential Revision: https://reviews.llvm.org/D46468

Added:
    compiler-rt/trunk/lib/asan/asan_rtems.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.h
Modified:
    compiler-rt/trunk/lib/asan/CMakeLists.txt
    compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt

Modified: compiler-rt/trunk/lib/asan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/CMakeLists.txt?rev=332691&r1=332690&r2=332691&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/asan/CMakeLists.txt Thu May 17 21:10:12 2018
@@ -23,6 +23,7 @@ set(ASAN_SOURCES
   asan_posix.cc
   asan_premap_shadow.cc
   asan_report.cc
+  asan_rtems.cc
   asan_rtl.cc
   asan_shadow_setup.cc
   asan_stack.cc

Added: compiler-rt/trunk/lib/asan/asan_rtems.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtems.cc?rev=332691&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtems.cc (added)
+++ compiler-rt/trunk/lib/asan/asan_rtems.cc Thu May 17 21:10:12 2018
@@ -0,0 +1,263 @@
+//===-- asan_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 a part of AddressSanitizer, an address sanity checker.
+//
+// RTEMS-specific details.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_rtems.h"
+#if SANITIZER_RTEMS
+
+#include "asan_internal.h"
+#include "asan_interceptors.h"
+#include "asan_mapping.h"
+#include "asan_poisoning.h"
+#include "asan_report.h"
+#include "asan_stack.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_libc.h"
+
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace __asan {
+
+void InitializeShadowMemory() {
+  kHighMemEnd = 0;
+  kMidMemBeg =  0;
+  kMidMemEnd =  0;
+
+  uptr shadow_start = SHADOW_OFFSET;
+  uptr shadow_end = MEM_TO_SHADOW(kMyriadMemoryEnd32);
+  uptr shadow_size = shadow_end - shadow_start;
+  uptr gap_start = MEM_TO_SHADOW(shadow_start);
+  uptr gap_end = MEM_TO_SHADOW(shadow_end);
+
+  REAL(memset)((void *)shadow_start, 0, shadow_size);
+  REAL(memset)((void *)gap_start, kAsanShadowGap, gap_end - gap_start);
+}
+
+void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
+  UNIMPLEMENTED();
+}
+
+void AsanCheckDynamicRTPrereqs() {}
+void AsanCheckIncompatibleRT() {}
+void InitializeAsanInterceptors() {}
+void InitializePlatformInterceptors() {}
+void InitializePlatformExceptionHandlers() {}
+
+// RTEMS only support static linking; it sufficies to return with no
+// error.
+void *AsanDoesNotSupportStaticLinkage() { return nullptr; }
+
+void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
+  UNIMPLEMENTED();
+}
+
+void EarlyInit() {
+  // Provide early initialization of shadow memory so that
+  // instrumented code running before full initialzation will not
+  // report spurious errors.
+  InitializeShadowMemory();
+}
+
+// Main thread information.  Initialized in CreateMainThread() and
+// used by ThreadStartHook().
+static uptr MainThreadSelf;
+static AsanThread *MainThread;
+
+// We can use a plain thread_local variable for TSD.
+static thread_local void *per_thread;
+
+void *AsanTSDGet() { return per_thread; }
+
+void AsanTSDSet(void *tsd) { per_thread = tsd; }
+
+// There's no initialization needed, and the passed-in destructor
+// will never be called.  Instead, our own thread destruction hook
+// (below) will call AsanThread::TSDDtor directly.
+void AsanTSDInit(void (*destructor)(void *tsd)) {
+  DCHECK(destructor == &PlatformTSDDtor);
+}
+
+void PlatformTSDDtor(void *tsd) { UNREACHABLE(__func__); }
+
+//
+// Thread registration.  We provide an API similar to the Fushia port.
+//
+
+struct AsanThread::InitOptions {
+  uptr stack_bottom, stack_size, tls_bottom, tls_size;
+};
+
+// Shared setup between thread creation and startup for the initial thread.
+static AsanThread *CreateAsanThread(StackTrace *stack, u32 parent_tid,
+                                    uptr user_id, bool detached,
+                                    uptr stack_bottom, uptr stack_size,
+                                    uptr tls_bottom, uptr tls_size) {
+  // In lieu of AsanThread::Create.
+  AsanThread *thread = (AsanThread *)MmapOrDie(sizeof(AsanThread), __func__);
+  AsanThreadContext::CreateThreadContextArgs args = {thread, stack};
+  asanThreadRegistry().CreateThread(user_id, detached, parent_tid, &args);
+
+  // On other systems, AsanThread::Init() is called from the new
+  // thread itself.  But on RTEMS we already know the stack address
+  // range beforehand, so we can do most of the setup right now.
+  const AsanThread::InitOptions options = {stack_bottom, stack_size,
+                                           tls_bottom, tls_size};
+  thread->Init(&options);
+  return thread;
+}
+
+// This gets the same arguments passed to Init by CreateAsanThread, above.
+// We're in the creator thread before the new thread is actually started,
+// but its stack address range is already known.  We don't bother tracking
+// the static TLS address range because the system itself already uses an
+// ASan-aware allocator for that.
+void AsanThread::SetThreadStackAndTls(const AsanThread::InitOptions *options) {
+  DCHECK_NE(GetCurrentThread(), this);
+  DCHECK_NE(GetCurrentThread(), nullptr);
+  CHECK_NE(options->stack_bottom, 0);
+  CHECK_NE(options->stack_size, 0);
+  stack_bottom_ = options->stack_bottom;
+  stack_top_ = options->stack_bottom + options->stack_size;
+  tls_begin_ = options->tls_bottom;
+  tls_end_ = options->tls_bottom + options->tls_size;
+}
+
+// Called by __asan::AsanInitInternal (asan_rtl.c).
+AsanThread *CreateMainThread() {
+  CHECK_NE(__sanitizer::MainThreadStackBase, 0);
+  CHECK_GT(__sanitizer::MainThreadStackSize, 0);
+  AsanThread *t = CreateAsanThread(
+      nullptr, 0, GetThreadSelf(), true,
+      __sanitizer::MainThreadStackBase, __sanitizer::MainThreadStackSize,
+      __sanitizer::MainThreadTlsBase, __sanitizer::MainThreadTlsSize);
+  SetCurrentThread(t);
+  MainThreadSelf = pthread_self();
+  MainThread = t;
+  return t;
+}
+
+// This is called before each thread creation is attempted.  So, in
+// its first call, the calling thread is the initial and sole thread.
+static void *BeforeThreadCreateHook(uptr user_id, bool detached,
+                                    uptr stack_bottom, uptr stack_size,
+                                    uptr tls_bottom, uptr tls_size) {
+  EnsureMainThreadIDIsCorrect();
+  // Strict init-order checking is thread-hostile.
+  if (flags()->strict_init_order) StopInitOrderChecking();
+
+  GET_STACK_TRACE_THREAD;
+  u32 parent_tid = GetCurrentTidOrInvalid();
+
+  return CreateAsanThread(&stack, parent_tid, user_id, detached,
+                          stack_bottom, stack_size, tls_bottom, tls_size);
+}
+
+// This is called after creating a new thread (in the creating thread),
+// with the pointer returned by BeforeThreadCreateHook (above).
+static void ThreadCreateHook(void *hook, bool aborted) {
+  AsanThread *thread = static_cast<AsanThread *>(hook);
+  if (!aborted) {
+    // The thread was created successfully.
+    // ThreadStartHook is already running in the new thread.
+  } else {
+    // The thread wasn't created after all.
+    // Clean up everything we set up in BeforeThreadCreateHook.
+    asanThreadRegistry().FinishThread(thread->tid());
+    UnmapOrDie(thread, sizeof(AsanThread));
+  }
+}
+
+// This is called (1) in the newly-created thread before it runs
+// anything else, with the pointer returned by BeforeThreadCreateHook
+// (above).  cf. asan_interceptors.cc:asan_thread_start.  (2) before
+// a thread restart.
+static void ThreadStartHook(void *hook, uptr os_id) {
+  if (!hook && !MainThreadSelf)
+    return;
+
+  DCHECK(hook || os_id == MainThreadSelf);
+  AsanThread *thread = hook ? static_cast<AsanThread *>(hook) : MainThread;
+  SetCurrentThread(thread);
+
+  ThreadStatus status =
+      asanThreadRegistry().GetThreadLocked(thread->tid())->status;
+  DCHECK(status == ThreadStatusCreated || status == ThreadStatusRunning);
+  // Determine whether we are starting or restarting the thread.
+  if (status == ThreadStatusCreated)
+    // In lieu of AsanThread::ThreadStart.
+    asanThreadRegistry().StartThread(thread->tid(), os_id,
+                                     /*workerthread*/ false, nullptr);
+  else {
+    // In a thread restart, a thread may resume execution at an
+    // arbitrary function entry point, with its stack and TLS state
+    // reset.  We unpoison the stack in that case.
+    PoisonShadow(thread->stack_bottom(), thread->stack_size(), 0);
+  }
+}
+
+// Each thread runs this just before it exits,
+// with the pointer returned by BeforeThreadCreateHook (above).
+// All per-thread destructors have already been called.
+static void ThreadExitHook(void *hook, uptr os_id) {
+  AsanThread *thread = static_cast<AsanThread *>(hook);
+  if (thread)
+    AsanThread::TSDDtor(thread->context());
+}
+
+static void HandleExit() {
+  // Disable ASan by setting it to uninitialized.  Also reset the
+  // shadow memory to avoid reporting errors after the run-time has
+  // been desroyed.
+  asan_inited = false;
+  //  InitializeShadowMemory();
+}
+
+}  // namespace __asan
+
+// These are declared (in extern "C") by <some_path/sanitizer.h>.
+// The system runtime will call our definitions directly.
+
+extern "C" {
+void __sanitizer_early_init() {
+  __asan::EarlyInit();
+}
+
+void *__sanitizer_before_thread_create_hook(uptr thread, bool detached,
+                                            const char *name,
+                                            void *stack_base, size_t stack_size,
+                                            void *tls_base, size_t tls_size) {
+  return __asan::BeforeThreadCreateHook(
+      thread, detached,
+      reinterpret_cast<uptr>(stack_base), stack_size,
+      reinterpret_cast<uptr>(tls_base), tls_size);
+}
+
+void __sanitizer_thread_create_hook(void *handle, uptr thread, int status) {
+  __asan::ThreadCreateHook(handle, status != 0);
+}
+
+void __sanitizer_thread_start_hook(void *handle, uptr self) {
+  __asan::ThreadStartHook(handle, self);
+}
+
+void __sanitizer_thread_exit_hook(void *handle, uptr self) {
+  __asan::ThreadExitHook(handle, self);
+}
+
+void __sanitizer_exit() {
+  __asan::HandleExit();
+}
+}  // "C"
+
+#endif  // SANITIZER_RTEMS

Modified: compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt?rev=332691&r1=332690&r2=332691&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt Thu May 17 21:10:12 2018
@@ -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

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc?rev=332691&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc Thu May 17 21:10:12 2018
@@ -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

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.h?rev=332691&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.h (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.h Thu May 17 21:10:12 2018
@@ -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




More information about the llvm-commits mailing list