//===-- copyprof.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 implements the core CopyProf runtime initialization and callback
/// functions inserted by the instrumentation passes.
///
//===----------------------------------------------------------------------===//

#include "copyprof_interface_internal.h"
#include "copyprof_reporting.h"
#include "copyprof_shadow.h"
#include "copyprof_state.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_internal_defs.h"

using namespace __copyprof;

namespace __copyprof {

// Whether CopyProf has been initialized.
bool copyprof_is_initialized;
// Whether CopyProf is currently initializing.
bool copyprof_init_is_running;

static void CheckUnwind() {
  UNINITIALIZED BufferedStackTrace trace;
  trace.Unwind(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(),
               /*context=*/nullptr, common_flags()->fast_unwind_on_check);
  trace.Print();
}

static void Initialize() {
  if (LIKELY(copyprof_is_initialized))
    return;
  CHECK(!copyprof_init_is_running &&
        "BUG: CopyProf Initialize() must not call itself.");
  copyprof_init_is_running = true;
  CacheBinaryName();
  SetCheckUnwindCallback(&CheckUnwind);
  InitializePlatformEarly();
  SetCommonFlagsDefaults();
  InitializeCommonFlags();
  InitializeShadowMemory();
  copyprof_init_is_running = false;
  copyprof_is_initialized = true;
}

static void MaybeUpdateSmfContext(SmfContext context) {
  // Only entering a top level special member function changes the current
  // context. The context logically remains the same until control flow leaves
  // the top level function.
  if (__copyprof_state.construct_nesting_level == 0 &&
      __copyprof_state.copy_nesting_level == 0 &&
      __copyprof_state.destruct_nesting_level == 0) {
    __copyprof_state.smf_context = context;
  }
}

// Updates shadow memory for `[addr, addr + size)` according to the current SMF
// context: no update in `DTOR` context (objects may mutate their memory during
// destruction, but that must not invalidate its classification as an
// unnecessary copy), marked as copy in `COPY` context, and marked as non-copy
// otherwise.
static void UpdateShadow(const void* addr, uptr size) {
  if (UNLIKELY(__copyprof_state.smf_context == SmfContext::DTOR))
    return;
  MarkApplicationMemory(addr, size,
                        __copyprof_state.smf_context == SmfContext::COPY);
}

static void CopyMemberFunctionEnter(const void* this_ptr, uptr obj_size) {
  MaybeUpdateSmfContext(SmfContext::COPY);
  if (__copyprof_state.copy_nesting_level++ == 0) {
    __copyprof_state.current_this_ptr = this_ptr;
  }
  UpdateShadow(this_ptr, obj_size);
}

static void CopyMemberFunctionExit(const void* this_ptr, uptr obj_size) {
  --__copyprof_state.copy_nesting_level;
  MaybeUpdateSmfContext(SmfContext::NONE);
}

}  // namespace __copyprof

void __copyprof_init_once() { Initialize(); }

void __copyprof_ctor_enter_callback(const void* this_ptr, uptr obj_size) {
  MaybeUpdateSmfContext(SmfContext::CTOR);
  ++__copyprof_state.construct_nesting_level;
  UpdateShadow(this_ptr, obj_size);
}

void __copyprof_ctor_exit_callback(const void* this_ptr, uptr obj_size) {
  --__copyprof_state.construct_nesting_level;
  MaybeUpdateSmfContext(SmfContext::NONE);
}

void __copyprof_copy_ctor_enter_callback(const void* this_ptr,
                                         const void* other_ptr, uptr obj_size) {
  CopyMemberFunctionEnter(this_ptr, obj_size);
}

void __copyprof_copy_ctor_exit_callback(const void* this_ptr,
                                        const void* other_ptr, uptr obj_size) {
  CopyMemberFunctionExit(this_ptr, obj_size);
}

void __copyprof_copy_assign_op_enter_callback(const void* this_ptr,
                                              const void* other_ptr,
                                              uptr obj_size) {
  CopyMemberFunctionEnter(this_ptr, obj_size);
}

void __copyprof_copy_assign_op_exit_callback(const void* this_ptr,
                                             const void* other_ptr,
                                             uptr obj_size) {
  CopyMemberFunctionExit(this_ptr, obj_size);
}

void __copyprof_dtor_enter_callback(const void* this_ptr, uptr obj_size) {
  MaybeUpdateSmfContext(SmfContext::DTOR);
  if (__copyprof_state.destruct_nesting_level++ == 0) {
    // Control flow just entered the top-level d'tor. Optimistically mark
    // `is_transitive_copy` as `true`. If any subsequent d'tor observes object
    // memory marked as not copy, then the flag will be set to `false`.
    __copyprof_state.is_transitive_copy = true;
  }
}

void __copyprof_dtor_exit_callback(const void* this_ptr, uptr obj_size) {
  --__copyprof_state.destruct_nesting_level;
  MaybeUpdateSmfContext(SmfContext::NONE);
  // If this is the top level-dtor and `this` is transitively marked as copy,
  // then an object has been found whose transitively owned memory is marked as
  // copy, so a report is logged.
  __copyprof_state.is_transitive_copy &= IsMarkedAsCopy(this_ptr, obj_size);
  if (__copyprof_state.destruct_nesting_level == 0 &&
      __copyprof_state.is_transitive_copy) {
    // TODO: Dynamic allocation tracking via malloc/new interception will be
    // added in a subsequent patch. For now, did_allocate is set to true.
    LogCopyProfReport(GET_CALLER_PC(), GET_CURRENT_FRAME(), obj_size,
                      /*did_allocate=*/true);
  }
}

void __copyprof_store_callback(const void* addr, uptr size) {
  UpdateShadow(addr, size);
}
