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:
ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G)30fe6060f1SDimitry Andric ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {}
31fe6060f1SDimitry Andric virtual ~ELFLinkGraphBuilderBase();
32fe6060f1SDimitry Andric
33fe6060f1SDimitry Andric protected:
isDwarfSection(StringRef SectionName)34fe6060f1SDimitry Andric static bool isDwarfSection(StringRef SectionName) {
35fe6060f1SDimitry Andric return llvm::is_contained(DwarfSectionNames, SectionName);
36fe6060f1SDimitry Andric }
37fe6060f1SDimitry Andric
getCommonSection()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.
setProcessDebugSections(bool ProcessDebugSections)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
isRelocatable()84fe6060f1SDimitry Andric bool isRelocatable() const {
85fe6060f1SDimitry Andric return Obj.getHeader().e_type == llvm::ELF::ET_REL;
86fe6060f1SDimitry Andric }
87fe6060f1SDimitry Andric
setGraphBlock(ELFSectionIndex SecIndex,Block * B)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
getGraphBlock(ELFSectionIndex SecIndex)9304eeddc0SDimitry Andric Block *getGraphBlock(ELFSectionIndex SecIndex) {
9406c3fb27SDimitry Andric return GraphBlocks.lookup(SecIndex);
95fe6060f1SDimitry Andric }
96fe6060f1SDimitry Andric
setGraphSymbol(ELFSymbolIndex SymIndex,Symbol & Sym)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
getGraphSymbol(ELFSymbolIndex SymIndex)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.
makeTargetFlags(const typename ELFT::Sym & Sym)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.
getRawOffset(const typename ELFT::Sym & Sym,TargetFlagsType Flags)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.
excludeSection(const typename ELFT::Shdr & Sect)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>
forEachRelaRelocation(const typename ELFT::Shdr & RelSect,ClassT * Instance,RelocHandlerMethod && Method)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>
forEachRelRelocation(const typename ELFT::Shdr & RelSect,ClassT * Instance,RelocHandlerMethod && Method)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>
ELFLinkGraphBuilder(const ELFFile & Obj,Triple TT,SubtargetFeatures Features,StringRef FileName,LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)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>
buildGraph()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>>
getSymbolLinkageAndScope(const typename ELFT::Sym & Sym,StringRef Name)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
prepare()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
graphifySections()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
graphifySymbols()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>
forEachRelaRelocation(const typename ELFT::Shdr & RelSect,RelocHandlerFunction && Func)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>
forEachRelRelocation(const typename ELFT::Shdr & RelSect,RelocHandlerFunction && Func)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