[llvm] 410e0aa - [JITLink][COFF] Implement dllimport stubs.

Sunho Kim via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 29 00:30:01 PDT 2022


Author: Sunho Kim
Date: 2022-07-29T16:29:53+09:00
New Revision: 410e0aa759ac4ccc6b939e01bf26dba772cc2571

URL: https://github.com/llvm/llvm-project/commit/410e0aa759ac4ccc6b939e01bf26dba772cc2571
DIFF: https://github.com/llvm/llvm-project/commit/410e0aa759ac4ccc6b939e01bf26dba772cc2571.diff

LOG: [JITLink][COFF] Implement dllimport stubs.

Implements dllimport stubs using GOT table manager. Benefit of using GOT table manager is that we can just reuse jitlink-check architecture.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D130175

Added: 
    

Modified: 
    llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
    llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
    llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
    llvm/test/ExecutionEngine/JITLink/X86/COFF_x86-64_small_pic_relocations.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
index 3a6162db75c4..8fd644d3c3b0 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
@@ -144,7 +144,7 @@ Error COFFLinkGraphBuilder::graphifySections() {
     // FIXME: Revisit crash when dropping IMAGE_SCN_MEM_DISCARDABLE sections
 
     // Get the section's memory protection flags.
-    MemProt Prot = MemProt::None;
+    MemProt Prot = MemProt::Read;
     if ((*Sec)->Characteristics & COFF::IMAGE_SCN_MEM_EXECUTE)
       Prot |= MemProt::Exec;
     if ((*Sec)->Characteristics & COFF::IMAGE_SCN_MEM_READ)
@@ -224,17 +224,30 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
                << " (index: " << SectionIndex << ") \n";
       });
     else if (Sym->isUndefined()) {
-      LLVM_DEBUG({
-        dbgs() << "    " << SymIndex
-               << ": Creating external graph symbol for COFF symbol \""
-               << SymbolName << "\" in "
-               << getCOFFSectionName(SectionIndex, Sec, *Sym)
-               << " (index: " << SectionIndex << ") \n";
-      });
-      if (!ExternalSymbols.count(SymbolName))
-        ExternalSymbols[SymbolName] =
-            &G->addExternalSymbol(SymbolName, Sym->getValue(), Linkage::Strong);
-      GSym = ExternalSymbols[SymbolName];
+      auto CreateExternalSymbol = [&](StringRef SymbolName) {
+        if (!ExternalSymbols.count(SymbolName))
+          ExternalSymbols[SymbolName] = &G->addExternalSymbol(
+              SymbolName, Sym->getValue(), Linkage::Strong);
+
+        LLVM_DEBUG({
+          dbgs() << "    " << SymIndex
+                 << ": Creating external graph symbol for COFF symbol \""
+                 << SymbolName << "\" in "
+                 << getCOFFSectionName(SectionIndex, Sec, *Sym)
+                 << " (index: " << SectionIndex << ") \n";
+        });
+        return ExternalSymbols[SymbolName];
+      };
+      if (SymbolName.startswith(getDLLImportStubPrefix())) {
+        if (Sym->getValue() != 0)
+          return make_error<JITLinkError>(
+              "DLL import symbol has non-zero offset");
+
+        auto ExternalSym = CreateExternalSymbol(
+            SymbolName.drop_front(getDLLImportStubPrefix().size()));
+        GSym = &createDLLImportEntry(SymbolName, *ExternalSym);
+      } else
+        GSym = CreateExternalSymbol(SymbolName);
     } else if (Sym->isWeakExternal()) {
       auto *WeakExternal = Sym->getAux<object::coff_aux_weak_external>();
       COFFSymbolIndex TagIndex = WeakExternal->TagIndex;

diff  --git a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
index f925f6d7aeef..a571e5e6f4fe 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
@@ -45,6 +45,7 @@ class COFFLinkGraphBuilder {
   const object::COFFObjectFile &getObject() const { return Obj; }
 
   virtual Error addRelocations() = 0;
+  virtual Symbol &createDLLImportEntry(StringRef StubName, Symbol &Target) = 0;
 
   Error graphifySections();
   Error graphifySymbols();
@@ -152,6 +153,7 @@ class COFFLinkGraphBuilder {
   static bool isComdatSection(const object::coff_section *Section);
   static unsigned getPointerSize(const object::COFFObjectFile &Obj);
   static support::endianness getEndianness(const object::COFFObjectFile &Obj);
+  static StringRef getDLLImportStubPrefix() { return "__imp_"; }
   StringRef getCOFFSectionName(COFFSectionIndex SectionIndex,
                                const object::coff_section *Sec,
                                object::COFFSymbolRef Sym);

diff  --git a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
index e2040dc95acc..1ff64badc887 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
@@ -59,6 +59,12 @@ class COFFLinkGraphBuilder_x86_64 : public COFFLinkGraphBuilder {
     return Error::success();
   }
 
+  Symbol &createDLLImportEntry(StringRef StubName, Symbol &Target) override {
+    auto &Sym = DLLImportTable.getEntryForTarget(getGraph(), Target);
+    Sym.setName(StubName);
+    return Sym;
+  }
+
   Error addSingleRelocation(const object::RelocationRef &Rel,
                             const object::SectionRef &FixupSect,
                             Block &BlockToFix) {
@@ -126,6 +132,8 @@ class COFFLinkGraphBuilder_x86_64 : public COFFLinkGraphBuilder {
     return Error::success();
   }
 
+  x86_64::GOTTableManager DLLImportTable;
+
 public:
   COFFLinkGraphBuilder_x86_64(const object::COFFObjectFile &Obj, const Triple T)
       : COFFLinkGraphBuilder(Obj, std::move(T), getCOFFX86RelocationKindName) {}

diff  --git a/llvm/test/ExecutionEngine/JITLink/X86/COFF_x86-64_small_pic_relocations.s b/llvm/test/ExecutionEngine/JITLink/X86/COFF_x86-64_small_pic_relocations.s
index ae9bf1f423de..60bad11803eb 100644
--- a/llvm/test/ExecutionEngine/JITLink/X86/COFF_x86-64_small_pic_relocations.s
+++ b/llvm/test/ExecutionEngine/JITLink/X86/COFF_x86-64_small_pic_relocations.s
@@ -40,6 +40,21 @@ test_rel32_func:
 test_rel32_data:
     leaq named_data(%rip), %rax
 
+# Check a dllimport stub for target out of reach is created as a GOT entry.
+# jitlink-check: decode_operand(test_call_dllimport, 3) = \
+# jitlink-check:     got_addr(coff_sm_reloc.o, extern_out_of_range32) - \
+# jitlink-check:        next_pc(test_call_dllimport)
+# jitlink-check: *{8}(got_addr(coff_sm_reloc.o, extern_out_of_range32)) = \
+# jitlink-check:     extern_out_of_range32
+	.def test_call_dllimport;
+	.scl 2;
+	.type 32;
+	.endef
+	.globl test_call_dllimport
+	.p2align 4, 0x90
+test_call_dllimport:
+	callq	*__imp_extern_out_of_range32(%rip)
+
 # Local named data/func that is used in conjunction with other test cases
 	.text
 	.def named_func;


        


More information about the llvm-commits mailing list