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,48 @@ EXPECT_EQ(E2->getOffset(), 4U); } } + +struct InitSymbolsTestParams { + InitSymbolsTestParams(StringRef Triple, StringRef Section, + bool ExpectedHasInitializerSection) + : Triple(Triple), Section(Section), + ExpectedHasInitializerSection(ExpectedHasInitializerSection) {} + + StringRef Triple; + StringRef Section; + bool ExpectedHasInitializerSection; +}; + +class InitSymbolsTestFixture + : public ::testing::TestWithParam {}; + +TEST_P(InitSymbolsTestFixture, InitSymbolSections) { + InitSymbolsTestParams Params = GetParam(); + auto Graph = std::make_unique( + "foo", Triple(Params.Triple), 8, support::little, getGenericEdgeKindName); + Graph->createSection(Params.Section, + orc::MemProt::Read | orc::MemProt::Write); + EXPECT_EQ(orc::hasInitializerSection(*Graph), + Params.ExpectedHasInitializerSection); +} + +INSTANTIATE_TEST_SUITE_P( + InitSymbolsTests, InitSymbolsTestFixture, + ::testing::Values( + InitSymbolsTestParams("x86_64-apple-darwin", "__DATA,__objc_selrefs", + true), + InitSymbolsTestParams("x86_64-apple-darwin", "__DATA,__mod_init_func", + true), + InitSymbolsTestParams("x86_64-apple-darwin", "__DATA,__objc_classlist", + true), + InitSymbolsTestParams("x86_64-apple-darwin", "__TEXT,__swift5_proto", + true), + InitSymbolsTestParams("x86_64-apple-darwin", "__TEXT,__swift5_protos", + true), + InitSymbolsTestParams("x86_64-apple-darwin", "__TEXT,__swift5_types", + true), + InitSymbolsTestParams("x86_64-apple-darwin", "__DATA,__not_an_init_sec", + false), + InitSymbolsTestParams("x86_64-unknown-linux", ".init_array", true), + InitSymbolsTestParams("x86_64-unknown-linux", ".init_array.0", true), + InitSymbolsTestParams("x86_64-unknown-linux", ".text", false)));