xref: /src/contrib/llvm-project/lld/ELF/LinkerScript.cpp (revision 52418fc2be8efa5172b90a3a9e617017173612c4)
15a5c549fSDimitry Andric //===- LinkerScript.cpp ---------------------------------------------------===//
25a5c549fSDimitry Andric //
3f1e1c239SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f1e1c239SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5f1e1c239SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a5c549fSDimitry Andric //
75a5c549fSDimitry Andric //===----------------------------------------------------------------------===//
85a5c549fSDimitry Andric //
95a5c549fSDimitry Andric // This file contains the parser/evaluator of the linker script.
105a5c549fSDimitry Andric //
115a5c549fSDimitry Andric //===----------------------------------------------------------------------===//
125a5c549fSDimitry Andric 
131c986198SDimitry Andric #include "LinkerScript.h"
145a5c549fSDimitry Andric #include "Config.h"
15145449b1SDimitry Andric #include "InputFiles.h"
161c986198SDimitry Andric #include "InputSection.h"
171c986198SDimitry Andric #include "OutputSections.h"
185a5c549fSDimitry Andric #include "SymbolTable.h"
19d93e1dfaSDimitry Andric #include "Symbols.h"
20d93e1dfaSDimitry Andric #include "SyntheticSections.h"
21bef2946cSDimitry Andric #include "Target.h"
22d93e1dfaSDimitry Andric #include "Writer.h"
236f8fc217SDimitry Andric #include "lld/Common/CommonLinkerContext.h"
2420d35e67SDimitry Andric #include "lld/Common/Strings.h"
25d93e1dfaSDimitry Andric #include "llvm/ADT/STLExtras.h"
26d93e1dfaSDimitry Andric #include "llvm/ADT/StringRef.h"
272079716dSDimitry Andric #include "llvm/BinaryFormat/ELF.h"
28d93e1dfaSDimitry Andric #include "llvm/Support/Casting.h"
29d93e1dfaSDimitry Andric #include "llvm/Support/Endian.h"
30d93e1dfaSDimitry Andric #include "llvm/Support/ErrorHandling.h"
31b60736ecSDimitry Andric #include "llvm/Support/TimeProfiler.h"
32d93e1dfaSDimitry Andric #include <algorithm>
33d93e1dfaSDimitry Andric #include <cassert>
34d93e1dfaSDimitry Andric #include <cstddef>
35d93e1dfaSDimitry Andric #include <cstdint>
36d93e1dfaSDimitry Andric #include <limits>
37d93e1dfaSDimitry Andric #include <string>
38d93e1dfaSDimitry Andric #include <vector>
395a5c549fSDimitry Andric 
405a5c549fSDimitry Andric using namespace llvm;
411c986198SDimitry Andric using namespace llvm::ELF;
421c986198SDimitry Andric using namespace llvm::object;
43d93e1dfaSDimitry Andric using namespace llvm::support::endian;
44cfca06d7SDimitry Andric using namespace lld;
45cfca06d7SDimitry Andric using namespace lld::elf;
465a5c549fSDimitry Andric 
47ac9a064cSDimitry Andric ScriptWrapper elf::script;
48d2d3ebb8SDimitry Andric 
isSectionPrefix(StringRef prefix,StringRef name)49f65dcba8SDimitry Andric static bool isSectionPrefix(StringRef prefix, StringRef name) {
5077fc4c14SDimitry Andric   return name.consume_front(prefix) && (name.empty() || name[0] == '.');
51f65dcba8SDimitry Andric }
52f65dcba8SDimitry Andric 
getOutputSectionName(const InputSectionBase * s)53f65dcba8SDimitry Andric static StringRef getOutputSectionName(const InputSectionBase *s) {
54b1c73532SDimitry Andric   // This is for --emit-relocs and -r. If .text.foo is emitted as .text.bar, we
55b1c73532SDimitry Andric   // want to emit .rela.text.foo as .rela.text.bar for consistency (this is not
56f65dcba8SDimitry Andric   // technically required, but not doing it is odd). This code guarantees that.
57f65dcba8SDimitry Andric   if (auto *isec = dyn_cast<InputSection>(s)) {
58f65dcba8SDimitry Andric     if (InputSectionBase *rel = isec->getRelocatedSection()) {
59f65dcba8SDimitry Andric       OutputSection *out = rel->getOutputSection();
60aca2e42cSDimitry Andric       if (!out) {
61aca2e42cSDimitry Andric         assert(config->relocatable && (rel->flags & SHF_LINK_ORDER));
62aca2e42cSDimitry Andric         return s->name;
63aca2e42cSDimitry Andric       }
649b950333SDimitry Andric       if (s->type == SHT_CREL)
659b950333SDimitry Andric         return saver().save(".crel" + out->name);
66f65dcba8SDimitry Andric       if (s->type == SHT_RELA)
676f8fc217SDimitry Andric         return saver().save(".rela" + out->name);
686f8fc217SDimitry Andric       return saver().save(".rel" + out->name);
69f65dcba8SDimitry Andric     }
70f65dcba8SDimitry Andric   }
71f65dcba8SDimitry Andric 
72b1c73532SDimitry Andric   if (config->relocatable)
73b1c73532SDimitry Andric     return s->name;
74b1c73532SDimitry Andric 
75f65dcba8SDimitry Andric   // A BssSection created for a common symbol is identified as "COMMON" in
76f65dcba8SDimitry Andric   // linker scripts. It should go to .bss section.
77f65dcba8SDimitry Andric   if (s->name == "COMMON")
78f65dcba8SDimitry Andric     return ".bss";
79f65dcba8SDimitry Andric 
80f65dcba8SDimitry Andric   if (script->hasSectionsCommand)
81f65dcba8SDimitry Andric     return s->name;
82f65dcba8SDimitry Andric 
83f65dcba8SDimitry Andric   // When no SECTIONS is specified, emulate GNU ld's internal linker scripts
84f65dcba8SDimitry Andric   // by grouping sections with certain prefixes.
85f65dcba8SDimitry Andric 
86f65dcba8SDimitry Andric   // GNU ld places text sections with prefix ".text.hot.", ".text.unknown.",
87f65dcba8SDimitry Andric   // ".text.unlikely.", ".text.startup." or ".text.exit." before others.
88f65dcba8SDimitry Andric   // We provide an option -z keep-text-section-prefix to group such sections
89f65dcba8SDimitry Andric   // into separate output sections. This is more flexible. See also
90f65dcba8SDimitry Andric   // sortISDBySectionOrder().
91f65dcba8SDimitry Andric   // ".text.unknown" means the hotness of the section is unknown. When
92f65dcba8SDimitry Andric   // SampleFDO is used, if a function doesn't have sample, it could be very
93f65dcba8SDimitry Andric   // cold or it could be a new function never being sampled. Those functions
94f65dcba8SDimitry Andric   // will be kept in the ".text.unknown" section.
95f65dcba8SDimitry Andric   // ".text.split." holds symbols which are split out from functions in other
96f65dcba8SDimitry Andric   // input sections. For example, with -fsplit-machine-functions, placing the
97f65dcba8SDimitry Andric   // cold parts in .text.split instead of .text.unlikely mitigates against poor
98f65dcba8SDimitry Andric   // profile inaccuracy. Techniques such as hugepage remapping can make
99f65dcba8SDimitry Andric   // conservative decisions at the section granularity.
10077fc4c14SDimitry Andric   if (isSectionPrefix(".text", s->name)) {
101f65dcba8SDimitry Andric     if (config->zKeepTextSectionPrefix)
10277fc4c14SDimitry Andric       for (StringRef v : {".text.hot", ".text.unknown", ".text.unlikely",
10377fc4c14SDimitry Andric                           ".text.startup", ".text.exit", ".text.split"})
10477fc4c14SDimitry Andric         if (isSectionPrefix(v.substr(5), s->name.substr(5)))
10577fc4c14SDimitry Andric           return v;
10677fc4c14SDimitry Andric     return ".text";
10777fc4c14SDimitry Andric   }
108f65dcba8SDimitry Andric 
109f65dcba8SDimitry Andric   for (StringRef v :
1107fa27ce4SDimitry Andric        {".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss", ".ldata",
1117fa27ce4SDimitry Andric         ".lrodata", ".lbss", ".gcc_except_table", ".init_array", ".fini_array",
1127fa27ce4SDimitry Andric         ".tbss", ".tdata", ".ARM.exidx", ".ARM.extab", ".ctors", ".dtors"})
113f65dcba8SDimitry Andric     if (isSectionPrefix(v, s->name))
11477fc4c14SDimitry Andric       return v;
115f65dcba8SDimitry Andric 
116f65dcba8SDimitry Andric   return s->name;
117022ebf5bSDimitry Andric }
118eb1ff93dSDimitry Andric 
getValue() const119eb1ff93dSDimitry Andric uint64_t ExprValue::getValue() const {
120f1e1c239SDimitry Andric   if (sec)
12108e8dd7bSDimitry Andric     return alignToPowerOf2(sec->getOutputSection()->addr + sec->getOffset(val),
122f1e1c239SDimitry Andric                            alignment);
12308e8dd7bSDimitry Andric   return alignToPowerOf2(val, alignment);
124d2d3ebb8SDimitry Andric }
125d2d3ebb8SDimitry Andric 
getSecAddr() const126d2d3ebb8SDimitry Andric uint64_t ExprValue::getSecAddr() const {
127f65dcba8SDimitry Andric   return sec ? sec->getOutputSection()->addr + sec->getOffset(0) : 0;
128d2d3ebb8SDimitry Andric }
1291c986198SDimitry Andric 
getSectionOffset() const130eb1ff93dSDimitry Andric uint64_t ExprValue::getSectionOffset() const {
131eb1ff93dSDimitry Andric   return getValue() - getSecAddr();
1321c986198SDimitry Andric }
1331c986198SDimitry Andric 
createOutputSection(StringRef name,StringRef location)134145449b1SDimitry Andric OutputDesc *LinkerScript::createOutputSection(StringRef name,
135f1e1c239SDimitry Andric                                               StringRef location) {
136145449b1SDimitry Andric   OutputDesc *&secRef = nameToOutputSection[CachedHashStringRef(name)];
137145449b1SDimitry Andric   OutputDesc *sec;
138145449b1SDimitry Andric   if (secRef && secRef->osec.location.empty()) {
13980350c11SDimitry Andric     // There was a forward reference.
140f1e1c239SDimitry Andric     sec = secRef;
14180350c11SDimitry Andric   } else {
142145449b1SDimitry Andric     sec = make<OutputDesc>(name, SHT_PROGBITS, 0);
143f1e1c239SDimitry Andric     if (!secRef)
144f1e1c239SDimitry Andric       secRef = sec;
14580350c11SDimitry Andric   }
146145449b1SDimitry Andric   sec->osec.location = std::string(location);
147f1e1c239SDimitry Andric   return sec;
1481c986198SDimitry Andric }
1491c986198SDimitry Andric 
getOrCreateOutputSection(StringRef name)150145449b1SDimitry Andric OutputDesc *LinkerScript::getOrCreateOutputSection(StringRef name) {
151145449b1SDimitry Andric   OutputDesc *&cmdRef = nameToOutputSection[CachedHashStringRef(name)];
152f1e1c239SDimitry Andric   if (!cmdRef)
153145449b1SDimitry Andric     cmdRef = make<OutputDesc>(name, SHT_PROGBITS, 0);
154f1e1c239SDimitry Andric   return cmdRef;
1551c986198SDimitry Andric }
1561c986198SDimitry Andric 
15720d35e67SDimitry Andric // Expands the memory region by the specified size.
expandMemoryRegion(MemoryRegion * memRegion,uint64_t size,StringRef secName)158f1e1c239SDimitry Andric static void expandMemoryRegion(MemoryRegion *memRegion, uint64_t size,
159f65dcba8SDimitry Andric                                StringRef secName) {
160f1e1c239SDimitry Andric   memRegion->curPos += size;
16120d35e67SDimitry Andric }
16220d35e67SDimitry Andric 
expandMemoryRegions(uint64_t size)163f1e1c239SDimitry Andric void LinkerScript::expandMemoryRegions(uint64_t size) {
164e3b55780SDimitry Andric   if (state->memRegion)
165e3b55780SDimitry Andric     expandMemoryRegion(state->memRegion, size, state->outSec->name);
166f1e1c239SDimitry Andric   // Only expand the LMARegion if it is different from memRegion.
167e3b55780SDimitry Andric   if (state->lmaRegion && state->memRegion != state->lmaRegion)
168e3b55780SDimitry Andric     expandMemoryRegion(state->lmaRegion, size, state->outSec->name);
16920d35e67SDimitry Andric }
17020d35e67SDimitry Andric 
expandOutputSection(uint64_t size)171f1e1c239SDimitry Andric void LinkerScript::expandOutputSection(uint64_t size) {
172e3b55780SDimitry Andric   state->outSec->size += size;
173f1e1c239SDimitry Andric   expandMemoryRegions(size);
17420d35e67SDimitry Andric }
17520d35e67SDimitry Andric 
setDot(Expr e,const Twine & loc,bool inSec)176f1e1c239SDimitry Andric void LinkerScript::setDot(Expr e, const Twine &loc, bool inSec) {
177f1e1c239SDimitry Andric   uint64_t val = e().getValue();
178b1c73532SDimitry Andric   // If val is smaller and we are in an output section, record the error and
179b1c73532SDimitry Andric   // report it if this is the last assignAddresses iteration. dot may be smaller
180b1c73532SDimitry Andric   // if there is another assignAddresses iteration.
181b1c73532SDimitry Andric   if (val < dot && inSec) {
182ac9a064cSDimitry Andric     recordError(loc + ": unable to move location counter (0x" +
183ac9a064cSDimitry Andric                 Twine::utohexstr(dot) + ") backward to 0x" +
184ac9a064cSDimitry Andric                 Twine::utohexstr(val) + " for section '" + state->outSec->name +
185ac9a064cSDimitry Andric                 "'");
186b1c73532SDimitry Andric   }
187eb1ff93dSDimitry Andric 
188d2d3ebb8SDimitry Andric   // Update to location counter means update to section size.
189f1e1c239SDimitry Andric   if (inSec)
190f1e1c239SDimitry Andric     expandOutputSection(val - dot);
19120d35e67SDimitry Andric 
192f1e1c239SDimitry Andric   dot = val;
19320d35e67SDimitry Andric }
19420d35e67SDimitry Andric 
19520d35e67SDimitry Andric // Used for handling linker symbol assignments, for both finalizing
19620d35e67SDimitry Andric // their values and doing early declarations. Returns true if symbol
19720d35e67SDimitry Andric // should be defined from linker script.
shouldDefineSym(SymbolAssignment * cmd)198f1e1c239SDimitry Andric static bool shouldDefineSym(SymbolAssignment *cmd) {
199f1e1c239SDimitry Andric   if (cmd->name == ".")
20020d35e67SDimitry Andric     return false;
20120d35e67SDimitry Andric 
202ac9a064cSDimitry Andric   return !cmd->provide || LinkerScript::shouldAddProvideSym(cmd->name);
203d2d3ebb8SDimitry Andric }
204d2d3ebb8SDimitry Andric 
205d2bd9e70SDimitry Andric // Called by processSymbolAssignments() to assign definitions to
206d2bd9e70SDimitry Andric // linker-script-defined symbols.
addSymbol(SymbolAssignment * cmd)207f1e1c239SDimitry Andric void LinkerScript::addSymbol(SymbolAssignment *cmd) {
208f1e1c239SDimitry Andric   if (!shouldDefineSym(cmd))
209eb1ff93dSDimitry Andric     return;
210eb1ff93dSDimitry Andric 
211eb1ff93dSDimitry Andric   // Define a symbol.
212f1e1c239SDimitry Andric   ExprValue value = cmd->expression();
213f1e1c239SDimitry Andric   SectionBase *sec = value.isAbsolute() ? nullptr : value.sec;
214f1e1c239SDimitry Andric   uint8_t visibility = cmd->hidden ? STV_HIDDEN : STV_DEFAULT;
215eb1ff93dSDimitry Andric 
216eb1ff93dSDimitry Andric   // When this function is called, section addresses have not been
217eb1ff93dSDimitry Andric   // fixed yet. So, we may or may not know the value of the RHS
218eb1ff93dSDimitry Andric   // expression.
219eb1ff93dSDimitry Andric   //
220eb1ff93dSDimitry Andric   // For example, if an expression is `x = 42`, we know x is always 42.
221eb1ff93dSDimitry Andric   // However, if an expression is `x = .`, there's no way to know its
222eb1ff93dSDimitry Andric   // value at the moment.
223eb1ff93dSDimitry Andric   //
224eb1ff93dSDimitry Andric   // We want to set symbol values early if we can. This allows us to
225eb1ff93dSDimitry Andric   // use symbols as variables in linker scripts. Doing so allows us to
226eb1ff93dSDimitry Andric   // write expressions like this: `alignment = 16; . = ALIGN(., alignment)`.
227f1e1c239SDimitry Andric   uint64_t symValue = value.sec ? 0 : value.getValue();
228eb1ff93dSDimitry Andric 
2294df029ccSDimitry Andric   Defined newSym(createInternalFile(cmd->location), cmd->name, STB_GLOBAL,
2304df029ccSDimitry Andric                  visibility, value.type, symValue, 0, sec);
231f1e1c239SDimitry Andric 
232e3b55780SDimitry Andric   Symbol *sym = symtab.insert(cmd->name);
233d2bd9e70SDimitry Andric   sym->mergeProperties(newSym);
234e3b55780SDimitry Andric   newSym.overwrite(*sym);
235145449b1SDimitry Andric   sym->isUsedInRegularObj = true;
236f1e1c239SDimitry Andric   cmd->sym = cast<Defined>(sym);
237eb1ff93dSDimitry Andric }
238eb1ff93dSDimitry Andric 
23920d35e67SDimitry Andric // This function is called from LinkerScript::declareSymbols.
24020d35e67SDimitry Andric // It creates a placeholder symbol if needed.
declareSymbol(SymbolAssignment * cmd)241f1e1c239SDimitry Andric static void declareSymbol(SymbolAssignment *cmd) {
242f1e1c239SDimitry Andric   if (!shouldDefineSym(cmd))
24320d35e67SDimitry Andric     return;
24420d35e67SDimitry Andric 
245f1e1c239SDimitry Andric   uint8_t visibility = cmd->hidden ? STV_HIDDEN : STV_DEFAULT;
2464df029ccSDimitry Andric   Defined newSym(ctx.internalFile, cmd->name, STB_GLOBAL, visibility,
2474df029ccSDimitry Andric                  STT_NOTYPE, 0, 0, nullptr);
248f1e1c239SDimitry Andric 
249b1c73532SDimitry Andric   // If the symbol is already defined, its order is 0 (with absence indicating
250b1c73532SDimitry Andric   // 0); otherwise it's assigned the order of the SymbolAssignment.
251e3b55780SDimitry Andric   Symbol *sym = symtab.insert(cmd->name);
252b1c73532SDimitry Andric   if (!sym->isDefined())
253b1c73532SDimitry Andric     ctx.scriptSymOrder.insert({sym, cmd->symOrder});
254b1c73532SDimitry Andric 
255b1c73532SDimitry Andric   // We can't calculate final value right now.
256d2bd9e70SDimitry Andric   sym->mergeProperties(newSym);
257e3b55780SDimitry Andric   newSym.overwrite(*sym);
258f1e1c239SDimitry Andric 
259f1e1c239SDimitry Andric   cmd->sym = cast<Defined>(sym);
260f1e1c239SDimitry Andric   cmd->provide = false;
261145449b1SDimitry Andric   sym->isUsedInRegularObj = true;
262f1e1c239SDimitry Andric   sym->scriptDefined = true;
26320d35e67SDimitry Andric }
26420d35e67SDimitry Andric 
265d2bd9e70SDimitry Andric using SymbolAssignmentMap =
266d2bd9e70SDimitry Andric     DenseMap<const Defined *, std::pair<SectionBase *, uint64_t>>;
267d2bd9e70SDimitry Andric 
268d2bd9e70SDimitry Andric // Collect section/value pairs of linker-script-defined symbols. This is used to
269d2bd9e70SDimitry Andric // check whether symbol values converge.
2706f8fc217SDimitry Andric static SymbolAssignmentMap
getSymbolAssignmentValues(ArrayRef<SectionCommand * > sectionCommands)2716f8fc217SDimitry Andric getSymbolAssignmentValues(ArrayRef<SectionCommand *> sectionCommands) {
272d2bd9e70SDimitry Andric   SymbolAssignmentMap ret;
273f65dcba8SDimitry Andric   for (SectionCommand *cmd : sectionCommands) {
274f65dcba8SDimitry Andric     if (auto *assign = dyn_cast<SymbolAssignment>(cmd)) {
275f65dcba8SDimitry Andric       if (assign->sym) // sym is nullptr for dot.
276f65dcba8SDimitry Andric         ret.try_emplace(assign->sym, std::make_pair(assign->sym->section,
277f65dcba8SDimitry Andric                                                     assign->sym->value));
278d2bd9e70SDimitry Andric       continue;
279d2bd9e70SDimitry Andric     }
280145449b1SDimitry Andric     for (SectionCommand *subCmd : cast<OutputDesc>(cmd)->osec.commands)
281f65dcba8SDimitry Andric       if (auto *assign = dyn_cast<SymbolAssignment>(subCmd))
282f65dcba8SDimitry Andric         if (assign->sym)
283f65dcba8SDimitry Andric           ret.try_emplace(assign->sym, std::make_pair(assign->sym->section,
284f65dcba8SDimitry Andric                                                       assign->sym->value));
285d2bd9e70SDimitry Andric   }
286d2bd9e70SDimitry Andric   return ret;
287d2bd9e70SDimitry Andric }
288d2bd9e70SDimitry Andric 
289d2bd9e70SDimitry Andric // Returns the lexicographical smallest (for determinism) Defined whose
290d2bd9e70SDimitry Andric // section/value has changed.
291d2bd9e70SDimitry Andric static const Defined *
getChangedSymbolAssignment(const SymbolAssignmentMap & oldValues)292d2bd9e70SDimitry Andric getChangedSymbolAssignment(const SymbolAssignmentMap &oldValues) {
293d2bd9e70SDimitry Andric   const Defined *changed = nullptr;
294d2bd9e70SDimitry Andric   for (auto &it : oldValues) {
295d2bd9e70SDimitry Andric     const Defined *sym = it.first;
296d2bd9e70SDimitry Andric     if (std::make_pair(sym->section, sym->value) != it.second &&
297d2bd9e70SDimitry Andric         (!changed || sym->getName() < changed->getName()))
298d2bd9e70SDimitry Andric       changed = sym;
299d2bd9e70SDimitry Andric   }
300d2bd9e70SDimitry Andric   return changed;
301d2bd9e70SDimitry Andric }
302d2bd9e70SDimitry Andric 
303cfca06d7SDimitry Andric // Process INSERT [AFTER|BEFORE] commands. For each command, we move the
304cfca06d7SDimitry Andric // specified output section to the designated place.
processInsertCommands()30520d35e67SDimitry Andric void LinkerScript::processInsertCommands() {
306145449b1SDimitry Andric   SmallVector<OutputDesc *, 0> moves;
307cfca06d7SDimitry Andric   for (const InsertCommand &cmd : insertCommands) {
308ac9a064cSDimitry Andric     if (config->enableNonContiguousRegions)
309ac9a064cSDimitry Andric       error("INSERT cannot be used with --enable-non-contiguous-regions");
310ac9a064cSDimitry Andric 
311344a3780SDimitry Andric     for (StringRef name : cmd.names) {
312344a3780SDimitry Andric       // If base is empty, it may have been discarded by
313ecbca9f5SDimitry Andric       // adjustOutputSections(). We do not handle such output sections.
314f65dcba8SDimitry Andric       auto from = llvm::find_if(sectionCommands, [&](SectionCommand *subCmd) {
315145449b1SDimitry Andric         return isa<OutputDesc>(subCmd) &&
316145449b1SDimitry Andric                cast<OutputDesc>(subCmd)->osec.name == name;
317344a3780SDimitry Andric       });
318cfca06d7SDimitry Andric       if (from == sectionCommands.end())
31920d35e67SDimitry Andric         continue;
320145449b1SDimitry Andric       moves.push_back(cast<OutputDesc>(*from));
321cfca06d7SDimitry Andric       sectionCommands.erase(from);
322344a3780SDimitry Andric     }
32320d35e67SDimitry Andric 
324f65dcba8SDimitry Andric     auto insertPos =
325f65dcba8SDimitry Andric         llvm::find_if(sectionCommands, [&cmd](SectionCommand *subCmd) {
326145449b1SDimitry Andric           auto *to = dyn_cast<OutputDesc>(subCmd);
327145449b1SDimitry Andric           return to != nullptr && to->osec.name == cmd.where;
328cfca06d7SDimitry Andric         });
329cfca06d7SDimitry Andric     if (insertPos == sectionCommands.end()) {
330344a3780SDimitry Andric       error("unable to insert " + cmd.names[0] +
331cfca06d7SDimitry Andric             (cmd.isAfter ? " after " : " before ") + cmd.where);
332cfca06d7SDimitry Andric     } else {
333cfca06d7SDimitry Andric       if (cmd.isAfter)
334cfca06d7SDimitry Andric         ++insertPos;
335344a3780SDimitry Andric       sectionCommands.insert(insertPos, moves.begin(), moves.end());
336cfca06d7SDimitry Andric     }
337344a3780SDimitry Andric     moves.clear();
338cfca06d7SDimitry Andric   }
33920d35e67SDimitry Andric }
34020d35e67SDimitry Andric 
34120d35e67SDimitry Andric // Symbols defined in script should not be inlined by LTO. At the same time
34220d35e67SDimitry Andric // we don't know their final values until late stages of link. Here we scan
34320d35e67SDimitry Andric // over symbol assignment commands and create placeholder symbols if needed.
declareSymbols()34420d35e67SDimitry Andric void LinkerScript::declareSymbols() {
345e3b55780SDimitry Andric   assert(!state);
346f65dcba8SDimitry Andric   for (SectionCommand *cmd : sectionCommands) {
347f65dcba8SDimitry Andric     if (auto *assign = dyn_cast<SymbolAssignment>(cmd)) {
348f65dcba8SDimitry Andric       declareSymbol(assign);
34920d35e67SDimitry Andric       continue;
35020d35e67SDimitry Andric     }
35120d35e67SDimitry Andric 
35220d35e67SDimitry Andric     // If the output section directive has constraints,
35320d35e67SDimitry Andric     // we can't say for sure if it is going to be included or not.
35420d35e67SDimitry Andric     // Skip such sections for now. Improve the checks if we ever
35520d35e67SDimitry Andric     // need symbols from that sections to be declared early.
356145449b1SDimitry Andric     const OutputSection &sec = cast<OutputDesc>(cmd)->osec;
357145449b1SDimitry Andric     if (sec.constraint != ConstraintKind::NoConstraint)
35820d35e67SDimitry Andric       continue;
359145449b1SDimitry Andric     for (SectionCommand *cmd : sec.commands)
360f65dcba8SDimitry Andric       if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
361f65dcba8SDimitry Andric         declareSymbol(assign);
36220d35e67SDimitry Andric   }
36320d35e67SDimitry Andric }
36420d35e67SDimitry Andric 
365eb1ff93dSDimitry Andric // This function is called from assignAddresses, while we are
366eb1ff93dSDimitry Andric // fixing the output section addresses. This function is supposed
367eb1ff93dSDimitry Andric // to set the final value for a given symbol assignment.
assignSymbol(SymbolAssignment * cmd,bool inSec)368f1e1c239SDimitry Andric void LinkerScript::assignSymbol(SymbolAssignment *cmd, bool inSec) {
369f1e1c239SDimitry Andric   if (cmd->name == ".") {
370f1e1c239SDimitry Andric     setDot(cmd->expression, cmd->location, inSec);
371d2d3ebb8SDimitry Andric     return;
372d2d3ebb8SDimitry Andric   }
373d2d3ebb8SDimitry Andric 
374f1e1c239SDimitry Andric   if (!cmd->sym)
375b047feadSDimitry Andric     return;
376b047feadSDimitry Andric 
377f1e1c239SDimitry Andric   ExprValue v = cmd->expression();
378f1e1c239SDimitry Andric   if (v.isAbsolute()) {
379f1e1c239SDimitry Andric     cmd->sym->section = nullptr;
380f1e1c239SDimitry Andric     cmd->sym->value = v.getValue();
381b047feadSDimitry Andric   } else {
382f1e1c239SDimitry Andric     cmd->sym->section = v.sec;
383f1e1c239SDimitry Andric     cmd->sym->value = v.getSectionOffset();
384d93e1dfaSDimitry Andric   }
385b60736ecSDimitry Andric   cmd->sym->type = v.type;
386b047feadSDimitry Andric }
387b047feadSDimitry Andric 
getFilename(const InputFile * file)388b60736ecSDimitry Andric static inline StringRef getFilename(const InputFile *file) {
389b60736ecSDimitry Andric   return file ? file->getNameForScript() : StringRef();
390b60736ecSDimitry Andric }
391b60736ecSDimitry Andric 
matchesFile(const InputFile * file) const392b60736ecSDimitry Andric bool InputSectionDescription::matchesFile(const InputFile *file) const {
393b60736ecSDimitry Andric   if (filePat.isTrivialMatchAll())
394b60736ecSDimitry Andric     return true;
395b60736ecSDimitry Andric 
396b60736ecSDimitry Andric   if (!matchesFileCache || matchesFileCache->first != file)
397b60736ecSDimitry Andric     matchesFileCache.emplace(file, filePat.match(getFilename(file)));
398b60736ecSDimitry Andric 
399b60736ecSDimitry Andric   return matchesFileCache->second;
400b60736ecSDimitry Andric }
401b60736ecSDimitry Andric 
excludesFile(const InputFile * file) const402b60736ecSDimitry Andric bool SectionPattern::excludesFile(const InputFile *file) const {
403b60736ecSDimitry Andric   if (excludedFilePat.empty())
404b60736ecSDimitry Andric     return false;
405b60736ecSDimitry Andric 
406b60736ecSDimitry Andric   if (!excludesFileCache || excludesFileCache->first != file)
407b60736ecSDimitry Andric     excludesFileCache.emplace(file, excludedFilePat.match(getFilename(file)));
408b60736ecSDimitry Andric 
409b60736ecSDimitry Andric   return excludesFileCache->second;
410d93e1dfaSDimitry Andric }
411d93e1dfaSDimitry Andric 
shouldKeep(InputSectionBase * s)412f1e1c239SDimitry Andric bool LinkerScript::shouldKeep(InputSectionBase *s) {
413f1e1c239SDimitry Andric   for (InputSectionDescription *id : keptSections)
414b60736ecSDimitry Andric     if (id->matchesFile(s->file))
415f1e1c239SDimitry Andric       for (SectionPattern &p : id->sectionPatterns)
416cfca06d7SDimitry Andric         if (p.sectionPat.match(s->name) &&
417cfca06d7SDimitry Andric             (s->flags & id->withFlags) == id->withFlags &&
418cfca06d7SDimitry Andric             (s->flags & id->withoutFlags) == 0)
419d93e1dfaSDimitry Andric           return true;
420d93e1dfaSDimitry Andric   return false;
4211c986198SDimitry Andric }
4221c986198SDimitry Andric 
423d2d3ebb8SDimitry Andric // A helper function for the SORT() command.
matchConstraints(ArrayRef<InputSectionBase * > sections,ConstraintKind kind)424d2bd9e70SDimitry Andric static bool matchConstraints(ArrayRef<InputSectionBase *> sections,
425f1e1c239SDimitry Andric                              ConstraintKind kind) {
426f1e1c239SDimitry Andric   if (kind == ConstraintKind::NoConstraint)
427d93e1dfaSDimitry Andric     return true;
428d2d3ebb8SDimitry Andric 
429f1e1c239SDimitry Andric   bool isRW = llvm::any_of(
430d2bd9e70SDimitry Andric       sections, [](InputSectionBase *sec) { return sec->flags & SHF_WRITE; });
431d2d3ebb8SDimitry Andric 
432f1e1c239SDimitry Andric   return (isRW && kind == ConstraintKind::ReadWrite) ||
433f1e1c239SDimitry Andric          (!isRW && kind == ConstraintKind::ReadOnly);
434d93e1dfaSDimitry Andric }
435d93e1dfaSDimitry Andric 
sortSections(MutableArrayRef<InputSectionBase * > vec,SortSectionPolicy k)436d2bd9e70SDimitry Andric static void sortSections(MutableArrayRef<InputSectionBase *> vec,
437f1e1c239SDimitry Andric                          SortSectionPolicy k) {
438d2bd9e70SDimitry Andric   auto alignmentComparator = [](InputSectionBase *a, InputSectionBase *b) {
439d2bd9e70SDimitry Andric     // ">" is not a mistake. Sections with larger alignments are placed
440d2bd9e70SDimitry Andric     // before sections with smaller alignments in order to reduce the
441d2bd9e70SDimitry Andric     // amount of padding necessary. This is compatible with GNU.
442e3b55780SDimitry Andric     return a->addralign > b->addralign;
443d2bd9e70SDimitry Andric   };
444d2bd9e70SDimitry Andric   auto nameComparator = [](InputSectionBase *a, InputSectionBase *b) {
445d2bd9e70SDimitry Andric     return a->name < b->name;
446d2bd9e70SDimitry Andric   };
447d2bd9e70SDimitry Andric   auto priorityComparator = [](InputSectionBase *a, InputSectionBase *b) {
448d2bd9e70SDimitry Andric     return getPriority(a->name) < getPriority(b->name);
449d2bd9e70SDimitry Andric   };
450d2bd9e70SDimitry Andric 
451d2bd9e70SDimitry Andric   switch (k) {
452d2bd9e70SDimitry Andric   case SortSectionPolicy::Default:
453d2bd9e70SDimitry Andric   case SortSectionPolicy::None:
454d2bd9e70SDimitry Andric     return;
455d2bd9e70SDimitry Andric   case SortSectionPolicy::Alignment:
456d2bd9e70SDimitry Andric     return llvm::stable_sort(vec, alignmentComparator);
457d2bd9e70SDimitry Andric   case SortSectionPolicy::Name:
458d2bd9e70SDimitry Andric     return llvm::stable_sort(vec, nameComparator);
459d2bd9e70SDimitry Andric   case SortSectionPolicy::Priority:
460d2bd9e70SDimitry Andric     return llvm::stable_sort(vec, priorityComparator);
4617fa27ce4SDimitry Andric   case SortSectionPolicy::Reverse:
4627fa27ce4SDimitry Andric     return std::reverse(vec.begin(), vec.end());
463d2bd9e70SDimitry Andric   }
464d93e1dfaSDimitry Andric }
465d93e1dfaSDimitry Andric 
466d93e1dfaSDimitry Andric // Sort sections as instructed by SORT-family commands and --sort-section
467d93e1dfaSDimitry Andric // option. Because SORT-family commands can be nested at most two depth
468d93e1dfaSDimitry Andric // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
469d93e1dfaSDimitry Andric // line option is respected even if a SORT command is given, the exact
470d93e1dfaSDimitry Andric // behavior we have here is a bit complicated. Here are the rules.
471d93e1dfaSDimitry Andric //
472d93e1dfaSDimitry Andric // 1. If two SORT commands are given, --sort-section is ignored.
473d93e1dfaSDimitry Andric // 2. If one SORT command is given, and if it is not SORT_NONE,
474d93e1dfaSDimitry Andric //    --sort-section is handled as an inner SORT command.
475d93e1dfaSDimitry Andric // 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
476d93e1dfaSDimitry Andric // 4. If no SORT command is given, sort according to --sort-section.
sortInputSections(MutableArrayRef<InputSectionBase * > vec,SortSectionPolicy outer,SortSectionPolicy inner)477d2bd9e70SDimitry Andric static void sortInputSections(MutableArrayRef<InputSectionBase *> vec,
478b60736ecSDimitry Andric                               SortSectionPolicy outer,
479b60736ecSDimitry Andric                               SortSectionPolicy inner) {
480b60736ecSDimitry Andric   if (outer == SortSectionPolicy::None)
481eb1ff93dSDimitry Andric     return;
482eb1ff93dSDimitry Andric 
483b60736ecSDimitry Andric   if (inner == SortSectionPolicy::Default)
484f1e1c239SDimitry Andric     sortSections(vec, config->sortSection);
485eb1ff93dSDimitry Andric   else
486b60736ecSDimitry Andric     sortSections(vec, inner);
487b60736ecSDimitry Andric   sortSections(vec, outer);
488eb1ff93dSDimitry Andric }
489eb1ff93dSDimitry Andric 
490eb1ff93dSDimitry Andric // Compute and remember which sections the InputSectionDescription matches.
4916f8fc217SDimitry Andric SmallVector<InputSectionBase *, 0>
computeInputSections(const InputSectionDescription * cmd,ArrayRef<InputSectionBase * > sections,const OutputSection & outCmd)492cfca06d7SDimitry Andric LinkerScript::computeInputSections(const InputSectionDescription *cmd,
493ac9a064cSDimitry Andric                                    ArrayRef<InputSectionBase *> sections,
494ac9a064cSDimitry Andric                                    const OutputSection &outCmd) {
4956f8fc217SDimitry Andric   SmallVector<InputSectionBase *, 0> ret;
4966f8fc217SDimitry Andric   SmallVector<size_t, 0> indexes;
497b60736ecSDimitry Andric   DenseSet<size_t> seen;
498ac9a064cSDimitry Andric   DenseSet<InputSectionBase *> spills;
499b60736ecSDimitry Andric   auto sortByPositionThenCommandLine = [&](size_t begin, size_t end) {
500b60736ecSDimitry Andric     llvm::sort(MutableArrayRef<size_t>(indexes).slice(begin, end - begin));
501b60736ecSDimitry Andric     for (size_t i = begin; i != end; ++i)
502b60736ecSDimitry Andric       ret[i] = sections[indexes[i]];
503b60736ecSDimitry Andric     sortInputSections(
504b60736ecSDimitry Andric         MutableArrayRef<InputSectionBase *>(ret).slice(begin, end - begin),
505b60736ecSDimitry Andric         config->sortSection, SortSectionPolicy::None);
506b60736ecSDimitry Andric   };
507eb1ff93dSDimitry Andric 
508eb1ff93dSDimitry Andric   // Collects all sections that satisfy constraints of Cmd.
509b60736ecSDimitry Andric   size_t sizeAfterPrevSort = 0;
510f1e1c239SDimitry Andric   for (const SectionPattern &pat : cmd->sectionPatterns) {
511b60736ecSDimitry Andric     size_t sizeBeforeCurrPat = ret.size();
512eb1ff93dSDimitry Andric 
513b60736ecSDimitry Andric     for (size_t i = 0, e = sections.size(); i != e; ++i) {
514ac9a064cSDimitry Andric       // Skip if the section is dead or has been matched by a previous pattern
515ac9a064cSDimitry Andric       // in this input section description.
516b60736ecSDimitry Andric       InputSectionBase *sec = sections[i];
517ac9a064cSDimitry Andric       if (!sec->isLive() || seen.contains(i))
518eb1ff93dSDimitry Andric         continue;
519eb1ff93dSDimitry Andric 
520c0981da4SDimitry Andric       // For --emit-relocs we have to ignore entries like
521eb1ff93dSDimitry Andric       //   .rela.dyn : { *(.rela.data) }
522eb1ff93dSDimitry Andric       // which are common because they are in the default bfd script.
52320d35e67SDimitry Andric       // We do not ignore SHT_REL[A] linker-synthesized sections here because
52420d35e67SDimitry Andric       // want to support scripts that do custom layout for them.
525d2bd9e70SDimitry Andric       if (isa<InputSection>(sec) &&
526d2bd9e70SDimitry Andric           cast<InputSection>(sec)->getRelocatedSection())
527eb1ff93dSDimitry Andric         continue;
528eb1ff93dSDimitry Andric 
529cfca06d7SDimitry Andric       // Check the name early to improve performance in the common case.
530cfca06d7SDimitry Andric       if (!pat.sectionPat.match(sec->name))
531cfca06d7SDimitry Andric         continue;
532cfca06d7SDimitry Andric 
533b60736ecSDimitry Andric       if (!cmd->matchesFile(sec->file) || pat.excludesFile(sec->file) ||
534cfca06d7SDimitry Andric           (sec->flags & cmd->withFlags) != cmd->withFlags ||
535cfca06d7SDimitry Andric           (sec->flags & cmd->withoutFlags) != 0)
536eb1ff93dSDimitry Andric         continue;
537eb1ff93dSDimitry Andric 
538ac9a064cSDimitry Andric       if (sec->parent) {
539ac9a064cSDimitry Andric         // Skip if not allowing multiple matches.
540ac9a064cSDimitry Andric         if (!config->enableNonContiguousRegions)
541ac9a064cSDimitry Andric           continue;
542ac9a064cSDimitry Andric 
543ac9a064cSDimitry Andric         // Disallow spilling into /DISCARD/; special handling would be needed
544ac9a064cSDimitry Andric         // for this in address assignment, and the semantics are nebulous.
545ac9a064cSDimitry Andric         if (outCmd.name == "/DISCARD/")
546ac9a064cSDimitry Andric           continue;
547ac9a064cSDimitry Andric 
548ac9a064cSDimitry Andric         // Skip if the section's first match was /DISCARD/; such sections are
549ac9a064cSDimitry Andric         // always discarded.
550ac9a064cSDimitry Andric         if (sec->parent->name == "/DISCARD/")
551ac9a064cSDimitry Andric           continue;
552ac9a064cSDimitry Andric 
553ac9a064cSDimitry Andric         // Skip if the section was already matched by a different input section
554ac9a064cSDimitry Andric         // description within this output section.
555ac9a064cSDimitry Andric         if (sec->parent == &outCmd)
556ac9a064cSDimitry Andric           continue;
557ac9a064cSDimitry Andric 
558ac9a064cSDimitry Andric         spills.insert(sec);
559ac9a064cSDimitry Andric       }
560ac9a064cSDimitry Andric 
561d2bd9e70SDimitry Andric       ret.push_back(sec);
562b60736ecSDimitry Andric       indexes.push_back(i);
563b60736ecSDimitry Andric       seen.insert(i);
564eb1ff93dSDimitry Andric     }
565eb1ff93dSDimitry Andric 
566b60736ecSDimitry Andric     if (pat.sortOuter == SortSectionPolicy::Default)
567b60736ecSDimitry Andric       continue;
568b60736ecSDimitry Andric 
569b60736ecSDimitry Andric     // Matched sections are ordered by radix sort with the keys being (SORT*,
570b60736ecSDimitry Andric     // --sort-section, input order), where SORT* (if present) is most
571b60736ecSDimitry Andric     // significant.
572b60736ecSDimitry Andric     //
573b60736ecSDimitry Andric     // Matched sections between the previous SORT* and this SORT* are sorted by
574b60736ecSDimitry Andric     // (--sort-alignment, input order).
575b60736ecSDimitry Andric     sortByPositionThenCommandLine(sizeAfterPrevSort, sizeBeforeCurrPat);
576b60736ecSDimitry Andric     // Matched sections by this SORT* pattern are sorted using all 3 keys.
577b60736ecSDimitry Andric     // ret[sizeBeforeCurrPat,ret.size()) are already in the input order, so we
578b60736ecSDimitry Andric     // just sort by sortOuter and sortInner.
579d2bd9e70SDimitry Andric     sortInputSections(
580b60736ecSDimitry Andric         MutableArrayRef<InputSectionBase *>(ret).slice(sizeBeforeCurrPat),
581b60736ecSDimitry Andric         pat.sortOuter, pat.sortInner);
582b60736ecSDimitry Andric     sizeAfterPrevSort = ret.size();
583d93e1dfaSDimitry Andric   }
584b60736ecSDimitry Andric   // Matched sections after the last SORT* are sorted by (--sort-alignment,
585b60736ecSDimitry Andric   // input order).
586b60736ecSDimitry Andric   sortByPositionThenCommandLine(sizeAfterPrevSort, ret.size());
587ac9a064cSDimitry Andric 
588ac9a064cSDimitry Andric   // The flag --enable-non-contiguous-regions may cause sections to match an
589ac9a064cSDimitry Andric   // InputSectionDescription in more than one OutputSection. Matches after the
590ac9a064cSDimitry Andric   // first were collected in the spills set, so replace these with potential
591ac9a064cSDimitry Andric   // spill sections.
592ac9a064cSDimitry Andric   if (!spills.empty()) {
593ac9a064cSDimitry Andric     for (InputSectionBase *&sec : ret) {
594ac9a064cSDimitry Andric       if (!spills.contains(sec))
595ac9a064cSDimitry Andric         continue;
596ac9a064cSDimitry Andric 
597ac9a064cSDimitry Andric       // Append the spill input section to the list for the input section,
598ac9a064cSDimitry Andric       // creating it if necessary.
599ac9a064cSDimitry Andric       PotentialSpillSection *pss = make<PotentialSpillSection>(
600ac9a064cSDimitry Andric           *sec, const_cast<InputSectionDescription &>(*cmd));
601ac9a064cSDimitry Andric       auto [it, inserted] =
602ac9a064cSDimitry Andric           potentialSpillLists.try_emplace(sec, PotentialSpillList{pss, pss});
603ac9a064cSDimitry Andric       if (!inserted) {
604ac9a064cSDimitry Andric         PotentialSpillSection *&tail = it->second.tail;
605ac9a064cSDimitry Andric         tail = tail->next = pss;
606ac9a064cSDimitry Andric       }
607ac9a064cSDimitry Andric       sec = pss;
608ac9a064cSDimitry Andric     }
609ac9a064cSDimitry Andric   }
610ac9a064cSDimitry Andric 
611f1e1c239SDimitry Andric   return ret;
612d93e1dfaSDimitry Andric }
613d93e1dfaSDimitry Andric 
discard(InputSectionBase & s)61477fc4c14SDimitry Andric void LinkerScript::discard(InputSectionBase &s) {
6156f8fc217SDimitry Andric   if (&s == in.shStrTab.get())
61677fc4c14SDimitry Andric     error("discarding " + s.name + " section is not allowed");
617eb1ff93dSDimitry Andric 
61877fc4c14SDimitry Andric   s.markDead();
61977fc4c14SDimitry Andric   s.parent = nullptr;
62077fc4c14SDimitry Andric   for (InputSection *sec : s.dependentSections)
62177fc4c14SDimitry Andric     discard(*sec);
622d93e1dfaSDimitry Andric }
623d93e1dfaSDimitry Andric 
discardSynthetic(OutputSection & outCmd)624cfca06d7SDimitry Andric void LinkerScript::discardSynthetic(OutputSection &outCmd) {
625cfca06d7SDimitry Andric   for (Partition &part : partitions) {
626cfca06d7SDimitry Andric     if (!part.armExidx || !part.armExidx->isLive())
627cfca06d7SDimitry Andric       continue;
6286f8fc217SDimitry Andric     SmallVector<InputSectionBase *, 0> secs(
6296f8fc217SDimitry Andric         part.armExidx->exidxSections.begin(),
630cfca06d7SDimitry Andric         part.armExidx->exidxSections.end());
631f65dcba8SDimitry Andric     for (SectionCommand *cmd : outCmd.commands)
6326f8fc217SDimitry Andric       if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
633ac9a064cSDimitry Andric         for (InputSectionBase *s : computeInputSections(isd, secs, outCmd))
63477fc4c14SDimitry Andric           discard(*s);
635cfca06d7SDimitry Andric   }
636cfca06d7SDimitry Andric }
637cfca06d7SDimitry Andric 
6386f8fc217SDimitry Andric SmallVector<InputSectionBase *, 0>
createInputSectionList(OutputSection & outCmd)639f1e1c239SDimitry Andric LinkerScript::createInputSectionList(OutputSection &outCmd) {
6406f8fc217SDimitry Andric   SmallVector<InputSectionBase *, 0> ret;
641d93e1dfaSDimitry Andric 
642f65dcba8SDimitry Andric   for (SectionCommand *cmd : outCmd.commands) {
643f65dcba8SDimitry Andric     if (auto *isd = dyn_cast<InputSectionDescription>(cmd)) {
644ac9a064cSDimitry Andric       isd->sectionBases = computeInputSections(isd, ctx.inputSections, outCmd);
645f65dcba8SDimitry Andric       for (InputSectionBase *s : isd->sectionBases)
646d2bd9e70SDimitry Andric         s->parent = &outCmd;
647f65dcba8SDimitry Andric       ret.insert(ret.end(), isd->sectionBases.begin(), isd->sectionBases.end());
648d93e1dfaSDimitry Andric     }
649eb1ff93dSDimitry Andric   }
650f1e1c239SDimitry Andric   return ret;
651d93e1dfaSDimitry Andric }
652d93e1dfaSDimitry Andric 
653d2bd9e70SDimitry Andric // Create output sections described by SECTIONS commands.
processSectionCommands()654eb1ff93dSDimitry Andric void LinkerScript::processSectionCommands() {
655344a3780SDimitry Andric   auto process = [this](OutputSection *osec) {
6566f8fc217SDimitry Andric     SmallVector<InputSectionBase *, 0> v = createInputSectionList(*osec);
657d93e1dfaSDimitry Andric 
658d93e1dfaSDimitry Andric     // The output section name `/DISCARD/' is special.
659d93e1dfaSDimitry Andric     // Any input section assigned to it is discarded.
660344a3780SDimitry Andric     if (osec->name == "/DISCARD/") {
661d2bd9e70SDimitry Andric       for (InputSectionBase *s : v)
66277fc4c14SDimitry Andric         discard(*s);
663344a3780SDimitry Andric       discardSynthetic(*osec);
664f65dcba8SDimitry Andric       osec->commands.clear();
665344a3780SDimitry Andric       return false;
666d93e1dfaSDimitry Andric     }
667d93e1dfaSDimitry Andric 
668d93e1dfaSDimitry Andric     // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
669d93e1dfaSDimitry Andric     // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
670d93e1dfaSDimitry Andric     // sections satisfy a given constraint. If not, a directive is handled
671d93e1dfaSDimitry Andric     // as if it wasn't present from the beginning.
672d93e1dfaSDimitry Andric     //
673eb1ff93dSDimitry Andric     // Because we'll iterate over SectionCommands many more times, the easy
674eb1ff93dSDimitry Andric     // way to "make it as if it wasn't present" is to make it empty.
675344a3780SDimitry Andric     if (!matchConstraints(v, osec->constraint)) {
676f1e1c239SDimitry Andric       for (InputSectionBase *s : v)
677d2bd9e70SDimitry Andric         s->parent = nullptr;
678f65dcba8SDimitry Andric       osec->commands.clear();
679344a3780SDimitry Andric       return false;
680d93e1dfaSDimitry Andric     }
681d93e1dfaSDimitry Andric 
682d93e1dfaSDimitry Andric     // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
683d93e1dfaSDimitry Andric     // is given, input sections are aligned to that value, whether the
684d93e1dfaSDimitry Andric     // given value is larger or smaller than the original section alignment.
685344a3780SDimitry Andric     if (osec->subalignExpr) {
686344a3780SDimitry Andric       uint32_t subalign = osec->subalignExpr().getValue();
687f1e1c239SDimitry Andric       for (InputSectionBase *s : v)
688e3b55780SDimitry Andric         s->addralign = subalign;
689d93e1dfaSDimitry Andric     }
690d93e1dfaSDimitry Andric 
691d2bd9e70SDimitry Andric     // Set the partition field the same way OutputSection::recordSection()
692d2bd9e70SDimitry Andric     // does. Partitions cannot be used with the SECTIONS command, so this is
693d2bd9e70SDimitry Andric     // always 1.
694344a3780SDimitry Andric     osec->partition = 1;
695344a3780SDimitry Andric     return true;
696344a3780SDimitry Andric   };
697eb1ff93dSDimitry Andric 
698344a3780SDimitry Andric   // Process OVERWRITE_SECTIONS first so that it can overwrite the main script
699344a3780SDimitry Andric   // or orphans.
700ac9a064cSDimitry Andric   if (config->enableNonContiguousRegions && !overwriteSections.empty())
701ac9a064cSDimitry Andric     error("OVERWRITE_SECTIONS cannot be used with "
702ac9a064cSDimitry Andric           "--enable-non-contiguous-regions");
703145449b1SDimitry Andric   DenseMap<CachedHashStringRef, OutputDesc *> map;
704344a3780SDimitry Andric   size_t i = 0;
705145449b1SDimitry Andric   for (OutputDesc *osd : overwriteSections) {
706145449b1SDimitry Andric     OutputSection *osec = &osd->osec;
7076f8fc217SDimitry Andric     if (process(osec) &&
708145449b1SDimitry Andric         !map.try_emplace(CachedHashStringRef(osec->name), osd).second)
709344a3780SDimitry Andric       warn("OVERWRITE_SECTIONS specifies duplicate " + osec->name);
710145449b1SDimitry Andric   }
711f65dcba8SDimitry Andric   for (SectionCommand *&base : sectionCommands)
712145449b1SDimitry Andric     if (auto *osd = dyn_cast<OutputDesc>(base)) {
713145449b1SDimitry Andric       OutputSection *osec = &osd->osec;
714145449b1SDimitry Andric       if (OutputDesc *overwrite = map.lookup(CachedHashStringRef(osec->name))) {
715145449b1SDimitry Andric         log(overwrite->osec.location + " overwrites " + osec->name);
716145449b1SDimitry Andric         overwrite->osec.sectionIndex = i++;
717344a3780SDimitry Andric         base = overwrite;
718344a3780SDimitry Andric       } else if (process(osec)) {
719344a3780SDimitry Andric         osec->sectionIndex = i++;
720274c9ff5SDimitry Andric       }
721d93e1dfaSDimitry Andric     }
722344a3780SDimitry Andric 
723344a3780SDimitry Andric   // If an OVERWRITE_SECTIONS specified output section is not in
724344a3780SDimitry Andric   // sectionCommands, append it to the end. The section will be inserted by
725344a3780SDimitry Andric   // orphan placement.
726145449b1SDimitry Andric   for (OutputDesc *osd : overwriteSections)
727145449b1SDimitry Andric     if (osd->osec.partition == 1 && osd->osec.sectionIndex == UINT32_MAX)
728145449b1SDimitry Andric       sectionCommands.push_back(osd);
729d2bd9e70SDimitry Andric }
730d2bd9e70SDimitry Andric 
processSymbolAssignments()731d2bd9e70SDimitry Andric void LinkerScript::processSymbolAssignments() {
732d2bd9e70SDimitry Andric   // Dot outside an output section still represents a relative address, whose
733d2bd9e70SDimitry Andric   // sh_shndx should not be SHN_UNDEF or SHN_ABS. Create a dummy aether section
734d2bd9e70SDimitry Andric   // that fills the void outside a section. It has an index of one, which is
735d2bd9e70SDimitry Andric   // indistinguishable from any other regular section index.
736d2bd9e70SDimitry Andric   aether = make<OutputSection>("", 0, SHF_ALLOC);
737d2bd9e70SDimitry Andric   aether->sectionIndex = 1;
738d2bd9e70SDimitry Andric 
739e3b55780SDimitry Andric   // `st` captures the local AddressState and makes it accessible deliberately.
740d2bd9e70SDimitry Andric   // This is needed as there are some cases where we cannot just thread the
741d2bd9e70SDimitry Andric   // current state through to a lambda function created by the script parser.
742e3b55780SDimitry Andric   AddressState st;
743e3b55780SDimitry Andric   state = &st;
744e3b55780SDimitry Andric   st.outSec = aether;
745d2bd9e70SDimitry Andric 
746f65dcba8SDimitry Andric   for (SectionCommand *cmd : sectionCommands) {
747f65dcba8SDimitry Andric     if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
748f65dcba8SDimitry Andric       addSymbol(assign);
749d2bd9e70SDimitry Andric     else
750145449b1SDimitry Andric       for (SectionCommand *subCmd : cast<OutputDesc>(cmd)->osec.commands)
751f65dcba8SDimitry Andric         if (auto *assign = dyn_cast<SymbolAssignment>(subCmd))
752f65dcba8SDimitry Andric           addSymbol(assign);
753d2bd9e70SDimitry Andric   }
754d2bd9e70SDimitry Andric 
755e3b55780SDimitry Andric   state = nullptr;
756d93e1dfaSDimitry Andric }
757d93e1dfaSDimitry Andric 
findByName(ArrayRef<SectionCommand * > vec,StringRef name)758f65dcba8SDimitry Andric static OutputSection *findByName(ArrayRef<SectionCommand *> vec,
759f1e1c239SDimitry Andric                                  StringRef name) {
760f65dcba8SDimitry Andric   for (SectionCommand *cmd : vec)
761145449b1SDimitry Andric     if (auto *osd = dyn_cast<OutputDesc>(cmd))
762145449b1SDimitry Andric       if (osd->osec.name == name)
763145449b1SDimitry Andric         return &osd->osec;
764eb1ff93dSDimitry Andric   return nullptr;
765be08ec96SDimitry Andric }
766eb1ff93dSDimitry Andric 
createSection(InputSectionBase * isec,StringRef outsecName)767145449b1SDimitry Andric static OutputDesc *createSection(InputSectionBase *isec, StringRef outsecName) {
768145449b1SDimitry Andric   OutputDesc *osd = script->createOutputSection(outsecName, "<internal>");
769145449b1SDimitry Andric   osd->osec.recordSection(isec);
770145449b1SDimitry Andric   return osd;
771be08ec96SDimitry Andric }
772eb1ff93dSDimitry Andric 
addInputSec(StringMap<TinyPtrVector<OutputSection * >> & map,InputSectionBase * isec,StringRef outsecName)773145449b1SDimitry Andric static OutputDesc *addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map,
774f1e1c239SDimitry Andric                                InputSectionBase *isec, StringRef outsecName) {
775eb1ff93dSDimitry Andric   // Sections with SHT_GROUP or SHF_GROUP attributes reach here only when the -r
776eb1ff93dSDimitry Andric   // option is given. A section with SHT_GROUP defines a "section group", and
777eb1ff93dSDimitry Andric   // its members have SHF_GROUP attribute. Usually these flags have already been
778eb1ff93dSDimitry Andric   // stripped by InputFiles.cpp as section groups are processed and uniquified.
779eb1ff93dSDimitry Andric   // However, for the -r option, we want to pass through all section groups
780eb1ff93dSDimitry Andric   // as-is because adding/removing members or merging them with other groups
781eb1ff93dSDimitry Andric   // change their semantics.
782f1e1c239SDimitry Andric   if (isec->type == SHT_GROUP || (isec->flags & SHF_GROUP))
783f1e1c239SDimitry Andric     return createSection(isec, outsecName);
784eb1ff93dSDimitry Andric 
785eb1ff93dSDimitry Andric   // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
786eb1ff93dSDimitry Andric   // relocation sections .rela.foo and .rela.bar for example. Most tools do
787eb1ff93dSDimitry Andric   // not allow multiple REL[A] sections for output section. Hence we
788eb1ff93dSDimitry Andric   // should combine these relocation sections into single output.
789eb1ff93dSDimitry Andric   // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
790eb1ff93dSDimitry Andric   // other REL[A] sections created by linker itself.
791ac9a064cSDimitry Andric   if (!isa<SyntheticSection>(isec) && isStaticRelSecType(isec->type)) {
792f1e1c239SDimitry Andric     auto *sec = cast<InputSection>(isec);
793f1e1c239SDimitry Andric     OutputSection *out = sec->getRelocatedSection()->getOutputSection();
794eb1ff93dSDimitry Andric 
795ac9a064cSDimitry Andric     if (auto *relSec = out->relocationSection) {
796ac9a064cSDimitry Andric       relSec->recordSection(sec);
797eb1ff93dSDimitry Andric       return nullptr;
798be08ec96SDimitry Andric     }
799eb1ff93dSDimitry Andric 
800145449b1SDimitry Andric     OutputDesc *osd = createSection(isec, outsecName);
801145449b1SDimitry Andric     out->relocationSection = &osd->osec;
802145449b1SDimitry Andric     return osd;
803eb1ff93dSDimitry Andric   }
804eb1ff93dSDimitry Andric 
805eb1ff93dSDimitry Andric   //  The ELF spec just says
806eb1ff93dSDimitry Andric   // ----------------------------------------------------------------
807eb1ff93dSDimitry Andric   // In the first phase, input sections that match in name, type and
808eb1ff93dSDimitry Andric   // attribute flags should be concatenated into single sections.
809eb1ff93dSDimitry Andric   // ----------------------------------------------------------------
810eb1ff93dSDimitry Andric   //
811eb1ff93dSDimitry Andric   // However, it is clear that at least some flags have to be ignored for
812eb1ff93dSDimitry Andric   // section merging. At the very least SHF_GROUP and SHF_COMPRESSED have to be
813eb1ff93dSDimitry Andric   // ignored. We should not have two output .text sections just because one was
814eb1ff93dSDimitry Andric   // in a group and another was not for example.
815eb1ff93dSDimitry Andric   //
81620d35e67SDimitry Andric   // It also seems that wording was a late addition and didn't get the
817eb1ff93dSDimitry Andric   // necessary scrutiny.
818eb1ff93dSDimitry Andric   //
819eb1ff93dSDimitry Andric   // Merging sections with different flags is expected by some users. One
820eb1ff93dSDimitry Andric   // reason is that if one file has
821eb1ff93dSDimitry Andric   //
822eb1ff93dSDimitry Andric   // int *const bar __attribute__((section(".foo"))) = (int *)0;
823eb1ff93dSDimitry Andric   //
824eb1ff93dSDimitry Andric   // gcc with -fPIC will produce a read only .foo section. But if another
825eb1ff93dSDimitry Andric   // file has
826eb1ff93dSDimitry Andric   //
827eb1ff93dSDimitry Andric   // int zed;
828eb1ff93dSDimitry Andric   // int *const bar __attribute__((section(".foo"))) = (int *)&zed;
829eb1ff93dSDimitry Andric   //
830eb1ff93dSDimitry Andric   // gcc with -fPIC will produce a read write section.
831eb1ff93dSDimitry Andric   //
832eb1ff93dSDimitry Andric   // Last but not least, when using linker script the merge rules are forced by
833eb1ff93dSDimitry Andric   // the script. Unfortunately, linker scripts are name based. This means that
834eb1ff93dSDimitry Andric   // expressions like *(.foo*) can refer to multiple input sections with
835eb1ff93dSDimitry Andric   // different flags. We cannot put them in different output sections or we
836eb1ff93dSDimitry Andric   // would produce wrong results for
837eb1ff93dSDimitry Andric   //
838eb1ff93dSDimitry Andric   // start = .; *(.foo.*) end = .; *(.bar)
839eb1ff93dSDimitry Andric   //
840eb1ff93dSDimitry Andric   // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to
841eb1ff93dSDimitry Andric   // another. The problem is that there is no way to layout those output
842eb1ff93dSDimitry Andric   // sections such that the .foo sections are the only thing between the start
843eb1ff93dSDimitry Andric   // and end symbols.
844eb1ff93dSDimitry Andric   //
845eb1ff93dSDimitry Andric   // Given the above issues, we instead merge sections by name and error on
846eb1ff93dSDimitry Andric   // incompatible types and flags.
847f1e1c239SDimitry Andric   TinyPtrVector<OutputSection *> &v = map[outsecName];
848f1e1c239SDimitry Andric   for (OutputSection *sec : v) {
849f1e1c239SDimitry Andric     if (sec->partition != isec->partition)
850f1e1c239SDimitry Andric       continue;
851d2bd9e70SDimitry Andric 
852d2bd9e70SDimitry Andric     if (config->relocatable && (isec->flags & SHF_LINK_ORDER)) {
853d2bd9e70SDimitry Andric       // Merging two SHF_LINK_ORDER sections with different sh_link fields will
854d2bd9e70SDimitry Andric       // change their semantics, so we only merge them in -r links if they will
855d2bd9e70SDimitry Andric       // end up being linked to the same output section. The casts are fine
856d2bd9e70SDimitry Andric       // because everything in the map was created by the orphan placement code.
857d2bd9e70SDimitry Andric       auto *firstIsec = cast<InputSectionBase>(
858f65dcba8SDimitry Andric           cast<InputSectionDescription>(sec->commands[0])->sectionBases[0]);
859b60736ecSDimitry Andric       OutputSection *firstIsecOut =
860ac9a064cSDimitry Andric           (firstIsec->flags & SHF_LINK_ORDER)
861b60736ecSDimitry Andric               ? firstIsec->getLinkOrderDep()->getOutputSection()
862b60736ecSDimitry Andric               : nullptr;
863b60736ecSDimitry Andric       if (firstIsecOut != isec->getLinkOrderDep()->getOutputSection())
864d2bd9e70SDimitry Andric         continue;
865d2bd9e70SDimitry Andric     }
866d2bd9e70SDimitry Andric 
867d2bd9e70SDimitry Andric     sec->recordSection(isec);
868eb1ff93dSDimitry Andric     return nullptr;
869eb1ff93dSDimitry Andric   }
870eb1ff93dSDimitry Andric 
871145449b1SDimitry Andric   OutputDesc *osd = createSection(isec, outsecName);
872145449b1SDimitry Andric   v.push_back(&osd->osec);
873145449b1SDimitry Andric   return osd;
874be08ec96SDimitry Andric }
875be08ec96SDimitry Andric 
876d93e1dfaSDimitry Andric // Add sections that didn't match any sections command.
addOrphanSections()877eb1ff93dSDimitry Andric void LinkerScript::addOrphanSections() {
878f1e1c239SDimitry Andric   StringMap<TinyPtrVector<OutputSection *>> map;
879145449b1SDimitry Andric   SmallVector<OutputDesc *, 0> v;
88020d35e67SDimitry Andric 
8816f8fc217SDimitry Andric   auto add = [&](InputSectionBase *s) {
882d2bd9e70SDimitry Andric     if (s->isLive() && !s->parent) {
883cfca06d7SDimitry Andric       orphanSections.push_back(s);
884cfca06d7SDimitry Andric 
885f1e1c239SDimitry Andric       StringRef name = getOutputSectionName(s);
886cfca06d7SDimitry Andric       if (config->unique) {
887cfca06d7SDimitry Andric         v.push_back(createSection(s, name));
888cfca06d7SDimitry Andric       } else if (OutputSection *sec = findByName(sectionCommands, name)) {
889d2bd9e70SDimitry Andric         sec->recordSection(s);
890d2bd9e70SDimitry Andric       } else {
891145449b1SDimitry Andric         if (OutputDesc *osd = addInputSec(map, s, name))
892145449b1SDimitry Andric           v.push_back(osd);
893d2bd9e70SDimitry Andric         assert(isa<MergeInputSection>(s) ||
894d2bd9e70SDimitry Andric                s->getOutputSection()->sectionIndex == UINT32_MAX);
895d2bd9e70SDimitry Andric       }
896d2bd9e70SDimitry Andric     }
89720d35e67SDimitry Andric   };
89820d35e67SDimitry Andric 
899344a3780SDimitry Andric   // For further --emit-reloc handling code we need target output section
90020d35e67SDimitry Andric   // to be created before we create relocation output section, so we want
90120d35e67SDimitry Andric   // to create target sections first. We do not want priority handling
90220d35e67SDimitry Andric   // for synthetic sections because them are special.
903e3b55780SDimitry Andric   size_t n = 0;
904e3b55780SDimitry Andric   for (InputSectionBase *isec : ctx.inputSections) {
905e3b55780SDimitry Andric     // Process InputSection and MergeInputSection.
906e3b55780SDimitry Andric     if (LLVM_LIKELY(isa<InputSection>(isec)))
907e3b55780SDimitry Andric       ctx.inputSections[n++] = isec;
908e3b55780SDimitry Andric 
909d2bd9e70SDimitry Andric     // In -r links, SHF_LINK_ORDER sections are added while adding their parent
910d2bd9e70SDimitry Andric     // sections because we need to know the parent's output section before we
911d2bd9e70SDimitry Andric     // can select an output section for the SHF_LINK_ORDER section.
912d2bd9e70SDimitry Andric     if (config->relocatable && (isec->flags & SHF_LINK_ORDER))
913d2bd9e70SDimitry Andric       continue;
914d2bd9e70SDimitry Andric 
915f1e1c239SDimitry Andric     if (auto *sec = dyn_cast<InputSection>(isec))
916f1e1c239SDimitry Andric       if (InputSectionBase *rel = sec->getRelocatedSection())
917f1e1c239SDimitry Andric         if (auto *relIS = dyn_cast_or_null<InputSectionBase>(rel->parent))
918f1e1c239SDimitry Andric           add(relIS);
919f1e1c239SDimitry Andric     add(isec);
9206f8fc217SDimitry Andric     if (config->relocatable)
9216f8fc217SDimitry Andric       for (InputSectionBase *depSec : isec->dependentSections)
9226f8fc217SDimitry Andric         if (depSec->flags & SHF_LINK_ORDER)
9236f8fc217SDimitry Andric           add(depSec);
924eb1ff93dSDimitry Andric   }
925e3b55780SDimitry Andric   // Keep just InputSection.
926e3b55780SDimitry Andric   ctx.inputSections.resize(n);
927eb1ff93dSDimitry Andric 
928eb1ff93dSDimitry Andric   // If no SECTIONS command was given, we should insert sections commands
929eb1ff93dSDimitry Andric   // before others, so that we can handle scripts which refers them,
930eb1ff93dSDimitry Andric   // for example: "foo = ABSOLUTE(ADDR(.text)));".
931eb1ff93dSDimitry Andric   // When SECTIONS command is present we just add all orphans to the end.
932f1e1c239SDimitry Andric   if (hasSectionsCommand)
933f1e1c239SDimitry Andric     sectionCommands.insert(sectionCommands.end(), v.begin(), v.end());
934eb1ff93dSDimitry Andric   else
935f1e1c239SDimitry Andric     sectionCommands.insert(sectionCommands.begin(), v.begin(), v.end());
936eb1ff93dSDimitry Andric }
937eb1ff93dSDimitry Andric 
diagnoseOrphanHandling() const938cfca06d7SDimitry Andric void LinkerScript::diagnoseOrphanHandling() const {
939b60736ecSDimitry Andric   llvm::TimeTraceScope timeScope("Diagnose orphan sections");
940ac9a064cSDimitry Andric   if (config->orphanHandling == OrphanHandlingPolicy::Place ||
941ac9a064cSDimitry Andric       !hasSectionsCommand)
942b60736ecSDimitry Andric     return;
943cfca06d7SDimitry Andric   for (const InputSectionBase *sec : orphanSections) {
944b1c73532SDimitry Andric     // .relro_padding is inserted before DATA_SEGMENT_RELRO_END, if present,
945b1c73532SDimitry Andric     // automatically. The section is not supposed to be specified by scripts.
946b1c73532SDimitry Andric     if (sec == in.relroPadding.get())
947b1c73532SDimitry Andric       continue;
948cfca06d7SDimitry Andric     // Input SHT_REL[A] retained by --emit-relocs are ignored by
949cfca06d7SDimitry Andric     // computeInputSections(). Don't warn/error.
950cfca06d7SDimitry Andric     if (isa<InputSection>(sec) &&
951cfca06d7SDimitry Andric         cast<InputSection>(sec)->getRelocatedSection())
952cfca06d7SDimitry Andric       continue;
953cfca06d7SDimitry Andric 
954cfca06d7SDimitry Andric     StringRef name = getOutputSectionName(sec);
955cfca06d7SDimitry Andric     if (config->orphanHandling == OrphanHandlingPolicy::Error)
956cfca06d7SDimitry Andric       error(toString(sec) + " is being placed in '" + name + "'");
957b60736ecSDimitry Andric     else
958cfca06d7SDimitry Andric       warn(toString(sec) + " is being placed in '" + name + "'");
959cfca06d7SDimitry Andric   }
960cfca06d7SDimitry Andric }
961cfca06d7SDimitry Andric 
diagnoseMissingSGSectionAddress() const9627fa27ce4SDimitry Andric void LinkerScript::diagnoseMissingSGSectionAddress() const {
9637fa27ce4SDimitry Andric   if (!config->cmseImplib || !in.armCmseSGSection->isNeeded())
9647fa27ce4SDimitry Andric     return;
9657fa27ce4SDimitry Andric 
9667fa27ce4SDimitry Andric   OutputSection *sec = findByName(sectionCommands, ".gnu.sgstubs");
9677fa27ce4SDimitry Andric   if (sec && !sec->addrExpr && !config->sectionStartMap.count(".gnu.sgstubs"))
9687fa27ce4SDimitry Andric     error("no address assigned to the veneers output section " + sec->name);
9697fa27ce4SDimitry Andric }
9707fa27ce4SDimitry Andric 
971d2d3ebb8SDimitry Andric // This function searches for a memory region to place the given output
972d2d3ebb8SDimitry Andric // section in. If found, a pointer to the appropriate memory region is
973c0981da4SDimitry Andric // returned in the first member of the pair. Otherwise, a nullptr is returned.
974c0981da4SDimitry Andric // The second member of the pair is a hint that should be passed to the
975c0981da4SDimitry Andric // subsequent call of this method.
976c0981da4SDimitry Andric std::pair<MemoryRegion *, MemoryRegion *>
findMemoryRegion(OutputSection * sec,MemoryRegion * hint)977c0981da4SDimitry Andric LinkerScript::findMemoryRegion(OutputSection *sec, MemoryRegion *hint) {
978c0981da4SDimitry Andric   // Non-allocatable sections are not part of the process image.
979c0981da4SDimitry Andric   if (!(sec->flags & SHF_ALLOC)) {
9807fa27ce4SDimitry Andric     bool hasInputOrByteCommand =
9817fa27ce4SDimitry Andric         sec->hasInputSections ||
9827fa27ce4SDimitry Andric         llvm::any_of(sec->commands, [](SectionCommand *comm) {
9837fa27ce4SDimitry Andric           return ByteCommand::classof(comm);
9847fa27ce4SDimitry Andric         });
9857fa27ce4SDimitry Andric     if (!sec->memoryRegionName.empty() && hasInputOrByteCommand)
986c0981da4SDimitry Andric       warn("ignoring memory region assignment for non-allocatable section '" +
987c0981da4SDimitry Andric            sec->name + "'");
988c0981da4SDimitry Andric     return {nullptr, nullptr};
989c0981da4SDimitry Andric   }
990c0981da4SDimitry Andric 
991d2d3ebb8SDimitry Andric   // If a memory region name was specified in the output section command,
992d2d3ebb8SDimitry Andric   // then try to find that region first.
993f1e1c239SDimitry Andric   if (!sec->memoryRegionName.empty()) {
994f1e1c239SDimitry Andric     if (MemoryRegion *m = memoryRegions.lookup(sec->memoryRegionName))
995c0981da4SDimitry Andric       return {m, m};
996f1e1c239SDimitry Andric     error("memory region '" + sec->memoryRegionName + "' not declared");
997c0981da4SDimitry Andric     return {nullptr, nullptr};
998d2d3ebb8SDimitry Andric   }
999d2d3ebb8SDimitry Andric 
1000d2d3ebb8SDimitry Andric   // If at least one memory region is defined, all sections must
1001d2d3ebb8SDimitry Andric   // belong to some memory region. Otherwise, we don't need to do
1002d2d3ebb8SDimitry Andric   // anything for memory regions.
1003f1e1c239SDimitry Andric   if (memoryRegions.empty())
1004c0981da4SDimitry Andric     return {nullptr, nullptr};
1005c0981da4SDimitry Andric 
1006c0981da4SDimitry Andric   // An orphan section should continue the previous memory region.
1007c0981da4SDimitry Andric   if (sec->sectionIndex == UINT32_MAX && hint)
1008c0981da4SDimitry Andric     return {hint, hint};
1009d2d3ebb8SDimitry Andric 
1010d2d3ebb8SDimitry Andric   // See if a region can be found by matching section flags.
1011f1e1c239SDimitry Andric   for (auto &pair : memoryRegions) {
1012f1e1c239SDimitry Andric     MemoryRegion *m = pair.second;
1013f65dcba8SDimitry Andric     if (m->compatibleWith(sec->flags))
1014c0981da4SDimitry Andric       return {m, nullptr};
1015d2d3ebb8SDimitry Andric   }
1016d2d3ebb8SDimitry Andric 
1017d2d3ebb8SDimitry Andric   // Otherwise, no suitable region was found.
1018f1e1c239SDimitry Andric   error("no memory region specified for section '" + sec->name + "'");
1019c0981da4SDimitry Andric   return {nullptr, nullptr};
1020d93e1dfaSDimitry Andric }
1021d93e1dfaSDimitry Andric 
findFirstSection(PhdrEntry * load)1022f1e1c239SDimitry Andric static OutputSection *findFirstSection(PhdrEntry *load) {
1023f1e1c239SDimitry Andric   for (OutputSection *sec : outputSections)
1024f1e1c239SDimitry Andric     if (sec->ptLoad == load)
1025f1e1c239SDimitry Andric       return sec;
1026e2fd426bSDimitry Andric   return nullptr;
1027e2fd426bSDimitry Andric }
1028e2fd426bSDimitry Andric 
1029ac9a064cSDimitry Andric // Assign addresses to an output section and offsets to its input sections and
1030ac9a064cSDimitry Andric // symbol assignments. Return true if the output section's address has changed.
assignOffsets(OutputSection * sec)1031ac9a064cSDimitry Andric bool LinkerScript::assignOffsets(OutputSection *sec) {
1032c0981da4SDimitry Andric   const bool isTbss = (sec->flags & SHF_TLS) && sec->type == SHT_NOBITS;
1033e3b55780SDimitry Andric   const bool sameMemRegion = state->memRegion == sec->memRegion;
1034e3b55780SDimitry Andric   const bool prevLMARegionIsDefault = state->lmaRegion == nullptr;
1035b60736ecSDimitry Andric   const uint64_t savedDot = dot;
1036ac9a064cSDimitry Andric   bool addressChanged = false;
1037e3b55780SDimitry Andric   state->memRegion = sec->memRegion;
1038e3b55780SDimitry Andric   state->lmaRegion = sec->lmaRegion;
1039b60736ecSDimitry Andric 
1040c0981da4SDimitry Andric   if (!(sec->flags & SHF_ALLOC)) {
1041c0981da4SDimitry Andric     // Non-SHF_ALLOC sections have zero addresses.
1042c0981da4SDimitry Andric     dot = 0;
1043c0981da4SDimitry Andric   } else if (isTbss) {
1044c0981da4SDimitry Andric     // Allow consecutive SHF_TLS SHT_NOBITS output sections. The address range
1045c0981da4SDimitry Andric     // starts from the end address of the previous tbss section.
1046e3b55780SDimitry Andric     if (state->tbssAddr == 0)
1047e3b55780SDimitry Andric       state->tbssAddr = dot;
1048c0981da4SDimitry Andric     else
1049e3b55780SDimitry Andric       dot = state->tbssAddr;
1050c0981da4SDimitry Andric   } else {
1051e3b55780SDimitry Andric     if (state->memRegion)
1052e3b55780SDimitry Andric       dot = state->memRegion->curPos;
1053b60736ecSDimitry Andric     if (sec->addrExpr)
1054f1e1c239SDimitry Andric       setDot(sec->addrExpr, sec->location, false);
1055d2d3ebb8SDimitry Andric 
1056d2bd9e70SDimitry Andric     // If the address of the section has been moved forward by an explicit
1057d2bd9e70SDimitry Andric     // expression so that it now starts past the current curPos of the enclosing
1058d2bd9e70SDimitry Andric     // region, we need to expand the current region to account for the space
1059d2bd9e70SDimitry Andric     // between the previous section, if any, and the start of this section.
1060e3b55780SDimitry Andric     if (state->memRegion && state->memRegion->curPos < dot)
1061e3b55780SDimitry Andric       expandMemoryRegion(state->memRegion, dot - state->memRegion->curPos,
1062f65dcba8SDimitry Andric                          sec->name);
1063b60736ecSDimitry Andric   }
1064d2bd9e70SDimitry Andric 
1065e3b55780SDimitry Andric   state->outSec = sec;
1066ac9a064cSDimitry Andric   if (!(sec->addrExpr && script->hasSectionsCommand)) {
1067ac9a064cSDimitry Andric     // ALIGN is respected. sec->alignment is the max of ALIGN and the maximum of
1068ac9a064cSDimitry Andric     // input section alignments.
1069f65dcba8SDimitry Andric     const uint64_t pos = dot;
1070e3b55780SDimitry Andric     dot = alignToPowerOf2(dot, sec->addralign);
1071f65dcba8SDimitry Andric     expandMemoryRegions(dot - pos);
1072f65dcba8SDimitry Andric   }
1073ac9a064cSDimitry Andric   addressChanged = sec->addr != dot;
1074ac9a064cSDimitry Andric   sec->addr = dot;
1075fbe69f78SDimitry Andric 
1076e3b55780SDimitry Andric   // state->lmaOffset is LMA minus VMA. If LMA is explicitly specified via AT()
1077e3b55780SDimitry Andric   // or AT>, recompute state->lmaOffset; otherwise, if both previous/current LMA
1078cfca06d7SDimitry Andric   // region is the default, and the two sections are in the same memory region,
1079cfca06d7SDimitry Andric   // reuse previous lmaOffset; otherwise, reset lmaOffset to 0. This emulates
1080cfca06d7SDimitry Andric   // heuristics described in
1081cfca06d7SDimitry Andric   // https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html
1082c0981da4SDimitry Andric   if (sec->lmaExpr) {
1083e3b55780SDimitry Andric     state->lmaOffset = sec->lmaExpr().getValue() - dot;
1084c0981da4SDimitry Andric   } else if (MemoryRegion *mr = sec->lmaRegion) {
1085e3b55780SDimitry Andric     uint64_t lmaStart = alignToPowerOf2(mr->curPos, sec->addralign);
1086c0981da4SDimitry Andric     if (mr->curPos < lmaStart)
1087f65dcba8SDimitry Andric       expandMemoryRegion(mr, lmaStart - mr->curPos, sec->name);
1088e3b55780SDimitry Andric     state->lmaOffset = lmaStart - dot;
1089c0981da4SDimitry Andric   } else if (!sameMemRegion || !prevLMARegionIsDefault) {
1090e3b55780SDimitry Andric     state->lmaOffset = 0;
1091c0981da4SDimitry Andric   }
1092f1e1c239SDimitry Andric 
1093e3b55780SDimitry Andric   // Propagate state->lmaOffset to the first "non-header" section.
1094f65dcba8SDimitry Andric   if (PhdrEntry *l = sec->ptLoad)
1095f1e1c239SDimitry Andric     if (sec == findFirstSection(l))
1096e3b55780SDimitry Andric       l->lmaOffset = state->lmaOffset;
109720d35e67SDimitry Andric 
109820d35e67SDimitry Andric   // We can call this method multiple times during the creation of
109920d35e67SDimitry Andric   // thunks and want to start over calculation each time.
1100f1e1c239SDimitry Andric   sec->size = 0;
1101eb1ff93dSDimitry Andric 
1102eb1ff93dSDimitry Andric   // We visited SectionsCommands from processSectionCommands to
1103eb1ff93dSDimitry Andric   // layout sections. Now, we visit SectionsCommands again to fix
1104eb1ff93dSDimitry Andric   // section offsets.
1105f65dcba8SDimitry Andric   for (SectionCommand *cmd : sec->commands) {
1106eb1ff93dSDimitry Andric     // This handles the assignments to symbol or to the dot.
1107f65dcba8SDimitry Andric     if (auto *assign = dyn_cast<SymbolAssignment>(cmd)) {
1108f65dcba8SDimitry Andric       assign->addr = dot;
1109f65dcba8SDimitry Andric       assignSymbol(assign, true);
1110f65dcba8SDimitry Andric       assign->size = dot - assign->addr;
1111eb1ff93dSDimitry Andric       continue;
1112eb1ff93dSDimitry Andric     }
1113eb1ff93dSDimitry Andric 
1114eb1ff93dSDimitry Andric     // Handle BYTE(), SHORT(), LONG(), or QUAD().
1115f65dcba8SDimitry Andric     if (auto *data = dyn_cast<ByteCommand>(cmd)) {
1116f65dcba8SDimitry Andric       data->offset = dot - sec->addr;
1117f65dcba8SDimitry Andric       dot += data->size;
1118f65dcba8SDimitry Andric       expandOutputSection(data->size);
1119eb1ff93dSDimitry Andric       continue;
1120eb1ff93dSDimitry Andric     }
1121eb1ff93dSDimitry Andric 
1122eb1ff93dSDimitry Andric     // Handle a single input section description command.
1123eb1ff93dSDimitry Andric     // It calculates and assigns the offsets for each section and also
1124eb1ff93dSDimitry Andric     // updates the output section size.
1125ac9a064cSDimitry Andric 
1126ac9a064cSDimitry Andric     auto &sections = cast<InputSectionDescription>(cmd)->sections;
1127ac9a064cSDimitry Andric     for (InputSection *isec : sections) {
1128f65dcba8SDimitry Andric       assert(isec->getParent() == sec);
1129ac9a064cSDimitry Andric       if (isa<PotentialSpillSection>(isec))
1130ac9a064cSDimitry Andric         continue;
1131f65dcba8SDimitry Andric       const uint64_t pos = dot;
1132e3b55780SDimitry Andric       dot = alignToPowerOf2(dot, isec->addralign);
1133f65dcba8SDimitry Andric       isec->outSecOff = dot - sec->addr;
1134f65dcba8SDimitry Andric       dot += isec->getSize();
1135f65dcba8SDimitry Andric 
1136f65dcba8SDimitry Andric       // Update output section size after adding each section. This is so that
1137f65dcba8SDimitry Andric       // SIZEOF works correctly in the case below:
1138f65dcba8SDimitry Andric       // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
1139f65dcba8SDimitry Andric       expandOutputSection(dot - pos);
1140f65dcba8SDimitry Andric     }
1141eb1ff93dSDimitry Andric   }
1142b60736ecSDimitry Andric 
1143b1c73532SDimitry Andric   // If .relro_padding is present, round up the end to a common-page-size
1144b1c73532SDimitry Andric   // boundary to protect the last page.
1145b1c73532SDimitry Andric   if (in.relroPadding && sec == in.relroPadding->getParent())
1146b1c73532SDimitry Andric     expandOutputSection(alignToPowerOf2(dot, config->commonPageSize) - dot);
1147b1c73532SDimitry Andric 
1148b60736ecSDimitry Andric   // Non-SHF_ALLOC sections do not affect the addresses of other OutputSections
1149b60736ecSDimitry Andric   // as they are not part of the process image.
1150c0981da4SDimitry Andric   if (!(sec->flags & SHF_ALLOC)) {
1151c0981da4SDimitry Andric     dot = savedDot;
1152c0981da4SDimitry Andric   } else if (isTbss) {
1153c0981da4SDimitry Andric     // NOBITS TLS sections are similar. Additionally save the end address.
1154e3b55780SDimitry Andric     state->tbssAddr = dot;
1155b60736ecSDimitry Andric     dot = savedDot;
1156eb1ff93dSDimitry Andric   }
1157ac9a064cSDimitry Andric   return addressChanged;
1158c0981da4SDimitry Andric }
1159d2d3ebb8SDimitry Andric 
isDiscardable(const OutputSection & sec)1160c0981da4SDimitry Andric static bool isDiscardable(const OutputSection &sec) {
1161f1e1c239SDimitry Andric   if (sec.name == "/DISCARD/")
1162f1e1c239SDimitry Andric     return true;
1163f1e1c239SDimitry Andric 
1164f1e1c239SDimitry Andric   // We do not want to remove OutputSections with expressions that reference
1165f1e1c239SDimitry Andric   // symbols even if the OutputSection is empty. We want to ensure that the
1166f1e1c239SDimitry Andric   // expressions can be evaluated and report an error if they cannot.
1167f1e1c239SDimitry Andric   if (sec.expressionsUseSymbols)
116820d35e67SDimitry Andric     return false;
116920d35e67SDimitry Andric 
1170f1e1c239SDimitry Andric   // OutputSections may be referenced by name in ADDR and LOADADDR expressions,
1171f1e1c239SDimitry Andric   // as an empty Section can has a valid VMA and LMA we keep the OutputSection
1172f1e1c239SDimitry Andric   // to maintain the integrity of the other Expression.
1173f1e1c239SDimitry Andric   if (sec.usedInExpression)
1174f1e1c239SDimitry Andric     return false;
1175f1e1c239SDimitry Andric 
1176f65dcba8SDimitry Andric   for (SectionCommand *cmd : sec.commands) {
1177f65dcba8SDimitry Andric     if (auto assign = dyn_cast<SymbolAssignment>(cmd))
117820d35e67SDimitry Andric       // Don't create empty output sections just for unreferenced PROVIDE
117920d35e67SDimitry Andric       // symbols.
1180f65dcba8SDimitry Andric       if (assign->name != "." && !assign->sym)
118120d35e67SDimitry Andric         continue;
118220d35e67SDimitry Andric 
1183f65dcba8SDimitry Andric     if (!isa<InputSectionDescription>(*cmd))
1184d93e1dfaSDimitry Andric       return false;
118520d35e67SDimitry Andric   }
1186d93e1dfaSDimitry Andric   return true;
1187d93e1dfaSDimitry Andric }
1188d93e1dfaSDimitry Andric 
maybePropagatePhdrs(OutputSection & sec,SmallVector<StringRef,0> & phdrs)1189b60736ecSDimitry Andric static void maybePropagatePhdrs(OutputSection &sec,
11906f8fc217SDimitry Andric                                 SmallVector<StringRef, 0> &phdrs) {
1191b60736ecSDimitry Andric   if (sec.phdrs.empty()) {
1192b60736ecSDimitry Andric     // To match the bfd linker script behaviour, only propagate program
1193b60736ecSDimitry Andric     // headers to sections that are allocated.
1194b60736ecSDimitry Andric     if (sec.flags & SHF_ALLOC)
1195b60736ecSDimitry Andric       sec.phdrs = phdrs;
1196b60736ecSDimitry Andric   } else {
1197b60736ecSDimitry Andric     phdrs = sec.phdrs;
1198b60736ecSDimitry Andric   }
1199b60736ecSDimitry Andric }
1200b60736ecSDimitry Andric 
adjustOutputSections()1201ecbca9f5SDimitry Andric void LinkerScript::adjustOutputSections() {
1202d93e1dfaSDimitry Andric   // If the output section contains only symbol assignments, create a
1203eb1ff93dSDimitry Andric   // corresponding output section. The issue is what to do with linker script
1204eb1ff93dSDimitry Andric   // like ".foo : { symbol = 42; }". One option would be to convert it to
1205eb1ff93dSDimitry Andric   // "symbol = 42;". That is, move the symbol out of the empty section
1206eb1ff93dSDimitry Andric   // description. That seems to be what bfd does for this simple case. The
1207eb1ff93dSDimitry Andric   // problem is that this is not completely general. bfd will give up and
1208eb1ff93dSDimitry Andric   // create a dummy section too if there is a ". = . + 1" inside the section
1209eb1ff93dSDimitry Andric   // for example.
1210eb1ff93dSDimitry Andric   // Given that we want to create the section, we have to worry what impact
1211eb1ff93dSDimitry Andric   // it will have on the link. For example, if we just create a section with
1212eb1ff93dSDimitry Andric   // 0 for flags, it would change which PT_LOADs are created.
121320d35e67SDimitry Andric   // We could remember that particular section is dummy and ignore it in
1214eb1ff93dSDimitry Andric   // other parts of the linker, but unfortunately there are quite a few places
1215eb1ff93dSDimitry Andric   // that would need to change:
1216eb1ff93dSDimitry Andric   //   * The program header creation.
1217eb1ff93dSDimitry Andric   //   * The orphan section placement.
1218eb1ff93dSDimitry Andric   //   * The address assignment.
1219eb1ff93dSDimitry Andric   // The other option is to pick flags that minimize the impact the section
1220eb1ff93dSDimitry Andric   // will have on the rest of the linker. That is why we copy the flags from
1221b1c73532SDimitry Andric   // the previous sections. We copy just SHF_ALLOC and SHF_WRITE to keep the
1222b1c73532SDimitry Andric   // impact low. We do not propagate SHF_EXECINSTR as in some cases this can
1223b1c73532SDimitry Andric   // lead to executable writeable section.
1224f1e1c239SDimitry Andric   uint64_t flags = SHF_ALLOC;
1225fbe69f78SDimitry Andric 
12266f8fc217SDimitry Andric   SmallVector<StringRef, 0> defPhdrs;
1227b1c73532SDimitry Andric   bool seenRelro = false;
1228f65dcba8SDimitry Andric   for (SectionCommand *&cmd : sectionCommands) {
1229145449b1SDimitry Andric     if (!isa<OutputDesc>(cmd))
1230d93e1dfaSDimitry Andric       continue;
1231145449b1SDimitry Andric     auto *sec = &cast<OutputDesc>(cmd)->osec;
123220d35e67SDimitry Andric 
123320d35e67SDimitry Andric     // Handle align (e.g. ".foo : ALIGN(16) { ... }").
1234f1e1c239SDimitry Andric     if (sec->alignExpr)
1235e3b55780SDimitry Andric       sec->addralign =
1236e3b55780SDimitry Andric           std::max<uint32_t>(sec->addralign, sec->alignExpr().getValue());
123720d35e67SDimitry Andric 
1238ecbca9f5SDimitry Andric     bool isEmpty = (getFirstInputSection(sec) == nullptr);
1239ecbca9f5SDimitry Andric     bool discardable = isEmpty && isDiscardable(*sec);
1240ecbca9f5SDimitry Andric     // If sec has at least one input section and not discarded, remember its
1241ecbca9f5SDimitry Andric     // flags to be inherited by subsequent output sections. (sec may contain
1242ecbca9f5SDimitry Andric     // just one empty synthetic section.)
1243ecbca9f5SDimitry Andric     if (sec->hasInputSections && !discardable)
1244f1e1c239SDimitry Andric       flags = sec->flags;
124520d35e67SDimitry Andric 
124620d35e67SDimitry Andric     // We do not want to keep any special flags for output section
124720d35e67SDimitry Andric     // in case it is empty.
1248ac9a064cSDimitry Andric     if (isEmpty) {
1249b1c73532SDimitry Andric       sec->flags =
1250b1c73532SDimitry Andric           flags & ((sec->nonAlloc ? 0 : (uint64_t)SHF_ALLOC) | SHF_WRITE);
1251ac9a064cSDimitry Andric       sec->sortRank = getSectionRank(*sec);
1252ac9a064cSDimitry Andric     }
125320d35e67SDimitry Andric 
1254b60736ecSDimitry Andric     // The code below may remove empty output sections. We should save the
1255b60736ecSDimitry Andric     // specified program headers (if exist) and propagate them to subsequent
1256b60736ecSDimitry Andric     // sections which do not specify program headers.
1257b60736ecSDimitry Andric     // An example of such a linker script is:
1258b60736ecSDimitry Andric     // SECTIONS { .empty : { *(.empty) } :rw
1259b60736ecSDimitry Andric     //            .foo : { *(.foo) } }
1260b60736ecSDimitry Andric     // Note: at this point the order of output sections has not been finalized,
1261b60736ecSDimitry Andric     // because orphans have not been inserted into their expected positions. We
1262b60736ecSDimitry Andric     // will handle them in adjustSectionsAfterSorting().
1263b60736ecSDimitry Andric     if (sec->sectionIndex != UINT32_MAX)
1264b60736ecSDimitry Andric       maybePropagatePhdrs(*sec, defPhdrs);
1265b60736ecSDimitry Andric 
1266b1c73532SDimitry Andric     // Discard .relro_padding if we have not seen one RELRO section. Note: when
1267b1c73532SDimitry Andric     // .tbss is the only RELRO section, there is no associated PT_LOAD segment
1268b1c73532SDimitry Andric     // (needsPtLoad), so we don't append .relro_padding in the case.
1269b1c73532SDimitry Andric     if (in.relroPadding && in.relroPadding->getParent() == sec && !seenRelro)
1270b1c73532SDimitry Andric       discardable = true;
1271ecbca9f5SDimitry Andric     if (discardable) {
1272f1e1c239SDimitry Andric       sec->markDead();
1273f1e1c239SDimitry Andric       cmd = nullptr;
1274b1c73532SDimitry Andric     } else {
1275b1c73532SDimitry Andric       seenRelro |=
1276b1c73532SDimitry Andric           sec->relro && !(sec->type == SHT_NOBITS && (sec->flags & SHF_TLS));
127720d35e67SDimitry Andric     }
1278d93e1dfaSDimitry Andric   }
1279d93e1dfaSDimitry Andric 
128020d35e67SDimitry Andric   // It is common practice to use very generic linker scripts. So for any
128120d35e67SDimitry Andric   // given run some of the output sections in the script will be empty.
128220d35e67SDimitry Andric   // We could create corresponding empty output sections, but that would
128320d35e67SDimitry Andric   // clutter the output.
128420d35e67SDimitry Andric   // We instead remove trivially empty sections. The bfd linker seems even
128520d35e67SDimitry Andric   // more aggressive at removing them.
1286f65dcba8SDimitry Andric   llvm::erase_if(sectionCommands, [&](SectionCommand *cmd) { return !cmd; });
1287d93e1dfaSDimitry Andric }
1288d93e1dfaSDimitry Andric 
adjustSectionsAfterSorting()1289d2d3ebb8SDimitry Andric void LinkerScript::adjustSectionsAfterSorting() {
1290d2d3ebb8SDimitry Andric   // Try and find an appropriate memory region to assign offsets in.
1291c0981da4SDimitry Andric   MemoryRegion *hint = nullptr;
1292f65dcba8SDimitry Andric   for (SectionCommand *cmd : sectionCommands) {
1293145449b1SDimitry Andric     if (auto *osd = dyn_cast<OutputDesc>(cmd)) {
1294145449b1SDimitry Andric       OutputSection *sec = &osd->osec;
1295f1e1c239SDimitry Andric       if (!sec->lmaRegionName.empty()) {
1296f1e1c239SDimitry Andric         if (MemoryRegion *m = memoryRegions.lookup(sec->lmaRegionName))
1297f1e1c239SDimitry Andric           sec->lmaRegion = m;
129820d35e67SDimitry Andric         else
1299f1e1c239SDimitry Andric           error("memory region '" + sec->lmaRegionName + "' not declared");
130020d35e67SDimitry Andric       }
1301c0981da4SDimitry Andric       std::tie(sec->memRegion, hint) = findMemoryRegion(sec, hint);
1302d2d3ebb8SDimitry Andric     }
1303d2d3ebb8SDimitry Andric   }
1304d2d3ebb8SDimitry Andric 
1305d93e1dfaSDimitry Andric   // If output section command doesn't specify any segments,
1306d93e1dfaSDimitry Andric   // and we haven't previously assigned any section to segment,
1307d93e1dfaSDimitry Andric   // then we simply assign section to the very first load segment.
1308d93e1dfaSDimitry Andric   // Below is an example of such linker script:
1309d93e1dfaSDimitry Andric   // PHDRS { seg PT_LOAD; }
1310d93e1dfaSDimitry Andric   // SECTIONS { .aaa : { *(.aaa) } }
13116f8fc217SDimitry Andric   SmallVector<StringRef, 0> defPhdrs;
1312f1e1c239SDimitry Andric   auto firstPtLoad = llvm::find_if(phdrsCommands, [](const PhdrsCommand &cmd) {
1313f1e1c239SDimitry Andric     return cmd.type == PT_LOAD;
131420d35e67SDimitry Andric   });
1315f1e1c239SDimitry Andric   if (firstPtLoad != phdrsCommands.end())
1316f1e1c239SDimitry Andric     defPhdrs.push_back(firstPtLoad->name);
1317d93e1dfaSDimitry Andric 
1318d93e1dfaSDimitry Andric   // Walk the commands and propagate the program headers to commands that don't
1319d93e1dfaSDimitry Andric   // explicitly specify them.
1320f65dcba8SDimitry Andric   for (SectionCommand *cmd : sectionCommands)
1321145449b1SDimitry Andric     if (auto *osd = dyn_cast<OutputDesc>(cmd))
1322145449b1SDimitry Andric       maybePropagatePhdrs(osd->osec, defPhdrs);
132326782977SDimitry Andric }
1324d93e1dfaSDimitry Andric 
computeBase(uint64_t min,bool allocateHeaders)1325f1e1c239SDimitry Andric static uint64_t computeBase(uint64_t min, bool allocateHeaders) {
132620d35e67SDimitry Andric   // If there is no SECTIONS or if the linkerscript is explicit about program
132720d35e67SDimitry Andric   // headers, do our best to allocate them.
1328f1e1c239SDimitry Andric   if (!script->hasSectionsCommand || allocateHeaders)
132920d35e67SDimitry Andric     return 0;
133020d35e67SDimitry Andric   // Otherwise only allocate program headers if that would not add a page.
1331f1e1c239SDimitry Andric   return alignDown(min, config->maxPageSize);
133220d35e67SDimitry Andric }
133320d35e67SDimitry Andric 
1334d2bd9e70SDimitry Andric // When the SECTIONS command is used, try to find an address for the file and
1335d2bd9e70SDimitry Andric // program headers output sections, which can be added to the first PT_LOAD
1336d2bd9e70SDimitry Andric // segment when program headers are created.
1337eb1ff93dSDimitry Andric //
1338d2bd9e70SDimitry Andric // We check if the headers fit below the first allocated section. If there isn't
1339d2bd9e70SDimitry Andric // enough space for these sections, we'll remove them from the PT_LOAD segment,
1340d2bd9e70SDimitry Andric // and we'll also remove the PT_PHDR segment.
allocateHeaders(SmallVector<PhdrEntry *,0> & phdrs)13416f8fc217SDimitry Andric void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
1342f1e1c239SDimitry Andric   uint64_t min = std::numeric_limits<uint64_t>::max();
1343f1e1c239SDimitry Andric   for (OutputSection *sec : outputSections)
1344f1e1c239SDimitry Andric     if (sec->flags & SHF_ALLOC)
1345f1e1c239SDimitry Andric       min = std::min<uint64_t>(min, sec->addr);
134626782977SDimitry Andric 
1347f1e1c239SDimitry Andric   auto it = llvm::find_if(
1348f1e1c239SDimitry Andric       phdrs, [](const PhdrEntry *e) { return e->p_type == PT_LOAD; });
1349f1e1c239SDimitry Andric   if (it == phdrs.end())
135026782977SDimitry Andric     return;
1351f1e1c239SDimitry Andric   PhdrEntry *firstPTLoad = *it;
1352fbe69f78SDimitry Andric 
1353f1e1c239SDimitry Andric   bool hasExplicitHeaders =
1354f1e1c239SDimitry Andric       llvm::any_of(phdrsCommands, [](const PhdrsCommand &cmd) {
1355f1e1c239SDimitry Andric         return cmd.hasPhdrs || cmd.hasFilehdr;
135620d35e67SDimitry Andric       });
1357f1e1c239SDimitry Andric   bool paged = !config->omagic && !config->nmagic;
1358f1e1c239SDimitry Andric   uint64_t headerSize = getHeaderSize();
1359f1e1c239SDimitry Andric   if ((paged || hasExplicitHeaders) &&
1360f1e1c239SDimitry Andric       headerSize <= min - computeBase(min, hasExplicitHeaders)) {
1361f1e1c239SDimitry Andric     min = alignDown(min - headerSize, config->maxPageSize);
1362f1e1c239SDimitry Andric     Out::elfHeader->addr = min;
1363f1e1c239SDimitry Andric     Out::programHeaders->addr = min + Out::elfHeader->size;
136426782977SDimitry Andric     return;
1365fbe69f78SDimitry Andric   }
1366fbe69f78SDimitry Andric 
136720d35e67SDimitry Andric   // Error if we were explicitly asked to allocate headers.
1368f1e1c239SDimitry Andric   if (hasExplicitHeaders)
136920d35e67SDimitry Andric     error("could not allocate headers");
137020d35e67SDimitry Andric 
1371f1e1c239SDimitry Andric   Out::elfHeader->ptLoad = nullptr;
1372f1e1c239SDimitry Andric   Out::programHeaders->ptLoad = nullptr;
1373f1e1c239SDimitry Andric   firstPTLoad->firstSec = findFirstSection(firstPTLoad);
1374eb1ff93dSDimitry Andric 
1375f1e1c239SDimitry Andric   llvm::erase_if(phdrs,
1376f1e1c239SDimitry Andric                  [](const PhdrEntry *e) { return e->p_type == PT_PHDR; });
1377fbe69f78SDimitry Andric }
1378fbe69f78SDimitry Andric 
AddressState()1379eb1ff93dSDimitry Andric LinkerScript::AddressState::AddressState() {
1380f1e1c239SDimitry Andric   for (auto &mri : script->memoryRegions) {
1381f1e1c239SDimitry Andric     MemoryRegion *mr = mri.second;
1382cfca06d7SDimitry Andric     mr->curPos = (mr->origin)().getValue();
138326782977SDimitry Andric   }
138426782977SDimitry Andric }
138526782977SDimitry Andric 
1386eb1ff93dSDimitry Andric // Here we assign addresses as instructed by linker script SECTIONS
1387eb1ff93dSDimitry Andric // sub-commands. Doing that allows us to use final VA values, so here
1388eb1ff93dSDimitry Andric // we also handle rest commands like symbol assignments and ASSERTs.
1389ac9a064cSDimitry Andric // Return an output section that has changed its address or null, and a symbol
1390ac9a064cSDimitry Andric // that has changed its section or value (or nullptr if no symbol has changed).
1391ac9a064cSDimitry Andric std::pair<const OutputSection *, const Defined *>
assignAddresses()1392ac9a064cSDimitry Andric LinkerScript::assignAddresses() {
1393d2bd9e70SDimitry Andric   if (script->hasSectionsCommand) {
1394d2bd9e70SDimitry Andric     // With a linker script, assignment of addresses to headers is covered by
1395d2bd9e70SDimitry Andric     // allocateHeaders().
1396145449b1SDimitry Andric     dot = config->imageBase.value_or(0);
1397d2bd9e70SDimitry Andric   } else {
1398d2bd9e70SDimitry Andric     // Assign addresses to headers right now.
1399d2bd9e70SDimitry Andric     dot = target->getImageBase();
1400d2bd9e70SDimitry Andric     Out::elfHeader->addr = dot;
1401d2bd9e70SDimitry Andric     Out::programHeaders->addr = dot + Out::elfHeader->size;
1402d2bd9e70SDimitry Andric     dot += getHeaderSize();
1403d2bd9e70SDimitry Andric   }
1404eb1ff93dSDimitry Andric 
1405ac9a064cSDimitry Andric   OutputSection *changedOsec = nullptr;
1406e3b55780SDimitry Andric   AddressState st;
1407e3b55780SDimitry Andric   state = &st;
1408f1e1c239SDimitry Andric   errorOnMissingSection = true;
1409e3b55780SDimitry Andric   st.outSec = aether;
1410ac9a064cSDimitry Andric   recordedErrors.clear();
1411d93e1dfaSDimitry Andric 
1412d2bd9e70SDimitry Andric   SymbolAssignmentMap oldValues = getSymbolAssignmentValues(sectionCommands);
1413f65dcba8SDimitry Andric   for (SectionCommand *cmd : sectionCommands) {
1414f65dcba8SDimitry Andric     if (auto *assign = dyn_cast<SymbolAssignment>(cmd)) {
1415f65dcba8SDimitry Andric       assign->addr = dot;
1416f65dcba8SDimitry Andric       assignSymbol(assign, false);
1417f65dcba8SDimitry Andric       assign->size = dot - assign->addr;
14181c986198SDimitry Andric       continue;
14191c986198SDimitry Andric     }
1420ac9a064cSDimitry Andric     if (assignOffsets(&cast<OutputDesc>(cmd)->osec) && !changedOsec)
1421ac9a064cSDimitry Andric       changedOsec = &cast<OutputDesc>(cmd)->osec;
14221c986198SDimitry Andric   }
1423d2bd9e70SDimitry Andric 
1424e3b55780SDimitry Andric   state = nullptr;
1425ac9a064cSDimitry Andric   return {changedOsec, getChangedSymbolAssignment(oldValues)};
1426ac9a064cSDimitry Andric }
1427ac9a064cSDimitry Andric 
hasRegionOverflowed(MemoryRegion * mr)1428ac9a064cSDimitry Andric static bool hasRegionOverflowed(MemoryRegion *mr) {
1429ac9a064cSDimitry Andric   if (!mr)
1430ac9a064cSDimitry Andric     return false;
1431ac9a064cSDimitry Andric   return mr->curPos - mr->getOrigin() > mr->getLength();
1432ac9a064cSDimitry Andric }
1433ac9a064cSDimitry Andric 
1434ac9a064cSDimitry Andric // Spill input sections in reverse order of address assignment to (potentially)
1435ac9a064cSDimitry Andric // bring memory regions out of overflow. The size savings of a spill can only be
1436ac9a064cSDimitry Andric // estimated, since general linker script arithmetic may occur afterwards.
1437ac9a064cSDimitry Andric // Under-estimates may cause unnecessary spills, but over-estimates can always
1438ac9a064cSDimitry Andric // be corrected on the next pass.
spillSections()1439ac9a064cSDimitry Andric bool LinkerScript::spillSections() {
1440ac9a064cSDimitry Andric   if (!config->enableNonContiguousRegions)
1441ac9a064cSDimitry Andric     return false;
1442ac9a064cSDimitry Andric 
1443ac9a064cSDimitry Andric   bool spilled = false;
1444ac9a064cSDimitry Andric   for (SectionCommand *cmd : reverse(sectionCommands)) {
1445ac9a064cSDimitry Andric     auto *od = dyn_cast<OutputDesc>(cmd);
1446ac9a064cSDimitry Andric     if (!od)
1447ac9a064cSDimitry Andric       continue;
1448ac9a064cSDimitry Andric     OutputSection *osec = &od->osec;
1449ac9a064cSDimitry Andric     if (!osec->memRegion)
1450ac9a064cSDimitry Andric       continue;
1451ac9a064cSDimitry Andric 
1452ac9a064cSDimitry Andric     // Input sections that have replaced a potential spill and should be removed
1453ac9a064cSDimitry Andric     // from their input section description.
1454ac9a064cSDimitry Andric     DenseSet<InputSection *> spilledInputSections;
1455ac9a064cSDimitry Andric 
1456ac9a064cSDimitry Andric     for (SectionCommand *cmd : reverse(osec->commands)) {
1457ac9a064cSDimitry Andric       if (!hasRegionOverflowed(osec->memRegion) &&
1458ac9a064cSDimitry Andric           !hasRegionOverflowed(osec->lmaRegion))
1459ac9a064cSDimitry Andric         break;
1460ac9a064cSDimitry Andric 
1461ac9a064cSDimitry Andric       auto *isd = dyn_cast<InputSectionDescription>(cmd);
1462ac9a064cSDimitry Andric       if (!isd)
1463ac9a064cSDimitry Andric         continue;
1464ac9a064cSDimitry Andric       for (InputSection *isec : reverse(isd->sections)) {
1465ac9a064cSDimitry Andric         // Potential spill locations cannot be spilled.
1466ac9a064cSDimitry Andric         if (isa<PotentialSpillSection>(isec))
1467ac9a064cSDimitry Andric           continue;
1468ac9a064cSDimitry Andric 
1469ac9a064cSDimitry Andric         // Find the next potential spill location and remove it from the list.
1470ac9a064cSDimitry Andric         auto it = potentialSpillLists.find(isec);
1471ac9a064cSDimitry Andric         if (it == potentialSpillLists.end())
1472ac9a064cSDimitry Andric           continue;
1473ac9a064cSDimitry Andric         PotentialSpillList &list = it->second;
1474ac9a064cSDimitry Andric         PotentialSpillSection *spill = list.head;
1475ac9a064cSDimitry Andric         if (spill->next)
1476ac9a064cSDimitry Andric           list.head = spill->next;
1477ac9a064cSDimitry Andric         else
1478ac9a064cSDimitry Andric           potentialSpillLists.erase(isec);
1479ac9a064cSDimitry Andric 
1480ac9a064cSDimitry Andric         // Replace the next spill location with the spilled section and adjust
1481ac9a064cSDimitry Andric         // its properties to match the new location. Note that the alignment of
1482ac9a064cSDimitry Andric         // the spill section may have diverged from the original due to e.g. a
1483ac9a064cSDimitry Andric         // SUBALIGN. Correct assignment requires the spill's alignment to be
1484ac9a064cSDimitry Andric         // used, not the original.
1485ac9a064cSDimitry Andric         spilledInputSections.insert(isec);
1486ac9a064cSDimitry Andric         *llvm::find(spill->isd->sections, spill) = isec;
1487ac9a064cSDimitry Andric         isec->parent = spill->parent;
1488ac9a064cSDimitry Andric         isec->addralign = spill->addralign;
1489ac9a064cSDimitry Andric 
1490ac9a064cSDimitry Andric         // Record the (potential) reduction in the region's end position.
1491ac9a064cSDimitry Andric         osec->memRegion->curPos -= isec->getSize();
1492ac9a064cSDimitry Andric         if (osec->lmaRegion)
1493ac9a064cSDimitry Andric           osec->lmaRegion->curPos -= isec->getSize();
1494ac9a064cSDimitry Andric 
1495ac9a064cSDimitry Andric         // Spilling continues until the end position no longer overflows the
1496ac9a064cSDimitry Andric         // region. Then, another round of address assignment will either confirm
1497ac9a064cSDimitry Andric         // the spill's success or lead to yet more spilling.
1498ac9a064cSDimitry Andric         if (!hasRegionOverflowed(osec->memRegion) &&
1499ac9a064cSDimitry Andric             !hasRegionOverflowed(osec->lmaRegion))
1500ac9a064cSDimitry Andric           break;
1501ac9a064cSDimitry Andric       }
1502ac9a064cSDimitry Andric 
1503ac9a064cSDimitry Andric       // Remove any spilled input sections to complete their move.
1504ac9a064cSDimitry Andric       if (!spilledInputSections.empty()) {
1505ac9a064cSDimitry Andric         spilled = true;
1506ac9a064cSDimitry Andric         llvm::erase_if(isd->sections, [&](InputSection *isec) {
1507ac9a064cSDimitry Andric           return spilledInputSections.contains(isec);
1508ac9a064cSDimitry Andric         });
1509ac9a064cSDimitry Andric       }
1510ac9a064cSDimitry Andric     }
1511ac9a064cSDimitry Andric   }
1512ac9a064cSDimitry Andric 
1513ac9a064cSDimitry Andric   return spilled;
1514ac9a064cSDimitry Andric }
1515ac9a064cSDimitry Andric 
1516ac9a064cSDimitry Andric // Erase any potential spill sections that were not used.
erasePotentialSpillSections()1517ac9a064cSDimitry Andric void LinkerScript::erasePotentialSpillSections() {
1518ac9a064cSDimitry Andric   if (potentialSpillLists.empty())
1519ac9a064cSDimitry Andric     return;
1520ac9a064cSDimitry Andric 
1521ac9a064cSDimitry Andric   // Collect the set of input section descriptions that contain potential
1522ac9a064cSDimitry Andric   // spills.
1523ac9a064cSDimitry Andric   DenseSet<InputSectionDescription *> isds;
1524ac9a064cSDimitry Andric   for (const auto &[_, list] : potentialSpillLists)
1525ac9a064cSDimitry Andric     for (PotentialSpillSection *s = list.head; s; s = s->next)
1526ac9a064cSDimitry Andric       isds.insert(s->isd);
1527ac9a064cSDimitry Andric 
1528ac9a064cSDimitry Andric   for (InputSectionDescription *isd : isds)
1529ac9a064cSDimitry Andric     llvm::erase_if(isd->sections, [](InputSection *s) {
1530ac9a064cSDimitry Andric       return isa<PotentialSpillSection>(s);
1531ac9a064cSDimitry Andric     });
1532ac9a064cSDimitry Andric 
1533ac9a064cSDimitry Andric   potentialSpillLists.clear();
1534d93e1dfaSDimitry Andric }
1535d93e1dfaSDimitry Andric 
1536d93e1dfaSDimitry Andric // Creates program headers as instructed by PHDRS linker script command.
createPhdrs()15376f8fc217SDimitry Andric SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
15386f8fc217SDimitry Andric   SmallVector<PhdrEntry *, 0> ret;
1539d93e1dfaSDimitry Andric 
1540d93e1dfaSDimitry Andric   // Process PHDRS and FILEHDR keywords because they are not
1541d93e1dfaSDimitry Andric   // real output sections and cannot be added in the following loop.
1542f1e1c239SDimitry Andric   for (const PhdrsCommand &cmd : phdrsCommands) {
1543145449b1SDimitry Andric     PhdrEntry *phdr = make<PhdrEntry>(cmd.type, cmd.flags.value_or(PF_R));
1544d93e1dfaSDimitry Andric 
1545f1e1c239SDimitry Andric     if (cmd.hasFilehdr)
1546f1e1c239SDimitry Andric       phdr->add(Out::elfHeader);
1547f1e1c239SDimitry Andric     if (cmd.hasPhdrs)
1548f1e1c239SDimitry Andric       phdr->add(Out::programHeaders);
1549d93e1dfaSDimitry Andric 
1550f1e1c239SDimitry Andric     if (cmd.lmaExpr) {
1551f1e1c239SDimitry Andric       phdr->p_paddr = cmd.lmaExpr().getValue();
1552f1e1c239SDimitry Andric       phdr->hasLMA = true;
1553d93e1dfaSDimitry Andric     }
1554f1e1c239SDimitry Andric     ret.push_back(phdr);
1555d93e1dfaSDimitry Andric   }
1556d93e1dfaSDimitry Andric 
1557d93e1dfaSDimitry Andric   // Add output sections to program headers.
1558f1e1c239SDimitry Andric   for (OutputSection *sec : outputSections) {
1559d93e1dfaSDimitry Andric     // Assign headers specified by linker script
1560f1e1c239SDimitry Andric     for (size_t id : getPhdrIndices(sec)) {
1561f1e1c239SDimitry Andric       ret[id]->add(sec);
1562145449b1SDimitry Andric       if (!phdrsCommands[id].flags)
1563f1e1c239SDimitry Andric         ret[id]->p_flags |= sec->getPhdrFlags();
1564d93e1dfaSDimitry Andric     }
1565d93e1dfaSDimitry Andric   }
1566f1e1c239SDimitry Andric   return ret;
1567d93e1dfaSDimitry Andric }
1568d93e1dfaSDimitry Andric 
1569eb1ff93dSDimitry Andric // Returns true if we should emit an .interp section.
1570eb1ff93dSDimitry Andric //
1571eb1ff93dSDimitry Andric // We usually do. But if PHDRS commands are given, and
1572eb1ff93dSDimitry Andric // no PT_INTERP is there, there's no place to emit an
1573eb1ff93dSDimitry Andric // .interp, so we don't do that in that case.
needsInterpSection()1574eb1ff93dSDimitry Andric bool LinkerScript::needsInterpSection() {
1575f1e1c239SDimitry Andric   if (phdrsCommands.empty())
1576eb1ff93dSDimitry Andric     return true;
1577f1e1c239SDimitry Andric   for (PhdrsCommand &cmd : phdrsCommands)
1578f1e1c239SDimitry Andric     if (cmd.type == PT_INTERP)
1579d2d3ebb8SDimitry Andric       return true;
158026782977SDimitry Andric   return false;
158126782977SDimitry Andric }
158226782977SDimitry Andric 
getSymbolValue(StringRef name,const Twine & loc)1583f1e1c239SDimitry Andric ExprValue LinkerScript::getSymbolValue(StringRef name, const Twine &loc) {
1584f1e1c239SDimitry Andric   if (name == ".") {
1585e3b55780SDimitry Andric     if (state)
1586e3b55780SDimitry Andric       return {state->outSec, false, dot - state->outSec->addr, loc};
1587f1e1c239SDimitry Andric     error(loc + ": unable to get location counter value");
1588bef2946cSDimitry Andric     return 0;
15891c986198SDimitry Andric   }
15901c986198SDimitry Andric 
1591e3b55780SDimitry Andric   if (Symbol *sym = symtab.find(name)) {
1592b60736ecSDimitry Andric     if (auto *ds = dyn_cast<Defined>(sym)) {
1593b60736ecSDimitry Andric       ExprValue v{ds->section, false, ds->value, loc};
1594b60736ecSDimitry Andric       // Retain the original st_type, so that the alias will get the same
1595b60736ecSDimitry Andric       // behavior in relocation processing. Any operation will reset st_type to
1596b60736ecSDimitry Andric       // STT_NOTYPE.
1597b60736ecSDimitry Andric       v.type = ds->type;
1598b60736ecSDimitry Andric       return v;
1599b60736ecSDimitry Andric     }
1600f1e1c239SDimitry Andric     if (isa<SharedSymbol>(sym))
1601f1e1c239SDimitry Andric       if (!errorOnMissingSection)
1602f1e1c239SDimitry Andric         return {nullptr, false, 0, loc};
1603d93e1dfaSDimitry Andric   }
1604d93e1dfaSDimitry Andric 
1605f1e1c239SDimitry Andric   error(loc + ": symbol not found: " + name);
1606d93e1dfaSDimitry Andric   return 0;
16071c986198SDimitry Andric }
16081c986198SDimitry Andric 
1609eb1ff93dSDimitry Andric // Returns the index of the segment named Name.
getPhdrIndex(ArrayRef<PhdrsCommand> vec,StringRef name)1610e3b55780SDimitry Andric static std::optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> vec,
1611f1e1c239SDimitry Andric                                           StringRef name) {
1612f1e1c239SDimitry Andric   for (size_t i = 0; i < vec.size(); ++i)
1613f1e1c239SDimitry Andric     if (vec[i].name == name)
1614f1e1c239SDimitry Andric       return i;
1615e3b55780SDimitry Andric   return std::nullopt;
1616eb1ff93dSDimitry Andric }
16174ea16835SDimitry Andric 
1618022ebf5bSDimitry Andric // Returns indices of ELF headers containing specific section. Each index is a
1619022ebf5bSDimitry Andric // zero based number of ELF header listed within PHDRS {} script block.
getPhdrIndices(OutputSection * cmd)16206f8fc217SDimitry Andric SmallVector<size_t, 0> LinkerScript::getPhdrIndices(OutputSection *cmd) {
16216f8fc217SDimitry Andric   SmallVector<size_t, 0> ret;
1622eb1ff93dSDimitry Andric 
1623f1e1c239SDimitry Andric   for (StringRef s : cmd->phdrs) {
1624e3b55780SDimitry Andric     if (std::optional<size_t> idx = getPhdrIndex(phdrsCommands, s))
1625f1e1c239SDimitry Andric       ret.push_back(*idx);
1626f1e1c239SDimitry Andric     else if (s != "NONE")
1627cfca06d7SDimitry Andric       error(cmd->location + ": program header '" + s +
1628eb1ff93dSDimitry Andric             "' is not listed in PHDRS");
16294ea16835SDimitry Andric   }
1630f1e1c239SDimitry Andric   return ret;
1631d93e1dfaSDimitry Andric }
16327fa27ce4SDimitry Andric 
printMemoryUsage(raw_ostream & os)16337fa27ce4SDimitry Andric void LinkerScript::printMemoryUsage(raw_ostream& os) {
16347fa27ce4SDimitry Andric   auto printSize = [&](uint64_t size) {
16357fa27ce4SDimitry Andric     if ((size & 0x3fffffff) == 0)
16367fa27ce4SDimitry Andric       os << format_decimal(size >> 30, 10) << " GB";
16377fa27ce4SDimitry Andric     else if ((size & 0xfffff) == 0)
16387fa27ce4SDimitry Andric       os << format_decimal(size >> 20, 10) << " MB";
16397fa27ce4SDimitry Andric     else if ((size & 0x3ff) == 0)
16407fa27ce4SDimitry Andric       os << format_decimal(size >> 10, 10) << " KB";
16417fa27ce4SDimitry Andric     else
16427fa27ce4SDimitry Andric       os << " " << format_decimal(size, 10) << " B";
16437fa27ce4SDimitry Andric   };
16447fa27ce4SDimitry Andric   os << "Memory region         Used Size  Region Size  %age Used\n";
16457fa27ce4SDimitry Andric   for (auto &pair : memoryRegions) {
16467fa27ce4SDimitry Andric     MemoryRegion *m = pair.second;
16477fa27ce4SDimitry Andric     uint64_t usedLength = m->curPos - m->getOrigin();
16487fa27ce4SDimitry Andric     os << right_justify(m->name, 16) << ": ";
16497fa27ce4SDimitry Andric     printSize(usedLength);
16507fa27ce4SDimitry Andric     uint64_t length = m->getLength();
16517fa27ce4SDimitry Andric     if (length != 0) {
16527fa27ce4SDimitry Andric       printSize(length);
16537fa27ce4SDimitry Andric       double percent = usedLength * 100.0 / length;
16547fa27ce4SDimitry Andric       os << "    " << format("%6.2f%%", percent);
16557fa27ce4SDimitry Andric     }
16567fa27ce4SDimitry Andric     os << '\n';
16577fa27ce4SDimitry Andric   }
16587fa27ce4SDimitry Andric }
16597fa27ce4SDimitry Andric 
recordError(const Twine & msg)1660ac9a064cSDimitry Andric void LinkerScript::recordError(const Twine &msg) {
1661ac9a064cSDimitry Andric   auto &str = recordedErrors.emplace_back();
1662ac9a064cSDimitry Andric   msg.toVector(str);
1663ac9a064cSDimitry Andric }
1664ac9a064cSDimitry Andric 
checkMemoryRegion(const MemoryRegion * region,const OutputSection * osec,uint64_t addr)16657fa27ce4SDimitry Andric static void checkMemoryRegion(const MemoryRegion *region,
16667fa27ce4SDimitry Andric                               const OutputSection *osec, uint64_t addr) {
16677fa27ce4SDimitry Andric   uint64_t osecEnd = addr + osec->size;
16687fa27ce4SDimitry Andric   uint64_t regionEnd = region->getOrigin() + region->getLength();
16697fa27ce4SDimitry Andric   if (osecEnd > regionEnd) {
16707fa27ce4SDimitry Andric     error("section '" + osec->name + "' will not fit in region '" +
16717fa27ce4SDimitry Andric           region->name + "': overflowed by " + Twine(osecEnd - regionEnd) +
16727fa27ce4SDimitry Andric           " bytes");
16737fa27ce4SDimitry Andric   }
16747fa27ce4SDimitry Andric }
16757fa27ce4SDimitry Andric 
checkFinalScriptConditions() const1676b1c73532SDimitry Andric void LinkerScript::checkFinalScriptConditions() const {
1677ac9a064cSDimitry Andric   for (StringRef err : recordedErrors)
1678ac9a064cSDimitry Andric     errorOrWarn(err);
16797fa27ce4SDimitry Andric   for (const OutputSection *sec : outputSections) {
16807fa27ce4SDimitry Andric     if (const MemoryRegion *memoryRegion = sec->memRegion)
16817fa27ce4SDimitry Andric       checkMemoryRegion(memoryRegion, sec, sec->addr);
16827fa27ce4SDimitry Andric     if (const MemoryRegion *lmaRegion = sec->lmaRegion)
16837fa27ce4SDimitry Andric       checkMemoryRegion(lmaRegion, sec, sec->getLMA());
16847fa27ce4SDimitry Andric   }
16857fa27ce4SDimitry Andric }
1686ac9a064cSDimitry Andric 
addScriptReferencedSymbolsToSymTable()1687ac9a064cSDimitry Andric void LinkerScript::addScriptReferencedSymbolsToSymTable() {
1688ac9a064cSDimitry Andric   // Some symbols (such as __ehdr_start) are defined lazily only when there
1689ac9a064cSDimitry Andric   // are undefined symbols for them, so we add these to trigger that logic.
1690ac9a064cSDimitry Andric   auto reference = [](StringRef name) {
1691ac9a064cSDimitry Andric     Symbol *sym = symtab.addUnusedUndefined(name);
1692ac9a064cSDimitry Andric     sym->isUsedInRegularObj = true;
1693ac9a064cSDimitry Andric     sym->referenced = true;
1694ac9a064cSDimitry Andric   };
1695ac9a064cSDimitry Andric   for (StringRef name : referencedSymbols)
1696ac9a064cSDimitry Andric     reference(name);
1697ac9a064cSDimitry Andric 
1698ac9a064cSDimitry Andric   // Keeps track of references from which PROVIDE symbols have been added to the
1699ac9a064cSDimitry Andric   // symbol table.
1700ac9a064cSDimitry Andric   DenseSet<StringRef> added;
1701ac9a064cSDimitry Andric   SmallVector<const SmallVector<StringRef, 0> *, 0> symRefsVec;
1702ac9a064cSDimitry Andric   for (const auto &[name, symRefs] : provideMap)
1703ac9a064cSDimitry Andric     if (LinkerScript::shouldAddProvideSym(name) && added.insert(name).second)
1704ac9a064cSDimitry Andric       symRefsVec.push_back(&symRefs);
1705ac9a064cSDimitry Andric   while (symRefsVec.size()) {
1706ac9a064cSDimitry Andric     for (StringRef name : *symRefsVec.pop_back_val()) {
1707ac9a064cSDimitry Andric       reference(name);
1708ac9a064cSDimitry Andric       // Prevent the symbol from being discarded by --gc-sections.
1709ac9a064cSDimitry Andric       script->referencedSymbols.push_back(name);
1710ac9a064cSDimitry Andric       auto it = script->provideMap.find(name);
1711ac9a064cSDimitry Andric       if (it != script->provideMap.end() &&
1712ac9a064cSDimitry Andric           LinkerScript::shouldAddProvideSym(name) &&
1713ac9a064cSDimitry Andric           added.insert(name).second) {
1714ac9a064cSDimitry Andric         symRefsVec.push_back(&it->second);
1715ac9a064cSDimitry Andric       }
1716ac9a064cSDimitry Andric     }
1717ac9a064cSDimitry Andric   }
1718ac9a064cSDimitry Andric }
1719ac9a064cSDimitry Andric 
shouldAddProvideSym(StringRef symName)1720ac9a064cSDimitry Andric bool LinkerScript::shouldAddProvideSym(StringRef symName) {
1721ac9a064cSDimitry Andric   Symbol *sym = symtab.find(symName);
1722ac9a064cSDimitry Andric   return sym && !sym->isDefined() && !sym->isCommon();
1723ac9a064cSDimitry Andric }
1724