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) 40349cc55cSDimitry Andric CommonSection = 41349cc55cSDimitry 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 111349cc55cSDimitry Andric /// Traverse all matching relocation records in the given section. The handler 112349cc55cSDimitry Andric /// function Func should be callable with this signature: 113349cc55cSDimitry Andric /// Error(const typename ELFT::Rela &, 114349cc55cSDimitry Andric /// const typename ELFT::Shdr &, Section &) 115349cc55cSDimitry Andric /// 116349cc55cSDimitry Andric template <typename RelocHandlerFunction> 117349cc55cSDimitry Andric Error forEachRelocation(const typename ELFT::Shdr &RelSect, 118349cc55cSDimitry Andric RelocHandlerFunction &&Func, 119349cc55cSDimitry Andric bool ProcessDebugSections = false); 120349cc55cSDimitry Andric 121349cc55cSDimitry Andric /// Traverse all matching relocation records in the given section. Convenience 122349cc55cSDimitry Andric /// wrapper to allow passing a member function for the handler. 123349cc55cSDimitry Andric /// 124349cc55cSDimitry Andric template <typename ClassT, typename RelocHandlerMethod> 125349cc55cSDimitry Andric Error forEachRelocation(const typename ELFT::Shdr &RelSect, ClassT *Instance, 126349cc55cSDimitry Andric RelocHandlerMethod &&Method, 127349cc55cSDimitry Andric bool ProcessDebugSections = false) { 128349cc55cSDimitry Andric return forEachRelocation( 129349cc55cSDimitry Andric RelSect, 130349cc55cSDimitry Andric [Instance, Method](const auto &Rel, const auto &Target, auto &GS) { 131349cc55cSDimitry Andric return (Instance->*Method)(Rel, Target, GS); 132349cc55cSDimitry Andric }, 133349cc55cSDimitry Andric ProcessDebugSections); 134349cc55cSDimitry Andric } 135349cc55cSDimitry 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; 146*4824e7fdSDimitry Andric DenseMap<const typename ELFFile::Elf_Shdr *, 147*4824e7fdSDimitry Andric ArrayRef<typename ELFFile::Elf_Word>> 148*4824e7fdSDimitry Andric ShndxTables; 149fe6060f1SDimitry Andric }; 150fe6060f1SDimitry Andric 151fe6060f1SDimitry Andric template <typename ELFT> 152fe6060f1SDimitry Andric ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder( 153fe6060f1SDimitry Andric const ELFFile &Obj, Triple TT, StringRef FileName, 154fe6060f1SDimitry Andric LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) 155fe6060f1SDimitry Andric : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>( 156fe6060f1SDimitry Andric FileName.str(), Triple(std::move(TT)), ELFT::Is64Bits ? 8 : 4, 157fe6060f1SDimitry Andric support::endianness(ELFT::TargetEndianness), 158fe6060f1SDimitry Andric std::move(GetEdgeKindName))), 159fe6060f1SDimitry Andric Obj(Obj) { 160fe6060f1SDimitry Andric LLVM_DEBUG( 161fe6060f1SDimitry Andric { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; }); 162fe6060f1SDimitry Andric } 163fe6060f1SDimitry Andric 164fe6060f1SDimitry Andric template <typename ELFT> 165fe6060f1SDimitry Andric Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() { 166fe6060f1SDimitry Andric if (!isRelocatable()) 167fe6060f1SDimitry Andric return make_error<JITLinkError>("Object is not a relocatable ELF file"); 168fe6060f1SDimitry Andric 169fe6060f1SDimitry Andric if (auto Err = prepare()) 170fe6060f1SDimitry Andric return std::move(Err); 171fe6060f1SDimitry Andric 172fe6060f1SDimitry Andric if (auto Err = graphifySections()) 173fe6060f1SDimitry Andric return std::move(Err); 174fe6060f1SDimitry Andric 175fe6060f1SDimitry Andric if (auto Err = graphifySymbols()) 176fe6060f1SDimitry Andric return std::move(Err); 177fe6060f1SDimitry Andric 178fe6060f1SDimitry Andric if (auto Err = addRelocations()) 179fe6060f1SDimitry Andric return std::move(Err); 180fe6060f1SDimitry Andric 181fe6060f1SDimitry Andric return std::move(G); 182fe6060f1SDimitry Andric } 183fe6060f1SDimitry Andric 184fe6060f1SDimitry Andric template <typename ELFT> 185fe6060f1SDimitry Andric Expected<std::pair<Linkage, Scope>> 186fe6060f1SDimitry Andric ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope( 187fe6060f1SDimitry Andric const typename ELFT::Sym &Sym, StringRef Name) { 188fe6060f1SDimitry Andric Linkage L = Linkage::Strong; 189fe6060f1SDimitry Andric Scope S = Scope::Default; 190fe6060f1SDimitry Andric 191fe6060f1SDimitry Andric switch (Sym.getBinding()) { 192fe6060f1SDimitry Andric case ELF::STB_LOCAL: 193fe6060f1SDimitry Andric S = Scope::Local; 194fe6060f1SDimitry Andric break; 195fe6060f1SDimitry Andric case ELF::STB_GLOBAL: 196fe6060f1SDimitry Andric // Nothing to do here. 197fe6060f1SDimitry Andric break; 198fe6060f1SDimitry Andric case ELF::STB_WEAK: 199349cc55cSDimitry Andric case ELF::STB_GNU_UNIQUE: 200fe6060f1SDimitry Andric L = Linkage::Weak; 201fe6060f1SDimitry Andric break; 202fe6060f1SDimitry Andric default: 203349cc55cSDimitry Andric return make_error<StringError>( 204349cc55cSDimitry Andric "Unrecognized symbol binding " + 205349cc55cSDimitry Andric Twine(static_cast<int>(Sym.getBinding())) + " for " + Name, 206fe6060f1SDimitry Andric inconvertibleErrorCode()); 207fe6060f1SDimitry Andric } 208fe6060f1SDimitry Andric 209fe6060f1SDimitry Andric switch (Sym.getVisibility()) { 210fe6060f1SDimitry Andric case ELF::STV_DEFAULT: 211fe6060f1SDimitry Andric case ELF::STV_PROTECTED: 212fe6060f1SDimitry Andric // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs 213fe6060f1SDimitry Andric // Orc support. 214fe6060f1SDimitry Andric // Otherwise nothing to do here. 215fe6060f1SDimitry Andric break; 216fe6060f1SDimitry Andric case ELF::STV_HIDDEN: 217fe6060f1SDimitry Andric // Default scope -> Hidden scope. No effect on local scope. 218fe6060f1SDimitry Andric if (S == Scope::Default) 219fe6060f1SDimitry Andric S = Scope::Hidden; 220fe6060f1SDimitry Andric break; 221fe6060f1SDimitry Andric case ELF::STV_INTERNAL: 222349cc55cSDimitry Andric return make_error<StringError>( 223349cc55cSDimitry Andric "Unrecognized symbol visibility " + 224349cc55cSDimitry Andric Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name, 225fe6060f1SDimitry Andric inconvertibleErrorCode()); 226fe6060f1SDimitry Andric } 227fe6060f1SDimitry Andric 228fe6060f1SDimitry Andric return std::make_pair(L, S); 229fe6060f1SDimitry Andric } 230fe6060f1SDimitry Andric 231fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() { 232fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << " Preparing to build...\n"); 233fe6060f1SDimitry Andric 234fe6060f1SDimitry Andric // Get the sections array. 235fe6060f1SDimitry Andric if (auto SectionsOrErr = Obj.sections()) 236fe6060f1SDimitry Andric Sections = *SectionsOrErr; 237fe6060f1SDimitry Andric else 238fe6060f1SDimitry Andric return SectionsOrErr.takeError(); 239fe6060f1SDimitry Andric 240fe6060f1SDimitry Andric // Get the section string table. 241fe6060f1SDimitry Andric if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections)) 242fe6060f1SDimitry Andric SectionStringTab = *SectionStringTabOrErr; 243fe6060f1SDimitry Andric else 244fe6060f1SDimitry Andric return SectionStringTabOrErr.takeError(); 245fe6060f1SDimitry Andric 246fe6060f1SDimitry Andric // Get the SHT_SYMTAB section. 247*4824e7fdSDimitry Andric for (auto &Sec : Sections) { 248fe6060f1SDimitry Andric if (Sec.sh_type == ELF::SHT_SYMTAB) { 249fe6060f1SDimitry Andric if (!SymTabSec) 250fe6060f1SDimitry Andric SymTabSec = &Sec; 251fe6060f1SDimitry Andric else 252fe6060f1SDimitry Andric return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " + 253fe6060f1SDimitry Andric G->getName()); 254fe6060f1SDimitry Andric } 255fe6060f1SDimitry Andric 256*4824e7fdSDimitry Andric // Extended table. 257*4824e7fdSDimitry Andric if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) { 258*4824e7fdSDimitry Andric uint32_t SymtabNdx = Sec.sh_link; 259*4824e7fdSDimitry Andric if (SymtabNdx >= Sections.size()) 260*4824e7fdSDimitry Andric return make_error<JITLinkError>("sh_link is out of bound"); 261*4824e7fdSDimitry Andric 262*4824e7fdSDimitry Andric auto ShndxTable = Obj.getSHNDXTable(Sec); 263*4824e7fdSDimitry Andric if (!ShndxTable) 264*4824e7fdSDimitry Andric return ShndxTable.takeError(); 265*4824e7fdSDimitry Andric 266*4824e7fdSDimitry Andric ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable}); 267*4824e7fdSDimitry Andric } 268*4824e7fdSDimitry Andric } 269*4824e7fdSDimitry Andric 270fe6060f1SDimitry Andric return Error::success(); 271fe6060f1SDimitry Andric } 272fe6060f1SDimitry Andric 273fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() { 274fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << " Creating graph sections...\n"); 275fe6060f1SDimitry Andric 276fe6060f1SDimitry Andric // For each section... 277fe6060f1SDimitry Andric for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) { 278fe6060f1SDimitry Andric 279fe6060f1SDimitry Andric auto &Sec = Sections[SecIndex]; 280fe6060f1SDimitry Andric 281fe6060f1SDimitry Andric // Start by getting the section name. 282fe6060f1SDimitry Andric auto Name = Obj.getSectionName(Sec, SectionStringTab); 283fe6060f1SDimitry Andric if (!Name) 284fe6060f1SDimitry Andric return Name.takeError(); 285fe6060f1SDimitry Andric 286fe6060f1SDimitry Andric // If the name indicates that it's a debug section then skip it: We don't 287fe6060f1SDimitry Andric // support those yet. 288fe6060f1SDimitry Andric if (isDwarfSection(*Name)) { 289fe6060f1SDimitry Andric LLVM_DEBUG({ 290fe6060f1SDimitry Andric dbgs() << " " << SecIndex << ": \"" << *Name 291fe6060f1SDimitry Andric << "\" is a debug section: " 292fe6060f1SDimitry Andric "No graph section will be created.\n"; 293fe6060f1SDimitry Andric }); 294fe6060f1SDimitry Andric continue; 295fe6060f1SDimitry Andric } 296fe6060f1SDimitry Andric 297fe6060f1SDimitry Andric // Skip non-SHF_ALLOC sections 298fe6060f1SDimitry Andric if (!(Sec.sh_flags & ELF::SHF_ALLOC)) { 299fe6060f1SDimitry Andric LLVM_DEBUG({ 300fe6060f1SDimitry Andric dbgs() << " " << SecIndex << ": \"" << *Name 301fe6060f1SDimitry Andric << "\" is not an SHF_ALLOC section: " 302fe6060f1SDimitry Andric "No graph section will be created.\n"; 303fe6060f1SDimitry Andric }); 304fe6060f1SDimitry Andric continue; 305fe6060f1SDimitry Andric } 306fe6060f1SDimitry Andric 307fe6060f1SDimitry Andric LLVM_DEBUG({ 308fe6060f1SDimitry Andric dbgs() << " " << SecIndex << ": Creating section for \"" << *Name 309fe6060f1SDimitry Andric << "\"\n"; 310fe6060f1SDimitry Andric }); 311fe6060f1SDimitry Andric 312fe6060f1SDimitry Andric // Get the section's memory protection flags. 313349cc55cSDimitry Andric MemProt Prot; 314fe6060f1SDimitry Andric if (Sec.sh_flags & ELF::SHF_EXECINSTR) 315349cc55cSDimitry Andric Prot = MemProt::Read | MemProt::Exec; 316fe6060f1SDimitry Andric else 317349cc55cSDimitry Andric Prot = MemProt::Read | MemProt::Write; 318fe6060f1SDimitry Andric 319fe6060f1SDimitry Andric auto &GraphSec = G->createSection(*Name, Prot); 320fe6060f1SDimitry Andric if (Sec.sh_type != ELF::SHT_NOBITS) { 321fe6060f1SDimitry Andric auto Data = Obj.template getSectionContentsAsArray<char>(Sec); 322fe6060f1SDimitry Andric if (!Data) 323fe6060f1SDimitry Andric return Data.takeError(); 324fe6060f1SDimitry Andric 325fe6060f1SDimitry Andric G->createContentBlock(GraphSec, *Data, Sec.sh_addr, Sec.sh_addralign, 0); 326fe6060f1SDimitry Andric } else 327fe6060f1SDimitry Andric G->createZeroFillBlock(GraphSec, Sec.sh_size, Sec.sh_addr, 328fe6060f1SDimitry Andric Sec.sh_addralign, 0); 329fe6060f1SDimitry Andric 330fe6060f1SDimitry Andric setGraphSection(SecIndex, GraphSec); 331fe6060f1SDimitry Andric } 332fe6060f1SDimitry Andric 333fe6060f1SDimitry Andric return Error::success(); 334fe6060f1SDimitry Andric } 335fe6060f1SDimitry Andric 336fe6060f1SDimitry Andric template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() { 337fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << " Creating graph symbols...\n"); 338fe6060f1SDimitry Andric 339fe6060f1SDimitry Andric // No SYMTAB -- Bail out early. 340fe6060f1SDimitry Andric if (!SymTabSec) 341fe6060f1SDimitry Andric return Error::success(); 342fe6060f1SDimitry Andric 343fe6060f1SDimitry Andric // Get the section content as a Symbols array. 344fe6060f1SDimitry Andric auto Symbols = Obj.symbols(SymTabSec); 345fe6060f1SDimitry Andric if (!Symbols) 346fe6060f1SDimitry Andric return Symbols.takeError(); 347fe6060f1SDimitry Andric 348fe6060f1SDimitry Andric // Get the string table for this section. 349fe6060f1SDimitry Andric auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections); 350fe6060f1SDimitry Andric if (!StringTab) 351fe6060f1SDimitry Andric return StringTab.takeError(); 352fe6060f1SDimitry Andric 353fe6060f1SDimitry Andric LLVM_DEBUG({ 354fe6060f1SDimitry Andric StringRef SymTabName; 355fe6060f1SDimitry Andric 356fe6060f1SDimitry Andric if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab)) 357fe6060f1SDimitry Andric SymTabName = *SymTabNameOrErr; 358fe6060f1SDimitry Andric else { 359fe6060f1SDimitry Andric dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: " 360fe6060f1SDimitry Andric << toString(SymTabNameOrErr.takeError()) << "\n"; 361fe6060f1SDimitry Andric SymTabName = "<SHT_SYMTAB section with invalid name>"; 362fe6060f1SDimitry Andric } 363fe6060f1SDimitry Andric 364fe6060f1SDimitry Andric dbgs() << " Adding symbols from symtab section \"" << SymTabName 365fe6060f1SDimitry Andric << "\"\n"; 366fe6060f1SDimitry Andric }); 367fe6060f1SDimitry Andric 368fe6060f1SDimitry Andric for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) { 369fe6060f1SDimitry Andric auto &Sym = (*Symbols)[SymIndex]; 370fe6060f1SDimitry Andric 371fe6060f1SDimitry Andric // Check symbol type. 372fe6060f1SDimitry Andric switch (Sym.getType()) { 373fe6060f1SDimitry Andric case ELF::STT_FILE: 374fe6060f1SDimitry Andric LLVM_DEBUG({ 375fe6060f1SDimitry Andric if (auto Name = Sym.getName(*StringTab)) 376fe6060f1SDimitry Andric dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \"" 377fe6060f1SDimitry Andric << *Name << "\"\n"; 378fe6060f1SDimitry Andric else { 379fe6060f1SDimitry Andric dbgs() << "Could not get STT_FILE symbol name: " 380fe6060f1SDimitry Andric << toString(Name.takeError()) << "\n"; 381fe6060f1SDimitry Andric dbgs() << " " << SymIndex 382fe6060f1SDimitry Andric << ": Skipping STT_FILE symbol with invalid name\n"; 383fe6060f1SDimitry Andric } 384fe6060f1SDimitry Andric }); 385fe6060f1SDimitry Andric continue; 386fe6060f1SDimitry Andric break; 387fe6060f1SDimitry Andric } 388fe6060f1SDimitry Andric 389fe6060f1SDimitry Andric // Get the symbol name. 390fe6060f1SDimitry Andric auto Name = Sym.getName(*StringTab); 391fe6060f1SDimitry Andric if (!Name) 392fe6060f1SDimitry Andric return Name.takeError(); 393fe6060f1SDimitry Andric 394fe6060f1SDimitry Andric // Handle common symbols specially. 395fe6060f1SDimitry Andric if (Sym.isCommon()) { 396fe6060f1SDimitry Andric Symbol &GSym = 397fe6060f1SDimitry Andric G->addCommonSymbol(*Name, Scope::Default, getCommonSection(), 0, 398fe6060f1SDimitry Andric Sym.st_size, Sym.getValue(), false); 399fe6060f1SDimitry Andric setGraphSymbol(SymIndex, GSym); 400fe6060f1SDimitry Andric continue; 401fe6060f1SDimitry Andric } 402fe6060f1SDimitry Andric 403fe6060f1SDimitry Andric // Map Visibility and Binding to Scope and Linkage: 404fe6060f1SDimitry Andric Linkage L; 405fe6060f1SDimitry Andric Scope S; 406fe6060f1SDimitry Andric 407fe6060f1SDimitry Andric if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name)) 408fe6060f1SDimitry Andric std::tie(L, S) = *LSOrErr; 409fe6060f1SDimitry Andric else 410fe6060f1SDimitry Andric return LSOrErr.takeError(); 411fe6060f1SDimitry Andric 412fe6060f1SDimitry Andric if (Sym.isDefined() && 413fe6060f1SDimitry Andric (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC || 414fe6060f1SDimitry Andric Sym.getType() == ELF::STT_OBJECT || 415349cc55cSDimitry Andric Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) { 416*4824e7fdSDimitry Andric // Handle extended tables. 417*4824e7fdSDimitry Andric unsigned Shndx = Sym.st_shndx; 418*4824e7fdSDimitry Andric if (Shndx == ELF::SHN_XINDEX) { 419*4824e7fdSDimitry Andric auto ShndxTable = ShndxTables.find(SymTabSec); 420*4824e7fdSDimitry Andric if (ShndxTable == ShndxTables.end()) 421*4824e7fdSDimitry Andric continue; 422*4824e7fdSDimitry Andric auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>( 423*4824e7fdSDimitry Andric Sym, SymIndex, ShndxTable->second); 424*4824e7fdSDimitry Andric if (!NdxOrErr) 425*4824e7fdSDimitry Andric return NdxOrErr.takeError(); 426*4824e7fdSDimitry Andric Shndx = *NdxOrErr; 427*4824e7fdSDimitry Andric } 428*4824e7fdSDimitry Andric if (auto *GraphSec = getGraphSection(Shndx)) { 429fe6060f1SDimitry Andric Block *B = nullptr; 430fe6060f1SDimitry Andric { 431fe6060f1SDimitry Andric auto Blocks = GraphSec->blocks(); 432fe6060f1SDimitry Andric assert(Blocks.begin() != Blocks.end() && "No blocks for section"); 433fe6060f1SDimitry Andric assert(std::next(Blocks.begin()) == Blocks.end() && 434fe6060f1SDimitry Andric "Multiple blocks for section"); 435fe6060f1SDimitry Andric B = *Blocks.begin(); 436fe6060f1SDimitry Andric } 437fe6060f1SDimitry Andric 438fe6060f1SDimitry Andric LLVM_DEBUG({ 439fe6060f1SDimitry Andric dbgs() << " " << SymIndex 440fe6060f1SDimitry Andric << ": Creating defined graph symbol for ELF symbol \"" << *Name 441fe6060f1SDimitry Andric << "\"\n"; 442fe6060f1SDimitry Andric }); 443fe6060f1SDimitry Andric 444fe6060f1SDimitry Andric if (Sym.getType() == ELF::STT_SECTION) 445fe6060f1SDimitry Andric *Name = GraphSec->getName(); 446fe6060f1SDimitry Andric 447fe6060f1SDimitry Andric auto &GSym = 448fe6060f1SDimitry Andric G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L, S, 449fe6060f1SDimitry Andric Sym.getType() == ELF::STT_FUNC, false); 450fe6060f1SDimitry Andric setGraphSymbol(SymIndex, GSym); 451fe6060f1SDimitry Andric } 452fe6060f1SDimitry Andric } else if (Sym.isUndefined() && Sym.isExternal()) { 453fe6060f1SDimitry Andric LLVM_DEBUG({ 454fe6060f1SDimitry Andric dbgs() << " " << SymIndex 455fe6060f1SDimitry Andric << ": Creating external graph symbol for ELF symbol \"" << *Name 456fe6060f1SDimitry Andric << "\"\n"; 457fe6060f1SDimitry Andric }); 458fe6060f1SDimitry Andric auto &GSym = G->addExternalSymbol(*Name, Sym.st_size, L); 459fe6060f1SDimitry Andric setGraphSymbol(SymIndex, GSym); 460fe6060f1SDimitry Andric } else { 461fe6060f1SDimitry Andric LLVM_DEBUG({ 462fe6060f1SDimitry Andric dbgs() << " " << SymIndex 463fe6060f1SDimitry Andric << ": Not creating graph symbol for ELF symbol \"" << *Name 464fe6060f1SDimitry Andric << "\" with unrecognized type\n"; 465fe6060f1SDimitry Andric }); 466fe6060f1SDimitry Andric } 467fe6060f1SDimitry Andric } 468fe6060f1SDimitry Andric 469fe6060f1SDimitry Andric return Error::success(); 470fe6060f1SDimitry Andric } 471fe6060f1SDimitry Andric 472349cc55cSDimitry Andric template <typename ELFT> 473349cc55cSDimitry Andric template <typename RelocHandlerFunction> 474349cc55cSDimitry Andric Error ELFLinkGraphBuilder<ELFT>::forEachRelocation( 475349cc55cSDimitry Andric const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func, 476349cc55cSDimitry Andric bool ProcessDebugSections) { 477349cc55cSDimitry Andric 478349cc55cSDimitry Andric // Only look into sections that store relocation entries. 479349cc55cSDimitry Andric if (RelSect.sh_type != ELF::SHT_RELA && RelSect.sh_type != ELF::SHT_REL) 480349cc55cSDimitry Andric return Error::success(); 481349cc55cSDimitry Andric 482349cc55cSDimitry Andric // sh_info contains the section header index of the target (FixupSection), 483349cc55cSDimitry Andric // which is the section to which all relocations in RelSect apply. 484349cc55cSDimitry Andric auto FixupSection = Obj.getSection(RelSect.sh_info); 485349cc55cSDimitry Andric if (!FixupSection) 486349cc55cSDimitry Andric return FixupSection.takeError(); 487349cc55cSDimitry Andric 488349cc55cSDimitry Andric // Target sections have names in valid ELF object files. 489349cc55cSDimitry Andric Expected<StringRef> Name = Obj.getSectionName(**FixupSection); 490349cc55cSDimitry Andric if (!Name) 491349cc55cSDimitry Andric return Name.takeError(); 492349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << " " << *Name << ":\n"); 493349cc55cSDimitry Andric 494349cc55cSDimitry Andric // Consider skipping these relocations. 495349cc55cSDimitry Andric if (!ProcessDebugSections && isDwarfSection(*Name)) { 496349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n"); 497349cc55cSDimitry Andric return Error::success(); 498349cc55cSDimitry Andric } 499349cc55cSDimitry Andric 500349cc55cSDimitry Andric // Lookup the link-graph node corresponding to the target section name. 501349cc55cSDimitry Andric Section *GraphSect = G->findSectionByName(*Name); 502349cc55cSDimitry Andric if (!GraphSect) 503349cc55cSDimitry Andric return make_error<StringError>( 504349cc55cSDimitry Andric "Refencing a section that wasn't added to the graph: " + *Name, 505349cc55cSDimitry Andric inconvertibleErrorCode()); 506349cc55cSDimitry Andric 507349cc55cSDimitry Andric auto RelEntries = Obj.relas(RelSect); 508349cc55cSDimitry Andric if (!RelEntries) 509349cc55cSDimitry Andric return RelEntries.takeError(); 510349cc55cSDimitry Andric 511349cc55cSDimitry Andric // Let the callee process relocation entries one by one. 512349cc55cSDimitry Andric for (const typename ELFT::Rela &R : *RelEntries) 513349cc55cSDimitry Andric if (Error Err = Func(R, **FixupSection, *GraphSect)) 514349cc55cSDimitry Andric return Err; 515349cc55cSDimitry Andric 516349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "\n"); 517349cc55cSDimitry Andric return Error::success(); 518349cc55cSDimitry Andric } 519349cc55cSDimitry Andric 520fe6060f1SDimitry Andric } // end namespace jitlink 521fe6060f1SDimitry Andric } // end namespace llvm 522fe6060f1SDimitry Andric 523fe6060f1SDimitry Andric #undef DEBUG_TYPE 524fe6060f1SDimitry Andric 525fe6060f1SDimitry Andric #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H 526