//===-- 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/Debugger.h"
#include "lldb/Core/Disassembler.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/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.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,
                                       Status &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()) {
    Status err;
    Free(allocation_process_addr, err);

    return LLDB_INVALID_ADDRESS;
  }

  if (Log *log =
          lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) {
    DataBufferHeap my_buffer(size, 0);
    Status 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;

  Status err;

  Free(allocation, err);
}

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

  ExecutionContext exe_ctx(process_wp);

  Status 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();
  Status 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) {
  Status *err = static_cast<Status *>(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(Status &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;

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

  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)))
      .setOptLevel(llvm::CodeGenOpt::Less);

  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;

    Status 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);
        Status 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) {
    Status 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) {
    Status 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,
                                          Status &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::eSectionTypeDWARFDebugCuIndex:
  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::Status 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::Status 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();
}
