//===-- tsan_platform_mac.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer (TSan), a race detector.
//
// Mac-specific code.
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_APPLE

#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_posix.h"
#include "sanitizer_common/sanitizer_procmaps.h"
#include "sanitizer_common/sanitizer_ptrauth.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "tsan_platform.h"
#include "tsan_rtl.h"
#include "tsan_flags.h"

#include <limits.h>
#include <mach/mach.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <sched.h>

namespace __tsan {

#if !SANITIZER_GO
static char main_thread_state[sizeof(ThreadState)] ALIGNED(
    SANITIZER_CACHE_LINE_SIZE);
static ThreadState *dead_thread_state;
static pthread_key_t thread_state_key;

// We rely on the following documented, but Darwin-specific behavior to keep the
// reference to the ThreadState object alive in TLS:
// pthread_key_create man page:
//   If, after all the destructors have been called for all non-NULL values with
//   associated destructors, there are still some non-NULL values with
//   associated destructors, then the process is repeated.  If, after at least
//   [PTHREAD_DESTRUCTOR_ITERATIONS] iterations of destructor calls for
//   outstanding non-NULL values, there are still some non-NULL values with
//   associated destructors, the implementation stops calling destructors.
static_assert(PTHREAD_DESTRUCTOR_ITERATIONS == 4, "Small number of iterations");
static void ThreadStateDestructor(void *thr) {
  int res = pthread_setspecific(thread_state_key, thr);
  CHECK_EQ(res, 0);
}

static void InitializeThreadStateStorage() {
  int res;
  CHECK_EQ(thread_state_key, 0);
  res = pthread_key_create(&thread_state_key, ThreadStateDestructor);
  CHECK_EQ(res, 0);
  res = pthread_setspecific(thread_state_key, main_thread_state);
  CHECK_EQ(res, 0);

  auto dts = (ThreadState *)MmapOrDie(sizeof(ThreadState), "ThreadState");
  dts->fast_state.SetIgnoreBit();
  dts->ignore_interceptors = 1;
  dts->is_dead = true;
  const_cast<Tid &>(dts->tid) = kInvalidTid;
  res = internal_mprotect(dts, sizeof(ThreadState), PROT_READ);  // immutable
  CHECK_EQ(res, 0);
  dead_thread_state = dts;
}

ThreadState *cur_thread() {
  // Some interceptors get called before libpthread has been initialized and in
  // these cases we must avoid calling any pthread APIs.
  if (UNLIKELY(!thread_state_key)) {
    return (ThreadState *)main_thread_state;
  }

  // We only reach this line after InitializeThreadStateStorage() ran, i.e,
  // after TSan (and therefore libpthread) have been initialized.
  ThreadState *thr = (ThreadState *)pthread_getspecific(thread_state_key);
  if (UNLIKELY(!thr)) {
    thr = (ThreadState *)MmapOrDie(sizeof(ThreadState), "ThreadState");
    int res = pthread_setspecific(thread_state_key, thr);
    CHECK_EQ(res, 0);
  }
  return thr;
}

void set_cur_thread(ThreadState *thr) {
  int res = pthread_setspecific(thread_state_key, thr);
  CHECK_EQ(res, 0);
}

void cur_thread_finalize() {
  ThreadState *thr = (ThreadState *)pthread_getspecific(thread_state_key);
  CHECK(thr);
  if (thr == (ThreadState *)main_thread_state) {
    // Calling dispatch_main() or xpc_main() actually invokes pthread_exit to
    // exit the main thread. Let's keep the main thread's ThreadState.
    return;
  }
  // Intercepted functions can still get called after cur_thread_finalize()
  // (called from DestroyThreadState()), so put a fake thread state for "dead"
  // threads.  An alternative solution would be to release the ThreadState
  // object from THREAD_DESTROY (which is delivered later and on the parent
  // thread) instead of THREAD_TERMINATE.
  int res = pthread_setspecific(thread_state_key, dead_thread_state);
  CHECK_EQ(res, 0);
  UnmapOrDie(thr, sizeof(ThreadState));
}
#endif

void FlushShadowMemory() {
}

static void RegionMemUsage(uptr start, uptr end, uptr *res, uptr *dirty) {
  vm_address_t address = start;
  vm_address_t end_address = end;
  uptr resident_pages = 0;
  uptr dirty_pages = 0;
  while (address < end_address) {
    vm_size_t vm_region_size;
    mach_msg_type_number_t count = VM_REGION_EXTENDED_INFO_COUNT;
    vm_region_extended_info_data_t vm_region_info;
    mach_port_t object_name;
    kern_return_t ret = vm_region_64(
        mach_task_self(), &address, &vm_region_size, VM_REGION_EXTENDED_INFO,
        (vm_region_info_t)&vm_region_info, &count, &object_name);
    if (ret != KERN_SUCCESS) break;

    resident_pages += vm_region_info.pages_resident;
    dirty_pages += vm_region_info.pages_dirtied;

    address += vm_region_size;
  }
  *res = resident_pages * GetPageSizeCached();
  *dirty = dirty_pages * GetPageSizeCached();
}

void WriteMemoryProfile(char *buf, uptr buf_size, u64 uptime_ns) {
  uptr shadow_res, shadow_dirty;
  uptr meta_res, meta_dirty;
  uptr trace_res, trace_dirty;
  RegionMemUsage(ShadowBeg(), ShadowEnd(), &shadow_res, &shadow_dirty);
  RegionMemUsage(MetaShadowBeg(), MetaShadowEnd(), &meta_res, &meta_dirty);
  RegionMemUsage(TraceMemBeg(), TraceMemEnd(), &trace_res, &trace_dirty);

#if !SANITIZER_GO
  uptr low_res, low_dirty;
  uptr high_res, high_dirty;
  uptr heap_res, heap_dirty;
  RegionMemUsage(LoAppMemBeg(), LoAppMemEnd(), &low_res, &low_dirty);
  RegionMemUsage(HiAppMemBeg(), HiAppMemEnd(), &high_res, &high_dirty);
  RegionMemUsage(HeapMemBeg(), HeapMemEnd(), &heap_res, &heap_dirty);
#else  // !SANITIZER_GO
  uptr app_res, app_dirty;
  RegionMemUsage(LoAppMemBeg(), LoAppMemEnd(), &app_res, &app_dirty);
#endif

  StackDepotStats stacks = StackDepotGetStats();
  uptr nthread, nlive;
  ctx->thread_registry.GetNumberOfThreads(&nthread, &nlive);
  internal_snprintf(
      buf, buf_size,
      "shadow   (0x%016zx-0x%016zx): resident %zd kB, dirty %zd kB\n"
      "meta     (0x%016zx-0x%016zx): resident %zd kB, dirty %zd kB\n"
      "traces   (0x%016zx-0x%016zx): resident %zd kB, dirty %zd kB\n"
#  if !SANITIZER_GO
      "low app  (0x%016zx-0x%016zx): resident %zd kB, dirty %zd kB\n"
      "high app (0x%016zx-0x%016zx): resident %zd kB, dirty %zd kB\n"
      "heap     (0x%016zx-0x%016zx): resident %zd kB, dirty %zd kB\n"
#  else  // !SANITIZER_GO
      "app      (0x%016zx-0x%016zx): resident %zd kB, dirty %zd kB\n"
#  endif
      "stacks: %zd unique IDs, %zd kB allocated\n"
      "threads: %zd total, %zd live\n"
      "------------------------------\n",
      ShadowBeg(), ShadowEnd(), shadow_res / 1024, shadow_dirty / 1024,
      MetaShadowBeg(), MetaShadowEnd(), meta_res / 1024, meta_dirty / 1024,
      TraceMemBeg(), TraceMemEnd(), trace_res / 1024, trace_dirty / 1024,
#  if !SANITIZER_GO
      LoAppMemBeg(), LoAppMemEnd(), low_res / 1024, low_dirty / 1024,
      HiAppMemBeg(), HiAppMemEnd(), high_res / 1024, high_dirty / 1024,
      HeapMemBeg(), HeapMemEnd(), heap_res / 1024, heap_dirty / 1024,
#  else  // !SANITIZER_GO
      LoAppMemBeg(), LoAppMemEnd(), app_res / 1024, app_dirty / 1024,
#  endif
      stacks.n_uniq_ids, stacks.allocated / 1024, nthread, nlive);
}

#  if !SANITIZER_GO
void InitializeShadowMemoryPlatform() { }

// On OS X, GCD worker threads are created without a call to pthread_create. We
// need to properly register these threads with ThreadCreate and ThreadStart.
// These threads don't have a parent thread, as they are created "spuriously".
// We're using a libpthread API that notifies us about a newly created thread.
// The `thread == pthread_self()` check indicates this is actually a worker
// thread. If it's just a regular thread, this hook is called on the parent
// thread.
typedef void (*pthread_introspection_hook_t)(unsigned int event,
                                             pthread_t thread, void *addr,
                                             size_t size);
extern "C" pthread_introspection_hook_t pthread_introspection_hook_install(
    pthread_introspection_hook_t hook);
static const uptr PTHREAD_INTROSPECTION_THREAD_CREATE = 1;
static const uptr PTHREAD_INTROSPECTION_THREAD_TERMINATE = 3;
static pthread_introspection_hook_t prev_pthread_introspection_hook;
static void my_pthread_introspection_hook(unsigned int event, pthread_t thread,
                                          void *addr, size_t size) {
  if (event == PTHREAD_INTROSPECTION_THREAD_CREATE) {
    if (thread == pthread_self()) {
      // The current thread is a newly created GCD worker thread.
      ThreadState *thr = cur_thread();
      Processor *proc = ProcCreate();
      ProcWire(proc, thr);
      ThreadState *parent_thread_state = nullptr;  // No parent.
      Tid tid = ThreadCreate(parent_thread_state, 0, (uptr)thread, true);
      CHECK_NE(tid, kMainTid);
      ThreadStart(thr, tid, GetTid(), ThreadType::Worker);
    }
  } else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) {
    CHECK_EQ(thread, pthread_self());
    ThreadState *thr = cur_thread();
    if (thr->tctx) {
      DestroyThreadState();
    }
  }

