xref: /freebsd-src/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric //===-- IRExecutionUnit.cpp -----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/ExecutionEngine/ExecutionEngine.h"
100b57cec5SDimitry Andric #include "llvm/ExecutionEngine/ObjectCache.h"
110b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
12fe6060f1SDimitry Andric #include "llvm/IR/DiagnosticHandler.h"
13fe6060f1SDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
140b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
150b57cec5SDimitry Andric #include "llvm/IR/Module.h"
160b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
170b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
200b57cec5SDimitry Andric #include "lldb/Core/Disassembler.h"
210b57cec5SDimitry Andric #include "lldb/Core/Module.h"
220b57cec5SDimitry Andric #include "lldb/Core/Section.h"
230b57cec5SDimitry Andric #include "lldb/Expression/IRExecutionUnit.h"
2406c3fb27SDimitry Andric #include "lldb/Expression/ObjectFileJIT.h"
2581ad6265SDimitry Andric #include "lldb/Host/HostInfo.h"
260b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
270b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
280b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
290b57cec5SDimitry Andric #include "lldb/Symbol/SymbolVendor.h"
300b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h"
31349cc55cSDimitry Andric #include "lldb/Target/Language.h"
320b57cec5SDimitry Andric #include "lldb/Target/LanguageRuntime.h"
330b57cec5SDimitry Andric #include "lldb/Target/Target.h"
340b57cec5SDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
350b57cec5SDimitry Andric #include "lldb/Utility/DataExtractor.h"
360b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h"
3781ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
380b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
390b57cec5SDimitry Andric 
40bdd1243dSDimitry Andric #include <optional>
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric using namespace lldb_private;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric IRExecutionUnit::IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_up,
450b57cec5SDimitry Andric                                  std::unique_ptr<llvm::Module> &module_up,
460b57cec5SDimitry Andric                                  ConstString &name,
470b57cec5SDimitry Andric                                  const lldb::TargetSP &target_sp,
480b57cec5SDimitry Andric                                  const SymbolContext &sym_ctx,
490b57cec5SDimitry Andric                                  std::vector<std::string> &cpu_features)
500b57cec5SDimitry Andric     : IRMemoryMap(target_sp), m_context_up(context_up.release()),
510b57cec5SDimitry Andric       m_module_up(module_up.release()), m_module(m_module_up.get()),
520b57cec5SDimitry Andric       m_cpu_features(cpu_features), m_name(name), m_sym_ctx(sym_ctx),
530b57cec5SDimitry Andric       m_did_jit(false), m_function_load_addr(LLDB_INVALID_ADDRESS),
540b57cec5SDimitry Andric       m_function_end_load_addr(LLDB_INVALID_ADDRESS),
550b57cec5SDimitry Andric       m_reported_allocations(false) {}
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric lldb::addr_t IRExecutionUnit::WriteNow(const uint8_t *bytes, size_t size,
580b57cec5SDimitry Andric                                        Status &error) {
590b57cec5SDimitry Andric   const bool zero_memory = false;
600b57cec5SDimitry Andric   lldb::addr_t allocation_process_addr =
610b57cec5SDimitry Andric       Malloc(size, 8, lldb::ePermissionsWritable | lldb::ePermissionsReadable,
620b57cec5SDimitry Andric              eAllocationPolicyMirror, zero_memory, error);
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   if (!error.Success())
650b57cec5SDimitry Andric     return LLDB_INVALID_ADDRESS;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   WriteMemory(allocation_process_addr, bytes, size, error);
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   if (!error.Success()) {
700b57cec5SDimitry Andric     Status err;
710b57cec5SDimitry Andric     Free(allocation_process_addr, err);
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric     return LLDB_INVALID_ADDRESS;
740b57cec5SDimitry Andric   }
750b57cec5SDimitry Andric 
7681ad6265SDimitry Andric   if (Log *log = GetLog(LLDBLog::Expressions)) {
770b57cec5SDimitry Andric     DataBufferHeap my_buffer(size, 0);
780b57cec5SDimitry Andric     Status err;
790b57cec5SDimitry Andric     ReadMemory(my_buffer.GetBytes(), allocation_process_addr, size, err);
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric     if (err.Success()) {
820b57cec5SDimitry Andric       DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(),
830b57cec5SDimitry Andric                                  lldb::eByteOrderBig, 8);
840b57cec5SDimitry Andric       my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(),
850b57cec5SDimitry Andric                             allocation_process_addr, 16,
860b57cec5SDimitry Andric                             DataExtractor::TypeUInt8);
870b57cec5SDimitry Andric     }
880b57cec5SDimitry Andric   }
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   return allocation_process_addr;
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric void IRExecutionUnit::FreeNow(lldb::addr_t allocation) {
940b57cec5SDimitry Andric   if (allocation == LLDB_INVALID_ADDRESS)
950b57cec5SDimitry Andric     return;
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   Status err;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   Free(allocation, err);
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric Status IRExecutionUnit::DisassembleFunction(Stream &stream,
1030b57cec5SDimitry Andric                                             lldb::ProcessSP &process_wp) {
10481ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   ExecutionContext exe_ctx(process_wp);
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   Status ret;
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   ret.Clear();
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
1130b57cec5SDimitry Andric   lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   for (JittedFunction &function : m_jitted_functions) {
1160b57cec5SDimitry Andric     if (function.m_name == m_name) {
1170b57cec5SDimitry Andric       func_local_addr = function.m_local_addr;
1180b57cec5SDimitry Andric       func_remote_addr = function.m_remote_addr;
1190b57cec5SDimitry Andric     }
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   if (func_local_addr == LLDB_INVALID_ADDRESS) {
1230b57cec5SDimitry Andric     ret.SetErrorToGenericError();
1240b57cec5SDimitry Andric     ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly",
1250b57cec5SDimitry Andric                                  m_name.AsCString());
1260b57cec5SDimitry Andric     return ret;
1270b57cec5SDimitry Andric   }
1280b57cec5SDimitry Andric 
1299dba64beSDimitry Andric   LLDB_LOGF(log,
1309dba64beSDimitry Andric             "Found function, has local address 0x%" PRIx64
1310b57cec5SDimitry Andric             " and remote address 0x%" PRIx64,
1320b57cec5SDimitry Andric             (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   std::pair<lldb::addr_t, lldb::addr_t> func_range;
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   func_range = GetRemoteRangeForLocal(func_local_addr);
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   if (func_range.first == 0 && func_range.second == 0) {
1390b57cec5SDimitry Andric     ret.SetErrorToGenericError();
1400b57cec5SDimitry Andric     ret.SetErrorStringWithFormat("Couldn't find code range for function %s",
1410b57cec5SDimitry Andric                                  m_name.AsCString());
1420b57cec5SDimitry Andric     return ret;
1430b57cec5SDimitry Andric   }
1440b57cec5SDimitry Andric 
1459dba64beSDimitry Andric   LLDB_LOGF(log, "Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]",
1460b57cec5SDimitry Andric             func_range.first, func_range.second);
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1490b57cec5SDimitry Andric   if (!target) {
1500b57cec5SDimitry Andric     ret.SetErrorToGenericError();
1510b57cec5SDimitry Andric     ret.SetErrorString("Couldn't find the target");
1520b57cec5SDimitry Andric     return ret;
1530b57cec5SDimitry Andric   }
1540b57cec5SDimitry Andric 
15581ad6265SDimitry Andric   lldb::WritableDataBufferSP buffer_sp(
15681ad6265SDimitry Andric       new DataBufferHeap(func_range.second, 0));
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
1590b57cec5SDimitry Andric   Status err;
1600b57cec5SDimitry Andric   process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(),
1610b57cec5SDimitry Andric                       buffer_sp->GetByteSize(), err);
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   if (!err.Success()) {
1640b57cec5SDimitry Andric     ret.SetErrorToGenericError();
1650b57cec5SDimitry Andric     ret.SetErrorStringWithFormat("Couldn't read from process: %s",
1660b57cec5SDimitry Andric                                  err.AsCString("unknown error"));
1670b57cec5SDimitry Andric     return ret;
1680b57cec5SDimitry Andric   }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   ArchSpec arch(target->GetArchitecture());
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   const char *plugin_name = nullptr;
1730b57cec5SDimitry Andric   const char *flavor_string = nullptr;
1740b57cec5SDimitry Andric   lldb::DisassemblerSP disassembler_sp =
1750b57cec5SDimitry Andric       Disassembler::FindPlugin(arch, flavor_string, plugin_name);
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric   if (!disassembler_sp) {
1780b57cec5SDimitry Andric     ret.SetErrorToGenericError();
1790b57cec5SDimitry Andric     ret.SetErrorStringWithFormat(
1800b57cec5SDimitry Andric         "Unable to find disassembler plug-in for %s architecture.",
1810b57cec5SDimitry Andric         arch.GetArchitectureName());
1820b57cec5SDimitry Andric     return ret;
1830b57cec5SDimitry Andric   }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   if (!process) {
1860b57cec5SDimitry Andric     ret.SetErrorToGenericError();
1870b57cec5SDimitry Andric     ret.SetErrorString("Couldn't find the process");
1880b57cec5SDimitry Andric     return ret;
1890b57cec5SDimitry Andric   }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   DataExtractor extractor(buffer_sp, process->GetByteOrder(),
1920b57cec5SDimitry Andric                           target->GetArchitecture().GetAddressByteSize());
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric   if (log) {
1959dba64beSDimitry Andric     LLDB_LOGF(log, "Function data has contents:");
1960b57cec5SDimitry Andric     extractor.PutToLog(log, 0, extractor.GetByteSize(), func_remote_addr, 16,
1970b57cec5SDimitry Andric                        DataExtractor::TypeUInt8);
1980b57cec5SDimitry Andric   }
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric   disassembler_sp->DecodeInstructions(Address(func_remote_addr), extractor, 0,
2010b57cec5SDimitry Andric                                       UINT32_MAX, false, false);
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   InstructionList &instruction_list = disassembler_sp->GetInstructionList();
204*0fca6ea1SDimitry Andric   instruction_list.Dump(&stream, true, true, /*show_control_flow_kind=*/false,
205753f127fSDimitry Andric                         &exe_ctx);
206753f127fSDimitry Andric 
2070b57cec5SDimitry Andric   return ret;
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric 
210fe6060f1SDimitry Andric namespace {
211fe6060f1SDimitry Andric struct IRExecDiagnosticHandler : public llvm::DiagnosticHandler {
212fe6060f1SDimitry Andric   Status *err;
213fe6060f1SDimitry Andric   IRExecDiagnosticHandler(Status *err) : err(err) {}
214fe6060f1SDimitry Andric   bool handleDiagnostics(const llvm::DiagnosticInfo &DI) override {
215*0fca6ea1SDimitry Andric     if (DI.getSeverity() == llvm::DS_Error) {
216fe6060f1SDimitry Andric       const auto &DISM = llvm::cast<llvm::DiagnosticInfoSrcMgr>(DI);
2170b57cec5SDimitry Andric       if (err && err->Success()) {
2180b57cec5SDimitry Andric         err->SetErrorToGenericError();
219fe6060f1SDimitry Andric         err->SetErrorStringWithFormat(
220*0fca6ea1SDimitry Andric             "IRExecution error: %s",
221fe6060f1SDimitry Andric             DISM.getSMDiag().getMessage().str().c_str());
2220b57cec5SDimitry Andric       }
2230b57cec5SDimitry Andric     }
2240b57cec5SDimitry Andric 
225*0fca6ea1SDimitry Andric     return true;
226fe6060f1SDimitry Andric   }
227fe6060f1SDimitry Andric };
228fe6060f1SDimitry Andric } // namespace
229fe6060f1SDimitry Andric 
2300b57cec5SDimitry Andric void IRExecutionUnit::ReportSymbolLookupError(ConstString name) {
2310b57cec5SDimitry Andric   m_failed_lookups.push_back(name);
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
2350b57cec5SDimitry Andric                                       lldb::addr_t &func_end) {
2360b57cec5SDimitry Andric   lldb::ProcessSP process_sp(GetProcessWP().lock());
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric   static std::recursive_mutex s_runnable_info_mutex;
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   func_addr = LLDB_INVALID_ADDRESS;
2410b57cec5SDimitry Andric   func_end = LLDB_INVALID_ADDRESS;
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   if (!process_sp) {
2440b57cec5SDimitry Andric     error.SetErrorToGenericError();
2450b57cec5SDimitry Andric     error.SetErrorString("Couldn't write the JIT compiled code into the "
2460b57cec5SDimitry Andric                          "process because the process is invalid");
2470b57cec5SDimitry Andric     return;
2480b57cec5SDimitry Andric   }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric   if (m_did_jit) {
2510b57cec5SDimitry Andric     func_addr = m_function_load_addr;
2520b57cec5SDimitry Andric     func_end = m_function_end_load_addr;
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric     return;
2550b57cec5SDimitry Andric   };
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(s_runnable_info_mutex);
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   m_did_jit = true;
2600b57cec5SDimitry Andric 
26181ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric   std::string error_string;
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   if (log) {
2660b57cec5SDimitry Andric     std::string s;
2670b57cec5SDimitry Andric     llvm::raw_string_ostream oss(s);
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric     m_module->print(oss, nullptr);
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric     oss.flush();
2720b57cec5SDimitry Andric 
2739dba64beSDimitry Andric     LLDB_LOGF(log, "Module being sent to JIT: \n%s", s.c_str());
2740b57cec5SDimitry Andric   }
2750b57cec5SDimitry Andric 
276fe6060f1SDimitry Andric   m_module_up->getContext().setDiagnosticHandler(
277fe6060f1SDimitry Andric       std::make_unique<IRExecDiagnosticHandler>(&error));
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   llvm::EngineBuilder builder(std::move(m_module_up));
2800b57cec5SDimitry Andric   llvm::Triple triple(m_module->getTargetTriple());
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   builder.setEngineKind(llvm::EngineKind::JIT)
2830b57cec5SDimitry Andric       .setErrorStr(&error_string)
2845ffd83dbSDimitry Andric       .setRelocationModel(triple.isOSBinFormatMachO() ? llvm::Reloc::PIC_
2850b57cec5SDimitry Andric                                                       : llvm::Reloc::Static)
2865ffd83dbSDimitry Andric       .setMCJITMemoryManager(std::make_unique<MemoryManager>(*this))
2875f757f3fSDimitry Andric       .setOptLevel(llvm::CodeGenOptLevel::Less);
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric   llvm::StringRef mArch;
2900b57cec5SDimitry Andric   llvm::StringRef mCPU;
2910b57cec5SDimitry Andric   llvm::SmallVector<std::string, 0> mAttrs;
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   for (std::string &feature : m_cpu_features)
2940b57cec5SDimitry Andric     mAttrs.push_back(feature);
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   llvm::TargetMachine *target_machine =
2970b57cec5SDimitry Andric       builder.selectTarget(triple, mArch, mCPU, mAttrs);
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   m_execution_engine_up.reset(builder.create(target_machine));
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric   if (!m_execution_engine_up) {
3020b57cec5SDimitry Andric     error.SetErrorToGenericError();
3030b57cec5SDimitry Andric     error.SetErrorStringWithFormat("Couldn't JIT the function: %s",
3040b57cec5SDimitry Andric                                    error_string.c_str());
3050b57cec5SDimitry Andric     return;
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   m_strip_underscore =
3090b57cec5SDimitry Andric       (m_execution_engine_up->getDataLayout().getGlobalPrefix() == '_');
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   class ObjectDumper : public llvm::ObjectCache {
3120b57cec5SDimitry Andric   public:
31381ad6265SDimitry Andric     ObjectDumper(FileSpec output_dir)  : m_out_dir(output_dir) {}
3140b57cec5SDimitry Andric     void notifyObjectCompiled(const llvm::Module *module,
3150b57cec5SDimitry Andric                               llvm::MemoryBufferRef object) override {
3160b57cec5SDimitry Andric       int fd = 0;
3170b57cec5SDimitry Andric       llvm::SmallVector<char, 256> result_path;
3180b57cec5SDimitry Andric       std::string object_name_model =
3190b57cec5SDimitry Andric           "jit-object-" + module->getModuleIdentifier() + "-%%%.o";
32081ad6265SDimitry Andric       FileSpec model_spec
32181ad6265SDimitry Andric           = m_out_dir.CopyByAppendingPathComponent(object_name_model);
32281ad6265SDimitry Andric       std::string model_path = model_spec.GetPath();
32381ad6265SDimitry Andric 
32481ad6265SDimitry Andric       std::error_code result
32581ad6265SDimitry Andric         = llvm::sys::fs::createUniqueFile(model_path, fd, result_path);
32681ad6265SDimitry Andric       if (!result) {
3270b57cec5SDimitry Andric           llvm::raw_fd_ostream fds(fd, true);
3280b57cec5SDimitry Andric           fds.write(object.getBufferStart(), object.getBufferSize());
3290b57cec5SDimitry Andric       }
33081ad6265SDimitry Andric     }
3310b57cec5SDimitry Andric     std::unique_ptr<llvm::MemoryBuffer>
3320b57cec5SDimitry Andric     getObject(const llvm::Module *module) override  {
3330b57cec5SDimitry Andric       // Return nothing - we're just abusing the object-cache mechanism to dump
3340b57cec5SDimitry Andric       // objects.
3350b57cec5SDimitry Andric       return nullptr;
3360b57cec5SDimitry Andric   }
33781ad6265SDimitry Andric   private:
33881ad6265SDimitry Andric     FileSpec m_out_dir;
3390b57cec5SDimitry Andric   };
3400b57cec5SDimitry Andric 
34181ad6265SDimitry Andric   FileSpec save_objects_dir = process_sp->GetTarget().GetSaveJITObjectsDir();
34281ad6265SDimitry Andric   if (save_objects_dir) {
34381ad6265SDimitry Andric     m_object_cache_up = std::make_unique<ObjectDumper>(save_objects_dir);
3440b57cec5SDimitry Andric     m_execution_engine_up->setObjectCache(m_object_cache_up.get());
3450b57cec5SDimitry Andric   }
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   // Make sure we see all sections, including ones that don't have
3480b57cec5SDimitry Andric   // relocations...
3490b57cec5SDimitry Andric   m_execution_engine_up->setProcessAllSections(true);
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric   m_execution_engine_up->DisableLazyCompilation();
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric   for (llvm::Function &function : *m_module) {
3540b57cec5SDimitry Andric     if (function.isDeclaration() || function.hasPrivateLinkage())
3550b57cec5SDimitry Andric       continue;
3560b57cec5SDimitry Andric 
357e8d8bef9SDimitry Andric     const bool external = !function.hasLocalLinkage();
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric     void *fun_ptr = m_execution_engine_up->getPointerToFunction(&function);
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric     if (!error.Success()) {
3620b57cec5SDimitry Andric       // We got an error through our callback!
3630b57cec5SDimitry Andric       return;
3640b57cec5SDimitry Andric     }
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric     if (!fun_ptr) {
3670b57cec5SDimitry Andric       error.SetErrorToGenericError();
3680b57cec5SDimitry Andric       error.SetErrorStringWithFormat(
3690b57cec5SDimitry Andric           "'%s' was in the JITted module but wasn't lowered",
3700b57cec5SDimitry Andric           function.getName().str().c_str());
3710b57cec5SDimitry Andric       return;
3720b57cec5SDimitry Andric     }
3730b57cec5SDimitry Andric     m_jitted_functions.push_back(JittedFunction(
374480093f4SDimitry Andric         function.getName().str().c_str(), external, reinterpret_cast<uintptr_t>(fun_ptr)));
3750b57cec5SDimitry Andric   }
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric   CommitAllocations(process_sp);
3780b57cec5SDimitry Andric   ReportAllocations(*m_execution_engine_up);
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   // We have to do this after calling ReportAllocations because for the MCJIT,
3810b57cec5SDimitry Andric   // getGlobalValueAddress will cause the JIT to perform all relocations.  That
3820b57cec5SDimitry Andric   // can only be done once, and has to happen after we do the remapping from
3830b57cec5SDimitry Andric   // local -> remote. That means we don't know the local address of the
3840b57cec5SDimitry Andric   // Variables, but we don't need that for anything, so that's okay.
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric   std::function<void(llvm::GlobalValue &)> RegisterOneValue = [this](
3870b57cec5SDimitry Andric       llvm::GlobalValue &val) {
3880b57cec5SDimitry Andric     if (val.hasExternalLinkage() && !val.isDeclaration()) {
3890b57cec5SDimitry Andric       uint64_t var_ptr_addr =
3900b57cec5SDimitry Andric           m_execution_engine_up->getGlobalValueAddress(val.getName().str());
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric       lldb::addr_t remote_addr = GetRemoteAddressForLocal(var_ptr_addr);
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric       // This is a really unfortunae API that sometimes returns local addresses
3950b57cec5SDimitry Andric       // and sometimes returns remote addresses, based on whether the variable
3960b57cec5SDimitry Andric       // was relocated during ReportAllocations or not.
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric       if (remote_addr == LLDB_INVALID_ADDRESS) {
3990b57cec5SDimitry Andric         remote_addr = var_ptr_addr;
4000b57cec5SDimitry Andric       }
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric       if (var_ptr_addr != 0)
4030b57cec5SDimitry Andric         m_jitted_global_variables.push_back(JittedGlobalVariable(
4040b57cec5SDimitry Andric             val.getName().str().c_str(), LLDB_INVALID_ADDRESS, remote_addr));
4050b57cec5SDimitry Andric     }
4060b57cec5SDimitry Andric   };
4070b57cec5SDimitry Andric 
40806c3fb27SDimitry Andric   for (llvm::GlobalVariable &global_var : m_module->globals()) {
4090b57cec5SDimitry Andric     RegisterOneValue(global_var);
4100b57cec5SDimitry Andric   }
4110b57cec5SDimitry Andric 
41206c3fb27SDimitry Andric   for (llvm::GlobalAlias &global_alias : m_module->aliases()) {
4130b57cec5SDimitry Andric     RegisterOneValue(global_alias);
4140b57cec5SDimitry Andric   }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   WriteData(process_sp);
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   if (m_failed_lookups.size()) {
4190b57cec5SDimitry Andric     StreamString ss;
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric     ss.PutCString("Couldn't look up symbols:\n");
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric     bool emitNewLine = false;
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric     for (ConstString failed_lookup : m_failed_lookups) {
4260b57cec5SDimitry Andric       if (emitNewLine)
4270b57cec5SDimitry Andric         ss.PutCString("\n");
4280b57cec5SDimitry Andric       emitNewLine = true;
4290b57cec5SDimitry Andric       ss.PutCString("  ");
4305ffd83dbSDimitry Andric       ss.PutCString(Mangled(failed_lookup).GetDemangledName().GetStringRef());
4310b57cec5SDimitry Andric     }
4320b57cec5SDimitry Andric 
4330b57cec5SDimitry Andric     m_failed_lookups.clear();
434*0fca6ea1SDimitry Andric     ss.PutCString(
435*0fca6ea1SDimitry Andric         "\nHint: The expression tried to call a function that is not present "
436*0fca6ea1SDimitry Andric         "in the target, perhaps because it was optimized out by the compiler.");
4370b57cec5SDimitry Andric     error.SetErrorString(ss.GetString());
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric     return;
4400b57cec5SDimitry Andric   }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   m_function_load_addr = LLDB_INVALID_ADDRESS;
4430b57cec5SDimitry Andric   m_function_end_load_addr = LLDB_INVALID_ADDRESS;
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric   for (JittedFunction &jitted_function : m_jitted_functions) {
4460b57cec5SDimitry Andric     jitted_function.m_remote_addr =
4470b57cec5SDimitry Andric         GetRemoteAddressForLocal(jitted_function.m_local_addr);
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric     if (!m_name.IsEmpty() && jitted_function.m_name == m_name) {
4500b57cec5SDimitry Andric       AddrRange func_range =
4510b57cec5SDimitry Andric           GetRemoteRangeForLocal(jitted_function.m_local_addr);
4520b57cec5SDimitry Andric       m_function_end_load_addr = func_range.first + func_range.second;
4530b57cec5SDimitry Andric       m_function_load_addr = jitted_function.m_remote_addr;
4540b57cec5SDimitry Andric     }
4550b57cec5SDimitry Andric   }
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric   if (log) {
4589dba64beSDimitry Andric     LLDB_LOGF(log, "Code can be run in the target.");
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric     StreamString disassembly_stream;
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric     Status err = DisassembleFunction(disassembly_stream, process_sp);
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric     if (!err.Success()) {
4659dba64beSDimitry Andric       LLDB_LOGF(log, "Couldn't disassemble function : %s",
4660b57cec5SDimitry Andric                 err.AsCString("unknown error"));
4670b57cec5SDimitry Andric     } else {
4689dba64beSDimitry Andric       LLDB_LOGF(log, "Function disassembly:\n%s", disassembly_stream.GetData());
4690b57cec5SDimitry Andric     }
4700b57cec5SDimitry Andric 
4719dba64beSDimitry Andric     LLDB_LOGF(log, "Sections: ");
4720b57cec5SDimitry Andric     for (AllocationRecord &record : m_records) {
4730b57cec5SDimitry Andric       if (record.m_process_address != LLDB_INVALID_ADDRESS) {
4740b57cec5SDimitry Andric         record.dump(log);
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric         DataBufferHeap my_buffer(record.m_size, 0);
4770b57cec5SDimitry Andric         Status err;
4780b57cec5SDimitry Andric         ReadMemory(my_buffer.GetBytes(), record.m_process_address,
4790b57cec5SDimitry Andric                    record.m_size, err);
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric         if (err.Success()) {
4820b57cec5SDimitry Andric           DataExtractor my_extractor(my_buffer.GetBytes(),
4830b57cec5SDimitry Andric                                      my_buffer.GetByteSize(),
4840b57cec5SDimitry Andric                                      lldb::eByteOrderBig, 8);
4850b57cec5SDimitry Andric           my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(),
4860b57cec5SDimitry Andric                                 record.m_process_address, 16,
4870b57cec5SDimitry Andric                                 DataExtractor::TypeUInt8);
4880b57cec5SDimitry Andric         }
4890b57cec5SDimitry Andric       } else {
4900b57cec5SDimitry Andric         record.dump(log);
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric         DataExtractor my_extractor((const void *)record.m_host_address,
4930b57cec5SDimitry Andric                                    record.m_size, lldb::eByteOrderBig, 8);
4940b57cec5SDimitry Andric         my_extractor.PutToLog(log, 0, record.m_size, record.m_host_address, 16,
4950b57cec5SDimitry Andric                               DataExtractor::TypeUInt8);
4960b57cec5SDimitry Andric       }
4970b57cec5SDimitry Andric     }
4980b57cec5SDimitry Andric   }
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric   func_addr = m_function_load_addr;
5010b57cec5SDimitry Andric   func_end = m_function_end_load_addr;
5020b57cec5SDimitry Andric }
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric IRExecutionUnit::~IRExecutionUnit() {
5050b57cec5SDimitry Andric   m_module_up.reset();
5060b57cec5SDimitry Andric   m_execution_engine_up.reset();
5070b57cec5SDimitry Andric   m_context_up.reset();
5080b57cec5SDimitry Andric }
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric IRExecutionUnit::MemoryManager::MemoryManager(IRExecutionUnit &parent)
5110b57cec5SDimitry Andric     : m_default_mm_up(new llvm::SectionMemoryManager()), m_parent(parent) {}
5120b57cec5SDimitry Andric 
513fe6060f1SDimitry Andric IRExecutionUnit::MemoryManager::~MemoryManager() = default;
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric lldb::SectionType IRExecutionUnit::GetSectionTypeFromSectionName(
5160b57cec5SDimitry Andric     const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind) {
5170b57cec5SDimitry Andric   lldb::SectionType sect_type = lldb::eSectionTypeCode;
5180b57cec5SDimitry Andric   switch (alloc_kind) {
5190b57cec5SDimitry Andric   case AllocationKind::Stub:
5200b57cec5SDimitry Andric     sect_type = lldb::eSectionTypeCode;
5210b57cec5SDimitry Andric     break;
5220b57cec5SDimitry Andric   case AllocationKind::Code:
5230b57cec5SDimitry Andric     sect_type = lldb::eSectionTypeCode;
5240b57cec5SDimitry Andric     break;
5250b57cec5SDimitry Andric   case AllocationKind::Data:
5260b57cec5SDimitry Andric     sect_type = lldb::eSectionTypeData;
5270b57cec5SDimitry Andric     break;
5280b57cec5SDimitry Andric   case AllocationKind::Global:
5290b57cec5SDimitry Andric     sect_type = lldb::eSectionTypeData;
5300b57cec5SDimitry Andric     break;
5310b57cec5SDimitry Andric   case AllocationKind::Bytes:
5320b57cec5SDimitry Andric     sect_type = lldb::eSectionTypeOther;
5330b57cec5SDimitry Andric     break;
5340b57cec5SDimitry Andric   }
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric   if (!name.empty()) {
537*0fca6ea1SDimitry Andric     if (name == "__text" || name == ".text")
5380b57cec5SDimitry Andric       sect_type = lldb::eSectionTypeCode;
539*0fca6ea1SDimitry Andric     else if (name == "__data" || name == ".data")
5400b57cec5SDimitry Andric       sect_type = lldb::eSectionTypeCode;
5415f757f3fSDimitry Andric     else if (name.starts_with("__debug_") || name.starts_with(".debug_")) {
5420b57cec5SDimitry Andric       const uint32_t name_idx = name[0] == '_' ? 8 : 7;
5430b57cec5SDimitry Andric       llvm::StringRef dwarf_name(name.substr(name_idx));
5440b57cec5SDimitry Andric       switch (dwarf_name[0]) {
5450b57cec5SDimitry Andric       case 'a':
546*0fca6ea1SDimitry Andric         if (dwarf_name == "abbrev")
5470b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugAbbrev;
548*0fca6ea1SDimitry Andric         else if (dwarf_name == "aranges")
5490b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugAranges;
550*0fca6ea1SDimitry Andric         else if (dwarf_name == "addr")
5510b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugAddr;
5520b57cec5SDimitry Andric         break;
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric       case 'f':
555*0fca6ea1SDimitry Andric         if (dwarf_name == "frame")
5560b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugFrame;
5570b57cec5SDimitry Andric         break;
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric       case 'i':
560*0fca6ea1SDimitry Andric         if (dwarf_name == "info")
5610b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugInfo;
5620b57cec5SDimitry Andric         break;
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric       case 'l':
565*0fca6ea1SDimitry Andric         if (dwarf_name == "line")
5660b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugLine;
567*0fca6ea1SDimitry Andric         else if (dwarf_name == "loc")
5680b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugLoc;
569*0fca6ea1SDimitry Andric         else if (dwarf_name == "loclists")
5700b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugLocLists;
5710b57cec5SDimitry Andric         break;
5720b57cec5SDimitry Andric 
5730b57cec5SDimitry Andric       case 'm':
574*0fca6ea1SDimitry Andric         if (dwarf_name == "macinfo")
5750b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugMacInfo;
5760b57cec5SDimitry Andric         break;
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric       case 'p':
579*0fca6ea1SDimitry Andric         if (dwarf_name == "pubnames")
5800b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugPubNames;
581*0fca6ea1SDimitry Andric         else if (dwarf_name == "pubtypes")
5820b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugPubTypes;
5830b57cec5SDimitry Andric         break;
5840b57cec5SDimitry Andric 
5850b57cec5SDimitry Andric       case 's':
586*0fca6ea1SDimitry Andric         if (dwarf_name == "str")
5870b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugStr;
588*0fca6ea1SDimitry Andric         else if (dwarf_name == "str_offsets")
5890b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugStrOffsets;
5900b57cec5SDimitry Andric         break;
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric       case 'r':
593*0fca6ea1SDimitry Andric         if (dwarf_name == "ranges")
5940b57cec5SDimitry Andric           sect_type = lldb::eSectionTypeDWARFDebugRanges;
5950b57cec5SDimitry Andric         break;
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric       default:
5980b57cec5SDimitry Andric         break;
5990b57cec5SDimitry Andric       }
6005f757f3fSDimitry Andric     } else if (name.starts_with("__apple_") || name.starts_with(".apple_"))
6010b57cec5SDimitry Andric       sect_type = lldb::eSectionTypeInvalid;
602*0fca6ea1SDimitry Andric     else if (name == "__objc_imageinfo")
6030b57cec5SDimitry Andric       sect_type = lldb::eSectionTypeOther;
6040b57cec5SDimitry Andric   }
6050b57cec5SDimitry Andric   return sect_type;
6060b57cec5SDimitry Andric }
6070b57cec5SDimitry Andric 
6080b57cec5SDimitry Andric uint8_t *IRExecutionUnit::MemoryManager::allocateCodeSection(
6090b57cec5SDimitry Andric     uintptr_t Size, unsigned Alignment, unsigned SectionID,
6100b57cec5SDimitry Andric     llvm::StringRef SectionName) {
61181ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric   uint8_t *return_value = m_default_mm_up->allocateCodeSection(
6140b57cec5SDimitry Andric       Size, Alignment, SectionID, SectionName);
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric   m_parent.m_records.push_back(AllocationRecord(
6170b57cec5SDimitry Andric       (uintptr_t)return_value,
6180b57cec5SDimitry Andric       lldb::ePermissionsReadable | lldb::ePermissionsExecutable,
6190b57cec5SDimitry Andric       GetSectionTypeFromSectionName(SectionName, AllocationKind::Code), Size,
6200b57cec5SDimitry Andric       Alignment, SectionID, SectionName.str().c_str()));
6210b57cec5SDimitry Andric 
6229dba64beSDimitry Andric   LLDB_LOGF(log,
6239dba64beSDimitry Andric             "IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64
6240b57cec5SDimitry Andric             ", Alignment=%u, SectionID=%u) = %p",
6250b57cec5SDimitry Andric             (uint64_t)Size, Alignment, SectionID, (void *)return_value);
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric   if (m_parent.m_reported_allocations) {
6280b57cec5SDimitry Andric     Status err;
6290b57cec5SDimitry Andric     lldb::ProcessSP process_sp =
6300b57cec5SDimitry Andric         m_parent.GetBestExecutionContextScope()->CalculateProcess();
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric     m_parent.CommitOneAllocation(process_sp, err, m_parent.m_records.back());
6330b57cec5SDimitry Andric   }
6340b57cec5SDimitry Andric 
6350b57cec5SDimitry Andric   return return_value;
6360b57cec5SDimitry Andric }
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection(
6390b57cec5SDimitry Andric     uintptr_t Size, unsigned Alignment, unsigned SectionID,
6400b57cec5SDimitry Andric     llvm::StringRef SectionName, bool IsReadOnly) {
64181ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric   uint8_t *return_value = m_default_mm_up->allocateDataSection(
6440b57cec5SDimitry Andric       Size, Alignment, SectionID, SectionName, IsReadOnly);
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric   uint32_t permissions = lldb::ePermissionsReadable;
6470b57cec5SDimitry Andric   if (!IsReadOnly)
6480b57cec5SDimitry Andric     permissions |= lldb::ePermissionsWritable;
6490b57cec5SDimitry Andric   m_parent.m_records.push_back(AllocationRecord(
6500b57cec5SDimitry Andric       (uintptr_t)return_value, permissions,
6510b57cec5SDimitry Andric       GetSectionTypeFromSectionName(SectionName, AllocationKind::Data), Size,
6520b57cec5SDimitry Andric       Alignment, SectionID, SectionName.str().c_str()));
6539dba64beSDimitry Andric   LLDB_LOGF(log,
6549dba64beSDimitry Andric             "IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64
6550b57cec5SDimitry Andric             ", Alignment=%u, SectionID=%u) = %p",
6560b57cec5SDimitry Andric             (uint64_t)Size, Alignment, SectionID, (void *)return_value);
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   if (m_parent.m_reported_allocations) {
6590b57cec5SDimitry Andric     Status err;
6600b57cec5SDimitry Andric     lldb::ProcessSP process_sp =
6610b57cec5SDimitry Andric         m_parent.GetBestExecutionContextScope()->CalculateProcess();
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric     m_parent.CommitOneAllocation(process_sp, err, m_parent.m_records.back());
6640b57cec5SDimitry Andric   }
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric   return return_value;
6670b57cec5SDimitry Andric }
6680b57cec5SDimitry Andric 
669349cc55cSDimitry Andric void IRExecutionUnit::CollectCandidateCNames(std::vector<ConstString> &C_names,
6700b57cec5SDimitry Andric                                              ConstString name) {
6710b57cec5SDimitry Andric   if (m_strip_underscore && name.AsCString()[0] == '_')
672349cc55cSDimitry Andric     C_names.insert(C_names.begin(), ConstString(&name.AsCString()[1]));
673349cc55cSDimitry Andric   C_names.push_back(name);
6740b57cec5SDimitry Andric }
6750b57cec5SDimitry Andric 
6760b57cec5SDimitry Andric void IRExecutionUnit::CollectCandidateCPlusPlusNames(
677349cc55cSDimitry Andric     std::vector<ConstString> &CPP_names,
678349cc55cSDimitry Andric     const std::vector<ConstString> &C_names, const SymbolContext &sc) {
679349cc55cSDimitry Andric   if (auto *cpp_lang = Language::FindPlugin(lldb::eLanguageTypeC_plus_plus)) {
680349cc55cSDimitry Andric     for (const ConstString &name : C_names) {
6819dba64beSDimitry Andric       Mangled mangled(name);
682349cc55cSDimitry Andric       if (cpp_lang->SymbolNameFitsToLanguage(mangled)) {
683349cc55cSDimitry Andric         if (ConstString best_alternate =
684349cc55cSDimitry Andric                 cpp_lang->FindBestAlternateFunctionMangledName(mangled, sc)) {
685349cc55cSDimitry Andric           CPP_names.push_back(best_alternate);
686349cc55cSDimitry Andric         }
687349cc55cSDimitry Andric       }
6880b57cec5SDimitry Andric 
689349cc55cSDimitry Andric       std::vector<ConstString> alternates =
690349cc55cSDimitry Andric           cpp_lang->GenerateAlternateFunctionManglings(name);
691349cc55cSDimitry Andric       CPP_names.insert(CPP_names.end(), alternates.begin(), alternates.end());
6920b57cec5SDimitry Andric 
693349cc55cSDimitry Andric       // As a last-ditch fallback, try the base name for C++ names.  It's
694349cc55cSDimitry Andric       // terrible, but the DWARF doesn't always encode "extern C" correctly.
695349cc55cSDimitry Andric       ConstString basename =
696349cc55cSDimitry Andric           cpp_lang->GetDemangledFunctionNameWithoutArguments(mangled);
697349cc55cSDimitry Andric       CPP_names.push_back(basename);
6980b57cec5SDimitry Andric     }
6990b57cec5SDimitry Andric   }
7000b57cec5SDimitry Andric }
7010b57cec5SDimitry Andric 
702349cc55cSDimitry Andric class LoadAddressResolver {
703349cc55cSDimitry Andric public:
704349cc55cSDimitry Andric   LoadAddressResolver(Target *target, bool &symbol_was_missing_weak)
705349cc55cSDimitry Andric       : m_target(target), m_symbol_was_missing_weak(symbol_was_missing_weak) {}
7060b57cec5SDimitry Andric 
707bdd1243dSDimitry Andric   std::optional<lldb::addr_t> Resolve(SymbolContextList &sc_list) {
708349cc55cSDimitry Andric     if (sc_list.IsEmpty())
709bdd1243dSDimitry Andric       return std::nullopt;
7100b57cec5SDimitry Andric 
711349cc55cSDimitry Andric     lldb::addr_t load_address = LLDB_INVALID_ADDRESS;
7120b57cec5SDimitry Andric 
713349cc55cSDimitry Andric     // Missing_weak_symbol will be true only if we found only weak undefined
7140b57cec5SDimitry Andric     // references to this symbol.
715349cc55cSDimitry Andric     m_symbol_was_missing_weak = true;
7160b57cec5SDimitry Andric 
717349cc55cSDimitry Andric     for (auto candidate_sc : sc_list.SymbolContexts()) {
718349cc55cSDimitry Andric       // Only symbols can be weak undefined.
719349cc55cSDimitry Andric       if (!candidate_sc.symbol ||
720349cc55cSDimitry Andric           candidate_sc.symbol->GetType() != lldb::eSymbolTypeUndefined ||
721349cc55cSDimitry Andric           !candidate_sc.symbol->IsWeak())
722349cc55cSDimitry Andric         m_symbol_was_missing_weak = false;
723349cc55cSDimitry Andric 
724349cc55cSDimitry Andric       // First try the symbol.
725349cc55cSDimitry Andric       if (candidate_sc.symbol) {
726349cc55cSDimitry Andric         load_address = candidate_sc.symbol->ResolveCallableAddress(*m_target);
727349cc55cSDimitry Andric         if (load_address == LLDB_INVALID_ADDRESS) {
728349cc55cSDimitry Andric           Address addr = candidate_sc.symbol->GetAddress();
729349cc55cSDimitry Andric           load_address = m_target->GetProcessSP()
730349cc55cSDimitry Andric                              ? addr.GetLoadAddress(m_target)
731349cc55cSDimitry Andric                              : addr.GetFileAddress();
732349cc55cSDimitry Andric         }
733349cc55cSDimitry Andric       }
734349cc55cSDimitry Andric 
735349cc55cSDimitry Andric       // If that didn't work, try the function.
736349cc55cSDimitry Andric       if (load_address == LLDB_INVALID_ADDRESS && candidate_sc.function) {
737349cc55cSDimitry Andric         Address addr =
738349cc55cSDimitry Andric             candidate_sc.function->GetAddressRange().GetBaseAddress();
739349cc55cSDimitry Andric         load_address = m_target->GetProcessSP() ? addr.GetLoadAddress(m_target)
740349cc55cSDimitry Andric                                                 : addr.GetFileAddress();
741349cc55cSDimitry Andric       }
742349cc55cSDimitry Andric 
743349cc55cSDimitry Andric       // We found a load address.
744349cc55cSDimitry Andric       if (load_address != LLDB_INVALID_ADDRESS) {
745349cc55cSDimitry Andric         // If the load address is external, we're done.
7460b57cec5SDimitry Andric         const bool is_external =
7470b57cec5SDimitry Andric             (candidate_sc.function) ||
7480b57cec5SDimitry Andric             (candidate_sc.symbol && candidate_sc.symbol->IsExternal());
749349cc55cSDimitry Andric         if (is_external)
750349cc55cSDimitry Andric           return load_address;
7510b57cec5SDimitry Andric 
752349cc55cSDimitry Andric         // Otherwise, remember the best internal load address.
753349cc55cSDimitry Andric         if (m_best_internal_load_address == LLDB_INVALID_ADDRESS)
754349cc55cSDimitry Andric           m_best_internal_load_address = load_address;
7550b57cec5SDimitry Andric       }
7560b57cec5SDimitry Andric     }
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric     // You test the address of a weak symbol against NULL to see if it is
7590b57cec5SDimitry Andric     // present. So we should return 0 for a missing weak symbol.
760349cc55cSDimitry Andric     if (m_symbol_was_missing_weak)
761349cc55cSDimitry Andric       return 0;
762349cc55cSDimitry Andric 
763bdd1243dSDimitry Andric     return std::nullopt;
7640b57cec5SDimitry Andric   }
7650b57cec5SDimitry Andric 
766349cc55cSDimitry Andric   lldb::addr_t GetBestInternalLoadAddress() const {
767349cc55cSDimitry Andric     return m_best_internal_load_address;
768349cc55cSDimitry Andric   }
769349cc55cSDimitry Andric 
770349cc55cSDimitry Andric private:
771349cc55cSDimitry Andric   Target *m_target;
772349cc55cSDimitry Andric   bool &m_symbol_was_missing_weak;
773349cc55cSDimitry Andric   lldb::addr_t m_best_internal_load_address = LLDB_INVALID_ADDRESS;
7740b57cec5SDimitry Andric };
7750b57cec5SDimitry Andric 
776349cc55cSDimitry Andric lldb::addr_t
777349cc55cSDimitry Andric IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names,
778349cc55cSDimitry Andric                                const lldb_private::SymbolContext &sc,
779349cc55cSDimitry Andric                                bool &symbol_was_missing_weak) {
780349cc55cSDimitry Andric   symbol_was_missing_weak = false;
781349cc55cSDimitry Andric 
782349cc55cSDimitry Andric   Target *target = sc.target_sp.get();
783349cc55cSDimitry Andric   if (!target) {
784349cc55cSDimitry Andric     // We shouldn't be doing any symbol lookup at all without a target.
785349cc55cSDimitry Andric     return LLDB_INVALID_ADDRESS;
786349cc55cSDimitry Andric   }
787349cc55cSDimitry Andric 
788349cc55cSDimitry Andric   LoadAddressResolver resolver(target, symbol_was_missing_weak);
789349cc55cSDimitry Andric 
790349cc55cSDimitry Andric   ModuleFunctionSearchOptions function_options;
791349cc55cSDimitry Andric   function_options.include_symbols = true;
792349cc55cSDimitry Andric   function_options.include_inlines = false;
793349cc55cSDimitry Andric 
794349cc55cSDimitry Andric   for (const ConstString &name : names) {
7950b57cec5SDimitry Andric     if (sc.module_sp) {
796349cc55cSDimitry Andric       SymbolContextList sc_list;
797349cc55cSDimitry Andric       sc.module_sp->FindFunctions(name, CompilerDeclContext(),
798349cc55cSDimitry Andric                                   lldb::eFunctionNameTypeFull, function_options,
7990b57cec5SDimitry Andric                                   sc_list);
800349cc55cSDimitry Andric       if (auto load_addr = resolver.Resolve(sc_list))
801349cc55cSDimitry Andric         return *load_addr;
8020b57cec5SDimitry Andric     }
8030b57cec5SDimitry Andric 
804349cc55cSDimitry Andric     if (sc.target_sp) {
805349cc55cSDimitry Andric       SymbolContextList sc_list;
806349cc55cSDimitry Andric       sc.target_sp->GetImages().FindFunctions(name, lldb::eFunctionNameTypeFull,
807349cc55cSDimitry Andric                                               function_options, sc_list);
808349cc55cSDimitry Andric       if (auto load_addr = resolver.Resolve(sc_list))
809349cc55cSDimitry Andric         return *load_addr;
8100b57cec5SDimitry Andric     }
8110b57cec5SDimitry Andric 
812349cc55cSDimitry Andric     if (sc.target_sp) {
813349cc55cSDimitry Andric       SymbolContextList sc_list;
8140b57cec5SDimitry Andric       sc.target_sp->GetImages().FindSymbolsWithNameAndType(
815349cc55cSDimitry Andric           name, lldb::eSymbolTypeAny, sc_list);
816349cc55cSDimitry Andric       if (auto load_addr = resolver.Resolve(sc_list))
817349cc55cSDimitry Andric         return *load_addr;
8180b57cec5SDimitry Andric     }
8190b57cec5SDimitry Andric 
820349cc55cSDimitry Andric     lldb::addr_t best_internal_load_address =
821349cc55cSDimitry Andric         resolver.GetBestInternalLoadAddress();
822349cc55cSDimitry Andric     if (best_internal_load_address != LLDB_INVALID_ADDRESS)
8230b57cec5SDimitry Andric       return best_internal_load_address;
8240b57cec5SDimitry Andric   }
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric   return LLDB_INVALID_ADDRESS;
8270b57cec5SDimitry Andric }
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric lldb::addr_t
830349cc55cSDimitry Andric IRExecutionUnit::FindInRuntimes(const std::vector<ConstString> &names,
8310b57cec5SDimitry Andric                                 const lldb_private::SymbolContext &sc) {
8320b57cec5SDimitry Andric   lldb::TargetSP target_sp = sc.target_sp;
8330b57cec5SDimitry Andric 
8340b57cec5SDimitry Andric   if (!target_sp) {
8350b57cec5SDimitry Andric     return LLDB_INVALID_ADDRESS;
8360b57cec5SDimitry Andric   }
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric   lldb::ProcessSP process_sp = sc.target_sp->GetProcessSP();
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric   if (!process_sp) {
8410b57cec5SDimitry Andric     return LLDB_INVALID_ADDRESS;
8420b57cec5SDimitry Andric   }
8430b57cec5SDimitry Andric 
844349cc55cSDimitry Andric   for (const ConstString &name : names) {
8450b57cec5SDimitry Andric     for (LanguageRuntime *runtime : process_sp->GetLanguageRuntimes()) {
846349cc55cSDimitry Andric       lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(name);
8470b57cec5SDimitry Andric 
8480b57cec5SDimitry Andric       if (symbol_load_addr != LLDB_INVALID_ADDRESS)
8490b57cec5SDimitry Andric         return symbol_load_addr;
8500b57cec5SDimitry Andric     }
8510b57cec5SDimitry Andric   }
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric   return LLDB_INVALID_ADDRESS;
8540b57cec5SDimitry Andric }
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric lldb::addr_t IRExecutionUnit::FindInUserDefinedSymbols(
857349cc55cSDimitry Andric     const std::vector<ConstString> &names,
8580b57cec5SDimitry Andric     const lldb_private::SymbolContext &sc) {
8590b57cec5SDimitry Andric   lldb::TargetSP target_sp = sc.target_sp;
8600b57cec5SDimitry Andric 
861349cc55cSDimitry Andric   for (const ConstString &name : names) {
862349cc55cSDimitry Andric     lldb::addr_t symbol_load_addr = target_sp->GetPersistentSymbol(name);
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric     if (symbol_load_addr != LLDB_INVALID_ADDRESS)
8650b57cec5SDimitry Andric       return symbol_load_addr;
8660b57cec5SDimitry Andric   }
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric   return LLDB_INVALID_ADDRESS;
8690b57cec5SDimitry Andric }
8700b57cec5SDimitry Andric 
871349cc55cSDimitry Andric lldb::addr_t IRExecutionUnit::FindSymbol(lldb_private::ConstString name,
872349cc55cSDimitry Andric                                          bool &missing_weak) {
873349cc55cSDimitry Andric   std::vector<ConstString> candidate_C_names;
874349cc55cSDimitry Andric   std::vector<ConstString> candidate_CPlusPlus_names;
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric   CollectCandidateCNames(candidate_C_names, name);
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric   lldb::addr_t ret = FindInSymbols(candidate_C_names, m_sym_ctx, missing_weak);
8790b57cec5SDimitry Andric   if (ret != LLDB_INVALID_ADDRESS)
8800b57cec5SDimitry Andric     return ret;
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric   // If we find the symbol in runtimes or user defined symbols it can't be
8830b57cec5SDimitry Andric   // a missing weak symbol.
8840b57cec5SDimitry Andric   missing_weak = false;
8850b57cec5SDimitry Andric   ret = FindInRuntimes(candidate_C_names, m_sym_ctx);
8860b57cec5SDimitry Andric   if (ret != LLDB_INVALID_ADDRESS)
8870b57cec5SDimitry Andric     return ret;
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric   ret = FindInUserDefinedSymbols(candidate_C_names, m_sym_ctx);
8900b57cec5SDimitry Andric   if (ret != LLDB_INVALID_ADDRESS)
8910b57cec5SDimitry Andric     return ret;
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names,
8940b57cec5SDimitry Andric                                  m_sym_ctx);
8950b57cec5SDimitry Andric   ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx, missing_weak);
8960b57cec5SDimitry Andric   return ret;
8970b57cec5SDimitry Andric }
8980b57cec5SDimitry Andric 
8990b57cec5SDimitry Andric void IRExecutionUnit::GetStaticInitializers(
9000b57cec5SDimitry Andric     std::vector<lldb::addr_t> &static_initializers) {
90181ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
902480093f4SDimitry Andric 
903480093f4SDimitry Andric   llvm::GlobalVariable *global_ctors =
904480093f4SDimitry Andric       m_module->getNamedGlobal("llvm.global_ctors");
905480093f4SDimitry Andric   if (!global_ctors) {
906480093f4SDimitry Andric     LLDB_LOG(log, "Couldn't find llvm.global_ctors.");
907480093f4SDimitry Andric     return;
908480093f4SDimitry Andric   }
909480093f4SDimitry Andric   auto *ctor_array =
910480093f4SDimitry Andric       llvm::dyn_cast<llvm::ConstantArray>(global_ctors->getInitializer());
911480093f4SDimitry Andric   if (!ctor_array) {
912480093f4SDimitry Andric     LLDB_LOG(log, "llvm.global_ctors not a ConstantArray.");
913480093f4SDimitry Andric     return;
914480093f4SDimitry Andric   }
915480093f4SDimitry Andric 
9160b57cec5SDimitry Andric   for (llvm::Use &ctor_use : ctor_array->operands()) {
917480093f4SDimitry Andric     auto *ctor_struct = llvm::dyn_cast<llvm::ConstantStruct>(ctor_use);
918480093f4SDimitry Andric     if (!ctor_struct)
919480093f4SDimitry Andric       continue;
920480093f4SDimitry Andric     // this is standardized
921480093f4SDimitry Andric     lldbassert(ctor_struct->getNumOperands() == 3);
922480093f4SDimitry Andric     auto *ctor_function =
923480093f4SDimitry Andric         llvm::dyn_cast<llvm::Function>(ctor_struct->getOperand(1));
924480093f4SDimitry Andric     if (!ctor_function) {
925480093f4SDimitry Andric       LLDB_LOG(log, "global_ctor doesn't contain an llvm::Function");
926480093f4SDimitry Andric       continue;
927480093f4SDimitry Andric     }
928480093f4SDimitry Andric 
929480093f4SDimitry Andric     ConstString ctor_function_name(ctor_function->getName().str());
930480093f4SDimitry Andric     LLDB_LOG(log, "Looking for callable jitted function with name {0}.",
931480093f4SDimitry Andric              ctor_function_name);
9320b57cec5SDimitry Andric 
9330b57cec5SDimitry Andric     for (JittedFunction &jitted_function : m_jitted_functions) {
934480093f4SDimitry Andric       if (ctor_function_name != jitted_function.m_name)
935480093f4SDimitry Andric         continue;
936480093f4SDimitry Andric       if (jitted_function.m_remote_addr == LLDB_INVALID_ADDRESS) {
937480093f4SDimitry Andric         LLDB_LOG(log, "Found jitted function with invalid address.");
938480093f4SDimitry Andric         continue;
939480093f4SDimitry Andric       }
9400b57cec5SDimitry Andric       static_initializers.push_back(jitted_function.m_remote_addr);
941480093f4SDimitry Andric       LLDB_LOG(log, "Calling function at address {0:x}.",
942480093f4SDimitry Andric                jitted_function.m_remote_addr);
9430b57cec5SDimitry Andric       break;
9440b57cec5SDimitry Andric     }
9450b57cec5SDimitry Andric   }
9460b57cec5SDimitry Andric }
9470b57cec5SDimitry Andric 
9480b57cec5SDimitry Andric llvm::JITSymbol
9490b57cec5SDimitry Andric IRExecutionUnit::MemoryManager::findSymbol(const std::string &Name) {
9500b57cec5SDimitry Andric     bool missing_weak = false;
9510b57cec5SDimitry Andric     uint64_t addr = GetSymbolAddressAndPresence(Name, missing_weak);
9520b57cec5SDimitry Andric     // This is a weak symbol:
9530b57cec5SDimitry Andric     if (missing_weak)
9540b57cec5SDimitry Andric       return llvm::JITSymbol(addr,
9550b57cec5SDimitry Andric           llvm::JITSymbolFlags::Exported | llvm::JITSymbolFlags::Weak);
9560b57cec5SDimitry Andric     else
9570b57cec5SDimitry Andric       return llvm::JITSymbol(addr, llvm::JITSymbolFlags::Exported);
9580b57cec5SDimitry Andric }
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric uint64_t
9610b57cec5SDimitry Andric IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name) {
9620b57cec5SDimitry Andric   bool missing_weak = false;
9630b57cec5SDimitry Andric   return GetSymbolAddressAndPresence(Name, missing_weak);
9640b57cec5SDimitry Andric }
9650b57cec5SDimitry Andric 
9660b57cec5SDimitry Andric uint64_t
9670b57cec5SDimitry Andric IRExecutionUnit::MemoryManager::GetSymbolAddressAndPresence(
9680b57cec5SDimitry Andric     const std::string &Name, bool &missing_weak) {
96981ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   ConstString name_cs(Name.c_str());
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric   lldb::addr_t ret = m_parent.FindSymbol(name_cs, missing_weak);
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric   if (ret == LLDB_INVALID_ADDRESS) {
9769dba64beSDimitry Andric     LLDB_LOGF(log,
9770b57cec5SDimitry Andric               "IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
9780b57cec5SDimitry Andric               Name.c_str());
9790b57cec5SDimitry Andric 
9800b57cec5SDimitry Andric     m_parent.ReportSymbolLookupError(name_cs);
9810b57cec5SDimitry Andric     return 0;
9820b57cec5SDimitry Andric   } else {
9839dba64beSDimitry Andric     LLDB_LOGF(log, "IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
9840b57cec5SDimitry Andric               Name.c_str(), ret);
9850b57cec5SDimitry Andric     return ret;
9860b57cec5SDimitry Andric   }
9870b57cec5SDimitry Andric }
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric void *IRExecutionUnit::MemoryManager::getPointerToNamedFunction(
9900b57cec5SDimitry Andric     const std::string &Name, bool AbortOnFailure) {
9910b57cec5SDimitry Andric   return (void *)getSymbolAddress(Name);
9920b57cec5SDimitry Andric }
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric lldb::addr_t
9950b57cec5SDimitry Andric IRExecutionUnit::GetRemoteAddressForLocal(lldb::addr_t local_address) {
99681ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric   for (AllocationRecord &record : m_records) {
9990b57cec5SDimitry Andric     if (local_address >= record.m_host_address &&
10000b57cec5SDimitry Andric         local_address < record.m_host_address + record.m_size) {
10010b57cec5SDimitry Andric       if (record.m_process_address == LLDB_INVALID_ADDRESS)
10020b57cec5SDimitry Andric         return LLDB_INVALID_ADDRESS;
10030b57cec5SDimitry Andric 
10040b57cec5SDimitry Andric       lldb::addr_t ret =
10050b57cec5SDimitry Andric           record.m_process_address + (local_address - record.m_host_address);
10060b57cec5SDimitry Andric 
10079dba64beSDimitry Andric       LLDB_LOGF(log,
10080b57cec5SDimitry Andric                 "IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64
10090b57cec5SDimitry Andric                 " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64
10100b57cec5SDimitry Andric                 " from [0x%" PRIx64 "..0x%" PRIx64 "].",
10110b57cec5SDimitry Andric                 local_address, (uint64_t)record.m_host_address,
10120b57cec5SDimitry Andric                 (uint64_t)record.m_host_address + (uint64_t)record.m_size, ret,
10139dba64beSDimitry Andric                 record.m_process_address,
10149dba64beSDimitry Andric                 record.m_process_address + record.m_size);
10150b57cec5SDimitry Andric 
10160b57cec5SDimitry Andric       return ret;
10170b57cec5SDimitry Andric     }
10180b57cec5SDimitry Andric   }
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric   return LLDB_INVALID_ADDRESS;
10210b57cec5SDimitry Andric }
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric IRExecutionUnit::AddrRange
10240b57cec5SDimitry Andric IRExecutionUnit::GetRemoteRangeForLocal(lldb::addr_t local_address) {
10250b57cec5SDimitry Andric   for (AllocationRecord &record : m_records) {
10260b57cec5SDimitry Andric     if (local_address >= record.m_host_address &&
10270b57cec5SDimitry Andric         local_address < record.m_host_address + record.m_size) {
10280b57cec5SDimitry Andric       if (record.m_process_address == LLDB_INVALID_ADDRESS)
10290b57cec5SDimitry Andric         return AddrRange(0, 0);
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric       return AddrRange(record.m_process_address, record.m_size);
10320b57cec5SDimitry Andric     }
10330b57cec5SDimitry Andric   }
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric   return AddrRange(0, 0);
10360b57cec5SDimitry Andric }
10370b57cec5SDimitry Andric 
10380b57cec5SDimitry Andric bool IRExecutionUnit::CommitOneAllocation(lldb::ProcessSP &process_sp,
10390b57cec5SDimitry Andric                                           Status &error,
10400b57cec5SDimitry Andric                                           AllocationRecord &record) {
10410b57cec5SDimitry Andric   if (record.m_process_address != LLDB_INVALID_ADDRESS) {
10420b57cec5SDimitry Andric     return true;
10430b57cec5SDimitry Andric   }
10440b57cec5SDimitry Andric 
10450b57cec5SDimitry Andric   switch (record.m_sect_type) {
10460b57cec5SDimitry Andric   case lldb::eSectionTypeInvalid:
10470b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugAbbrev:
10480b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugAddr:
10490b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugAranges:
10500b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugCuIndex:
10510b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugFrame:
10520b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugInfo:
10530b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugLine:
10540b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugLoc:
10550b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugLocLists:
10560b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugMacInfo:
10570b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugPubNames:
10580b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugPubTypes:
10590b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugRanges:
10600b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugStr:
10610b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFDebugStrOffsets:
10620b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFAppleNames:
10630b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFAppleTypes:
10640b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFAppleNamespaces:
10650b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFAppleObjC:
10660b57cec5SDimitry Andric   case lldb::eSectionTypeDWARFGNUDebugAltLink:
10670b57cec5SDimitry Andric     error.Clear();
10680b57cec5SDimitry Andric     break;
10690b57cec5SDimitry Andric   default:
10700b57cec5SDimitry Andric     const bool zero_memory = false;
10710b57cec5SDimitry Andric     record.m_process_address =
10720b57cec5SDimitry Andric         Malloc(record.m_size, record.m_alignment, record.m_permissions,
10730b57cec5SDimitry Andric                eAllocationPolicyProcessOnly, zero_memory, error);
10740b57cec5SDimitry Andric     break;
10750b57cec5SDimitry Andric   }
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric   return error.Success();
10780b57cec5SDimitry Andric }
10790b57cec5SDimitry Andric 
10800b57cec5SDimitry Andric bool IRExecutionUnit::CommitAllocations(lldb::ProcessSP &process_sp) {
10810b57cec5SDimitry Andric   bool ret = true;
10820b57cec5SDimitry Andric 
10830b57cec5SDimitry Andric   lldb_private::Status err;
10840b57cec5SDimitry Andric 
10850b57cec5SDimitry Andric   for (AllocationRecord &record : m_records) {
10860b57cec5SDimitry Andric     ret = CommitOneAllocation(process_sp, err, record);
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric     if (!ret) {
10890b57cec5SDimitry Andric       break;
10900b57cec5SDimitry Andric     }
10910b57cec5SDimitry Andric   }
10920b57cec5SDimitry Andric 
10930b57cec5SDimitry Andric   if (!ret) {
10940b57cec5SDimitry Andric     for (AllocationRecord &record : m_records) {
10950b57cec5SDimitry Andric       if (record.m_process_address != LLDB_INVALID_ADDRESS) {
10960b57cec5SDimitry Andric         Free(record.m_process_address, err);
10970b57cec5SDimitry Andric         record.m_process_address = LLDB_INVALID_ADDRESS;
10980b57cec5SDimitry Andric       }
10990b57cec5SDimitry Andric     }
11000b57cec5SDimitry Andric   }
11010b57cec5SDimitry Andric 
11020b57cec5SDimitry Andric   return ret;
11030b57cec5SDimitry Andric }
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric void IRExecutionUnit::ReportAllocations(llvm::ExecutionEngine &engine) {
11060b57cec5SDimitry Andric   m_reported_allocations = true;
11070b57cec5SDimitry Andric 
11080b57cec5SDimitry Andric   for (AllocationRecord &record : m_records) {
11090b57cec5SDimitry Andric     if (record.m_process_address == LLDB_INVALID_ADDRESS)
11100b57cec5SDimitry Andric       continue;
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric     if (record.m_section_id == eSectionIDInvalid)
11130b57cec5SDimitry Andric       continue;
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric     engine.mapSectionAddress((void *)record.m_host_address,
11160b57cec5SDimitry Andric                              record.m_process_address);
11170b57cec5SDimitry Andric   }
11180b57cec5SDimitry Andric 
11190b57cec5SDimitry Andric   // Trigger re-application of relocations.
11200b57cec5SDimitry Andric   engine.finalizeObject();
11210b57cec5SDimitry Andric }
11220b57cec5SDimitry Andric 
11230b57cec5SDimitry Andric bool IRExecutionUnit::WriteData(lldb::ProcessSP &process_sp) {
11240b57cec5SDimitry Andric   bool wrote_something = false;
11250b57cec5SDimitry Andric   for (AllocationRecord &record : m_records) {
11260b57cec5SDimitry Andric     if (record.m_process_address != LLDB_INVALID_ADDRESS) {
11270b57cec5SDimitry Andric       lldb_private::Status err;
11280b57cec5SDimitry Andric       WriteMemory(record.m_process_address, (uint8_t *)record.m_host_address,
11290b57cec5SDimitry Andric                   record.m_size, err);
11300b57cec5SDimitry Andric       if (err.Success())
11310b57cec5SDimitry Andric         wrote_something = true;
11320b57cec5SDimitry Andric     }
11330b57cec5SDimitry Andric   }
11340b57cec5SDimitry Andric   return wrote_something;
11350b57cec5SDimitry Andric }
11360b57cec5SDimitry Andric 
11370b57cec5SDimitry Andric void IRExecutionUnit::AllocationRecord::dump(Log *log) {
11380b57cec5SDimitry Andric   if (!log)
11390b57cec5SDimitry Andric     return;
11400b57cec5SDimitry Andric 
11419dba64beSDimitry Andric   LLDB_LOGF(log,
11429dba64beSDimitry Andric             "[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d, name %s)",
11430b57cec5SDimitry Andric             (unsigned long long)m_host_address, (unsigned long long)m_size,
11440b57cec5SDimitry Andric             (unsigned long long)m_process_address, (unsigned)m_alignment,
11450b57cec5SDimitry Andric             (unsigned)m_section_id, m_name.c_str());
11460b57cec5SDimitry Andric }
11470b57cec5SDimitry Andric 
11480b57cec5SDimitry Andric lldb::ByteOrder IRExecutionUnit::GetByteOrder() const {
11490b57cec5SDimitry Andric   ExecutionContext exe_ctx(GetBestExecutionContextScope());
11500b57cec5SDimitry Andric   return exe_ctx.GetByteOrder();
11510b57cec5SDimitry Andric }
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric uint32_t IRExecutionUnit::GetAddressByteSize() const {
11540b57cec5SDimitry Andric   ExecutionContext exe_ctx(GetBestExecutionContextScope());
11550b57cec5SDimitry Andric   return exe_ctx.GetAddressByteSize();
11560b57cec5SDimitry Andric }
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric void IRExecutionUnit::PopulateSymtab(lldb_private::ObjectFile *obj_file,
11590b57cec5SDimitry Andric                                      lldb_private::Symtab &symtab) {
11600b57cec5SDimitry Andric   // No symbols yet...
11610b57cec5SDimitry Andric }
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric void IRExecutionUnit::PopulateSectionList(
11640b57cec5SDimitry Andric     lldb_private::ObjectFile *obj_file,
11650b57cec5SDimitry Andric     lldb_private::SectionList &section_list) {
11660b57cec5SDimitry Andric   for (AllocationRecord &record : m_records) {
11670b57cec5SDimitry Andric     if (record.m_size > 0) {
11680b57cec5SDimitry Andric       lldb::SectionSP section_sp(new lldb_private::Section(
11690b57cec5SDimitry Andric           obj_file->GetModule(), obj_file, record.m_section_id,
11700b57cec5SDimitry Andric           ConstString(record.m_name), record.m_sect_type,
11710b57cec5SDimitry Andric           record.m_process_address, record.m_size,
11720b57cec5SDimitry Andric           record.m_host_address, // file_offset (which is the host address for
11730b57cec5SDimitry Andric                                  // the data)
11740b57cec5SDimitry Andric           record.m_size,         // file_size
11750b57cec5SDimitry Andric           0,
11760b57cec5SDimitry Andric           record.m_permissions)); // flags
11770b57cec5SDimitry Andric       section_list.AddSection(section_sp);
11780b57cec5SDimitry Andric     }
11790b57cec5SDimitry Andric   }
11800b57cec5SDimitry Andric }
11810b57cec5SDimitry Andric 
11820b57cec5SDimitry Andric ArchSpec IRExecutionUnit::GetArchitecture() {
11830b57cec5SDimitry Andric   ExecutionContext exe_ctx(GetBestExecutionContextScope());
11840b57cec5SDimitry Andric   if(Target *target = exe_ctx.GetTargetPtr())
11850b57cec5SDimitry Andric     return target->GetArchitecture();
11860b57cec5SDimitry Andric   return ArchSpec();
11870b57cec5SDimitry Andric }
11880b57cec5SDimitry Andric 
11890b57cec5SDimitry Andric lldb::ModuleSP IRExecutionUnit::GetJITModule() {
11900b57cec5SDimitry Andric   ExecutionContext exe_ctx(GetBestExecutionContextScope());
11910b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
11920b57cec5SDimitry Andric   if (!target)
11930b57cec5SDimitry Andric     return nullptr;
11940b57cec5SDimitry Andric 
11950b57cec5SDimitry Andric   auto Delegate = std::static_pointer_cast<lldb_private::ObjectFileJITDelegate>(
11960b57cec5SDimitry Andric       shared_from_this());
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   lldb::ModuleSP jit_module_sp =
11990b57cec5SDimitry Andric       lldb_private::Module::CreateModuleFromObjectFile<ObjectFileJIT>(Delegate);
12000b57cec5SDimitry Andric   if (!jit_module_sp)
12010b57cec5SDimitry Andric     return nullptr;
12020b57cec5SDimitry Andric 
12030b57cec5SDimitry Andric   bool changed = false;
12040b57cec5SDimitry Andric   jit_module_sp->SetLoadAddress(*target, 0, true, changed);
12050b57cec5SDimitry Andric   return jit_module_sp;
12060b57cec5SDimitry Andric }
1207