xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h (revision fe6060f10f634930ff71b7c50291ddc610da2475)
1*fe6060f1SDimitry Andric //===------- ELFLinkGraphBuilder.h - ELF LinkGraph builder ------*- C++ -*-===//
2*fe6060f1SDimitry Andric //
3*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*fe6060f1SDimitry Andric //
7*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8*fe6060f1SDimitry Andric //
9*fe6060f1SDimitry Andric // Generic ELF LinkGraph building code.
10*fe6060f1SDimitry Andric //
11*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
12*fe6060f1SDimitry Andric 
13*fe6060f1SDimitry Andric #ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
14*fe6060f1SDimitry Andric #define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
15*fe6060f1SDimitry Andric 
16*fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/JITLink/JITLink.h"
17*fe6060f1SDimitry Andric #include "llvm/Object/ELF.h"
18*fe6060f1SDimitry Andric #include "llvm/Support/Debug.h"
19*fe6060f1SDimitry Andric #include "llvm/Support/Error.h"
20*fe6060f1SDimitry Andric #include "llvm/Support/FormatVariadic.h"
21*fe6060f1SDimitry Andric 
22*fe6060f1SDimitry Andric #define DEBUG_TYPE "jitlink"
23*fe6060f1SDimitry Andric 
24*fe6060f1SDimitry Andric namespace llvm {
25*fe6060f1SDimitry Andric namespace jitlink {
26*fe6060f1SDimitry Andric 
27*fe6060f1SDimitry Andric /// Common link-graph building code shared between all ELFFiles.
28*fe6060f1SDimitry Andric class ELFLinkGraphBuilderBase {
29*fe6060f1SDimitry Andric public:
30*fe6060f1SDimitry Andric   ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {}
31*fe6060f1SDimitry Andric   virtual ~ELFLinkGraphBuilderBase();
32*fe6060f1SDimitry Andric 
33*fe6060f1SDimitry Andric protected:
34*fe6060f1SDimitry Andric   static bool isDwarfSection(StringRef SectionName) {
35*fe6060f1SDimitry Andric     return llvm::is_contained(DwarfSectionNames, SectionName);
36*fe6060f1SDimitry Andric   }
37*fe6060f1SDimitry Andric 
38*fe6060f1SDimitry Andric   Section &getCommonSection() {
39*fe6060f1SDimitry Andric     if (!CommonSection) {
40*fe6060f1SDimitry Andric       auto Prot = static_cast<sys::Memory::ProtectionFlags>(
41*fe6060f1SDimitry Andric           sys::Memory::MF_READ | sys::Memory::MF_WRITE);
42*fe6060f1SDimitry Andric       CommonSection = &G->createSection(CommonSectionName, Prot);
43*fe6060f1SDimitry Andric     }
44*fe6060f1SDimitry Andric     return *CommonSection;
45*fe6060f1SDimitry Andric   }
46*fe6060f1SDimitry Andric 
47*fe6060f1SDimitry Andric   std::unique_ptr<LinkGraph> G;
48*fe6060f1SDimitry Andric 
49*fe6060f1SDimitry Andric private:
50*fe6060f1SDimitry Andric   static StringRef CommonSectionName;
51*fe6060f1SDimitry Andric   static ArrayRef<const char *> DwarfSectionNames;
52*fe6060f1SDimitry Andric 
53*fe6060f1SDimitry Andric   Section *CommonSection = nullptr;
54*fe6060f1SDimitry Andric };
55*fe6060f1SDimitry Andric 
56*fe6060f1SDimitry Andric /// Ling-graph building code that's specific to the given ELFT, but common
57*fe6060f1SDimitry Andric /// across all architectures.
58*fe6060f1SDimitry Andric template <typename ELFT>
59*fe6060f1SDimitry Andric class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
60*fe6060f1SDimitry Andric   using ELFFile = object::ELFFile<ELFT>;
61*fe6060f1SDimitry Andric 
62*fe6060f1SDimitry Andric public:
63*fe6060f1SDimitry Andric   ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj, Triple TT,
64*fe6060f1SDimitry Andric                       StringRef FileName,
65*fe6060f1SDimitry Andric                       LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
66*fe6060f1SDimitry Andric 
67*fe6060f1SDimitry Andric   /// Attempt to construct and return the LinkGraph.
68*fe6060f1SDimitry Andric   Expected<std::unique_ptr<LinkGraph>> buildGraph();
69*fe6060f1SDimitry Andric 
70*fe6060f1SDimitry Andric   /// Call to derived class to handle relocations. These require
71*fe6060f1SDimitry Andric   /// architecture specific knowledge to map to JITLink edge kinds.
72*fe6060f1SDimitry Andric   virtual Error addRelocations() = 0;
73*fe6060f1SDimitry Andric 
74*fe6060f1SDimitry Andric protected:
75*fe6060f1SDimitry Andric   using ELFSectionIndex = unsigned;
76*fe6060f1SDimitry Andric   using ELFSymbolIndex = unsigned;
77*fe6060f1SDimitry Andric 
78*fe6060f1SDimitry Andric   bool isRelocatable() const {
79*fe6060f1SDimitry Andric     return Obj.getHeader().e_type == llvm::ELF::ET_REL;
80*fe6060f1SDimitry Andric   }
81*fe6060f1SDimitry Andric 
82*fe6060f1SDimitry Andric   void setGraphSection(ELFSectionIndex SecIndex, Section &Sec) {
83*fe6060f1SDimitry Andric     assert(!GraphSections.count(SecIndex) && "Duplicate section at index");
84*fe6060f1SDimitry Andric     GraphSections[SecIndex] = &Sec;
85*fe6060f1SDimitry Andric   }
86*fe6060f1SDimitry Andric 
87*fe6060f1SDimitry Andric   Section *getGraphSection(ELFSectionIndex SecIndex) {
88*fe6060f1SDimitry Andric     auto I = GraphSections.find(SecIndex);
89*fe6060f1SDimitry Andric     if (I == GraphSections.end())
90*fe6060f1SDimitry Andric       return nullptr;
91*fe6060f1SDimitry Andric     return I->second;
92*fe6060f1SDimitry Andric   }
93*fe6060f1SDimitry Andric 
94*fe6060f1SDimitry Andric   void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) {
95*fe6060f1SDimitry Andric     assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");
96*fe6060f1SDimitry Andric     GraphSymbols[SymIndex] = &Sym;
97*fe6060f1SDimitry Andric   }
98*fe6060f1SDimitry Andric 
99*fe6060f1SDimitry Andric   Symbol *getGraphSymbol(ELFSymbolIndex SymIndex) {
100*fe6060f1SDimitry Andric     auto I = GraphSymbols.find(SymIndex);
101*fe6060f1SDimitry Andric     if (I == GraphSymbols.end())
102*fe6060f1SDimitry Andric       return nullptr;
103*fe6060f1SDimitry Andric     return I->second;
104*fe6060f1SDimitry Andric   }
105*fe6060f1SDimitry Andric 
106*fe6060f1SDimitry Andric   Expected<std::pair<Linkage, Scope>>
107*fe6060f1SDimitry Andric   getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
108*fe6060f1SDimitry Andric 
109*fe6060f1SDimitry Andric   Error prepare();
110*fe6060f1SDimitry Andric   Error graphifySections();
111*fe6060f1SDimitry Andric   Error graphifySymbols();
112*fe6060f1SDimitry Andric 
113*fe6060f1SDimitry Andric   const ELFFile &Obj;
114*fe6060f1SDimitry Andric 
115*fe6060f1SDimitry Andric   typename ELFFile::Elf_Shdr_Range Sections;
116*fe6060f1SDimitry Andric   const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
117*fe6060f1SDimitry Andric   StringRef SectionStringTab;
118*fe6060f1SDimitry Andric 
119*fe6060f1SDimitry Andric   // Maps ELF section indexes to LinkGraph Sections.
120*fe6060f1SDimitry Andric   // Only SHF_ALLOC sections will have graph sections.
121*fe6060f1SDimitry Andric   DenseMap<ELFSectionIndex, Section *> GraphSections;
122*fe6060f1SDimitry Andric   DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols;
123*fe6060f1SDimitry Andric };
124*fe6060f1SDimitry Andric 
125*fe6060f1SDimitry Andric template <typename ELFT>
126*fe6060f1SDimitry Andric ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder(
127*fe6060f1SDimitry Andric     const ELFFile &Obj, Triple TT, StringRef FileName,
128*fe6060f1SDimitry Andric     LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
129*fe6060f1SDimitry Andric     : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
130*fe6060f1SDimitry Andric           FileName.str(), Triple(std::move(TT)), ELFT::Is64Bits ? 8 : 4,
131*fe6060f1SDimitry Andric           support::endianness(ELFT::TargetEndianness),
132*fe6060f1SDimitry Andric           std::move(GetEdgeKindName))),
133*fe6060f1SDimitry Andric       Obj(Obj) {
134*fe6060f1SDimitry Andric   LLVM_DEBUG(
135*fe6060f1SDimitry Andric       { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
136*fe6060f1SDimitry Andric }
137*fe6060f1SDimitry Andric 
138*fe6060f1SDimitry Andric template <typename ELFT>
139*fe6060f1SDimitry Andric Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() {
140*fe6060f1SDimitry Andric   if (!isRelocatable())
141*fe6060f1SDimitry Andric     return make_error<JITLinkError>("Object is not a relocatable ELF file");
142*fe6060f1SDimitry Andric 
143*fe6060f1SDimitry Andric   if (auto Err = prepare())
144*fe6060f1SDimitry Andric     return std::move(Err);
145*fe6060f1SDimitry Andric 
146*fe6060f1SDimitry Andric   if (auto Err = graphifySections())
147*fe6060f1SDimitry Andric     return std::move(Err);
148*fe6060f1SDimitry Andric 
149*fe6060f1SDimitry Andric   if (auto Err = graphifySymbols())
150*fe6060f1SDimitry Andric     return std::move(Err);
151*fe6060f1SDimitry Andric 
152*fe6060f1SDimitry Andric   if (auto Err = addRelocations())
153*fe6060f1SDimitry Andric     return std::move(Err);
154*fe6060f1SDimitry Andric 
155*fe6060f1SDimitry Andric   return std::move(G);
156*fe6060f1SDimitry Andric }
157*fe6060f1SDimitry Andric 
158*fe6060f1SDimitry Andric template <typename ELFT>
159*fe6060f1SDimitry Andric Expected<std::pair<Linkage, Scope>>
160*fe6060f1SDimitry Andric ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope(
161*fe6060f1SDimitry Andric     const typename ELFT::Sym &Sym, StringRef Name) {
162*fe6060f1SDimitry Andric   Linkage L = Linkage::Strong;
163*fe6060f1SDimitry Andric   Scope S = Scope::Default;
164*fe6060f1SDimitry Andric 
165*fe6060f1SDimitry Andric   switch (Sym.getBinding()) {
166*fe6060f1SDimitry Andric   case ELF::STB_LOCAL:
167*fe6060f1SDimitry Andric     S = Scope::Local;
168*fe6060f1SDimitry Andric     break;
169*fe6060f1SDimitry Andric   case ELF::STB_GLOBAL:
170*fe6060f1SDimitry Andric     // Nothing to do here.
171*fe6060f1SDimitry Andric     break;
172*fe6060f1SDimitry Andric   case ELF::STB_WEAK:
173*fe6060f1SDimitry Andric     L = Linkage::Weak;
174*fe6060f1SDimitry Andric     break;
175*fe6060f1SDimitry Andric   default:
176*fe6060f1SDimitry Andric     return make_error<StringError>("Unrecognized symbol binding for " + Name,
177*fe6060f1SDimitry Andric                                    inconvertibleErrorCode());
178*fe6060f1SDimitry Andric   }
179*fe6060f1SDimitry Andric 
180*fe6060f1SDimitry Andric   switch (Sym.getVisibility()) {
181*fe6060f1SDimitry Andric   case ELF::STV_DEFAULT:
182*fe6060f1SDimitry Andric   case ELF::STV_PROTECTED:
183*fe6060f1SDimitry Andric     // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
184*fe6060f1SDimitry Andric     // Orc support.
185*fe6060f1SDimitry Andric     // Otherwise nothing to do here.
186*fe6060f1SDimitry Andric     break;
187*fe6060f1SDimitry Andric   case ELF::STV_HIDDEN:
188*fe6060f1SDimitry Andric     // Default scope -> Hidden scope. No effect on local scope.
189*fe6060f1SDimitry Andric     if (S == Scope::Default)
190*fe6060f1SDimitry Andric       S = Scope::Hidden;
191*fe6060f1SDimitry Andric     break;
192*fe6060f1SDimitry Andric   case ELF::STV_INTERNAL:
193*fe6060f1SDimitry Andric     return make_error<StringError>("Unrecognized symbol visibility for " + Name,
194*fe6060f1SDimitry Andric                                    inconvertibleErrorCode());
195*fe6060f1SDimitry Andric   }
196*fe6060f1SDimitry Andric 
197*fe6060f1SDimitry Andric   return std::make_pair(L, S);
198*fe6060f1SDimitry Andric }
199*fe6060f1SDimitry Andric 
200*fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
201*fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "  Preparing to build...\n");
202*fe6060f1SDimitry Andric 
203*fe6060f1SDimitry Andric   // Get the sections array.
204*fe6060f1SDimitry Andric   if (auto SectionsOrErr = Obj.sections())
205*fe6060f1SDimitry Andric     Sections = *SectionsOrErr;
206*fe6060f1SDimitry Andric   else
207*fe6060f1SDimitry Andric     return SectionsOrErr.takeError();
208*fe6060f1SDimitry Andric 
209*fe6060f1SDimitry Andric   // Get the section string table.
210*fe6060f1SDimitry Andric   if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
211*fe6060f1SDimitry Andric     SectionStringTab = *SectionStringTabOrErr;
212*fe6060f1SDimitry Andric   else
213*fe6060f1SDimitry Andric     return SectionStringTabOrErr.takeError();
214*fe6060f1SDimitry Andric 
215*fe6060f1SDimitry Andric   // Get the SHT_SYMTAB section.
216*fe6060f1SDimitry Andric   for (auto &Sec : Sections)
217*fe6060f1SDimitry Andric     if (Sec.sh_type == ELF::SHT_SYMTAB) {
218*fe6060f1SDimitry Andric       if (!SymTabSec)
219*fe6060f1SDimitry Andric         SymTabSec = &Sec;
220*fe6060f1SDimitry Andric       else
221*fe6060f1SDimitry Andric         return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
222*fe6060f1SDimitry Andric                                         G->getName());
223*fe6060f1SDimitry Andric     }
224*fe6060f1SDimitry Andric 
225*fe6060f1SDimitry Andric   return Error::success();
226*fe6060f1SDimitry Andric }
227*fe6060f1SDimitry Andric 
228*fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {
229*fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "  Creating graph sections...\n");
230*fe6060f1SDimitry Andric 
231*fe6060f1SDimitry Andric   // For each section...
232*fe6060f1SDimitry Andric   for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
233*fe6060f1SDimitry Andric 
234*fe6060f1SDimitry Andric     auto &Sec = Sections[SecIndex];
235*fe6060f1SDimitry Andric 
236*fe6060f1SDimitry Andric     // Start by getting the section name.
237*fe6060f1SDimitry Andric     auto Name = Obj.getSectionName(Sec, SectionStringTab);
238*fe6060f1SDimitry Andric     if (!Name)
239*fe6060f1SDimitry Andric       return Name.takeError();
240*fe6060f1SDimitry Andric 
241*fe6060f1SDimitry Andric     // If the name indicates that it's a debug section then skip it: We don't
242*fe6060f1SDimitry Andric     // support those yet.
243*fe6060f1SDimitry Andric     if (isDwarfSection(*Name)) {
244*fe6060f1SDimitry Andric       LLVM_DEBUG({
245*fe6060f1SDimitry Andric         dbgs() << "    " << SecIndex << ": \"" << *Name
246*fe6060f1SDimitry Andric                << "\" is a debug section: "
247*fe6060f1SDimitry Andric                   "No graph section will be created.\n";
248*fe6060f1SDimitry Andric       });
249*fe6060f1SDimitry Andric       continue;
250*fe6060f1SDimitry Andric     }
251*fe6060f1SDimitry Andric 
252*fe6060f1SDimitry Andric     // Skip non-SHF_ALLOC sections
253*fe6060f1SDimitry Andric     if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
254*fe6060f1SDimitry Andric       LLVM_DEBUG({
255*fe6060f1SDimitry Andric         dbgs() << "    " << SecIndex << ": \"" << *Name
256*fe6060f1SDimitry Andric                << "\" is not an SHF_ALLOC section: "
257*fe6060f1SDimitry Andric                   "No graph section will be created.\n";
258*fe6060f1SDimitry Andric       });
259*fe6060f1SDimitry Andric       continue;
260*fe6060f1SDimitry Andric     }
261*fe6060f1SDimitry Andric 
262*fe6060f1SDimitry Andric     LLVM_DEBUG({
263*fe6060f1SDimitry Andric       dbgs() << "    " << SecIndex << ": Creating section for \"" << *Name
264*fe6060f1SDimitry Andric              << "\"\n";
265*fe6060f1SDimitry Andric     });
266*fe6060f1SDimitry Andric 
267*fe6060f1SDimitry Andric     // Get the section's memory protection flags.
268*fe6060f1SDimitry Andric     sys::Memory::ProtectionFlags Prot;
269*fe6060f1SDimitry Andric     if (Sec.sh_flags & ELF::SHF_EXECINSTR)
270*fe6060f1SDimitry Andric       Prot = static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
271*fe6060f1SDimitry Andric                                                        sys::Memory::MF_EXEC);
272*fe6060f1SDimitry Andric     else
273*fe6060f1SDimitry Andric       Prot = static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
274*fe6060f1SDimitry Andric                                                        sys::Memory::MF_WRITE);
275*fe6060f1SDimitry Andric 
276*fe6060f1SDimitry Andric     // For now we just use this to skip the "undefined" section, probably need
277*fe6060f1SDimitry Andric     // to revist.
278*fe6060f1SDimitry Andric     if (Sec.sh_size == 0)
279*fe6060f1SDimitry Andric       continue;
280*fe6060f1SDimitry Andric 
281*fe6060f1SDimitry Andric     auto &GraphSec = G->createSection(*Name, Prot);
282*fe6060f1SDimitry Andric     if (Sec.sh_type != ELF::SHT_NOBITS) {
283*fe6060f1SDimitry Andric       auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
284*fe6060f1SDimitry Andric       if (!Data)
285*fe6060f1SDimitry Andric         return Data.takeError();
286*fe6060f1SDimitry Andric 
287*fe6060f1SDimitry Andric       G->createContentBlock(GraphSec, *Data, Sec.sh_addr, Sec.sh_addralign, 0);
288*fe6060f1SDimitry Andric     } else
289*fe6060f1SDimitry Andric       G->createZeroFillBlock(GraphSec, Sec.sh_size, Sec.sh_addr,
290*fe6060f1SDimitry Andric                              Sec.sh_addralign, 0);
291*fe6060f1SDimitry Andric 
292*fe6060f1SDimitry Andric     setGraphSection(SecIndex, GraphSec);
293*fe6060f1SDimitry Andric   }
294*fe6060f1SDimitry Andric 
295*fe6060f1SDimitry Andric   return Error::success();
296*fe6060f1SDimitry Andric }
297*fe6060f1SDimitry Andric 
298*fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
299*fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "  Creating graph symbols...\n");
300*fe6060f1SDimitry Andric 
301*fe6060f1SDimitry Andric   // No SYMTAB -- Bail out early.
302*fe6060f1SDimitry Andric   if (!SymTabSec)
303*fe6060f1SDimitry Andric     return Error::success();
304*fe6060f1SDimitry Andric 
305*fe6060f1SDimitry Andric   // Get the section content as a Symbols array.
306*fe6060f1SDimitry Andric   auto Symbols = Obj.symbols(SymTabSec);
307*fe6060f1SDimitry Andric   if (!Symbols)
308*fe6060f1SDimitry Andric     return Symbols.takeError();
309*fe6060f1SDimitry Andric 
310*fe6060f1SDimitry Andric   // Get the string table for this section.
311*fe6060f1SDimitry Andric   auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
312*fe6060f1SDimitry Andric   if (!StringTab)
313*fe6060f1SDimitry Andric     return StringTab.takeError();
314*fe6060f1SDimitry Andric 
315*fe6060f1SDimitry Andric   LLVM_DEBUG({
316*fe6060f1SDimitry Andric     StringRef SymTabName;
317*fe6060f1SDimitry Andric 
318*fe6060f1SDimitry Andric     if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
319*fe6060f1SDimitry Andric       SymTabName = *SymTabNameOrErr;
320*fe6060f1SDimitry Andric     else {
321*fe6060f1SDimitry Andric       dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
322*fe6060f1SDimitry Andric              << toString(SymTabNameOrErr.takeError()) << "\n";
323*fe6060f1SDimitry Andric       SymTabName = "<SHT_SYMTAB section with invalid name>";
324*fe6060f1SDimitry Andric     }
325*fe6060f1SDimitry Andric 
326*fe6060f1SDimitry Andric     dbgs() << "    Adding symbols from symtab section \"" << SymTabName
327*fe6060f1SDimitry Andric            << "\"\n";
328*fe6060f1SDimitry Andric   });
329*fe6060f1SDimitry Andric 
330*fe6060f1SDimitry Andric   for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
331*fe6060f1SDimitry Andric     auto &Sym = (*Symbols)[SymIndex];
332*fe6060f1SDimitry Andric 
333*fe6060f1SDimitry Andric     // Check symbol type.
334*fe6060f1SDimitry Andric     switch (Sym.getType()) {
335*fe6060f1SDimitry Andric     case ELF::STT_FILE:
336*fe6060f1SDimitry Andric       LLVM_DEBUG({
337*fe6060f1SDimitry Andric         if (auto Name = Sym.getName(*StringTab))
338*fe6060f1SDimitry Andric           dbgs() << "      " << SymIndex << ": Skipping STT_FILE symbol \""
339*fe6060f1SDimitry Andric                  << *Name << "\"\n";
340*fe6060f1SDimitry Andric         else {
341*fe6060f1SDimitry Andric           dbgs() << "Could not get STT_FILE symbol name: "
342*fe6060f1SDimitry Andric                  << toString(Name.takeError()) << "\n";
343*fe6060f1SDimitry Andric           dbgs() << "     " << SymIndex
344*fe6060f1SDimitry Andric                  << ": Skipping STT_FILE symbol with invalid name\n";
345*fe6060f1SDimitry Andric         }
346*fe6060f1SDimitry Andric       });
347*fe6060f1SDimitry Andric       continue;
348*fe6060f1SDimitry Andric       break;
349*fe6060f1SDimitry Andric     }
350*fe6060f1SDimitry Andric 
351*fe6060f1SDimitry Andric     // Get the symbol name.
352*fe6060f1SDimitry Andric     auto Name = Sym.getName(*StringTab);
353*fe6060f1SDimitry Andric     if (!Name)
354*fe6060f1SDimitry Andric       return Name.takeError();
355*fe6060f1SDimitry Andric 
356*fe6060f1SDimitry Andric     // Handle common symbols specially.
357*fe6060f1SDimitry Andric     if (Sym.isCommon()) {
358*fe6060f1SDimitry Andric       Symbol &GSym =
359*fe6060f1SDimitry Andric           G->addCommonSymbol(*Name, Scope::Default, getCommonSection(), 0,
360*fe6060f1SDimitry Andric                              Sym.st_size, Sym.getValue(), false);
361*fe6060f1SDimitry Andric       setGraphSymbol(SymIndex, GSym);
362*fe6060f1SDimitry Andric       continue;
363*fe6060f1SDimitry Andric     }
364*fe6060f1SDimitry Andric 
365*fe6060f1SDimitry Andric     // Map Visibility and Binding to Scope and Linkage:
366*fe6060f1SDimitry Andric     Linkage L;
367*fe6060f1SDimitry Andric     Scope S;
368*fe6060f1SDimitry Andric 
369*fe6060f1SDimitry Andric     if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
370*fe6060f1SDimitry Andric       std::tie(L, S) = *LSOrErr;
371*fe6060f1SDimitry Andric     else
372*fe6060f1SDimitry Andric       return LSOrErr.takeError();
373*fe6060f1SDimitry Andric 
374*fe6060f1SDimitry Andric     if (Sym.isDefined() &&
375*fe6060f1SDimitry Andric         (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
376*fe6060f1SDimitry Andric          Sym.getType() == ELF::STT_OBJECT ||
377*fe6060f1SDimitry Andric          Sym.getType() == ELF::STT_SECTION)) {
378*fe6060f1SDimitry Andric 
379*fe6060f1SDimitry Andric       // FIXME: Handle extended tables.
380*fe6060f1SDimitry Andric       if (auto *GraphSec = getGraphSection(Sym.st_shndx)) {
381*fe6060f1SDimitry Andric         Block *B = nullptr;
382*fe6060f1SDimitry Andric         {
383*fe6060f1SDimitry Andric           auto Blocks = GraphSec->blocks();
384*fe6060f1SDimitry Andric           assert(Blocks.begin() != Blocks.end() && "No blocks for section");
385*fe6060f1SDimitry Andric           assert(std::next(Blocks.begin()) == Blocks.end() &&
386*fe6060f1SDimitry Andric                  "Multiple blocks for section");
387*fe6060f1SDimitry Andric           B = *Blocks.begin();
388*fe6060f1SDimitry Andric         }
389*fe6060f1SDimitry Andric 
390*fe6060f1SDimitry Andric         LLVM_DEBUG({
391*fe6060f1SDimitry Andric           dbgs() << "      " << SymIndex
392*fe6060f1SDimitry Andric                  << ": Creating defined graph symbol for ELF symbol \"" << *Name
393*fe6060f1SDimitry Andric                  << "\"\n";
394*fe6060f1SDimitry Andric         });
395*fe6060f1SDimitry Andric 
396*fe6060f1SDimitry Andric         if (Sym.getType() == ELF::STT_SECTION)
397*fe6060f1SDimitry Andric           *Name = GraphSec->getName();
398*fe6060f1SDimitry Andric 
399*fe6060f1SDimitry Andric         auto &GSym =
400*fe6060f1SDimitry Andric             G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L, S,
401*fe6060f1SDimitry Andric                                 Sym.getType() == ELF::STT_FUNC, false);
402*fe6060f1SDimitry Andric         setGraphSymbol(SymIndex, GSym);
403*fe6060f1SDimitry Andric       }
404*fe6060f1SDimitry Andric     } else if (Sym.isUndefined() && Sym.isExternal()) {
405*fe6060f1SDimitry Andric       LLVM_DEBUG({
406*fe6060f1SDimitry Andric         dbgs() << "      " << SymIndex
407*fe6060f1SDimitry Andric                << ": Creating external graph symbol for ELF symbol \"" << *Name
408*fe6060f1SDimitry Andric                << "\"\n";
409*fe6060f1SDimitry Andric       });
410*fe6060f1SDimitry Andric       auto &GSym = G->addExternalSymbol(*Name, Sym.st_size, L);
411*fe6060f1SDimitry Andric       setGraphSymbol(SymIndex, GSym);
412*fe6060f1SDimitry Andric     } else {
413*fe6060f1SDimitry Andric       LLVM_DEBUG({
414*fe6060f1SDimitry Andric         dbgs() << "      " << SymIndex
415*fe6060f1SDimitry Andric                << ": Not creating graph symbol for ELF symbol \"" << *Name
416*fe6060f1SDimitry Andric                << "\" with unrecognized type\n";
417*fe6060f1SDimitry Andric       });
418*fe6060f1SDimitry Andric     }
419*fe6060f1SDimitry Andric   }
420*fe6060f1SDimitry Andric 
421*fe6060f1SDimitry Andric   return Error::success();
422*fe6060f1SDimitry Andric }
423*fe6060f1SDimitry Andric 
424*fe6060f1SDimitry Andric } // end namespace jitlink
425*fe6060f1SDimitry Andric } // end namespace llvm
426*fe6060f1SDimitry Andric 
427*fe6060f1SDimitry Andric #undef DEBUG_TYPE
428*fe6060f1SDimitry Andric 
429*fe6060f1SDimitry Andric #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
430