xref: /llvm-project/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h (revision 4eaff6c58ae2f130ac8d63cf2c87bbb483114876)
1 //===------- ELFLinkGraphBuilder.h - ELF LinkGraph builder ------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Generic ELF LinkGraph building code.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
14 #define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
15 
16 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
17 #include "llvm/Object/ELF.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/Error.h"
20 #include "llvm/Support/FormatVariadic.h"
21 
22 #define DEBUG_TYPE "jitlink"
23 
24 namespace llvm {
25 namespace jitlink {
26 
27 /// Common link-graph building code shared between all ELFFiles.
28 class ELFLinkGraphBuilderBase {
29 public:
30   ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {}
31   virtual ~ELFLinkGraphBuilderBase();
32 
33 protected:
34   static bool isDwarfSection(StringRef SectionName) {
35     return llvm::is_contained(DwarfSectionNames, SectionName);
36   }
37 
38   Section &getCommonSection() {
39     if (!CommonSection)
40       CommonSection = &G->createSection(
41           CommonSectionName, orc::MemProt::Read | orc::MemProt::Write);
42     return *CommonSection;
43   }
44 
45   std::unique_ptr<LinkGraph> G;
46 
47 private:
48   static StringRef CommonSectionName;
49   static ArrayRef<const char *> DwarfSectionNames;
50 
51   Section *CommonSection = nullptr;
52 };
53 
54 /// LinkGraph building code that's specific to the given ELFT, but common
55 /// across all architectures.
56 template <typename ELFT>
57 class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
58   using ELFFile = object::ELFFile<ELFT>;
59 
60 public:
61   ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj,
62                       std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
63                       SubtargetFeatures Features, StringRef FileName,
64                       LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
65 
66   /// Debug sections are included in the graph by default. Use
67   /// setProcessDebugSections(false) to ignore them if debug info is not
68   /// needed.
69   ELFLinkGraphBuilder &setProcessDebugSections(bool ProcessDebugSections) {
70     this->ProcessDebugSections = ProcessDebugSections;
71     return *this;
72   }
73 
74   /// Attempt to construct and return the LinkGraph.
75   Expected<std::unique_ptr<LinkGraph>> buildGraph();
76 
77   /// Call to derived class to handle relocations. These require
78   /// architecture specific knowledge to map to JITLink edge kinds.
79   virtual Error addRelocations() = 0;
80 
81 protected:
82   using ELFSectionIndex = unsigned;
83   using ELFSymbolIndex = unsigned;
84 
85   bool isRelocatable() const {
86     return Obj.getHeader().e_type == llvm::ELF::ET_REL;
87   }
88 
89   void setGraphBlock(ELFSectionIndex SecIndex, Block *B) {
90     assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index");
91     GraphBlocks[SecIndex] = B;
92   }
93 
94   Block *getGraphBlock(ELFSectionIndex SecIndex) {
95     return GraphBlocks.lookup(SecIndex);
96   }
97 
98   void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) {
99     assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");
100     GraphSymbols[SymIndex] = &Sym;
101   }
102 
103   Symbol *getGraphSymbol(ELFSymbolIndex SymIndex) {
104     return GraphSymbols.lookup(SymIndex);
105   }
106 
107   Expected<std::pair<Linkage, Scope>>
108   getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
109 
110   /// Set the target flags on the given Symbol.
111   virtual TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) {
112     return TargetFlagsType{};
113   }
114 
115   /// Get the physical offset of the symbol on the target platform.
116   virtual orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym,
117                                              TargetFlagsType Flags) {
118     return Sym.getValue();
119   }
120 
121   Error prepare();
122   Error graphifySections();
123   Error graphifySymbols();
124 
125   /// Override in derived classes to suppress certain sections in the link
126   /// graph.
127   virtual bool excludeSection(const typename ELFT::Shdr &Sect) const {
128     return false;
129   }
130 
131   /// Traverse all matching ELFT::Rela relocation records in the given section.
132   /// The handler function Func should be callable with this signature:
133   ///   Error(const typename ELFT::Rela &,
134   ///         const typename ELFT::Shdr &, Section &)
135   ///
136   template <typename RelocHandlerMethod>
137   Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
138                               RelocHandlerMethod &&Func);
139 
140   /// Traverse all matching ELFT::Rel relocation records in the given section.
141   /// The handler function Func should be callable with this signature:
142   ///   Error(const typename ELFT::Rel &,
143   ///         const typename ELFT::Shdr &, Section &)
144   ///
145   template <typename RelocHandlerMethod>
146   Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
147                              RelocHandlerMethod &&Func);
148 
149   /// Traverse all matching rela relocation records in the given section.
150   /// Convenience wrapper to allow passing a member function for the handler.
151   ///
152   template <typename ClassT, typename RelocHandlerMethod>
153   Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
154                               ClassT *Instance, RelocHandlerMethod &&Method) {
155     return forEachRelaRelocation(
156         RelSect,
157         [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
158           return (Instance->*Method)(Rel, Target, GS);
159         });
160   }
161 
162   /// Traverse all matching rel relocation records in the given section.
163   /// Convenience wrapper to allow passing a member function for the handler.
164   ///
165   template <typename ClassT, typename RelocHandlerMethod>
166   Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
167                              ClassT *Instance, RelocHandlerMethod &&Method) {
168     return forEachRelRelocation(
169         RelSect,
170         [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
171           return (Instance->*Method)(Rel, Target, GS);
172         });
173   }
174 
175   const ELFFile &Obj;
176 
177   typename ELFFile::Elf_Shdr_Range Sections;
178   const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
179   StringRef SectionStringTab;
180   bool ProcessDebugSections = true;
181 
182   // Maps ELF section indexes to LinkGraph Blocks.
183   // Only SHF_ALLOC sections will have graph blocks.
184   DenseMap<ELFSectionIndex, Block *> GraphBlocks;
185   DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols;
186   DenseMap<const typename ELFFile::Elf_Shdr *,
187            ArrayRef<typename ELFFile::Elf_Word>>
188       ShndxTables;
189 };
190 
191 template <typename ELFT>
192 ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder(
193     const ELFFile &Obj, std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
194     SubtargetFeatures Features, StringRef FileName,
195     LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
196     : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
197           FileName.str(), std::move(SSP), std::move(TT), std::move(Features),
198           std::move(GetEdgeKindName))),
199       Obj(Obj) {
200   LLVM_DEBUG(
201       { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
202 }
203 
204 template <typename ELFT>
205 Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() {
206   if (!isRelocatable())
207     return make_error<JITLinkError>("Object is not a relocatable ELF file");
208 
209   if (auto Err = prepare())
210     return std::move(Err);
211 
212   if (auto Err = graphifySections())
213     return std::move(Err);
214 
215   if (auto Err = graphifySymbols())
216     return std::move(Err);
217 
218   if (auto Err = addRelocations())
219     return std::move(Err);
220 
221   return std::move(G);
222 }
223 
224 template <typename ELFT>
225 Expected<std::pair<Linkage, Scope>>
226 ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope(
227     const typename ELFT::Sym &Sym, StringRef Name) {
228   Linkage L = Linkage::Strong;
229   Scope S = Scope::Default;
230 
231   switch (Sym.getBinding()) {
232   case ELF::STB_LOCAL:
233     S = Scope::Local;
234     break;
235   case ELF::STB_GLOBAL:
236     // Nothing to do here.
237     break;
238   case ELF::STB_WEAK:
239   case ELF::STB_GNU_UNIQUE:
240     L = Linkage::Weak;
241     break;
242   default:
243     return make_error<StringError>(
244         "Unrecognized symbol binding " +
245             Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
246         inconvertibleErrorCode());
247   }
248 
249   switch (Sym.getVisibility()) {
250   case ELF::STV_DEFAULT:
251   case ELF::STV_PROTECTED:
252     // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
253     // Orc support.
254     // Otherwise nothing to do here.
255     break;
256   case ELF::STV_HIDDEN:
257     // Default scope -> Hidden scope. No effect on local scope.
258     if (S == Scope::Default)
259       S = Scope::Hidden;
260     break;
261   case ELF::STV_INTERNAL:
262     return make_error<StringError>(
263         "Unrecognized symbol visibility " +
264             Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,
265         inconvertibleErrorCode());
266   }
267 
268   return std::make_pair(L, S);
269 }
270 
271 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
272   LLVM_DEBUG(dbgs() << "  Preparing to build...\n");
273 
274   // Get the sections array.
275   if (auto SectionsOrErr = Obj.sections())
276     Sections = *SectionsOrErr;
277   else
278     return SectionsOrErr.takeError();
279 
280   // Get the section string table.
281   if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
282     SectionStringTab = *SectionStringTabOrErr;
283   else
284     return SectionStringTabOrErr.takeError();
285 
286   // Get the SHT_SYMTAB section.
287   for (auto &Sec : Sections) {
288     if (Sec.sh_type == ELF::SHT_SYMTAB) {
289       if (!SymTabSec)
290         SymTabSec = &Sec;
291       else
292         return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
293                                         G->getName());
294     }
295 
296     // Extended table.
297     if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
298       uint32_t SymtabNdx = Sec.sh_link;
299       if (SymtabNdx >= Sections.size())
300         return make_error<JITLinkError>("sh_link is out of bound");
301 
302       auto ShndxTable = Obj.getSHNDXTable(Sec);
303       if (!ShndxTable)
304         return ShndxTable.takeError();
305 
306       ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
307     }
308   }
309 
310   return Error::success();
311 }
312 
313 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {
314   LLVM_DEBUG(dbgs() << "  Creating graph sections...\n");
315 
316   // For each section...
317   for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
318 
319     auto &Sec = Sections[SecIndex];
320 
321     // Start by getting the section name.
322     auto Name = Obj.getSectionName(Sec, SectionStringTab);
323     if (!Name)
324       return Name.takeError();
325     if (excludeSection(Sec)) {
326       LLVM_DEBUG({
327         dbgs() << "    " << SecIndex << ": Skipping section \"" << *Name
328                << "\" explicitly\n";
329       });
330       continue;
331     }
332 
333     // Skip null sections.
334     if (Sec.sh_type == ELF::SHT_NULL) {
335       LLVM_DEBUG({
336         dbgs() << "    " << SecIndex << ": has type SHT_NULL. Skipping.\n";
337       });
338       continue;
339     }
340 
341     // If the name indicates that it's a debug section then skip it: We don't
342     // support those yet.
343     if (!ProcessDebugSections && isDwarfSection(*Name)) {
344       LLVM_DEBUG({
345         dbgs() << "    " << SecIndex << ": \"" << *Name
346                << "\" is a debug section: "
347                   "No graph section will be created.\n";
348       });
349       continue;
350     }
351 
352     LLVM_DEBUG({
353       dbgs() << "    " << SecIndex << ": Creating section for \"" << *Name
354              << "\"\n";
355     });
356 
357     // Get the section's memory protection flags.
358     orc::MemProt Prot = orc::MemProt::Read;
359     if (Sec.sh_flags & ELF::SHF_EXECINSTR)
360       Prot |= orc::MemProt::Exec;
361     if (Sec.sh_flags & ELF::SHF_WRITE)
362       Prot |= orc::MemProt::Write;
363 
364     // Look for existing sections first.
365     auto *GraphSec = G->findSectionByName(*Name);
366     if (!GraphSec) {
367       GraphSec = &G->createSection(*Name, Prot);
368       // Non-SHF_ALLOC sections get NoAlloc memory lifetimes.
369       if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
370         GraphSec->setMemLifetime(orc::MemLifetime::NoAlloc);
371         LLVM_DEBUG({
372           dbgs() << "      " << SecIndex << ": \"" << *Name
373                  << "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n";
374         });
375       }
376     }
377 
378     if (GraphSec->getMemProt() != Prot) {
379       std::string ErrMsg;
380       raw_string_ostream(ErrMsg)
381           << "In " << G->getName() << ", section " << *Name
382           << " is present more than once with different permissions: "
383           << GraphSec->getMemProt() << " vs " << Prot;
384       return make_error<JITLinkError>(std::move(ErrMsg));
385     }
386 
387     Block *B = nullptr;
388     if (Sec.sh_type != ELF::SHT_NOBITS) {
389       auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
390       if (!Data)
391         return Data.takeError();
392 
393       B = &G->createContentBlock(*GraphSec, *Data,
394                                  orc::ExecutorAddr(Sec.sh_addr),
395                                  Sec.sh_addralign, 0);
396     } else
397       B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
398                                   orc::ExecutorAddr(Sec.sh_addr),
399                                   Sec.sh_addralign, 0);
400 
401     if (Sec.sh_type == ELF::SHT_ARM_EXIDX) {
402       // Add live symbol to avoid dead-stripping for .ARM.exidx sections
403       G->addAnonymousSymbol(*B, orc::ExecutorAddrDiff(),
404                             orc::ExecutorAddrDiff(), false, true);
405     }
406 
407     setGraphBlock(SecIndex, B);
408   }
409 
410   return Error::success();
411 }
412 
413 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
414   LLVM_DEBUG(dbgs() << "  Creating graph symbols...\n");
415 
416   // No SYMTAB -- Bail out early.
417   if (!SymTabSec)
418     return Error::success();
419 
420   // Get the section content as a Symbols array.
421   auto Symbols = Obj.symbols(SymTabSec);
422   if (!Symbols)
423     return Symbols.takeError();
424 
425   // Get the string table for this section.
426   auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
427   if (!StringTab)
428     return StringTab.takeError();
429 
430   LLVM_DEBUG({
431     StringRef SymTabName;
432 
433     if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
434       SymTabName = *SymTabNameOrErr;
435     else {
436       dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
437              << toString(SymTabNameOrErr.takeError()) << "\n";
438       SymTabName = "<SHT_SYMTAB section with invalid name>";
439     }
440 
441     dbgs() << "    Adding symbols from symtab section \"" << SymTabName
442            << "\"\n";
443   });
444 
445   for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
446     auto &Sym = (*Symbols)[SymIndex];
447 
448     // Check symbol type.
449     switch (Sym.getType()) {
450     case ELF::STT_FILE:
451       LLVM_DEBUG({
452         if (auto Name = Sym.getName(*StringTab))
453           dbgs() << "      " << SymIndex << ": Skipping STT_FILE symbol \""
454                  << *Name << "\"\n";
455         else {
456           dbgs() << "Could not get STT_FILE symbol name: "
457                  << toString(Name.takeError()) << "\n";
458           dbgs() << "     " << SymIndex
459                  << ": Skipping STT_FILE symbol with invalid name\n";
460         }
461       });
462       continue;
463       break;
464     }
465 
466     // Get the symbol name.
467     auto Name = Sym.getName(*StringTab);
468     if (!Name)
469       return Name.takeError();
470 
471     // Handle common symbols specially.
472     if (Sym.isCommon()) {
473       Symbol &GSym = G->addDefinedSymbol(
474           G->createZeroFillBlock(getCommonSection(), Sym.st_size,
475                                  orc::ExecutorAddr(), Sym.getValue(), 0),
476           0, *Name, Sym.st_size, Linkage::Weak, Scope::Default, false, false);
477       setGraphSymbol(SymIndex, GSym);
478       continue;
479     }
480 
481     if (Sym.isDefined() &&
482         (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
483          Sym.getType() == ELF::STT_OBJECT ||
484          Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {
485 
486       // Map Visibility and Binding to Scope and Linkage:
487       Linkage L;
488       Scope S;
489       if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
490         std::tie(L, S) = *LSOrErr;
491       else
492         return LSOrErr.takeError();
493 
494       // Handle extended tables.
495       unsigned Shndx = Sym.st_shndx;
496       if (Shndx == ELF::SHN_XINDEX) {
497         auto ShndxTable = ShndxTables.find(SymTabSec);
498         if (ShndxTable == ShndxTables.end())
499           continue;
500         auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
501             Sym, SymIndex, ShndxTable->second);
502         if (!NdxOrErr)
503           return NdxOrErr.takeError();
504         Shndx = *NdxOrErr;
505       }
506       if (auto *B = getGraphBlock(Shndx)) {
507         LLVM_DEBUG({
508           dbgs() << "      " << SymIndex
509                  << ": Creating defined graph symbol for ELF symbol \"" << *Name
510                  << "\"\n";
511         });
512 
513         TargetFlagsType Flags = makeTargetFlags(Sym);
514         orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags);
515 
516         if (Offset + Sym.st_size > B->getSize()) {
517           std::string ErrMsg;
518           raw_string_ostream ErrStream(ErrMsg);
519           ErrStream << "In " << G->getName() << ", symbol ";
520           if (!Name->empty())
521             ErrStream << *Name;
522           else
523             ErrStream << "<anon>";
524           ErrStream << " (" << (B->getAddress() + Offset) << " -- "
525                     << (B->getAddress() + Offset + Sym.st_size) << ") extends "
526                     << formatv("{0:x}", Offset + Sym.st_size - B->getSize())
527                     << " bytes past the end of its containing block ("
528                     << B->getRange() << ")";
529           return make_error<JITLinkError>(std::move(ErrMsg));
530         }
531 
532         // In RISCV, temporary symbols (Used to generate dwarf, eh_frame
533         // sections...) will appear in object code's symbol table, and LLVM does
534         // not use names on these temporary symbols (RISCV gnu toolchain uses
535         // names on these temporary symbols). If the symbol is unnamed, add an
536         // anonymous symbol.
537         auto &GSym =
538             Name->empty()
539                 ? G->addAnonymousSymbol(*B, Offset, Sym.st_size,
540                                         false, false)
541                 : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L,
542                                       S, Sym.getType() == ELF::STT_FUNC,
543                                       false);
544 
545         GSym.setTargetFlags(Flags);
546         setGraphSymbol(SymIndex, GSym);
547       }
548     } else if (Sym.isUndefined() && Sym.isExternal()) {
549       LLVM_DEBUG({
550         dbgs() << "      " << SymIndex
551                << ": Creating external graph symbol for ELF symbol \"" << *Name
552                << "\"\n";
553       });
554 
555       if (Sym.getBinding() != ELF::STB_GLOBAL &&
556           Sym.getBinding() != ELF::STB_WEAK)
557         return make_error<StringError>(
558             "Invalid symbol binding " +
559                 Twine(static_cast<int>(Sym.getBinding())) +
560                 " for external symbol " + *Name,
561             inconvertibleErrorCode());
562 
563       // If L is Linkage::Weak that means this is a weakly referenced symbol.
564       auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,
565                                         Sym.getBinding() == ELF::STB_WEAK);
566       setGraphSymbol(SymIndex, GSym);
567     } else if (Sym.isUndefined() && Sym.st_value == 0 && Sym.st_size == 0 &&
568                Sym.getType() == ELF::STT_NOTYPE &&
569                Sym.getBinding() == ELF::STB_LOCAL && Name->empty()) {
570       // Some relocations (e.g., R_RISCV_ALIGN) don't have a target symbol and
571       // use this kind of null symbol as a placeholder.
572       LLVM_DEBUG({
573         dbgs() << "      " << SymIndex << ": Creating null graph symbol\n";
574       });
575 
576       auto SymName =
577           G->allocateContent("__jitlink_ELF_SYM_UND_" + Twine(SymIndex));
578       auto SymNameRef = StringRef(SymName.data(), SymName.size());
579       auto &GSym = G->addAbsoluteSymbol(SymNameRef, orc::ExecutorAddr(0), 0,
580                                         Linkage::Strong, Scope::Local, false);
581       setGraphSymbol(SymIndex, GSym);
582     } else {
583       LLVM_DEBUG({
584         dbgs() << "      " << SymIndex
585                << ": Not creating graph symbol for ELF symbol \"" << *Name
586                << "\" with unrecognized type\n";
587       });
588     }
589   }
590 
591   return Error::success();
592 }
593 
594 template <typename ELFT>
595 template <typename RelocHandlerFunction>
596 Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation(
597     const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
598   // Only look into sections that store relocation entries.
599   if (RelSect.sh_type != ELF::SHT_RELA)
600     return Error::success();
601 
602   // sh_info contains the section header index of the target (FixupSection),
603   // which is the section to which all relocations in RelSect apply.
604   auto FixupSection = Obj.getSection(RelSect.sh_info);
605   if (!FixupSection)
606     return FixupSection.takeError();
607 
608   // Target sections have names in valid ELF object files.
609   Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
610   if (!Name)
611     return Name.takeError();
612   LLVM_DEBUG(dbgs() << "  " << *Name << ":\n");
613 
614   // Consider skipping these relocations.
615   if (!ProcessDebugSections && isDwarfSection(*Name)) {
616     LLVM_DEBUG(dbgs() << "    skipped (dwarf section)\n\n");
617     return Error::success();
618   }
619   if (excludeSection(**FixupSection)) {
620     LLVM_DEBUG(dbgs() << "    skipped (fixup section excluded explicitly)\n\n");
621     return Error::success();
622   }
623 
624   // Lookup the link-graph node corresponding to the target section name.
625   auto *BlockToFix = getGraphBlock(RelSect.sh_info);
626   if (!BlockToFix)
627     return make_error<StringError>(
628         "Refencing a section that wasn't added to the graph: " + *Name,
629         inconvertibleErrorCode());
630 
631   auto RelEntries = Obj.relas(RelSect);
632   if (!RelEntries)
633     return RelEntries.takeError();
634 
635   // Let the callee process relocation entries one by one.
636   for (const typename ELFT::Rela &R : *RelEntries)
637     if (Error Err = Func(R, **FixupSection, *BlockToFix))
638       return Err;
639 
640   LLVM_DEBUG(dbgs() << "\n");
641   return Error::success();
642 }
643 
644 template <typename ELFT>
645 template <typename RelocHandlerFunction>
646 Error ELFLinkGraphBuilder<ELFT>::forEachRelRelocation(
647     const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
648   // Only look into sections that store relocation entries.
649   if (RelSect.sh_type != ELF::SHT_REL)
650     return Error::success();
651 
652   // sh_info contains the section header index of the target (FixupSection),
653   // which is the section to which all relocations in RelSect apply.
654   auto FixupSection = Obj.getSection(RelSect.sh_info);
655   if (!FixupSection)
656     return FixupSection.takeError();
657 
658   // Target sections have names in valid ELF object files.
659   Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
660   if (!Name)
661     return Name.takeError();
662   LLVM_DEBUG(dbgs() << "  " << *Name << ":\n");
663 
664   // Consider skipping these relocations.
665   if (!ProcessDebugSections && isDwarfSection(*Name)) {
666     LLVM_DEBUG(dbgs() << "    skipped (dwarf section)\n\n");
667     return Error::success();
668   }
669   if (excludeSection(**FixupSection)) {
670     LLVM_DEBUG(dbgs() << "    skipped (fixup section excluded explicitly)\n\n");
671     return Error::success();
672   }
673 
674   // Lookup the link-graph node corresponding to the target section name.
675   auto *BlockToFix = getGraphBlock(RelSect.sh_info);
676   if (!BlockToFix)
677     return make_error<StringError>(
678         "Refencing a section that wasn't added to the graph: " + *Name,
679         inconvertibleErrorCode());
680 
681   auto RelEntries = Obj.rels(RelSect);
682   if (!RelEntries)
683     return RelEntries.takeError();
684 
685   // Let the callee process relocation entries one by one.
686   for (const typename ELFT::Rel &R : *RelEntries)
687     if (Error Err = Func(R, **FixupSection, *BlockToFix))
688       return Err;
689 
690   LLVM_DEBUG(dbgs() << "\n");
691   return Error::success();
692 }
693 
694 } // end namespace jitlink
695 } // end namespace llvm
696 
697 #undef DEBUG_TYPE
698 
699 #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
700