  if (prev_pthread_introspection_hook != nullptr)
    prev_pthread_introspection_hook(event, thread, addr, size);
}
#endif

void InitializePlatformEarly() {
#  if !SANITIZER_GO && SANITIZER_IOS
  uptr max_vm = GetMaxUserVirtualAddress() + 1;
  if (max_vm != HiAppMemEnd()) {
    Printf("ThreadSanitizer: unsupported vm address limit %p, expected %p.\n",
           (void *)max_vm, (void *)HiAppMemEnd());
    Die();
  }
#endif
}

static uptr longjmp_xor_key = 0;

void InitializePlatform() {
  DisableCoreDumperIfNecessary();
#if !SANITIZER_GO
  CheckAndProtect();

  InitializeThreadStateStorage();

  prev_pthread_introspection_hook =
      pthread_introspection_hook_install(&my_pthread_introspection_hook);
#endif

  if (GetMacosAlignedVersion() >= MacosVersion(10, 14)) {
    // Libsystem currently uses a process-global key; this might change.
    const unsigned kTLSLongjmpXorKeySlot = 0x7;
    longjmp_xor_key = (uptr)pthread_getspecific(kTLSLongjmpXorKeySlot);
  }
}

#ifdef __aarch64__
# define LONG_JMP_SP_ENV_SLOT \
    ((GetMacosAlignedVersion() >= MacosVersion(10, 14)) ? 12 : 13)
