diff --git a/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp b/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp index e0901186347..7c60d516771 100644 --- a/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp +++ b/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/test/ExecutionEngine/JITLink/X86/Inputs/MachO_test_harness_test.s b/test/ExecutionEngine/JITLink/X86/Inputs/MachO_test_harness_test.s index 3ca616a4a72..337f467d096 100644 --- a/test/ExecutionEngine/JITLink/X86/Inputs/MachO_test_harness_test.s +++ b/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/test/ExecutionEngine/JITLink/X86/MachO_test_harness_harness.s b/test/ExecutionEngine/JITLink/X86/MachO_test_harness_harness.s index 7fdddf2a64c..ee510387b35 100644 --- a/test/ExecutionEngine/JITLink/X86/MachO_test_harness_harness.s +++ b/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/tools/llvm-jitlink/llvm-jitlink.cpp b/tools/llvm-jitlink/llvm-jitlink.cpp index 22d29c12e19..798087d8cae 100644 --- a/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/tools/llvm-jitlink/llvm-jitlink.cpp @@ -132,6 +132,11 @@ static cl::opt ShowRelocatedSectionContents( cl::desc("show section contents after fixups have been applied"), cl::init(false)); +static cl::opt 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 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> Session::Create(Triple TT) { Error Err = Error::success(); std::unique_ptr 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()); +} + Error loadObjects(Session &S) { std::map 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));