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

#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"

#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"

#include "lldb/../../source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"

using namespace lldb_private;

IRExecutionUnit::IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_ap,
                                 std::unique_ptr<llvm::Module> &module_ap,
                                 ConstString &name,
                                 const lldb::TargetSP &target_sp,
                                 const SymbolContext &sym_ctx,
                                 std::vector<std::string> &cpu_features)
    : IRMemoryMap(target_sp), m_context_ap(context_ap.release()),
      m_module_ap(module_ap.release()), m_module(m_module_ap.get()),
      m_cpu_features(cpu_features), m_name(name), m_sym_ctx(sym_ctx),
      m_did_jit(false), m_function_load_addr(LLDB_INVALID_ADDRESS),
      m_function_end_load_addr(LLDB_INVALID_ADDRESS),
      m_reported_allocations(false) {}

lldb::addr_t IRExecutionUnit::WriteNow(const uint8_t *bytes, size_t size,
                                       Error &error) {
  const bool zero_memory = false;
  lldb::addr_t allocation_process_addr =
      Malloc(size, 8, lldb::ePermissionsWritable | lldb::ePermissionsReadable,
             eAllocationPolicyMirror, zero_memory, error);

  if (!error.Success())
    return LLDB_INVALID_ADDRESS;

  WriteMemory(allocation_process_addr, bytes, size, error);

  if (!error.Success()) {
    Error err;
    Free(allocation_process_addr, err);

    return LLDB_INVALID_ADDRESS;
  }

  if (Log *log =
          lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) {
    DataBufferHeap my_buffer(size, 0);
    Error err;
    ReadMemory(my_buffer.GetBytes(), allocation_process_addr, size, err);

    if (err.Success()) {
      DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(),
                                 lldb::eByteOrderBig, 8);
      my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(),
                            allocation_process_addr, 16,
                            DataExtractor::TypeUInt8);
    }
  }

  return allocation_process_addr;
}

void IRExecutionUnit::FreeNow(lldb::addr_t allocation) {
  if (allocation == LLDB_INVALID_ADDRESS)
    return;

  Error err;

  Free(allocation, err);
}

Error IRExecutionUnit::DisassembleFunction(Stream &stream,
                                           lldb::ProcessSP &process_wp) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  ExecutionContext exe_ctx(process_wp);

  Error ret;

  ret.Clear();

  lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
  lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;

  for (JittedFunction &function : m_jitted_functions) {
    if (function.m_name == m_name) {
      func_local_addr = function.m_local_addr;
      func_remote_addr = function.m_remote_addr;
    }
  }

  if (func_local_addr == LLDB_INVALID_ADDRESS) {
    ret.SetErrorToGenericError();
    ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly",
                                 m_name.AsCString());
    return ret;
  }

  if (log)
    log->Printf("Found function, has local address 0x%" PRIx64
                " and remote address 0x%" PRIx64,
                (uint64_t)func_local_addr, (uint64_t)func_remote_addr);

  std::pair<lldb::addr_t, lldb::addr_t> func_range;

  func_range = GetRemoteRangeForLocal(func_local_addr);

  if (func_range.first == 0 && func_range.second == 0) {
    ret.SetErrorToGenericError();
    ret.SetErrorStringWithFormat("Couldn't find code range for function %s",
                                 m_name.AsCString());
    return ret;
  }

  if (log)
    log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]",
                func_range.first, func_range.second);

  Target *target = exe_ctx.GetTargetPtr();
  if (!target) {
    ret.SetErrorToGenericError();
    ret.SetErrorString("Couldn't find the target");
    return ret;
  }

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));

  Process *process = exe_ctx.GetProcessPtr();
  Error err;
  process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(),
                      buffer_sp->GetByteSize(), err);

  if (!err.Success()) {
    ret.SetErrorToGenericError();
    ret.SetErrorStringWithFormat("Couldn't read from process: %s",
                                 err.AsCString("unknown error"));
    return ret;
  }

  ArchSpec arch(target->GetArchitecture());

  const char *plugin_name = NULL;
  const char *flavor_string = NULL;
  lldb::DisassemblerSP disassembler_sp =
      Disassembler::FindPlugin(arch, flavor_string, plugin_name);

  if (!disassembler_sp) {
    ret.SetErrorToGenericError();
    ret.SetErrorStringWithFormat(
        "Unable to find disassembler plug-in for %s architecture.",
        arch.GetArchitectureName());
    return ret;
  }

  if (!process) {
    ret.SetErrorToGenericError();
    ret.SetErrorString("Couldn't find the process");
    return ret;
  }

  DataExtractor extractor(buffer_sp, process->GetByteOrder(),
                          target->GetArchitecture().GetAddressByteSize());

  if (log) {
    log->Printf("Function data has contents:");
    extractor.PutToLog(log, 0, extractor.GetByteSize(), func_remote_addr, 16,
                       DataExtractor::TypeUInt8);
  }

  disassembler_sp->DecodeInstructions(Address(func_remote_addr), extractor, 0,
                                      UINT32_MAX, false, false);

  InstructionList &instruction_list = disassembler_sp->GetInstructionList();
  instruction_list.Dump(&stream, true, true, &exe_ctx);
  return ret;
}