#else
# define LONG_JMP_SP_ENV_SLOT 2
#endif

uptr ExtractLongJmpSp(uptr *env) {
  uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT];
  uptr sp = mangled_sp ^ longjmp_xor_key;
  sp = (uptr)ptrauth_auth_data((void *)sp, ptrauth_key_asdb,
                               ptrauth_string_discriminator("sp"));
  return sp;
}

#if !SANITIZER_GO
extern "C" void __tsan_tls_initialization() {}

void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
  const uptr pc = StackTrace::GetNextInstructionPc(
      reinterpret_cast<uptr>(__tsan_tls_initialization));
  // Unlike Linux, we only store a pointer to the ThreadState object in TLS;
  // just mark the entire range as written to.
  MemoryRangeImitateWrite(thr, pc, tls_addr, tls_size);
}
#endif

#if !SANITIZER_GO
// Note: this function runs with async signals enabled,
// so it must not touch any tsan state.
int call_pthread_cancel_with_cleanup(int (*fn)(void *arg),
                                     void (*cleanup)(void *arg), void *arg) {
  // pthread_cleanup_push/pop are hardcore macros mess.
  // We can't intercept nor call them w/o including pthread.h.
  int res;
  pthread_cleanup_push(cleanup, arg);
  res = fn(arg);
  pthread_cleanup_pop(0);
  return res;
}
#endif

}  // namespace __tsan

#endif  // SANITIZER_APPLE
