[llvm] 3b64052 - [ORC] Fix some bugs in TPCDynamicLibrarySearchGenerator, use in llvm-jitlink.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 4 13:24:18 PDT 2020
Author: Lang Hames
Date: 2020-09-04T13:23:52-07:00
New Revision: 3b64052a2572e69355969a59a0c4c8aba4fee887
URL: https://github.com/llvm/llvm-project/commit/3b64052a2572e69355969a59a0c4c8aba4fee887
DIFF: https://github.com/llvm/llvm-project/commit/3b64052a2572e69355969a59a0c4c8aba4fee887.diff
LOG: [ORC] Fix some bugs in TPCDynamicLibrarySearchGenerator, use in llvm-jitlink.
TPCDynamicLibrarySearchGenerator was generating errors on missing
symbols, but that doesn't fit the DefinitionGenerator contract: A symbol
that isn't generated by a particular generator should not cause an
error.
This commit fixes the error by using SymbolLookupFlags::WeaklyReferencedSymbol
for all elements of the lookup, and switches llvm-jitlink to use
TPCDynamicLibrarySearchGenerator.
Added:
Modified:
llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
llvm/lib/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.cpp
llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp
llvm/tools/llvm-jitlink/llvm-jitlink.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h b/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
index d35c8abc84a2..7c1b72befde7 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
@@ -14,6 +14,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
#define LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
+#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
namespace llvm {
@@ -21,6 +22,8 @@ namespace orc {
class TPCDynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator {
public:
+ using SymbolPredicate = unique_function<bool(const SymbolStringPtr &)>;
+
/// Create a DynamicLibrarySearchGenerator that searches for symbols in the
/// library with the given handle.
///
@@ -28,19 +31,22 @@ class TPCDynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator {
/// will be searched for. If the predicate is not given then all symbols will
/// be searched for.
TPCDynamicLibrarySearchGenerator(TargetProcessControl &TPC,
- TargetProcessControl::DylibHandle H)
- : TPC(TPC), H(H) {}
+ TargetProcessControl::DylibHandle H,
+ SymbolPredicate Allow = SymbolPredicate())
+ : TPC(TPC), H(H), Allow(std::move(Allow)) {}
/// Permanently loads the library at the given path and, on success, returns
/// a DynamicLibrarySearchGenerator that will search it for symbol definitions
/// in the library. On failure returns the reason the library failed to load.
static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
- Load(TargetProcessControl &TPC, const char *LibraryPath);
+ Load(TargetProcessControl &TPC, const char *LibraryPath,
+ SymbolPredicate Allow = SymbolPredicate());
/// Creates a TPCDynamicLibrarySearchGenerator that searches for symbols in
/// the target process.
static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
- GetForTargetProcess(TargetProcessControl &TPC) {
+ GetForTargetProcess(TargetProcessControl &TPC,
+ SymbolPredicate Allow = SymbolPredicate()) {
return Load(TPC, nullptr);
}
@@ -51,6 +57,7 @@ class TPCDynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator {
private:
TargetProcessControl &TPC;
TargetProcessControl::DylibHandle H;
+ SymbolPredicate Allow;
};
} // end namespace orc
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
index 159b6e8d56df..d3349753284e 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
@@ -149,8 +149,11 @@ class TargetProcessControl {
virtual Expected<DylibHandle> loadDylib(const char *DylibPath) = 0;
/// Search for symbols in the target process.
+ ///
/// The result of the lookup is a 2-dimentional array of target addresses
- /// that correspond to the lookup order.
+ /// that correspond to the lookup order. If a required symbol is not
+ /// found then this method will return an error. If a weakly referenced
+ /// symbol is not found then it be assigned a '0' value in the result.
virtual Expected<LookupResult> lookupSymbols(LookupRequest Request) = 0;
protected:
diff --git a/llvm/lib/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.cpp b/llvm/lib/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.cpp
index 18de5b616eec..d85f3c38feb9 100644
--- a/llvm/lib/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.cpp
@@ -13,12 +13,14 @@ namespace orc {
Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
TPCDynamicLibrarySearchGenerator::Load(TargetProcessControl &TPC,
- const char *LibraryPath) {
+ const char *LibraryPath,
+ SymbolPredicate Allow) {
auto Handle = TPC.loadDylib(LibraryPath);
if (!Handle)
return Handle.takeError();
- return std::make_unique<TPCDynamicLibrarySearchGenerator>(TPC, *Handle);
+ return std::make_unique<TPCDynamicLibrarySearchGenerator>(TPC, *Handle,
+ std::move(Allow));
}
Error TPCDynamicLibrarySearchGenerator::tryToGenerate(
@@ -28,22 +30,38 @@ Error TPCDynamicLibrarySearchGenerator::tryToGenerate(
if (Symbols.empty())
return Error::success();
+ SymbolLookupSet LookupSymbols;
+
+ for (auto &KV : Symbols) {
+ // Skip symbols that don't match the filter.
+ if (Allow && !Allow(KV.first))
+ continue;
+ LookupSymbols.add(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol);
+ }
+
SymbolMap NewSymbols;
- TargetProcessControl::LookupRequestElement Request(H, Symbols);
+ TargetProcessControl::LookupRequestElement Request(H, LookupSymbols);
auto Result = TPC.lookupSymbols(Request);
if (!Result)
return Result.takeError();
assert(Result->size() == 1 && "Results for more than one library returned");
- assert(Result->front().size() == Symbols.size() &&
+ assert(Result->front().size() == LookupSymbols.size() &&
"Result has incorrect number of elements");
+ SymbolNameVector MissingSymbols;
auto ResultI = Result->front().begin();
- for (auto &KV : Symbols)
- NewSymbols[KV.first] =
- JITEvaluatedSymbol(*ResultI++, JITSymbolFlags::Exported);
+ for (auto &KV : LookupSymbols)
+ if (*ResultI)
+ NewSymbols[KV.first] =
+ JITEvaluatedSymbol(*ResultI++, JITSymbolFlags::Exported);
+
+ // If there were no resolved symbols bail out.
+ if (NewSymbols.empty())
+ return Error::success();
+ // Define resolved symbols.
return JD.define(absoluteSymbols(std::move(NewSymbols)));
}
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp
index 59c9ce2393c9..1e7736d1f40d 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp
@@ -78,14 +78,14 @@ SelfTargetProcessControl::lookupSymbols(LookupRequest Request) {
auto &Sym = KV.first;
std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
(*Sym).size() - !!GlobalManglingPrefix);
- if (void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str()))
- R.back().push_back(pointerToJITTargetAddress(Addr));
- else if (KV.second == SymbolLookupFlags::RequiredSymbol) {
+ void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str());
+ if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol) {
// FIXME: Collect all failing symbols before erroring out.
SymbolNameVector MissingSymbols;
MissingSymbols.push_back(Sym);
return make_error<SymbolsNotFound>(std::move(MissingSymbols));
}
+ R.back().push_back(pointerToJITTargetAddress(Addr));
}
}
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index f1cc1f2550b3..a848bf029dbf 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -17,6 +17,7 @@
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
+#include "llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
@@ -30,7 +31,6 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Process.h"
@@ -802,19 +802,13 @@ Error sanitizeArguments(const Session &S) {
}
Error loadProcessSymbols(Session &S) {
- std::string ErrMsg;
- if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr, &ErrMsg))
- return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
-
- char GlobalPrefix =
- S.TPC->getTargetTriple().getObjectFormat() == Triple::MachO ? '_' : '\0';
auto InternedEntryPointName = S.ES.intern(EntryPointName);
auto FilterMainEntryPoint = [InternedEntryPointName](SymbolStringPtr Name) {
return Name != InternedEntryPointName;
};
S.MainJD->addGenerator(
- ExitOnErr(orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
- GlobalPrefix, FilterMainEntryPoint)));
+ ExitOnErr(orc::TPCDynamicLibrarySearchGenerator::GetForTargetProcess(
+ *S.TPC, std::move(FilterMainEntryPoint))));
return Error::success();
}
More information about the llvm-commits
mailing list