diff options
Diffstat (limited to 'source/Expression/IRExecutionUnit.cpp')
-rw-r--r-- | source/Expression/IRExecutionUnit.cpp | 193 |
1 files changed, 113 insertions, 80 deletions
diff --git a/source/Expression/IRExecutionUnit.cpp b/source/Expression/IRExecutionUnit.cpp index ec6ceeac1813..25404ad313e1 100644 --- a/source/Expression/IRExecutionUnit.cpp +++ b/source/Expression/IRExecutionUnit.cpp @@ -1,9 +1,8 @@ //===-- IRExecutionUnit.cpp -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -25,7 +24,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/ObjCLanguageRuntime.h" +#include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" @@ -37,14 +36,14 @@ using namespace lldb_private; -IRExecutionUnit::IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_ap, - std::unique_ptr<llvm::Module> &module_ap, +IRExecutionUnit::IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_up, + std::unique_ptr<llvm::Module> &module_up, ConstString &name, const lldb::TargetSP &target_sp, const SymbolContext &sym_ctx, std::vector<std::string> &cpu_features) - : IRMemoryMap(target_sp), m_context_ap(context_ap.release()), - m_module_ap(module_ap.release()), m_module(m_module_ap.get()), + : IRMemoryMap(target_sp), m_context_up(context_up.release()), + m_module_up(module_up.release()), m_module(m_module_up.get()), m_cpu_features(cpu_features), m_name(name), m_sym_ctx(sym_ctx), m_did_jit(false), m_function_load_addr(LLDB_INVALID_ADDRESS), m_function_end_load_addr(LLDB_INVALID_ADDRESS), @@ -166,8 +165,8 @@ Status IRExecutionUnit::DisassembleFunction(Stream &stream, ArchSpec arch(target->GetArchitecture()); - const char *plugin_name = NULL; - const char *flavor_string = NULL; + const char *plugin_name = nullptr; + const char *flavor_string = nullptr; lldb::DisassemblerSP disassembler_sp = Disassembler::FindPlugin(arch, flavor_string, plugin_name); @@ -213,7 +212,7 @@ static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, } } -void IRExecutionUnit::ReportSymbolLookupError(const ConstString &name) { +void IRExecutionUnit::ReportSymbolLookupError(ConstString name) { m_failed_lookups.push_back(name); } @@ -252,30 +251,24 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, std::string s; llvm::raw_string_ostream oss(s); - m_module->print(oss, NULL); + m_module->print(oss, nullptr); oss.flush(); log->Printf("Module being sent to JIT: \n%s", s.c_str()); } - llvm::Triple triple(m_module->getTargetTriple()); - llvm::Reloc::Model relocModel; - - if (triple.isOSBinFormatELF()) { - relocModel = llvm::Reloc::Static; - } else { - relocModel = llvm::Reloc::PIC_; - } - - m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, + m_module_up->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, &error); - llvm::EngineBuilder builder(std::move(m_module_ap)); + llvm::EngineBuilder builder(std::move(m_module_up)); + llvm::Triple triple(m_module->getTargetTriple()); builder.setEngineKind(llvm::EngineKind::JIT) .setErrorStr(&error_string) - .setRelocationModel(relocModel) + .setRelocationModel(triple.isOSBinFormatMachO() + ? llvm::Reloc::PIC_ + : llvm::Reloc::Static) .setMCJITMemoryManager( std::unique_ptr<MemoryManager>(new MemoryManager(*this))) .setOptLevel(llvm::CodeGenOpt::Less); @@ -290,18 +283,18 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, llvm::TargetMachine *target_machine = builder.selectTarget(triple, mArch, mCPU, mAttrs); - m_execution_engine_ap.reset(builder.create(target_machine)); - - m_strip_underscore = - (m_execution_engine_ap->getDataLayout().getGlobalPrefix() == '_'); + m_execution_engine_up.reset(builder.create(target_machine)); - if (!m_execution_engine_ap.get()) { + if (!m_execution_engine_up) { error.SetErrorToGenericError(); error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str()); return; } + m_strip_underscore = + (m_execution_engine_up->getDataLayout().getGlobalPrefix() == '_'); + class ObjectDumper : public llvm::ObjectCache { public: void notifyObjectCompiled(const llvm::Module *module, @@ -324,15 +317,15 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, }; if (process_sp->GetTarget().GetEnableSaveObjects()) { - m_object_cache_ap = llvm::make_unique<ObjectDumper>(); - m_execution_engine_ap->setObjectCache(m_object_cache_ap.get()); + m_object_cache_up = llvm::make_unique<ObjectDumper>(); + m_execution_engine_up->setObjectCache(m_object_cache_up.get()); } // Make sure we see all sections, including ones that don't have // relocations... - m_execution_engine_ap->setProcessAllSections(true); + m_execution_engine_up->setProcessAllSections(true); - m_execution_engine_ap->DisableLazyCompilation(); + m_execution_engine_up->DisableLazyCompilation(); for (llvm::Function &function : *m_module) { if (function.isDeclaration() || function.hasPrivateLinkage()) @@ -341,7 +334,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, const bool external = function.hasExternalLinkage() || function.hasLinkOnceODRLinkage(); - void *fun_ptr = m_execution_engine_ap->getPointerToFunction(&function); + void *fun_ptr = m_execution_engine_up->getPointerToFunction(&function); if (!error.Success()) { // We got an error through our callback! @@ -360,7 +353,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, } CommitAllocations(process_sp); - ReportAllocations(*m_execution_engine_ap); + ReportAllocations(*m_execution_engine_up); // We have to do this after calling ReportAllocations because for the MCJIT, // getGlobalValueAddress will cause the JIT to perform all relocations. That @@ -372,7 +365,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, llvm::GlobalValue &val) { if (val.hasExternalLinkage() && !val.isDeclaration()) { uint64_t var_ptr_addr = - m_execution_engine_ap->getGlobalValueAddress(val.getName().str()); + m_execution_engine_up->getGlobalValueAddress(val.getName().str()); lldb::addr_t remote_addr = GetRemoteAddressForLocal(var_ptr_addr); @@ -407,7 +400,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, bool emitNewLine = false; - for (const ConstString &failed_lookup : m_failed_lookups) { + for (ConstString failed_lookup : m_failed_lookups) { if (emitNewLine) ss.PutCString("\n"); emitNewLine = true; @@ -489,13 +482,13 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, } IRExecutionUnit::~IRExecutionUnit() { - m_module_ap.reset(); - m_execution_engine_ap.reset(); - m_context_ap.reset(); + m_module_up.reset(); + m_execution_engine_up.reset(); + m_context_up.reset(); } IRExecutionUnit::MemoryManager::MemoryManager(IRExecutionUnit &parent) - : m_default_mm_ap(new llvm::SectionMemoryManager()), m_parent(parent) {} + : m_default_mm_up(new llvm::SectionMemoryManager()), m_parent(parent) {} IRExecutionUnit::MemoryManager::~MemoryManager() {} @@ -597,7 +590,7 @@ uint8_t *IRExecutionUnit::MemoryManager::allocateCodeSection( llvm::StringRef SectionName) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - uint8_t *return_value = m_default_mm_ap->allocateCodeSection( + uint8_t *return_value = m_default_mm_up->allocateCodeSection( Size, Alignment, SectionID, SectionName); m_parent.m_records.push_back(AllocationRecord( @@ -628,7 +621,7 @@ uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection( llvm::StringRef SectionName, bool IsReadOnly) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - uint8_t *return_value = m_default_mm_ap->allocateDataSection( + uint8_t *return_value = m_default_mm_up->allocateDataSection( Size, Alignment, SectionID, SectionName, IsReadOnly); uint32_t permissions = lldb::ePermissionsReadable; @@ -656,7 +649,7 @@ uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection( } static ConstString -FindBestAlternateMangledName(const ConstString &demangled, +FindBestAlternateMangledName(ConstString demangled, const lldb::LanguageType &lang_type, const SymbolContext &sym_ctx) { CPlusPlusLanguage::MethodName cpp_name(demangled); @@ -718,7 +711,7 @@ struct IRExecutionUnit::SearchSpec { void IRExecutionUnit::CollectCandidateCNames( std::vector<IRExecutionUnit::SearchSpec> &C_specs, - const ConstString &name) { + ConstString name) { if (m_strip_underscore && name.AsCString()[0] == '_') C_specs.insert(C_specs.begin(), ConstString(&name.AsCString()[1])); C_specs.push_back(SearchSpec(name)); @@ -728,7 +721,7 @@ void IRExecutionUnit::CollectCandidateCPlusPlusNames( std::vector<IRExecutionUnit::SearchSpec> &CPP_specs, const std::vector<SearchSpec> &C_specs, const SymbolContext &sc) { for (const SearchSpec &C_spec : C_specs) { - const ConstString &name = C_spec.name; + ConstString name = C_spec.name; if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) { Mangled mangled(name, true); @@ -760,7 +753,7 @@ void IRExecutionUnit::CollectFallbackNames( // but the DWARF doesn't always encode "extern C" correctly. for (const SearchSpec &C_spec : C_specs) { - const ConstString &name = C_spec.name; + ConstString name = C_spec.name; if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) { Mangled mangled_name(name); @@ -781,7 +774,9 @@ void IRExecutionUnit::CollectFallbackNames( lldb::addr_t IRExecutionUnit::FindInSymbols( const std::vector<IRExecutionUnit::SearchSpec> &specs, - const lldb_private::SymbolContext &sc) { + const lldb_private::SymbolContext &sc, + bool &symbol_was_missing_weak) { + symbol_was_missing_weak = false; Target *target = sc.target_sp.get(); if (!target) { @@ -796,16 +791,26 @@ lldb::addr_t IRExecutionUnit::FindInSymbols( std::function<bool(lldb::addr_t &, SymbolContextList &, const lldb_private::SymbolContext &)> - get_external_load_address = [&best_internal_load_address, target]( + get_external_load_address = [&best_internal_load_address, target, + &symbol_was_missing_weak]( lldb::addr_t &load_address, SymbolContextList &sc_list, const lldb_private::SymbolContext &sc) -> lldb::addr_t { load_address = LLDB_INVALID_ADDRESS; - for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si) { - SymbolContext candidate_sc; - - sc_list.GetContextAtIndex(si, candidate_sc); - + if (sc_list.GetSize() == 0) + return false; + + // missing_weak_symbol will be true only if we found only weak undefined + // references to this symbol. + symbol_was_missing_weak = true; + for (auto candidate_sc : sc_list.SymbolContexts()) { + // Only symbols can be weak undefined: + if (!candidate_sc.symbol) + symbol_was_missing_weak = false; + else if (candidate_sc.symbol->GetType() != lldb::eSymbolTypeUndefined + || !candidate_sc.symbol->IsWeak()) + symbol_was_missing_weak = false; + const bool is_external = (candidate_sc.function) || (candidate_sc.symbol && candidate_sc.symbol->IsExternal()); @@ -842,11 +847,18 @@ lldb::addr_t IRExecutionUnit::FindInSymbols( } } + // You test the address of a weak symbol against NULL to see if it is + // present. So we should return 0 for a missing weak symbol. + if (symbol_was_missing_weak) { + load_address = 0; + return true; + } + return false; }; if (sc.module_sp) { - sc.module_sp->FindFunctions(spec.name, NULL, spec.mask, + sc.module_sp->FindFunctions(spec.name, nullptr, spec.mask, true, // include_symbols false, // include_inlines true, // append @@ -909,10 +921,8 @@ IRExecutionUnit::FindInRuntimes(const std::vector<SearchSpec> &specs, return LLDB_INVALID_ADDRESS; } - ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime(); - - if (runtime) { - for (const SearchSpec &spec : specs) { + for (const SearchSpec &spec : specs) { + for (LanguageRuntime *runtime : process_sp->GetLanguageRuntimes()) { lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(spec.name); if (symbol_load_addr != LLDB_INVALID_ADDRESS) @@ -939,31 +949,37 @@ lldb::addr_t IRExecutionUnit::FindInUserDefinedSymbols( } lldb::addr_t -IRExecutionUnit::FindSymbol(const lldb_private::ConstString &name) { +IRExecutionUnit::FindSymbol(lldb_private::ConstString name, bool &missing_weak) { std::vector<SearchSpec> candidate_C_names; std::vector<SearchSpec> candidate_CPlusPlus_names; CollectCandidateCNames(candidate_C_names, name); + + lldb::addr_t ret = FindInSymbols(candidate_C_names, m_sym_ctx, missing_weak); + if (ret != LLDB_INVALID_ADDRESS) + return ret; + + // If we find the symbol in runtimes or user defined symbols it can't be + // a missing weak symbol. + missing_weak = false; + ret = FindInRuntimes(candidate_C_names, m_sym_ctx); + if (ret != LLDB_INVALID_ADDRESS) + return ret; - lldb::addr_t ret = FindInSymbols(candidate_C_names, m_sym_ctx); - if (ret == LLDB_INVALID_ADDRESS) - ret = FindInRuntimes(candidate_C_names, m_sym_ctx); + ret = FindInUserDefinedSymbols(candidate_C_names, m_sym_ctx); + if (ret != LLDB_INVALID_ADDRESS) + return ret; - if (ret == LLDB_INVALID_ADDRESS) - ret = FindInUserDefinedSymbols(candidate_C_names, m_sym_ctx); + CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names, + m_sym_ctx); + ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx, missing_weak); + if (ret != LLDB_INVALID_ADDRESS) + return ret; - if (ret == LLDB_INVALID_ADDRESS) { - CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names, - m_sym_ctx); - ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx); - } + std::vector<SearchSpec> candidate_fallback_names; - if (ret == LLDB_INVALID_ADDRESS) { - std::vector<SearchSpec> candidate_fallback_names; - - CollectFallbackNames(candidate_fallback_names, candidate_C_names); - ret = FindInSymbols(candidate_fallback_names, m_sym_ctx); - } + CollectFallbackNames(candidate_fallback_names, candidate_C_names); + ret = FindInSymbols(candidate_fallback_names, m_sym_ctx, missing_weak); return ret; } @@ -998,13 +1014,32 @@ void IRExecutionUnit::GetStaticInitializers( } } +llvm::JITSymbol +IRExecutionUnit::MemoryManager::findSymbol(const std::string &Name) { + bool missing_weak = false; + uint64_t addr = GetSymbolAddressAndPresence(Name, missing_weak); + // This is a weak symbol: + if (missing_weak) + return llvm::JITSymbol(addr, + llvm::JITSymbolFlags::Exported | llvm::JITSymbolFlags::Weak); + else + return llvm::JITSymbol(addr, llvm::JITSymbolFlags::Exported); +} + uint64_t IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name) { + bool missing_weak = false; + return GetSymbolAddressAndPresence(Name, missing_weak); +} + +uint64_t +IRExecutionUnit::MemoryManager::GetSymbolAddressAndPresence( + const std::string &Name, bool &missing_weak) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); ConstString name_cs(Name.c_str()); - lldb::addr_t ret = m_parent.FindSymbol(name_cs); + lldb::addr_t ret = m_parent.FindSymbol(name_cs, missing_weak); if (ret == LLDB_INVALID_ADDRESS) { if (log) @@ -1024,8 +1059,6 @@ IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name) { void *IRExecutionUnit::MemoryManager::getPointerToNamedFunction( const std::string &Name, bool AbortOnFailure) { - assert(sizeof(void *) == 8); - return (void *)getSymbolAddress(Name); } |