static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic,
                                 void *Context, unsigned LocCookie) {
  Error *err = static_cast<Error *>(Context);

  if (err && err->Success()) {
    err->SetErrorToGenericError();
    err->SetErrorStringWithFormat("Inline assembly error: %s",
                                  diagnostic.getMessage().str().c_str());
  }
}

void IRExecutionUnit::ReportSymbolLookupError(const ConstString &name) {
  m_failed_lookups.push_back(name);
}

void IRExecutionUnit::GetRunnableInfo(Error &error, lldb::addr_t &func_addr,
                                      lldb::addr_t &func_end) {
  lldb::ProcessSP process_sp(GetProcessWP().lock());

  static std::recursive_mutex s_runnable_info_mutex;

  func_addr = LLDB_INVALID_ADDRESS;
  func_end = LLDB_INVALID_ADDRESS;

  if (!process_sp) {
    error.SetErrorToGenericError();
    error.SetErrorString("Couldn't write the JIT compiled code into the "
                         "process because the process is invalid");
    return;
  }

  if (m_did_jit) {
    func_addr = m_function_load_addr;
    func_end = m_function_end_load_addr;

    return;
  };

  std::lock_guard<std::recursive_mutex> guard(s_runnable_info_mutex);

  m_did_jit = true;

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  std::string error_string;

  if (log) {
    std::string s;
    llvm::raw_string_ostream oss(s);

    m_module->print(oss, NULL);

    oss.flush();

    log->Printf("Module being sent to JIT: \n%s", s.c_str());
  }

  llvm::Triple triple(m_module->getTargetTriple());
  llvm::Reloc::Model relocModel;
  llvm::CodeModel::Model codeModel;

  if (triple.isOSBinFormatELF()) {
    relocModel = llvm::Reloc::Static;
  } else {
    relocModel = llvm::Reloc::PIC_;
  }

  // This will be small for 32-bit and large for 64-bit.
  codeModel = llvm::CodeModel::JITDefault;

  m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError,
                                                          &error);

  llvm::EngineBuilder builder(std::move(m_module_ap));

  builder.setEngineKind(llvm::EngineKind::JIT)
      .setErrorStr(&error_string)
      .setRelocationModel(relocModel)
      .setMCJITMemoryManager(
          std::unique_ptr<MemoryManager>(new MemoryManager(*this)))
      .setCodeModel(codeModel)
      .setOptLevel(llvm::CodeGenOpt::Less)
      .setUseOrcMCJITReplacement(true);

  llvm::StringRef mArch;
  llvm::StringRef mCPU;
  llvm::SmallVector<std::string, 0> mAttrs;

  for (std::string &feature : m_cpu_features)
    mAttrs.push_back(feature);

  llvm::TargetMachine *target_machine =
      builder.selectTarget(triple, mArch, mCPU, mAttrs);

  m_execution_engine_ap.reset(builder.create(target_machine));

  m_strip_underscore =
      (m_execution_engine_ap->getDataLayout().getGlobalPrefix() == '_');

  if (!m_execution_engine_ap.get()) {
    error.SetErrorToGenericError();
    error.SetErrorStringWithFormat("Couldn't JIT the function: %s",
                                   error_string.c_str());
    return;
  }

  class ObjectDumper : public llvm::ObjectCache {
  public:
    void notifyObjectCompiled(const llvm::Module *module,
                              llvm::MemoryBufferRef object) override {
      int fd = 0;
      llvm::SmallVector<char, 256> result_path;
      std::string object_name_model =
          "jit-object-" + module->getModuleIdentifier() + "-%%%.o";
      (void)llvm::sys::fs::createUniqueFile(object_name_model, fd, result_path);
      llvm::raw_fd_ostream fds(fd, true);
      fds.write(object.getBufferStart(), object.getBufferSize());
    }

    std::unique_ptr<llvm::MemoryBuffer>
    getObject(const llvm::Module *module) override {
      // Return nothing - we're just abusing the object-cache mechanism to dump
      // objects.
      return nullptr;
    }
  };

  if (process_sp->GetTarget().GetEnableSaveObjects()) {
    m_object_cache_ap = llvm::make_unique<ObjectDumper>();
    m_execution_engine_ap->setObjectCache(m_object_cache_ap.get());
  }

  // Make sure we see all sections, including ones that don't have
  // relocations...
  m_execution_engine_ap->setProcessAllSections(true);

  m_execution_engine_ap->DisableLazyCompilation();

  for (llvm::Function &function : *m_module) {
    if (function.isDeclaration() || function.hasPrivateLinkage())
      continue;

    const bool external =
        function.hasExternalLinkage() || function.hasLinkOnceODRLinkage();

    void *fun_ptr = m_execution_engine_ap->getPointerToFunction(&function);

    if (!error.Success()) {
      // We got an error through our callback!
      return;
    }

    if (!fun_ptr) {
      error.SetErrorToGenericError();
      error.SetErrorStringWithFormat(
          "'%s' was in the JITted module but wasn't lowered",
          function.getName().str().c_str());
      return;
    }
    m_jitted_functions.push_back(JittedFunction(
        function.getName().str().c_str(), external, (lldb::addr_t)fun_ptr));
  }

  CommitAllocations(process_sp);
  ReportAllocations(*m_execution_engine_ap);

  // We have to do this after calling ReportAllocations because for the MCJIT,
  // getGlobalValueAddress
  // will cause the JIT to perform all relocations.  That can only be done once,
  // and has to happen
  // after we do the remapping from local -> remote.
  // That means we don't know the local address of the Variables, but we don't
  // need that for anything,
  // so that's okay.

  std::function<void(llvm::GlobalValue &)> RegisterOneValue = [this](
      llvm::GlobalValue &val) {
    if (val.hasExternalLinkage() && !val.isDeclaration()) {
      uint64_t var_ptr_addr =
          m_execution_engine_ap->getGlobalValueAddress(val.getName().str());

      lldb::addr_t remote_addr = GetRemoteAddressForLocal(var_ptr_addr);

      // This is a really unfortunae API that sometimes returns local addresses
      // and sometimes returns remote addresses, based on whether
      // the variable was relocated during ReportAllocations or not.

      if (remote_addr == LLDB_INVALID_ADDRESS) {
        remote_addr = var_ptr_addr;
      }

      if (var_ptr_addr != 0)
        m_jitted_global_variables.push_back(JittedGlobalVariable(
            val.getName().str().c_str(), LLDB_INVALID_ADDRESS, remote_addr));
    }
  };

  for (llvm::GlobalVariable &global_var : m_module->getGlobalList()) {
    RegisterOneValue(global_var);
  }

  for (llvm::GlobalAlias &global_alias : m_module->getAliasList()) {
    RegisterOneValue(global_alias);
  }

  WriteData(process_sp);

  if (m_failed_lookups.size()) {
    StreamString ss;

    ss.PutCString("Couldn't lookup symbols:\n");

    bool emitNewLine = false;

    for (const ConstString &failed_lookup : m_failed_lookups) {
      if (emitNewLine)
        ss.PutCString("\n");
      emitNewLine = true;
      ss.PutCString("  ");
      ss.PutCString(Mangled(failed_lookup)
                        .GetDemangledName(lldb::eLanguageTypeObjC_plus_plus)
                        .AsCString());
    }

    m_failed_lookups.clear();

    error.SetErrorString(ss.GetString());

    return;
  }

  m_function_load_addr = LLDB_INVALID_ADDRESS;
  m_function_end_load_addr = LLDB_INVALID_ADDRESS;

  for (JittedFunction &jitted_function : m_jitted_functions) {
    jitted_function.m_remote_addr =
        GetRemoteAddressForLocal(jitted_function.m_local_addr);

    if (!m_name.IsEmpty() && jitted_function.m_name == m_name) {
      AddrRange func_range =
          GetRemoteRangeForLocal(jitted_function.m_local_addr);
      m_function_end_load_addr = func_range.first + func_range.second;
      m_function_load_addr = jitted_function.m_remote_addr;
    }
  }

  if (log) {
    log->Printf("Code can be run in the target.");

    StreamString disassembly_stream;

    Error err = DisassembleFunction(disassembly_stream, process_sp);

    if (!err.Success()) {
      log->Printf("Couldn't disassemble function : %s",
                  err.AsCString("unknown error"));
    } else {
      log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
    }

    log->Printf("Sections: ");
    for (AllocationRecord &record : m_records) {
      if (record.m_process_address != LLDB_INVALID_ADDRESS) {
        record.dump(log);

        DataBufferHeap my_buffer(record.m_size, 0);
        Error err;
        ReadMemory(my_buffer.GetBytes(), record.m_process_address,
                   record.m_size, err);

        if (err.Success()) {
          DataExtractor my_extractor(my_buffer.GetBytes(),
                                     my_buffer.GetByteSize(),
                                     lldb::eByteOrderBig, 8);
          my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(),
                                record.m_process_address, 16,
                                DataExtractor::TypeUInt8);
        }
      } else {
        record.dump(log);

        DataExtractor my_extractor((const void *)record.m_host_address,
                                   record.m_size, lldb::eByteOrderBig, 8);
        my_extractor.PutToLog(log, 0, record.m_size, record.m_host_address, 16,
                              DataExtractor::TypeUInt8);
      }
    }
  }

  func_addr = m_function_load_addr;
  func_end = m_function_end_load_addr;

  return;
}

