[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