xref: /freebsd/contrib/llvm-project/lld/ELF/InputSection.h (revision d65cd7a57bf0600b722afc770838a5d0c1c3a8e1)
10b57cec5SDimitry Andric //===- InputSection.h -------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLD_ELF_INPUT_SECTION_H
100b57cec5SDimitry Andric #define LLD_ELF_INPUT_SECTION_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "Config.h"
130b57cec5SDimitry Andric #include "Relocations.h"
140b57cec5SDimitry Andric #include "Thunks.h"
150b57cec5SDimitry Andric #include "lld/Common/LLVM.h"
160b57cec5SDimitry Andric #include "llvm/ADT/CachedHashString.h"
170b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h"
180b57cec5SDimitry Andric #include "llvm/ADT/TinyPtrVector.h"
190b57cec5SDimitry Andric #include "llvm/Object/ELF.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace lld {
220b57cec5SDimitry Andric namespace elf {
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric class Symbol;
250b57cec5SDimitry Andric struct SectionPiece;
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric class Defined;
280b57cec5SDimitry Andric struct Partition;
290b57cec5SDimitry Andric class SyntheticSection;
300b57cec5SDimitry Andric class MergeSyntheticSection;
310b57cec5SDimitry Andric template <class ELFT> class ObjFile;
320b57cec5SDimitry Andric class OutputSection;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric extern std::vector<Partition> partitions;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric // This is the base class of all sections that lld handles. Some are sections in
370b57cec5SDimitry Andric // input files, some are sections in the produced output file and some exist
380b57cec5SDimitry Andric // just as a convenience for implementing special ways of combining some
390b57cec5SDimitry Andric // sections.
400b57cec5SDimitry Andric class SectionBase {
410b57cec5SDimitry Andric public:
420b57cec5SDimitry Andric   enum Kind { Regular, EHFrame, Merge, Synthetic, Output };
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   Kind kind() const { return (Kind)sectionKind; }
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   StringRef name;
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   // This pointer points to the "real" instance of this instance.
490b57cec5SDimitry Andric   // Usually Repl == this. However, if ICF merges two sections,
500b57cec5SDimitry Andric   // Repl pointer of one section points to another section. So,
510b57cec5SDimitry Andric   // if you need to get a pointer to this instance, do not use
520b57cec5SDimitry Andric   // this but instead this->Repl.
530b57cec5SDimitry Andric   SectionBase *repl;
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   unsigned sectionKind : 3;
560b57cec5SDimitry Andric 
5785868e8aSDimitry Andric   // The next two bit fields are only used by InputSectionBase, but we
580b57cec5SDimitry Andric   // put them here so the struct packs better.
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   unsigned bss : 1;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   // Set for sections that should not be folded by ICF.
630b57cec5SDimitry Andric   unsigned keepUnique : 1;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   // The 1-indexed partition that this section is assigned to by the garbage
660b57cec5SDimitry Andric   // collector, or 0 if this section is dead. Normally there is only one
670b57cec5SDimitry Andric   // partition, so this will either be 0 or 1.
680b57cec5SDimitry Andric   uint8_t partition;
690b57cec5SDimitry Andric   elf::Partition &getPartition() const;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   // These corresponds to the fields in Elf_Shdr.
720b57cec5SDimitry Andric   uint32_t alignment;
730b57cec5SDimitry Andric   uint64_t flags;
740b57cec5SDimitry Andric   uint64_t entsize;
750b57cec5SDimitry Andric   uint32_t type;
760b57cec5SDimitry Andric   uint32_t link;
770b57cec5SDimitry Andric   uint32_t info;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   OutputSection *getOutputSection();
800b57cec5SDimitry Andric   const OutputSection *getOutputSection() const {
810b57cec5SDimitry Andric     return const_cast<SectionBase *>(this)->getOutputSection();
820b57cec5SDimitry Andric   }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric   // Translate an offset in the input section to an offset in the output
850b57cec5SDimitry Andric   // section.
860b57cec5SDimitry Andric   uint64_t getOffset(uint64_t offset) const;
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   uint64_t getVA(uint64_t offset = 0) const;
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   bool isLive() const { return partition != 0; }
910b57cec5SDimitry Andric   void markLive() { partition = 1; }
920b57cec5SDimitry Andric   void markDead() { partition = 0; }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric protected:
950b57cec5SDimitry Andric   SectionBase(Kind sectionKind, StringRef name, uint64_t flags,
960b57cec5SDimitry Andric               uint64_t entsize, uint64_t alignment, uint32_t type,
970b57cec5SDimitry Andric               uint32_t info, uint32_t link)
9885868e8aSDimitry Andric       : name(name), repl(this), sectionKind(sectionKind), bss(false),
9985868e8aSDimitry Andric         keepUnique(false), partition(0), alignment(alignment), flags(flags),
10085868e8aSDimitry Andric         entsize(entsize), type(type), link(link), info(info) {}
1010b57cec5SDimitry Andric };
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric // This corresponds to a section of an input file.
1040b57cec5SDimitry Andric class InputSectionBase : public SectionBase {
1050b57cec5SDimitry Andric public:
1060b57cec5SDimitry Andric   template <class ELFT>
1070b57cec5SDimitry Andric   InputSectionBase(ObjFile<ELFT> &file, const typename ELFT::Shdr &header,
1080b57cec5SDimitry Andric                    StringRef name, Kind sectionKind);
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   InputSectionBase(InputFile *file, uint64_t flags, uint32_t type,
1110b57cec5SDimitry Andric                    uint64_t entsize, uint32_t link, uint32_t info,
1120b57cec5SDimitry Andric                    uint32_t alignment, ArrayRef<uint8_t> data, StringRef name,
1130b57cec5SDimitry Andric                    Kind sectionKind);
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   static bool classof(const SectionBase *s) { return s->kind() != Output; }
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   // Relocations that refer to this section.
1180b57cec5SDimitry Andric   unsigned numRelocations : 31;
1190b57cec5SDimitry Andric   unsigned areRelocsRela : 1;
1200b57cec5SDimitry Andric   const void *firstRelocation = nullptr;
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   // The file which contains this section. Its dynamic type is always
1230b57cec5SDimitry Andric   // ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as
1240b57cec5SDimitry Andric   // its static type.
1250b57cec5SDimitry Andric   InputFile *file;
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   template <class ELFT> ObjFile<ELFT> *getFile() const {
1280b57cec5SDimitry Andric     return cast_or_null<ObjFile<ELFT>>(file);
1290b57cec5SDimitry Andric   }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   ArrayRef<uint8_t> data() const {
1320b57cec5SDimitry Andric     if (uncompressedSize >= 0)
1330b57cec5SDimitry Andric       uncompress();
1340b57cec5SDimitry Andric     return rawData;
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   uint64_t getOffsetInFile() const;
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric   // Input sections are part of an output section. Special sections
1400b57cec5SDimitry Andric   // like .eh_frame and merge sections are first combined into a
1410b57cec5SDimitry Andric   // synthetic section that is then added to an output section. In all
1420b57cec5SDimitry Andric   // cases this points one level up.
1430b57cec5SDimitry Andric   SectionBase *parent = nullptr;
1440b57cec5SDimitry Andric 
145480093f4SDimitry Andric   // The next member in the section group if this section is in a group. This is
146480093f4SDimitry Andric   // used by --gc-sections.
147480093f4SDimitry Andric   InputSectionBase *nextInSectionGroup = nullptr;
148480093f4SDimitry Andric 
1490b57cec5SDimitry Andric   template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
1500b57cec5SDimitry Andric     assert(!areRelocsRela);
1510b57cec5SDimitry Andric     return llvm::makeArrayRef(
1520b57cec5SDimitry Andric         static_cast<const typename ELFT::Rel *>(firstRelocation),
1530b57cec5SDimitry Andric         numRelocations);
1540b57cec5SDimitry Andric   }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
1570b57cec5SDimitry Andric     assert(areRelocsRela);
1580b57cec5SDimitry Andric     return llvm::makeArrayRef(
1590b57cec5SDimitry Andric         static_cast<const typename ELFT::Rela *>(firstRelocation),
1600b57cec5SDimitry Andric         numRelocations);
1610b57cec5SDimitry Andric   }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   // InputSections that are dependent on us (reverse dependency for GC)
1640b57cec5SDimitry Andric   llvm::TinyPtrVector<InputSection *> dependentSections;
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   // Returns the size of this section (even if this is a common or BSS.)
1670b57cec5SDimitry Andric   size_t getSize() const;
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   InputSection *getLinkOrderDep() const;
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric   // Get the function symbol that encloses this offset from within the
1720b57cec5SDimitry Andric   // section.
1730b57cec5SDimitry Andric   template <class ELFT>
1740b57cec5SDimitry Andric   Defined *getEnclosingFunction(uint64_t offset);
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   // Returns a source location string. Used to construct an error message.
1770b57cec5SDimitry Andric   template <class ELFT> std::string getLocation(uint64_t offset);
1780b57cec5SDimitry Andric   std::string getSrcMsg(const Symbol &sym, uint64_t offset);
1790b57cec5SDimitry Andric   std::string getObjMsg(uint64_t offset);
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   // Each section knows how to relocate itself. These functions apply
1820b57cec5SDimitry Andric   // relocations, assuming that Buf points to this section's copy in
1830b57cec5SDimitry Andric   // the mmap'ed output buffer.
1840b57cec5SDimitry Andric   template <class ELFT> void relocate(uint8_t *buf, uint8_t *bufEnd);
1850b57cec5SDimitry Andric   void relocateAlloc(uint8_t *buf, uint8_t *bufEnd);
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric   // The native ELF reloc data type is not very convenient to handle.
1880b57cec5SDimitry Andric   // So we convert ELF reloc records to our own records in Relocations.cpp.
1890b57cec5SDimitry Andric   // This vector contains such "cooked" relocations.
1900b57cec5SDimitry Andric   std::vector<Relocation> relocations;
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric   // A function compiled with -fsplit-stack calling a function
1930b57cec5SDimitry Andric   // compiled without -fsplit-stack needs its prologue adjusted. Find
1940b57cec5SDimitry Andric   // such functions and adjust their prologues.  This is very similar
1950b57cec5SDimitry Andric   // to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more
1960b57cec5SDimitry Andric   // information.
1970b57cec5SDimitry Andric   template <typename ELFT>
1980b57cec5SDimitry Andric   void adjustSplitStackFunctionPrologues(uint8_t *buf, uint8_t *end);
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   template <typename T> llvm::ArrayRef<T> getDataAs() const {
2020b57cec5SDimitry Andric     size_t s = data().size();
2030b57cec5SDimitry Andric     assert(s % sizeof(T) == 0);
2040b57cec5SDimitry Andric     return llvm::makeArrayRef<T>((const T *)data().data(), s / sizeof(T));
2050b57cec5SDimitry Andric   }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric protected:
2080b57cec5SDimitry Andric   void parseCompressedHeader();
2090b57cec5SDimitry Andric   void uncompress() const;
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   mutable ArrayRef<uint8_t> rawData;
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   // This field stores the uncompressed size of the compressed data in rawData,
2140b57cec5SDimitry Andric   // or -1 if rawData is not compressed (either because the section wasn't
2150b57cec5SDimitry Andric   // compressed in the first place, or because we ended up uncompressing it).
2160b57cec5SDimitry Andric   // Since the feature is not used often, this is usually -1.
2170b57cec5SDimitry Andric   mutable int64_t uncompressedSize = -1;
2180b57cec5SDimitry Andric };
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric // SectionPiece represents a piece of splittable section contents.
2210b57cec5SDimitry Andric // We allocate a lot of these and binary search on them. This means that they
2220b57cec5SDimitry Andric // have to be as compact as possible, which is why we don't store the size (can
2230b57cec5SDimitry Andric // be found by looking at the next one).
2240b57cec5SDimitry Andric struct SectionPiece {
2250b57cec5SDimitry Andric   SectionPiece(size_t off, uint32_t hash, bool live)
2260b57cec5SDimitry Andric       : inputOff(off), live(live || !config->gcSections), hash(hash >> 1) {}
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   uint32_t inputOff;
2290b57cec5SDimitry Andric   uint32_t live : 1;
2300b57cec5SDimitry Andric   uint32_t hash : 31;
2310b57cec5SDimitry Andric   uint64_t outputOff = 0;
2320b57cec5SDimitry Andric };
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric // This corresponds to a SHF_MERGE section of an input file.
2370b57cec5SDimitry Andric class MergeInputSection : public InputSectionBase {
2380b57cec5SDimitry Andric public:
2390b57cec5SDimitry Andric   template <class ELFT>
2400b57cec5SDimitry Andric   MergeInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
2410b57cec5SDimitry Andric                     StringRef name);
2420b57cec5SDimitry Andric   MergeInputSection(uint64_t flags, uint32_t type, uint64_t entsize,
2430b57cec5SDimitry Andric                     ArrayRef<uint8_t> data, StringRef name);
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   static bool classof(const SectionBase *s) { return s->kind() == Merge; }
2460b57cec5SDimitry Andric   void splitIntoPieces();
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   // Translate an offset in the input section to an offset in the parent
2490b57cec5SDimitry Andric   // MergeSyntheticSection.
2500b57cec5SDimitry Andric   uint64_t getParentOffset(uint64_t offset) const;
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   // Splittable sections are handled as a sequence of data
2530b57cec5SDimitry Andric   // rather than a single large blob of data.
2540b57cec5SDimitry Andric   std::vector<SectionPiece> pieces;
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric   // Returns I'th piece's data. This function is very hot when
2570b57cec5SDimitry Andric   // string merging is enabled, so we want to inline.
2580b57cec5SDimitry Andric   LLVM_ATTRIBUTE_ALWAYS_INLINE
2590b57cec5SDimitry Andric   llvm::CachedHashStringRef getData(size_t i) const {
2600b57cec5SDimitry Andric     size_t begin = pieces[i].inputOff;
2610b57cec5SDimitry Andric     size_t end =
2620b57cec5SDimitry Andric         (pieces.size() - 1 == i) ? data().size() : pieces[i + 1].inputOff;
2630b57cec5SDimitry Andric     return {toStringRef(data().slice(begin, end - begin)), pieces[i].hash};
2640b57cec5SDimitry Andric   }
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric   // Returns the SectionPiece at a given input section offset.
2670b57cec5SDimitry Andric   SectionPiece *getSectionPiece(uint64_t offset);
2680b57cec5SDimitry Andric   const SectionPiece *getSectionPiece(uint64_t offset) const {
2690b57cec5SDimitry Andric     return const_cast<MergeInputSection *>(this)->getSectionPiece(offset);
2700b57cec5SDimitry Andric   }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric   SyntheticSection *getParent() const;
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric private:
2750b57cec5SDimitry Andric   void splitStrings(ArrayRef<uint8_t> a, size_t size);
2760b57cec5SDimitry Andric   void splitNonStrings(ArrayRef<uint8_t> a, size_t size);
2770b57cec5SDimitry Andric };
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric struct EhSectionPiece {
2800b57cec5SDimitry Andric   EhSectionPiece(size_t off, InputSectionBase *sec, uint32_t size,
2810b57cec5SDimitry Andric                  unsigned firstRelocation)
2820b57cec5SDimitry Andric       : inputOff(off), sec(sec), size(size), firstRelocation(firstRelocation) {}
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric   ArrayRef<uint8_t> data() {
2850b57cec5SDimitry Andric     return {sec->data().data() + this->inputOff, size};
2860b57cec5SDimitry Andric   }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric   size_t inputOff;
2890b57cec5SDimitry Andric   ssize_t outputOff = -1;
2900b57cec5SDimitry Andric   InputSectionBase *sec;
2910b57cec5SDimitry Andric   uint32_t size;
2920b57cec5SDimitry Andric   unsigned firstRelocation;
2930b57cec5SDimitry Andric };
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric // This corresponds to a .eh_frame section of an input file.
2960b57cec5SDimitry Andric class EhInputSection : public InputSectionBase {
2970b57cec5SDimitry Andric public:
2980b57cec5SDimitry Andric   template <class ELFT>
2990b57cec5SDimitry Andric   EhInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
3000b57cec5SDimitry Andric                  StringRef name);
3010b57cec5SDimitry Andric   static bool classof(const SectionBase *s) { return s->kind() == EHFrame; }
3020b57cec5SDimitry Andric   template <class ELFT> void split();
3030b57cec5SDimitry Andric   template <class ELFT, class RelTy> void split(ArrayRef<RelTy> rels);
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric   // Splittable sections are handled as a sequence of data
3060b57cec5SDimitry Andric   // rather than a single large blob of data.
3070b57cec5SDimitry Andric   std::vector<EhSectionPiece> pieces;
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   SyntheticSection *getParent() const;
3100b57cec5SDimitry Andric };
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric // This is a section that is added directly to an output section
3130b57cec5SDimitry Andric // instead of needing special combination via a synthetic section. This
3140b57cec5SDimitry Andric // includes all input sections with the exceptions of SHF_MERGE and
3150b57cec5SDimitry Andric // .eh_frame. It also includes the synthetic sections themselves.
3160b57cec5SDimitry Andric class InputSection : public InputSectionBase {
3170b57cec5SDimitry Andric public:
3180b57cec5SDimitry Andric   InputSection(InputFile *f, uint64_t flags, uint32_t type, uint32_t alignment,
3190b57cec5SDimitry Andric                ArrayRef<uint8_t> data, StringRef name, Kind k = Regular);
3200b57cec5SDimitry Andric   template <class ELFT>
3210b57cec5SDimitry Andric   InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
3220b57cec5SDimitry Andric                StringRef name);
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric   // Write this section to a mmap'ed file, assuming Buf is pointing to
3250b57cec5SDimitry Andric   // beginning of the output section.
3260b57cec5SDimitry Andric   template <class ELFT> void writeTo(uint8_t *buf);
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   uint64_t getOffset(uint64_t offset) const { return outSecOff + offset; }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   OutputSection *getParent() const;
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric   // This variable has two usages. Initially, it represents an index in the
3330b57cec5SDimitry Andric   // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER
3340b57cec5SDimitry Andric   // sections. After assignAddresses is called, it represents the offset from
3350b57cec5SDimitry Andric   // the beginning of the output section this section was assigned to.
3360b57cec5SDimitry Andric   uint64_t outSecOff = 0;
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   static bool classof(const SectionBase *s);
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric   InputSectionBase *getRelocatedSection() const;
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   template <class ELFT, class RelTy>
3430b57cec5SDimitry Andric   void relocateNonAlloc(uint8_t *buf, llvm::ArrayRef<RelTy> rels);
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric   // Used by ICF.
3460b57cec5SDimitry Andric   uint32_t eqClass[2] = {0, 0};
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   // Called by ICF to merge two input sections.
3490b57cec5SDimitry Andric   void replace(InputSection *other);
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric   static InputSection discarded;
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric private:
3540b57cec5SDimitry Andric   template <class ELFT, class RelTy>
3550b57cec5SDimitry Andric   void copyRelocations(uint8_t *buf, llvm::ArrayRef<RelTy> rels);
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric   template <class ELFT> void copyShtGroup(uint8_t *buf);
3580b57cec5SDimitry Andric };
3590b57cec5SDimitry Andric 
360*d65cd7a5SDimitry Andric inline bool isDebugSection(const InputSectionBase &sec) {
361*d65cd7a5SDimitry Andric   return sec.name.startswith(".debug") || sec.name.startswith(".zdebug");
362*d65cd7a5SDimitry Andric }
363*d65cd7a5SDimitry Andric 
3640b57cec5SDimitry Andric // The list of all input sections.
3650b57cec5SDimitry Andric extern std::vector<InputSectionBase *> inputSections;
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric } // namespace elf
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric std::string toString(const elf::InputSectionBase *);
3700b57cec5SDimitry Andric } // namespace lld
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric #endif
373