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() { 39349cc55cSDimitry Andric if (!CommonSection) 40*bdd1243dSDimitry Andric CommonSection = &G->createSection( 41*bdd1243dSDimitry Andric CommonSectionName, orc::MemProt::Read | orc::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 8004eeddc0SDimitry Andric void setGraphBlock(ELFSectionIndex SecIndex, Block *B) { 8104eeddc0SDimitry Andric assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index"); 8204eeddc0SDimitry Andric GraphBlocks[SecIndex] = B; 83fe6060f1SDimitry Andric } 84fe6060f1SDimitry Andric 8504eeddc0SDimitry Andric Block *getGraphBlock(ELFSectionIndex SecIndex) { 8604eeddc0SDimitry Andric auto I = GraphBlocks.find(SecIndex); 8704eeddc0SDimitry Andric if (I == GraphBlocks.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*bdd1243dSDimitry Andric /// Traverse all matching ELFT::Rela relocation records in the given section. 112*bdd1243dSDimitry Andric /// The handler function Func should be callable with this signature: 113349cc55cSDimitry Andric /// Error(const typename ELFT::Rela &, 114349cc55cSDimitry Andric /// const typename ELFT::Shdr &, Section &) 115349cc55cSDimitry Andric /// 116*bdd1243dSDimitry Andric template <typename RelocHandlerMethod> 117*bdd1243dSDimitry Andric Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect, 118*bdd1243dSDimitry Andric RelocHandlerMethod &&Func, 119349cc55cSDimitry Andric bool ProcessDebugSections = false); 120349cc55cSDimitry Andric 121*bdd1243dSDimitry Andric /// Traverse all matching ELFT::Rel relocation records in the given section. 122*bdd1243dSDimitry Andric /// The handler function Func should be callable with this signature: 123*bdd1243dSDimitry Andric /// Error(const typename ELFT::Rel &, 124*bdd1243dSDimitry Andric /// const typename ELFT::Shdr &, Section &) 125*bdd1243dSDimitry Andric /// 126*bdd1243dSDimitry Andric template <typename RelocHandlerMethod> 127*bdd1243dSDimitry Andric Error forEachRelRelocation(const typename ELFT::Shdr &RelSect, 128*bdd1243dSDimitry Andric RelocHandlerMethod &&Func, 129*bdd1243dSDimitry Andric bool ProcessDebugSections = false); 130*bdd1243dSDimitry Andric 131*bdd1243dSDimitry Andric /// Traverse all matching rela relocation records in the given section. 132*bdd1243dSDimitry Andric /// Convenience wrapper to allow passing a member function for the handler. 133349cc55cSDimitry Andric /// 134349cc55cSDimitry Andric template <typename ClassT, typename RelocHandlerMethod> 135*bdd1243dSDimitry Andric Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect, 136*bdd1243dSDimitry Andric ClassT *Instance, RelocHandlerMethod &&Method, 137349cc55cSDimitry Andric bool ProcessDebugSections = false) { 138*bdd1243dSDimitry Andric return forEachRelaRelocation( 139*bdd1243dSDimitry Andric RelSect, 140*bdd1243dSDimitry Andric [Instance, Method](const auto &Rel, const auto &Target, auto &GS) { 141*bdd1243dSDimitry Andric return (Instance->*Method)(Rel, Target, GS); 142*bdd1243dSDimitry Andric }, 143*bdd1243dSDimitry Andric ProcessDebugSections); 144*bdd1243dSDimitry Andric } 145*bdd1243dSDimitry Andric 146*bdd1243dSDimitry Andric /// Traverse all matching rel relocation records in the given section. 147*bdd1243dSDimitry Andric /// Convenience wrapper to allow passing a member function for the handler. 148*bdd1243dSDimitry Andric /// 149*bdd1243dSDimitry Andric template <typename ClassT, typename RelocHandlerMethod> 150*bdd1243dSDimitry Andric Error forEachRelRelocation(const typename ELFT::Shdr &RelSect, 151*bdd1243dSDimitry Andric ClassT *Instance, RelocHandlerMethod &&Method, 152*bdd1243dSDimitry Andric bool ProcessDebugSections = false) { 153*bdd1243dSDimitry Andric return forEachRelRelocation( 154349cc55cSDimitry Andric RelSect, 155349cc55cSDimitry Andric [Instance, Method](const auto &Rel, const auto &Target, auto &GS) { 156349cc55cSDimitry Andric return (Instance->*Method)(Rel, Target, GS); 157349cc55cSDimitry Andric }, 158349cc55cSDimitry Andric ProcessDebugSections); 159349cc55cSDimitry Andric } 160349cc55cSDimitry Andric 161fe6060f1SDimitry Andric const ELFFile &Obj; 162fe6060f1SDimitry Andric 163fe6060f1SDimitry Andric typename ELFFile::Elf_Shdr_Range Sections; 164fe6060f1SDimitry Andric const typename ELFFile::Elf_Shdr *SymTabSec = nullptr; 165fe6060f1SDimitry Andric StringRef SectionStringTab; 166fe6060f1SDimitry Andric 16704eeddc0SDimitry Andric // Maps ELF section indexes to LinkGraph Blocks. 16804eeddc0SDimitry Andric // Only SHF_ALLOC sections will have graph blocks. 16904eeddc0SDimitry Andric DenseMap<ELFSectionIndex, Block *> GraphBlocks; 170fe6060f1SDimitry Andric DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols; 1714824e7fdSDimitry Andric DenseMap<const typename ELFFile::Elf_Shdr *, 1724824e7fdSDimitry Andric ArrayRef<typename ELFFile::Elf_Word>> 1734824e7fdSDimitry Andric ShndxTables; 174fe6060f1SDimitry Andric }; 175fe6060f1SDimitry Andric 176fe6060f1SDimitry Andric template <typename ELFT> 177fe6060f1SDimitry Andric ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder( 178fe6060f1SDimitry Andric const ELFFile &Obj, Triple TT, StringRef FileName, 179fe6060f1SDimitry Andric LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) 180fe6060f1SDimitry Andric : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>( 181fe6060f1SDimitry Andric FileName.str(), Triple(std::move(TT)), ELFT::Is64Bits ? 8 : 4, 182fe6060f1SDimitry Andric support::endianness(ELFT::TargetEndianness), 183fe6060f1SDimitry Andric std::move(GetEdgeKindName))), 184fe6060f1SDimitry Andric Obj(Obj) { 185fe6060f1SDimitry Andric LLVM_DEBUG( 186fe6060f1SDimitry Andric { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; }); 187fe6060f1SDimitry Andric } 188fe6060f1SDimitry Andric 189fe6060f1SDimitry Andric template <typename ELFT> 190fe6060f1SDimitry Andric Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() { 191fe6060f1SDimitry Andric if (!isRelocatable()) 192fe6060f1SDimitry Andric return make_error<JITLinkError>("Object is not a relocatable ELF file"); 193fe6060f1SDimitry Andric 194fe6060f1SDimitry Andric if (auto Err = prepare()) 195fe6060f1SDimitry Andric return std::move(Err); 196fe6060f1SDimitry Andric 197fe6060f1SDimitry Andric if (auto Err = graphifySections()) 198fe6060f1SDimitry Andric return std::move(Err); 199fe6060f1SDimitry Andric 200fe6060f1SDimitry Andric if (auto Err = graphifySymbols()) 201fe6060f1SDimitry Andric return std::move(Err); 202fe6060f1SDimitry Andric 203fe6060f1SDimitry Andric if (auto Err = addRelocations()) 204fe6060f1SDimitry Andric return std::move(Err); 205fe6060f1SDimitry Andric 206fe6060f1SDimitry Andric return std::move(G); 207fe6060f1SDimitry Andric } 208fe6060f1SDimitry Andric 209fe6060f1SDimitry Andric template <typename ELFT> 210fe6060f1SDimitry Andric Expected<std::pair<Linkage, Scope>> 211fe6060f1SDimitry Andric ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope( 212fe6060f1SDimitry Andric const typename ELFT::Sym &Sym, StringRef Name) { 213fe6060f1SDimitry Andric Linkage L = Linkage::Strong; 214fe6060f1SDimitry Andric Scope S = Scope::Default; 215fe6060f1SDimitry Andric 216fe6060f1SDimitry Andric switch (Sym.getBinding()) { 217fe6060f1SDimitry Andric case ELF::STB_LOCAL: 218fe6060f1SDimitry Andric S = Scope::Local; 219fe6060f1SDimitry Andric break; 220fe6060f1SDimitry Andric case ELF::STB_GLOBAL: 221fe6060f1SDimitry Andric // Nothing to do here. 222fe6060f1SDimitry Andric break; 223fe6060f1SDimitry Andric case ELF::STB_WEAK: 224349cc55cSDimitry Andric case ELF::STB_GNU_UNIQUE: 225fe6060f1SDimitry Andric L = Linkage::Weak; 226fe6060f1SDimitry Andric break; 227fe6060f1SDimitry Andric default: 228349cc55cSDimitry Andric return make_error<StringError>( 229349cc55cSDimitry Andric "Unrecognized symbol binding " + 230349cc55cSDimitry Andric Twine(static_cast<int>(Sym.getBinding())) + " for " + Name, 231fe6060f1SDimitry Andric inconvertibleErrorCode()); 232fe6060f1SDimitry Andric } 233fe6060f1SDimitry Andric 234fe6060f1SDimitry Andric switch (Sym.getVisibility()) { 235fe6060f1SDimitry Andric case ELF::STV_DEFAULT: 236fe6060f1SDimitry Andric case ELF::STV_PROTECTED: 237fe6060f1SDimitry Andric // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs 238fe6060f1SDimitry Andric // Orc support. 239fe6060f1SDimitry Andric // Otherwise nothing to do here. 240fe6060f1SDimitry Andric break; 241fe6060f1SDimitry Andric case ELF::STV_HIDDEN: 242fe6060f1SDimitry Andric // Default scope -> Hidden scope. No effect on local scope. 243fe6060f1SDimitry Andric if (S == Scope::Default) 244fe6060f1SDimitry Andric S = Scope::Hidden; 245fe6060f1SDimitry Andric break; 246fe6060f1SDimitry Andric case ELF::STV_INTERNAL: 247349cc55cSDimitry Andric return make_error<StringError>( 248349cc55cSDimitry Andric "Unrecognized symbol visibility " + 249349cc55cSDimitry Andric Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name, 250fe6060f1SDimitry Andric inconvertibleErrorCode()); 251fe6060f1SDimitry Andric } 252fe6060f1SDimitry Andric 253fe6060f1SDimitry Andric return std::make_pair(L, S); 254fe6060f1SDimitry Andric } 255fe6060f1SDimitry Andric 256fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() { 257fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << " Preparing to build...\n"); 258fe6060f1SDimitry Andric 259fe6060f1SDimitry Andric // Get the sections array. 260fe6060f1SDimitry Andric if (auto SectionsOrErr = Obj.sections()) 261fe6060f1SDimitry Andric Sections = *SectionsOrErr; 262fe6060f1SDimitry Andric else 263fe6060f1SDimitry Andric return SectionsOrErr.takeError(); 264fe6060f1SDimitry Andric 265fe6060f1SDimitry Andric // Get the section string table. 266fe6060f1SDimitry Andric if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections)) 267fe6060f1SDimitry Andric SectionStringTab = *SectionStringTabOrErr; 268fe6060f1SDimitry Andric else 269fe6060f1SDimitry Andric return SectionStringTabOrErr.takeError(); 270fe6060f1SDimitry Andric 271fe6060f1SDimitry Andric // Get the SHT_SYMTAB section. 2724824e7fdSDimitry Andric for (auto &Sec : Sections) { 273fe6060f1SDimitry Andric if (Sec.sh_type == ELF::SHT_SYMTAB) { 274fe6060f1SDimitry Andric if (!SymTabSec) 275fe6060f1SDimitry Andric SymTabSec = &Sec; 276fe6060f1SDimitry Andric else 277fe6060f1SDimitry Andric return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " + 278fe6060f1SDimitry Andric G->getName()); 279fe6060f1SDimitry Andric } 280fe6060f1SDimitry Andric 2814824e7fdSDimitry Andric // Extended table. 2824824e7fdSDimitry Andric if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) { 2834824e7fdSDimitry Andric uint32_t SymtabNdx = Sec.sh_link; 2844824e7fdSDimitry Andric if (SymtabNdx >= Sections.size()) 2854824e7fdSDimitry Andric return make_error<JITLinkError>("sh_link is out of bound"); 2864824e7fdSDimitry Andric 2874824e7fdSDimitry Andric auto ShndxTable = Obj.getSHNDXTable(Sec); 2884824e7fdSDimitry Andric if (!ShndxTable) 2894824e7fdSDimitry Andric return ShndxTable.takeError(); 2904824e7fdSDimitry Andric 2914824e7fdSDimitry Andric ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable}); 2924824e7fdSDimitry Andric } 2934824e7fdSDimitry Andric } 2944824e7fdSDimitry Andric 295fe6060f1SDimitry Andric return Error::success(); 296fe6060f1SDimitry Andric } 297fe6060f1SDimitry Andric 298fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() { 299fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << " Creating graph sections...\n"); 300fe6060f1SDimitry Andric 301fe6060f1SDimitry Andric // For each section... 302fe6060f1SDimitry Andric for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) { 303fe6060f1SDimitry Andric 304fe6060f1SDimitry Andric auto &Sec = Sections[SecIndex]; 305fe6060f1SDimitry Andric 306fe6060f1SDimitry Andric // Start by getting the section name. 307fe6060f1SDimitry Andric auto Name = Obj.getSectionName(Sec, SectionStringTab); 308fe6060f1SDimitry Andric if (!Name) 309fe6060f1SDimitry Andric return Name.takeError(); 310fe6060f1SDimitry Andric 311fe6060f1SDimitry Andric // If the name indicates that it's a debug section then skip it: We don't 312fe6060f1SDimitry Andric // support those yet. 313fe6060f1SDimitry Andric if (isDwarfSection(*Name)) { 314fe6060f1SDimitry Andric LLVM_DEBUG({ 315fe6060f1SDimitry Andric dbgs() << " " << SecIndex << ": \"" << *Name 316fe6060f1SDimitry Andric << "\" is a debug section: " 317fe6060f1SDimitry Andric "No graph section will be created.\n"; 318fe6060f1SDimitry Andric }); 319fe6060f1SDimitry Andric continue; 320fe6060f1SDimitry Andric } 321fe6060f1SDimitry Andric 322fe6060f1SDimitry Andric // Skip non-SHF_ALLOC sections 323fe6060f1SDimitry Andric if (!(Sec.sh_flags & ELF::SHF_ALLOC)) { 324fe6060f1SDimitry Andric LLVM_DEBUG({ 325fe6060f1SDimitry Andric dbgs() << " " << SecIndex << ": \"" << *Name 326fe6060f1SDimitry Andric << "\" is not an SHF_ALLOC section: " 327fe6060f1SDimitry Andric "No graph section will be created.\n"; 328fe6060f1SDimitry Andric }); 329fe6060f1SDimitry Andric continue; 330fe6060f1SDimitry Andric } 331fe6060f1SDimitry Andric 332fe6060f1SDimitry Andric LLVM_DEBUG({ 333fe6060f1SDimitry Andric dbgs() << " " << SecIndex << ": Creating section for \"" << *Name 334fe6060f1SDimitry Andric << "\"\n"; 335fe6060f1SDimitry Andric }); 336fe6060f1SDimitry Andric 337fe6060f1SDimitry Andric // Get the section's memory protection flags. 338*bdd1243dSDimitry Andric orc::MemProt Prot; 339fe6060f1SDimitry Andric if (Sec.sh_flags & ELF::SHF_EXECINSTR) 340*bdd1243dSDimitry Andric Prot = orc::MemProt::Read | orc::MemProt::Exec; 341fe6060f1SDimitry Andric else 342*bdd1243dSDimitry Andric Prot = orc::MemProt::Read | orc::MemProt::Write; 343fe6060f1SDimitry Andric 34404eeddc0SDimitry Andric // Look for existing sections first. 34504eeddc0SDimitry Andric auto *GraphSec = G->findSectionByName(*Name); 34604eeddc0SDimitry Andric if (!GraphSec) 34704eeddc0SDimitry Andric GraphSec = &G->createSection(*Name, Prot); 34804eeddc0SDimitry Andric assert(GraphSec->getMemProt() == Prot && "MemProt should match"); 34904eeddc0SDimitry Andric 35004eeddc0SDimitry Andric Block *B = nullptr; 351fe6060f1SDimitry Andric if (Sec.sh_type != ELF::SHT_NOBITS) { 352fe6060f1SDimitry Andric auto Data = Obj.template getSectionContentsAsArray<char>(Sec); 353fe6060f1SDimitry Andric if (!Data) 354fe6060f1SDimitry Andric return Data.takeError(); 355fe6060f1SDimitry Andric 35604eeddc0SDimitry Andric B = &G->createContentBlock(*GraphSec, *Data, 35704eeddc0SDimitry Andric orc::ExecutorAddr(Sec.sh_addr), 35804eeddc0SDimitry Andric Sec.sh_addralign, 0); 359fe6060f1SDimitry Andric } else 36004eeddc0SDimitry Andric B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size, 36104eeddc0SDimitry Andric orc::ExecutorAddr(Sec.sh_addr), 362fe6060f1SDimitry Andric Sec.sh_addralign, 0); 363fe6060f1SDimitry Andric 36404eeddc0SDimitry Andric setGraphBlock(SecIndex, B); 365fe6060f1SDimitry Andric } 366fe6060f1SDimitry Andric 367fe6060f1SDimitry Andric return Error::success(); 368fe6060f1SDimitry Andric } 369fe6060f1SDimitry Andric 370fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() { 371fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << " Creating graph symbols...\n"); 372fe6060f1SDimitry Andric 373fe6060f1SDimitry Andric // No SYMTAB -- Bail out early. 374fe6060f1SDimitry Andric if (!SymTabSec) 375fe6060f1SDimitry Andric return Error::success(); 376fe6060f1SDimitry Andric 377fe6060f1SDimitry Andric // Get the section content as a Symbols array. 378fe6060f1SDimitry Andric auto Symbols = Obj.symbols(SymTabSec); 379fe6060f1SDimitry Andric if (!Symbols) 380fe6060f1SDimitry Andric return Symbols.takeError(); 381fe6060f1SDimitry Andric 382fe6060f1SDimitry Andric // Get the string table for this section. 383fe6060f1SDimitry Andric auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections); 384fe6060f1SDimitry Andric if (!StringTab) 385fe6060f1SDimitry Andric return StringTab.takeError(); 386fe6060f1SDimitry Andric 387fe6060f1SDimitry Andric LLVM_DEBUG({ 388fe6060f1SDimitry Andric StringRef SymTabName; 389fe6060f1SDimitry Andric 390fe6060f1SDimitry Andric if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab)) 391fe6060f1SDimitry Andric SymTabName = *SymTabNameOrErr; 392fe6060f1SDimitry Andric else { 393fe6060f1SDimitry Andric dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: " 394fe6060f1SDimitry Andric << toString(SymTabNameOrErr.takeError()) << "\n"; 395fe6060f1SDimitry Andric SymTabName = "<SHT_SYMTAB section with invalid name>"; 396fe6060f1SDimitry Andric } 397fe6060f1SDimitry Andric 398fe6060f1SDimitry Andric dbgs() << " Adding symbols from symtab section \"" << SymTabName 399fe6060f1SDimitry Andric << "\"\n"; 400fe6060f1SDimitry Andric }); 401fe6060f1SDimitry Andric 402fe6060f1SDimitry Andric for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) { 403fe6060f1SDimitry Andric auto &Sym = (*Symbols)[SymIndex]; 404fe6060f1SDimitry Andric 405fe6060f1SDimitry Andric // Check symbol type. 406fe6060f1SDimitry Andric switch (Sym.getType()) { 407fe6060f1SDimitry Andric case ELF::STT_FILE: 408fe6060f1SDimitry Andric LLVM_DEBUG({ 409fe6060f1SDimitry Andric if (auto Name = Sym.getName(*StringTab)) 410fe6060f1SDimitry Andric dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \"" 411fe6060f1SDimitry Andric << *Name << "\"\n"; 412fe6060f1SDimitry Andric else { 413fe6060f1SDimitry Andric dbgs() << "Could not get STT_FILE symbol name: " 414fe6060f1SDimitry Andric << toString(Name.takeError()) << "\n"; 415fe6060f1SDimitry Andric dbgs() << " " << SymIndex 416fe6060f1SDimitry Andric << ": Skipping STT_FILE symbol with invalid name\n"; 417fe6060f1SDimitry Andric } 418fe6060f1SDimitry Andric }); 419fe6060f1SDimitry Andric continue; 420fe6060f1SDimitry Andric break; 421fe6060f1SDimitry Andric } 422fe6060f1SDimitry Andric 423fe6060f1SDimitry Andric // Get the symbol name. 424fe6060f1SDimitry Andric auto Name = Sym.getName(*StringTab); 425fe6060f1SDimitry Andric if (!Name) 426fe6060f1SDimitry Andric return Name.takeError(); 427fe6060f1SDimitry Andric 428fe6060f1SDimitry Andric // Handle common symbols specially. 429fe6060f1SDimitry Andric if (Sym.isCommon()) { 430*bdd1243dSDimitry Andric Symbol &GSym = G->addDefinedSymbol( 431*bdd1243dSDimitry Andric G->createZeroFillBlock(getCommonSection(), Sym.st_size, 432*bdd1243dSDimitry Andric orc::ExecutorAddr(), Sym.getValue(), 0), 433*bdd1243dSDimitry Andric 0, *Name, Sym.st_size, Linkage::Strong, Scope::Default, false, false); 434fe6060f1SDimitry Andric setGraphSymbol(SymIndex, GSym); 435fe6060f1SDimitry Andric continue; 436fe6060f1SDimitry Andric } 437fe6060f1SDimitry Andric 438fe6060f1SDimitry Andric if (Sym.isDefined() && 439fe6060f1SDimitry Andric (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC || 440fe6060f1SDimitry Andric Sym.getType() == ELF::STT_OBJECT || 441349cc55cSDimitry Andric Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) { 442*bdd1243dSDimitry Andric 443*bdd1243dSDimitry Andric // Map Visibility and Binding to Scope and Linkage: 444*bdd1243dSDimitry Andric Linkage L; 445*bdd1243dSDimitry Andric Scope S; 446*bdd1243dSDimitry Andric if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name)) 447*bdd1243dSDimitry Andric std::tie(L, S) = *LSOrErr; 448*bdd1243dSDimitry Andric else 449*bdd1243dSDimitry Andric return LSOrErr.takeError(); 450*bdd1243dSDimitry Andric 4514824e7fdSDimitry Andric // Handle extended tables. 4524824e7fdSDimitry Andric unsigned Shndx = Sym.st_shndx; 4534824e7fdSDimitry Andric if (Shndx == ELF::SHN_XINDEX) { 4544824e7fdSDimitry Andric auto ShndxTable = ShndxTables.find(SymTabSec); 4554824e7fdSDimitry Andric if (ShndxTable == ShndxTables.end()) 4564824e7fdSDimitry Andric continue; 4574824e7fdSDimitry Andric auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>( 4584824e7fdSDimitry Andric Sym, SymIndex, ShndxTable->second); 4594824e7fdSDimitry Andric if (!NdxOrErr) 4604824e7fdSDimitry Andric return NdxOrErr.takeError(); 4614824e7fdSDimitry Andric Shndx = *NdxOrErr; 4624824e7fdSDimitry Andric } 46304eeddc0SDimitry Andric if (auto *B = getGraphBlock(Shndx)) { 464fe6060f1SDimitry Andric LLVM_DEBUG({ 465fe6060f1SDimitry Andric dbgs() << " " << SymIndex 466fe6060f1SDimitry Andric << ": Creating defined graph symbol for ELF symbol \"" << *Name 467fe6060f1SDimitry Andric << "\"\n"; 468fe6060f1SDimitry Andric }); 469fe6060f1SDimitry Andric 47004eeddc0SDimitry Andric // In RISCV, temporary symbols (Used to generate dwarf, eh_frame 47104eeddc0SDimitry Andric // sections...) will appear in object code's symbol table, and LLVM does 47204eeddc0SDimitry Andric // not use names on these temporary symbols (RISCV gnu toolchain uses 47304eeddc0SDimitry Andric // names on these temporary symbols). If the symbol is unnamed, add an 47404eeddc0SDimitry Andric // anonymous symbol. 475fe6060f1SDimitry Andric auto &GSym = 47604eeddc0SDimitry Andric Name->empty() 47704eeddc0SDimitry Andric ? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size, 47804eeddc0SDimitry Andric false, false) 47904eeddc0SDimitry Andric : G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L, 48004eeddc0SDimitry Andric S, Sym.getType() == ELF::STT_FUNC, false); 481fe6060f1SDimitry Andric setGraphSymbol(SymIndex, GSym); 482fe6060f1SDimitry Andric } 483fe6060f1SDimitry Andric } else if (Sym.isUndefined() && Sym.isExternal()) { 484fe6060f1SDimitry Andric LLVM_DEBUG({ 485fe6060f1SDimitry Andric dbgs() << " " << SymIndex 486fe6060f1SDimitry Andric << ": Creating external graph symbol for ELF symbol \"" << *Name 487fe6060f1SDimitry Andric << "\"\n"; 488fe6060f1SDimitry Andric }); 489*bdd1243dSDimitry Andric 490*bdd1243dSDimitry Andric if (Sym.getBinding() != ELF::STB_GLOBAL && 491*bdd1243dSDimitry Andric Sym.getBinding() != ELF::STB_WEAK) 492*bdd1243dSDimitry Andric return make_error<StringError>( 493*bdd1243dSDimitry Andric "Invalid symbol binding " + 494*bdd1243dSDimitry Andric Twine(static_cast<int>(Sym.getBinding())) + 495*bdd1243dSDimitry Andric " for external symbol " + *Name, 496*bdd1243dSDimitry Andric inconvertibleErrorCode()); 497*bdd1243dSDimitry Andric 498*bdd1243dSDimitry Andric // If L is Linkage::Weak that means this is a weakly referenced symbol. 499*bdd1243dSDimitry Andric auto &GSym = G->addExternalSymbol(*Name, Sym.st_size, 500*bdd1243dSDimitry Andric Sym.getBinding() == ELF::STB_WEAK); 501fe6060f1SDimitry Andric setGraphSymbol(SymIndex, GSym); 502fe6060f1SDimitry Andric } else { 503fe6060f1SDimitry Andric LLVM_DEBUG({ 504fe6060f1SDimitry Andric dbgs() << " " << SymIndex 505fe6060f1SDimitry Andric << ": Not creating graph symbol for ELF symbol \"" << *Name 506fe6060f1SDimitry Andric << "\" with unrecognized type\n"; 507fe6060f1SDimitry Andric }); 508fe6060f1SDimitry Andric } 509fe6060f1SDimitry Andric } 510fe6060f1SDimitry Andric 511fe6060f1SDimitry Andric return Error::success(); 512fe6060f1SDimitry Andric } 513fe6060f1SDimitry Andric 514349cc55cSDimitry Andric template <typename ELFT> 515349cc55cSDimitry Andric template <typename RelocHandlerFunction> 516*bdd1243dSDimitry Andric Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation( 517349cc55cSDimitry Andric const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func, 518349cc55cSDimitry Andric bool ProcessDebugSections) { 519349cc55cSDimitry Andric // Only look into sections that store relocation entries. 520*bdd1243dSDimitry Andric if (RelSect.sh_type != ELF::SHT_RELA) 521349cc55cSDimitry Andric return Error::success(); 522349cc55cSDimitry Andric 523349cc55cSDimitry Andric // sh_info contains the section header index of the target (FixupSection), 524349cc55cSDimitry Andric // which is the section to which all relocations in RelSect apply. 525349cc55cSDimitry Andric auto FixupSection = Obj.getSection(RelSect.sh_info); 526349cc55cSDimitry Andric if (!FixupSection) 527349cc55cSDimitry Andric return FixupSection.takeError(); 528349cc55cSDimitry Andric 529349cc55cSDimitry Andric // Target sections have names in valid ELF object files. 530349cc55cSDimitry Andric Expected<StringRef> Name = Obj.getSectionName(**FixupSection); 531349cc55cSDimitry Andric if (!Name) 532349cc55cSDimitry Andric return Name.takeError(); 533349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << " " << *Name << ":\n"); 534349cc55cSDimitry Andric 535349cc55cSDimitry Andric // Consider skipping these relocations. 536349cc55cSDimitry Andric if (!ProcessDebugSections && isDwarfSection(*Name)) { 537349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n"); 538349cc55cSDimitry Andric return Error::success(); 539349cc55cSDimitry Andric } 540349cc55cSDimitry Andric 541349cc55cSDimitry Andric // Lookup the link-graph node corresponding to the target section name. 54204eeddc0SDimitry Andric auto *BlockToFix = getGraphBlock(RelSect.sh_info); 54304eeddc0SDimitry Andric if (!BlockToFix) 544349cc55cSDimitry Andric return make_error<StringError>( 545349cc55cSDimitry Andric "Refencing a section that wasn't added to the graph: " + *Name, 546349cc55cSDimitry Andric inconvertibleErrorCode()); 547349cc55cSDimitry Andric 548349cc55cSDimitry Andric auto RelEntries = Obj.relas(RelSect); 549349cc55cSDimitry Andric if (!RelEntries) 550349cc55cSDimitry Andric return RelEntries.takeError(); 551349cc55cSDimitry Andric 552349cc55cSDimitry Andric // Let the callee process relocation entries one by one. 553349cc55cSDimitry Andric for (const typename ELFT::Rela &R : *RelEntries) 55404eeddc0SDimitry Andric if (Error Err = Func(R, **FixupSection, *BlockToFix)) 555349cc55cSDimitry Andric return Err; 556349cc55cSDimitry Andric 557349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "\n"); 558349cc55cSDimitry Andric return Error::success(); 559349cc55cSDimitry Andric } 560349cc55cSDimitry Andric 561*bdd1243dSDimitry Andric template <typename ELFT> 562*bdd1243dSDimitry Andric template <typename RelocHandlerFunction> 563*bdd1243dSDimitry Andric Error ELFLinkGraphBuilder<ELFT>::forEachRelRelocation( 564*bdd1243dSDimitry Andric const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func, 565*bdd1243dSDimitry Andric bool ProcessDebugSections) { 566*bdd1243dSDimitry Andric // Only look into sections that store relocation entries. 567*bdd1243dSDimitry Andric if (RelSect.sh_type != ELF::SHT_REL) 568*bdd1243dSDimitry Andric return Error::success(); 569*bdd1243dSDimitry Andric 570*bdd1243dSDimitry Andric // sh_info contains the section header index of the target (FixupSection), 571*bdd1243dSDimitry Andric // which is the section to which all relocations in RelSect apply. 572*bdd1243dSDimitry Andric auto FixupSection = Obj.getSection(RelSect.sh_info); 573*bdd1243dSDimitry Andric if (!FixupSection) 574*bdd1243dSDimitry Andric return FixupSection.takeError(); 575*bdd1243dSDimitry Andric 576*bdd1243dSDimitry Andric // Target sections have names in valid ELF object files. 577*bdd1243dSDimitry Andric Expected<StringRef> Name = Obj.getSectionName(**FixupSection); 578*bdd1243dSDimitry Andric if (!Name) 579*bdd1243dSDimitry Andric return Name.takeError(); 580*bdd1243dSDimitry Andric LLVM_DEBUG(dbgs() << " " << *Name << ":\n"); 581*bdd1243dSDimitry Andric 582*bdd1243dSDimitry Andric // Consider skipping these relocations. 583*bdd1243dSDimitry Andric if (!ProcessDebugSections && isDwarfSection(*Name)) { 584*bdd1243dSDimitry Andric LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n"); 585*bdd1243dSDimitry Andric return Error::success(); 586*bdd1243dSDimitry Andric } 587*bdd1243dSDimitry Andric 588*bdd1243dSDimitry Andric // Lookup the link-graph node corresponding to the target section name. 589*bdd1243dSDimitry Andric auto *BlockToFix = getGraphBlock(RelSect.sh_info); 590*bdd1243dSDimitry Andric if (!BlockToFix) 591*bdd1243dSDimitry Andric return make_error<StringError>( 592*bdd1243dSDimitry Andric "Refencing a section that wasn't added to the graph: " + *Name, 593*bdd1243dSDimitry Andric inconvertibleErrorCode()); 594*bdd1243dSDimitry Andric 595*bdd1243dSDimitry Andric auto RelEntries = Obj.rels(RelSect); 596*bdd1243dSDimitry Andric if (!RelEntries) 597*bdd1243dSDimitry Andric return RelEntries.takeError(); 598*bdd1243dSDimitry Andric 599*bdd1243dSDimitry Andric // Let the callee process relocation entries one by one. 600*bdd1243dSDimitry Andric for (const typename ELFT::Rel &R : *RelEntries) 601*bdd1243dSDimitry Andric if (Error Err = Func(R, **FixupSection, *BlockToFix)) 602*bdd1243dSDimitry Andric return Err; 603*bdd1243dSDimitry Andric 604*bdd1243dSDimitry Andric LLVM_DEBUG(dbgs() << "\n"); 605*bdd1243dSDimitry Andric return Error::success(); 606*bdd1243dSDimitry Andric } 607*bdd1243dSDimitry Andric 608fe6060f1SDimitry Andric } // end namespace jitlink 609fe6060f1SDimitry Andric } // end namespace llvm 610fe6060f1SDimitry Andric 611fe6060f1SDimitry Andric #undef DEBUG_TYPE 612fe6060f1SDimitry Andric 613fe6060f1SDimitry Andric #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H 614