xref: /freebsd/contrib/llvm-project/lld/ELF/InputSection.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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