//=-- lsan_common_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.
// Implementation of common leak checking functionality. Fuchsia-specific code.
//
//===---------------------------------------------------------------------===//

#include "lsan_common.h"
#include "sanitizer_common/sanitizer_platform.h"

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

#include "lsan_allocator.h"
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_stoptheworld_fuchsia.h"
#include "sanitizer_common/sanitizer_thread_registry.h"

// Ensure that the Zircon system ABI is linked in.
#pragma comment(lib, "zircon")

namespace __lsan {

void InitializePlatformSpecificModules() {}

LoadedModule *GetLinker() { return nullptr; }

__attribute__((tls_model("initial-exec"))) THREADLOCAL int disable_counter;
bool DisabledInThisThread() { return disable_counter > 0; }
void DisableInThisThread() { disable_counter++; }
void EnableInThisThread() {
  if (disable_counter == 0) {
    DisableCounterUnderflow();
  }
  disable_counter--;
}

// There is nothing left to do after the globals callbacks.
void ProcessGlobalRegions(Frontier *frontier) {}

// Nothing to do here.
void ProcessPlatformSpecificAllocations(Frontier *frontier) {}

// On Fuchsia, we can intercept _Exit gracefully, and return a failing exit
// code if required at that point.  Calling Die() here is undefined
// behavior and causes rare race conditions.
void HandleLeaks() {}

int ExitHook(int status) {
  return status == 0 && HasReportedLeaks() ? common_flags()->exitcode : status;
}

void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
                              CheckForLeaksParam *argument) {
  LockThreadRegistry();
  LockAllocator();

  struct Params {
    InternalMmapVector<uptr> allocator_caches;
    StopTheWorldCallback callback;
    CheckForLeaksParam *argument;
  } params = {{}, callback, argument};

  // Callback from libc for globals (data/bss modulo relro), when enabled.
  auto globals = +[](void *chunk, size_t size, void *data) {
    auto params = static_cast<const Params *>(data);
    uptr begin = reinterpret_cast<uptr>(chunk);
    uptr end = begin + size;
    ScanGlobalRange(begin, end, &params->argument->frontier);
  };

  // Callback from libc for thread stacks.
  auto stacks = +[](void *chunk, size_t size, void *data) {
    auto params = static_cast<const Params *>(data);
    uptr begin = reinterpret_cast<uptr>(chunk);
    uptr end = begin + size;
    ScanRangeForPointers(begin, end, &params->argument->frontier, "STACK",
                         kReachable);
  };

  // Callback from libc for thread registers.
  auto registers = +[](void *chunk, size_t size, void *data) {
    auto params = static_cast<const Params *>(data);
    uptr begin = reinterpret_cast<uptr>(chunk);
    uptr end = begin + size;
    ScanRangeForPointers(begin, end, &params->argument->frontier, "REGISTERS",
                         kReachable);
  };

  if (flags()->use_tls) {
    // Collect the allocator cache range from each thread so these
    // can all be excluded from the reported TLS ranges.
    GetAllThreadAllocatorCachesLocked(&params.allocator_caches);
    __sanitizer::Sort(params.allocator_caches.data(),
                      params.allocator_caches.size());
  }

  // Callback from libc for TLS regions.  This includes thread_local
  // variables as well as C11 tss_set and POSIX pthread_setspecific.
  auto tls = +[](void *chunk, size_t size, void *data) {
    auto params = static_cast<const Params *>(data);
    uptr begin = reinterpret_cast<uptr>(chunk);
    uptr end = begin + size;
    auto i = __sanitizer::InternalLowerBound(params->allocator_caches, begin);
    if (i < params->allocator_caches.size() &&
        params->allocator_caches[i] >= begin &&
        end - params->allocator_caches[i] <= sizeof(AllocatorCache)) {
      // Split the range in two and omit the allocator cache within.
      ScanRangeForPointers(begin, params->allocator_caches[i],
                           &params->argument->frontier, "TLS", kReachable);
      uptr begin2 = params->allocator_caches[i] + sizeof(AllocatorCache);
      ScanRangeForPointers(begin2, end, &params->argument->frontier, "TLS",
                           kReachable);
    } else {
      ScanRangeForPointers(begin, end, &params->argument->frontier, "TLS",
                           kReachable);
    }
  };

  // This stops the world and then makes callbacks for various memory regions.
  // The final callback is the last thing before the world starts up again.
  __sanitizer_memory_snapshot(
      flags()->use_globals ? globals : nullptr,
      flags()->use_stacks ? stacks : nullptr,
      flags()->use_registers ? registers : nullptr,
      flags()->use_tls ? tls : nullptr,
      [](zx_status_t, void *data) {
        auto params = static_cast<const Params *>(data);

        // We don't use the thread registry at all for enumerating the threads
        // and their stacks, registers, and TLS regions.  So use it separately
        // just for the allocator cache, and to call ForEachExtraStackRange,
        // which ASan needs.
        if (flags()->use_stacks) {
          GetThreadRegistryLocked()->RunCallbackForEachThreadLocked(
              [](ThreadContextBase *tctx, void *arg) {
                ForEachExtraStackRange(tctx->os_id, ForEachExtraStackRangeCb,
                                       arg);
              },
              &params->argument->frontier);
        }

        params->callback(SuspendedThreadsListFuchsia(), params->argument);
      },
      &params);

  UnlockAllocator();
  UnlockThreadRegistry();
}

}  // namespace __lsan

// This is declared (in extern "C") by <zircon/sanitizer.h>.
// _Exit calls this directly to intercept and change the status value.
int __sanitizer_process_exit_hook(int status) {
  return __lsan::ExitHook(status);
}

#endif
