[llvm] 0f5b707 - [llvm-jitlink] Add -phony-externals option to suppress unresolved externals.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 1 18:33:57 PDT 2020
Author: Lang Hames
Date: 2020-08-01T18:33:44-07:00
New Revision: 0f5b70769d15d8cc728dcba353a33fb459450381
URL: https://github.com/llvm/llvm-project/commit/0f5b70769d15d8cc728dcba353a33fb459450381
DIFF: https://github.com/llvm/llvm-project/commit/0f5b70769d15d8cc728dcba353a33fb459450381.diff
LOG: [llvm-jitlink] Add -phony-externals option to suppress unresolved externals.
The -phony-externals option adds a generator which explicitly defines any
otherwise unresolved externals as null. This transforms link-time
unresolved-symbol errors into potential runtime null pointer accesses
(if an unresolved external is actually accessed during execution).
This option can be useful in -harness mode to avoid having to mock a
large number of symbols that are not reachable at runtime (e.g. unused
methods referenced by a class vtable).
Added:
Modified:
llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_test_harness_test.s
llvm/test/ExecutionEngine/JITLink/X86/MachO_test_harness_harness.s
llvm/tools/llvm-jitlink/llvm-jitlink.cpp
Removed:
################################################################################
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
index e0901186347f..7c60d5167718 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
@@ -337,12 +337,6 @@ void JITLinkerBase::applyLookupResult(AsyncLookupResult Result) {
dbgs() << " " << Sym->getName() << ": "
<< formatv("{0:x16}", Sym->getAddress()) << "\n";
});
- assert(llvm::all_of(G->external_symbols(),
- [](Symbol *Sym) {
- return Sym->getAddress() != 0 ||
- Sym->getLinkage() == Linkage::Weak;
- }) &&
- "All strong external symbols should have been resolved by now");
}
void JITLinkerBase::copyBlockContentToWorkingMemory(
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_test_harness_test.s b/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_test_harness_test.s
index 3ca616a4a729..337f467d0967 100644
--- a/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_test_harness_test.s
+++ b/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_test_harness_test.s
@@ -27,6 +27,7 @@ _used_weak:
.p2align 4, 0x90
_public_func_to_test:
callq _used_weak
+ callq _used_unresolved_external
jmp _public_func_to_interpose
.p2align 4, 0x90
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_test_harness_harness.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_test_harness_harness.s
index 7fdddf2a64ca..ee510387b35f 100644
--- a/llvm/test/ExecutionEngine/JITLink/X86/MachO_test_harness_harness.s
+++ b/llvm/test/ExecutionEngine/JITLink/X86/MachO_test_harness_harness.s
@@ -3,7 +3,9 @@
# RUN: -o %t/file_to_test.o %S/Inputs/MachO_test_harness_test.s
# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj \
# RUN: -o %t/test_harness.o %s
-# RUN: llvm-jitlink -noexec -check %s %t/file_to_test.o \
+# RUN: not llvm-jitlink -noexec -check %s %t/file_to_test.o \
+# RUN: -harness %t/test_harness.o
+# RUN: llvm-jitlink -noexec -phony-externals -check %s %t/file_to_test.o \
# RUN: -harness %t/test_harness.o
#
# Check that we
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 22d29c12e192..798087d8cae7 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -132,6 +132,11 @@ static cl::opt<bool> ShowRelocatedSectionContents(
cl::desc("show section contents after fixups have been applied"),
cl::init(false));
+static cl::opt<bool> PhonyExternals(
+ "phony-externals",
+ cl::desc("resolve all otherwise unresolved externals to null"),
+ cl::init(false));
+
ExitOnError ExitOnErr;
namespace llvm {
@@ -179,9 +184,9 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
LLVM_DEBUG(dbgs() << "Appling promotions to graph " << G.getName() << "\n");
- // If it isn't then promote any symbols referenced by the harness to default
- // scope, remove all symbols that clash with harness definitions, and demote
- // all others.
+ // If this graph is part of the test then promote any symbols referenced by
+ // the harness to default scope, remove all symbols that clash with harness
+ // definitions, demote all other definitions.
std::vector<Symbol *> DefinitionsToRemove;
for (auto *Sym : G.defined_symbols()) {
@@ -560,6 +565,18 @@ Error LLVMJITLinkObjectLinkingLayer::add(JITDylib &JD,
return JD.define(std::move(MU));
}
+class PhonyExternalsGenerator : public JITDylib::DefinitionGenerator {
+public:
+ Error tryToGenerate(LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &LookupSet) override {
+ SymbolMap PhonySymbols;
+ for (auto &KV : LookupSet)
+ PhonySymbols[KV.first] = JITEvaluatedSymbol(0, JITSymbolFlags::Exported);
+ return JD.define(absoluteSymbols(std::move(PhonySymbols)));
+ }
+};
+
Expected<std::unique_ptr<Session>> Session::Create(Triple TT) {
Error Err = Error::success();
std::unique_ptr<Session> S(new Session(std::move(TT), Err));
@@ -813,6 +830,10 @@ Error loadDylibs() {
return Error::success();
}
+void addPhonyExternalsGenerator(Session &S) {
+ S.MainJD->addGenerator(std::make_unique<PhonyExternalsGenerator>());
+}
+
Error loadObjects(Session &S) {
std::map<unsigned, JITDylib *> IdxToJLD;
@@ -1039,6 +1060,9 @@ int main(int argc, char *argv[]) {
ExitOnErr(loadProcessSymbols(*S));
ExitOnErr(loadDylibs());
+ if (PhonyExternals)
+ addPhonyExternalsGenerator(*S);
+
{
TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
ExitOnErr(loadObjects(*S));
More information about the llvm-commits
mailing list