//===-- InferiorCallPOSIX.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
//
//===----------------------------------------------------------------------===//

#include "InferiorCallPOSIX.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Host/Config.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/ValueObject/ValueObject.h"

#if LLDB_ENABLE_POSIX
#include <sys/mman.h>
#else
// define them
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#endif

using namespace lldb;
using namespace lldb_private;

/// Pick a call target from \p sc_list.  A symbol from an ELF filter/auxiliary
/// library is resolved through its filtee(s) first, falling back to its own
/// definition only if none of them provide it, mirroring what the dynamic
/// linker does.
static Address GetCallableAddress(Target &target,
                                  const SymbolContextList &sc_list) {
  const uint32_t count = sc_list.GetSize();
  for (uint32_t i = 0; i < count; ++i) {
    SymbolContext sc;
    if (!sc_list.GetContextAtIndex(i, sc))
      continue;
    if (sc.symbol) {
      // Pass the containing module so all of its re-exported libraries
      // (e.g. an ELF filter library's filtees) are searched in order.
      if (Symbol *actual =
              sc.symbol->ResolveReExportedSymbol(target, sc.module_sp))
        return actual->GetAddress();
      // A pure re-export placeholder with no filtee providing a definition
      // has no code of its own and isn't callable.
      if (sc.symbol->GetType() == eSymbolTypeReExported)
        continue;
    }
    return sc.GetFunctionOrSymbolAddress();
  }
  return Address();
}

bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
                                    addr_t addr, addr_t length, unsigned prot,
                                    unsigned flags, addr_t fd, addr_t offset) {
  Thread *thread =
      process->GetThreadList().GetExpressionExecutionThread().get();
  if (thread == nullptr)
    return false;

  ModuleFunctionSearchOptions function_options;
  function_options.include_symbols = true;
  function_options.include_inlines = false;

  SymbolContextList sc_list;
  process->GetTarget().GetImages().FindFunctions(
      ConstString("mmap"), eFunctionNameTypeFull, function_options, sc_list);
  const uint32_t count = sc_list.GetSize();
  if (count > 0) {
    EvaluateExpressionOptions options;
    options.SetStopOthers(true);
    options.SetUnwindOnError(true);
    options.SetIgnoreBreakpoints(true);
    options.SetTryAllThreads(true);
    options.SetDebug(false);
    options.SetTimeout(process->GetUtilityExpressionTimeout());
    options.SetTrapExceptions(false);

    addr_t prot_arg;
    if (prot == eMmapProtNone)
      prot_arg = PROT_NONE;
    else {
      prot_arg = 0;
      if (prot & eMmapProtExec)
        prot_arg |= PROT_EXEC;
      if (prot & eMmapProtRead)
        prot_arg |= PROT_READ;
      if (prot & eMmapProtWrite)
        prot_arg |= PROT_WRITE;
    }

    Address mmap_addr = GetCallableAddress(process->GetTarget(), sc_list);
    if (mmap_addr.IsValid()) {
      auto type_system_or_err =
          process->GetTarget().GetScratchTypeSystemForLanguage(eLanguageTypeC);
      if (!type_system_or_err) {
        llvm::consumeError(type_system_or_err.takeError());
        return false;
      }
      auto ts = *type_system_or_err;
      if (!ts)
        return false;
      CompilerType void_ptr_type =
          ts->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
      const ArchSpec arch = process->GetTarget().GetArchitecture();
      MmapArgList args =
          process->GetTarget().GetPlatform()->GetMmapArgumentList(
              arch, addr, length, prot_arg, flags, fd, offset);
      lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
          *thread, mmap_addr, void_ptr_type, args, options));
      if (call_plan_sp) {
        DiagnosticManager diagnostics;

        StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
        if (frame) {
          ExecutionContext exe_ctx;
          frame->CalculateExecutionContext(exe_ctx);
          ExpressionResults result = process->RunThreadPlan(
              exe_ctx, call_plan_sp, options, diagnostics);
          if (result == eExpressionCompleted) {

            allocated_addr =
                call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
                    LLDB_INVALID_ADDRESS);
            if (process->GetAddressByteSize() == 4) {
              if (allocated_addr == UINT32_MAX)
                return false;
            } else if (process->GetAddressByteSize() == 8) {
              if (allocated_addr == UINT64_MAX)
                return false;
            }
            return true;
          }
        }
      }
    }
  }

  return false;
}

bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
                                      addr_t length) {
  Thread *thread =
      process->GetThreadList().GetExpressionExecutionThread().get();
  if (thread == nullptr)
    return false;

  ModuleFunctionSearchOptions function_options;
  function_options.include_symbols = true;
  function_options.include_inlines = false;

  SymbolContextList sc_list;
  process->GetTarget().GetImages().FindFunctions(
      ConstString("munmap"), eFunctionNameTypeFull, function_options, sc_list);
  const uint32_t count = sc_list.GetSize();
  if (count > 0) {
    EvaluateExpressionOptions options;
    options.SetStopOthers(true);
    options.SetUnwindOnError(true);
    options.SetIgnoreBreakpoints(true);
    options.SetTryAllThreads(true);
    options.SetDebug(false);
    options.SetTimeout(process->GetUtilityExpressionTimeout());
    options.SetTrapExceptions(false);

    Address munmap_addr = GetCallableAddress(process->GetTarget(), sc_list);
    if (munmap_addr.IsValid()) {
      lldb::addr_t args[] = {addr, length};
      lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
          *thread, munmap_addr, CompilerType(), args, options));
      if (call_plan_sp) {
        DiagnosticManager diagnostics;

        StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
        if (frame) {
          ExecutionContext exe_ctx;
          frame->CalculateExecutionContext(exe_ctx);
          ExpressionResults result = process->RunThreadPlan(
              exe_ctx, call_plan_sp, options, diagnostics);
          if (result == eExpressionCompleted) {
            return true;
          }
        }
      }
    }
  }

  return false;
}
