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