Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lld/ELF/OutputSections.h
34878 views
1
//===- OutputSections.h -----------------------------------------*- C++ -*-===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLD_ELF_OUTPUT_SECTIONS_H
10
#define LLD_ELF_OUTPUT_SECTIONS_H
11
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"
17
18
#include <array>
19
20
namespace lld::elf {
21
22
struct PhdrEntry;
23
24
struct CompressedData {
25
std::unique_ptr<SmallVector<uint8_t, 0>[]> shards;
26
uint32_t type = 0;
27
uint32_t numShards = 0;
28
uint32_t checksum = 0;
29
uint64_t uncompressedSize;
30
};
31
32
// This represents a section in an output file.
33
// It is composed of multiple InputSections.
34
// The writer creates multiple OutputSections and assign them unique,
35
// non-overlapping file offsets and VAs.
36
class OutputSection final : public SectionBase {
37
public:
38
OutputSection(StringRef name, uint32_t type, uint64_t flags);
39
40
static bool classof(const SectionBase *s) {
41
return s->kind() == SectionBase::Output;
42
}
43
44
uint64_t getLMA() const { return ptLoad ? addr + ptLoad->lmaOffset : addr; }
45
template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *sHdr);
46
47
uint32_t sectionIndex = UINT32_MAX;
48
unsigned sortRank;
49
50
uint32_t getPhdrFlags() const;
51
52
// Pointer to the PT_LOAD segment, which this section resides in. This field
53
// is used to correctly compute file offset of a section. When two sections
54
// share the same load segment, difference between their file offsets should
55
// be equal to difference between their virtual addresses. To compute some
56
// section offset we use the following formula: Off = Off_first + VA -
57
// VA_first, where Off_first and VA_first is file offset and VA of first
58
// section in PT_LOAD.
59
PhdrEntry *ptLoad = nullptr;
60
61
// Pointer to a relocation section for this section. Usually nullptr because
62
// we consume relocations, but if --emit-relocs is specified (which is rare),
63
// it may have a non-null value.
64
OutputSection *relocationSection = nullptr;
65
66
// Initially this field is the number of InputSections that have been added to
67
// the OutputSection so far. Later on, after a call to assignAddresses, it
68
// corresponds to the Elf_Shdr member.
69
uint64_t size = 0;
70
71
// The following fields correspond to Elf_Shdr members.
72
uint64_t offset = 0;
73
uint64_t addr = 0;
74
uint32_t shName = 0;
75
76
void recordSection(InputSectionBase *isec);
77
void commitSection(InputSection *isec);
78
void finalizeInputSections(LinkerScript *script = nullptr);
79
80
// The following members are normally only used in linker scripts.
81
MemoryRegion *memRegion = nullptr;
82
MemoryRegion *lmaRegion = nullptr;
83
Expr addrExpr;
84
Expr alignExpr;
85
Expr lmaExpr;
86
Expr subalignExpr;
87
88
// Used by non-alloc SHT_CREL to hold the header and content byte stream.
89
uint64_t crelHeader = 0;
90
SmallVector<char, 0> crelBody;
91
92
SmallVector<SectionCommand *, 0> commands;
93
SmallVector<StringRef, 0> phdrs;
94
std::optional<std::array<uint8_t, 4>> filler;
95
ConstraintKind constraint = ConstraintKind::NoConstraint;
96
std::string location;
97
std::string memoryRegionName;
98
std::string lmaRegionName;
99
bool nonAlloc = false;
100
bool typeIsSet = false;
101
bool expressionsUseSymbols = false;
102
bool usedInExpression = false;
103
bool inOverlay = false;
104
105
// Tracks whether the section has ever had an input section added to it, even
106
// if the section was later removed (e.g. because it is a synthetic section
107
// that wasn't needed). This is needed for orphan placement.
108
bool hasInputSections = false;
109
110
// The output section description is specified between DATA_SEGMENT_ALIGN and
111
// DATA_RELRO_END.
112
bool relro = false;
113
114
template <bool is64> void finalizeNonAllocCrel();
115
void finalize();
116
template <class ELFT>
117
void writeTo(uint8_t *buf, llvm::parallel::TaskGroup &tg);
118
// Check that the addends for dynamic relocations were written correctly.
119
void checkDynRelAddends(const uint8_t *bufStart);
120
template <class ELFT> void maybeCompress();
121
122
void sort(llvm::function_ref<int(InputSectionBase *s)> order);
123
void sortInitFini();
124
void sortCtorsDtors();
125
126
// Used for implementation of --compress-debug-sections and
127
// --compress-sections.
128
CompressedData compressed;
129
130
private:
131
SmallVector<InputSection *, 0> storage;
132
133
std::array<uint8_t, 4> getFiller();
134
};
135
136
struct OutputDesc final : SectionCommand {
137
OutputSection osec;
138
OutputDesc(StringRef name, uint32_t type, uint64_t flags)
139
: SectionCommand(OutputSectionKind), osec(name, type, flags) {}
140
141
static bool classof(const SectionCommand *c) {
142
return c->kind == OutputSectionKind;
143
}
144
};
145
146
int getPriority(StringRef s);
147
148
InputSection *getFirstInputSection(const OutputSection *os);
149
llvm::ArrayRef<InputSection *>
150
getInputSections(const OutputSection &os,
151
SmallVector<InputSection *, 0> &storage);
152
153
// All output sections that are handled by the linker specially are
154
// globally accessible. Writer initializes them, so don't use them
155
// until Writer is initialized.
156
struct Out {
157
static uint8_t *bufferStart;
158
static PhdrEntry *tlsPhdr;
159
static OutputSection *elfHeader;
160
static OutputSection *programHeaders;
161
static OutputSection *preinitArray;
162
static OutputSection *initArray;
163
static OutputSection *finiArray;
164
};
165
166
uint64_t getHeaderSize();
167
168
LLVM_LIBRARY_VISIBILITY extern llvm::SmallVector<OutputSection *, 0>
169
outputSections;
170
} // namespace lld::elf
171
172
#endif
173
174