IRExecutionUnit::~IRExecutionUnit() {
  m_module_ap.reset();
  m_execution_engine_ap.reset();
  m_context_ap.reset();
}

IRExecutionUnit::MemoryManager::MemoryManager(IRExecutionUnit &parent)
    : m_default_mm_ap(new llvm::SectionMemoryManager()), m_parent(parent) {}

IRExecutionUnit::MemoryManager::~MemoryManager() {}

lldb::SectionType IRExecutionUnit::GetSectionTypeFromSectionName(
    const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind) {
  lldb::SectionType sect_type = lldb::eSectionTypeCode;
  switch (alloc_kind) {
  case AllocationKind::Stub:
    sect_type = lldb::eSectionTypeCode;
    break;
  case AllocationKind::Code:
    sect_type = lldb::eSectionTypeCode;
    break;
  case AllocationKind::Data:
    sect_type = lldb::eSectionTypeData;
    break;
  case AllocationKind::Global:
    sect_type = lldb::eSectionTypeData;
    break;
  case AllocationKind::Bytes:
    sect_type = lldb::eSectionTypeOther;
    break;
  }

  if (!name.empty()) {
    if (name.equals("__text") || name.equals(".text"))
      sect_type = lldb::eSectionTypeCode;
    else if (name.equals("__data") || name.equals(".data"))
      sect_type = lldb::eSectionTypeCode;
    else if (name.startswith("__debug_") || name.startswith(".debug_")) {
      const uint32_t name_idx = name[0] == '_' ? 8 : 7;
      llvm::StringRef dwarf_name(name.substr(name_idx));
      switch (dwarf_name[0]) {
      case 'a':
        if (dwarf_name.equals("abbrev"))
          sect_type = lldb::eSectionTypeDWARFDebugAbbrev;
        else if (dwarf_name.equals("aranges"))
          sect_type = lldb::eSectionTypeDWARFDebugAranges;
        else if (dwarf_name.equals("addr"))
          sect_type = lldb::eSectionTypeDWARFDebugAddr;
        break;

      case 'f':
        if (dwarf_name.equals("frame"))
          sect_type = lldb::eSectionTypeDWARFDebugFrame;
        break;

      case 'i':
        if (dwarf_name.equals("info"))
          sect_type = lldb::eSectionTypeDWARFDebugInfo;
        break;

      case 'l':
        if (dwarf_name.equals("line"))
          sect_type = lldb::eSectionTypeDWARFDebugLine;
        else if (dwarf_name.equals("loc"))
          sect_type = lldb::eSectionTypeDWARFDebugLoc;
        break;

      case 'm':
        if (dwarf_name.equals("macinfo"))
          sect_type = lldb::eSectionTypeDWARFDebugMacInfo;
        break;

      case 'p':
        if (dwarf_name.equals("pubnames"))
          sect_type = lldb::eSectionTypeDWARFDebugPubNames;
        else if (dwarf_name.equals("pubtypes"))
          sect_type = lldb::eSectionTypeDWARFDebugPubTypes;
        break;

      case 's':
        if (dwarf_name.equals("str"))
          sect_type = lldb::eSectionTypeDWARFDebugStr;
        else if (dwarf_name.equals("str_offsets"))
          sect_type = lldb::eSectionTypeDWARFDebugStrOffsets;
        break;

      case 'r':
        if (dwarf_name.equals("ranges"))
          sect_type = lldb::eSectionTypeDWARFDebugRanges;
        break;

      default:
        break;
      }
    } else if (name.startswith("__apple_") || name.startswith(".apple_")) {
#if 0
            const uint32_t name_idx = name[0] == '_' ? 8 : 7;
            llvm::StringRef apple_name(name.substr(name_idx));
            switch (apple_name[0])
            {
                case 'n':
                    if (apple_name.equals("names"))
                        sect_type = lldb::eSectionTypeDWARFAppleNames;
                    else if (apple_name.equals("namespac") || apple_name.equals("namespaces"))
                        sect_type = lldb::eSectionTypeDWARFAppleNamespaces;
                    break;
                case 't':
                    if (apple_name.equals("types"))
                        sect_type = lldb::eSectionTypeDWARFAppleTypes;
                    break;
                case 'o':
                    if (apple_name.equals("objc"))
                        sect_type = lldb::eSectionTypeDWARFAppleObjC;
                    break;
                default:
                    break;
            }
#else
      sect_type = lldb::eSectionTypeInvalid;
#endif
    } else if (name.equals("__objc_imageinfo"))
      sect_type = lldb::eSectionTypeOther;
  }
  return sect_type;
}

