//===-- DynamicLoaderWindowsDYLD.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 "DynamicLoaderWindowsDYLD.h"

#include "MSVCRTCFrameRecognizer.h"
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlanStepInstruction.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#include "llvm/TargetParser/Triple.h"

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(DynamicLoaderWindowsDYLD)

DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process)
    : DynamicLoader(process) {}

DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() = default;

void DynamicLoaderWindowsDYLD::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(), CreateInstance);
}

void DynamicLoaderWindowsDYLD::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

llvm::StringRef DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() {
  return "Dynamic loader plug-in that watches for shared library "
         "loads/unloads in Windows processes.";
}

DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process,
                                                        bool force) {
  bool should_create = force;
  if (!should_create) {
    const llvm::Triple &triple_ref =
        process->GetTarget().GetArchitecture().GetTriple();
    if (triple_ref.getOS() == llvm::Triple::Win32)
      should_create = true;
  }

  if (should_create)
    return new DynamicLoaderWindowsDYLD(process);

  return nullptr;
}

void DynamicLoaderWindowsDYLD::OnLoadModule(lldb::ModuleSP module_sp,
                                            const ModuleSpec module_spec,
                                            lldb::addr_t module_addr) {
  // Resolve the module unless we already have one.
  if (!module_sp) {
    Status error;
    module_sp = m_process->GetTarget().GetOrCreateModule(
        module_spec, true /* notify */, &error);
    if (error.Fail())
      return;
  }

  m_loaded_modules.insert({module_addr, lldb::ModuleWP(module_sp)});
  UpdateLoadedSectionsCommon(module_sp, module_addr, false);
  ModuleList module_list;
  module_list.Append(module_sp);
  m_process->GetTarget().ModulesDidLoad(module_list);
}

void DynamicLoaderWindowsDYLD::OnUnloadModule(lldb::addr_t module_addr) {
  auto it = m_loaded_modules.find(module_addr);
  if (it == m_loaded_modules.end())
    return;

  ModuleSP module_sp = it->second.lock();
  m_loaded_modules.erase(it);

  if (!module_sp)
    return;

  bool full_unload = true;
  for (const auto &entry : m_loaded_modules) {
    ModuleSP other_sp = entry.second.lock();
    if (other_sp == module_sp) {
      UpdateLoadedSectionsCommon(module_sp, entry.first, false);
      full_unload = false;
    }
  }

  if (full_unload) {
    UnloadSectionsCommon(module_sp);
    ModuleList module_list;
    module_list.Append(module_sp);
    m_process->GetTarget().ModulesDidUnload(module_list, false);
  }
}

lldb::addr_t DynamicLoaderWindowsDYLD::GetLoadAddress(ModuleSP executable) {
  // First, see if the load address is already cached.
  for (const auto &entry : m_loaded_modules) {
    ModuleSP mod = entry.second.lock();
    if (mod == executable && entry.first != LLDB_INVALID_ADDRESS)
      return entry.first;
  }

  lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;

  // Second, try to get it through the process plugins.  For a remote process,
  // the remote platform will be responsible for providing it.
  FileSpec file_spec(executable->GetPlatformFileSpec());
  bool is_loaded = false;
  Status status =
      m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr);
  // Servers other than lldb server could respond with a bogus address.
  if (status.Success() && is_loaded && load_addr != LLDB_INVALID_ADDRESS) {
    m_loaded_modules.insert({load_addr, lldb::ModuleWP(executable)});
    return load_addr;
  }

  return LLDB_INVALID_ADDRESS;
}

