1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===//
2f7c5fbb1SRui Ueyama //
3f7c5fbb1SRui Ueyama //                             The LLVM Linker
4f7c5fbb1SRui Ueyama //
5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source
6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details.
7f7c5fbb1SRui Ueyama //
8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===//
9f7c5fbb1SRui Ueyama //
10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script.
11f7c5fbb1SRui Ueyama //
12f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===//
13f7c5fbb1SRui Ueyama 
14717677afSRui Ueyama #include "LinkerScript.h"
15f7c5fbb1SRui Ueyama #include "Config.h"
161ebc8ed7SRui Ueyama #include "InputSection.h"
179381eb10SRui Ueyama #include "Memory.h"
18652852c5SGeorge Rimar #include "OutputSections.h"
1993c9af42SRui Ueyama #include "Strings.h"
20f7c5fbb1SRui Ueyama #include "SymbolTable.h"
2155518e7dSRui Ueyama #include "Symbols.h"
223fb5a6dcSGeorge Rimar #include "SyntheticSections.h"
2355b169bfSRafael Espindola #include "Target.h"
2455b169bfSRafael Espindola #include "Threads.h"
25bbe38602SEugene Leviant #include "Writer.h"
2622886a28SEugene Zelenko #include "llvm/ADT/STLExtras.h"
2722886a28SEugene Zelenko #include "llvm/ADT/StringRef.h"
2822886a28SEugene Zelenko #include "llvm/Support/Casting.h"
2968880728SRafael Espindola #include "llvm/Support/Compression.h"
30652852c5SGeorge Rimar #include "llvm/Support/ELF.h"
3122886a28SEugene Zelenko #include "llvm/Support/Endian.h"
3222886a28SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
33f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h"
34f03f3cc1SRui Ueyama #include "llvm/Support/Path.h"
3522886a28SEugene Zelenko #include <algorithm>
3622886a28SEugene Zelenko #include <cassert>
3722886a28SEugene Zelenko #include <cstddef>
3822886a28SEugene Zelenko #include <cstdint>
3922886a28SEugene Zelenko #include <iterator>
4022886a28SEugene Zelenko #include <limits>
4122886a28SEugene Zelenko #include <string>
4222886a28SEugene Zelenko #include <vector>
43f7c5fbb1SRui Ueyama 
44f7c5fbb1SRui Ueyama using namespace llvm;
45652852c5SGeorge Rimar using namespace llvm::ELF;
461ebc8ed7SRui Ueyama using namespace llvm::object;
47e38cbab5SGeorge Rimar using namespace llvm::support::endian;
48f7c5fbb1SRui Ueyama using namespace lld;
49e0df00b9SRafael Espindola using namespace lld::elf;
50f7c5fbb1SRui Ueyama 
51a34da938SRui Ueyama LinkerScript *elf::Script;
52a34da938SRui Ueyama 
5372dc195dSRafael Espindola uint64_t ExprValue::getValue() const {
54608cf670SGeorge Rimar   if (Sec) {
55d54c5665SRafael Espindola     if (OutputSection *OS = Sec->getOutputSection())
56d54c5665SRafael Espindola       return alignTo(Sec->getOffset(Val) + OS->Addr, Alignment);
57608cf670SGeorge Rimar     error("unable to evaluate expression: input section " + Sec->Name +
58608cf670SGeorge Rimar           " has no output section assigned");
59608cf670SGeorge Rimar   }
603c6de1a6SPetr Hosek   return alignTo(Val, Alignment);
6172dc195dSRafael Espindola }
6272dc195dSRafael Espindola 
637ba5f47eSRafael Espindola uint64_t ExprValue::getSecAddr() const {
647ba5f47eSRafael Espindola   if (Sec)
657ba5f47eSRafael Espindola     return Sec->getOffset(0) + Sec->getOutputSection()->Addr;
667ba5f47eSRafael Espindola   return 0;
677ba5f47eSRafael Espindola }
687ba5f47eSRafael Espindola 
698f1f3c40SMeador Inge template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
705e51f7d2SPetr Hosek   Symbol *Sym;
713dabfc6bSRafael Espindola   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
725e51f7d2SPetr Hosek   std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
735e51f7d2SPetr Hosek       Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
745e51f7d2SPetr Hosek       /*File*/ nullptr);
755e51f7d2SPetr Hosek   Sym->Binding = STB_GLOBAL;
7672dc195dSRafael Espindola   ExprValue Value = Cmd->Expression();
7772dc195dSRafael Espindola   SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
7801aa795fSGeorge Rimar 
7901aa795fSGeorge Rimar   // We want to set symbol values early if we can. This allows us to use symbols
8001aa795fSGeorge Rimar   // as variables in linker scripts. Doing so allows us to write expressions
8101aa795fSGeorge Rimar   // like this: `alignment = 16; . = ALIGN(., alignment)`
8201aa795fSGeorge Rimar   uint64_t SymValue = Value.isAbsolute() ? Value.getValue() : 0;
8380474a26SRui Ueyama   replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility,
8401aa795fSGeorge Rimar                               STT_NOTYPE, SymValue, 0, Sec, nullptr);
858f1f3c40SMeador Inge   return Sym->body();
86ceabe80eSEugene Leviant }
87ceabe80eSEugene Leviant 
8805c4f67cSRafael Espindola OutputSectionCommand *
8905c4f67cSRafael Espindola LinkerScript::createOutputSectionCommand(StringRef Name, StringRef Location) {
9005c4f67cSRafael Espindola   OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name];
9105c4f67cSRafael Espindola   OutputSectionCommand *Cmd;
9205c4f67cSRafael Espindola   if (CmdRef && CmdRef->Location.empty()) {
9305c4f67cSRafael Espindola     // There was a forward reference.
9405c4f67cSRafael Espindola     Cmd = CmdRef;
9505c4f67cSRafael Espindola   } else {
9605c4f67cSRafael Espindola     Cmd = make<OutputSectionCommand>(Name);
9705c4f67cSRafael Espindola     if (!CmdRef)
9805c4f67cSRafael Espindola       CmdRef = Cmd;
9905c4f67cSRafael Espindola   }
10005c4f67cSRafael Espindola   Cmd->Location = Location;
10105c4f67cSRafael Espindola   return Cmd;
102851dc1e8SGeorge Rimar }
103851dc1e8SGeorge Rimar 
10405c4f67cSRafael Espindola OutputSectionCommand *
10505c4f67cSRafael Espindola LinkerScript::getOrCreateOutputSectionCommand(StringRef Name) {
10605c4f67cSRafael Espindola   OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name];
10705c4f67cSRafael Espindola   if (!CmdRef)
10805c4f67cSRafael Espindola     CmdRef = make<OutputSectionCommand>(Name);
10905c4f67cSRafael Espindola   return CmdRef;
110d83ce1b4SGeorge Rimar }
111d83ce1b4SGeorge Rimar 
112b8dd23f5SRui Ueyama void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
11372dc195dSRafael Espindola   uint64_t Val = E().getValue();
1144cd7352cSRafael Espindola   if (Val < Dot) {
1154cd7352cSRafael Espindola     if (InSec)
1162ee2d2dcSGeorge Rimar       error(Loc + ": unable to move location counter backward for: " +
1172ee2d2dcSGeorge Rimar             CurOutSec->Name);
1184cd7352cSRafael Espindola     else
1192ee2d2dcSGeorge Rimar       error(Loc + ": unable to move location counter backward");
1204cd7352cSRafael Espindola   }
1214cd7352cSRafael Espindola   Dot = Val;
1224cd7352cSRafael Espindola   // Update to location counter means update to section size.
1234cd7352cSRafael Espindola   if (InSec)
1244cd7352cSRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
125679828ffSRafael Espindola }
126679828ffSRafael Espindola 
127679828ffSRafael Espindola // Sets value of a symbol. Two kinds of symbols are processed: synthetic
128679828ffSRafael Espindola // symbols, whose value is an offset from beginning of section and regular
129679828ffSRafael Espindola // symbols whose value is absolute.
130b8dd23f5SRui Ueyama void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
131679828ffSRafael Espindola   if (Cmd->Name == ".") {
1322ee2d2dcSGeorge Rimar     setDot(Cmd->Expression, Cmd->Location, InSec);
1334cd7352cSRafael Espindola     return;
1344cd7352cSRafael Espindola   }
1354cd7352cSRafael Espindola 
136b2b70975SGeorge Rimar   if (!Cmd->Sym)
1378f1f3c40SMeador Inge     return;
1388f1f3c40SMeador Inge 
1395616adf6SRafael Espindola   auto *Sym = cast<DefinedRegular>(Cmd->Sym);
14072dc195dSRafael Espindola   ExprValue V = Cmd->Expression();
14172dc195dSRafael Espindola   if (V.isAbsolute()) {
14272dc195dSRafael Espindola     Sym->Value = V.getValue();
14372dc195dSRafael Espindola   } else {
14472dc195dSRafael Espindola     Sym->Section = V.Sec;
14572dc195dSRafael Espindola     if (Sym->Section->Flags & SHF_ALLOC)
1463c6de1a6SPetr Hosek       Sym->Value = alignTo(V.Val, V.Alignment);
14772dc195dSRafael Espindola     else
14872dc195dSRafael Espindola       Sym->Value = V.getValue();
149ea590d91SRafael Espindola   }
1508f1f3c40SMeador Inge }
1518f1f3c40SMeador Inge 
152a8dba487SGeorge Rimar static SymbolBody *findSymbol(StringRef S) {
153a8dba487SGeorge Rimar   switch (Config->EKind) {
154a8dba487SGeorge Rimar   case ELF32LEKind:
155a8dba487SGeorge Rimar     return Symtab<ELF32LE>::X->find(S);
156a8dba487SGeorge Rimar   case ELF32BEKind:
157a8dba487SGeorge Rimar     return Symtab<ELF32BE>::X->find(S);
158a8dba487SGeorge Rimar   case ELF64LEKind:
159a8dba487SGeorge Rimar     return Symtab<ELF64LE>::X->find(S);
160a8dba487SGeorge Rimar   case ELF64BEKind:
161a8dba487SGeorge Rimar     return Symtab<ELF64BE>::X->find(S);
162a8dba487SGeorge Rimar   default:
163a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
164a8dba487SGeorge Rimar   }
165a8dba487SGeorge Rimar }
166a8dba487SGeorge Rimar 
167a8dba487SGeorge Rimar static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) {
168a8dba487SGeorge Rimar   switch (Config->EKind) {
169a8dba487SGeorge Rimar   case ELF32LEKind:
170a8dba487SGeorge Rimar     return addRegular<ELF32LE>(Cmd);
171a8dba487SGeorge Rimar   case ELF32BEKind:
172a8dba487SGeorge Rimar     return addRegular<ELF32BE>(Cmd);
173a8dba487SGeorge Rimar   case ELF64LEKind:
174a8dba487SGeorge Rimar     return addRegular<ELF64LE>(Cmd);
175a8dba487SGeorge Rimar   case ELF64BEKind:
176a8dba487SGeorge Rimar     return addRegular<ELF64BE>(Cmd);
177a8dba487SGeorge Rimar   default:
178a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
179a8dba487SGeorge Rimar   }
180a8dba487SGeorge Rimar }
181a8dba487SGeorge Rimar 
182b8dd23f5SRui Ueyama void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
1831602421cSRui Ueyama   if (Cmd->Name == ".")
1848f1f3c40SMeador Inge     return;
1858f1f3c40SMeador Inge 
1868f1f3c40SMeador Inge   // If a symbol was in PROVIDE(), we need to define it only when
1878f1f3c40SMeador Inge   // it is a referenced undefined symbol.
188a8dba487SGeorge Rimar   SymbolBody *B = findSymbol(Cmd->Name);
1898f1f3c40SMeador Inge   if (Cmd->Provide && (!B || B->isDefined()))
1908f1f3c40SMeador Inge     return;
1918f1f3c40SMeador Inge 
192a8dba487SGeorge Rimar   Cmd->Sym = addRegularSymbol(Cmd);
193ceabe80eSEugene Leviant }
194ceabe80eSEugene Leviant 
195076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
196076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
197076fe157SGeorge Rimar }
198076fe157SGeorge Rimar 
199076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
200076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
201076fe157SGeorge Rimar }
202076fe157SGeorge Rimar 
20355b169bfSRafael Espindola // Fill [Buf, Buf + Size) with Filler.
20455b169bfSRafael Espindola // This is used for linker script "=fillexp" command.
20555b169bfSRafael Espindola static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {
20655b169bfSRafael Espindola   size_t I = 0;
20755b169bfSRafael Espindola   for (; I + 4 < Size; I += 4)
20855b169bfSRafael Espindola     memcpy(Buf + I, &Filler, 4);
20955b169bfSRafael Espindola   memcpy(Buf + I, &Filler, Size - I);
21055b169bfSRafael Espindola }
21155b169bfSRafael Espindola 
212eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
213eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
214eea3114fSGeorge Rimar }
215eea3114fSGeorge Rimar 
216eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) {
217eefa758eSGeorge Rimar   return C->Kind == AssertKind;
218eefa758eSGeorge Rimar }
219eefa758eSGeorge Rimar 
220e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) {
221e38cbab5SGeorge Rimar   return C->Kind == BytesDataKind;
222e38cbab5SGeorge Rimar }
223e38cbab5SGeorge Rimar 
224b4c9b81aSRafael Espindola static StringRef basename(InputSectionBase *S) {
225b4c9b81aSRafael Espindola   if (S->File)
226b4c9b81aSRafael Espindola     return sys::path::filename(S->File->getName());
227e0be2901SRui Ueyama   return "";
228e0be2901SRui Ueyama }
229e0be2901SRui Ueyama 
230b8dd23f5SRui Ueyama bool LinkerScript::shouldKeep(InputSectionBase *S) {
231e0be2901SRui Ueyama   for (InputSectionDescription *ID : Opt.KeptSections)
232e0be2901SRui Ueyama     if (ID->FilePat.match(basename(S)))
233cf43f179SEugene Leviant       for (SectionPattern &P : ID->SectionPatterns)
234f91282e1SRui Ueyama         if (P.SectionPat.match(S->Name))
235eea3114fSGeorge Rimar           return true;
236eea3114fSGeorge Rimar   return false;
237eea3114fSGeorge Rimar }
238eea3114fSGeorge Rimar 
239ea93fe00SRui Ueyama // A helper function for the SORT() command.
240c404d50dSRafael Espindola static std::function<bool(InputSectionBase *, InputSectionBase *)>
241be394db3SGeorge Rimar getComparator(SortSectionPolicy K) {
242be394db3SGeorge Rimar   switch (K) {
243be394db3SGeorge Rimar   case SortSectionPolicy::Alignment:
244ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
245ea93fe00SRui Ueyama       // ">" is not a mistake. Sections with larger alignments are placed
246ea93fe00SRui Ueyama       // before sections with smaller alignments in order to reduce the
247ea93fe00SRui Ueyama       // amount of padding necessary. This is compatible with GNU.
248ea93fe00SRui Ueyama       return A->Alignment > B->Alignment;
249ea93fe00SRui Ueyama     };
250be394db3SGeorge Rimar   case SortSectionPolicy::Name:
251ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
252ea93fe00SRui Ueyama       return A->Name < B->Name;
253ea93fe00SRui Ueyama     };
254be394db3SGeorge Rimar   case SortSectionPolicy::Priority:
255ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
256ea93fe00SRui Ueyama       return getPriority(A->Name) < getPriority(B->Name);
257ea93fe00SRui Ueyama     };
258be394db3SGeorge Rimar   default:
259be394db3SGeorge Rimar     llvm_unreachable("unknown sort policy");
260be394db3SGeorge Rimar   }
261742c3836SRui Ueyama }
2620702c4e8SGeorge Rimar 
263ea93fe00SRui Ueyama // A helper function for the SORT() command.
264b4c9b81aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase *> Sections,
26506ae6836SGeorge Rimar                              ConstraintKind Kind) {
2668f66df92SGeorge Rimar   if (Kind == ConstraintKind::NoConstraint)
2678f66df92SGeorge Rimar     return true;
2682c7171bfSRui Ueyama 
2692c7171bfSRui Ueyama   bool IsRW = llvm::any_of(Sections, [](InputSectionBase *Sec) {
2702c7171bfSRui Ueyama     return static_cast<InputSectionBase *>(Sec)->Flags & SHF_WRITE;
27106ae6836SGeorge Rimar   });
2722c7171bfSRui Ueyama 
273e746e52cSRafael Espindola   return (IsRW && Kind == ConstraintKind::ReadWrite) ||
274e746e52cSRafael Espindola          (!IsRW && Kind == ConstraintKind::ReadOnly);
27506ae6836SGeorge Rimar }
27606ae6836SGeorge Rimar 
2776a1aa8d9SRafael Espindola static void sortSections(InputSection **Begin, InputSection **End,
278ee924709SRui Ueyama                          SortSectionPolicy K) {
279ee924709SRui Ueyama   if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
28007171f21SGeorge Rimar     std::stable_sort(Begin, End, getComparator(K));
281ee924709SRui Ueyama }
282ee924709SRui Ueyama 
283d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches.
2846a1aa8d9SRafael Espindola std::vector<InputSection *>
28572e107f3SRui Ueyama LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
2866a1aa8d9SRafael Espindola   std::vector<InputSection *> Ret;
2878c6a5aafSRui Ueyama 
28872e107f3SRui Ueyama   // Collects all sections that satisfy constraints of Cmd.
28972e107f3SRui Ueyama   for (const SectionPattern &Pat : Cmd->SectionPatterns) {
29072e107f3SRui Ueyama     size_t SizeBefore = Ret.size();
29172e107f3SRui Ueyama 
29272e107f3SRui Ueyama     for (InputSectionBase *Sec : InputSections) {
29372e107f3SRui Ueyama       if (Sec->Assigned)
2948c6a5aafSRui Ueyama         continue;
29572e107f3SRui Ueyama 
296e39709b2SRafael Espindola       if (!Sec->Live) {
297e39709b2SRafael Espindola         reportDiscarded(Sec);
298e39709b2SRafael Espindola         continue;
299e39709b2SRafael Espindola       }
300e39709b2SRafael Espindola 
301908a3d34SRafael Espindola       // For -emit-relocs we have to ignore entries like
302908a3d34SRafael Espindola       //   .rela.dyn : { *(.rela.data) }
303908a3d34SRafael Espindola       // which are common because they are in the default bfd script.
30472e107f3SRui Ueyama       if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
305908a3d34SRafael Espindola         continue;
3068c6a5aafSRui Ueyama 
30772e107f3SRui Ueyama       StringRef Filename = basename(Sec);
30872e107f3SRui Ueyama       if (!Cmd->FilePat.match(Filename) ||
30972e107f3SRui Ueyama           Pat.ExcludedFilePat.match(Filename) ||
31072e107f3SRui Ueyama           !Pat.SectionPat.match(Sec->Name))
311e0be2901SRui Ueyama         continue;
31272e107f3SRui Ueyama 
3136a1aa8d9SRafael Espindola       Ret.push_back(cast<InputSection>(Sec));
31472e107f3SRui Ueyama       Sec->Assigned = true;
315f94efdddSRui Ueyama     }
316d3190795SRafael Espindola 
317ee924709SRui Ueyama     // Sort sections as instructed by SORT-family commands and --sort-section
318ee924709SRui Ueyama     // option. Because SORT-family commands can be nested at most two depth
319ee924709SRui Ueyama     // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
320ee924709SRui Ueyama     // line option is respected even if a SORT command is given, the exact
321ee924709SRui Ueyama     // behavior we have here is a bit complicated. Here are the rules.
322ee924709SRui Ueyama     //
323ee924709SRui Ueyama     // 1. If two SORT commands are given, --sort-section is ignored.
324ee924709SRui Ueyama     // 2. If one SORT command is given, and if it is not SORT_NONE,
325ee924709SRui Ueyama     //    --sort-section is handled as an inner SORT command.
326ee924709SRui Ueyama     // 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
327ee924709SRui Ueyama     // 4. If no SORT command is given, sort according to --sort-section.
3286a1aa8d9SRafael Espindola     InputSection **Begin = Ret.data() + SizeBefore;
3296a1aa8d9SRafael Espindola     InputSection **End = Ret.data() + Ret.size();
33007171f21SGeorge Rimar     if (Pat.SortOuter != SortSectionPolicy::None) {
33107171f21SGeorge Rimar       if (Pat.SortInner == SortSectionPolicy::Default)
33207171f21SGeorge Rimar         sortSections(Begin, End, Config->SortSection);
333ee924709SRui Ueyama       else
33407171f21SGeorge Rimar         sortSections(Begin, End, Pat.SortInner);
33507171f21SGeorge Rimar       sortSections(Begin, End, Pat.SortOuter);
33607171f21SGeorge Rimar     }
337ee924709SRui Ueyama   }
33872e107f3SRui Ueyama   return Ret;
339be94e1b6SRafael Espindola }
340be94e1b6SRafael Espindola 
341b8dd23f5SRui Ueyama void LinkerScript::discard(ArrayRef<InputSectionBase *> V) {
342b4c9b81aSRafael Espindola   for (InputSectionBase *S : V) {
343be94e1b6SRafael Espindola     S->Live = false;
344503206c5SGeorge Rimar     if (S == InX::ShStrTab)
345ecbfd871SRafael Espindola       error("discarding .shstrtab section is not allowed");
346647c1685SGeorge Rimar     discard(S->DependentSections);
347be94e1b6SRafael Espindola   }
348be94e1b6SRafael Espindola }
349be94e1b6SRafael Espindola 
350b4c9b81aSRafael Espindola std::vector<InputSectionBase *>
351b8dd23f5SRui Ueyama LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) {
352b4c9b81aSRafael Espindola   std::vector<InputSectionBase *> Ret;
353e7f912cdSRui Ueyama 
3548f99f73cSRui Ueyama   for (BaseCommand *Base : OutCmd.Commands) {
3558f99f73cSRui Ueyama     auto *Cmd = dyn_cast<InputSectionDescription>(Base);
3567c3ff2ebSRafael Espindola     if (!Cmd)
3570b9ce6a4SRui Ueyama       continue;
35872e107f3SRui Ueyama 
35972e107f3SRui Ueyama     Cmd->Sections = computeInputSections(Cmd);
360e4c8b9b7SRafael Espindola     Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end());
3610b9ce6a4SRui Ueyama   }
362e71a3f8aSRafael Espindola 
3630b9ce6a4SRui Ueyama   return Ret;
3640b9ce6a4SRui Ueyama }
3650b9ce6a4SRui Ueyama 
366b8dd23f5SRui Ueyama void LinkerScript::processCommands(OutputSectionFactory &Factory) {
3675616adf6SRafael Espindola   // A symbol can be assigned before any section is mentioned in the linker
3685616adf6SRafael Espindola   // script. In an DSO, the symbol values are addresses, so the only important
3695616adf6SRafael Espindola   // section values are:
3705616adf6SRafael Espindola   // * SHN_UNDEF
3715616adf6SRafael Espindola   // * SHN_ABS
3725616adf6SRafael Espindola   // * Any value meaning a regular section.
3735616adf6SRafael Espindola   // To handle that, create a dummy aether section that fills the void before
3745616adf6SRafael Espindola   // the linker scripts switches to another section. It has an index of one
3755616adf6SRafael Espindola   // which will map to whatever the first actual section is.
3765616adf6SRafael Espindola   Aether = make<OutputSection>("", 0, SHF_ALLOC);
3775616adf6SRafael Espindola   Aether->SectionIndex = 1;
3785616adf6SRafael Espindola   CurOutSec = Aether;
37949592cf6SRafael Espindola   Dot = 0;
3805616adf6SRafael Espindola 
38192a5ba6dSRui Ueyama   for (size_t I = 0; I < Opt.Commands.size(); ++I) {
3820b1b695aSRui Ueyama     // Handle symbol assignments outside of any output section.
38392a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Opt.Commands[I])) {
3844cd7352cSRafael Espindola       addSymbol(Cmd);
3852ab5f73dSRui Ueyama       continue;
3862ab5f73dSRui Ueyama     }
3870b1b695aSRui Ueyama 
38892a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I])) {
389b4c9b81aSRafael Espindola       std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
3907bd37870SRafael Espindola 
3910b1b695aSRui Ueyama       // The output section name `/DISCARD/' is special.
3920b1b695aSRui Ueyama       // Any input section assigned to it is discarded.
39348c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
3947bd37870SRafael Espindola         discard(V);
39548c3f1ceSRui Ueyama         continue;
39648c3f1ceSRui Ueyama       }
3970b9ce6a4SRui Ueyama 
3980b1b695aSRui Ueyama       // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
3990b1b695aSRui Ueyama       // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
4000b1b695aSRui Ueyama       // sections satisfy a given constraint. If not, a directive is handled
40107d7c42cSGeorge Rimar       // as if it wasn't present from the beginning.
4020b1b695aSRui Ueyama       //
4030b1b695aSRui Ueyama       // Because we'll iterate over Commands many more times, the easiest
40407d7c42cSGeorge Rimar       // way to "make it as if it wasn't present" is to just remove it.
405f7f0d088SGeorge Rimar       if (!matchConstraints(V, Cmd->Constraint)) {
406b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
407f94efdddSRui Ueyama           S->Assigned = false;
40892a5ba6dSRui Ueyama         Opt.Commands.erase(Opt.Commands.begin() + I);
40907d7c42cSGeorge Rimar         --I;
4107c3ff2ebSRafael Espindola         continue;
4117c3ff2ebSRafael Espindola       }
4127c3ff2ebSRafael Espindola 
4130b1b695aSRui Ueyama       // A directive may contain symbol definitions like this:
4140b1b695aSRui Ueyama       // ".foo : { ...; bar = .; }". Handle them.
4158f99f73cSRui Ueyama       for (BaseCommand *Base : Cmd->Commands)
4168f99f73cSRui Ueyama         if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
4174cd7352cSRafael Espindola           addSymbol(OutCmd);
4187c3ff2ebSRafael Espindola 
4190b1b695aSRui Ueyama       // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
4200b1b695aSRui Ueyama       // is given, input sections are aligned to that value, whether the
4210b1b695aSRui Ueyama       // given value is larger or smaller than the original section alignment.
4220b1b695aSRui Ueyama       if (Cmd->SubalignExpr) {
42372dc195dSRafael Espindola         uint32_t Subalign = Cmd->SubalignExpr().getValue();
424b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
4250b1b695aSRui Ueyama           S->Alignment = Subalign;
42620d03194SEugene Leviant       }
4270b1b695aSRui Ueyama 
4280b1b695aSRui Ueyama       // Add input sections to an output section.
429d86a4e50SGeorge Rimar       for (InputSectionBase *S : V)
4304f013bb3SRafael Espindola         Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
431660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
432660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX);
433660c9ab9SRafael Espindola         Sec->SectionIndex = I;
434d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
435660c9ab9SRafael Espindola       }
43648c3f1ceSRui Ueyama     }
4374aa2ef5bSRafael Espindola   }
4385616adf6SRafael Espindola   CurOutSec = nullptr;
439db24d9c3SGeorge Rimar }
440e63d81bdSEugene Leviant 
44102ed7575SRafael Espindola void LinkerScript::fabricateDefaultCommands() {
442cbfe9e94SPeter Smith   std::vector<BaseCommand *> Commands;
443cbfe9e94SPeter Smith 
444cbfe9e94SPeter Smith   // Define start address
44502ed7575SRafael Espindola   uint64_t StartAddr = Config->ImageBase + elf::getHeaderSize();
446cbfe9e94SPeter Smith 
447c60b4510SPeter Smith   // The Sections with -T<section> have been sorted in order of ascending
448c60b4510SPeter Smith   // address. We must lower StartAddr if the lowest -T<section address> as
449c60b4510SPeter Smith   // calls to setDot() must be monotonically increasing.
450c60b4510SPeter Smith   for (auto& KV : Config->SectionStartMap)
451c60b4510SPeter Smith     StartAddr = std::min(StartAddr, KV.second);
452c60b4510SPeter Smith 
453cbfe9e94SPeter Smith   Commands.push_back(
454cbfe9e94SPeter Smith       make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
455cbfe9e94SPeter Smith 
456cbfe9e94SPeter Smith   // For each OutputSection that needs a VA fabricate an OutputSectionCommand
457cbfe9e94SPeter Smith   // with an InputSectionDescription describing the InputSections
458cbfe9e94SPeter Smith   for (OutputSection *Sec : *OutputSections) {
45905c4f67cSRafael Espindola     auto *OSCmd = createOutputSectionCommand(Sec->Name, "<internal>");
460c60b4510SPeter Smith     OSCmd->Sec = Sec;
461d7dc2258SRafael Espindola     SecToCommand[Sec] = OSCmd;
462c60b4510SPeter Smith 
463c60b4510SPeter Smith     // Prefer user supplied address over additional alignment constraint
464cbfe9e94SPeter Smith     auto I = Config->SectionStartMap.find(Sec->Name);
465cbfe9e94SPeter Smith     if (I != Config->SectionStartMap.end())
466*bb7bd3eeSRafael Espindola       OSCmd->AddrExpr = [=] { return I->second; };
467c60b4510SPeter Smith     else if (Sec->PageAlign)
468cbfe9e94SPeter Smith       OSCmd->AddrExpr = [=] {
469cbfe9e94SPeter Smith         return alignTo(Script->getDot(), Config->MaxPageSize);
470cbfe9e94SPeter Smith       };
471c60b4510SPeter Smith 
472cbfe9e94SPeter Smith     Commands.push_back(OSCmd);
473cbfe9e94SPeter Smith     if (Sec->Sections.size()) {
474cbfe9e94SPeter Smith       auto *ISD = make<InputSectionDescription>("");
475cbfe9e94SPeter Smith       OSCmd->Commands.push_back(ISD);
476cbfe9e94SPeter Smith       for (InputSection *ISec : Sec->Sections) {
477cbfe9e94SPeter Smith         ISD->Sections.push_back(ISec);
478cbfe9e94SPeter Smith         ISec->Assigned = true;
479cbfe9e94SPeter Smith       }
480cbfe9e94SPeter Smith     }
481cbfe9e94SPeter Smith   }
482cbfe9e94SPeter Smith   // SECTIONS commands run before other non SECTIONS commands
483cbfe9e94SPeter Smith   Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end());
484cbfe9e94SPeter Smith   Opt.Commands = std::move(Commands);
485cbfe9e94SPeter Smith }
486cbfe9e94SPeter Smith 
4870b1b695aSRui Ueyama // Add sections that didn't match any sections command.
488b8dd23f5SRui Ueyama void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
4894f013bb3SRafael Espindola   for (InputSectionBase *S : InputSections) {
490db5e56f7SRafael Espindola     if (!S->Live || S->Parent)
4914f013bb3SRafael Espindola       continue;
4924f013bb3SRafael Espindola     StringRef Name = getOutputSectionName(S->Name);
4934f013bb3SRafael Espindola     auto I = std::find_if(
4944f013bb3SRafael Espindola         Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
4954f013bb3SRafael Espindola           if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
4964f013bb3SRafael Espindola             return Cmd->Name == Name;
4974f013bb3SRafael Espindola           return false;
4984f013bb3SRafael Espindola         });
499de8d9897SRafael Espindola     if (I == Opt.Commands.end()) {
5004f013bb3SRafael Espindola       Factory.addInputSec(S, Name);
501de8d9897SRafael Espindola     } else {
502de8d9897SRafael Espindola       auto *Cmd = cast<OutputSectionCommand>(*I);
503de8d9897SRafael Espindola       Factory.addInputSec(S, Name, Cmd->Sec);
504660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
505d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
506660c9ab9SRafael Espindola         unsigned Index = std::distance(Opt.Commands.begin(), I);
507660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index);
508660c9ab9SRafael Espindola         Sec->SectionIndex = Index;
509660c9ab9SRafael Espindola       }
510de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
5116a1aa8d9SRafael Espindola       ISD->Sections.push_back(cast<InputSection>(S));
512de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
513de8d9897SRafael Espindola     }
5144f013bb3SRafael Espindola   }
515e63d81bdSEugene Leviant }
516e63d81bdSEugene Leviant 
5177c4eafa3SRafael Espindola uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
5187c4eafa3SRafael Espindola   bool IsTbss = (CurOutSec->Flags & SHF_TLS) && CurOutSec->Type == SHT_NOBITS;
5197c4eafa3SRafael Espindola   uint64_t Start = IsTbss ? Dot + ThreadBssOffset : Dot;
5207c4eafa3SRafael Espindola   Start = alignTo(Start, Align);
5217c4eafa3SRafael Espindola   uint64_t End = Start + Size;
5227c4eafa3SRafael Espindola 
5237c4eafa3SRafael Espindola   if (IsTbss)
5247c4eafa3SRafael Espindola     ThreadBssOffset = End - Dot;
5257c4eafa3SRafael Espindola   else
5267c4eafa3SRafael Espindola     Dot = End;
5277c4eafa3SRafael Espindola   return End;
528a940e539SRafael Espindola }
529a940e539SRafael Espindola 
530b8dd23f5SRui Ueyama void LinkerScript::output(InputSection *S) {
5317c4eafa3SRafael Espindola   uint64_t Pos = advance(S->getSize(), S->Alignment);
5327c4eafa3SRafael Espindola   S->OutSecOff = Pos - S->getSize() - CurOutSec->Addr;
533d3190795SRafael Espindola 
534d3190795SRafael Espindola   // Update output section size after adding each section. This is so that
535d3190795SRafael Espindola   // SIZEOF works correctly in the case below:
536d3190795SRafael Espindola   // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
53704a2e348SRafael Espindola   CurOutSec->Size = Pos - CurOutSec->Addr;
538d3190795SRafael Espindola 
539b889744eSMeador Inge   // If there is a memory region associated with this input section, then
540b889744eSMeador Inge   // place the section in that region and update the region index.
541b889744eSMeador Inge   if (CurMemRegion) {
542b889744eSMeador Inge     CurMemRegion->Offset += CurOutSec->Size;
543b889744eSMeador Inge     uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin;
544b889744eSMeador Inge     if (CurSize > CurMemRegion->Length) {
545b889744eSMeador Inge       uint64_t OverflowAmt = CurSize - CurMemRegion->Length;
546b889744eSMeador Inge       error("section '" + CurOutSec->Name + "' will not fit in region '" +
547b889744eSMeador Inge             CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
548b889744eSMeador Inge             " bytes");
549b889744eSMeador Inge     }
550b889744eSMeador Inge   }
5512de509c3SRui Ueyama }
552ceabe80eSEugene Leviant 
553b8dd23f5SRui Ueyama void LinkerScript::switchTo(OutputSection *Sec) {
554d3190795SRafael Espindola   if (CurOutSec == Sec)
555d3190795SRafael Espindola     return;
556d3190795SRafael Espindola 
557d3190795SRafael Espindola   CurOutSec = Sec;
5587c4eafa3SRafael Espindola   CurOutSec->Addr = advance(0, CurOutSec->Alignment);
559b71d6f7aSEugene Leviant 
560b71d6f7aSEugene Leviant   // If neither AT nor AT> is specified for an allocatable section, the linker
561b71d6f7aSEugene Leviant   // will set the LMA such that the difference between VMA and LMA for the
562b71d6f7aSEugene Leviant   // section is the same as the preceding output section in the same region
563b71d6f7aSEugene Leviant   // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
56421467876SGeorge Rimar   if (LMAOffset)
56529c1afb8SRafael Espindola     CurOutSec->LMAOffset = LMAOffset();
566d3190795SRafael Espindola }
567d3190795SRafael Espindola 
568b8dd23f5SRui Ueyama void LinkerScript::process(BaseCommand &Base) {
5692e081a4fSRui Ueyama   // This handles the assignments to symbol or to the dot.
5702e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<SymbolAssignment>(&Base)) {
5712e081a4fSRui Ueyama     assignSymbol(Cmd, true);
572d3190795SRafael Espindola     return;
57397403d15SEugene Leviant   }
574e38cbab5SGeorge Rimar 
575e38cbab5SGeorge Rimar   // Handle BYTE(), SHORT(), LONG(), or QUAD().
5762e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) {
5772e081a4fSRui Ueyama     Cmd->Offset = Dot - CurOutSec->Addr;
5782e081a4fSRui Ueyama     Dot += Cmd->Size;
57904a2e348SRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
580e38cbab5SGeorge Rimar     return;
581e38cbab5SGeorge Rimar   }
582e38cbab5SGeorge Rimar 
5832e081a4fSRui Ueyama   // Handle ASSERT().
5842e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<AssertCommand>(&Base)) {
5852e081a4fSRui Ueyama     Cmd->Expression();
586b2d99d6aSMeador Inge     return;
587b2d99d6aSMeador Inge   }
588b2d99d6aSMeador Inge 
5892e081a4fSRui Ueyama   // Handle a single input section description command.
5902e081a4fSRui Ueyama   // It calculates and assigns the offsets for each section and also
591e38cbab5SGeorge Rimar   // updates the output section size.
5922e081a4fSRui Ueyama   auto &Cmd = cast<InputSectionDescription>(Base);
593a85e8ddaSRafael Espindola   for (InputSection *Sec : Cmd.Sections) {
5943fb5a6dcSGeorge Rimar     // We tentatively added all synthetic sections at the beginning and removed
5953fb5a6dcSGeorge Rimar     // empty ones afterwards (because there is no way to know whether they were
5963fb5a6dcSGeorge Rimar     // going be empty or not other than actually running linker scripts.)
5973fb5a6dcSGeorge Rimar     // We need to ignore remains of empty sections.
5982e081a4fSRui Ueyama     if (auto *S = dyn_cast<SyntheticSection>(Sec))
5992e081a4fSRui Ueyama       if (S->empty())
6003fb5a6dcSGeorge Rimar         continue;
6013fb5a6dcSGeorge Rimar 
6022e081a4fSRui Ueyama     if (!Sec->Live)
60378ef645fSGeorge Rimar       continue;
604db5e56f7SRafael Espindola     assert(CurOutSec == Sec->getParent());
605a85e8ddaSRafael Espindola     output(Sec);
606ceabe80eSEugene Leviant   }
607ceabe80eSEugene Leviant }
608ceabe80eSEugene Leviant 
609b889744eSMeador Inge // This function searches for a memory region to place the given output
610b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is
611b889744eSMeador Inge // returned. Otherwise, a nullptr is returned.
6121902b337SRafael Espindola MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd) {
613b889744eSMeador Inge   // If a memory region name was specified in the output section command,
614b889744eSMeador Inge   // then try to find that region first.
615b889744eSMeador Inge   if (!Cmd->MemoryRegionName.empty()) {
616b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
617b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
618b889744eSMeador Inge       return &It->second;
619b889744eSMeador Inge     error("memory region '" + Cmd->MemoryRegionName + "' not declared");
620b889744eSMeador Inge     return nullptr;
621b889744eSMeador Inge   }
622b889744eSMeador Inge 
623d7c5400fSRui Ueyama   // If at least one memory region is defined, all sections must
624d7c5400fSRui Ueyama   // belong to some memory region. Otherwise, we don't need to do
625d7c5400fSRui Ueyama   // anything for memory regions.
626cc400cc8SRui Ueyama   if (Opt.MemoryRegions.empty())
627b889744eSMeador Inge     return nullptr;
628b889744eSMeador Inge 
6291902b337SRafael Espindola   OutputSection *Sec = Cmd->Sec;
630b889744eSMeador Inge   // See if a region can be found by matching section flags.
6312e081a4fSRui Ueyama   for (auto &Pair : Opt.MemoryRegions) {
6322e081a4fSRui Ueyama     MemoryRegion &M = Pair.second;
6332e081a4fSRui Ueyama     if ((M.Flags & Sec->Flags) && (M.NegFlags & Sec->Flags) == 0)
6342e081a4fSRui Ueyama       return &M;
635b889744eSMeador Inge   }
636b889744eSMeador Inge 
637b889744eSMeador Inge   // Otherwise, no suitable region was found.
638b889744eSMeador Inge   if (Sec->Flags & SHF_ALLOC)
639b889744eSMeador Inge     error("no memory region specified for section '" + Sec->Name + "'");
640b889744eSMeador Inge   return nullptr;
641b889744eSMeador Inge }
642b889744eSMeador Inge 
6430b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section
6440b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }").
645b8dd23f5SRui Ueyama void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) {
6469b980095SRafael Espindola   OutputSection *Sec = Cmd->Sec;
6472b074553SRafael Espindola   if (!Sec)
648d3190795SRafael Espindola     return;
649b889744eSMeador Inge 
650cba41013SRui Ueyama   if (Cmd->AddrExpr && (Sec->Flags & SHF_ALLOC))
651d379f735SRui Ueyama     setDot(Cmd->AddrExpr, Cmd->Location, false);
652679828ffSRafael Espindola 
6535784e96fSEugene Leviant   if (Cmd->LMAExpr) {
6540c1c8085SGeorge Rimar     uint64_t D = Dot;
65572dc195dSRafael Espindola     LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; };
6565784e96fSEugene Leviant   }
6575784e96fSEugene Leviant 
658feed7506SRafael Espindola   CurMemRegion = Cmd->MemRegion;
659b889744eSMeador Inge   if (CurMemRegion)
660b889744eSMeador Inge     Dot = CurMemRegion->Offset;
661b889744eSMeador Inge   switchTo(Sec);
6620b1b695aSRui Ueyama 
663d86a4e50SGeorge Rimar   // We do not support custom layout for compressed debug sectons.
664d86a4e50SGeorge Rimar   // At this point we already know their size and have compressed content.
665d86a4e50SGeorge Rimar   if (CurOutSec->Flags & SHF_COMPRESSED)
666d86a4e50SGeorge Rimar     return;
667d86a4e50SGeorge Rimar 
668de8d9897SRafael Espindola   for (BaseCommand *C : Cmd->Commands)
669de8d9897SRafael Espindola     process(*C);
670d3190795SRafael Espindola }
671d3190795SRafael Espindola 
672b8dd23f5SRui Ueyama void LinkerScript::removeEmptyCommands() {
6736d38e4dbSRafael Espindola   // It is common practice to use very generic linker scripts. So for any
6746d38e4dbSRafael Espindola   // given run some of the output sections in the script will be empty.
6756d38e4dbSRafael Espindola   // We could create corresponding empty output sections, but that would
6766d38e4dbSRafael Espindola   // clutter the output.
6776d38e4dbSRafael Espindola   // We instead remove trivially empty sections. The bfd linker seems even
6786d38e4dbSRafael Espindola   // more aggressive at removing them.
6796d38e4dbSRafael Espindola   auto Pos = std::remove_if(
6808f99f73cSRui Ueyama       Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
6818f99f73cSRui Ueyama         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
6824f013bb3SRafael Espindola           return std::find(OutputSections->begin(), OutputSections->end(),
6834f013bb3SRafael Espindola                            Cmd->Sec) == OutputSections->end();
6840b1b695aSRui Ueyama         return false;
6856d38e4dbSRafael Espindola       });
6866d38e4dbSRafael Espindola   Opt.Commands.erase(Pos, Opt.Commands.end());
68707fe6129SRafael Espindola }
68807fe6129SRafael Espindola 
6896a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
6908f99f73cSRui Ueyama   for (BaseCommand *Base : Cmd.Commands)
6918f99f73cSRui Ueyama     if (!isa<InputSectionDescription>(*Base))
6926a53737cSRafael Espindola       return false;
6936a53737cSRafael Espindola   return true;
6946a53737cSRafael Espindola }
6956d38e4dbSRafael Espindola 
696b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsBeforeSorting() {
6979546fffbSRafael Espindola   // If the output section contains only symbol assignments, create a
6989546fffbSRafael Espindola   // corresponding output section. The bfd linker seems to only create them if
6999546fffbSRafael Espindola   // '.' is assigned to, but creating these section should not have any bad
7009546fffbSRafael Espindola   // consequeces and gives us a section to put the symbol in.
7010c1c8085SGeorge Rimar   uint64_t Flags = SHF_ALLOC;
702660c9ab9SRafael Espindola 
703660c9ab9SRafael Espindola   for (int I = 0, E = Opt.Commands.size(); I != E; ++I) {
704660c9ab9SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
7059546fffbSRafael Espindola     if (!Cmd)
7069546fffbSRafael Espindola       continue;
7074f013bb3SRafael Espindola     if (OutputSection *Sec = Cmd->Sec) {
7082b074553SRafael Espindola       Flags = Sec->Flags;
7099546fffbSRafael Espindola       continue;
7109546fffbSRafael Espindola     }
7119546fffbSRafael Espindola 
7126a53737cSRafael Espindola     if (isAllSectionDescription(*Cmd))
7136a53737cSRafael Espindola       continue;
7146a53737cSRafael Espindola 
715fd0c844fSDmitry Mikulin     auto *OutSec = make<OutputSection>(Cmd->Name, SHT_PROGBITS, Flags);
716660c9ab9SRafael Espindola     OutSec->SectionIndex = I;
7179546fffbSRafael Espindola     OutputSections->push_back(OutSec);
7189b980095SRafael Espindola     Cmd->Sec = OutSec;
719d7dc2258SRafael Espindola     SecToCommand[OutSec] = Cmd;
7209546fffbSRafael Espindola   }
721f7a17448SRafael Espindola }
722f7a17448SRafael Espindola 
723b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsAfterSorting() {
724f7a17448SRafael Espindola   placeOrphanSections();
725f7a17448SRafael Espindola 
726feed7506SRafael Espindola   // Try and find an appropriate memory region to assign offsets in.
727d1960dc0SRafael Espindola   for (BaseCommand *Base : Opt.Commands) {
728d1960dc0SRafael Espindola     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) {
729feed7506SRafael Espindola       Cmd->MemRegion = findMemoryRegion(Cmd);
730d1960dc0SRafael Espindola       // Handle align (e.g. ".foo : ALIGN(16) { ... }").
731d1960dc0SRafael Espindola       if (Cmd->AlignExpr)
732d1960dc0SRafael Espindola 	Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue());
733d1960dc0SRafael Espindola     }
734d1960dc0SRafael Espindola   }
735feed7506SRafael Espindola 
736f7a17448SRafael Espindola   // If output section command doesn't specify any segments,
737f7a17448SRafael Espindola   // and we haven't previously assigned any section to segment,
738f7a17448SRafael Espindola   // then we simply assign section to the very first load segment.
739f7a17448SRafael Espindola   // Below is an example of such linker script:
740f7a17448SRafael Espindola   // PHDRS { seg PT_LOAD; }
741f7a17448SRafael Espindola   // SECTIONS { .aaa : { *(.aaa) } }
742f7a17448SRafael Espindola   std::vector<StringRef> DefPhdrs;
743f7a17448SRafael Espindola   auto FirstPtLoad =
744f7a17448SRafael Espindola       std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(),
745f7a17448SRafael Espindola                    [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; });
746f7a17448SRafael Espindola   if (FirstPtLoad != Opt.PhdrsCommands.end())
747f7a17448SRafael Espindola     DefPhdrs.push_back(FirstPtLoad->Name);
748f7a17448SRafael Espindola 
749f7a17448SRafael Espindola   // Walk the commands and propagate the program headers to commands that don't
750f7a17448SRafael Espindola   // explicitly specify them.
7518f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
7528f99f73cSRui Ueyama     auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
753f7a17448SRafael Espindola     if (!Cmd)
754f7a17448SRafael Espindola       continue;
7558f99f73cSRui Ueyama 
756f7a17448SRafael Espindola     if (Cmd->Phdrs.empty())
757f7a17448SRafael Espindola       Cmd->Phdrs = DefPhdrs;
758f7a17448SRafael Espindola     else
759f7a17448SRafael Espindola       DefPhdrs = Cmd->Phdrs;
760f7a17448SRafael Espindola   }
7616a53737cSRafael Espindola 
7626a53737cSRafael Espindola   removeEmptyCommands();
7639546fffbSRafael Espindola }
7649546fffbSRafael Espindola 
76515c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments
76615c57951SRafael Espindola // so that an orphan after
76715c57951SRafael Espindola //   begin_foo = .;
76815c57951SRafael Espindola //   foo : { *(foo) }
76915c57951SRafael Espindola //   end_foo = .;
77015c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols.
77115c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the
77215c57951SRafael Espindola // one in charge of deciding the order of the sections.
77315c57951SRafael Espindola // We don't want to go over alignments, since doing so in
77415c57951SRafael Espindola //  rx_sec : { *(rx_sec) }
77515c57951SRafael Espindola //  . = ALIGN(0x1000);
77615c57951SRafael Espindola //  /* The RW PT_LOAD starts here*/
77715c57951SRafael Espindola //  rw_sec : { *(rw_sec) }
77815c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned.
7794e1e88e3SRui Ueyama static bool shouldSkip(BaseCommand *Cmd) {
78015c57951SRafael Espindola   if (isa<OutputSectionCommand>(Cmd))
78115c57951SRafael Espindola     return false;
7824e1e88e3SRui Ueyama   if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd))
7835fcc99c2SRafael Espindola     return Assign->Name != ".";
7844e1e88e3SRui Ueyama   return true;
78515c57951SRafael Espindola }
78615c57951SRafael Espindola 
7876697ec29SRui Ueyama // Orphan sections are sections present in the input files which are
7886697ec29SRui Ueyama // not explicitly placed into the output file by the linker script.
7896697ec29SRui Ueyama //
7906697ec29SRui Ueyama // When the control reaches this function, Opt.Commands contains
7916697ec29SRui Ueyama // output section commands for non-orphan sections only. This function
79281cb7107SRui Ueyama // adds new elements for orphan sections so that all sections are
79381cb7107SRui Ueyama // explicitly handled by Opt.Commands.
7946697ec29SRui Ueyama //
7956697ec29SRui Ueyama // Writer<ELFT>::sortSections has already sorted output sections.
7966697ec29SRui Ueyama // What we need to do is to scan OutputSections vector and
7976697ec29SRui Ueyama // Opt.Commands in parallel to find orphan sections. If there is an
7986697ec29SRui Ueyama // output section that doesn't have a corresponding entry in
7996697ec29SRui Ueyama // Opt.Commands, we will insert a new entry to Opt.Commands.
8006697ec29SRui Ueyama //
8016697ec29SRui Ueyama // There is some ambiguity as to where exactly a new entry should be
8026697ec29SRui Ueyama // inserted, because Opt.Commands contains not only output section
80381cb7107SRui Ueyama // commands but also other types of commands such as symbol assignment
8046697ec29SRui Ueyama // expressions. There's no correct answer here due to the lack of the
8056697ec29SRui Ueyama // formal specification of the linker script. We use heuristics to
8066697ec29SRui Ueyama // determine whether a new output command should be added before or
8076697ec29SRui Ueyama // after another commands. For the details, look at shouldSkip
8086697ec29SRui Ueyama // function.
809b8dd23f5SRui Ueyama void LinkerScript::placeOrphanSections() {
810aab6d5c5SRafael Espindola   // The OutputSections are already in the correct order.
811aab6d5c5SRafael Espindola   // This loops creates or moves commands as needed so that they are in the
812aab6d5c5SRafael Espindola   // correct order.
813aab6d5c5SRafael Espindola   int CmdIndex = 0;
8145fcc99c2SRafael Espindola 
8155fcc99c2SRafael Espindola   // As a horrible special case, skip the first . assignment if it is before any
8165fcc99c2SRafael Espindola   // section. We do this because it is common to set a load address by starting
8175fcc99c2SRafael Espindola   // the script with ". = 0xabcd" and the expectation is that every section is
8185fcc99c2SRafael Espindola   // after that.
8194e1e88e3SRui Ueyama   auto FirstSectionOrDotAssignment =
8204e1e88e3SRui Ueyama       std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
8214e1e88e3SRui Ueyama                    [](BaseCommand *Cmd) { return !shouldSkip(Cmd); });
8225fcc99c2SRafael Espindola   if (FirstSectionOrDotAssignment != Opt.Commands.end()) {
8235fcc99c2SRafael Espindola     CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin();
8245fcc99c2SRafael Espindola     if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
8255fcc99c2SRafael Espindola       ++CmdIndex;
8265fcc99c2SRafael Espindola   }
8275fcc99c2SRafael Espindola 
82824e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
82940849419SRafael Espindola     StringRef Name = Sec->Name;
830aab6d5c5SRafael Espindola 
831aab6d5c5SRafael Espindola     // Find the last spot where we can insert a command and still get the
83215c57951SRafael Espindola     // correct result.
833aab6d5c5SRafael Espindola     auto CmdIter = Opt.Commands.begin() + CmdIndex;
834aab6d5c5SRafael Espindola     auto E = Opt.Commands.end();
8354e1e88e3SRui Ueyama     while (CmdIter != E && shouldSkip(*CmdIter)) {
836aab6d5c5SRafael Espindola       ++CmdIter;
837aab6d5c5SRafael Espindola       ++CmdIndex;
838aab6d5c5SRafael Espindola     }
839aab6d5c5SRafael Espindola 
840de8d9897SRafael Espindola     // If there is no command corresponding to this output section,
841de8d9897SRafael Espindola     // create one and put a InputSectionDescription in it so that both
842de8d9897SRafael Espindola     // representations agree on which input sections to use.
843fa948c72SRafael Espindola     OutputSectionCommand *Cmd = getCmd(Sec);
844fa948c72SRafael Espindola     if (!Cmd) {
84505c4f67cSRafael Espindola       Cmd = createOutputSectionCommand(Name, "<internal>");
8469b980095SRafael Espindola       Opt.Commands.insert(CmdIter, Cmd);
847aab6d5c5SRafael Espindola       ++CmdIndex;
848de8d9897SRafael Espindola 
849de8d9897SRafael Espindola       Cmd->Sec = Sec;
850d7dc2258SRafael Espindola       SecToCommand[Sec] = Cmd;
851de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
852de8d9897SRafael Espindola       for (InputSection *IS : Sec->Sections)
853de8d9897SRafael Espindola         ISD->Sections.push_back(IS);
854de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
855de8d9897SRafael Espindola 
85615c57951SRafael Espindola       continue;
85715c57951SRafael Espindola     }
85815c57951SRafael Espindola 
85915c57951SRafael Espindola     // Continue from where we found it.
860fa948c72SRafael Espindola     while (*CmdIter != Cmd) {
861fa948c72SRafael Espindola       ++CmdIter;
862fa948c72SRafael Espindola       ++CmdIndex;
863fa948c72SRafael Espindola     }
864fa948c72SRafael Espindola     ++CmdIndex;
865652852c5SGeorge Rimar   }
866337f903cSRafael Espindola }
867337f903cSRafael Espindola 
868b8dd23f5SRui Ueyama void LinkerScript::processNonSectionCommands() {
8698f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
8708f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
871d379f735SRui Ueyama       assignSymbol(Cmd, false);
8728f99f73cSRui Ueyama     else if (auto *Cmd = dyn_cast<AssertCommand>(Base))
87302ad516bSPetr Hosek       Cmd->Expression();
87402ad516bSPetr Hosek   }
87502ad516bSPetr Hosek }
87602ad516bSPetr Hosek 
877de8d9897SRafael Espindola // Do a last effort at synchronizing the linker script "AST" and the section
878de8d9897SRafael Espindola // list. This is needed to account for last minute changes, like adding a
879de8d9897SRafael Espindola // .ARM.exidx terminator and sorting SHF_LINK_ORDER sections.
880de8d9897SRafael Espindola //
881de8d9897SRafael Espindola // FIXME: We should instead create the "AST" earlier and the above changes would
882de8d9897SRafael Espindola // be done directly in the "AST".
883de8d9897SRafael Espindola //
884de8d9897SRafael Espindola // This can only handle new sections being added and sections being reordered.
885de8d9897SRafael Espindola void LinkerScript::synchronize() {
886de8d9897SRafael Espindola   for (BaseCommand *Base : Opt.Commands) {
887de8d9897SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
888de8d9897SRafael Espindola     if (!Cmd)
889de8d9897SRafael Espindola       continue;
890de8d9897SRafael Espindola     ArrayRef<InputSection *> Sections = Cmd->Sec->Sections;
8916a1aa8d9SRafael Espindola     std::vector<InputSection **> ScriptSections;
8926a1aa8d9SRafael Espindola     DenseSet<InputSection *> ScriptSectionsSet;
893de8d9897SRafael Espindola     for (BaseCommand *Base : Cmd->Commands) {
894de8d9897SRafael Espindola       auto *ISD = dyn_cast<InputSectionDescription>(Base);
895de8d9897SRafael Espindola       if (!ISD)
896de8d9897SRafael Espindola         continue;
8976a1aa8d9SRafael Espindola       for (InputSection *&IS : ISD->Sections) {
898de8d9897SRafael Espindola         if (IS->Live) {
899de8d9897SRafael Espindola           ScriptSections.push_back(&IS);
900de8d9897SRafael Espindola           ScriptSectionsSet.insert(IS);
901de8d9897SRafael Espindola         }
902de8d9897SRafael Espindola       }
903de8d9897SRafael Espindola     }
9046a1aa8d9SRafael Espindola     std::vector<InputSection *> Missing;
905de8d9897SRafael Espindola     for (InputSection *IS : Sections)
906de8d9897SRafael Espindola       if (!ScriptSectionsSet.count(IS))
907de8d9897SRafael Espindola         Missing.push_back(IS);
908de8d9897SRafael Espindola     if (!Missing.empty()) {
909de8d9897SRafael Espindola       auto ISD = make<InputSectionDescription>("");
910de8d9897SRafael Espindola       ISD->Sections = Missing;
911de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
9126a1aa8d9SRafael Espindola       for (InputSection *&IS : ISD->Sections)
913de8d9897SRafael Espindola         if (IS->Live)
914de8d9897SRafael Espindola           ScriptSections.push_back(&IS);
915de8d9897SRafael Espindola     }
916de8d9897SRafael Espindola     assert(ScriptSections.size() == Sections.size());
917de8d9897SRafael Espindola     for (int I = 0, N = Sections.size(); I < N; ++I)
918de8d9897SRafael Espindola       *ScriptSections[I] = Sections[I];
919de8d9897SRafael Espindola   }
920de8d9897SRafael Espindola }
921de8d9897SRafael Espindola 
922faf25a72SRafael Espindola static bool
923faf25a72SRafael Espindola allocateHeaders(std::vector<PhdrEntry> &Phdrs,
924faf25a72SRafael Espindola                 ArrayRef<OutputSectionCommand *> OutputSectionCommands,
92502ed7575SRafael Espindola                 uint64_t Min) {
92602ed7575SRafael Espindola   auto FirstPTLoad =
92702ed7575SRafael Espindola       std::find_if(Phdrs.begin(), Phdrs.end(),
92802ed7575SRafael Espindola                    [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
92902ed7575SRafael Espindola   if (FirstPTLoad == Phdrs.end())
93002ed7575SRafael Espindola     return false;
93102ed7575SRafael Espindola 
93202ed7575SRafael Espindola   uint64_t HeaderSize = getHeaderSize();
93302ed7575SRafael Espindola   if (HeaderSize <= Min || Script->hasPhdrsCommands()) {
93402ed7575SRafael Espindola     Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
93502ed7575SRafael Espindola     Out::ElfHeader->Addr = Min;
93602ed7575SRafael Espindola     Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
93702ed7575SRafael Espindola     return true;
93802ed7575SRafael Espindola   }
93902ed7575SRafael Espindola 
94002ed7575SRafael Espindola   assert(FirstPTLoad->First == Out::ElfHeader);
94102ed7575SRafael Espindola   OutputSection *ActualFirst = nullptr;
942faf25a72SRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
943faf25a72SRafael Espindola     OutputSection *Sec = Cmd->Sec;
94402ed7575SRafael Espindola     if (Sec->FirstInPtLoad == Out::ElfHeader) {
94502ed7575SRafael Espindola       ActualFirst = Sec;
94602ed7575SRafael Espindola       break;
94702ed7575SRafael Espindola     }
94802ed7575SRafael Espindola   }
94902ed7575SRafael Espindola   if (ActualFirst) {
950faf25a72SRafael Espindola     for (OutputSectionCommand *Cmd : OutputSectionCommands) {
951faf25a72SRafael Espindola       OutputSection *Sec = Cmd->Sec;
95202ed7575SRafael Espindola       if (Sec->FirstInPtLoad == Out::ElfHeader)
95302ed7575SRafael Espindola         Sec->FirstInPtLoad = ActualFirst;
954faf25a72SRafael Espindola     }
95502ed7575SRafael Espindola     FirstPTLoad->First = ActualFirst;
95602ed7575SRafael Espindola   } else {
95702ed7575SRafael Espindola     Phdrs.erase(FirstPTLoad);
95802ed7575SRafael Espindola   }
95902ed7575SRafael Espindola 
96002ed7575SRafael Espindola   auto PhdrI = std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry &E) {
96102ed7575SRafael Espindola     return E.p_type == PT_PHDR;
96202ed7575SRafael Espindola   });
96302ed7575SRafael Espindola   if (PhdrI != Phdrs.end())
96402ed7575SRafael Espindola     Phdrs.erase(PhdrI);
96502ed7575SRafael Espindola   return false;
96602ed7575SRafael Espindola }
96702ed7575SRafael Espindola 
968faf25a72SRafael Espindola void LinkerScript::assignAddresses(
969faf25a72SRafael Espindola     std::vector<PhdrEntry> &Phdrs,
970faf25a72SRafael Espindola     ArrayRef<OutputSectionCommand *> OutputSectionCommands) {
9717c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
972be607334SRafael Espindola   Dot = 0;
97372dc195dSRafael Espindola   ErrorOnMissingSection = true;
97406f4743aSRafael Espindola   switchTo(Aether);
97506f4743aSRafael Espindola 
9768f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
9778f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
978d379f735SRui Ueyama       assignSymbol(Cmd, false);
97905ef4cffSRui Ueyama       continue;
980652852c5SGeorge Rimar     }
981652852c5SGeorge Rimar 
9828f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<AssertCommand>(Base)) {
9834595df94SRafael Espindola       Cmd->Expression();
984eefa758eSGeorge Rimar       continue;
985eefa758eSGeorge Rimar     }
986eefa758eSGeorge Rimar 
9878f99f73cSRui Ueyama     auto *Cmd = cast<OutputSectionCommand>(Base);
988d3190795SRafael Espindola     assignOffsets(Cmd);
989a14b13d8SGeorge Rimar   }
990467c4d55SEugene Leviant 
9910c1c8085SGeorge Rimar   uint64_t MinVA = std::numeric_limits<uint64_t>::max();
992faf25a72SRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
993faf25a72SRafael Espindola     OutputSection *Sec = Cmd->Sec;
99404a2e348SRafael Espindola     if (Sec->Flags & SHF_ALLOC)
995e08e78dfSRafael Espindola       MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
996ea590d91SRafael Espindola     else
997ea590d91SRafael Espindola       Sec->Addr = 0;
998ea590d91SRafael Espindola   }
999aab6d5c5SRafael Espindola 
1000faf25a72SRafael Espindola   allocateHeaders(Phdrs, OutputSectionCommands, MinVA);
1001fb8978fcSDima Stepanov }
1002652852c5SGeorge Rimar 
1003464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
1004b8dd23f5SRui Ueyama std::vector<PhdrEntry> LinkerScript::createPhdrs() {
100517cb7c0aSRafael Espindola   std::vector<PhdrEntry> Ret;
1006bbe38602SEugene Leviant 
1007464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
1008464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
1009bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
1010edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
101117cb7c0aSRafael Espindola     PhdrEntry &Phdr = Ret.back();
1012bbe38602SEugene Leviant 
1013bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
10149d1bacb1SRui Ueyama       Phdr.add(Out::ElfHeader);
1015bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
10169d1bacb1SRui Ueyama       Phdr.add(Out::ProgramHeaders);
101756b21c86SEugene Leviant 
101856b21c86SEugene Leviant     if (Cmd.LMAExpr) {
101972dc195dSRafael Espindola       Phdr.p_paddr = Cmd.LMAExpr().getValue();
102056b21c86SEugene Leviant       Phdr.HasLMA = true;
102156b21c86SEugene Leviant     }
1022bbe38602SEugene Leviant   }
1023bbe38602SEugene Leviant 
1024464daadcSRui Ueyama   // Add output sections to program headers.
102524e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
102604a2e348SRafael Espindola     if (!(Sec->Flags & SHF_ALLOC))
1027bbe38602SEugene Leviant       break;
1028bbe38602SEugene Leviant 
1029bbe38602SEugene Leviant     // Assign headers specified by linker script
10302c923c2cSRafael Espindola     for (size_t Id : getPhdrIndices(Sec)) {
1031edebbdf1SRui Ueyama       Ret[Id].add(Sec);
1032865bf863SEugene Leviant       if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
103317cb7c0aSRafael Espindola         Ret[Id].p_flags |= Sec->getPhdrFlags();
1034bbe38602SEugene Leviant     }
1035bbe38602SEugene Leviant   }
1036edebbdf1SRui Ueyama   return Ret;
1037bbe38602SEugene Leviant }
1038bbe38602SEugene Leviant 
1039b8dd23f5SRui Ueyama bool LinkerScript::ignoreInterpSection() {
1040f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
1041f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
1042e31d9886SRui Ueyama   if (Opt.PhdrsCommands.empty())
1043e31d9886SRui Ueyama     return false;
1044e31d9886SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands)
1045e31d9886SRui Ueyama     if (Cmd.Type == PT_INTERP)
1046e31d9886SRui Ueyama       return false;
1047e31d9886SRui Ueyama   return true;
1048f9bc3bd2SEugene Leviant }
1049f9bc3bd2SEugene Leviant 
1050d7dc2258SRafael Espindola OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) const {
1051d7dc2258SRafael Espindola   auto I = SecToCommand.find(Sec);
1052d7dc2258SRafael Espindola   if (I == SecToCommand.end())
1053fa948c72SRafael Espindola     return nullptr;
1054d7dc2258SRafael Espindola   return I->second;
1055fa948c72SRafael Espindola }
1056fa948c72SRafael Espindola 
105755b169bfSRafael Espindola uint32_t OutputSectionCommand::getFiller() {
105855b169bfSRafael Espindola   if (Filler)
105955b169bfSRafael Espindola     return *Filler;
106055b169bfSRafael Espindola   if (Sec->Flags & SHF_EXECINSTR)
106155b169bfSRafael Espindola     return Target->TrapInstr;
106255b169bfSRafael Espindola   return 0;
1063e2ee72b5SGeorge Rimar }
1064e2ee72b5SGeorge Rimar 
1065e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
1066f62d2607SRui Ueyama   if (Size == 1)
1067f62d2607SRui Ueyama     *Buf = Data;
1068f62d2607SRui Ueyama   else if (Size == 2)
1069f93ed4deSRui Ueyama     write16(Buf, Data, Config->Endianness);
1070f62d2607SRui Ueyama   else if (Size == 4)
1071f93ed4deSRui Ueyama     write32(Buf, Data, Config->Endianness);
1072f62d2607SRui Ueyama   else if (Size == 8)
1073f93ed4deSRui Ueyama     write64(Buf, Data, Config->Endianness);
1074f62d2607SRui Ueyama   else
1075e38cbab5SGeorge Rimar     llvm_unreachable("unsupported Size argument");
1076e38cbab5SGeorge Rimar }
1077e38cbab5SGeorge Rimar 
107868880728SRafael Espindola // Compress section contents if this section contains debug info.
107968880728SRafael Espindola template <class ELFT> void OutputSectionCommand::maybeCompress() {
108068880728SRafael Espindola   typedef typename ELFT::Chdr Elf_Chdr;
108168880728SRafael Espindola 
108268880728SRafael Espindola   // Compress only DWARF debug sections.
108368880728SRafael Espindola   if (!Config->CompressDebugSections || (Sec->Flags & SHF_ALLOC) ||
108468880728SRafael Espindola       !Name.startswith(".debug_"))
108568880728SRafael Espindola     return;
108668880728SRafael Espindola 
108768880728SRafael Espindola   // Create a section header.
108868880728SRafael Espindola   Sec->ZDebugHeader.resize(sizeof(Elf_Chdr));
108968880728SRafael Espindola   auto *Hdr = reinterpret_cast<Elf_Chdr *>(Sec->ZDebugHeader.data());
109068880728SRafael Espindola   Hdr->ch_type = ELFCOMPRESS_ZLIB;
109168880728SRafael Espindola   Hdr->ch_size = Sec->Size;
109268880728SRafael Espindola   Hdr->ch_addralign = Sec->Alignment;
109368880728SRafael Espindola 
109468880728SRafael Espindola   // Write section contents to a temporary buffer and compress it.
109568880728SRafael Espindola   std::vector<uint8_t> Buf(Sec->Size);
109668880728SRafael Espindola   writeTo<ELFT>(Buf.data());
109768880728SRafael Espindola   if (Error E = zlib::compress(toStringRef(Buf), Sec->CompressedData))
109868880728SRafael Espindola     fatal("compress failed: " + llvm::toString(std::move(E)));
109968880728SRafael Espindola 
110068880728SRafael Espindola   // Update section headers.
110168880728SRafael Espindola   Sec->Size = sizeof(Elf_Chdr) + Sec->CompressedData.size();
110268880728SRafael Espindola   Sec->Flags |= SHF_COMPRESSED;
110368880728SRafael Espindola }
110468880728SRafael Espindola 
110555b169bfSRafael Espindola template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
110655b169bfSRafael Espindola   Sec->Loc = Buf;
110755b169bfSRafael Espindola 
110855b169bfSRafael Espindola   // We may have already rendered compressed content when using
110955b169bfSRafael Espindola   // -compress-debug-sections option. Write it together with header.
111055b169bfSRafael Espindola   if (!Sec->CompressedData.empty()) {
111155b169bfSRafael Espindola     memcpy(Buf, Sec->ZDebugHeader.data(), Sec->ZDebugHeader.size());
111255b169bfSRafael Espindola     memcpy(Buf + Sec->ZDebugHeader.size(), Sec->CompressedData.data(),
111355b169bfSRafael Espindola            Sec->CompressedData.size());
111455b169bfSRafael Espindola     return;
111555b169bfSRafael Espindola   }
111655b169bfSRafael Espindola 
1117d4096140SGeorge Rimar   if (Sec->Type == SHT_NOBITS)
1118d4096140SGeorge Rimar     return;
1119d4096140SGeorge Rimar 
112055b169bfSRafael Espindola   // Write leading padding.
1121969c6512SRafael Espindola   std::vector<InputSection *> Sections;
1122969c6512SRafael Espindola   for (BaseCommand *Cmd : Commands)
1123969c6512SRafael Espindola     if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
1124969c6512SRafael Espindola       for (InputSection *IS : ISD->Sections)
1125969c6512SRafael Espindola         if (IS->Live)
1126969c6512SRafael Espindola           Sections.push_back(IS);
112755b169bfSRafael Espindola   uint32_t Filler = getFiller();
112855b169bfSRafael Espindola   if (Filler)
112955b169bfSRafael Espindola     fill(Buf, Sections.empty() ? Sec->Size : Sections[0]->OutSecOff, Filler);
113055b169bfSRafael Espindola 
113155b169bfSRafael Espindola   parallelForEachN(0, Sections.size(), [=](size_t I) {
113255b169bfSRafael Espindola     InputSection *IS = Sections[I];
113355b169bfSRafael Espindola     IS->writeTo<ELFT>(Buf);
113455b169bfSRafael Espindola 
113555b169bfSRafael Espindola     // Fill gaps between sections.
113655b169bfSRafael Espindola     if (Filler) {
113755b169bfSRafael Espindola       uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
113855b169bfSRafael Espindola       uint8_t *End;
113955b169bfSRafael Espindola       if (I + 1 == Sections.size())
114055b169bfSRafael Espindola         End = Buf + Sec->Size;
114155b169bfSRafael Espindola       else
114255b169bfSRafael Espindola         End = Buf + Sections[I + 1]->OutSecOff;
114355b169bfSRafael Espindola       fill(Start, End - Start, Filler);
114455b169bfSRafael Espindola     }
114555b169bfSRafael Espindola   });
114655b169bfSRafael Espindola 
114755b169bfSRafael Espindola   // Linker scripts may have BYTE()-family commands with which you
114855b169bfSRafael Espindola   // can write arbitrary bytes to the output. Process them if any.
114955b169bfSRafael Espindola   for (BaseCommand *Base : Commands)
11508f99f73cSRui Ueyama     if (auto *Data = dyn_cast<BytesDataCommand>(Base))
1151a8dba487SGeorge Rimar       writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
1152e38cbab5SGeorge Rimar }
1153e38cbab5SGeorge Rimar 
1154dc1ed120SRafael Espindola bool LinkerScript::hasLMA(OutputSection *Sec) {
1155fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec))
1156fa948c72SRafael Espindola     if (Cmd->LMAExpr)
1157b71d6f7aSEugene Leviant       return true;
1158b71d6f7aSEugene Leviant   return false;
11598ceadb38SGeorge Rimar }
11608ceadb38SGeorge Rimar 
1161b8dd23f5SRui Ueyama ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
11624595df94SRafael Espindola   if (S == ".")
116372dc195dSRafael Espindola     return {CurOutSec, Dot - CurOutSec->Addr};
1164a8dba487SGeorge Rimar   if (SymbolBody *B = findSymbol(S)) {
116572dc195dSRafael Espindola     if (auto *D = dyn_cast<DefinedRegular>(B))
116672dc195dSRafael Espindola       return {D->Section, D->Value};
116730f16b23SPetr Hosek     if (auto *C = dyn_cast<DefinedCommon>(B))
1168a8dba487SGeorge Rimar       return {InX::Common, C->Offset};
116972dc195dSRafael Espindola   }
1170f6aeed36SEugene Leviant   error(Loc + ": symbol not found: " + S);
1171884e786dSGeorge Rimar   return 0;
1172884e786dSGeorge Rimar }
1173884e786dSGeorge Rimar 
1174b8dd23f5SRui Ueyama bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
1175f34f45fdSGeorge Rimar 
11762c923c2cSRafael Espindola // Returns indices of ELF headers containing specific section. Each index is a
11772c923c2cSRafael Espindola // zero based number of ELF header listed within PHDRS {} script block.
11782c923c2cSRafael Espindola std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) {
1179fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec)) {
118029c5a2a9SRui Ueyama     std::vector<size_t> Ret;
118129c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
11822a942c4bSEugene Leviant       Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
118329c5a2a9SRui Ueyama     return Ret;
1184bbe38602SEugene Leviant   }
118531d842f5SGeorge Rimar   return {};
118631d842f5SGeorge Rimar }
1187bbe38602SEugene Leviant 
1188b8dd23f5SRui Ueyama size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
118929c5a2a9SRui Ueyama   size_t I = 0;
119029c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
119129c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
119229c5a2a9SRui Ueyama       return I;
119329c5a2a9SRui Ueyama     ++I;
119429c5a2a9SRui Ueyama   }
11952a942c4bSEugene Leviant   error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
119629c5a2a9SRui Ueyama   return 0;
119729c5a2a9SRui Ueyama }
119855b169bfSRafael Espindola 
119955b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);
120055b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32BE>(uint8_t *Buf);
120155b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64LE>(uint8_t *Buf);
120255b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64BE>(uint8_t *Buf);
120368880728SRafael Espindola 
120468880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32LE>();
120568880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32BE>();
120668880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64LE>();
120768880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64BE>();
1208