xref: /freebsd/contrib/llvm-project/lld/ELF/OutputSections.h (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
10b57cec5SDimitry Andric //===- OutputSections.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_OUTPUT_SECTIONS_H
100b57cec5SDimitry Andric #define LLD_ELF_OUTPUT_SECTIONS_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "Config.h"
130b57cec5SDimitry Andric #include "InputSection.h"
140b57cec5SDimitry Andric #include "LinkerScript.h"
150b57cec5SDimitry Andric #include "Relocations.h"
160b57cec5SDimitry Andric #include "lld/Common/LLVM.h"
170b57cec5SDimitry Andric #include "llvm/MC/StringTableBuilder.h"
180b57cec5SDimitry Andric #include "llvm/Object/ELF.h"
190b57cec5SDimitry Andric #include <array>
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace lld {
220b57cec5SDimitry Andric namespace elf {
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric struct PhdrEntry;
250b57cec5SDimitry Andric class InputSection;
260b57cec5SDimitry Andric class InputSectionBase;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric // This represents a section in an output file.
290b57cec5SDimitry Andric // It is composed of multiple InputSections.
300b57cec5SDimitry Andric // The writer creates multiple OutputSections and assign them unique,
310b57cec5SDimitry Andric // non-overlapping file offsets and VAs.
320b57cec5SDimitry Andric class OutputSection final : public BaseCommand, public SectionBase {
330b57cec5SDimitry Andric public:
340b57cec5SDimitry Andric   OutputSection(StringRef name, uint32_t type, uint64_t flags);
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric   static bool classof(const SectionBase *s) {
370b57cec5SDimitry Andric     return s->kind() == SectionBase::Output;
380b57cec5SDimitry Andric   }
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   static bool classof(const BaseCommand *c);
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   uint64_t getLMA() const { return ptLoad ? addr + ptLoad->lmaOffset : addr; }
430b57cec5SDimitry Andric   template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *sHdr);
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   uint32_t sectionIndex = UINT32_MAX;
460b57cec5SDimitry Andric   unsigned sortRank;
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   uint32_t getPhdrFlags() const;
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   // Pointer to the PT_LOAD segment, which this section resides in. This field
510b57cec5SDimitry Andric   // is used to correctly compute file offset of a section. When two sections
520b57cec5SDimitry Andric   // share the same load segment, difference between their file offsets should
530b57cec5SDimitry Andric   // be equal to difference between their virtual addresses. To compute some
540b57cec5SDimitry Andric   // section offset we use the following formula: Off = Off_first + VA -
550b57cec5SDimitry Andric   // VA_first, where Off_first and VA_first is file offset and VA of first
560b57cec5SDimitry Andric   // section in PT_LOAD.
570b57cec5SDimitry Andric   PhdrEntry *ptLoad = nullptr;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   // Pointer to a relocation section for this section. Usually nullptr because
600b57cec5SDimitry Andric   // we consume relocations, but if --emit-relocs is specified (which is rare),
610b57cec5SDimitry Andric   // it may have a non-null value.
620b57cec5SDimitry Andric   OutputSection *relocationSection = nullptr;
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   // Initially this field is the number of InputSections that have been added to
650b57cec5SDimitry Andric   // the OutputSection so far. Later on, after a call to assignAddresses, it
660b57cec5SDimitry Andric   // corresponds to the Elf_Shdr member.
670b57cec5SDimitry Andric   uint64_t size = 0;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   // The following fields correspond to Elf_Shdr members.
700b57cec5SDimitry Andric   uint64_t offset = 0;
710b57cec5SDimitry Andric   uint64_t addr = 0;
720b57cec5SDimitry Andric   uint32_t shName = 0;
730b57cec5SDimitry Andric 
7485868e8aSDimitry Andric   void recordSection(InputSectionBase *isec);
7585868e8aSDimitry Andric   void commitSection(InputSection *isec);
7685868e8aSDimitry Andric   void finalizeInputSections();
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   // The following members are normally only used in linker scripts.
790b57cec5SDimitry Andric   MemoryRegion *memRegion = nullptr;
800b57cec5SDimitry Andric   MemoryRegion *lmaRegion = nullptr;
810b57cec5SDimitry Andric   Expr addrExpr;
820b57cec5SDimitry Andric   Expr alignExpr;
830b57cec5SDimitry Andric   Expr lmaExpr;
840b57cec5SDimitry Andric   Expr subalignExpr;
850b57cec5SDimitry Andric   std::vector<BaseCommand *> sectionCommands;
860b57cec5SDimitry Andric   std::vector<StringRef> phdrs;
870b57cec5SDimitry Andric   llvm::Optional<std::array<uint8_t, 4>> filler;
880b57cec5SDimitry Andric   ConstraintKind constraint = ConstraintKind::NoConstraint;
890b57cec5SDimitry Andric   std::string location;
900b57cec5SDimitry Andric   std::string memoryRegionName;
910b57cec5SDimitry Andric   std::string lmaRegionName;
920b57cec5SDimitry Andric   bool nonAlloc = false;
930b57cec5SDimitry Andric   bool noload = false;
940b57cec5SDimitry Andric   bool expressionsUseSymbols = false;
950b57cec5SDimitry Andric   bool usedInExpression = false;
960b57cec5SDimitry Andric   bool inOverlay = false;
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   // Tracks whether the section has ever had an input section added to it, even
990b57cec5SDimitry Andric   // if the section was later removed (e.g. because it is a synthetic section
1000b57cec5SDimitry Andric   // that wasn't needed). This is needed for orphan placement.
1010b57cec5SDimitry Andric   bool hasInputSections = false;
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   void finalize();
1040b57cec5SDimitry Andric   template <class ELFT> void writeTo(uint8_t *buf);
1050b57cec5SDimitry Andric   template <class ELFT> void maybeCompress();
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   void sort(llvm::function_ref<int(InputSectionBase *s)> order);
1080b57cec5SDimitry Andric   void sortInitFini();
1090b57cec5SDimitry Andric   void sortCtorsDtors();
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric private:
1120b57cec5SDimitry Andric   // Used for implementation of --compress-debug-sections option.
1130b57cec5SDimitry Andric   std::vector<uint8_t> zDebugHeader;
1140b57cec5SDimitry Andric   llvm::SmallVector<char, 1> compressedData;
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   std::array<uint8_t, 4> getFiller();
1170b57cec5SDimitry Andric };
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric int getPriority(StringRef s);
1200b57cec5SDimitry Andric 
121*5ffd83dbSDimitry Andric InputSection *getFirstInputSection(const OutputSection *os);
122*5ffd83dbSDimitry Andric std::vector<InputSection *> getInputSections(const OutputSection *os);
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric // All output sections that are handled by the linker specially are
1250b57cec5SDimitry Andric // globally accessible. Writer initializes them, so don't use them
1260b57cec5SDimitry Andric // until Writer is initialized.
1270b57cec5SDimitry Andric struct Out {
1280b57cec5SDimitry Andric   static uint8_t *bufferStart;
1290b57cec5SDimitry Andric   static uint8_t first;
1300b57cec5SDimitry Andric   static PhdrEntry *tlsPhdr;
1310b57cec5SDimitry Andric   static OutputSection *elfHeader;
1320b57cec5SDimitry Andric   static OutputSection *programHeaders;
1330b57cec5SDimitry Andric   static OutputSection *preinitArray;
1340b57cec5SDimitry Andric   static OutputSection *initArray;
1350b57cec5SDimitry Andric   static OutputSection *finiArray;
1360b57cec5SDimitry Andric };
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric } // namespace elf
1390b57cec5SDimitry Andric } // namespace lld
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric namespace lld {
1420b57cec5SDimitry Andric namespace elf {
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric uint64_t getHeaderSize();
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric extern std::vector<OutputSection *> outputSections;
1470b57cec5SDimitry Andric } // namespace elf
1480b57cec5SDimitry Andric } // namespace lld
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric #endif
151