void DynamicLoaderWindowsDYLD::DidAttach() {
  Log *log = GetLog(LLDBLog::DynamicLoader);
  LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);

  RegisterMSVCRTCFrameRecognizer(m_process->GetTarget());

  ModuleSP executable = GetTargetExecutable();

  if (!executable)
    return;

  // Try to fetch the load address of the file from the process, since there
  // could be randomization of the load address.
  lldb::addr_t load_addr = GetLoadAddress(executable);
  if (load_addr == LLDB_INVALID_ADDRESS) {
    // The process does not know the executable under the target's path: it
    // was started through another path to the same file, or runs a different
    // one. Take the modules it reports as loaded, which replaces the target's
    // executable with the process's.
    auto error = m_process->LoadModules();
    if (!error)
      return;
    LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}");

    // If the load address couldn't be determined (e.g. for a remote gdbstub
    // target), fall back to the preferred load address/image base from the
    // file if the process is live.
    // This is a best-effort guess, if the image isn't loaded there the
    // sections will have incorrect addresses and the slide will have to be
    // specified manually.
    if (!m_process->IsLiveDebugSession())
      return;

    ObjectFile *object_file = executable->GetObjectFile();
    if (!object_file)
      return;

    load_addr = object_file->GetBaseAddress().GetFileAddress();
    if (load_addr == LLDB_INVALID_ADDRESS)
      return;

    executable->ReportWarning(
        "failed to get load address, assuming image base at {0:x}", load_addr);
  } else {
    // Request the process base address.
    lldb::addr_t image_base = m_process->GetImageInfoAddress();
    if (image_base == load_addr)
      return;
  }

  // Rebase the process's modules if there is a mismatch.
  UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);

  ModuleList module_list;
  module_list.Append(executable);
  m_process->GetTarget().ModulesDidLoad(module_list);
  auto error = m_process->LoadModules();
  LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}");
}

void DynamicLoaderWindowsDYLD::DidLaunch() {
  Log *log = GetLog(LLDBLog::DynamicLoader);
  LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);

  RegisterMSVCRTCFrameRecognizer(m_process->GetTarget());

  ModuleSP executable = GetTargetExecutable();
  if (!executable)
    return;

  lldb::addr_t load_addr = GetLoadAddress(executable);
  if (load_addr != LLDB_INVALID_ADDRESS) {
    // Update the loaded sections so that the breakpoints can be resolved.
    UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);

    ModuleList module_list;
    module_list.Append(executable);
    m_process->GetTarget().ModulesDidLoad(module_list);
    auto error = m_process->LoadModules();
    LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}");
  }
}

Status DynamicLoaderWindowsDYLD::CanLoadImage() { return Status(); }

ThreadPlanSP
DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
                                                       bool stop) {
  auto arch = m_process->GetTarget().GetArchitecture();
  if (arch.GetMachine() != llvm::Triple::x86) {
    return ThreadPlanSP();
  }

  RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
  if (!reg_ctx_sp)
    return ThreadPlanSP();

  uint64_t pc = reg_ctx_sp->GetPC();
  // Max size of an instruction in x86 is 15 bytes.
  AddressRange range(pc, 2 * 15);

  DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
      arch, nullptr, nullptr, nullptr, nullptr, m_process->GetTarget(), range);
  if (!disassembler_sp) {
    return ThreadPlanSP();
  }

  InstructionList &insn_list = disassembler_sp->GetInstructionList();

  // First instruction in a x86 Windows trampoline is going to be an indirect
  // jump through the IAT and the next one will be a nop (usually there for
  // alignment purposes). e.g.:
  //     0x70ff4cfc <+956>: jmpl   *0x7100c2a8
  //     0x70ff4d02 <+962>: nop

  auto first_insn = insn_list.GetInstructionAtIndex(0);
  auto second_insn = insn_list.GetInstructionAtIndex(1);

  ExecutionContext exe_ctx(m_process->GetTarget());
  if (first_insn == nullptr || second_insn == nullptr)
    return ThreadPlanSP();

  const char *first_mnemonic = first_insn->GetMnemonic(&exe_ctx);
  const char *second_mnemonic = second_insn->GetMnemonic(&exe_ctx);
  if (!first_mnemonic || !second_mnemonic ||
      strcmp(first_mnemonic, "jmpl") != 0 ||
      strcmp(second_mnemonic, "nop") != 0)
    return ThreadPlanSP();

  assert(first_insn->DoesBranch() && !second_insn->DoesBranch());

  return ThreadPlanSP(new ThreadPlanStepInstruction(
      thread, false, false, eVoteNoOpinion, eVoteNoOpinion));
}

