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 §ion_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