xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
1 //===------- ELFLinkGraphBuilder.h - ELF LinkGraph builder ------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Generic ELF LinkGraph building code.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
14 #define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
15 
16 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
17 #include "llvm/Object/ELF.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/Error.h"
20 #include "llvm/Support/FormatVariadic.h"
21 
22 #define DEBUG_TYPE "jitlink"
23 
24 namespace llvm {
25 namespace jitlink {
26 
27 /// Common link-graph building code shared between all ELFFiles.
28 class ELFLinkGraphBuilderBase {
29 public:
30   ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {}
31   virtual ~ELFLinkGraphBuilderBase();
32 
33 protected:
34   static bool isDwarfSection(StringRef SectionName) {
35     return llvm::is_contained(DwarfSectionNames, SectionName);
36   }
37 
38   Section &getCommonSection() {
39     if (!CommonSection)
40       CommonSection = &G->createSection(
41           CommonSectionName, orc::MemProt::Read | orc::MemProt::Write);
42     return *CommonSection;
43   }
44 
45   std::unique_ptr<LinkGraph> G;
46 
47 private:
48   static StringRef CommonSectionName;
49   static ArrayRef<const char *> DwarfSectionNames;
50 
51   Section *CommonSection = nullptr;
52 };
53 
54 /// 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 ELFT::Rela relocation records in the given section.
112   /// The handler function Func should be callable with this signature:
113   ///   Error(const typename ELFT::Rela &,
114   ///         const typename ELFT::Shdr &, Section &)
115   ///
116   template <typename RelocHandlerMethod>
117   Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
118                               RelocHandlerMethod &&Func,
119                               bool ProcessDebugSections = false);
120 
121   /// Traverse all matching ELFT::Rel relocation records in the given section.
122   /// The handler function Func should be callable with this signature:
123   ///   Error(const typename ELFT::Rel &,
124   ///         const typename ELFT::Shdr &, Section &)
125   ///
126   template <typename RelocHandlerMethod>
127   Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
128                              RelocHandlerMethod &&Func,
129                              bool ProcessDebugSections = false);
130 
131   /// Traverse all matching rela relocation records in the given section.
132   /// Convenience wrapper to allow passing a member function for the handler.
133   ///
134   template <typename ClassT, typename RelocHandlerMethod>
135   Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
136                               ClassT *Instance, RelocHandlerMethod &&Method,
137                               bool ProcessDebugSections = false) {
138     return forEachRelaRelocation(
139         RelSect,
140         [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
141           return (Instance->*Method)(Rel, Target, GS);
142         },
143         ProcessDebugSections);
144   }
145 
146   /// Traverse all matching rel relocation records in the given section.
147   /// Convenience wrapper to allow passing a member function for the handler.
148   ///
149   template <typename ClassT, typename RelocHandlerMethod>
150   Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
151                              ClassT *Instance, RelocHandlerMethod &&Method,
152                              bool ProcessDebugSections = false) {
153     return forEachRelRelocation(
154         RelSect,
155         [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
156           return (Instance->*Method)(Rel, Target, GS);
157         },
158         ProcessDebugSections);
159   }
160 
161   const ELFFile &Obj;
162 
163   typename ELFFile::Elf_Shdr_Range Sections;
164   const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
165   StringRef SectionStringTab;
166 
167   // Maps ELF section indexes to LinkGraph Blocks.
168   // Only SHF_ALLOC sections will have graph blocks.
169   DenseMap<ELFSectionIndex, Block *> GraphBlocks;
170   DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols;
171   DenseMap<const typename ELFFile::Elf_Shdr *,
172            ArrayRef<typename ELFFile::Elf_Word>>
173       ShndxTables;
174 };
175 
176 template <typename ELFT>
177 ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder(
178     const ELFFile &Obj, Triple TT, StringRef FileName,
179     LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
180     : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
181           FileName.str(), Triple(std::move(TT)), ELFT::Is64Bits ? 8 : 4,
182           support::endianness(ELFT::TargetEndianness),
183           std::move(GetEdgeKindName))),
184       Obj(Obj) {
185   LLVM_DEBUG(
186       { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
187 }
188 
189 template <typename ELFT>
190 Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() {
191   if (!isRelocatable())
192     return make_error<JITLinkError>("Object is not a relocatable ELF file");
193 
194   if (auto Err = prepare())
195     return std::move(Err);
196 
197   if (auto Err = graphifySections())
198     return std::move(Err);
199 
200   if (auto Err = graphifySymbols())
201     return std::move(Err);
202 
203   if (auto Err = addRelocations())
204     return std::move(Err);
205 
206   return std::move(G);
207 }
208 
209 template <typename ELFT>
210 Expected<std::pair<Linkage, Scope>>
211 ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope(
212     const typename ELFT::Sym &Sym, StringRef Name) {
213   Linkage L = Linkage::Strong;
214   Scope S = Scope::Default;
215 
216   switch (Sym.getBinding()) {
217   case ELF::STB_LOCAL:
218     S = Scope::Local;
219     break;
220   case ELF::STB_GLOBAL:
221     // Nothing to do here.
222     break;
223   case ELF::STB_WEAK:
224   case ELF::STB_GNU_UNIQUE:
225     L = Linkage::Weak;
226     break;
227   default:
228     return make_error<StringError>(
229         "Unrecognized symbol binding " +
230             Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
231         inconvertibleErrorCode());
232   }
233 
234   switch (Sym.getVisibility()) {
235   case ELF::STV_DEFAULT:
236   case ELF::STV_PROTECTED:
237     // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
238     // Orc support.
239     // Otherwise nothing to do here.
240     break;
241   case ELF::STV_HIDDEN:
242     // Default scope -> Hidden scope. No effect on local scope.
243     if (S == Scope::Default)
244       S = Scope::Hidden;
245     break;
246   case ELF::STV_INTERNAL:
247     return make_error<StringError>(
248         "Unrecognized symbol visibility " +
249             Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,
250         inconvertibleErrorCode());
251   }
252 
253   return std::make_pair(L, S);
254 }
255 
256 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
257   LLVM_DEBUG(dbgs() << "  Preparing to build...\n");
258 
259   // Get the sections array.
260   if (auto SectionsOrErr = Obj.sections())
261     Sections = *SectionsOrErr;
262   else
263     return SectionsOrErr.takeError();
264 
265   // Get the section string table.
266   if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
267     SectionStringTab = *SectionStringTabOrErr;
268   else
269     return SectionStringTabOrErr.takeError();
270 
271   // Get the SHT_SYMTAB section.
272   for (auto &Sec : Sections) {
273     if (Sec.sh_type == ELF::SHT_SYMTAB) {
274       if (!SymTabSec)
275         SymTabSec = &Sec;
276       else
277         return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
278                                         G->getName());
279     }
280 
281     // Extended table.
282     if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
283       uint32_t SymtabNdx = Sec.sh_link;
284       if (SymtabNdx >= Sections.size())
285         return make_error<JITLinkError>("sh_link is out of bound");
286 
287       auto ShndxTable = Obj.getSHNDXTable(Sec);
288       if (!ShndxTable)
289         return ShndxTable.takeError();
290 
291       ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
292     }
293   }
294 
295   return Error::success();
296 }
297 
298 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {
299   LLVM_DEBUG(dbgs() << "  Creating graph sections...\n");
300 
301   // For each section...
302   for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
303 
304     auto &Sec = Sections[SecIndex];
305 
306     // Start by getting the section name.
307     auto Name = Obj.getSectionName(Sec, SectionStringTab);
308     if (!Name)
309       return Name.takeError();
310 
311     // If the name indicates that it's a debug section then skip it: We don't
312     // support those yet.
313     if (isDwarfSection(*Name)) {
314       LLVM_DEBUG({
315         dbgs() << "    " << SecIndex << ": \"" << *Name
316                << "\" is a debug section: "
317                   "No graph section will be created.\n";
318       });
319       continue;
320     }
321 
322     // Skip non-SHF_ALLOC sections
323     if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
324       LLVM_DEBUG({
325         dbgs() << "    " << SecIndex << ": \"" << *Name
326                << "\" is not an SHF_ALLOC section: "
327                   "No graph section will be created.\n";
328       });
329       continue;
330     }
331 
332     LLVM_DEBUG({
333       dbgs() << "    " << SecIndex << ": Creating section for \"" << *Name
334              << "\"\n";
335     });
336 
337     // Get the section's memory protection flags.
338     orc::MemProt Prot;
339     if (Sec.sh_flags & ELF::SHF_EXECINSTR)
340       Prot = orc::MemProt::Read | orc::MemProt::Exec;
341     else
342       Prot = orc::MemProt::Read | orc::MemProt::Write;
343 
344     // Look for existing sections first.
345     auto *GraphSec = G->findSectionByName(*Name);
346     if (!GraphSec)
347       GraphSec = &G->createSection(*Name, Prot);
348     assert(GraphSec->getMemProt() == Prot && "MemProt should match");
349 
350     Block *B = nullptr;
351     if (Sec.sh_type != ELF::SHT_NOBITS) {
352       auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
353       if (!Data)
354         return Data.takeError();
355 
356       B = &G->createContentBlock(*GraphSec, *Data,
357                                  orc::ExecutorAddr(Sec.sh_addr),
358                                  Sec.sh_addralign, 0);
359     } else
360       B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
361                                   orc::ExecutorAddr(Sec.sh_addr),
362                                   Sec.sh_addralign, 0);
363 
364     setGraphBlock(SecIndex, B);
365   }
366 
367   return Error::success();
368 }
369 
370 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
371   LLVM_DEBUG(dbgs() << "  Creating graph symbols...\n");
372 
373   // No SYMTAB -- Bail out early.
374   if (!SymTabSec)
375     return Error::success();
376 
377   // Get the section content as a Symbols array.
378   auto Symbols = Obj.symbols(SymTabSec);
379   if (!Symbols)
380     return Symbols.takeError();
381 
382   // Get the string table for this section.
383   auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
384   if (!StringTab)
385     return StringTab.takeError();
386 
387   LLVM_DEBUG({
388     StringRef SymTabName;
389 
390     if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
391       SymTabName = *SymTabNameOrErr;
392     else {
393       dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
394              << toString(SymTabNameOrErr.takeError()) << "\n";
395       SymTabName = "<SHT_SYMTAB section with invalid name>";
396     }
397 
398     dbgs() << "    Adding symbols from symtab section \"" << SymTabName
399            << "\"\n";
400   });
401 
402   for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
403     auto &Sym = (*Symbols)[SymIndex];
404 
405     // Check symbol type.
406     switch (Sym.getType()) {
407     case ELF::STT_FILE:
408       LLVM_DEBUG({
409         if (auto Name = Sym.getName(*StringTab))
410           dbgs() << "      " << SymIndex << ": Skipping STT_FILE symbol \""
411                  << *Name << "\"\n";
412         else {
413           dbgs() << "Could not get STT_FILE symbol name: "
414                  << toString(Name.takeError()) << "\n";
415           dbgs() << "     " << SymIndex
416                  << ": Skipping STT_FILE symbol with invalid name\n";
417         }
418       });
419       continue;
420       break;
421     }
422 
423     // Get the symbol name.
424     auto Name = Sym.getName(*StringTab);
425     if (!Name)
426       return Name.takeError();
427 
428     // Handle common symbols specially.
429     if (Sym.isCommon()) {
430       Symbol &GSym = G->addDefinedSymbol(
431           G->createZeroFillBlock(getCommonSection(), Sym.st_size,
432                                  orc::ExecutorAddr(), Sym.getValue(), 0),
433           0, *Name, Sym.st_size, Linkage::Strong, Scope::Default, false, false);
434       setGraphSymbol(SymIndex, GSym);
435       continue;
436     }
437 
438     if (Sym.isDefined() &&
439         (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
440          Sym.getType() == ELF::STT_OBJECT ||
441          Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {
442 
443       // Map Visibility and Binding to Scope and Linkage:
444       Linkage L;
445       Scope S;
446       if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
447         std::tie(L, S) = *LSOrErr;
448       else
449         return LSOrErr.takeError();
450 
451       // Handle extended tables.
452       unsigned Shndx = Sym.st_shndx;
453       if (Shndx == ELF::SHN_XINDEX) {
454         auto ShndxTable = ShndxTables.find(SymTabSec);
455         if (ShndxTable == ShndxTables.end())
456           continue;
457         auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
458             Sym, SymIndex, ShndxTable->second);
459         if (!NdxOrErr)
460           return NdxOrErr.takeError();
461         Shndx = *NdxOrErr;
462       }
463       if (auto *B = getGraphBlock(Shndx)) {
464         LLVM_DEBUG({
465           dbgs() << "      " << SymIndex
466                  << ": Creating defined graph symbol for ELF symbol \"" << *Name
467                  << "\"\n";
468         });
469 
470         // In RISCV, temporary symbols (Used to generate dwarf, eh_frame
471         // sections...) will appear in object code's symbol table, and LLVM does
472         // not use names on these temporary symbols (RISCV gnu toolchain uses
473         // names on these temporary symbols). If the symbol is unnamed, add an
474         // anonymous symbol.
475         auto &GSym =
476             Name->empty()
477                 ? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size,
478                                         false, false)
479                 : G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L,
480                                       S, Sym.getType() == ELF::STT_FUNC, false);
481         setGraphSymbol(SymIndex, GSym);
482       }
483     } else if (Sym.isUndefined() && Sym.isExternal()) {
484       LLVM_DEBUG({
485         dbgs() << "      " << SymIndex
486                << ": Creating external graph symbol for ELF symbol \"" << *Name
487                << "\"\n";
488       });
489 
490       if (Sym.getBinding() != ELF::STB_GLOBAL &&
491           Sym.getBinding() != ELF::STB_WEAK)
492         return make_error<StringError>(
493             "Invalid symbol binding " +
494                 Twine(static_cast<int>(Sym.getBinding())) +
495                 " for external symbol " + *Name,
496             inconvertibleErrorCode());
497 
498       // If L is Linkage::Weak that means this is a weakly referenced symbol.
499       auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,
500                                         Sym.getBinding() == ELF::STB_WEAK);
501       setGraphSymbol(SymIndex, GSym);
502     } else {
503       LLVM_DEBUG({
504         dbgs() << "      " << SymIndex
505                << ": Not creating graph symbol for ELF symbol \"" << *Name
506                << "\" with unrecognized type\n";
507       });
508     }
509   }
510 
511   return Error::success();
512 }
513 
514 template <typename ELFT>
515 template <typename RelocHandlerFunction>
516 Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation(
517     const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
518     bool ProcessDebugSections) {
519   // Only look into sections that store relocation entries.
520   if (RelSect.sh_type != ELF::SHT_RELA)
521     return Error::success();
522 
523   // sh_info contains the section header index of the target (FixupSection),
524   // which is the section to which all relocations in RelSect apply.
525   auto FixupSection = Obj.getSection(RelSect.sh_info);
526   if (!FixupSection)
527     return FixupSection.takeError();
528 
529   // Target sections have names in valid ELF object files.
530   Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
531   if (!Name)
532     return Name.takeError();
533   LLVM_DEBUG(dbgs() << "  " << *Name << ":\n");
534 
535   // Consider skipping these relocations.
536   if (!ProcessDebugSections && isDwarfSection(*Name)) {
537     LLVM_DEBUG(dbgs() << "    skipped (dwarf section)\n\n");
538     return Error::success();
539   }
540 
541   // Lookup the link-graph node corresponding to the target section name.
542   auto *BlockToFix = getGraphBlock(RelSect.sh_info);
543   if (!BlockToFix)
544     return make_error<StringError>(
545         "Refencing a section that wasn't added to the graph: " + *Name,
546         inconvertibleErrorCode());
547 
548   auto RelEntries = Obj.relas(RelSect);
549   if (!RelEntries)
550     return RelEntries.takeError();
551 
552   // Let the callee process relocation entries one by one.
553   for (const typename ELFT::Rela &R : *RelEntries)
554     if (Error Err = Func(R, **FixupSection, *BlockToFix))
555       return Err;
556 
557   LLVM_DEBUG(dbgs() << "\n");
558   return Error::success();
559 }
560 
561 template <typename ELFT>
562 template <typename RelocHandlerFunction>
563 Error ELFLinkGraphBuilder<ELFT>::forEachRelRelocation(
564     const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
565     bool ProcessDebugSections) {
566   // Only look into sections that store relocation entries.
567   if (RelSect.sh_type != ELF::SHT_REL)
568     return Error::success();
569 
570   // sh_info contains the section header index of the target (FixupSection),
571   // which is the section to which all relocations in RelSect apply.
572   auto FixupSection = Obj.getSection(RelSect.sh_info);
573   if (!FixupSection)
574     return FixupSection.takeError();
575 
576   // Target sections have names in valid ELF object files.
577   Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
578   if (!Name)
579     return Name.takeError();
580   LLVM_DEBUG(dbgs() << "  " << *Name << ":\n");
581 
582   // Consider skipping these relocations.
583   if (!ProcessDebugSections && isDwarfSection(*Name)) {
584     LLVM_DEBUG(dbgs() << "    skipped (dwarf section)\n\n");
585     return Error::success();
586   }
587 
588   // Lookup the link-graph node corresponding to the target section name.
589   auto *BlockToFix = getGraphBlock(RelSect.sh_info);
590   if (!BlockToFix)
591     return make_error<StringError>(
592         "Refencing a section that wasn't added to the graph: " + *Name,
593         inconvertibleErrorCode());
594 
595   auto RelEntries = Obj.rels(RelSect);
596   if (!RelEntries)
597     return RelEntries.takeError();
598 
599   // Let the callee process relocation entries one by one.
600   for (const typename ELFT::Rel &R : *RelEntries)
601     if (Error Err = Func(R, **FixupSection, *BlockToFix))
602       return Err;
603 
604   LLVM_DEBUG(dbgs() << "\n");
605   return Error::success();
606 }
607 
608 } // end namespace jitlink
609 } // end namespace llvm
610 
611 #undef DEBUG_TYPE
612 
613 #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
614