1 //===- OutputSections.h -----------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLD_ELF_OUTPUT_SECTIONS_H
10 #define LLD_ELF_OUTPUT_SECTIONS_H
12 #include "InputSection.h"
13 #include "LinkerScript.h"
14 #include "lld/Common/LLVM.h"
15 #include "llvm/Support/Compiler.h"
16 #include "llvm/Support/Parallel.h"
24 struct CompressedData
{
25 std::unique_ptr
<SmallVector
<uint8_t, 0>[]> shards
;
26 uint32_t numShards
= 0;
27 uint32_t checksum
= 0;
28 uint64_t uncompressedSize
;
31 // This represents a section in an output file.
32 // It is composed of multiple InputSections.
33 // The writer creates multiple OutputSections and assign them unique,
34 // non-overlapping file offsets and VAs.
35 class OutputSection final
: public SectionBase
{
37 OutputSection(StringRef name
, uint32_t type
, uint64_t flags
);
39 static bool classof(const SectionBase
*s
) {
40 return s
->kind() == SectionBase::Output
;
43 uint64_t getLMA() const { return ptLoad
? addr
+ ptLoad
->lmaOffset
: addr
; }
44 template <typename ELFT
> void writeHeaderTo(typename
ELFT::Shdr
*sHdr
);
46 uint32_t sectionIndex
= UINT32_MAX
;
49 uint32_t getPhdrFlags() const;
51 // Pointer to the PT_LOAD segment, which this section resides in. This field
52 // is used to correctly compute file offset of a section. When two sections
53 // share the same load segment, difference between their file offsets should
54 // be equal to difference between their virtual addresses. To compute some
55 // section offset we use the following formula: Off = Off_first + VA -
56 // VA_first, where Off_first and VA_first is file offset and VA of first
57 // section in PT_LOAD.
58 PhdrEntry
*ptLoad
= nullptr;
60 // Pointer to a relocation section for this section. Usually nullptr because
61 // we consume relocations, but if --emit-relocs is specified (which is rare),
62 // it may have a non-null value.
63 OutputSection
*relocationSection
= nullptr;
65 // Initially this field is the number of InputSections that have been added to
66 // the OutputSection so far. Later on, after a call to assignAddresses, it
67 // corresponds to the Elf_Shdr member.
70 // The following fields correspond to Elf_Shdr members.
75 void recordSection(InputSectionBase
*isec
);
76 void commitSection(InputSection
*isec
);
77 void finalizeInputSections();
79 // The following members are normally only used in linker scripts.
80 MemoryRegion
*memRegion
= nullptr;
81 MemoryRegion
*lmaRegion
= nullptr;
86 SmallVector
<SectionCommand
*, 0> commands
;
87 SmallVector
<StringRef
, 0> phdrs
;
88 std::optional
<std::array
<uint8_t, 4>> filler
;
89 ConstraintKind constraint
= ConstraintKind::NoConstraint
;
91 std::string memoryRegionName
;
92 std::string lmaRegionName
;
93 bool nonAlloc
= false;
94 bool typeIsSet
= false;
95 bool expressionsUseSymbols
= false;
96 bool usedInExpression
= false;
97 bool inOverlay
= false;
99 // Tracks whether the section has ever had an input section added to it, even
100 // if the section was later removed (e.g. because it is a synthetic section
101 // that wasn't needed). This is needed for orphan placement.
102 bool hasInputSections
= false;
104 // The output section description is specified between DATA_SEGMENT_ALIGN and
109 template <class ELFT
>
110 void writeTo(uint8_t *buf
, llvm::parallel::TaskGroup
&tg
);
111 // Check that the addends for dynamic relocations were written correctly.
112 void checkDynRelAddends(const uint8_t *bufStart
);
113 template <class ELFT
> void maybeCompress();
115 void sort(llvm::function_ref
<int(InputSectionBase
*s
)> order
);
117 void sortCtorsDtors();
120 SmallVector
<InputSection
*, 0> storage
;
122 // Used for implementation of --compress-debug-sections option.
123 CompressedData compressed
;
125 std::array
<uint8_t, 4> getFiller();
128 struct OutputDesc final
: SectionCommand
{
130 OutputDesc(StringRef name
, uint32_t type
, uint64_t flags
)
131 : SectionCommand(OutputSectionKind
), osec(name
, type
, flags
) {}
133 static bool classof(const SectionCommand
*c
) {
134 return c
->kind
== OutputSectionKind
;
138 int getPriority(StringRef s
);
140 InputSection
*getFirstInputSection(const OutputSection
*os
);
141 llvm::ArrayRef
<InputSection
*>
142 getInputSections(const OutputSection
&os
,
143 SmallVector
<InputSection
*, 0> &storage
);
145 // All output sections that are handled by the linker specially are
146 // globally accessible. Writer initializes them, so don't use them
147 // until Writer is initialized.
149 static uint8_t *bufferStart
;
150 static PhdrEntry
*tlsPhdr
;
151 static OutputSection
*elfHeader
;
152 static OutputSection
*programHeaders
;
153 static OutputSection
*preinitArray
;
154 static OutputSection
*initArray
;
155 static OutputSection
*finiArray
;
158 uint64_t getHeaderSize();
160 LLVM_LIBRARY_VISIBILITY
extern llvm::SmallVector
<OutputSection
*, 0>
162 } // namespace lld::elf