uint8_t *IRExecutionUnit::MemoryManager::allocateCodeSection(
    uintptr_t Size, unsigned Alignment, unsigned SectionID,
    llvm::StringRef SectionName) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  uint8_t *return_value = m_default_mm_ap->allocateCodeSection(
      Size, Alignment, SectionID, SectionName);

  m_parent.m_records.push_back(AllocationRecord(
      (uintptr_t)return_value,
      lldb::ePermissionsReadable | lldb::ePermissionsExecutable,
      GetSectionTypeFromSectionName(SectionName, AllocationKind::Code), Size,
      Alignment, SectionID, SectionName.str().c_str()));

  if (log) {
    log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64
                ", Alignment=%u, SectionID=%u) = %p",
                (uint64_t)Size, Alignment, SectionID, (void *)return_value);
  }

  if (m_parent.m_reported_allocations) {
    Error err;
    lldb::ProcessSP process_sp =
        m_parent.GetBestExecutionContextScope()->CalculateProcess();

    m_parent.CommitOneAllocation(process_sp, err, m_parent.m_records.back());
  }

  return return_value;
}

uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection(
    uintptr_t Size, unsigned Alignment, unsigned SectionID,
    llvm::StringRef SectionName, bool IsReadOnly) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  uint8_t *return_value = m_default_mm_ap->allocateDataSection(
      Size, Alignment, SectionID, SectionName, IsReadOnly);

  uint32_t permissions = lldb::ePermissionsReadable;
  if (!IsReadOnly)
    permissions |= lldb::ePermissionsWritable;
  m_parent.m_records.push_back(AllocationRecord(
      (uintptr_t)return_value, permissions,
      GetSectionTypeFromSectionName(SectionName, AllocationKind::Data), Size,
      Alignment, SectionID, SectionName.str().c_str()));
  if (log) {
    log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64
                ", Alignment=%u, SectionID=%u) = %p",
                (uint64_t)Size, Alignment, SectionID, (void *)return_value);
  }

  if (m_parent.m_reported_allocations) {
    Error err;
    lldb::ProcessSP process_sp =
        m_parent.GetBestExecutionContextScope()->CalculateProcess();

    m_parent.CommitOneAllocation(process_sp, err, m_parent.m_records.back());
  }

  return return_value;
}

