1fe6060f1SDimitry Andric //===------- ELFLinkGraphBuilder.h - ELF LinkGraph builder ------*- C++ -*-===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric // 9fe6060f1SDimitry Andric // Generic ELF LinkGraph building code. 10fe6060f1SDimitry Andric // 11fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 12fe6060f1SDimitry Andric 13fe6060f1SDimitry Andric #ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H 14fe6060f1SDimitry Andric #define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H 15fe6060f1SDimitry Andric 16fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/JITLink/JITLink.h" 17fe6060f1SDimitry Andric #include "llvm/Object/ELF.h" 18fe6060f1SDimitry Andric #include "llvm/Support/Debug.h" 19fe6060f1SDimitry Andric #include "llvm/Support/Error.h" 20fe6060f1SDimitry Andric #include "llvm/Support/FormatVariadic.h" 21fe6060f1SDimitry Andric 22fe6060f1SDimitry Andric #define DEBUG_TYPE "jitlink" 23fe6060f1SDimitry Andric 24fe6060f1SDimitry Andric namespace llvm { 25fe6060f1SDimitry Andric namespace jitlink { 26fe6060f1SDimitry Andric 27fe6060f1SDimitry Andric /// Common link-graph building code shared between all ELFFiles. 28fe6060f1SDimitry Andric class ELFLinkGraphBuilderBase { 29fe6060f1SDimitry Andric public: 30fe6060f1SDimitry Andric ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {} 31fe6060f1SDimitry Andric virtual ~ELFLinkGraphBuilderBase(); 32fe6060f1SDimitry Andric 33fe6060f1SDimitry Andric protected: 34fe6060f1SDimitry Andric static bool isDwarfSection(StringRef SectionName) { 35fe6060f1SDimitry Andric return llvm::is_contained(DwarfSectionNames, SectionName); 36fe6060f1SDimitry Andric } 37fe6060f1SDimitry Andric 38fe6060f1SDimitry Andric Section &getCommonSection() { 39349cc55cSDimitry Andric if (!CommonSection) 40bdd1243dSDimitry Andric CommonSection = &G->createSection( 41bdd1243dSDimitry Andric CommonSectionName, orc::MemProt::Read | orc::MemProt::Write); 42fe6060f1SDimitry Andric return *CommonSection; 43fe6060f1SDimitry Andric } 44fe6060f1SDimitry Andric 45fe6060f1SDimitry Andric std::unique_ptr<LinkGraph> G; 46fe6060f1SDimitry Andric 47fe6060f1SDimitry Andric private: 48fe6060f1SDimitry Andric static StringRef CommonSectionName; 49fe6060f1SDimitry Andric static ArrayRef<const char *> DwarfSectionNames; 50fe6060f1SDimitry Andric 51fe6060f1SDimitry Andric Section *CommonSection = nullptr; 52fe6060f1SDimitry Andric }; 53fe6060f1SDimitry Andric 545f757f3fSDimitry Andric /// LinkGraph building code that's specific to the given ELFT, but common 55fe6060f1SDimitry Andric /// across all architectures. 56fe6060f1SDimitry Andric template <typename ELFT> 57fe6060f1SDimitry Andric class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase { 58fe6060f1SDimitry Andric using ELFFile = object::ELFFile<ELFT>; 59fe6060f1SDimitry Andric 60fe6060f1SDimitry Andric public: 61fe6060f1SDimitry Andric ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj, Triple TT, 6206c3fb27SDimitry Andric SubtargetFeatures Features, StringRef FileName, 63fe6060f1SDimitry Andric LinkGraph::GetEdgeKindNameFunction GetEdgeKindName); 64fe6060f1SDimitry Andric 6506c3fb27SDimitry Andric /// Debug sections are included in the graph by default. Use 6606c3fb27SDimitry Andric /// setProcessDebugSections(false) to ignore them if debug info is not 6706c3fb27SDimitry Andric /// needed. 6806c3fb27SDimitry Andric ELFLinkGraphBuilder &setProcessDebugSections(bool ProcessDebugSections) { 6906c3fb27SDimitry Andric this->ProcessDebugSections = ProcessDebugSections; 7006c3fb27SDimitry Andric return *this; 7106c3fb27SDimitry Andric } 7206c3fb27SDimitry Andric 73fe6060f1SDimitry Andric /// Attempt to construct and return the LinkGraph. 74fe6060f1SDimitry Andric Expected<std::unique_ptr<LinkGraph>> buildGraph(); 75fe6060f1SDimitry Andric 76fe6060f1SDimitry Andric /// Call to derived class to handle relocations. These require 77fe6060f1SDimitry Andric /// architecture specific knowledge to map to JITLink edge kinds. 78fe6060f1SDimitry Andric virtual Error addRelocations() = 0; 79fe6060f1SDimitry Andric 80fe6060f1SDimitry Andric protected: 81fe6060f1SDimitry Andric using ELFSectionIndex = unsigned; 82fe6060f1SDimitry Andric using ELFSymbolIndex = unsigned; 83fe6060f1SDimitry Andric 84fe6060f1SDimitry Andric bool isRelocatable() const { 85fe6060f1SDimitry Andric return Obj.getHeader().e_type == llvm::ELF::ET_REL; 86fe6060f1SDimitry Andric } 87fe6060f1SDimitry Andric 8804eeddc0SDimitry Andric void setGraphBlock(ELFSectionIndex SecIndex, Block *B) { 8904eeddc0SDimitry Andric assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index"); 9004eeddc0SDimitry Andric GraphBlocks[SecIndex] = B; 91fe6060f1SDimitry Andric } 92fe6060f1SDimitry Andric 9304eeddc0SDimitry Andric Block *getGraphBlock(ELFSectionIndex SecIndex) { 9406c3fb27SDimitry Andric return GraphBlocks.lookup(SecIndex); 95fe6060f1SDimitry Andric } 96fe6060f1SDimitry Andric 97fe6060f1SDimitry Andric void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) { 98fe6060f1SDimitry Andric assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index"); 99fe6060f1SDimitry Andric GraphSymbols[SymIndex] = &Sym; 100fe6060f1SDimitry Andric } 101fe6060f1SDimitry Andric 102fe6060f1SDimitry Andric Symbol *getGraphSymbol(ELFSymbolIndex SymIndex) { 10306c3fb27SDimitry Andric return GraphSymbols.lookup(SymIndex); 104fe6060f1SDimitry Andric } 105fe6060f1SDimitry Andric 106fe6060f1SDimitry Andric Expected<std::pair<Linkage, Scope>> 107fe6060f1SDimitry Andric getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name); 108fe6060f1SDimitry Andric 10906c3fb27SDimitry Andric /// Set the target flags on the given Symbol. 11006c3fb27SDimitry Andric virtual TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) { 11106c3fb27SDimitry Andric return TargetFlagsType{}; 11206c3fb27SDimitry Andric } 11306c3fb27SDimitry Andric 11406c3fb27SDimitry Andric /// Get the physical offset of the symbol on the target platform. 11506c3fb27SDimitry Andric virtual orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym, 11606c3fb27SDimitry Andric TargetFlagsType Flags) { 11706c3fb27SDimitry Andric return Sym.getValue(); 11806c3fb27SDimitry Andric } 11906c3fb27SDimitry Andric 120fe6060f1SDimitry Andric Error prepare(); 121fe6060f1SDimitry Andric Error graphifySections(); 122fe6060f1SDimitry Andric Error graphifySymbols(); 123fe6060f1SDimitry Andric 12406c3fb27SDimitry Andric /// Override in derived classes to suppress certain sections in the link 12506c3fb27SDimitry Andric /// graph. 12606c3fb27SDimitry Andric virtual bool excludeSection(const typename ELFT::Shdr &Sect) const { 12706c3fb27SDimitry Andric return false; 12806c3fb27SDimitry Andric } 12906c3fb27SDimitry Andric 130bdd1243dSDimitry Andric /// Traverse all matching ELFT::Rela relocation records in the given section. 131bdd1243dSDimitry Andric /// The handler function Func should be callable with this signature: 132349cc55cSDimitry Andric /// Error(const typename ELFT::Rela &, 133349cc55cSDimitry Andric /// const typename ELFT::Shdr &, Section &) 134349cc55cSDimitry Andric /// 135bdd1243dSDimitry Andric template <typename RelocHandlerMethod> 136bdd1243dSDimitry Andric Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect, 13706c3fb27SDimitry Andric RelocHandlerMethod &&Func); 138349cc55cSDimitry Andric 139bdd1243dSDimitry Andric /// Traverse all matching ELFT::Rel relocation records in the given section. 140bdd1243dSDimitry Andric /// The handler function Func should be callable with this signature: 141bdd1243dSDimitry Andric /// Error(const typename ELFT::Rel &, 142bdd1243dSDimitry Andric /// const typename ELFT::Shdr &, Section &) 143bdd1243dSDimitry Andric /// 144bdd1243dSDimitry Andric template <typename RelocHandlerMethod> 145bdd1243dSDimitry Andric Error forEachRelRelocation(const typename ELFT::Shdr &RelSect, 14606c3fb27SDimitry Andric RelocHandlerMethod &&Func); 147bdd1243dSDimitry Andric 148bdd1243dSDimitry Andric /// Traverse all matching rela relocation records in the given section. 149bdd1243dSDimitry Andric /// Convenience wrapper to allow passing a member function for the handler. 150349cc55cSDimitry Andric /// 151349cc55cSDimitry Andric template <typename ClassT, typename RelocHandlerMethod> 152bdd1243dSDimitry Andric Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect, 15306c3fb27SDimitry Andric ClassT *Instance, RelocHandlerMethod &&Method) { 154bdd1243dSDimitry Andric return forEachRelaRelocation( 155bdd1243dSDimitry Andric RelSect, 156bdd1243dSDimitry Andric [Instance, Method](const auto &Rel, const auto &Target, auto &GS) { 157bdd1243dSDimitry Andric return (Instance->*Method)(Rel, Target, GS); 15806c3fb27SDimitry Andric }); 159bdd1243dSDimitry Andric } 160bdd1243dSDimitry Andric 161bdd1243dSDimitry Andric /// Traverse all matching rel relocation records in the given section. 162bdd1243dSDimitry Andric /// Convenience wrapper to allow passing a member function for the handler. 163bdd1243dSDimitry Andric /// 164bdd1243dSDimitry Andric template <typename ClassT, typename RelocHandlerMethod> 165bdd1243dSDimitry Andric Error forEachRelRelocation(const typename ELFT::Shdr &RelSect, 16606c3fb27SDimitry Andric ClassT *Instance, RelocHandlerMethod &&Method) { 167bdd1243dSDimitry Andric return forEachRelRelocation( 168349cc55cSDimitry Andric RelSect, 169349cc55cSDimitry Andric [Instance, Method](const auto &Rel, const auto &Target, auto &GS) { 170349cc55cSDimitry Andric return (Instance->*Method)(Rel, Target, GS); 17106c3fb27SDimitry Andric }); 172349cc55cSDimitry Andric } 173349cc55cSDimitry Andric 174fe6060f1SDimitry Andric const ELFFile &Obj; 175fe6060f1SDimitry Andric 176fe6060f1SDimitry Andric typename ELFFile::Elf_Shdr_Range Sections; 177fe6060f1SDimitry Andric const typename ELFFile::Elf_Shdr *SymTabSec = nullptr; 178fe6060f1SDimitry Andric StringRef SectionStringTab; 17906c3fb27SDimitry Andric bool ProcessDebugSections = true; 180fe6060f1SDimitry Andric 18104eeddc0SDimitry Andric // Maps ELF section indexes to LinkGraph Blocks. 18204eeddc0SDimitry Andric // Only SHF_ALLOC sections will have graph blocks. 18304eeddc0SDimitry Andric DenseMap<ELFSectionIndex, Block *> GraphBlocks; 184fe6060f1SDimitry Andric DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols; 1854824e7fdSDimitry Andric DenseMap<const typename ELFFile::Elf_Shdr *, 1864824e7fdSDimitry Andric ArrayRef<typename ELFFile::Elf_Word>> 1874824e7fdSDimitry Andric ShndxTables; 188fe6060f1SDimitry Andric }; 189fe6060f1SDimitry Andric 190fe6060f1SDimitry Andric template <typename ELFT> 191fe6060f1SDimitry Andric ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder( 19206c3fb27SDimitry Andric const ELFFile &Obj, Triple TT, SubtargetFeatures Features, 19306c3fb27SDimitry Andric StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) 194fe6060f1SDimitry Andric : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>( 19506c3fb27SDimitry Andric FileName.str(), Triple(std::move(TT)), std::move(Features), 196*0fca6ea1SDimitry Andric ELFT::Is64Bits ? 8 : 4, llvm::endianness(ELFT::Endianness), 197fe6060f1SDimitry Andric std::move(GetEdgeKindName))), 198fe6060f1SDimitry Andric Obj(Obj) { 199fe6060f1SDimitry Andric LLVM_DEBUG( 200fe6060f1SDimitry Andric { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; }); 201fe6060f1SDimitry Andric } 202fe6060f1SDimitry Andric 203fe6060f1SDimitry Andric template <typename ELFT> 204fe6060f1SDimitry Andric Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() { 205fe6060f1SDimitry Andric if (!isRelocatable()) 206fe6060f1SDimitry Andric return make_error<JITLinkError>("Object is not a relocatable ELF file"); 207fe6060f1SDimitry Andric 208fe6060f1SDimitry Andric if (auto Err = prepare()) 209fe6060f1SDimitry Andric return std::move(Err); 210fe6060f1SDimitry Andric 211fe6060f1SDimitry Andric if (auto Err = graphifySections()) 212fe6060f1SDimitry Andric return std::move(Err); 213fe6060f1SDimitry Andric 214fe6060f1SDimitry Andric if (auto Err = graphifySymbols()) 215fe6060f1SDimitry Andric return std::move(Err); 216fe6060f1SDimitry Andric 217fe6060f1SDimitry Andric if (auto Err = addRelocations()) 218fe6060f1SDimitry Andric return std::move(Err); 219fe6060f1SDimitry Andric 220fe6060f1SDimitry Andric return std::move(G); 221fe6060f1SDimitry Andric } 222fe6060f1SDimitry Andric 223fe6060f1SDimitry Andric template <typename ELFT> 224fe6060f1SDimitry Andric Expected<std::pair<Linkage, Scope>> 225fe6060f1SDimitry Andric ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope( 226fe6060f1SDimitry Andric const typename ELFT::Sym &Sym, StringRef Name) { 227fe6060f1SDimitry Andric Linkage L = Linkage::Strong; 228fe6060f1SDimitry Andric Scope S = Scope::Default; 229fe6060f1SDimitry Andric 230fe6060f1SDimitry Andric switch (Sym.getBinding()) { 231fe6060f1SDimitry Andric case ELF::STB_LOCAL: 232fe6060f1SDimitry Andric S = Scope::Local; 233fe6060f1SDimitry Andric break; 234fe6060f1SDimitry Andric case ELF::STB_GLOBAL: 235fe6060f1SDimitry Andric // Nothing to do here. 236fe6060f1SDimitry Andric break; 237fe6060f1SDimitry Andric case ELF::STB_WEAK: 238349cc55cSDimitry Andric case ELF::STB_GNU_UNIQUE: 239fe6060f1SDimitry Andric L = Linkage::Weak; 240fe6060f1SDimitry Andric break; 241fe6060f1SDimitry Andric default: 242349cc55cSDimitry Andric return make_error<StringError>( 243349cc55cSDimitry Andric "Unrecognized symbol binding " + 244349cc55cSDimitry Andric Twine(static_cast<int>(Sym.getBinding())) + " for " + Name, 245fe6060f1SDimitry Andric inconvertibleErrorCode()); 246fe6060f1SDimitry Andric } 247fe6060f1SDimitry Andric 248fe6060f1SDimitry Andric switch (Sym.getVisibility()) { 249fe6060f1SDimitry Andric case ELF::STV_DEFAULT: 250fe6060f1SDimitry Andric case ELF::STV_PROTECTED: 251fe6060f1SDimitry Andric // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs 252fe6060f1SDimitry Andric // Orc support. 253fe6060f1SDimitry Andric // Otherwise nothing to do here. 254fe6060f1SDimitry Andric break; 255fe6060f1SDimitry Andric case ELF::STV_HIDDEN: 256fe6060f1SDimitry Andric // Default scope -> Hidden scope. No effect on local scope. 257fe6060f1SDimitry Andric if (S == Scope::Default) 258fe6060f1SDimitry Andric S = Scope::Hidden; 259fe6060f1SDimitry Andric break; 260fe6060f1SDimitry Andric case ELF::STV_INTERNAL: 261349cc55cSDimitry Andric return make_error<StringError>( 262349cc55cSDimitry Andric "Unrecognized symbol visibility " + 263349cc55cSDimitry Andric Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name, 264fe6060f1SDimitry Andric inconvertibleErrorCode()); 265fe6060f1SDimitry Andric } 266fe6060f1SDimitry Andric 267fe6060f1SDimitry Andric return std::make_pair(L, S); 268fe6060f1SDimitry Andric } 269fe6060f1SDimitry Andric 270fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() { 271fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << " Preparing to build...\n"); 272fe6060f1SDimitry Andric 273fe6060f1SDimitry Andric // Get the sections array. 274fe6060f1SDimitry Andric if (auto SectionsOrErr = Obj.sections()) 275fe6060f1SDimitry Andric Sections = *SectionsOrErr; 276fe6060f1SDimitry Andric else 277fe6060f1SDimitry Andric return SectionsOrErr.takeError(); 278fe6060f1SDimitry Andric 279fe6060f1SDimitry Andric // Get the section string table. 280fe6060f1SDimitry Andric if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections)) 281fe6060f1SDimitry Andric SectionStringTab = *SectionStringTabOrErr; 282fe6060f1SDimitry Andric else 283fe6060f1SDimitry Andric return SectionStringTabOrErr.takeError(); 284fe6060f1SDimitry Andric 285fe6060f1SDimitry Andric // Get the SHT_SYMTAB section. 2864824e7fdSDimitry Andric for (auto &Sec : Sections) { 287fe6060f1SDimitry Andric if (Sec.sh_type == ELF::SHT_SYMTAB) { 288fe6060f1SDimitry Andric if (!SymTabSec) 289fe6060f1SDimitry Andric SymTabSec = &Sec; 290fe6060f1SDimitry Andric else 291fe6060f1SDimitry Andric return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " + 292fe6060f1SDimitry Andric G->getName()); 293fe6060f1SDimitry Andric } 294fe6060f1SDimitry Andric 2954824e7fdSDimitry Andric // Extended table. 2964824e7fdSDimitry Andric if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) { 2974824e7fdSDimitry Andric uint32_t SymtabNdx = Sec.sh_link; 2984824e7fdSDimitry Andric if (SymtabNdx >= Sections.size()) 2994824e7fdSDimitry Andric return make_error<JITLinkError>("sh_link is out of bound"); 3004824e7fdSDimitry Andric 3014824e7fdSDimitry Andric auto ShndxTable = Obj.getSHNDXTable(Sec); 3024824e7fdSDimitry Andric if (!ShndxTable) 3034824e7fdSDimitry Andric return ShndxTable.takeError(); 3044824e7fdSDimitry Andric 3054824e7fdSDimitry Andric ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable}); 3064824e7fdSDimitry Andric } 3074824e7fdSDimitry Andric } 3084824e7fdSDimitry Andric 309fe6060f1SDimitry Andric return Error::success(); 310fe6060f1SDimitry Andric } 311fe6060f1SDimitry Andric 312fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() { 313fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << " Creating graph sections...\n"); 314fe6060f1SDimitry Andric 315fe6060f1SDimitry Andric // For each section... 316fe6060f1SDimitry Andric for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) { 317fe6060f1SDimitry Andric 318fe6060f1SDimitry Andric auto &Sec = Sections[SecIndex]; 319fe6060f1SDimitry Andric 320fe6060f1SDimitry Andric // Start by getting the section name. 321fe6060f1SDimitry Andric auto Name = Obj.getSectionName(Sec, SectionStringTab); 322fe6060f1SDimitry Andric if (!Name) 323fe6060f1SDimitry Andric return Name.takeError(); 32406c3fb27SDimitry Andric if (excludeSection(Sec)) { 325fe6060f1SDimitry Andric LLVM_DEBUG({ 32606c3fb27SDimitry Andric dbgs() << " " << SecIndex << ": Skipping section \"" << *Name 32706c3fb27SDimitry Andric << "\" explicitly\n"; 328fe6060f1SDimitry Andric }); 329fe6060f1SDimitry Andric continue; 330fe6060f1SDimitry Andric } 331fe6060f1SDimitry Andric 33206c3fb27SDimitry Andric // Skip null sections. 33306c3fb27SDimitry Andric if (Sec.sh_type == ELF::SHT_NULL) { 33406c3fb27SDimitry Andric LLVM_DEBUG({ 33506c3fb27SDimitry Andric dbgs() << " " << SecIndex << ": has type SHT_NULL. Skipping.\n"; 33606c3fb27SDimitry Andric }); 33706c3fb27SDimitry Andric continue; 33806c3fb27SDimitry Andric } 33906c3fb27SDimitry Andric 34006c3fb27SDimitry Andric // If the name indicates that it's a debug section then skip it: We don't 34106c3fb27SDimitry Andric // support those yet. 34206c3fb27SDimitry Andric if (!ProcessDebugSections && isDwarfSection(*Name)) { 343fe6060f1SDimitry Andric LLVM_DEBUG({ 344fe6060f1SDimitry Andric dbgs() << " " << SecIndex << ": \"" << *Name 34506c3fb27SDimitry Andric << "\" is a debug section: " 346fe6060f1SDimitry Andric "No graph section will be created.\n"; 347fe6060f1SDimitry Andric }); 348fe6060f1SDimitry Andric continue; 349fe6060f1SDimitry Andric } 350fe6060f1SDimitry Andric 351fe6060f1SDimitry Andric LLVM_DEBUG({ 352fe6060f1SDimitry Andric dbgs() << " " << SecIndex << ": Creating section for \"" << *Name 353fe6060f1SDimitry Andric << "\"\n"; 354fe6060f1SDimitry Andric }); 355fe6060f1SDimitry Andric 356fe6060f1SDimitry Andric // Get the section's memory protection flags. 35706c3fb27SDimitry Andric orc::MemProt Prot = orc::MemProt::Read; 358fe6060f1SDimitry Andric if (Sec.sh_flags & ELF::SHF_EXECINSTR) 35906c3fb27SDimitry Andric Prot |= orc::MemProt::Exec; 36006c3fb27SDimitry Andric if (Sec.sh_flags & ELF::SHF_WRITE) 36106c3fb27SDimitry Andric Prot |= orc::MemProt::Write; 362fe6060f1SDimitry Andric 36304eeddc0SDimitry Andric // Look for existing sections first. 36404eeddc0SDimitry Andric auto *GraphSec = G->findSectionByName(*Name); 36506c3fb27SDimitry Andric if (!GraphSec) { 36604eeddc0SDimitry Andric GraphSec = &G->createSection(*Name, Prot); 36706c3fb27SDimitry Andric // Non-SHF_ALLOC sections get NoAlloc memory lifetimes. 36806c3fb27SDimitry Andric if (!(Sec.sh_flags & ELF::SHF_ALLOC)) { 3695f757f3fSDimitry Andric GraphSec->setMemLifetime(orc::MemLifetime::NoAlloc); 37006c3fb27SDimitry Andric LLVM_DEBUG({ 37106c3fb27SDimitry Andric dbgs() << " " << SecIndex << ": \"" << *Name 37206c3fb27SDimitry Andric << "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n"; 37306c3fb27SDimitry Andric }); 37406c3fb27SDimitry Andric } 37506c3fb27SDimitry Andric } 37606c3fb27SDimitry Andric 3775f757f3fSDimitry Andric if (GraphSec->getMemProt() != Prot) { 3785f757f3fSDimitry Andric std::string ErrMsg; 3795f757f3fSDimitry Andric raw_string_ostream(ErrMsg) 3805f757f3fSDimitry Andric << "In " << G->getName() << ", section " << *Name 3815f757f3fSDimitry Andric << " is present more than once with different permissions: " 3825f757f3fSDimitry Andric << GraphSec->getMemProt() << " vs " << Prot; 3835f757f3fSDimitry Andric return make_error<JITLinkError>(std::move(ErrMsg)); 3845f757f3fSDimitry Andric } 38504eeddc0SDimitry Andric 38604eeddc0SDimitry Andric Block *B = nullptr; 387fe6060f1SDimitry Andric if (Sec.sh_type != ELF::SHT_NOBITS) { 388fe6060f1SDimitry Andric auto Data = Obj.template getSectionContentsAsArray<char>(Sec); 389fe6060f1SDimitry Andric if (!Data) 390fe6060f1SDimitry Andric return Data.takeError(); 391fe6060f1SDimitry Andric 39204eeddc0SDimitry Andric B = &G->createContentBlock(*GraphSec, *Data, 39304eeddc0SDimitry Andric orc::ExecutorAddr(Sec.sh_addr), 39404eeddc0SDimitry Andric Sec.sh_addralign, 0); 395fe6060f1SDimitry Andric } else 39604eeddc0SDimitry Andric B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size, 39704eeddc0SDimitry Andric orc::ExecutorAddr(Sec.sh_addr), 398fe6060f1SDimitry Andric Sec.sh_addralign, 0); 399fe6060f1SDimitry Andric 4007a6dacacSDimitry Andric if (Sec.sh_type == ELF::SHT_ARM_EXIDX) { 4017a6dacacSDimitry Andric // Add live symbol to avoid dead-stripping for .ARM.exidx sections 4027a6dacacSDimitry Andric G->addAnonymousSymbol(*B, orc::ExecutorAddrDiff(), 4037a6dacacSDimitry Andric orc::ExecutorAddrDiff(), false, true); 4047a6dacacSDimitry Andric } 4057a6dacacSDimitry Andric 40604eeddc0SDimitry Andric setGraphBlock(SecIndex, B); 407fe6060f1SDimitry Andric } 408fe6060f1SDimitry Andric 409fe6060f1SDimitry Andric return Error::success(); 410fe6060f1SDimitry Andric } 411fe6060f1SDimitry Andric 412fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() { 413fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << " Creating graph symbols...\n"); 414fe6060f1SDimitry Andric 415fe6060f1SDimitry Andric // No SYMTAB -- Bail out early. 416fe6060f1SDimitry Andric if (!SymTabSec) 417fe6060f1SDimitry Andric return Error::success(); 418fe6060f1SDimitry Andric 419fe6060f1SDimitry Andric // Get the section content as a Symbols array. 420fe6060f1SDimitry Andric auto Symbols = Obj.symbols(SymTabSec); 421fe6060f1SDimitry Andric if (!Symbols) 422fe6060f1SDimitry Andric return Symbols.takeError(); 423fe6060f1SDimitry Andric 424fe6060f1SDimitry Andric // Get the string table for this section. 425fe6060f1SDimitry Andric auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections); 426fe6060f1SDimitry Andric if (!StringTab) 427fe6060f1SDimitry Andric return StringTab.takeError(); 428fe6060f1SDimitry Andric 429fe6060f1SDimitry Andric LLVM_DEBUG({ 430fe6060f1SDimitry Andric StringRef SymTabName; 431fe6060f1SDimitry Andric 432fe6060f1SDimitry Andric if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab)) 433fe6060f1SDimitry Andric SymTabName = *SymTabNameOrErr; 434fe6060f1SDimitry Andric else { 435fe6060f1SDimitry Andric dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: " 436fe6060f1SDimitry Andric << toString(SymTabNameOrErr.takeError()) << "\n"; 437fe6060f1SDimitry Andric SymTabName = "<SHT_SYMTAB section with invalid name>"; 438fe6060f1SDimitry Andric } 439fe6060f1SDimitry Andric 440fe6060f1SDimitry Andric dbgs() << " Adding symbols from symtab section \"" << SymTabName 441fe6060f1SDimitry Andric << "\"\n"; 442fe6060f1SDimitry Andric }); 443fe6060f1SDimitry Andric 444fe6060f1SDimitry Andric for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) { 445fe6060f1SDimitry Andric auto &Sym = (*Symbols)[SymIndex]; 446fe6060f1SDimitry Andric 447fe6060f1SDimitry Andric // Check symbol type. 448fe6060f1SDimitry Andric switch (Sym.getType()) { 449fe6060f1SDimitry Andric case ELF::STT_FILE: 450fe6060f1SDimitry Andric LLVM_DEBUG({ 451fe6060f1SDimitry Andric if (auto Name = Sym.getName(*StringTab)) 452fe6060f1SDimitry Andric dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \"" 453fe6060f1SDimitry Andric << *Name << "\"\n"; 454fe6060f1SDimitry Andric else { 455fe6060f1SDimitry Andric dbgs() << "Could not get STT_FILE symbol name: " 456fe6060f1SDimitry Andric << toString(Name.takeError()) << "\n"; 457fe6060f1SDimitry Andric dbgs() << " " << SymIndex 458fe6060f1SDimitry Andric << ": Skipping STT_FILE symbol with invalid name\n"; 459fe6060f1SDimitry Andric } 460fe6060f1SDimitry Andric }); 461fe6060f1SDimitry Andric continue; 462fe6060f1SDimitry Andric break; 463fe6060f1SDimitry Andric } 464fe6060f1SDimitry Andric 465fe6060f1SDimitry Andric // Get the symbol name. 466fe6060f1SDimitry Andric auto Name = Sym.getName(*StringTab); 467fe6060f1SDimitry Andric if (!Name) 468fe6060f1SDimitry Andric return Name.takeError(); 469fe6060f1SDimitry Andric 470fe6060f1SDimitry Andric // Handle common symbols specially. 471fe6060f1SDimitry Andric if (Sym.isCommon()) { 472bdd1243dSDimitry Andric Symbol &GSym = G->addDefinedSymbol( 473bdd1243dSDimitry Andric G->createZeroFillBlock(getCommonSection(), Sym.st_size, 474bdd1243dSDimitry Andric orc::ExecutorAddr(), Sym.getValue(), 0), 475bdd1243dSDimitry Andric 0, *Name, Sym.st_size, Linkage::Strong, Scope::Default, false, false); 476fe6060f1SDimitry Andric setGraphSymbol(SymIndex, GSym); 477fe6060f1SDimitry Andric continue; 478fe6060f1SDimitry Andric } 479fe6060f1SDimitry Andric 480fe6060f1SDimitry Andric if (Sym.isDefined() && 481fe6060f1SDimitry Andric (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC || 482fe6060f1SDimitry Andric Sym.getType() == ELF::STT_OBJECT || 483349cc55cSDimitry Andric Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) { 484bdd1243dSDimitry Andric 485bdd1243dSDimitry Andric // Map Visibility and Binding to Scope and Linkage: 486bdd1243dSDimitry Andric Linkage L; 487bdd1243dSDimitry Andric Scope S; 488bdd1243dSDimitry Andric if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name)) 489bdd1243dSDimitry Andric std::tie(L, S) = *LSOrErr; 490bdd1243dSDimitry Andric else 491bdd1243dSDimitry Andric return LSOrErr.takeError(); 492bdd1243dSDimitry Andric 4934824e7fdSDimitry Andric // Handle extended tables. 4944824e7fdSDimitry Andric unsigned Shndx = Sym.st_shndx; 4954824e7fdSDimitry Andric if (Shndx == ELF::SHN_XINDEX) { 4964824e7fdSDimitry Andric auto ShndxTable = ShndxTables.find(SymTabSec); 4974824e7fdSDimitry Andric if (ShndxTable == ShndxTables.end()) 4984824e7fdSDimitry Andric continue; 4994824e7fdSDimitry Andric auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>( 5004824e7fdSDimitry Andric Sym, SymIndex, ShndxTable->second); 5014824e7fdSDimitry Andric if (!NdxOrErr) 5024824e7fdSDimitry Andric return NdxOrErr.takeError(); 5034824e7fdSDimitry Andric Shndx = *NdxOrErr; 5044824e7fdSDimitry Andric } 50504eeddc0SDimitry Andric if (auto *B = getGraphBlock(Shndx)) { 506fe6060f1SDimitry Andric LLVM_DEBUG({ 507fe6060f1SDimitry Andric dbgs() << " " << SymIndex 508fe6060f1SDimitry Andric << ": Creating defined graph symbol for ELF symbol \"" << *Name 509fe6060f1SDimitry Andric << "\"\n"; 510fe6060f1SDimitry Andric }); 511fe6060f1SDimitry Andric 51206c3fb27SDimitry Andric TargetFlagsType Flags = makeTargetFlags(Sym); 51306c3fb27SDimitry Andric orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags); 51406c3fb27SDimitry Andric 5155f757f3fSDimitry Andric if (Offset + Sym.st_size > B->getSize()) { 5165f757f3fSDimitry Andric std::string ErrMsg; 5175f757f3fSDimitry Andric raw_string_ostream ErrStream(ErrMsg); 5185f757f3fSDimitry Andric ErrStream << "In " << G->getName() << ", symbol "; 5195f757f3fSDimitry Andric if (!Name->empty()) 5205f757f3fSDimitry Andric ErrStream << *Name; 5215f757f3fSDimitry Andric else 5225f757f3fSDimitry Andric ErrStream << "<anon>"; 5235f757f3fSDimitry Andric ErrStream << " (" << (B->getAddress() + Offset) << " -- " 5245f757f3fSDimitry Andric << (B->getAddress() + Offset + Sym.st_size) << ") extends " 5255f757f3fSDimitry Andric << formatv("{0:x}", Offset + Sym.st_size - B->getSize()) 5265f757f3fSDimitry Andric << " bytes past the end of its containing block (" 5275f757f3fSDimitry Andric << B->getRange() << ")"; 5285f757f3fSDimitry Andric return make_error<JITLinkError>(std::move(ErrMsg)); 5295f757f3fSDimitry Andric } 5305f757f3fSDimitry Andric 53104eeddc0SDimitry Andric // In RISCV, temporary symbols (Used to generate dwarf, eh_frame 53204eeddc0SDimitry Andric // sections...) will appear in object code's symbol table, and LLVM does 53304eeddc0SDimitry Andric // not use names on these temporary symbols (RISCV gnu toolchain uses 53404eeddc0SDimitry Andric // names on these temporary symbols). If the symbol is unnamed, add an 53504eeddc0SDimitry Andric // anonymous symbol. 536fe6060f1SDimitry Andric auto &GSym = 53704eeddc0SDimitry Andric Name->empty() 53806c3fb27SDimitry Andric ? G->addAnonymousSymbol(*B, Offset, Sym.st_size, 53904eeddc0SDimitry Andric false, false) 54006c3fb27SDimitry Andric : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L, 54106c3fb27SDimitry Andric S, Sym.getType() == ELF::STT_FUNC, 54206c3fb27SDimitry Andric false); 54306c3fb27SDimitry Andric 54406c3fb27SDimitry Andric GSym.setTargetFlags(Flags); 545fe6060f1SDimitry Andric setGraphSymbol(SymIndex, GSym); 546fe6060f1SDimitry Andric } 547fe6060f1SDimitry Andric } else if (Sym.isUndefined() && Sym.isExternal()) { 548fe6060f1SDimitry Andric LLVM_DEBUG({ 549fe6060f1SDimitry Andric dbgs() << " " << SymIndex 550fe6060f1SDimitry Andric << ": Creating external graph symbol for ELF symbol \"" << *Name 551fe6060f1SDimitry Andric << "\"\n"; 552fe6060f1SDimitry Andric }); 553bdd1243dSDimitry Andric 554bdd1243dSDimitry Andric if (Sym.getBinding() != ELF::STB_GLOBAL && 555bdd1243dSDimitry Andric Sym.getBinding() != ELF::STB_WEAK) 556bdd1243dSDimitry Andric return make_error<StringError>( 557bdd1243dSDimitry Andric "Invalid symbol binding " + 558bdd1243dSDimitry Andric Twine(static_cast<int>(Sym.getBinding())) + 559bdd1243dSDimitry Andric " for external symbol " + *Name, 560bdd1243dSDimitry Andric inconvertibleErrorCode()); 561bdd1243dSDimitry Andric 562bdd1243dSDimitry Andric // If L is Linkage::Weak that means this is a weakly referenced symbol. 563bdd1243dSDimitry Andric auto &GSym = G->addExternalSymbol(*Name, Sym.st_size, 564bdd1243dSDimitry Andric Sym.getBinding() == ELF::STB_WEAK); 565fe6060f1SDimitry Andric setGraphSymbol(SymIndex, GSym); 56606c3fb27SDimitry Andric } else if (Sym.isUndefined() && Sym.st_value == 0 && Sym.st_size == 0 && 56706c3fb27SDimitry Andric Sym.getType() == ELF::STT_NOTYPE && 56806c3fb27SDimitry Andric Sym.getBinding() == ELF::STB_LOCAL && Name->empty()) { 56906c3fb27SDimitry Andric // Some relocations (e.g., R_RISCV_ALIGN) don't have a target symbol and 57006c3fb27SDimitry Andric // use this kind of null symbol as a placeholder. 57106c3fb27SDimitry Andric LLVM_DEBUG({ 57206c3fb27SDimitry Andric dbgs() << " " << SymIndex << ": Creating null graph symbol\n"; 57306c3fb27SDimitry Andric }); 57406c3fb27SDimitry Andric 57506c3fb27SDimitry Andric auto SymName = 57606c3fb27SDimitry Andric G->allocateContent("__jitlink_ELF_SYM_UND_" + Twine(SymIndex)); 57706c3fb27SDimitry Andric auto SymNameRef = StringRef(SymName.data(), SymName.size()); 57806c3fb27SDimitry Andric auto &GSym = G->addAbsoluteSymbol(SymNameRef, orc::ExecutorAddr(0), 0, 57906c3fb27SDimitry Andric Linkage::Strong, Scope::Local, false); 58006c3fb27SDimitry Andric setGraphSymbol(SymIndex, GSym); 581fe6060f1SDimitry Andric } else { 582fe6060f1SDimitry Andric LLVM_DEBUG({ 583fe6060f1SDimitry Andric dbgs() << " " << SymIndex 584fe6060f1SDimitry Andric << ": Not creating graph symbol for ELF symbol \"" << *Name 585fe6060f1SDimitry Andric << "\" with unrecognized type\n"; 586fe6060f1SDimitry Andric }); 587fe6060f1SDimitry Andric } 588fe6060f1SDimitry Andric } 589fe6060f1SDimitry Andric 590fe6060f1SDimitry Andric return Error::success(); 591fe6060f1SDimitry Andric } 592fe6060f1SDimitry Andric 593349cc55cSDimitry Andric template <typename ELFT> 594349cc55cSDimitry Andric template <typename RelocHandlerFunction> 595bdd1243dSDimitry Andric Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation( 59606c3fb27SDimitry Andric const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) { 597349cc55cSDimitry Andric // Only look into sections that store relocation entries. 598bdd1243dSDimitry Andric if (RelSect.sh_type != ELF::SHT_RELA) 599349cc55cSDimitry Andric return Error::success(); 600349cc55cSDimitry Andric 601349cc55cSDimitry Andric // sh_info contains the section header index of the target (FixupSection), 602349cc55cSDimitry Andric // which is the section to which all relocations in RelSect apply. 603349cc55cSDimitry Andric auto FixupSection = Obj.getSection(RelSect.sh_info); 604349cc55cSDimitry Andric if (!FixupSection) 605349cc55cSDimitry Andric return FixupSection.takeError(); 606349cc55cSDimitry Andric 607349cc55cSDimitry Andric // Target sections have names in valid ELF object files. 608349cc55cSDimitry Andric Expected<StringRef> Name = Obj.getSectionName(**FixupSection); 609349cc55cSDimitry Andric if (!Name) 610349cc55cSDimitry Andric return Name.takeError(); 611349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << " " << *Name << ":\n"); 612349cc55cSDimitry Andric 613349cc55cSDimitry Andric // Consider skipping these relocations. 614349cc55cSDimitry Andric if (!ProcessDebugSections && isDwarfSection(*Name)) { 615349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n"); 616349cc55cSDimitry Andric return Error::success(); 617349cc55cSDimitry Andric } 61806c3fb27SDimitry Andric if (excludeSection(**FixupSection)) { 61906c3fb27SDimitry Andric LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n"); 62006c3fb27SDimitry Andric return Error::success(); 62106c3fb27SDimitry Andric } 622349cc55cSDimitry Andric 623349cc55cSDimitry Andric // Lookup the link-graph node corresponding to the target section name. 62404eeddc0SDimitry Andric auto *BlockToFix = getGraphBlock(RelSect.sh_info); 62504eeddc0SDimitry Andric if (!BlockToFix) 626349cc55cSDimitry Andric return make_error<StringError>( 627349cc55cSDimitry Andric "Refencing a section that wasn't added to the graph: " + *Name, 628349cc55cSDimitry Andric inconvertibleErrorCode()); 629349cc55cSDimitry Andric 630349cc55cSDimitry Andric auto RelEntries = Obj.relas(RelSect); 631349cc55cSDimitry Andric if (!RelEntries) 632349cc55cSDimitry Andric return RelEntries.takeError(); 633349cc55cSDimitry Andric 634349cc55cSDimitry Andric // Let the callee process relocation entries one by one. 635349cc55cSDimitry Andric for (const typename ELFT::Rela &R : *RelEntries) 63604eeddc0SDimitry Andric if (Error Err = Func(R, **FixupSection, *BlockToFix)) 637349cc55cSDimitry Andric return Err; 638349cc55cSDimitry Andric 639349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "\n"); 640349cc55cSDimitry Andric return Error::success(); 641349cc55cSDimitry Andric } 642349cc55cSDimitry Andric 643bdd1243dSDimitry Andric template <typename ELFT> 644bdd1243dSDimitry Andric template <typename RelocHandlerFunction> 645bdd1243dSDimitry Andric Error ELFLinkGraphBuilder<ELFT>::forEachRelRelocation( 64606c3fb27SDimitry Andric const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) { 647bdd1243dSDimitry Andric // Only look into sections that store relocation entries. 648bdd1243dSDimitry Andric if (RelSect.sh_type != ELF::SHT_REL) 649bdd1243dSDimitry Andric return Error::success(); 650bdd1243dSDimitry Andric 651bdd1243dSDimitry Andric // sh_info contains the section header index of the target (FixupSection), 652bdd1243dSDimitry Andric // which is the section to which all relocations in RelSect apply. 653bdd1243dSDimitry Andric auto FixupSection = Obj.getSection(RelSect.sh_info); 654bdd1243dSDimitry Andric if (!FixupSection) 655bdd1243dSDimitry Andric return FixupSection.takeError(); 656bdd1243dSDimitry Andric 657bdd1243dSDimitry Andric // Target sections have names in valid ELF object files. 658bdd1243dSDimitry Andric Expected<StringRef> Name = Obj.getSectionName(**FixupSection); 659bdd1243dSDimitry Andric if (!Name) 660bdd1243dSDimitry Andric return Name.takeError(); 661bdd1243dSDimitry Andric LLVM_DEBUG(dbgs() << " " << *Name << ":\n"); 662bdd1243dSDimitry Andric 663bdd1243dSDimitry Andric // Consider skipping these relocations. 664bdd1243dSDimitry Andric if (!ProcessDebugSections && isDwarfSection(*Name)) { 665bdd1243dSDimitry Andric LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n"); 666bdd1243dSDimitry Andric return Error::success(); 667bdd1243dSDimitry Andric } 66806c3fb27SDimitry Andric if (excludeSection(**FixupSection)) { 66906c3fb27SDimitry Andric LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n"); 67006c3fb27SDimitry Andric return Error::success(); 67106c3fb27SDimitry Andric } 672bdd1243dSDimitry Andric 673bdd1243dSDimitry Andric // Lookup the link-graph node corresponding to the target section name. 674bdd1243dSDimitry Andric auto *BlockToFix = getGraphBlock(RelSect.sh_info); 675bdd1243dSDimitry Andric if (!BlockToFix) 676bdd1243dSDimitry Andric return make_error<StringError>( 677bdd1243dSDimitry Andric "Refencing a section that wasn't added to the graph: " + *Name, 678bdd1243dSDimitry Andric inconvertibleErrorCode()); 679bdd1243dSDimitry Andric 680bdd1243dSDimitry Andric auto RelEntries = Obj.rels(RelSect); 681bdd1243dSDimitry Andric if (!RelEntries) 682bdd1243dSDimitry Andric return RelEntries.takeError(); 683bdd1243dSDimitry Andric 684bdd1243dSDimitry Andric // Let the callee process relocation entries one by one. 685bdd1243dSDimitry Andric for (const typename ELFT::Rel &R : *RelEntries) 686bdd1243dSDimitry Andric if (Error Err = Func(R, **FixupSection, *BlockToFix)) 687bdd1243dSDimitry Andric return Err; 688bdd1243dSDimitry Andric 689bdd1243dSDimitry Andric LLVM_DEBUG(dbgs() << "\n"); 690bdd1243dSDimitry Andric return Error::success(); 691bdd1243dSDimitry Andric } 692bdd1243dSDimitry Andric 693fe6060f1SDimitry Andric } // end namespace jitlink 694fe6060f1SDimitry Andric } // end namespace llvm 695fe6060f1SDimitry Andric 696fe6060f1SDimitry Andric #undef DEBUG_TYPE 697fe6060f1SDimitry Andric 698fe6060f1SDimitry Andric #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H 699