12e40cf06SLang Hames //===---- ELF_x86_64.cpp -JIT linker implementation for ELF/x86-64 ----===// 22e40cf06SLang Hames // 32e40cf06SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42e40cf06SLang Hames // See https://llvm.org/LICENSE.txt for license information. 52e40cf06SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62e40cf06SLang Hames // 72e40cf06SLang Hames //===----------------------------------------------------------------------===// 82e40cf06SLang Hames // 92e40cf06SLang Hames // ELF/x86-64 jit-link implementation. 102e40cf06SLang Hames // 112e40cf06SLang Hames //===----------------------------------------------------------------------===// 122e40cf06SLang Hames 132e40cf06SLang Hames #include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h" 14d46409fcSShubham Sandeep Rastogi #include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h" 152e40cf06SLang Hames #include "llvm/ExecutionEngine/JITLink/JITLink.h" 16bc03a9c0SLang Hames #include "llvm/ExecutionEngine/JITLink/TableManager.h" 17209ceed7SLang Hames #include "llvm/ExecutionEngine/JITLink/x86_64.h" 182e40cf06SLang Hames #include "llvm/Object/ELFObjectFile.h" 192e40cf06SLang Hames 200a74ec32SLang Hames #include "DefineExternalSectionStartAndEndSymbols.h" 21cda4d3d3SLang Hames #include "EHFrameSupportImpl.h" 22aff57ff2SLang Hames #include "ELFLinkGraphBuilder.h" 23cda4d3d3SLang Hames #include "JITLinkGeneric.h" 24cda4d3d3SLang Hames 252e40cf06SLang Hames #define DEBUG_TYPE "jitlink" 262e40cf06SLang Hames 272e40cf06SLang Hames using namespace llvm; 282e40cf06SLang Hames using namespace llvm::jitlink; 29ef454c54SJared Wyles 309a0689e0SBenjamin Kramer namespace { 31a817f46dSLang Hames 32cc4ad2c5SLang Hames constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_"; 33ff6069b8Sluxufan constexpr StringRef ELFTLSInfoSectionName = "$__TLSINFO"; 34ff6069b8Sluxufan 35849b36bfSluxufan class TLSInfoTableManager_ELF_x86_64 36849b36bfSluxufan : public TableManager<TLSInfoTableManager_ELF_x86_64> { 37849b36bfSluxufan public: 38849b36bfSluxufan static const uint8_t TLSInfoEntryContent[16]; 39849b36bfSluxufan 40cc3115cdSLang Hames static StringRef getSectionName() { return ELFTLSInfoSectionName; } 41849b36bfSluxufan 42bc03a9c0SLang Hames bool visitEdge(LinkGraph &G, Block *B, Edge &E) { 43849b36bfSluxufan if (E.getKind() == x86_64::RequestTLSDescInGOTAndTransformToDelta32) { 44849b36bfSluxufan LLVM_DEBUG({ 45849b36bfSluxufan dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at " 46849b36bfSluxufan << formatv("{0:x}", B->getFixupAddress(E)) << " (" 47849b36bfSluxufan << formatv("{0:x}", B->getAddress()) << " + " 48849b36bfSluxufan << formatv("{0:x}", E.getOffset()) << ")\n"; 49849b36bfSluxufan }); 50849b36bfSluxufan E.setKind(x86_64::Delta32); 51bc03a9c0SLang Hames E.setTarget(getEntryForTarget(G, E.getTarget())); 52849b36bfSluxufan return true; 53849b36bfSluxufan } 54849b36bfSluxufan return false; 55849b36bfSluxufan } 56849b36bfSluxufan 57849b36bfSluxufan Symbol &createEntry(LinkGraph &G, Symbol &Target) { 58849b36bfSluxufan // the TLS Info entry's key value will be written by the fixTLVSectionByName 59849b36bfSluxufan // pass, so create mutable content. 60849b36bfSluxufan auto &TLSInfoEntry = G.createMutableContentBlock( 61118e953bSLang Hames getTLSInfoSection(G), G.allocateContent(getTLSInfoEntryContent()), 62118e953bSLang Hames orc::ExecutorAddr(), 8, 0); 63849b36bfSluxufan TLSInfoEntry.addEdge(x86_64::Pointer64, 8, Target, 0); 64849b36bfSluxufan return G.addAnonymousSymbol(TLSInfoEntry, 0, 16, false, false); 65849b36bfSluxufan } 66849b36bfSluxufan 67849b36bfSluxufan private: 68849b36bfSluxufan Section &getTLSInfoSection(LinkGraph &G) { 69849b36bfSluxufan if (!TLSInfoTable) 70d3d9f7caSLang Hames TLSInfoTable = 71d3d9f7caSLang Hames &G.createSection(ELFTLSInfoSectionName, orc::MemProt::Read); 72849b36bfSluxufan return *TLSInfoTable; 73849b36bfSluxufan } 74849b36bfSluxufan 75849b36bfSluxufan ArrayRef<char> getTLSInfoEntryContent() const { 76849b36bfSluxufan return {reinterpret_cast<const char *>(TLSInfoEntryContent), 77849b36bfSluxufan sizeof(TLSInfoEntryContent)}; 78849b36bfSluxufan } 79849b36bfSluxufan 80849b36bfSluxufan Section *TLSInfoTable = nullptr; 81ef454c54SJared Wyles }; 82a817f46dSLang Hames 83849b36bfSluxufan const uint8_t TLSInfoTableManager_ELF_x86_64::TLSInfoEntryContent[16] = { 84849b36bfSluxufan 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*pthread key */ 85849b36bfSluxufan 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*data address*/ 86849b36bfSluxufan }; 872e40cf06SLang Hames 88849b36bfSluxufan Error buildTables_ELF_x86_64(LinkGraph &G) { 89849b36bfSluxufan LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n"); 90849b36bfSluxufan 91*8fb29ba2SLang Hames x86_64::GOTTableManager GOT(G); 92*8fb29ba2SLang Hames x86_64::PLTTableManager PLT(G, GOT); 93849b36bfSluxufan TLSInfoTableManager_ELF_x86_64 TLSInfo; 94849b36bfSluxufan visitExistingEdges(G, GOT, PLT, TLSInfo); 95849b36bfSluxufan return Error::success(); 96849b36bfSluxufan } 97849b36bfSluxufan } // namespace 98b384736bSluxufan 992e40cf06SLang Hames namespace llvm { 1002e40cf06SLang Hames namespace jitlink { 1013f0841f6SJared Wyles 102aff57ff2SLang Hames class ELFLinkGraphBuilder_x86_64 : public ELFLinkGraphBuilder<object::ELF64LE> { 1032e40cf06SLang Hames private: 10468914dc9SStefan Gränitz using ELFT = object::ELF64LE; 1052e40cf06SLang Hames 1068e66fc43SLang Hames Error addRelocations() override { 10768914dc9SStefan Gränitz LLVM_DEBUG(dbgs() << "Processing relocations:\n"); 1083f0841f6SJared Wyles 10968914dc9SStefan Gränitz using Base = ELFLinkGraphBuilder<ELFT>; 11068914dc9SStefan Gränitz using Self = ELFLinkGraphBuilder_x86_64; 11168914dc9SStefan Gränitz for (const auto &RelSect : Base::Sections) { 11259c84774SZarko Todorovski // Validate the section to read relocation entries from. 11368914dc9SStefan Gränitz if (RelSect.sh_type == ELF::SHT_REL) 11468914dc9SStefan Gränitz return make_error<StringError>( 11568914dc9SStefan Gränitz "No SHT_REL in valid x64 ELF object files", 11668914dc9SStefan Gränitz inconvertibleErrorCode()); 117a817f46dSLang Hames 1182a3b257aSKshitij Jain if (Error Err = Base::forEachRelaRelocation(RelSect, this, 11968914dc9SStefan Gränitz &Self::addSingleRelocation)) 12068914dc9SStefan Gränitz return Err; 121ef454c54SJared Wyles } 1223f0841f6SJared Wyles 12368914dc9SStefan Gränitz return Error::success(); 12468914dc9SStefan Gränitz } 12568914dc9SStefan Gränitz 12668914dc9SStefan Gränitz Error addSingleRelocation(const typename ELFT::Rela &Rel, 12768914dc9SStefan Gränitz const typename ELFT::Shdr &FixupSection, 128091e3648SSteven Wu Block &BlockToFix) { 12968914dc9SStefan Gränitz using Base = ELFLinkGraphBuilder<ELFT>; 13068914dc9SStefan Gränitz 1318308e81bSLang Hames auto ELFReloc = Rel.getType(false); 1328308e81bSLang Hames 1338308e81bSLang Hames // R_X86_64_NONE is a no-op. 1348308e81bSLang Hames if (LLVM_UNLIKELY(ELFReloc == ELF::R_X86_64_NONE)) 1358308e81bSLang Hames return Error::success(); 1368308e81bSLang Hames 13768914dc9SStefan Gränitz uint32_t SymbolIndex = Rel.getSymbol(false); 13868914dc9SStefan Gränitz auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec); 13968914dc9SStefan Gränitz if (!ObjSymbol) 14068914dc9SStefan Gränitz return ObjSymbol.takeError(); 14168914dc9SStefan Gränitz 14268914dc9SStefan Gränitz Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex); 14368914dc9SStefan Gränitz if (!GraphSymbol) 14468914dc9SStefan Gränitz return make_error<StringError>( 14568914dc9SStefan Gränitz formatv("Could not find symbol at given index, did you add it to " 14668914dc9SStefan Gränitz "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}", 14768914dc9SStefan Gränitz SymbolIndex, (*ObjSymbol)->st_shndx, 14868914dc9SStefan Gränitz Base::GraphSymbols.size()), 14968914dc9SStefan Gränitz inconvertibleErrorCode()); 15068914dc9SStefan Gränitz 15159c84774SZarko Todorovski // Validate the relocation kind. 15268914dc9SStefan Gränitz int64_t Addend = Rel.r_addend; 153ee659383Sluxufan Edge::Kind Kind = Edge::Invalid; 154d3df7b15SLang Hames 155d3df7b15SLang Hames switch (ELFReloc) { 156ae6f730bSMaksim Panchenko case ELF::R_X86_64_PC8: 157ae6f730bSMaksim Panchenko Kind = x86_64::Delta8; 158ae6f730bSMaksim Panchenko break; 15957bee1e4SXing Guo case ELF::R_X86_64_PC16: 16057bee1e4SXing Guo Kind = x86_64::Delta16; 16157bee1e4SXing Guo break; 162d3df7b15SLang Hames case ELF::R_X86_64_PC32: 163e4b6e686SLang Hames case ELF::R_X86_64_GOTPC32: 164ee659383Sluxufan Kind = x86_64::Delta32; 165ee659383Sluxufan break; 166d3df7b15SLang Hames case ELF::R_X86_64_PC64: 167d3df7b15SLang Hames case ELF::R_X86_64_GOTPC64: 168ee659383Sluxufan Kind = x86_64::Delta64; 169ee659383Sluxufan break; 170d3df7b15SLang Hames case ELF::R_X86_64_32: 171ede78c17SLang Hames Kind = x86_64::Pointer32; 172ede78c17SLang Hames break; 173ad7ab8f4SLang Hames case ELF::R_X86_64_16: 174ad7ab8f4SLang Hames Kind = x86_64::Pointer16; 175ad7ab8f4SLang Hames break; 1769ee16eb5SLang Hames case ELF::R_X86_64_8: 1779ee16eb5SLang Hames Kind = x86_64::Pointer8; 1789ee16eb5SLang Hames break; 179d3df7b15SLang Hames case ELF::R_X86_64_32S: 180dda116bcSluxufan Kind = x86_64::Pointer32Signed; 181dda116bcSluxufan break; 182d3df7b15SLang Hames case ELF::R_X86_64_64: 183ee659383Sluxufan Kind = x86_64::Pointer64; 184ee659383Sluxufan break; 185210140abSXing Guo case ELF::R_X86_64_SIZE32: 186210140abSXing Guo Kind = x86_64::Size32; 187210140abSXing Guo break; 188210140abSXing Guo case ELF::R_X86_64_SIZE64: 189210140abSXing Guo Kind = x86_64::Size64; 190210140abSXing Guo break; 191d3df7b15SLang Hames case ELF::R_X86_64_GOTPCREL: 192a9095f00Sluxufan Kind = x86_64::RequestGOTAndTransformToDelta32; 193a9095f00Sluxufan break; 194d3df7b15SLang Hames case ELF::R_X86_64_REX_GOTPCRELX: 195a9095f00Sluxufan Kind = x86_64::RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable; 1964ec32375Sluxufan Addend = 0; 1974ec32375Sluxufan break; 198d3df7b15SLang Hames case ELF::R_X86_64_TLSGD: 19901b097afSGeoffrey Martin-Noble Kind = x86_64::RequestTLSDescInGOTAndTransformToDelta32; 20001b097afSGeoffrey Martin-Noble break; 201d3df7b15SLang Hames case ELF::R_X86_64_GOTPCRELX: 202a9095f00Sluxufan Kind = x86_64::RequestGOTAndTransformToPCRel32GOTLoadRelaxable; 203ee659383Sluxufan Addend = 0; 204ee659383Sluxufan break; 205d3df7b15SLang Hames case ELF::R_X86_64_GOTPCREL64: 206ee659383Sluxufan Kind = x86_64::RequestGOTAndTransformToDelta64; 207ee659383Sluxufan break; 208d3df7b15SLang Hames case ELF::R_X86_64_GOT64: 209ee659383Sluxufan Kind = x86_64::RequestGOTAndTransformToDelta64FromGOT; 210ee659383Sluxufan break; 211d3df7b15SLang Hames case ELF::R_X86_64_GOTOFF64: 212ee659383Sluxufan Kind = x86_64::Delta64FromGOT; 213ee659383Sluxufan break; 214d3df7b15SLang Hames case ELF::R_X86_64_PLT32: 215ee659383Sluxufan Kind = x86_64::BranchPCRel32; 21621562c03SLang Hames // BranchPCRel32 implicitly handles the '-4' PC adjustment, so we have to 21721562c03SLang Hames // adjust the addend by '+4' to compensate. 21821562c03SLang Hames Addend += 4; 219ee659383Sluxufan break; 220d3df7b15SLang Hames default: 221d3df7b15SLang Hames return make_error<JITLinkError>( 222d3df7b15SLang Hames "In " + G->getName() + ": Unsupported x86-64 relocation type " + 223d3df7b15SLang Hames object::getELFRelocationTypeName(ELF::EM_X86_64, ELFReloc)); 224ee659383Sluxufan } 2253f0841f6SJared Wyles 226118e953bSLang Hames auto FixupAddress = orc::ExecutorAddr(FixupSection.sh_addr) + Rel.r_offset; 227091e3648SSteven Wu Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress(); 22868914dc9SStefan Gränitz Edge GE(Kind, Offset, *GraphSymbol, Addend); 2293f0841f6SJared Wyles LLVM_DEBUG({ 23068914dc9SStefan Gränitz dbgs() << " "; 231091e3648SSteven Wu printEdge(dbgs(), BlockToFix, GE, x86_64::getEdgeKindName(Kind)); 2323f0841f6SJared Wyles dbgs() << "\n"; 2333f0841f6SJared Wyles }); 23468914dc9SStefan Gränitz 235091e3648SSteven Wu BlockToFix.addEdge(std::move(GE)); 2363f0841f6SJared Wyles return Error::success(); 2373f0841f6SJared Wyles } 2383f0841f6SJared Wyles 2392e40cf06SLang Hames public: 240ec6b71dfSLang Hames ELFLinkGraphBuilder_x86_64(StringRef FileName, 2412ccf7ed2SJared Wyles std::shared_ptr<orc::SymbolStringPool> SSP, 242348d0a6bSJob Noorman const object::ELFFile<object::ELF64LE> &Obj, 24352b88457SJob Noorman SubtargetFeatures Features) 2442ccf7ed2SJared Wyles : ELFLinkGraphBuilder(Obj, std::move(SSP), Triple("x86_64-unknown-linux"), 245348d0a6bSJob Noorman std::move(Features), FileName, 246ee659383Sluxufan x86_64::getEdgeKindName) {} 2472e40cf06SLang Hames }; 2482e40cf06SLang Hames 2492e40cf06SLang Hames class ELFJITLinker_x86_64 : public JITLinker<ELFJITLinker_x86_64> { 2502e40cf06SLang Hames friend class JITLinker<ELFJITLinker_x86_64>; 2512e40cf06SLang Hames 2522e40cf06SLang Hames public: 2532e40cf06SLang Hames ELFJITLinker_x86_64(std::unique_ptr<JITLinkContext> Ctx, 254ec6b71dfSLang Hames std::unique_ptr<LinkGraph> G, 2552e40cf06SLang Hames PassConfiguration PassConfig) 256fc36a511SLang Hames : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) { 257265d6bdaSLang Hames 25835c9072cSLang Hames if (shouldAddDefaultTargetPasses(getGraph().getTargetTriple())) 259fc36a511SLang Hames getPassConfig().PostAllocationPasses.push_back( 260fc36a511SLang Hames [this](LinkGraph &G) { return getOrCreateGOTSymbol(G); }); 261fc36a511SLang Hames } 2622e40cf06SLang Hames 2632e40cf06SLang Hames private: 264fc36a511SLang Hames Symbol *GOTSymbol = nullptr; 265fc36a511SLang Hames Error getOrCreateGOTSymbol(LinkGraph &G) { 266fc36a511SLang Hames auto DefineExternalGOTSymbolIfPresent = 267fc36a511SLang Hames createDefineExternalSectionStartAndEndSymbolsPass( 268fc36a511SLang Hames [&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc { 2692ccf7ed2SJared Wyles if (Sym.getName() != nullptr && 2702ccf7ed2SJared Wyles *Sym.getName() == ELFGOTSymbolName) 271cc3115cdSLang Hames if (auto *GOTSection = G.findSectionByName( 272cc3115cdSLang Hames x86_64::GOTTableManager::getSectionName())) { 273fc36a511SLang Hames GOTSymbol = &Sym; 274fc36a511SLang Hames return {*GOTSection, true}; 275fc36a511SLang Hames } 276fc36a511SLang Hames return {}; 277fc36a511SLang Hames }); 278fc36a511SLang Hames 279fc36a511SLang Hames // Try to attach _GLOBAL_OFFSET_TABLE_ to the GOT if it's defined as an 280fc36a511SLang Hames // external. 281fc36a511SLang Hames if (auto Err = DefineExternalGOTSymbolIfPresent(G)) 282fc36a511SLang Hames return Err; 283fc36a511SLang Hames 284cc4ad2c5SLang Hames // If we succeeded then we're done. 285cc4ad2c5SLang Hames if (GOTSymbol) 286cc4ad2c5SLang Hames return Error::success(); 287cc4ad2c5SLang Hames 288cc4ad2c5SLang Hames // Otherwise look for a GOT section: If it already has a start symbol we'll 289cc4ad2c5SLang Hames // record it, otherwise we'll create our own. 290fc36a511SLang Hames // If there's a GOT section but we didn't find an external GOT symbol... 291cc3115cdSLang Hames if (auto *GOTSection = 292cc3115cdSLang Hames G.findSectionByName(x86_64::GOTTableManager::getSectionName())) { 293fc36a511SLang Hames 294fc36a511SLang Hames // Check for an existing defined symbol. 295fc36a511SLang Hames for (auto *Sym : GOTSection->symbols()) 2962ccf7ed2SJared Wyles if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) { 297fc36a511SLang Hames GOTSymbol = Sym; 298fc36a511SLang Hames return Error::success(); 299fc36a511SLang Hames } 300fc36a511SLang Hames 301fc36a511SLang Hames // If there's no defined symbol then create one. 302fc36a511SLang Hames SectionRange SR(*GOTSection); 303fc36a511SLang Hames if (SR.empty()) 304118e953bSLang Hames GOTSymbol = 305118e953bSLang Hames &G.addAbsoluteSymbol(ELFGOTSymbolName, orc::ExecutorAddr(), 0, 306fc36a511SLang Hames Linkage::Strong, Scope::Local, true); 307fc36a511SLang Hames else 308fc36a511SLang Hames GOTSymbol = 309fc36a511SLang Hames &G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0, 310fc36a511SLang Hames Linkage::Strong, Scope::Local, false, true); 311fc36a511SLang Hames } 312fc36a511SLang Hames 313e4b6e686SLang Hames // If we still haven't found a GOT symbol then double check the externals. 314e4b6e686SLang Hames // We may have a GOT-relative reference but no GOT section, in which case 315e4b6e686SLang Hames // we just need to point the GOT symbol at some address in this graph. 316e4b6e686SLang Hames if (!GOTSymbol) { 317e4b6e686SLang Hames for (auto *Sym : G.external_symbols()) { 3182ccf7ed2SJared Wyles if (*Sym->getName() == ELFGOTSymbolName) { 319e4b6e686SLang Hames auto Blocks = G.blocks(); 320e4b6e686SLang Hames if (!Blocks.empty()) { 321e4b6e686SLang Hames G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress()); 322e4b6e686SLang Hames GOTSymbol = Sym; 323e4b6e686SLang Hames break; 324e4b6e686SLang Hames } 325e4b6e686SLang Hames } 326e4b6e686SLang Hames } 327e4b6e686SLang Hames } 328e4b6e686SLang Hames 329fc36a511SLang Hames return Error::success(); 330fc36a511SLang Hames } 331fc36a511SLang Hames 33282ad2b6eSLang Hames Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const { 333ee659383Sluxufan return x86_64::applyFixup(G, B, E, GOTSymbol); 3342e40cf06SLang Hames } 3352e40cf06SLang Hames }; 3362e40cf06SLang Hames 3372ccf7ed2SJared Wyles Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_x86_64( 3382ccf7ed2SJared Wyles MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) { 339ec6b71dfSLang Hames LLVM_DEBUG({ 340ec6b71dfSLang Hames dbgs() << "Building jitlink graph for new input " 341ec6b71dfSLang Hames << ObjectBuffer.getBufferIdentifier() << "...\n"; 342ec6b71dfSLang Hames }); 343ec6b71dfSLang Hames 344ec6b71dfSLang Hames auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer); 345ec6b71dfSLang Hames if (!ELFObj) 346ec6b71dfSLang Hames return ELFObj.takeError(); 347ec6b71dfSLang Hames 348348d0a6bSJob Noorman auto Features = (*ELFObj)->getFeatures(); 349348d0a6bSJob Noorman if (!Features) 350348d0a6bSJob Noorman return Features.takeError(); 351348d0a6bSJob Noorman 352ec6b71dfSLang Hames auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj); 3532ccf7ed2SJared Wyles return ELFLinkGraphBuilder_x86_64((*ELFObj)->getFileName(), std::move(SSP), 354348d0a6bSJob Noorman ELFObjFile.getELFFile(), 35552b88457SJob Noorman std::move(*Features)) 356ec6b71dfSLang Hames .buildGraph(); 357ec6b71dfSLang Hames } 358ec6b71dfSLang Hames 359ec6b71dfSLang Hames void link_ELF_x86_64(std::unique_ptr<LinkGraph> G, 360ec6b71dfSLang Hames std::unique_ptr<JITLinkContext> Ctx) { 3612e40cf06SLang Hames PassConfiguration Config; 362ec6b71dfSLang Hames 363cda4d3d3SLang Hames if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) { 364cda4d3d3SLang Hames 365229d576bSShubham Sandeep Rastogi Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame")); 36643acef48SLang Hames Config.PrePrunePasses.push_back(EHFrameEdgeFixer( 36743acef48SLang Hames ".eh_frame", x86_64::PointerSize, x86_64::Pointer32, x86_64::Pointer64, 36843acef48SLang Hames x86_64::Delta32, x86_64::Delta64, x86_64::NegDelta32)); 369bcb53999SLang Hames Config.PrePrunePasses.push_back(EHFrameNullTerminator(".eh_frame")); 370cda4d3d3SLang Hames 3712e40cf06SLang Hames // Construct a JITLinker and run the link function. 3722e40cf06SLang Hames // Add a mark-live pass. 373ec6b71dfSLang Hames if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple())) 3742e40cf06SLang Hames Config.PrePrunePasses.push_back(std::move(MarkLive)); 3752e40cf06SLang Hames else 3762e40cf06SLang Hames Config.PrePrunePasses.push_back(markAllSymbolsLive); 3772e40cf06SLang Hames 378849b36bfSluxufan // Add an in-place GOT/Stubs/TLSInfoEntry build pass. 379849b36bfSluxufan Config.PostPrunePasses.push_back(buildTables_ELF_x86_64); 380ef454c54SJared Wyles 3810a74ec32SLang Hames // Resolve any external section start / end symbols. 382fc36a511SLang Hames Config.PostAllocationPasses.push_back( 3830a74ec32SLang Hames createDefineExternalSectionStartAndEndSymbolsPass( 3840a74ec32SLang Hames identifyELFSectionStartAndEndSymbols)); 385fc36a511SLang Hames 386fc36a511SLang Hames // Add GOT/Stubs optimizer pass. 387cc3115cdSLang Hames Config.PreFixupPasses.push_back(x86_64::optimizeGOTAndStubAccesses); 388cda4d3d3SLang Hames } 389ef454c54SJared Wyles 3904e30b20bSLang Hames if (auto Err = Ctx->modifyPassConfig(*G, Config)) 391a6deaeecSLang Hames return Ctx->notifyFailed(std::move(Err)); 392a6deaeecSLang Hames 393ec6b71dfSLang Hames ELFJITLinker_x86_64::link(std::move(Ctx), std::move(G), std::move(Config)); 3942e40cf06SLang Hames } 3952e40cf06SLang Hames } // end namespace jitlink 3962e40cf06SLang Hames } // end namespace llvm 397