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 =
41           &G->createSection(CommonSectionName, MemProt::Read | 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 /// Ling-graph 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, Triple TT,
62                       StringRef FileName,
63                       LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
64 
65   /// Attempt to construct and return the LinkGraph.
66   Expected<std::unique_ptr<LinkGraph>> buildGraph();
67 
68   /// Call to derived class to handle relocations. These require
69   /// architecture specific knowledge to map to JITLink edge kinds.
70   virtual Error addRelocations() = 0;
71 
72 protected:
73   using ELFSectionIndex = unsigned;
74   using ELFSymbolIndex = unsigned;
75 
76   bool isRelocatable() const {
77     return Obj.getHeader().e_type == llvm::ELF::ET_REL;
78   }
79 
80   void setGraphBlock(ELFSectionIndex SecIndex, Block *B) {
81     assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index");
82     GraphBlocks[SecIndex] = B;
83   }
84 
85   Block *getGraphBlock(ELFSectionIndex SecIndex) {
86     auto I = GraphBlocks.find(SecIndex);
87     if (I == GraphBlocks.end())
88       return nullptr;
89     return I->second;
90   }
91 
92   void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) {
93     assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");
94     GraphSymbols[SymIndex] = &Sym;
95   }
96 
97   Symbol *getGraphSymbol(ELFSymbolIndex SymIndex) {
98     auto I = GraphSymbols.find(SymIndex);
99     if (I == GraphSymbols.end())
100       return nullptr;
101     return I->second;
102   }
103 
104   Expected<std::pair<Linkage, Scope>>
105   getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
106 
107   Error prepare();
108   Error graphifySections();
109   Error graphifySymbols();
110 
111   /// Traverse all matching relocation records in the given section. The handler
112   /// function Func should be callable with this signature:
113   ///   Error(const typename ELFT::Rela &,
114   ///         const typename ELFT::Shdr &, Section &)
115   ///
116   template <typename RelocHandlerFunction>
117   Error forEachRelocation(const typename ELFT::Shdr &RelSect,
118                           RelocHandlerFunction &&Func,
119                           bool ProcessDebugSections = false);
120 
121   /// Traverse all matching relocation records in the given section. Convenience
122   /// wrapper to allow passing a member function for the handler.
123   ///
124   template <typename ClassT, typename RelocHandlerMethod>
125   Error forEachRelocation(const typename ELFT::Shdr &RelSect, ClassT *Instance,
126                           RelocHandlerMethod &&Method,
127                           bool ProcessDebugSections = false) {
128     return forEachRelocation(
129         RelSect,
130         [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
131           return (Instance->*Method)(Rel, Target, GS);
132         },
133         ProcessDebugSections);
134   }
135 
136   const ELFFile &Obj;
137 
138   typename ELFFile::Elf_Shdr_Range Sections;
139   const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
140   StringRef SectionStringTab;
141 
142   // Maps ELF section indexes to LinkGraph Blocks.
143   // Only SHF_ALLOC sections will have graph blocks.
144   DenseMap<ELFSectionIndex, Block *> GraphBlocks;
145   DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols;
146   DenseMap<const typename ELFFile::Elf_Shdr *,
147            ArrayRef<typename ELFFile::Elf_Word>>
148       ShndxTables;
149 };
150 
151 template <typename ELFT>
152 ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder(
153     const ELFFile &Obj, Triple TT, StringRef FileName,
154     LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
155     : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
156           FileName.str(), Triple(std::move(TT)), ELFT::Is64Bits ? 8 : 4,
157           support::endianness(ELFT::TargetEndianness),
158           std::move(GetEdgeKindName))),
159       Obj(Obj) {
160   LLVM_DEBUG(
161       { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
162 }
163 
164 template <typename ELFT>
165 Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() {
166   if (!isRelocatable())
167     return make_error<JITLinkError>("Object is not a relocatable ELF file");
168 
169   if (auto Err = prepare())
170     return std::move(Err);
171 
172   if (auto Err = graphifySections())
173     return std::move(Err);
174 
175   if (auto Err = graphifySymbols())
176     return std::move(Err);
177 
178   if (auto Err = addRelocations())
179     return std::move(Err);
180 
181   return std::move(G);
182 }
183 
184 template <typename ELFT>
185 Expected<std::pair<Linkage, Scope>>
186 ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope(
187     const typename ELFT::Sym &Sym, StringRef Name) {
188   Linkage L = Linkage::Strong;
189   Scope S = Scope::Default;
190 
191   switch (Sym.getBinding()) {
192   case ELF::STB_LOCAL:
193     S = Scope::Local;
194     break;
195   case ELF::STB_GLOBAL:
196     // Nothing to do here.
197     break;
198   case ELF::STB_WEAK:
199   case ELF::STB_GNU_UNIQUE:
200     L = Linkage::Weak;
201     break;
202   default:
203     return make_error<StringError>(
204         "Unrecognized symbol binding " +
205             Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
206         inconvertibleErrorCode());
207   }
208 
209   switch (Sym.getVisibility()) {
210   case ELF::STV_DEFAULT:
211   case ELF::STV_PROTECTED:
212     // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
213     // Orc support.
214     // Otherwise nothing to do here.
215     break;
216   case ELF::STV_HIDDEN:
217     // Default scope -> Hidden scope. No effect on local scope.
218     if (S == Scope::Default)
219       S = Scope::Hidden;
220     break;
221   case ELF::STV_INTERNAL:
222     return make_error<StringError>(
223         "Unrecognized symbol visibility " +
224             Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,
225         inconvertibleErrorCode());
226   }
227 
228   return std::make_pair(L, S);
229 }
230 
231 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
232   LLVM_DEBUG(dbgs() << "  Preparing to build...\n");
233 
234   // Get the sections array.
235   if (auto SectionsOrErr = Obj.sections())
236     Sections = *SectionsOrErr;
237   else
238     return SectionsOrErr.takeError();
239 
240   // Get the section string table.
241   if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
242     SectionStringTab = *SectionStringTabOrErr;
243   else
244     return SectionStringTabOrErr.takeError();
245 
246   // Get the SHT_SYMTAB section.
247   for (auto &Sec : Sections) {
248     if (Sec.sh_type == ELF::SHT_SYMTAB) {
249       if (!SymTabSec)
250         SymTabSec = &Sec;
251       else
252         return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
253                                         G->getName());
254     }
255 
256     // Extended table.
257     if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
258       uint32_t SymtabNdx = Sec.sh_link;
259       if (SymtabNdx >= Sections.size())
260         return make_error<JITLinkError>("sh_link is out of bound");
261 
262       auto ShndxTable = Obj.getSHNDXTable(Sec);
263       if (!ShndxTable)
264         return ShndxTable.takeError();
265 
266       ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
267     }
268   }
269 
270   return Error::success();
271 }
272 
273 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {
274   LLVM_DEBUG(dbgs() << "  Creating graph sections...\n");
275 
276   // For each section...
277   for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
278 
279     auto &Sec = Sections[SecIndex];
280 
281     // Start by getting the section name.
282     auto Name = Obj.getSectionName(Sec, SectionStringTab);
283     if (!Name)
284       return Name.takeError();
285 
286     // If the name indicates that it's a debug section then skip it: We don't
287     // support those yet.
288     if (isDwarfSection(*Name)) {
289       LLVM_DEBUG({
290         dbgs() << "    " << SecIndex << ": \"" << *Name
291                << "\" is a debug section: "
292                   "No graph section will be created.\n";
293       });
294       continue;
295     }
296 
297     // Skip non-SHF_ALLOC sections
298     if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
299       LLVM_DEBUG({
300         dbgs() << "    " << SecIndex << ": \"" << *Name
301                << "\" is not an SHF_ALLOC section: "
302                   "No graph section will be created.\n";
303       });
304       continue;
305     }
306 
307     LLVM_DEBUG({
308       dbgs() << "    " << SecIndex << ": Creating section for \"" << *Name
309              << "\"\n";
310     });
311 
312     // Get the section's memory protection flags.
313     MemProt Prot;
314     if (Sec.sh_flags & ELF::SHF_EXECINSTR)
315       Prot = MemProt::Read | MemProt::Exec;
316     else
317       Prot = MemProt::Read | MemProt::Write;
318 
319     // Look for existing sections first.
320     auto *GraphSec = G->findSectionByName(*Name);
321     if (!GraphSec)
322       GraphSec = &G->createSection(*Name, Prot);
323     assert(GraphSec->getMemProt() == Prot && "MemProt should match");
324 
325     Block *B = nullptr;
326     if (Sec.sh_type != ELF::SHT_NOBITS) {
327       auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
328       if (!Data)
329         return Data.takeError();
330 
331       B = &G->createContentBlock(*GraphSec, *Data,
332                                  orc::ExecutorAddr(Sec.sh_addr),
333                                  Sec.sh_addralign, 0);
334     } else
335       B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
336                                   orc::ExecutorAddr(Sec.sh_addr),
337                                   Sec.sh_addralign, 0);
338 
339     setGraphBlock(SecIndex, B);
340   }
341 
342   return Error::success();
343 }
344 
345 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
346   LLVM_DEBUG(dbgs() << "  Creating graph symbols...\n");
347 
348   // No SYMTAB -- Bail out early.
349   if (!SymTabSec)
350     return Error::success();
351 
352   // Get the section content as a Symbols array.
353   auto Symbols = Obj.symbols(SymTabSec);
354   if (!Symbols)
355     return Symbols.takeError();
356 
357   // Get the string table for this section.
358   auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
359   if (!StringTab)
360     return StringTab.takeError();
361 
362   LLVM_DEBUG({
363     StringRef SymTabName;
364 
365     if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
366       SymTabName = *SymTabNameOrErr;
367     else {
368       dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
369              << toString(SymTabNameOrErr.takeError()) << "\n";
370       SymTabName = "<SHT_SYMTAB section with invalid name>";
371     }
372 
373     dbgs() << "    Adding symbols from symtab section \"" << SymTabName
374            << "\"\n";
375   });
376 
377   for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
378     auto &Sym = (*Symbols)[SymIndex];
379 
380     // Check symbol type.
381     switch (Sym.getType()) {
382     case ELF::STT_FILE:
383       LLVM_DEBUG({
384         if (auto Name = Sym.getName(*StringTab))
385           dbgs() << "      " << SymIndex << ": Skipping STT_FILE symbol \""
386                  << *Name << "\"\n";
387         else {
388           dbgs() << "Could not get STT_FILE symbol name: "
389                  << toString(Name.takeError()) << "\n";
390           dbgs() << "     " << SymIndex
391                  << ": Skipping STT_FILE symbol with invalid name\n";
392         }
393       });
394       continue;
395       break;
396     }
397 
398     // Get the symbol name.
399     auto Name = Sym.getName(*StringTab);
400     if (!Name)
401       return Name.takeError();
402 
403     // Handle common symbols specially.
404     if (Sym.isCommon()) {
405       Symbol &GSym = G->addCommonSymbol(*Name, Scope::Default,
406                                         getCommonSection(), orc::ExecutorAddr(),
407                                         Sym.st_size, Sym.getValue(), false);
408       setGraphSymbol(SymIndex, GSym);
409       continue;
410     }
411 
412     // Map Visibility and Binding to Scope and Linkage:
413     Linkage L;
414     Scope S;
415 
416     if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
417       std::tie(L, S) = *LSOrErr;
418     else
419       return LSOrErr.takeError();
420 
421     if (Sym.isDefined() &&
422         (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
423          Sym.getType() == ELF::STT_OBJECT ||
424          Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {
425       // Handle extended tables.
426       unsigned Shndx = Sym.st_shndx;
427       if (Shndx == ELF::SHN_XINDEX) {
428         auto ShndxTable = ShndxTables.find(SymTabSec);
429         if (ShndxTable == ShndxTables.end())
430           continue;
431         auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
432             Sym, SymIndex, ShndxTable->second);
433         if (!NdxOrErr)
434           return NdxOrErr.takeError();
435         Shndx = *NdxOrErr;
436       }
437       if (auto *B = getGraphBlock(Shndx)) {
438         LLVM_DEBUG({
439           dbgs() << "      " << SymIndex
440                  << ": Creating defined graph symbol for ELF symbol \"" << *Name
441                  << "\"\n";
442         });
443 
444         // In RISCV, temporary symbols (Used to generate dwarf, eh_frame
445         // sections...) will appear in object code's symbol table, and LLVM does
446         // not use names on these temporary symbols (RISCV gnu toolchain uses
447         // names on these temporary symbols). If the symbol is unnamed, add an
448         // anonymous symbol.
449         auto &GSym =
450             Name->empty()
451                 ? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size,
452                                         false, false)
453                 : G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L,
454                                       S, Sym.getType() == ELF::STT_FUNC, false);
455         setGraphSymbol(SymIndex, GSym);
456       }
457     } else if (Sym.isUndefined() && Sym.isExternal()) {
458       LLVM_DEBUG({
459         dbgs() << "      " << SymIndex
460                << ": Creating external graph symbol for ELF symbol \"" << *Name
461                << "\"\n";
462       });
463       auto &GSym = G->addExternalSymbol(*Name, Sym.st_size, L);
464       setGraphSymbol(SymIndex, GSym);
465     } else {
466       LLVM_DEBUG({
467         dbgs() << "      " << SymIndex
468                << ": Not creating graph symbol for ELF symbol \"" << *Name
469                << "\" with unrecognized type\n";
470       });
471     }
472   }
473 
474   return Error::success();
475 }
476 
477 template <typename ELFT>
478 template <typename RelocHandlerFunction>
479 Error ELFLinkGraphBuilder<ELFT>::forEachRelocation(
480     const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
481     bool ProcessDebugSections) {
482 
483   // Only look into sections that store relocation entries.
484   if (RelSect.sh_type != ELF::SHT_RELA && RelSect.sh_type != ELF::SHT_REL)
485     return Error::success();
486 
487   // sh_info contains the section header index of the target (FixupSection),
488   // which is the section to which all relocations in RelSect apply.
489   auto FixupSection = Obj.getSection(RelSect.sh_info);
490   if (!FixupSection)
491     return FixupSection.takeError();
492 
493   // Target sections have names in valid ELF object files.
494   Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
495   if (!Name)
496     return Name.takeError();
497   LLVM_DEBUG(dbgs() << "  " << *Name << ":\n");
498 
499   // Consider skipping these relocations.
500   if (!ProcessDebugSections && isDwarfSection(*Name)) {
501     LLVM_DEBUG(dbgs() << "    skipped (dwarf section)\n\n");
502     return Error::success();
503   }
504 
505   // Lookup the link-graph node corresponding to the target section name.
506   auto *BlockToFix = getGraphBlock(RelSect.sh_info);
507   if (!BlockToFix)
508     return make_error<StringError>(
509         "Refencing a section that wasn't added to the graph: " + *Name,
510         inconvertibleErrorCode());
511 
512   auto RelEntries = Obj.relas(RelSect);
513   if (!RelEntries)
514     return RelEntries.takeError();
515 
516   // Let the callee process relocation entries one by one.
517   for (const typename ELFT::Rela &R : *RelEntries)
518     if (Error Err = Func(R, **FixupSection, *BlockToFix))
519       return Err;
520 
521   LLVM_DEBUG(dbgs() << "\n");
522   return Error::success();
523 }
524 
525 } // end namespace jitlink
526 } // end namespace llvm
527 
528 #undef DEBUG_TYPE
529 
530 #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
531