static ConstString
FindBestAlternateMangledName(const ConstString &demangled,
                             const lldb::LanguageType &lang_type,
                             const SymbolContext &sym_ctx) {
  CPlusPlusLanguage::MethodName cpp_name(demangled);
  std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();

  if (!scope_qualified_name.size())
    return ConstString();

  if (!sym_ctx.module_sp)
    return ConstString();

  SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor();
  if (!sym_vendor)
    return ConstString();

  lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile();
  if (!sym_file)
    return ConstString();

  std::vector<ConstString> alternates;
  sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);

  std::vector<ConstString> param_and_qual_matches;
  std::vector<ConstString> param_matches;
  for (size_t i = 0; i < alternates.size(); i++) {
    ConstString alternate_mangled_name = alternates[i];
    Mangled mangled(alternate_mangled_name, true);
    ConstString demangled = mangled.GetDemangledName(lang_type);

    CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
    if (!cpp_name.IsValid())
      continue;

    if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) {
      if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
        param_and_qual_matches.push_back(alternate_mangled_name);
      else
        param_matches.push_back(alternate_mangled_name);
    }
  }

  if (param_and_qual_matches.size())
    return param_and_qual_matches[0]; // It is assumed that there will be only
                                      // one!
  else if (param_matches.size())
    return param_matches[0]; // Return one of them as a best match
  else
    return ConstString();
}

struct IRExecutionUnit::SearchSpec {
  ConstString name;
  uint32_t mask;

  SearchSpec(ConstString n, uint32_t m = lldb::eFunctionNameTypeFull)
      : name(n), mask(m) {}
};

void IRExecutionUnit::CollectCandidateCNames(
    std::vector<IRExecutionUnit::SearchSpec> &C_specs,
    const ConstString &name) {
  if (m_strip_underscore && name.AsCString()[0] == '_')
    C_specs.insert(C_specs.begin(), ConstString(&name.AsCString()[1]));
  C_specs.push_back(SearchSpec(name));
}

void IRExecutionUnit::CollectCandidateCPlusPlusNames(
    std::vector<IRExecutionUnit::SearchSpec> &CPP_specs,
    const std::vector<SearchSpec> &C_specs, const SymbolContext &sc) {
  for (const SearchSpec &C_spec : C_specs) {
    const ConstString &name = C_spec.name;

    if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) {
      Mangled mangled(name, true);
      ConstString demangled =
          mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus);

      if (demangled) {
        ConstString best_alternate_mangled_name = FindBestAlternateMangledName(
            demangled, lldb::eLanguageTypeC_plus_plus, sc);

        if (best_alternate_mangled_name) {
          CPP_specs.push_back(best_alternate_mangled_name);
        }

        CPP_specs.push_back(SearchSpec(demangled, lldb::eFunctionNameTypeFull));
      }
    }

    std::set<ConstString> alternates;
    CPlusPlusLanguage::FindAlternateFunctionManglings(name, alternates);
    CPP_specs.insert(CPP_specs.end(), alternates.begin(), alternates.end());
  }
}

void IRExecutionUnit::CollectFallbackNames(
    std::vector<SearchSpec> &fallback_specs,
    const std::vector<SearchSpec> &C_specs) {
  // As a last-ditch fallback, try the base name for C++ names.  It's terrible,
  // but the DWARF doesn't always encode "extern C" correctly.

  for (const SearchSpec &C_spec : C_specs) {
    const ConstString &name = C_spec.name;

    if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) {
      Mangled mangled_name(name);
      ConstString demangled_name =
          mangled_name.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
      if (!demangled_name.IsEmpty()) {
        const char *demangled_cstr = demangled_name.AsCString();
        const char *lparen_loc = strchr(demangled_cstr, '(');
        if (lparen_loc) {
          llvm::StringRef base_name(demangled_cstr,
                                    lparen_loc - demangled_cstr);
          fallback_specs.push_back(ConstString(base_name));
        }
      }
    }
  }
}

