//===-- AppleGetThreadItemInfoHandler.cpp -------------------------------*- C++
//-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "AppleGetThreadItemInfoHandler.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes

#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/Expression.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/lldb-private.h"

using namespace lldb;
using namespace lldb_private;

const char
    *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_name =
        "__lldb_backtrace_recording_get_thread_item_info";
const char
    *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_code =
        "                                  \n\
extern \"C\"                                                                                                    \n\
{                                                                                                               \n\
    /*                                                                                                          \n\
     * mach defines                                                                                             \n\
     */                                                                                                         \n\
                                                                                                                \n\
    typedef unsigned int uint32_t;                                                                              \n\
    typedef unsigned long long uint64_t;                                                                        \n\
    typedef uint32_t mach_port_t;                                                                               \n\
    typedef mach_port_t vm_map_t;                                                                               \n\
    typedef int kern_return_t;                                                                                  \n\
    typedef uint64_t mach_vm_address_t;                                                                         \n\
    typedef uint64_t mach_vm_size_t;                                                                            \n\
                                                                                                                \n\
    mach_port_t mach_task_self ();                                                                              \n\
    kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size);         \n\
                                                                                                                \n\
    typedef void *pthread_t;                                                                                    \n\
    extern int printf(const char *format, ...);                                                                 \n\
    extern pthread_t pthread_self(void);                                                                        \n\
                                                                                                                \n\
    /*                                                                                                          \n\
     * libBacktraceRecording defines                                                                            \n\
     */                                                                                                         \n\
                                                                                                                \n\
    typedef uint32_t queue_list_scope_t;                                                                        \n\
    typedef void *dispatch_queue_t;                                                                             \n\
    typedef void *introspection_dispatch_queue_info_t;                                                          \n\
    typedef void *introspection_dispatch_item_info_ref;                                                         \n\
                                                                                                                \n\
    extern void __introspection_dispatch_thread_get_item_info (uint64_t  thread_id,                             \n\
                                                 introspection_dispatch_item_info_ref *returned_queues_buffer,  \n\
                                                 uint64_t *returned_queues_buffer_size);                        \n\
                                                                                                                \n\
    /*                                                                                                          \n\
     * return type define                                                                                       \n\
     */                                                                                                         \n\
                                                                                                                \n\
    struct get_thread_item_info_return_values                                                                      \n\
    {                                                                                                           \n\
        uint64_t item_info_buffer_ptr;    /* the address of the items buffer from libBacktraceRecording */  \n\
        uint64_t item_info_buffer_size;   /* the size of the items buffer from libBacktraceRecording */     \n\
    };                                                                                                          \n\
                                                                                                                \n\
    void  __lldb_backtrace_recording_get_thread_item_info                                                          \n\
                                               (struct get_thread_item_info_return_values *return_buffer,          \n\
                                                int debug,                                                      \n\
                                                uint64_t thread_id,                                             \n\
                                                void *page_to_free,                                             \n\
                                                uint64_t page_to_free_size)                                     \n\
{                                                                                                               \n\
    void *pthread_id = pthread_self ();                                                                         \n\
    if (debug)                                                                                                  \n\
      printf (\"entering get_thread_item_info with args return_buffer == %p, debug == %d, thread id == 0x%llx, page_to_free == %p, page_to_free_size == 0x%llx\\n\", return_buffer, debug, (uint64_t) thread_id, page_to_free, page_to_free_size); \n\
    if (page_to_free != 0)                                                                                      \n\
    {                                                                                                           \n\
        mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
    }                                                                                                           \n\
                                                                                                                \n\
    __introspection_dispatch_thread_get_item_info (thread_id,                                                  \n\
                                                  (void**)&return_buffer->item_info_buffer_ptr,                 \n\
                                                  &return_buffer->item_info_buffer_size);                       \n\
}                                                                                                               \n\
}                                                                                                               \n\
";

AppleGetThreadItemInfoHandler::AppleGetThreadItemInfoHandler(Process *process)
    : m_process(process), m_get_thread_item_info_impl_code(),
      m_get_thread_item_info_function_mutex(),
      m_get_thread_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
      m_get_thread_item_info_retbuffer_mutex() {}

AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler() {}

void AppleGetThreadItemInfoHandler::Detach() {

  if (m_process && m_process->IsAlive() &&
      m_get_thread_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS) {
    std::unique_lock<std::mutex> lock(m_get_thread_item_info_retbuffer_mutex,
                                      std::defer_lock);
    lock.try_lock(); // Even if we don't get the lock, deallocate the buffer
    m_process->DeallocateMemory(m_get_thread_item_info_return_buffer_addr);
  }
}

