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