lldb::addr_t IRExecutionUnit::FindInSymbols(
    const std::vector<IRExecutionUnit::SearchSpec> &specs,
    const lldb_private::SymbolContext &sc) {
  Target *target = sc.target_sp.get();

  if (!target) {
    // we shouldn't be doing any symbol lookup at all without a target
    return LLDB_INVALID_ADDRESS;
  }

  for (const SearchSpec &spec : specs) {
    SymbolContextList sc_list;

    lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS;

    std::function<bool(lldb::addr_t &, SymbolContextList &,
                       const lldb_private::SymbolContext &)>
        get_external_load_address = [&best_internal_load_address, target](
            lldb::addr_t &load_address, SymbolContextList &sc_list,
            const lldb_private::SymbolContext &sc) -> lldb::addr_t {
      load_address = LLDB_INVALID_ADDRESS;

      for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si) {
        SymbolContext candidate_sc;

        sc_list.GetContextAtIndex(si, candidate_sc);

        const bool is_external =
            (candidate_sc.function) ||
            (candidate_sc.symbol && candidate_sc.symbol->IsExternal());
        if (candidate_sc.symbol) {
          load_address = candidate_sc.symbol->ResolveCallableAddress(*target);

          if (load_address == LLDB_INVALID_ADDRESS) {
            if (target->GetProcessSP())
              load_address =
                  candidate_sc.symbol->GetAddress().GetLoadAddress(target);
            else
              load_address = candidate_sc.symbol->GetAddress().GetFileAddress();
          }
        }

        if (load_address == LLDB_INVALID_ADDRESS && candidate_sc.function) {
          if (target->GetProcessSP())
            load_address = candidate_sc.function->GetAddressRange()
                               .GetBaseAddress()
                               .GetLoadAddress(target);
          else
            load_address = candidate_sc.function->GetAddressRange()
                               .GetBaseAddress()
                               .GetFileAddress();
        }

        if (load_address != LLDB_INVALID_ADDRESS) {
          if (is_external) {
            return true;
          } else if (best_internal_load_address == LLDB_INVALID_ADDRESS) {
            best_internal_load_address = load_address;
            load_address = LLDB_INVALID_ADDRESS;
          }
        }
      }

      return false;
    };

    if (sc.module_sp) {
      sc.module_sp->FindFunctions(spec.name, NULL, spec.mask,
                                  true,  // include_symbols
                                  false, // include_inlines
                                  true,  // append
                                  sc_list);
    }

    lldb::addr_t load_address = LLDB_INVALID_ADDRESS;

    if (get_external_load_address(load_address, sc_list, sc)) {
      return load_address;
    } else {
      sc_list.Clear();
    }

    if (sc_list.GetSize() == 0 && sc.target_sp) {
      sc.target_sp->GetImages().FindFunctions(spec.name, spec.mask,
                                              true,  // include_symbols
                                              false, // include_inlines
                                              true,  // append
                                              sc_list);
    }

    if (get_external_load_address(load_address, sc_list, sc)) {
      return load_address;
    } else {
      sc_list.Clear();
    }

    if (sc_list.GetSize() == 0 && sc.target_sp) {
      sc.target_sp->GetImages().FindSymbolsWithNameAndType(
          spec.name, lldb::eSymbolTypeAny, sc_list);
    }

    if (get_external_load_address(load_address, sc_list, sc)) {
      return load_address;
    }
    // if there are any searches we try after this, add an sc_list.Clear() in an
    // "else" clause here

    if (best_internal_load_address != LLDB_INVALID_ADDRESS) {
      return best_internal_load_address;
    }
  }

  return LLDB_INVALID_ADDRESS;
}

lldb::addr_t
IRExecutionUnit::FindInRuntimes(const std::vector<SearchSpec> &specs,
                                const lldb_private::SymbolContext &sc) {
  lldb::TargetSP target_sp = sc.target_sp;

  if (!target_sp) {
    return LLDB_INVALID_ADDRESS;
  }

  lldb::ProcessSP process_sp = sc.target_sp->GetProcessSP();

  if (!process_sp) {
    return LLDB_INVALID_ADDRESS;
  }

  ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();

  if (runtime) {
    for (const SearchSpec &spec : specs) {
      lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(spec.name);

      if (symbol_load_addr != LLDB_INVALID_ADDRESS)
        return symbol_load_addr;
    }
  }

  return LLDB_INVALID_ADDRESS;
}

lldb::addr_t IRExecutionUnit::FindInUserDefinedSymbols(
    const std::vector<SearchSpec> &specs,
    const lldb_private::SymbolContext &sc) {
  lldb::TargetSP target_sp = sc.target_sp;

  for (const SearchSpec &spec : specs) {
    lldb::addr_t symbol_load_addr = target_sp->GetPersistentSymbol(spec.name);

    if (symbol_load_addr != LLDB_INVALID_ADDRESS)
      return symbol_load_addr;
  }

  return LLDB_INVALID_ADDRESS;
}

