1 //===------- ELFLinkGraphBuilder.h - ELF LinkGraph builder ------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Generic ELF LinkGraph building code.
11 //===----------------------------------------------------------------------===//
13 #ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
14 #define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
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"
22 #define DEBUG_TYPE "jitlink"
27 /// Common link-graph building code shared between all ELFFiles.
28 class ELFLinkGraphBuilderBase {
30 ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {}
31 virtual ~ELFLinkGraphBuilderBase();
34 static bool isDwarfSection(StringRef SectionName) {
35 return llvm::is_contained(DwarfSectionNames, SectionName);
38 Section &getCommonSection() {
41 &G->createSection(CommonSectionName, MemProt::Read | MemProt::Write);
42 return *CommonSection;
45 std::unique_ptr<LinkGraph> G;
48 static StringRef CommonSectionName;
49 static ArrayRef<const char *> DwarfSectionNames;
51 Section *CommonSection = nullptr;
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>;
61 ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj, Triple TT,
63 LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
65 /// Attempt to construct and return the LinkGraph.
66 Expected<std::unique_ptr<LinkGraph>> buildGraph();
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;
73 using ELFSectionIndex = unsigned;
74 using ELFSymbolIndex = unsigned;
76 bool isRelocatable() const {
77 return Obj.getHeader().e_type == llvm::ELF::ET_REL;
80 void setGraphBlock(ELFSectionIndex SecIndex, Block *B) {
81 assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index");
82 GraphBlocks[SecIndex] = B;
85 Block *getGraphBlock(ELFSectionIndex SecIndex) {
86 auto I = GraphBlocks.find(SecIndex);
87 if (I == GraphBlocks.end())
92 void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) {
93 assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");
94 GraphSymbols[SymIndex] = &Sym;
97 Symbol *getGraphSymbol(ELFSymbolIndex SymIndex) {
98 auto I = GraphSymbols.find(SymIndex);
99 if (I == GraphSymbols.end())
104 Expected<std::pair<Linkage, Scope>>
105 getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
108 Error graphifySections();
109 Error graphifySymbols();
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 &)
116 template <typename RelocHandlerFunction>
117 Error forEachRelocation(const typename ELFT::Shdr &RelSect,
118 RelocHandlerFunction &&Func,
119 bool ProcessDebugSections = false);
121 /// Traverse all matching relocation records in the given section. Convenience
122 /// wrapper to allow passing a member function for the handler.
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(
130 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
131 return (Instance->*Method)(Rel, Target, GS);
133 ProcessDebugSections);
138 typename ELFFile::Elf_Shdr_Range Sections;
139 const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
140 StringRef SectionStringTab;
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>>
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))),
161 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
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");
169 if (auto Err = prepare())
170 return std::move(Err);
172 if (auto Err = graphifySections())
173 return std::move(Err);
175 if (auto Err = graphifySymbols())
176 return std::move(Err);
178 if (auto Err = addRelocations())
179 return std::move(Err);
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;
191 switch (Sym.getBinding()) {
195 case ELF::STB_GLOBAL:
196 // Nothing to do here.
199 case ELF::STB_GNU_UNIQUE:
203 return make_error<StringError>(
204 "Unrecognized symbol binding " +
205 Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
206 inconvertibleErrorCode());
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
214 // Otherwise nothing to do here.
216 case ELF::STV_HIDDEN:
217 // Default scope -> Hidden scope. No effect on local scope.
218 if (S == Scope::Default)
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());
228 return std::make_pair(L, S);
231 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
232 LLVM_DEBUG(dbgs() << " Preparing to build...\n");
234 // Get the sections array.
235 if (auto SectionsOrErr = Obj.sections())
236 Sections = *SectionsOrErr;
238 return SectionsOrErr.takeError();
240 // Get the section string table.
241 if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
242 SectionStringTab = *SectionStringTabOrErr;
244 return SectionStringTabOrErr.takeError();
246 // Get the SHT_SYMTAB section.
247 for (auto &Sec : Sections) {
248 if (Sec.sh_type == ELF::SHT_SYMTAB) {
252 return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
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");
262 auto ShndxTable = Obj.getSHNDXTable(Sec);
264 return ShndxTable.takeError();
266 ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
270 return Error::success();
273 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {
274 LLVM_DEBUG(dbgs() << " Creating graph sections...\n");
276 // For each section...
277 for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
279 auto &Sec = Sections[SecIndex];
281 // Start by getting the section name.
282 auto Name = Obj.getSectionName(Sec, SectionStringTab);
284 return Name.takeError();
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)) {
290 dbgs() << " " << SecIndex << ": \"" << *Name
291 << "\" is a debug section: "
292 "No graph section will be created.\n";
297 // Skip non-SHF_ALLOC sections
298 if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
300 dbgs() << " " << SecIndex << ": \"" << *Name
301 << "\" is not an SHF_ALLOC section: "
302 "No graph section will be created.\n";
308 dbgs() << " " << SecIndex << ": Creating section for \"" << *Name
312 // Get the section's memory protection flags.
314 if (Sec.sh_flags & ELF::SHF_EXECINSTR)
315 Prot = MemProt::Read | MemProt::Exec;
317 Prot = MemProt::Read | MemProt::Write;
319 // Look for existing sections first.
320 auto *GraphSec = G->findSectionByName(*Name);
322 GraphSec = &G->createSection(*Name, Prot);
323 assert(GraphSec->getMemProt() == Prot && "MemProt should match");
326 if (Sec.sh_type != ELF::SHT_NOBITS) {
327 auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
329 return Data.takeError();
331 B = &G->createContentBlock(*GraphSec, *Data,
332 orc::ExecutorAddr(Sec.sh_addr),
333 Sec.sh_addralign, 0);
335 B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
336 orc::ExecutorAddr(Sec.sh_addr),
337 Sec.sh_addralign, 0);
339 setGraphBlock(SecIndex, B);
342 return Error::success();
345 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {
346 LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");
348 // No SYMTAB -- Bail out early.
350 return Error::success();
352 // Get the section content as a Symbols array.
353 auto Symbols = Obj.symbols(SymTabSec);
355 return Symbols.takeError();
357 // Get the string table for this section.
358 auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
360 return StringTab.takeError();
363 StringRef SymTabName;
365 if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
366 SymTabName = *SymTabNameOrErr;
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>";
373 dbgs() << " Adding symbols from symtab section \"" << SymTabName
377 for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
378 auto &Sym = (*Symbols)[SymIndex];
380 // Check symbol type.
381 switch (Sym.getType()) {
384 if (auto Name = Sym.getName(*StringTab))
385 dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \""
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";
398 // Get the symbol name.
399 auto Name = Sym.getName(*StringTab);
401 return Name.takeError();
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);
412 // Map Visibility and Binding to Scope and Linkage:
416 if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
417 std::tie(L, S) = *LSOrErr;
419 return LSOrErr.takeError();
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())
431 auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
432 Sym, SymIndex, ShndxTable->second);
434 return NdxOrErr.takeError();
437 if (auto *B = getGraphBlock(Shndx)) {
439 dbgs() << " " << SymIndex
440 << ": Creating defined graph symbol for ELF symbol \"" << *Name
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
451 ? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size,
453 : G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L,
454 S, Sym.getType() == ELF::STT_FUNC, false);
455 setGraphSymbol(SymIndex, GSym);
457 } else if (Sym.isUndefined() && Sym.isExternal()) {
459 dbgs() << " " << SymIndex
460 << ": Creating external graph symbol for ELF symbol \"" << *Name
463 auto &GSym = G->addExternalSymbol(*Name, Sym.st_size, L);
464 setGraphSymbol(SymIndex, GSym);
467 dbgs() << " " << SymIndex
468 << ": Not creating graph symbol for ELF symbol \"" << *Name
469 << "\" with unrecognized type\n";
474 return Error::success();
477 template <typename ELFT>
478 template <typename RelocHandlerFunction>
479 Error ELFLinkGraphBuilder<ELFT>::forEachRelocation(
480 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
481 bool ProcessDebugSections) {
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();
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);
491 return FixupSection.takeError();
493 // Target sections have names in valid ELF object files.
494 Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
496 return Name.takeError();
497 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
499 // Consider skipping these relocations.
500 if (!ProcessDebugSections && isDwarfSection(*Name)) {
501 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
502 return Error::success();
505 // Lookup the link-graph node corresponding to the target section name.
506 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
508 return make_error<StringError>(
509 "Refencing a section that wasn't added to the graph: " + *Name,
510 inconvertibleErrorCode());
512 auto RelEntries = Obj.relas(RelSect);
514 return RelEntries.takeError();
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))
521 LLVM_DEBUG(dbgs() << "\n");
522 return Error::success();
525 } // end namespace jitlink
526 } // end namespace llvm
530 #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H