lldb::addr_t
DynamicLoaderWindowsDYLD::GetThreadLocalData(const lldb::ModuleSP module,
                                             lldb::ThreadSP thread,
                                             lldb::addr_t tls_file_addr) {
  Log *log = GetLog(LLDBLog::DynamicLoader);
  ObjectFile *obj = module->GetObjectFile();
  if (!obj) {
    LLDB_LOG(log, "no object file for module");
    return LLDB_INVALID_ADDRESS;
  }
  std::string object_name;
  if (log)
    object_name = obj->GetObjectName();

  StructuredData::ObjectSP extended_info = thread->GetExtendedInfo();
  if (!extended_info) {
    LLDB_LOG(log, "missing extended info of thread");
    return LLDB_INVALID_ADDRESS;
  }
  StructuredData::Dictionary *dict = extended_info->GetAsDictionary();
  if (!dict) {
    LLDB_LOG(log, "extended info of thread is not a dictionary");
    return LLDB_INVALID_ADDRESS;
  }
  addr_t teb_base = 0;
  if (!dict->GetValueForKeyAsInteger("teb_address", teb_base) || !teb_base ||
      teb_base == LLDB_INVALID_ADDRESS) {
    LLDB_LOG(log, "missing 'teb_address' in extended thread info");
    return LLDB_INVALID_ADDRESS;
  }

  ProcessSP process = thread->GetProcess();
  if (!process) {
    LLDB_LOG(log, "missing process");
    return LLDB_INVALID_ADDRESS;
  }
  uint32_t addr_byte_size = process->GetAddressByteSize();
  addr_t tls_array_addr = teb_base + 11 * addr_byte_size;
  llvm::Expected<addr_t> tls_array =
      process->ReadPointerFromMemory(tls_array_addr);
  if (!tls_array || *tls_array == LLDB_INVALID_ADDRESS) {
    LLDB_LOG_ERROR(log, tls_array.takeError(),
                   "failed to read TLS array from {1:x16}: {0}",
                   tls_array_addr);
    return LLDB_INVALID_ADDRESS;
  }

  Address tls_index_addr;
  if (!GetTlsIndexAddressForModule(module, tls_index_addr)) {
    LLDB_LOG(log, "failed to resolve tls index for {0}", object_name);
    return LLDB_INVALID_ADDRESS;
  }

  Target &target = process->GetTarget();
  addr_t tls_index_load_addr = tls_index_addr.GetLoadAddress(&target);
  if (tls_index_load_addr == LLDB_INVALID_ADDRESS) {
    LLDB_LOG(log, "failed to resolve load address of '_tls_index' in {0}",
             object_name);
    return LLDB_INVALID_ADDRESS;
  }

  Status error;
  uint64_t tls_index =
      process->ReadUnsignedIntegerFromMemory(tls_index_load_addr, 4, 0, error);
  if (error.Fail()) {
    LLDB_LOG_ERROR(log, error.takeError(),
                   "failed to read '_tls_index' in {1} from {2:x8}: {0}",
                   object_name, tls_index_load_addr);
    return LLDB_INVALID_ADDRESS;
  }

  addr_t tls_index_item = *tls_array + tls_index * addr_byte_size;
  LLDB_LOG(log, "tls base address for {0} is at {1:x8} + {2:x8} * {3} = {4:x8}",
           object_name, *tls_array, tls_index, addr_byte_size, tls_index_item);

  llvm::Expected<addr_t> tls_base =
      process->ReadPointerFromMemory(tls_index_item);
  if (!tls_base || *tls_base == LLDB_INVALID_ADDRESS || *tls_base == 0) {
    LLDB_LOG_ERROR(log, tls_base.takeError(),
                   "failed to read tls array in {1} at index {2} ({3:x8}): {0}",
                   object_name, tls_index, tls_index_item);
    return LLDB_INVALID_ADDRESS;
  }

  return *tls_base + tls_file_addr;
}

bool DynamicLoaderWindowsDYLD::GetTlsIndexAddressForModule(
    const ModuleSP &module, Address &addr) const {
  ObjectFilePECOFF *obj =
      llvm::dyn_cast_or_null<ObjectFilePECOFF>(module->GetObjectFile());
  if (obj) {
    addr_t tls_index_file_addr = obj->GetTlsIndexAddress();
    if (tls_index_file_addr != LLDB_INVALID_ADDRESS &&
        module->ResolveFileAddress(tls_index_file_addr, addr))
      return true;
  }

  // If we can't get the tls index from the object file, try the _tls_index
  // symbol.
  Symtab *symtab = module->GetSymtab();
  if (!symtab)
    return false;

  Symbol *tls_index_sym = symtab->FindFirstSymbolWithNameAndType(
      ConstString("_tls_index"), eSymbolTypeAny, Symtab::eDebugAny,
      Symtab::eVisibilityAny);
  if (!tls_index_sym)
    return false;

  addr = tls_index_sym->GetAddress();
  return addr.IsValid();
}
