//=-- lsan_fuchsia.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 LeakSanitizer.
// Standalone LSan RTL code specific to Fuchsia.
//
//===---------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_platform.h"

#if SANITIZER_FUCHSIA
#include <zircon/sanitizer.h>

#include "lsan.h"
#include "lsan_allocator.h"

using namespace __lsan;

namespace __lsan {

void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {}

ThreadContext::ThreadContext(int tid) : ThreadContextLsanBase(tid) {}

struct OnCreatedArgs {
  uptr stack_begin, stack_end;
};

// On Fuchsia, the stack bounds of a new thread are available before
// the thread itself has started running.
void ThreadContext::OnCreated(void *arg) {
  // Stack bounds passed through from __sanitizer_before_thread_create_hook
  // or InitializeMainThread.
  auto args = reinterpret_cast<const OnCreatedArgs *>(arg);
  stack_begin_ = args->stack_begin;
  stack_end_ = args->stack_end;
}

struct OnStartedArgs {
  uptr cache_begin, cache_end;
};

void ThreadContext::OnStarted(void *arg) {
  auto args = reinterpret_cast<const OnStartedArgs *>(arg);
  cache_begin_ = args->cache_begin;
  cache_end_ = args->cache_end;
}

void ThreadStart(u32 tid) {
  OnStartedArgs args;
  GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);
  CHECK_EQ(args.cache_end - args.cache_begin, sizeof(AllocatorCache));
  ThreadContextLsanBase::ThreadStart(tid, GetTid(), ThreadType::Regular, &args);
}

void InitializeMainThread() {
  OnCreatedArgs args;
  __sanitizer::GetThreadStackTopAndBottom(true, &args.stack_end,
                                          &args.stack_begin);
  u32 tid = ThreadCreate(kMainTid, true, &args);
  CHECK_EQ(tid, 0);
  ThreadStart(tid);
}

void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) {
  GetThreadRegistryLocked()->RunCallbackForEachThreadLocked(
      [](ThreadContextBase *tctx, void *arg) {
        auto ctx = static_cast<ThreadContext *>(tctx);
        static_cast<decltype(caches)>(arg)->push_back(ctx->cache_begin());
      },
      caches);
}

// On Fuchsia, leak detection is done by a special hook after atexit hooks.
// So this doesn't install any atexit hook like on other platforms.
void InstallAtExitCheckLeaks() {}

// ASan defines this to check its `halt_on_error` flag.
bool UseExitcodeOnLeak() { return true; }

}  // namespace __lsan

// These are declared (in extern "C") by <zircon/sanitizer.h>.
// The system runtime will call our definitions directly.

// This is called before each thread creation is attempted.  So, in
// its first call, the calling thread is the initial and sole thread.
void *__sanitizer_before_thread_create_hook(thrd_t thread, bool detached,
                                            const char *name, void *stack_base,
                                            size_t stack_size) {
  ENSURE_LSAN_INITED;
  EnsureMainThreadIDIsCorrect();
  OnCreatedArgs args;
  args.stack_begin = reinterpret_cast<uptr>(stack_base);
  args.stack_end = args.stack_begin + stack_size;
  u32 parent_tid = GetCurrentThread();
  u32 tid = ThreadCreate(parent_tid, detached, &args);
  return reinterpret_cast<void *>(static_cast<uptr>(tid));
}

// This is called after creating a new thread (in the creating thread),
// with the pointer returned by __sanitizer_before_thread_create_hook (above).
void __sanitizer_thread_create_hook(void *hook, thrd_t thread, int error) {
  u32 tid = static_cast<u32>(reinterpret_cast<uptr>(hook));
  // On success, there is nothing to do here.
  if (error != thrd_success) {
    // Clean up the thread registry for the thread creation that didn't happen.
    GetThreadRegistryLocked()->FinishThread(tid);
  }
}

// This is called in the newly-created thread before it runs anything else,
// with the pointer returned by __sanitizer_before_thread_create_hook (above).
void __sanitizer_thread_start_hook(void *hook, thrd_t self) {
  u32 tid = static_cast<u32>(reinterpret_cast<uptr>(hook));
  ThreadStart(tid);
}

// Each thread runs this just before it exits,
// with the pointer returned by BeforeThreadCreateHook (above).
// All per-thread destructors have already been called.
void __sanitizer_thread_exit_hook(void *hook, thrd_t self) { ThreadFinish(); }

#endif  // SANITIZER_FUCHSIA
