[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