summaryrefslogtreecommitdiff
path: root/source/Expression/IRExecutionUnit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Expression/IRExecutionUnit.cpp')
-rw-r--r--source/Expression/IRExecutionUnit.cpp193
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);
}