lldb::addr_t
IRExecutionUnit::FindSymbol(const lldb_private::ConstString &name) {
  std::vector<SearchSpec> candidate_C_names;
  std::vector<SearchSpec> candidate_CPlusPlus_names;

  CollectCandidateCNames(candidate_C_names, name);

  lldb::addr_t ret = FindInSymbols(candidate_C_names, m_sym_ctx);
  if (ret == LLDB_INVALID_ADDRESS)
    ret = FindInRuntimes(candidate_C_names, m_sym_ctx);

  if (ret == LLDB_INVALID_ADDRESS)
    ret = FindInUserDefinedSymbols(candidate_C_names, m_sym_ctx);

  if (ret == LLDB_INVALID_ADDRESS) {
    CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names,
                                   m_sym_ctx);
    ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx);
  }

  if (ret == LLDB_INVALID_ADDRESS) {
    std::vector<SearchSpec> candidate_fallback_names;

    CollectFallbackNames(candidate_fallback_names, candidate_C_names);
    ret = FindInSymbols(candidate_fallback_names, m_sym_ctx);
  }

  return ret;
}

void IRExecutionUnit::GetStaticInitializers(
    std::vector<lldb::addr_t> &static_initializers) {
  if (llvm::GlobalVariable *global_ctors =
          m_module->getNamedGlobal("llvm.global_ctors")) {
    if (llvm::ConstantArray *ctor_array = llvm::dyn_cast<llvm::ConstantArray>(
            global_ctors->getInitializer())) {
      for (llvm::Use &ctor_use : ctor_array->operands()) {
        if (llvm::ConstantStruct *ctor_struct =
                llvm::dyn_cast<llvm::ConstantStruct>(ctor_use)) {
          lldbassert(ctor_struct->getNumOperands() ==
                     3); // this is standardized
          if (llvm::Function *ctor_function =
                  llvm::dyn_cast<llvm::Function>(ctor_struct->getOperand(1))) {
            ConstString ctor_function_name_cs(ctor_function->getName().str());

            for (JittedFunction &jitted_function : m_jitted_functions) {
              if (ctor_function_name_cs == jitted_function.m_name) {
                if (jitted_function.m_remote_addr != LLDB_INVALID_ADDRESS) {
                  static_initializers.push_back(jitted_function.m_remote_addr);
                }
                break;
              }
            }
          }
        }
      }
    }
  }
}

uint64_t
IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  ConstString name_cs(Name.c_str());

  lldb::addr_t ret = m_parent.FindSymbol(name_cs);

  if (ret == LLDB_INVALID_ADDRESS) {
    if (log)
      log->Printf(
          "IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
          Name.c_str());

    m_parent.ReportSymbolLookupError(name_cs);
    return 0xbad0bad0;
  } else {
    if (log)
      log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
                  Name.c_str(), ret);
    return ret;
  }
}

void *IRExecutionUnit::MemoryManager::getPointerToNamedFunction(
    const std::string &Name, bool AbortOnFailure) {
  assert(sizeof(void *) == 8);

  return (void *)getSymbolAddress(Name);
}

lldb::addr_t
IRExecutionUnit::GetRemoteAddressForLocal(lldb::addr_t local_address) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  for (AllocationRecord &record : m_records) {
    if (local_address >= record.m_host_address &&
        local_address < record.m_host_address + record.m_size) {
      if (record.m_process_address == LLDB_INVALID_ADDRESS)
        return LLDB_INVALID_ADDRESS;

      lldb::addr_t ret =
          record.m_process_address + (local_address - record.m_host_address);

      if (log) {
        log->Printf(
            "IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64
            " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64
            " from [0x%" PRIx64 "..0x%" PRIx64 "].",
            local_address, (uint64_t)record.m_host_address,
            (uint64_t)record.m_host_address + (uint64_t)record.m_size, ret,
            record.m_process_address, record.m_process_address + record.m_size);
      }

      return ret;
    }
  }

  return LLDB_INVALID_ADDRESS;
}

IRExecutionUnit::AddrRange
IRExecutionUnit::GetRemoteRangeForLocal(lldb::addr_t local_address) {
  for (AllocationRecord &record : m_records) {
    if (local_address >= record.m_host_address &&
        local_address < record.m_host_address + record.m_size) {
      if (record.m_process_address == LLDB_INVALID_ADDRESS)
        return AddrRange(0, 0);

      return AddrRange(record.m_process_address, record.m_size);
    }
  }

  return AddrRange(0, 0);
}

