1*0b57cec5SDimitry Andric //===- InputSection.h -------------------------------------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #ifndef LLD_ELF_INPUT_SECTION_H 10*0b57cec5SDimitry Andric #define LLD_ELF_INPUT_SECTION_H 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "Config.h" 13*0b57cec5SDimitry Andric #include "Relocations.h" 14*0b57cec5SDimitry Andric #include "Thunks.h" 15*0b57cec5SDimitry Andric #include "lld/Common/LLVM.h" 16*0b57cec5SDimitry Andric #include "llvm/ADT/CachedHashString.h" 17*0b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/TinyPtrVector.h" 19*0b57cec5SDimitry Andric #include "llvm/Object/ELF.h" 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric namespace lld { 22*0b57cec5SDimitry Andric namespace elf { 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric class Symbol; 25*0b57cec5SDimitry Andric struct SectionPiece; 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric class Defined; 28*0b57cec5SDimitry Andric struct Partition; 29*0b57cec5SDimitry Andric class SyntheticSection; 30*0b57cec5SDimitry Andric class MergeSyntheticSection; 31*0b57cec5SDimitry Andric template <class ELFT> class ObjFile; 32*0b57cec5SDimitry Andric class OutputSection; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric extern std::vector<Partition> partitions; 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric // This is the base class of all sections that lld handles. Some are sections in 37*0b57cec5SDimitry Andric // input files, some are sections in the produced output file and some exist 38*0b57cec5SDimitry Andric // just as a convenience for implementing special ways of combining some 39*0b57cec5SDimitry Andric // sections. 40*0b57cec5SDimitry Andric class SectionBase { 41*0b57cec5SDimitry Andric public: 42*0b57cec5SDimitry Andric enum Kind { Regular, EHFrame, Merge, Synthetic, Output }; 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric Kind kind() const { return (Kind)sectionKind; } 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric StringRef name; 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric // This pointer points to the "real" instance of this instance. 49*0b57cec5SDimitry Andric // Usually Repl == this. However, if ICF merges two sections, 50*0b57cec5SDimitry Andric // Repl pointer of one section points to another section. So, 51*0b57cec5SDimitry Andric // if you need to get a pointer to this instance, do not use 52*0b57cec5SDimitry Andric // this but instead this->Repl. 53*0b57cec5SDimitry Andric SectionBase *repl; 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric unsigned sectionKind : 3; 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric // The next three bit fields are only used by InputSectionBase, but we 58*0b57cec5SDimitry Andric // put them here so the struct packs better. 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric // True if this section has already been placed to a linker script 61*0b57cec5SDimitry Andric // output section. This is needed because, in a linker script, you 62*0b57cec5SDimitry Andric // can refer to the same section more than once. For example, in 63*0b57cec5SDimitry Andric // the following linker script, 64*0b57cec5SDimitry Andric // 65*0b57cec5SDimitry Andric // .foo : { *(.text) } 66*0b57cec5SDimitry Andric // .bar : { *(.text) } 67*0b57cec5SDimitry Andric // 68*0b57cec5SDimitry Andric // .foo takes all .text sections, and .bar becomes empty. To achieve 69*0b57cec5SDimitry Andric // this, we need to memorize whether a section has been placed or 70*0b57cec5SDimitry Andric // not for each input section. 71*0b57cec5SDimitry Andric unsigned assigned : 1; 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric unsigned bss : 1; 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric // Set for sections that should not be folded by ICF. 76*0b57cec5SDimitry Andric unsigned keepUnique : 1; 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric // The 1-indexed partition that this section is assigned to by the garbage 79*0b57cec5SDimitry Andric // collector, or 0 if this section is dead. Normally there is only one 80*0b57cec5SDimitry Andric // partition, so this will either be 0 or 1. 81*0b57cec5SDimitry Andric uint8_t partition; 82*0b57cec5SDimitry Andric elf::Partition &getPartition() const; 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric // These corresponds to the fields in Elf_Shdr. 85*0b57cec5SDimitry Andric uint32_t alignment; 86*0b57cec5SDimitry Andric uint64_t flags; 87*0b57cec5SDimitry Andric uint64_t entsize; 88*0b57cec5SDimitry Andric uint32_t type; 89*0b57cec5SDimitry Andric uint32_t link; 90*0b57cec5SDimitry Andric uint32_t info; 91*0b57cec5SDimitry Andric 92*0b57cec5SDimitry Andric OutputSection *getOutputSection(); 93*0b57cec5SDimitry Andric const OutputSection *getOutputSection() const { 94*0b57cec5SDimitry Andric return const_cast<SectionBase *>(this)->getOutputSection(); 95*0b57cec5SDimitry Andric } 96*0b57cec5SDimitry Andric 97*0b57cec5SDimitry Andric // Translate an offset in the input section to an offset in the output 98*0b57cec5SDimitry Andric // section. 99*0b57cec5SDimitry Andric uint64_t getOffset(uint64_t offset) const; 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric uint64_t getVA(uint64_t offset = 0) const; 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric bool isLive() const { return partition != 0; } 104*0b57cec5SDimitry Andric void markLive() { partition = 1; } 105*0b57cec5SDimitry Andric void markDead() { partition = 0; } 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric protected: 108*0b57cec5SDimitry Andric SectionBase(Kind sectionKind, StringRef name, uint64_t flags, 109*0b57cec5SDimitry Andric uint64_t entsize, uint64_t alignment, uint32_t type, 110*0b57cec5SDimitry Andric uint32_t info, uint32_t link) 111*0b57cec5SDimitry Andric : name(name), repl(this), sectionKind(sectionKind), assigned(false), 112*0b57cec5SDimitry Andric bss(false), keepUnique(false), partition(0), alignment(alignment), 113*0b57cec5SDimitry Andric flags(flags), entsize(entsize), type(type), link(link), info(info) {} 114*0b57cec5SDimitry Andric }; 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric // This corresponds to a section of an input file. 117*0b57cec5SDimitry Andric class InputSectionBase : public SectionBase { 118*0b57cec5SDimitry Andric public: 119*0b57cec5SDimitry Andric template <class ELFT> 120*0b57cec5SDimitry Andric InputSectionBase(ObjFile<ELFT> &file, const typename ELFT::Shdr &header, 121*0b57cec5SDimitry Andric StringRef name, Kind sectionKind); 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric InputSectionBase(InputFile *file, uint64_t flags, uint32_t type, 124*0b57cec5SDimitry Andric uint64_t entsize, uint32_t link, uint32_t info, 125*0b57cec5SDimitry Andric uint32_t alignment, ArrayRef<uint8_t> data, StringRef name, 126*0b57cec5SDimitry Andric Kind sectionKind); 127*0b57cec5SDimitry Andric 128*0b57cec5SDimitry Andric static bool classof(const SectionBase *s) { return s->kind() != Output; } 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric // Relocations that refer to this section. 131*0b57cec5SDimitry Andric unsigned numRelocations : 31; 132*0b57cec5SDimitry Andric unsigned areRelocsRela : 1; 133*0b57cec5SDimitry Andric const void *firstRelocation = nullptr; 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric // The file which contains this section. Its dynamic type is always 136*0b57cec5SDimitry Andric // ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as 137*0b57cec5SDimitry Andric // its static type. 138*0b57cec5SDimitry Andric InputFile *file; 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric template <class ELFT> ObjFile<ELFT> *getFile() const { 141*0b57cec5SDimitry Andric return cast_or_null<ObjFile<ELFT>>(file); 142*0b57cec5SDimitry Andric } 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric ArrayRef<uint8_t> data() const { 145*0b57cec5SDimitry Andric if (uncompressedSize >= 0) 146*0b57cec5SDimitry Andric uncompress(); 147*0b57cec5SDimitry Andric return rawData; 148*0b57cec5SDimitry Andric } 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric uint64_t getOffsetInFile() const; 151*0b57cec5SDimitry Andric 152*0b57cec5SDimitry Andric // Input sections are part of an output section. Special sections 153*0b57cec5SDimitry Andric // like .eh_frame and merge sections are first combined into a 154*0b57cec5SDimitry Andric // synthetic section that is then added to an output section. In all 155*0b57cec5SDimitry Andric // cases this points one level up. 156*0b57cec5SDimitry Andric SectionBase *parent = nullptr; 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const { 159*0b57cec5SDimitry Andric assert(!areRelocsRela); 160*0b57cec5SDimitry Andric return llvm::makeArrayRef( 161*0b57cec5SDimitry Andric static_cast<const typename ELFT::Rel *>(firstRelocation), 162*0b57cec5SDimitry Andric numRelocations); 163*0b57cec5SDimitry Andric } 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const { 166*0b57cec5SDimitry Andric assert(areRelocsRela); 167*0b57cec5SDimitry Andric return llvm::makeArrayRef( 168*0b57cec5SDimitry Andric static_cast<const typename ELFT::Rela *>(firstRelocation), 169*0b57cec5SDimitry Andric numRelocations); 170*0b57cec5SDimitry Andric } 171*0b57cec5SDimitry Andric 172*0b57cec5SDimitry Andric // InputSections that are dependent on us (reverse dependency for GC) 173*0b57cec5SDimitry Andric llvm::TinyPtrVector<InputSection *> dependentSections; 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric // Returns the size of this section (even if this is a common or BSS.) 176*0b57cec5SDimitry Andric size_t getSize() const; 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric InputSection *getLinkOrderDep() const; 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric // Get the function symbol that encloses this offset from within the 181*0b57cec5SDimitry Andric // section. 182*0b57cec5SDimitry Andric template <class ELFT> 183*0b57cec5SDimitry Andric Defined *getEnclosingFunction(uint64_t offset); 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric // Returns a source location string. Used to construct an error message. 186*0b57cec5SDimitry Andric template <class ELFT> std::string getLocation(uint64_t offset); 187*0b57cec5SDimitry Andric std::string getSrcMsg(const Symbol &sym, uint64_t offset); 188*0b57cec5SDimitry Andric std::string getObjMsg(uint64_t offset); 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric // Each section knows how to relocate itself. These functions apply 191*0b57cec5SDimitry Andric // relocations, assuming that Buf points to this section's copy in 192*0b57cec5SDimitry Andric // the mmap'ed output buffer. 193*0b57cec5SDimitry Andric template <class ELFT> void relocate(uint8_t *buf, uint8_t *bufEnd); 194*0b57cec5SDimitry Andric void relocateAlloc(uint8_t *buf, uint8_t *bufEnd); 195*0b57cec5SDimitry Andric 196*0b57cec5SDimitry Andric // The native ELF reloc data type is not very convenient to handle. 197*0b57cec5SDimitry Andric // So we convert ELF reloc records to our own records in Relocations.cpp. 198*0b57cec5SDimitry Andric // This vector contains such "cooked" relocations. 199*0b57cec5SDimitry Andric std::vector<Relocation> relocations; 200*0b57cec5SDimitry Andric 201*0b57cec5SDimitry Andric // A function compiled with -fsplit-stack calling a function 202*0b57cec5SDimitry Andric // compiled without -fsplit-stack needs its prologue adjusted. Find 203*0b57cec5SDimitry Andric // such functions and adjust their prologues. This is very similar 204*0b57cec5SDimitry Andric // to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more 205*0b57cec5SDimitry Andric // information. 206*0b57cec5SDimitry Andric template <typename ELFT> 207*0b57cec5SDimitry Andric void adjustSplitStackFunctionPrologues(uint8_t *buf, uint8_t *end); 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric 210*0b57cec5SDimitry Andric template <typename T> llvm::ArrayRef<T> getDataAs() const { 211*0b57cec5SDimitry Andric size_t s = data().size(); 212*0b57cec5SDimitry Andric assert(s % sizeof(T) == 0); 213*0b57cec5SDimitry Andric return llvm::makeArrayRef<T>((const T *)data().data(), s / sizeof(T)); 214*0b57cec5SDimitry Andric } 215*0b57cec5SDimitry Andric 216*0b57cec5SDimitry Andric protected: 217*0b57cec5SDimitry Andric void parseCompressedHeader(); 218*0b57cec5SDimitry Andric void uncompress() const; 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric mutable ArrayRef<uint8_t> rawData; 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric // This field stores the uncompressed size of the compressed data in rawData, 223*0b57cec5SDimitry Andric // or -1 if rawData is not compressed (either because the section wasn't 224*0b57cec5SDimitry Andric // compressed in the first place, or because we ended up uncompressing it). 225*0b57cec5SDimitry Andric // Since the feature is not used often, this is usually -1. 226*0b57cec5SDimitry Andric mutable int64_t uncompressedSize = -1; 227*0b57cec5SDimitry Andric }; 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andric // SectionPiece represents a piece of splittable section contents. 230*0b57cec5SDimitry Andric // We allocate a lot of these and binary search on them. This means that they 231*0b57cec5SDimitry Andric // have to be as compact as possible, which is why we don't store the size (can 232*0b57cec5SDimitry Andric // be found by looking at the next one). 233*0b57cec5SDimitry Andric struct SectionPiece { 234*0b57cec5SDimitry Andric SectionPiece(size_t off, uint32_t hash, bool live) 235*0b57cec5SDimitry Andric : inputOff(off), live(live || !config->gcSections), hash(hash >> 1) {} 236*0b57cec5SDimitry Andric 237*0b57cec5SDimitry Andric uint32_t inputOff; 238*0b57cec5SDimitry Andric uint32_t live : 1; 239*0b57cec5SDimitry Andric uint32_t hash : 31; 240*0b57cec5SDimitry Andric uint64_t outputOff = 0; 241*0b57cec5SDimitry Andric }; 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big"); 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric // This corresponds to a SHF_MERGE section of an input file. 246*0b57cec5SDimitry Andric class MergeInputSection : public InputSectionBase { 247*0b57cec5SDimitry Andric public: 248*0b57cec5SDimitry Andric template <class ELFT> 249*0b57cec5SDimitry Andric MergeInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header, 250*0b57cec5SDimitry Andric StringRef name); 251*0b57cec5SDimitry Andric MergeInputSection(uint64_t flags, uint32_t type, uint64_t entsize, 252*0b57cec5SDimitry Andric ArrayRef<uint8_t> data, StringRef name); 253*0b57cec5SDimitry Andric 254*0b57cec5SDimitry Andric static bool classof(const SectionBase *s) { return s->kind() == Merge; } 255*0b57cec5SDimitry Andric void splitIntoPieces(); 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric // Translate an offset in the input section to an offset in the parent 258*0b57cec5SDimitry Andric // MergeSyntheticSection. 259*0b57cec5SDimitry Andric uint64_t getParentOffset(uint64_t offset) const; 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric // Splittable sections are handled as a sequence of data 262*0b57cec5SDimitry Andric // rather than a single large blob of data. 263*0b57cec5SDimitry Andric std::vector<SectionPiece> pieces; 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andric // Returns I'th piece's data. This function is very hot when 266*0b57cec5SDimitry Andric // string merging is enabled, so we want to inline. 267*0b57cec5SDimitry Andric LLVM_ATTRIBUTE_ALWAYS_INLINE 268*0b57cec5SDimitry Andric llvm::CachedHashStringRef getData(size_t i) const { 269*0b57cec5SDimitry Andric size_t begin = pieces[i].inputOff; 270*0b57cec5SDimitry Andric size_t end = 271*0b57cec5SDimitry Andric (pieces.size() - 1 == i) ? data().size() : pieces[i + 1].inputOff; 272*0b57cec5SDimitry Andric return {toStringRef(data().slice(begin, end - begin)), pieces[i].hash}; 273*0b57cec5SDimitry Andric } 274*0b57cec5SDimitry Andric 275*0b57cec5SDimitry Andric // Returns the SectionPiece at a given input section offset. 276*0b57cec5SDimitry Andric SectionPiece *getSectionPiece(uint64_t offset); 277*0b57cec5SDimitry Andric const SectionPiece *getSectionPiece(uint64_t offset) const { 278*0b57cec5SDimitry Andric return const_cast<MergeInputSection *>(this)->getSectionPiece(offset); 279*0b57cec5SDimitry Andric } 280*0b57cec5SDimitry Andric 281*0b57cec5SDimitry Andric SyntheticSection *getParent() const; 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric private: 284*0b57cec5SDimitry Andric void splitStrings(ArrayRef<uint8_t> a, size_t size); 285*0b57cec5SDimitry Andric void splitNonStrings(ArrayRef<uint8_t> a, size_t size); 286*0b57cec5SDimitry Andric }; 287*0b57cec5SDimitry Andric 288*0b57cec5SDimitry Andric struct EhSectionPiece { 289*0b57cec5SDimitry Andric EhSectionPiece(size_t off, InputSectionBase *sec, uint32_t size, 290*0b57cec5SDimitry Andric unsigned firstRelocation) 291*0b57cec5SDimitry Andric : inputOff(off), sec(sec), size(size), firstRelocation(firstRelocation) {} 292*0b57cec5SDimitry Andric 293*0b57cec5SDimitry Andric ArrayRef<uint8_t> data() { 294*0b57cec5SDimitry Andric return {sec->data().data() + this->inputOff, size}; 295*0b57cec5SDimitry Andric } 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric size_t inputOff; 298*0b57cec5SDimitry Andric ssize_t outputOff = -1; 299*0b57cec5SDimitry Andric InputSectionBase *sec; 300*0b57cec5SDimitry Andric uint32_t size; 301*0b57cec5SDimitry Andric unsigned firstRelocation; 302*0b57cec5SDimitry Andric }; 303*0b57cec5SDimitry Andric 304*0b57cec5SDimitry Andric // This corresponds to a .eh_frame section of an input file. 305*0b57cec5SDimitry Andric class EhInputSection : public InputSectionBase { 306*0b57cec5SDimitry Andric public: 307*0b57cec5SDimitry Andric template <class ELFT> 308*0b57cec5SDimitry Andric EhInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header, 309*0b57cec5SDimitry Andric StringRef name); 310*0b57cec5SDimitry Andric static bool classof(const SectionBase *s) { return s->kind() == EHFrame; } 311*0b57cec5SDimitry Andric template <class ELFT> void split(); 312*0b57cec5SDimitry Andric template <class ELFT, class RelTy> void split(ArrayRef<RelTy> rels); 313*0b57cec5SDimitry Andric 314*0b57cec5SDimitry Andric // Splittable sections are handled as a sequence of data 315*0b57cec5SDimitry Andric // rather than a single large blob of data. 316*0b57cec5SDimitry Andric std::vector<EhSectionPiece> pieces; 317*0b57cec5SDimitry Andric 318*0b57cec5SDimitry Andric SyntheticSection *getParent() const; 319*0b57cec5SDimitry Andric }; 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric // This is a section that is added directly to an output section 322*0b57cec5SDimitry Andric // instead of needing special combination via a synthetic section. This 323*0b57cec5SDimitry Andric // includes all input sections with the exceptions of SHF_MERGE and 324*0b57cec5SDimitry Andric // .eh_frame. It also includes the synthetic sections themselves. 325*0b57cec5SDimitry Andric class InputSection : public InputSectionBase { 326*0b57cec5SDimitry Andric public: 327*0b57cec5SDimitry Andric InputSection(InputFile *f, uint64_t flags, uint32_t type, uint32_t alignment, 328*0b57cec5SDimitry Andric ArrayRef<uint8_t> data, StringRef name, Kind k = Regular); 329*0b57cec5SDimitry Andric template <class ELFT> 330*0b57cec5SDimitry Andric InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header, 331*0b57cec5SDimitry Andric StringRef name); 332*0b57cec5SDimitry Andric 333*0b57cec5SDimitry Andric // Write this section to a mmap'ed file, assuming Buf is pointing to 334*0b57cec5SDimitry Andric // beginning of the output section. 335*0b57cec5SDimitry Andric template <class ELFT> void writeTo(uint8_t *buf); 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric uint64_t getOffset(uint64_t offset) const { return outSecOff + offset; } 338*0b57cec5SDimitry Andric 339*0b57cec5SDimitry Andric OutputSection *getParent() const; 340*0b57cec5SDimitry Andric 341*0b57cec5SDimitry Andric // This variable has two usages. Initially, it represents an index in the 342*0b57cec5SDimitry Andric // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER 343*0b57cec5SDimitry Andric // sections. After assignAddresses is called, it represents the offset from 344*0b57cec5SDimitry Andric // the beginning of the output section this section was assigned to. 345*0b57cec5SDimitry Andric uint64_t outSecOff = 0; 346*0b57cec5SDimitry Andric 347*0b57cec5SDimitry Andric static bool classof(const SectionBase *s); 348*0b57cec5SDimitry Andric 349*0b57cec5SDimitry Andric InputSectionBase *getRelocatedSection() const; 350*0b57cec5SDimitry Andric 351*0b57cec5SDimitry Andric template <class ELFT, class RelTy> 352*0b57cec5SDimitry Andric void relocateNonAlloc(uint8_t *buf, llvm::ArrayRef<RelTy> rels); 353*0b57cec5SDimitry Andric 354*0b57cec5SDimitry Andric // Used by ICF. 355*0b57cec5SDimitry Andric uint32_t eqClass[2] = {0, 0}; 356*0b57cec5SDimitry Andric 357*0b57cec5SDimitry Andric // Called by ICF to merge two input sections. 358*0b57cec5SDimitry Andric void replace(InputSection *other); 359*0b57cec5SDimitry Andric 360*0b57cec5SDimitry Andric static InputSection discarded; 361*0b57cec5SDimitry Andric 362*0b57cec5SDimitry Andric private: 363*0b57cec5SDimitry Andric template <class ELFT, class RelTy> 364*0b57cec5SDimitry Andric void copyRelocations(uint8_t *buf, llvm::ArrayRef<RelTy> rels); 365*0b57cec5SDimitry Andric 366*0b57cec5SDimitry Andric template <class ELFT> void copyShtGroup(uint8_t *buf); 367*0b57cec5SDimitry Andric }; 368*0b57cec5SDimitry Andric 369*0b57cec5SDimitry Andric // The list of all input sections. 370*0b57cec5SDimitry Andric extern std::vector<InputSectionBase *> inputSections; 371*0b57cec5SDimitry Andric 372*0b57cec5SDimitry Andric } // namespace elf 373*0b57cec5SDimitry Andric 374*0b57cec5SDimitry Andric std::string toString(const elf::InputSectionBase *); 375*0b57cec5SDimitry Andric } // namespace lld 376*0b57cec5SDimitry Andric 377*0b57cec5SDimitry Andric #endif 378