// Compile our __lldb_backtrace_recording_get_thread_item_info() function (from
// the
// source above in g_get_thread_item_info_function_code) if we don't find that
// function in the inferior
// already with USE_BUILTIN_FUNCTION defined.  (e.g. this would be the case for
// testing.)
//
// Insert the __lldb_backtrace_recording_get_thread_item_info into the inferior
// process if needed.
//
// Write the get_thread_item_info_arglist into the inferior's memory space to
// prepare for the call.
//
// Returns the address of the arguments written down in the inferior process,
// which can be used to
// make the function call.

lldb::addr_t AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction(
    Thread &thread, ValueList &get_thread_item_info_arglist) {
  ThreadSP thread_sp(thread.shared_from_this());
  ExecutionContext exe_ctx(thread_sp);
  Address impl_code_address;
  DiagnosticManager diagnostics;
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));
  lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
  FunctionCaller *get_thread_item_info_caller = nullptr;

  // Scope for mutex locker:
  {
    std::lock_guard<std::mutex> guard(m_get_thread_item_info_function_mutex);

    // First stage is to make the ClangUtility to hold our injected function:

    if (!m_get_thread_item_info_impl_code.get()) {
      Status error;
      if (g_get_thread_item_info_function_code != NULL) {
        m_get_thread_item_info_impl_code.reset(
            exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
                g_get_thread_item_info_function_code, eLanguageTypeC,
                g_get_thread_item_info_function_name, error));
        if (error.Fail()) {
          if (log)
            log->Printf("Failed to get UtilityFunction for "
                        "get-thread-item-info introspection: %s.",
                        error.AsCString());
          m_get_thread_item_info_impl_code.reset();
          return args_addr;
        }

        if (!m_get_thread_item_info_impl_code->Install(diagnostics, exe_ctx)) {
          if (log) {
            log->Printf(
                "Failed to install get-thread-item-info introspection.");
            diagnostics.Dump(log);
          }

          m_get_thread_item_info_impl_code.reset();
          return args_addr;
        }
      } else {
        if (log)
          log->Printf("No get-thread-item-info introspection code found.");
        return LLDB_INVALID_ADDRESS;
      }

      // Also make the FunctionCaller for this UtilityFunction:

      ClangASTContext *clang_ast_context =
          thread.GetProcess()->GetTarget().GetScratchClangASTContext();
      CompilerType get_thread_item_info_return_type =
          clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();

      get_thread_item_info_caller =
          m_get_thread_item_info_impl_code->MakeFunctionCaller(
              get_thread_item_info_return_type, get_thread_item_info_arglist,
              thread_sp, error);
      if (error.Fail() || get_thread_item_info_caller == nullptr) {
        if (log)
          log->Printf("Failed to install get-thread-item-info introspection "
                      "caller: %s.",
                      error.AsCString());
        m_get_thread_item_info_impl_code.reset();
        return args_addr;
      }

    } else {
      get_thread_item_info_caller =
          m_get_thread_item_info_impl_code->GetFunctionCaller();
    }
  }

  diagnostics.Clear();

  // Now write down the argument values for this particular call.  This looks
  // like it might be a race condition
  // if other threads were calling into here, but actually it isn't because we
  // allocate a new args structure for
  // this call by passing args_addr = LLDB_INVALID_ADDRESS...

  if (!get_thread_item_info_caller->WriteFunctionArguments(
          exe_ctx, args_addr, get_thread_item_info_arglist, diagnostics)) {
    if (log) {
      log->Printf("Error writing get-thread-item-info function arguments");
      diagnostics.Dump(log);
    }
    return args_addr;
  }

  return args_addr;
}

AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo
AppleGetThreadItemInfoHandler::GetThreadItemInfo(Thread &thread,
                                                 tid_t thread_id,
                                                 addr_t page_to_free,
                                                 uint64_t page_to_free_size,
                                                 Status &error) {
  lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
  ProcessSP process_sp(thread.CalculateProcess());
  TargetSP target_sp(thread.CalculateTarget());
  ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYSTEM_RUNTIME));

  GetThreadItemInfoReturnInfo return_value;
  return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
  return_value.item_buffer_size = 0;

  error.Clear();

  if (thread.SafeToCallFunctions() == false) {
    if (log)
      log->Printf("Not safe to call functions on thread 0x%" PRIx64,
                  thread.GetID());
    error.SetErrorString("Not safe to call functions on this thread.");
    return return_value;
  }

  // Set up the arguments for a call to

  // struct get_thread_item_info_return_values
  // {
  //     uint64_t item_info_buffer_ptr;    /* the address of the items buffer
  //     from libBacktraceRecording */
  //     uint64_t item_info_buffer_size;   /* the size of the items buffer from
  //     libBacktraceRecording */
  // };
  //
  // void  __lldb_backtrace_recording_get_thread_item_info
  //                                            (struct
  //                                            get_thread_item_info_return_values
  //                                            *return_buffer,
  //                                             int debug,
  //                                             void *page_to_free,
  //                                             uint64_t page_to_free_size)

  // Where the return_buffer argument points to a 24 byte region of memory
  // already allocated by lldb in
  // the inferior process.

  CompilerType clang_void_ptr_type =
      clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
  Value return_buffer_ptr_value;
  return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
  return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);

  CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
  Value debug_value;
  debug_value.SetValueType(Value::eValueTypeScalar);
  debug_value.SetCompilerType(clang_int_type);

  CompilerType clang_uint64_type =
      clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
  Value thread_id_value;
  thread_id_value.SetValueType(Value::eValueTypeScalar);
  thread_id_value.SetCompilerType(clang_uint64_type);

  Value page_to_free_value;
  page_to_free_value.SetValueType(Value::eValueTypeScalar);
  page_to_free_value.SetCompilerType(clang_void_ptr_type);

  Value page_to_free_size_value;
  page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
  page_to_free_size_value.SetCompilerType(clang_uint64_type);

  std::lock_guard<std::mutex> guard(m_get_thread_item_info_retbuffer_mutex);
  if (m_get_thread_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS) {
    addr_t bufaddr = process_sp->AllocateMemory(
        32, ePermissionsReadable | ePermissionsWritable, error);
    if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS) {
      if (log)
        log->Printf("Failed to allocate memory for return buffer for get "
                    "current queues func call");
      return return_value;
    }
    m_get_thread_item_info_return_buffer_addr = bufaddr;
  }

  ValueList argument_values;

  return_buffer_ptr_value.GetScalar() =
      m_get_thread_item_info_return_buffer_addr;
  argument_values.PushValue(return_buffer_ptr_value);

  debug_value.GetScalar() = 0;
  argument_values.PushValue(debug_value);

  thread_id_value.GetScalar() = thread_id;
  argument_values.PushValue(thread_id_value);

  if (page_to_free != LLDB_INVALID_ADDRESS)
    page_to_free_value.GetScalar() = page_to_free;
  else
    page_to_free_value.GetScalar() = 0;
  argument_values.PushValue(page_to_free_value);

  page_to_free_size_value.GetScalar() = page_to_free_size;
  argument_values.PushValue(page_to_free_size_value);

  addr_t args_addr = SetupGetThreadItemInfoFunction(thread, argument_values);

  DiagnosticManager diagnostics;
  ExecutionContext exe_ctx;
  EvaluateExpressionOptions options;
  FunctionCaller *get_thread_item_info_caller = nullptr;

  options.SetUnwindOnError(true);
  options.SetIgnoreBreakpoints(true);
  options.SetStopOthers(true);
  options.SetTimeout(std::chrono::milliseconds(500));
  options.SetTryAllThreads(false);
  thread.CalculateExecutionContext(exe_ctx);

  if (!m_get_thread_item_info_impl_code) {
    error.SetErrorString("Unable to compile function to call "
                         "__introspection_dispatch_thread_get_item_info");
    return return_value;
  }

  get_thread_item_info_caller =
      m_get_thread_item_info_impl_code->GetFunctionCaller();

  if (!get_thread_item_info_caller) {
    error.SetErrorString("Unable to compile function caller for "
                         "__introspection_dispatch_thread_get_item_info");
    return return_value;
  }

  ExpressionResults func_call_ret;
  Value results;
  func_call_ret = get_thread_item_info_caller->ExecuteFunction(
      exe_ctx, &args_addr, options, diagnostics, results);
  if (func_call_ret != eExpressionCompleted || !error.Success()) {
    if (log)
      log->Printf("Unable to call "
                  "__introspection_dispatch_thread_get_item_info(), got "
                  "ExpressionResults %d, error contains %s",
                  func_call_ret, error.AsCString(""));
    error.SetErrorString("Unable to call "
                         "__introspection_dispatch_thread_get_item_info() for "
                         "list of queues");
    return return_value;
  }

  return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory(
      m_get_thread_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS,
      error);
  if (!error.Success() ||
      return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS) {
    return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
    return return_value;
  }

  return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory(
      m_get_thread_item_info_return_buffer_addr + 8, 8, 0, error);

  if (!error.Success()) {
    return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
    return return_value;
  }

  if (log)
    log->Printf("AppleGetThreadItemInfoHandler called "
                "__introspection_dispatch_thread_get_item_info (page_to_free "
                "== 0x%" PRIx64 ", size = %" PRId64
                "), returned page is at 0x%" PRIx64 ", size %" PRId64,
                page_to_free, page_to_free_size, return_value.item_buffer_ptr,
                return_value.item_buffer_size);

  return return_value;
}
