diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectFileInterface.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectFileInterface.h --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectFileInterface.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectFileInterface.h @@ -32,6 +32,8 @@ Expected getObjectFileInterface(ExecutionSession &ES, MemoryBufferRef ObjBuffer); +bool hasInitializerSection(jitlink::LinkGraph &G); + } // End namespace orc } // End namespace llvm diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp --- a/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp @@ -287,5 +287,22 @@ return getGenericObjectFileSymbolInfo(ES, **Obj); } +bool hasInitializerSection(jitlink::LinkGraph &G) { + bool IsMachO = G.getTargetTriple().isOSBinFormatMachO(); + bool IsElf = G.getTargetTriple().isOSBinFormatELF(); + if (!IsMachO && !IsElf) + return false; + + for (auto &Sec : G.sections()) { + if (IsMachO && std::apply(MachOPlatform::isInitializerSection, + Sec.getName().split(","))) + return true; + if (IsElf && ELFNixPlatform::isInitializerSection(Sec.getName())) + return true; + } + + return false; +} + } // End namespace orc. } // End namespace llvm. diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp --- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp @@ -9,6 +9,7 @@ #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" #include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h" +#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h" #include "llvm/Support/MemoryBuffer.h" #include #include @@ -57,35 +58,12 @@ LGI.SymbolFlags[ES.intern(Sym->getName())] = Flags; } - if ((G.getTargetTriple().isOSBinFormatMachO() && hasMachOInitSection(G)) || - (G.getTargetTriple().isOSBinFormatELF() && hasELFInitSection(G))) + if (hasInitializerSection(G)) LGI.InitSymbol = makeInitSymbol(ES, G); return LGI; } - static bool hasMachOInitSection(LinkGraph &G) { - for (auto &Sec : G.sections()) - if (Sec.getName() == "__DATA,__objc_selrefs" || - Sec.getName() == "__DATA,__objc_classlist" || - Sec.getName() == "__TEXT,__swift5_protos" || - Sec.getName() == "__TEXT,__swift5_proto" || - Sec.getName() == "__TEXT,__swift5_types" || - Sec.getName() == "__DATA,__mod_init_func") - return true; - return false; - } - - static bool hasELFInitSection(LinkGraph &G) { - for (auto &Sec : G.sections()) { - auto SecName = Sec.getName(); - if (SecName.consume_front(".init_array") && - (SecName.empty() || SecName[0] == '.')) - return true; - } - return false; - } - static SymbolStringPtr makeInitSymbol(ExecutionSession &ES, LinkGraph &G) { std::string InitSymString; raw_string_ostream(InitSymString) diff --git a/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt b/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt --- a/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt +++ b/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt @@ -2,6 +2,7 @@ ${LLVM_TARGETS_TO_BUILD} JITLink Object + OrcJIT OrcShared OrcTargetProcess RuntimeDyld diff --git a/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp --- a/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp +++ b/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp @@ -8,6 +8,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ExecutionEngine/JITLink/JITLink.h" +#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Memory.h" @@ -710,3 +711,39 @@ EXPECT_EQ(E2->getOffset(), 4U); } } +TEST(LinkGraphTest, InitSymbolSections) { + { + auto Graph = + std::make_unique("foo", Triple("x86_64-apple-darwin"), 8, + support::little, getGenericEdgeKindName); + Graph->createSection("__DATA,__objc_selrefs", + orc::MemProt::Read | orc::MemProt::Write); + EXPECT_TRUE(orc::hasInitializerSection(*Graph)); + } + + { + auto Graph = + std::make_unique("foo", Triple("x86_64-apple-darwin"), 8, + support::little, getGenericEdgeKindName); + Graph->createSection("__DATA,__not_an_init_sec", + orc::MemProt::Read | orc::MemProt::Write); + EXPECT_FALSE(orc::hasInitializerSection(*Graph)); + } + + { + auto Graph = + std::make_unique("foo", Triple("x86_64-unknown-linnx"), 8, + support::little, getGenericEdgeKindName); + Graph->createSection(".init_array", + orc::MemProt::Read | orc::MemProt::Write); + EXPECT_TRUE(orc::hasInitializerSection(*Graph)); + } + + { + auto Graph = + std::make_unique("foo", Triple("x86_64-unknown-linnx"), 8, + support::little, getGenericEdgeKindName); + Graph->createSection(".text", orc::MemProt::Read | orc::MemProt::Write); + EXPECT_FALSE(orc::hasInitializerSection(*Graph)); + } +}