bool IRExecutionUnit::CommitOneAllocation(lldb::ProcessSP &process_sp,
                                          Error &error,
                                          AllocationRecord &record) {
  if (record.m_process_address != LLDB_INVALID_ADDRESS) {
    return true;
  }

  switch (record.m_sect_type) {
  case lldb::eSectionTypeInvalid:
  case lldb::eSectionTypeDWARFDebugAbbrev:
  case lldb::eSectionTypeDWARFDebugAddr:
  case lldb::eSectionTypeDWARFDebugAranges:
  case lldb::eSectionTypeDWARFDebugFrame:
  case lldb::eSectionTypeDWARFDebugInfo:
  case lldb::eSectionTypeDWARFDebugLine:
  case lldb::eSectionTypeDWARFDebugLoc:
  case lldb::eSectionTypeDWARFDebugMacInfo:
  case lldb::eSectionTypeDWARFDebugPubNames:
  case lldb::eSectionTypeDWARFDebugPubTypes:
  case lldb::eSectionTypeDWARFDebugRanges:
  case lldb::eSectionTypeDWARFDebugStr:
  case lldb::eSectionTypeDWARFDebugStrOffsets:
  case lldb::eSectionTypeDWARFAppleNames:
  case lldb::eSectionTypeDWARFAppleTypes:
  case lldb::eSectionTypeDWARFAppleNamespaces:
  case lldb::eSectionTypeDWARFAppleObjC:
    error.Clear();
    break;
  default:
    const bool zero_memory = false;
    record.m_process_address =
        Malloc(record.m_size, record.m_alignment, record.m_permissions,
               eAllocationPolicyProcessOnly, zero_memory, error);
    break;
  }

  return error.Success();
}

bool IRExecutionUnit::CommitAllocations(lldb::ProcessSP &process_sp) {
  bool ret = true;

  lldb_private::Error err;

  for (AllocationRecord &record : m_records) {
    ret = CommitOneAllocation(process_sp, err, record);

    if (!ret) {
      break;
    }
  }

  if (!ret) {
    for (AllocationRecord &record : m_records) {
      if (record.m_process_address != LLDB_INVALID_ADDRESS) {
        Free(record.m_process_address, err);
        record.m_process_address = LLDB_INVALID_ADDRESS;
      }
    }
  }

  return ret;
}

void IRExecutionUnit::ReportAllocations(llvm::ExecutionEngine &engine) {
  m_reported_allocations = true;

  for (AllocationRecord &record : m_records) {
    if (record.m_process_address == LLDB_INVALID_ADDRESS)
      continue;

    if (record.m_section_id == eSectionIDInvalid)
      continue;

    engine.mapSectionAddress((void *)record.m_host_address,
                             record.m_process_address);
  }

  // Trigger re-application of relocations.
  engine.finalizeObject();
}

bool IRExecutionUnit::WriteData(lldb::ProcessSP &process_sp) {
  bool wrote_something = false;
  for (AllocationRecord &record : m_records) {
    if (record.m_process_address != LLDB_INVALID_ADDRESS) {
      lldb_private::Error err;
      WriteMemory(record.m_process_address, (uint8_t *)record.m_host_address,
                  record.m_size, err);
      if (err.Success())
        wrote_something = true;
    }
  }
  return wrote_something;
}

void IRExecutionUnit::AllocationRecord::dump(Log *log) {
  if (!log)
    return;

  log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d, name %s)",
              (unsigned long long)m_host_address, (unsigned long long)m_size,
              (unsigned long long)m_process_address, (unsigned)m_alignment,
              (unsigned)m_section_id, m_name.c_str());
}

lldb::ByteOrder IRExecutionUnit::GetByteOrder() const {
  ExecutionContext exe_ctx(GetBestExecutionContextScope());
  return exe_ctx.GetByteOrder();
}

uint32_t IRExecutionUnit::GetAddressByteSize() const {
  ExecutionContext exe_ctx(GetBestExecutionContextScope());
  return exe_ctx.GetAddressByteSize();
}

void IRExecutionUnit::PopulateSymtab(lldb_private::ObjectFile *obj_file,
                                     lldb_private::Symtab &symtab) {
  // No symbols yet...
}

void IRExecutionUnit::PopulateSectionList(
    lldb_private::ObjectFile *obj_file,
    lldb_private::SectionList &section_list) {
  for (AllocationRecord &record : m_records) {
    if (record.m_size > 0) {
      lldb::SectionSP section_sp(new lldb_private::Section(
          obj_file->GetModule(), obj_file, record.m_section_id,
          ConstString(record.m_name), record.m_sect_type,
          record.m_process_address, record.m_size,
          record.m_host_address, // file_offset (which is the host address for
                                 // the data)
          record.m_size,         // file_size
          0,
          record.m_permissions)); // flags
      section_list.AddSection(section_sp);
    }
  }
}

bool IRExecutionUnit::GetArchitecture(lldb_private::ArchSpec &arch) {
  ExecutionContext exe_ctx(GetBestExecutionContextScope());
  Target *target = exe_ctx.GetTargetPtr();
  if (target)
    arch = target->GetArchitecture();
  else
    arch.Clear();
  return arch.IsValid();
}

lldb::ModuleSP IRExecutionUnit::GetJITModule() {
  ExecutionContext exe_ctx(GetBestExecutionContextScope());
  Target *target = exe_ctx.GetTargetPtr();
  if (target) {
    lldb::ModuleSP jit_module_sp = lldb_private::Module::CreateJITModule(
        std::static_pointer_cast<lldb_private::ObjectFileJITDelegate>(
            shared_from_this()));
    if (jit_module_sp) {
      bool changed = false;
      jit_module_sp->SetLoadAddress(*target, 0, true, changed);
    }
    return jit_module_sp;
  }
  return lldb::ModuleSP();
}
