//===-- sanitizer_rtems.cc ------------------------------------------------===//
//
// 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 CheckASLR() {}
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 | O_TRUNC; 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 nullptr; }

const char *GetEnv(const char *name) {
  return getenv(name);
}

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

#endif  // SANITIZER_RTEMS
