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"
28264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h"
2922886a28SEugene Zelenko #include "llvm/Support/Casting.h"
3068880728SRafael Espindola #include "llvm/Support/Compression.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);
5741c7ab4aSGeorge Rimar     error(Loc + ": 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;
1453c6de1a6SPetr Hosek     Sym->Value = alignTo(V.Val, V.Alignment);
146ea590d91SRafael Espindola   }
1478f1f3c40SMeador Inge }
1488f1f3c40SMeador Inge 
149a8dba487SGeorge Rimar static SymbolBody *findSymbol(StringRef S) {
150a8dba487SGeorge Rimar   switch (Config->EKind) {
151a8dba487SGeorge Rimar   case ELF32LEKind:
152a8dba487SGeorge Rimar     return Symtab<ELF32LE>::X->find(S);
153a8dba487SGeorge Rimar   case ELF32BEKind:
154a8dba487SGeorge Rimar     return Symtab<ELF32BE>::X->find(S);
155a8dba487SGeorge Rimar   case ELF64LEKind:
156a8dba487SGeorge Rimar     return Symtab<ELF64LE>::X->find(S);
157a8dba487SGeorge Rimar   case ELF64BEKind:
158a8dba487SGeorge Rimar     return Symtab<ELF64BE>::X->find(S);
159a8dba487SGeorge Rimar   default:
160a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
161a8dba487SGeorge Rimar   }
162a8dba487SGeorge Rimar }
163a8dba487SGeorge Rimar 
164a8dba487SGeorge Rimar static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) {
165a8dba487SGeorge Rimar   switch (Config->EKind) {
166a8dba487SGeorge Rimar   case ELF32LEKind:
167a8dba487SGeorge Rimar     return addRegular<ELF32LE>(Cmd);
168a8dba487SGeorge Rimar   case ELF32BEKind:
169a8dba487SGeorge Rimar     return addRegular<ELF32BE>(Cmd);
170a8dba487SGeorge Rimar   case ELF64LEKind:
171a8dba487SGeorge Rimar     return addRegular<ELF64LE>(Cmd);
172a8dba487SGeorge Rimar   case ELF64BEKind:
173a8dba487SGeorge Rimar     return addRegular<ELF64BE>(Cmd);
174a8dba487SGeorge Rimar   default:
175a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
176a8dba487SGeorge Rimar   }
177a8dba487SGeorge Rimar }
178a8dba487SGeorge Rimar 
179b8dd23f5SRui Ueyama void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
1801602421cSRui Ueyama   if (Cmd->Name == ".")
1818f1f3c40SMeador Inge     return;
1828f1f3c40SMeador Inge 
1838f1f3c40SMeador Inge   // If a symbol was in PROVIDE(), we need to define it only when
1848f1f3c40SMeador Inge   // it is a referenced undefined symbol.
185a8dba487SGeorge Rimar   SymbolBody *B = findSymbol(Cmd->Name);
1868f1f3c40SMeador Inge   if (Cmd->Provide && (!B || B->isDefined()))
1878f1f3c40SMeador Inge     return;
1888f1f3c40SMeador Inge 
189a8dba487SGeorge Rimar   Cmd->Sym = addRegularSymbol(Cmd);
190ceabe80eSEugene Leviant }
191ceabe80eSEugene Leviant 
192076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
193076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
194076fe157SGeorge Rimar }
195076fe157SGeorge Rimar 
196076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
197076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
198076fe157SGeorge Rimar }
199076fe157SGeorge Rimar 
20055b169bfSRafael Espindola // Fill [Buf, Buf + Size) with Filler.
20155b169bfSRafael Espindola // This is used for linker script "=fillexp" command.
20255b169bfSRafael Espindola static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {
20355b169bfSRafael Espindola   size_t I = 0;
20455b169bfSRafael Espindola   for (; I + 4 < Size; I += 4)
20555b169bfSRafael Espindola     memcpy(Buf + I, &Filler, 4);
20655b169bfSRafael Espindola   memcpy(Buf + I, &Filler, Size - I);
20755b169bfSRafael Espindola }
20855b169bfSRafael Espindola 
209eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
210eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
211eea3114fSGeorge Rimar }
212eea3114fSGeorge Rimar 
213eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) {
214eefa758eSGeorge Rimar   return C->Kind == AssertKind;
215eefa758eSGeorge Rimar }
216eefa758eSGeorge Rimar 
217e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) {
218e38cbab5SGeorge Rimar   return C->Kind == BytesDataKind;
219e38cbab5SGeorge Rimar }
220e38cbab5SGeorge Rimar 
221b4c9b81aSRafael Espindola static StringRef basename(InputSectionBase *S) {
222b4c9b81aSRafael Espindola   if (S->File)
223b4c9b81aSRafael Espindola     return sys::path::filename(S->File->getName());
224e0be2901SRui Ueyama   return "";
225e0be2901SRui Ueyama }
226e0be2901SRui Ueyama 
227b8dd23f5SRui Ueyama bool LinkerScript::shouldKeep(InputSectionBase *S) {
228e0be2901SRui Ueyama   for (InputSectionDescription *ID : Opt.KeptSections)
229e0be2901SRui Ueyama     if (ID->FilePat.match(basename(S)))
230cf43f179SEugene Leviant       for (SectionPattern &P : ID->SectionPatterns)
231f91282e1SRui Ueyama         if (P.SectionPat.match(S->Name))
232eea3114fSGeorge Rimar           return true;
233eea3114fSGeorge Rimar   return false;
234eea3114fSGeorge Rimar }
235eea3114fSGeorge Rimar 
236ea93fe00SRui Ueyama // A helper function for the SORT() command.
237c404d50dSRafael Espindola static std::function<bool(InputSectionBase *, InputSectionBase *)>
238be394db3SGeorge Rimar getComparator(SortSectionPolicy K) {
239be394db3SGeorge Rimar   switch (K) {
240be394db3SGeorge Rimar   case SortSectionPolicy::Alignment:
241ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
242ea93fe00SRui Ueyama       // ">" is not a mistake. Sections with larger alignments are placed
243ea93fe00SRui Ueyama       // before sections with smaller alignments in order to reduce the
244ea93fe00SRui Ueyama       // amount of padding necessary. This is compatible with GNU.
245ea93fe00SRui Ueyama       return A->Alignment > B->Alignment;
246ea93fe00SRui Ueyama     };
247be394db3SGeorge Rimar   case SortSectionPolicy::Name:
248ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
249ea93fe00SRui Ueyama       return A->Name < B->Name;
250ea93fe00SRui Ueyama     };
251be394db3SGeorge Rimar   case SortSectionPolicy::Priority:
252ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
253ea93fe00SRui Ueyama       return getPriority(A->Name) < getPriority(B->Name);
254ea93fe00SRui Ueyama     };
255be394db3SGeorge Rimar   default:
256be394db3SGeorge Rimar     llvm_unreachable("unknown sort policy");
257be394db3SGeorge Rimar   }
258742c3836SRui Ueyama }
2590702c4e8SGeorge Rimar 
260ea93fe00SRui Ueyama // A helper function for the SORT() command.
261b4c9b81aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase *> Sections,
26206ae6836SGeorge Rimar                              ConstraintKind Kind) {
2638f66df92SGeorge Rimar   if (Kind == ConstraintKind::NoConstraint)
2648f66df92SGeorge Rimar     return true;
2652c7171bfSRui Ueyama 
2662c7171bfSRui Ueyama   bool IsRW = llvm::any_of(Sections, [](InputSectionBase *Sec) {
2672c7171bfSRui Ueyama     return static_cast<InputSectionBase *>(Sec)->Flags & SHF_WRITE;
26806ae6836SGeorge Rimar   });
2692c7171bfSRui Ueyama 
270e746e52cSRafael Espindola   return (IsRW && Kind == ConstraintKind::ReadWrite) ||
271e746e52cSRafael Espindola          (!IsRW && Kind == ConstraintKind::ReadOnly);
27206ae6836SGeorge Rimar }
27306ae6836SGeorge Rimar 
2746a1aa8d9SRafael Espindola static void sortSections(InputSection **Begin, InputSection **End,
275ee924709SRui Ueyama                          SortSectionPolicy K) {
276ee924709SRui Ueyama   if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
27707171f21SGeorge Rimar     std::stable_sort(Begin, End, getComparator(K));
278ee924709SRui Ueyama }
279ee924709SRui Ueyama 
280d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches.
2816a1aa8d9SRafael Espindola std::vector<InputSection *>
28272e107f3SRui Ueyama LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
2836a1aa8d9SRafael Espindola   std::vector<InputSection *> Ret;
2848c6a5aafSRui Ueyama 
28572e107f3SRui Ueyama   // Collects all sections that satisfy constraints of Cmd.
28672e107f3SRui Ueyama   for (const SectionPattern &Pat : Cmd->SectionPatterns) {
28772e107f3SRui Ueyama     size_t SizeBefore = Ret.size();
28872e107f3SRui Ueyama 
28972e107f3SRui Ueyama     for (InputSectionBase *Sec : InputSections) {
29072e107f3SRui Ueyama       if (Sec->Assigned)
2918c6a5aafSRui Ueyama         continue;
29272e107f3SRui Ueyama 
293e39709b2SRafael Espindola       if (!Sec->Live) {
294e39709b2SRafael Espindola         reportDiscarded(Sec);
295e39709b2SRafael Espindola         continue;
296e39709b2SRafael Espindola       }
297e39709b2SRafael Espindola 
298908a3d34SRafael Espindola       // For -emit-relocs we have to ignore entries like
299908a3d34SRafael Espindola       //   .rela.dyn : { *(.rela.data) }
300908a3d34SRafael Espindola       // which are common because they are in the default bfd script.
30172e107f3SRui Ueyama       if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
302908a3d34SRafael Espindola         continue;
3038c6a5aafSRui Ueyama 
30472e107f3SRui Ueyama       StringRef Filename = basename(Sec);
30572e107f3SRui Ueyama       if (!Cmd->FilePat.match(Filename) ||
30672e107f3SRui Ueyama           Pat.ExcludedFilePat.match(Filename) ||
30772e107f3SRui Ueyama           !Pat.SectionPat.match(Sec->Name))
308e0be2901SRui Ueyama         continue;
30972e107f3SRui Ueyama 
3106a1aa8d9SRafael Espindola       Ret.push_back(cast<InputSection>(Sec));
31172e107f3SRui Ueyama       Sec->Assigned = true;
312f94efdddSRui Ueyama     }
313d3190795SRafael Espindola 
314ee924709SRui Ueyama     // Sort sections as instructed by SORT-family commands and --sort-section
315ee924709SRui Ueyama     // option. Because SORT-family commands can be nested at most two depth
316ee924709SRui Ueyama     // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
317ee924709SRui Ueyama     // line option is respected even if a SORT command is given, the exact
318ee924709SRui Ueyama     // behavior we have here is a bit complicated. Here are the rules.
319ee924709SRui Ueyama     //
320ee924709SRui Ueyama     // 1. If two SORT commands are given, --sort-section is ignored.
321ee924709SRui Ueyama     // 2. If one SORT command is given, and if it is not SORT_NONE,
322ee924709SRui Ueyama     //    --sort-section is handled as an inner SORT command.
323ee924709SRui Ueyama     // 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
324ee924709SRui Ueyama     // 4. If no SORT command is given, sort according to --sort-section.
3256a1aa8d9SRafael Espindola     InputSection **Begin = Ret.data() + SizeBefore;
3266a1aa8d9SRafael Espindola     InputSection **End = Ret.data() + Ret.size();
32707171f21SGeorge Rimar     if (Pat.SortOuter != SortSectionPolicy::None) {
32807171f21SGeorge Rimar       if (Pat.SortInner == SortSectionPolicy::Default)
32907171f21SGeorge Rimar         sortSections(Begin, End, Config->SortSection);
330ee924709SRui Ueyama       else
33107171f21SGeorge Rimar         sortSections(Begin, End, Pat.SortInner);
33207171f21SGeorge Rimar       sortSections(Begin, End, Pat.SortOuter);
33307171f21SGeorge Rimar     }
334ee924709SRui Ueyama   }
33572e107f3SRui Ueyama   return Ret;
336be94e1b6SRafael Espindola }
337be94e1b6SRafael Espindola 
338b8dd23f5SRui Ueyama void LinkerScript::discard(ArrayRef<InputSectionBase *> V) {
339b4c9b81aSRafael Espindola   for (InputSectionBase *S : V) {
340be94e1b6SRafael Espindola     S->Live = false;
3414f1fca27SRafael Espindola     if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab ||
3424f1fca27SRafael Espindola         S == InX::DynStrTab)
3432af64b0bSRafael Espindola       error("discarding " + S->Name + " section is not allowed");
344647c1685SGeorge Rimar     discard(S->DependentSections);
345be94e1b6SRafael Espindola   }
346be94e1b6SRafael Espindola }
347be94e1b6SRafael Espindola 
348b4c9b81aSRafael Espindola std::vector<InputSectionBase *>
349b8dd23f5SRui Ueyama LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) {
350b4c9b81aSRafael Espindola   std::vector<InputSectionBase *> Ret;
351e7f912cdSRui Ueyama 
3528f99f73cSRui Ueyama   for (BaseCommand *Base : OutCmd.Commands) {
3538f99f73cSRui Ueyama     auto *Cmd = dyn_cast<InputSectionDescription>(Base);
3547c3ff2ebSRafael Espindola     if (!Cmd)
3550b9ce6a4SRui Ueyama       continue;
35672e107f3SRui Ueyama 
35772e107f3SRui Ueyama     Cmd->Sections = computeInputSections(Cmd);
358e4c8b9b7SRafael Espindola     Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end());
3590b9ce6a4SRui Ueyama   }
360e71a3f8aSRafael Espindola 
3610b9ce6a4SRui Ueyama   return Ret;
3620b9ce6a4SRui Ueyama }
3630b9ce6a4SRui Ueyama 
364b8dd23f5SRui Ueyama void LinkerScript::processCommands(OutputSectionFactory &Factory) {
3655616adf6SRafael Espindola   // A symbol can be assigned before any section is mentioned in the linker
3665616adf6SRafael Espindola   // script. In an DSO, the symbol values are addresses, so the only important
3675616adf6SRafael Espindola   // section values are:
3685616adf6SRafael Espindola   // * SHN_UNDEF
3695616adf6SRafael Espindola   // * SHN_ABS
3705616adf6SRafael Espindola   // * Any value meaning a regular section.
3715616adf6SRafael Espindola   // To handle that, create a dummy aether section that fills the void before
3725616adf6SRafael Espindola   // the linker scripts switches to another section. It has an index of one
3735616adf6SRafael Espindola   // which will map to whatever the first actual section is.
3745616adf6SRafael Espindola   Aether = make<OutputSection>("", 0, SHF_ALLOC);
3755616adf6SRafael Espindola   Aether->SectionIndex = 1;
3765616adf6SRafael Espindola   CurOutSec = Aether;
37749592cf6SRafael Espindola   Dot = 0;
3785616adf6SRafael Espindola 
37992a5ba6dSRui Ueyama   for (size_t I = 0; I < Opt.Commands.size(); ++I) {
3800b1b695aSRui Ueyama     // Handle symbol assignments outside of any output section.
38192a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Opt.Commands[I])) {
3824cd7352cSRafael Espindola       addSymbol(Cmd);
3832ab5f73dSRui Ueyama       continue;
3842ab5f73dSRui Ueyama     }
3850b1b695aSRui Ueyama 
38692a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I])) {
387b4c9b81aSRafael Espindola       std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
3887bd37870SRafael Espindola 
3890b1b695aSRui Ueyama       // The output section name `/DISCARD/' is special.
3900b1b695aSRui Ueyama       // Any input section assigned to it is discarded.
39148c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
3927bd37870SRafael Espindola         discard(V);
39348c3f1ceSRui Ueyama         continue;
39448c3f1ceSRui Ueyama       }
3950b9ce6a4SRui Ueyama 
3960b1b695aSRui Ueyama       // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
3970b1b695aSRui Ueyama       // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
3980b1b695aSRui Ueyama       // sections satisfy a given constraint. If not, a directive is handled
39907d7c42cSGeorge Rimar       // as if it wasn't present from the beginning.
4000b1b695aSRui Ueyama       //
4010b1b695aSRui Ueyama       // Because we'll iterate over Commands many more times, the easiest
40207d7c42cSGeorge Rimar       // way to "make it as if it wasn't present" is to just remove it.
403f7f0d088SGeorge Rimar       if (!matchConstraints(V, Cmd->Constraint)) {
404b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
405f94efdddSRui Ueyama           S->Assigned = false;
40692a5ba6dSRui Ueyama         Opt.Commands.erase(Opt.Commands.begin() + I);
40707d7c42cSGeorge Rimar         --I;
4087c3ff2ebSRafael Espindola         continue;
4097c3ff2ebSRafael Espindola       }
4107c3ff2ebSRafael Espindola 
4110b1b695aSRui Ueyama       // A directive may contain symbol definitions like this:
4120b1b695aSRui Ueyama       // ".foo : { ...; bar = .; }". Handle them.
4138f99f73cSRui Ueyama       for (BaseCommand *Base : Cmd->Commands)
4148f99f73cSRui Ueyama         if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
4154cd7352cSRafael Espindola           addSymbol(OutCmd);
4167c3ff2ebSRafael Espindola 
4170b1b695aSRui Ueyama       // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
4180b1b695aSRui Ueyama       // is given, input sections are aligned to that value, whether the
4190b1b695aSRui Ueyama       // given value is larger or smaller than the original section alignment.
4200b1b695aSRui Ueyama       if (Cmd->SubalignExpr) {
42172dc195dSRafael Espindola         uint32_t Subalign = Cmd->SubalignExpr().getValue();
422b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
4230b1b695aSRui Ueyama           S->Alignment = Subalign;
42420d03194SEugene Leviant       }
4250b1b695aSRui Ueyama 
4260b1b695aSRui Ueyama       // Add input sections to an output section.
427d86a4e50SGeorge Rimar       for (InputSectionBase *S : V)
4284f013bb3SRafael Espindola         Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
429660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
430660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX);
431660c9ab9SRafael Espindola         Sec->SectionIndex = I;
432fbb0463fSGeorge Rimar         if (Cmd->Noload)
433fbb0463fSGeorge Rimar           Sec->Type = SHT_NOBITS;
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
445e76231b6SRafael Espindola   uint64_t StartAddr = -1;
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 
453e76231b6SRafael Espindola   Commands.push_back(make<SymbolAssignment>(
454e76231b6SRafael Espindola       ".",
455e76231b6SRafael Espindola       [=] {
456e76231b6SRafael Espindola         return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize());
457e76231b6SRafael Espindola       },
458e76231b6SRafael Espindola       ""));
459cbfe9e94SPeter Smith 
460cbfe9e94SPeter Smith   // For each OutputSection that needs a VA fabricate an OutputSectionCommand
461cbfe9e94SPeter Smith   // with an InputSectionDescription describing the InputSections
462f51c8055SRafael Espindola   for (OutputSection *Sec : OutputSections) {
46305c4f67cSRafael Espindola     auto *OSCmd = createOutputSectionCommand(Sec->Name, "<internal>");
464c60b4510SPeter Smith     OSCmd->Sec = Sec;
465d7dc2258SRafael Espindola     SecToCommand[Sec] = OSCmd;
466c60b4510SPeter Smith 
467cbfe9e94SPeter Smith     Commands.push_back(OSCmd);
468cbfe9e94SPeter Smith     if (Sec->Sections.size()) {
469cbfe9e94SPeter Smith       auto *ISD = make<InputSectionDescription>("");
470cbfe9e94SPeter Smith       OSCmd->Commands.push_back(ISD);
471cbfe9e94SPeter Smith       for (InputSection *ISec : Sec->Sections) {
472cbfe9e94SPeter Smith         ISD->Sections.push_back(ISec);
473cbfe9e94SPeter Smith         ISec->Assigned = true;
474cbfe9e94SPeter Smith       }
475cbfe9e94SPeter Smith     }
476cbfe9e94SPeter Smith   }
477cbfe9e94SPeter Smith   // SECTIONS commands run before other non SECTIONS commands
478cbfe9e94SPeter Smith   Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end());
479cbfe9e94SPeter Smith   Opt.Commands = std::move(Commands);
480cbfe9e94SPeter Smith }
481cbfe9e94SPeter Smith 
4820b1b695aSRui Ueyama // Add sections that didn't match any sections command.
483b8dd23f5SRui Ueyama void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
4844f013bb3SRafael Espindola   for (InputSectionBase *S : InputSections) {
485db5e56f7SRafael Espindola     if (!S->Live || S->Parent)
4864f013bb3SRafael Espindola       continue;
4874f013bb3SRafael Espindola     StringRef Name = getOutputSectionName(S->Name);
488a951d5c4SGeorge Rimar     auto I = llvm::find_if(Opt.Commands, [&](BaseCommand *Base) {
4894f013bb3SRafael Espindola       if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
4904f013bb3SRafael Espindola         return Cmd->Name == Name;
4914f013bb3SRafael Espindola       return false;
4924f013bb3SRafael Espindola     });
493de8d9897SRafael Espindola     if (I == Opt.Commands.end()) {
4944f013bb3SRafael Espindola       Factory.addInputSec(S, Name);
495de8d9897SRafael Espindola     } else {
496de8d9897SRafael Espindola       auto *Cmd = cast<OutputSectionCommand>(*I);
497de8d9897SRafael Espindola       Factory.addInputSec(S, Name, Cmd->Sec);
498660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
499d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
500660c9ab9SRafael Espindola         unsigned Index = std::distance(Opt.Commands.begin(), I);
501660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index);
502660c9ab9SRafael Espindola         Sec->SectionIndex = Index;
503660c9ab9SRafael Espindola       }
504de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
5056a1aa8d9SRafael Espindola       ISD->Sections.push_back(cast<InputSection>(S));
506de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
507de8d9897SRafael Espindola     }
5084f013bb3SRafael Espindola   }
509e63d81bdSEugene Leviant }
510e63d81bdSEugene Leviant 
5117c4eafa3SRafael Espindola uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
5127c4eafa3SRafael Espindola   bool IsTbss = (CurOutSec->Flags & SHF_TLS) && CurOutSec->Type == SHT_NOBITS;
5137c4eafa3SRafael Espindola   uint64_t Start = IsTbss ? Dot + ThreadBssOffset : Dot;
5147c4eafa3SRafael Espindola   Start = alignTo(Start, Align);
5157c4eafa3SRafael Espindola   uint64_t End = Start + Size;
5167c4eafa3SRafael Espindola 
5177c4eafa3SRafael Espindola   if (IsTbss)
5187c4eafa3SRafael Espindola     ThreadBssOffset = End - Dot;
5197c4eafa3SRafael Espindola   else
5207c4eafa3SRafael Espindola     Dot = End;
5217c4eafa3SRafael Espindola   return End;
522a940e539SRafael Espindola }
523a940e539SRafael Espindola 
524b8dd23f5SRui Ueyama void LinkerScript::output(InputSection *S) {
5257c4eafa3SRafael Espindola   uint64_t Pos = advance(S->getSize(), S->Alignment);
5267c4eafa3SRafael Espindola   S->OutSecOff = Pos - S->getSize() - CurOutSec->Addr;
527d3190795SRafael Espindola 
528d3190795SRafael Espindola   // Update output section size after adding each section. This is so that
529d3190795SRafael Espindola   // SIZEOF works correctly in the case below:
530d3190795SRafael Espindola   // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
53104a2e348SRafael Espindola   CurOutSec->Size = Pos - CurOutSec->Addr;
532d3190795SRafael Espindola 
533b889744eSMeador Inge   // If there is a memory region associated with this input section, then
534b889744eSMeador Inge   // place the section in that region and update the region index.
535b889744eSMeador Inge   if (CurMemRegion) {
536b889744eSMeador Inge     CurMemRegion->Offset += CurOutSec->Size;
537b889744eSMeador Inge     uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin;
538b889744eSMeador Inge     if (CurSize > CurMemRegion->Length) {
539b889744eSMeador Inge       uint64_t OverflowAmt = CurSize - CurMemRegion->Length;
540b889744eSMeador Inge       error("section '" + CurOutSec->Name + "' will not fit in region '" +
541b889744eSMeador Inge             CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
542b889744eSMeador Inge             " bytes");
543b889744eSMeador Inge     }
544b889744eSMeador Inge   }
5452de509c3SRui Ueyama }
546ceabe80eSEugene Leviant 
547b8dd23f5SRui Ueyama void LinkerScript::switchTo(OutputSection *Sec) {
548d3190795SRafael Espindola   if (CurOutSec == Sec)
549d3190795SRafael Espindola     return;
550d3190795SRafael Espindola 
551d3190795SRafael Espindola   CurOutSec = Sec;
5527c4eafa3SRafael Espindola   CurOutSec->Addr = advance(0, CurOutSec->Alignment);
553b71d6f7aSEugene Leviant 
554b71d6f7aSEugene Leviant   // If neither AT nor AT> is specified for an allocatable section, the linker
555b71d6f7aSEugene Leviant   // will set the LMA such that the difference between VMA and LMA for the
556b71d6f7aSEugene Leviant   // section is the same as the preceding output section in the same region
557b71d6f7aSEugene Leviant   // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
55821467876SGeorge Rimar   if (LMAOffset)
55929c1afb8SRafael Espindola     CurOutSec->LMAOffset = LMAOffset();
560d3190795SRafael Espindola }
561d3190795SRafael Espindola 
562b8dd23f5SRui Ueyama void LinkerScript::process(BaseCommand &Base) {
5632e081a4fSRui Ueyama   // This handles the assignments to symbol or to the dot.
5642e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<SymbolAssignment>(&Base)) {
5652e081a4fSRui Ueyama     assignSymbol(Cmd, true);
566d3190795SRafael Espindola     return;
56797403d15SEugene Leviant   }
568e38cbab5SGeorge Rimar 
569e38cbab5SGeorge Rimar   // Handle BYTE(), SHORT(), LONG(), or QUAD().
5702e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) {
5712e081a4fSRui Ueyama     Cmd->Offset = Dot - CurOutSec->Addr;
5722e081a4fSRui Ueyama     Dot += Cmd->Size;
57304a2e348SRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
574e38cbab5SGeorge Rimar     return;
575e38cbab5SGeorge Rimar   }
576e38cbab5SGeorge Rimar 
5772e081a4fSRui Ueyama   // Handle ASSERT().
5782e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<AssertCommand>(&Base)) {
5792e081a4fSRui Ueyama     Cmd->Expression();
580b2d99d6aSMeador Inge     return;
581b2d99d6aSMeador Inge   }
582b2d99d6aSMeador Inge 
5832e081a4fSRui Ueyama   // Handle a single input section description command.
5842e081a4fSRui Ueyama   // It calculates and assigns the offsets for each section and also
585e38cbab5SGeorge Rimar   // updates the output section size.
5862e081a4fSRui Ueyama   auto &Cmd = cast<InputSectionDescription>(Base);
587a85e8ddaSRafael Espindola   for (InputSection *Sec : Cmd.Sections) {
5883fb5a6dcSGeorge Rimar     // We tentatively added all synthetic sections at the beginning and removed
5893fb5a6dcSGeorge Rimar     // empty ones afterwards (because there is no way to know whether they were
5903fb5a6dcSGeorge Rimar     // going be empty or not other than actually running linker scripts.)
5913fb5a6dcSGeorge Rimar     // We need to ignore remains of empty sections.
5922e081a4fSRui Ueyama     if (auto *S = dyn_cast<SyntheticSection>(Sec))
5932e081a4fSRui Ueyama       if (S->empty())
5943fb5a6dcSGeorge Rimar         continue;
5953fb5a6dcSGeorge Rimar 
5962e081a4fSRui Ueyama     if (!Sec->Live)
59778ef645fSGeorge Rimar       continue;
598db5e56f7SRafael Espindola     assert(CurOutSec == Sec->getParent());
599a85e8ddaSRafael Espindola     output(Sec);
600ceabe80eSEugene Leviant   }
601ceabe80eSEugene Leviant }
602ceabe80eSEugene Leviant 
603b889744eSMeador Inge // This function searches for a memory region to place the given output
604b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is
605b889744eSMeador Inge // returned. Otherwise, a nullptr is returned.
6061902b337SRafael Espindola MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd) {
607b889744eSMeador Inge   // If a memory region name was specified in the output section command,
608b889744eSMeador Inge   // then try to find that region first.
609b889744eSMeador Inge   if (!Cmd->MemoryRegionName.empty()) {
610b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
611b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
612b889744eSMeador Inge       return &It->second;
613b889744eSMeador Inge     error("memory region '" + Cmd->MemoryRegionName + "' not declared");
614b889744eSMeador Inge     return nullptr;
615b889744eSMeador Inge   }
616b889744eSMeador Inge 
617d7c5400fSRui Ueyama   // If at least one memory region is defined, all sections must
618d7c5400fSRui Ueyama   // belong to some memory region. Otherwise, we don't need to do
619d7c5400fSRui Ueyama   // anything for memory regions.
620cc400cc8SRui Ueyama   if (Opt.MemoryRegions.empty())
621b889744eSMeador Inge     return nullptr;
622b889744eSMeador Inge 
6231902b337SRafael Espindola   OutputSection *Sec = Cmd->Sec;
624b889744eSMeador Inge   // See if a region can be found by matching section flags.
6252e081a4fSRui Ueyama   for (auto &Pair : Opt.MemoryRegions) {
6262e081a4fSRui Ueyama     MemoryRegion &M = Pair.second;
6272e081a4fSRui Ueyama     if ((M.Flags & Sec->Flags) && (M.NegFlags & Sec->Flags) == 0)
6282e081a4fSRui Ueyama       return &M;
629b889744eSMeador Inge   }
630b889744eSMeador Inge 
631b889744eSMeador Inge   // Otherwise, no suitable region was found.
632b889744eSMeador Inge   if (Sec->Flags & SHF_ALLOC)
633b889744eSMeador Inge     error("no memory region specified for section '" + Sec->Name + "'");
634b889744eSMeador Inge   return nullptr;
635b889744eSMeador Inge }
636b889744eSMeador Inge 
6370b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section
6380b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }").
639b8dd23f5SRui Ueyama void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) {
6409b980095SRafael Espindola   OutputSection *Sec = Cmd->Sec;
6412b074553SRafael Espindola   if (!Sec)
642d3190795SRafael Espindola     return;
643b889744eSMeador Inge 
644dece2808SRafael Espindola   if (!(Sec->Flags & SHF_ALLOC))
645dece2808SRafael Espindola     Dot = 0;
646dece2808SRafael Espindola   else if (Cmd->AddrExpr)
647d379f735SRui Ueyama     setDot(Cmd->AddrExpr, Cmd->Location, false);
648679828ffSRafael Espindola 
6495784e96fSEugene Leviant   if (Cmd->LMAExpr) {
6500c1c8085SGeorge Rimar     uint64_t D = Dot;
65172dc195dSRafael Espindola     LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; };
6525784e96fSEugene Leviant   }
6535784e96fSEugene Leviant 
654feed7506SRafael Espindola   CurMemRegion = Cmd->MemRegion;
655b889744eSMeador Inge   if (CurMemRegion)
656b889744eSMeador Inge     Dot = CurMemRegion->Offset;
657b889744eSMeador Inge   switchTo(Sec);
6580b1b695aSRui Ueyama 
659d86a4e50SGeorge Rimar   // We do not support custom layout for compressed debug sectons.
660d86a4e50SGeorge Rimar   // At this point we already know their size and have compressed content.
661d86a4e50SGeorge Rimar   if (CurOutSec->Flags & SHF_COMPRESSED)
662d86a4e50SGeorge Rimar     return;
663d86a4e50SGeorge Rimar 
664de8d9897SRafael Espindola   for (BaseCommand *C : Cmd->Commands)
665de8d9897SRafael Espindola     process(*C);
666d3190795SRafael Espindola }
667d3190795SRafael Espindola 
668b8dd23f5SRui Ueyama void LinkerScript::removeEmptyCommands() {
6696d38e4dbSRafael Espindola   // It is common practice to use very generic linker scripts. So for any
6706d38e4dbSRafael Espindola   // given run some of the output sections in the script will be empty.
6716d38e4dbSRafael Espindola   // We could create corresponding empty output sections, but that would
6726d38e4dbSRafael Espindola   // clutter the output.
6736d38e4dbSRafael Espindola   // We instead remove trivially empty sections. The bfd linker seems even
6746d38e4dbSRafael Espindola   // more aggressive at removing them.
6756d38e4dbSRafael Espindola   auto Pos = std::remove_if(
6768f99f73cSRui Ueyama       Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
6778f99f73cSRui Ueyama         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
678e86fddd6SRafael Espindola           return Cmd->Sec == nullptr;
6790b1b695aSRui Ueyama         return false;
6806d38e4dbSRafael Espindola       });
6816d38e4dbSRafael Espindola   Opt.Commands.erase(Pos, Opt.Commands.end());
68207fe6129SRafael Espindola }
68307fe6129SRafael Espindola 
6846a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
6858f99f73cSRui Ueyama   for (BaseCommand *Base : Cmd.Commands)
6868f99f73cSRui Ueyama     if (!isa<InputSectionDescription>(*Base))
6876a53737cSRafael Espindola       return false;
6886a53737cSRafael Espindola   return true;
6896a53737cSRafael Espindola }
6906d38e4dbSRafael Espindola 
691b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsBeforeSorting() {
6929546fffbSRafael Espindola   // If the output section contains only symbol assignments, create a
6939546fffbSRafael Espindola   // corresponding output section. The bfd linker seems to only create them if
6949546fffbSRafael Espindola   // '.' is assigned to, but creating these section should not have any bad
6959546fffbSRafael Espindola   // consequeces and gives us a section to put the symbol in.
6960c1c8085SGeorge Rimar   uint64_t Flags = SHF_ALLOC;
697660c9ab9SRafael Espindola 
698660c9ab9SRafael Espindola   for (int I = 0, E = Opt.Commands.size(); I != E; ++I) {
699660c9ab9SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
7009546fffbSRafael Espindola     if (!Cmd)
7019546fffbSRafael Espindola       continue;
7024f013bb3SRafael Espindola     if (OutputSection *Sec = Cmd->Sec) {
7032b074553SRafael Espindola       Flags = Sec->Flags;
7049546fffbSRafael Espindola       continue;
7059546fffbSRafael Espindola     }
7069546fffbSRafael Espindola 
7076a53737cSRafael Espindola     if (isAllSectionDescription(*Cmd))
7086a53737cSRafael Espindola       continue;
7096a53737cSRafael Espindola 
710fd0c844fSDmitry Mikulin     auto *OutSec = make<OutputSection>(Cmd->Name, SHT_PROGBITS, Flags);
711660c9ab9SRafael Espindola     OutSec->SectionIndex = I;
7129b980095SRafael Espindola     Cmd->Sec = OutSec;
713d7dc2258SRafael Espindola     SecToCommand[OutSec] = Cmd;
7149546fffbSRafael Espindola   }
715f7a17448SRafael Espindola }
716f7a17448SRafael Espindola 
717b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsAfterSorting() {
718feed7506SRafael Espindola   // Try and find an appropriate memory region to assign offsets in.
719d1960dc0SRafael Espindola   for (BaseCommand *Base : Opt.Commands) {
720d1960dc0SRafael Espindola     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) {
721feed7506SRafael Espindola       Cmd->MemRegion = findMemoryRegion(Cmd);
722d1960dc0SRafael Espindola       // Handle align (e.g. ".foo : ALIGN(16) { ... }").
723d1960dc0SRafael Espindola       if (Cmd->AlignExpr)
724d1960dc0SRafael Espindola 	Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue());
725d1960dc0SRafael Espindola     }
726d1960dc0SRafael Espindola   }
727feed7506SRafael Espindola 
728f7a17448SRafael Espindola   // If output section command doesn't specify any segments,
729f7a17448SRafael Espindola   // and we haven't previously assigned any section to segment,
730f7a17448SRafael Espindola   // then we simply assign section to the very first load segment.
731f7a17448SRafael Espindola   // Below is an example of such linker script:
732f7a17448SRafael Espindola   // PHDRS { seg PT_LOAD; }
733f7a17448SRafael Espindola   // SECTIONS { .aaa : { *(.aaa) } }
734f7a17448SRafael Espindola   std::vector<StringRef> DefPhdrs;
735f7a17448SRafael Espindola   auto FirstPtLoad =
736f7a17448SRafael Espindola       std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(),
737f7a17448SRafael Espindola                    [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; });
738f7a17448SRafael Espindola   if (FirstPtLoad != Opt.PhdrsCommands.end())
739f7a17448SRafael Espindola     DefPhdrs.push_back(FirstPtLoad->Name);
740f7a17448SRafael Espindola 
741f7a17448SRafael Espindola   // Walk the commands and propagate the program headers to commands that don't
742f7a17448SRafael Espindola   // explicitly specify them.
7438f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
7448f99f73cSRui Ueyama     auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
745f7a17448SRafael Espindola     if (!Cmd)
746f7a17448SRafael Espindola       continue;
7478f99f73cSRui Ueyama 
748a020d348SAndrew Ng     if (Cmd->Phdrs.empty()) {
749a020d348SAndrew Ng       OutputSection *Sec = Cmd->Sec;
750a020d348SAndrew Ng       // To match the bfd linker script behaviour, only propagate program
751a020d348SAndrew Ng       // headers to sections that are allocated.
752a020d348SAndrew Ng       if (Sec && (Sec->Flags & SHF_ALLOC))
753f7a17448SRafael Espindola         Cmd->Phdrs = DefPhdrs;
754a020d348SAndrew Ng     } else {
755f7a17448SRafael Espindola       DefPhdrs = Cmd->Phdrs;
756f7a17448SRafael Espindola     }
757a020d348SAndrew Ng   }
7586a53737cSRafael Espindola 
7596a53737cSRafael Espindola   removeEmptyCommands();
7609546fffbSRafael Espindola }
7619546fffbSRafael Espindola 
762383971d2SRafael Espindola void LinkerScript::createOrphanCommands() {
763f51c8055SRafael Espindola   for (OutputSection *Sec : OutputSections) {
764383971d2SRafael Espindola     if (Sec->SectionIndex != INT_MAX)
765383971d2SRafael Espindola       continue;
766383971d2SRafael Espindola     OutputSectionCommand *Cmd =
767383971d2SRafael Espindola         createOutputSectionCommand(Sec->Name, "<internal>");
768de8d9897SRafael Espindola     Cmd->Sec = Sec;
769d7dc2258SRafael Espindola     SecToCommand[Sec] = Cmd;
770de8d9897SRafael Espindola     auto *ISD = make<InputSectionDescription>("");
771383971d2SRafael Espindola     ISD->Sections = Sec->Sections;
772de8d9897SRafael Espindola     Cmd->Commands.push_back(ISD);
773383971d2SRafael Espindola     Opt.Commands.push_back(Cmd);
774652852c5SGeorge Rimar   }
775337f903cSRafael Espindola }
776337f903cSRafael Espindola 
777b8dd23f5SRui Ueyama void LinkerScript::processNonSectionCommands() {
7788f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
7798f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
780d379f735SRui Ueyama       assignSymbol(Cmd, false);
7818f99f73cSRui Ueyama     else if (auto *Cmd = dyn_cast<AssertCommand>(Base))
78202ad516bSPetr Hosek       Cmd->Expression();
78302ad516bSPetr Hosek   }
78402ad516bSPetr Hosek }
78502ad516bSPetr Hosek 
786*5aedebffSPeter Smith void LinkerScript::allocateHeaders(std::vector<PhdrEntry> &Phdrs) {
787*5aedebffSPeter Smith   uint64_t Min = std::numeric_limits<uint64_t>::max();
788*5aedebffSPeter Smith   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
789*5aedebffSPeter Smith     OutputSection *Sec = Cmd->Sec;
790*5aedebffSPeter Smith     if (Sec->Flags & SHF_ALLOC)
791*5aedebffSPeter Smith       Min = std::min<uint64_t>(Min, Sec->Addr);
792*5aedebffSPeter Smith   }
793*5aedebffSPeter Smith 
794d971e703SGeorge Rimar   auto FirstPTLoad = llvm::find_if(
795d971e703SGeorge Rimar       Phdrs, [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
79602ed7575SRafael Espindola   if (FirstPTLoad == Phdrs.end())
797d971e703SGeorge Rimar     return;
79802ed7575SRafael Espindola 
79902ed7575SRafael Espindola   uint64_t HeaderSize = getHeaderSize();
80002ed7575SRafael Espindola   if (HeaderSize <= Min || Script->hasPhdrsCommands()) {
80102ed7575SRafael Espindola     Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
80202ed7575SRafael Espindola     Out::ElfHeader->Addr = Min;
80302ed7575SRafael Espindola     Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
804d971e703SGeorge Rimar     return;
80502ed7575SRafael Espindola   }
80602ed7575SRafael Espindola 
80702ed7575SRafael Espindola   assert(FirstPTLoad->First == Out::ElfHeader);
80802ed7575SRafael Espindola   OutputSection *ActualFirst = nullptr;
809faf25a72SRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
810faf25a72SRafael Espindola     OutputSection *Sec = Cmd->Sec;
81102ed7575SRafael Espindola     if (Sec->FirstInPtLoad == Out::ElfHeader) {
81202ed7575SRafael Espindola       ActualFirst = Sec;
81302ed7575SRafael Espindola       break;
81402ed7575SRafael Espindola     }
81502ed7575SRafael Espindola   }
81602ed7575SRafael Espindola   if (ActualFirst) {
817faf25a72SRafael Espindola     for (OutputSectionCommand *Cmd : OutputSectionCommands) {
818faf25a72SRafael Espindola       OutputSection *Sec = Cmd->Sec;
81902ed7575SRafael Espindola       if (Sec->FirstInPtLoad == Out::ElfHeader)
82002ed7575SRafael Espindola         Sec->FirstInPtLoad = ActualFirst;
821faf25a72SRafael Espindola     }
82202ed7575SRafael Espindola     FirstPTLoad->First = ActualFirst;
82302ed7575SRafael Espindola   } else {
82402ed7575SRafael Espindola     Phdrs.erase(FirstPTLoad);
82502ed7575SRafael Espindola   }
82602ed7575SRafael Espindola 
827d971e703SGeorge Rimar   auto PhdrI = llvm::find_if(
828d971e703SGeorge Rimar       Phdrs, [](const PhdrEntry &E) { return E.p_type == PT_PHDR; });
82902ed7575SRafael Espindola   if (PhdrI != Phdrs.end())
83002ed7575SRafael Espindola     Phdrs.erase(PhdrI);
83102ed7575SRafael Espindola }
83202ed7575SRafael Espindola 
833*5aedebffSPeter Smith void LinkerScript::assignAddresses() {
8347c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
835be607334SRafael Espindola   Dot = 0;
83672dc195dSRafael Espindola   ErrorOnMissingSection = true;
83706f4743aSRafael Espindola   switchTo(Aether);
83806f4743aSRafael Espindola 
8398f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
8408f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
841d379f735SRui Ueyama       assignSymbol(Cmd, false);
84205ef4cffSRui Ueyama       continue;
843652852c5SGeorge Rimar     }
844652852c5SGeorge Rimar 
8458f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<AssertCommand>(Base)) {
8464595df94SRafael Espindola       Cmd->Expression();
847eefa758eSGeorge Rimar       continue;
848eefa758eSGeorge Rimar     }
849eefa758eSGeorge Rimar 
8508f99f73cSRui Ueyama     auto *Cmd = cast<OutputSectionCommand>(Base);
851d3190795SRafael Espindola     assignOffsets(Cmd);
852a14b13d8SGeorge Rimar   }
853fb8978fcSDima Stepanov }
854652852c5SGeorge Rimar 
855464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
856f51c8055SRafael Espindola std::vector<PhdrEntry> LinkerScript::createPhdrs() {
85717cb7c0aSRafael Espindola   std::vector<PhdrEntry> Ret;
858bbe38602SEugene Leviant 
859464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
860464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
861bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
862edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
86317cb7c0aSRafael Espindola     PhdrEntry &Phdr = Ret.back();
864bbe38602SEugene Leviant 
865bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
8669d1bacb1SRui Ueyama       Phdr.add(Out::ElfHeader);
867bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
8689d1bacb1SRui Ueyama       Phdr.add(Out::ProgramHeaders);
86956b21c86SEugene Leviant 
87056b21c86SEugene Leviant     if (Cmd.LMAExpr) {
87172dc195dSRafael Espindola       Phdr.p_paddr = Cmd.LMAExpr().getValue();
87256b21c86SEugene Leviant       Phdr.HasLMA = true;
87356b21c86SEugene Leviant     }
874bbe38602SEugene Leviant   }
875bbe38602SEugene Leviant 
876464daadcSRui Ueyama   // Add output sections to program headers.
8777ff9329bSRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
8787ff9329bSRafael Espindola     OutputSection *Sec = Cmd->Sec;
879bbe38602SEugene Leviant 
880bbe38602SEugene Leviant     // Assign headers specified by linker script
8812c923c2cSRafael Espindola     for (size_t Id : getPhdrIndices(Sec)) {
882edebbdf1SRui Ueyama       Ret[Id].add(Sec);
883865bf863SEugene Leviant       if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
88417cb7c0aSRafael Espindola         Ret[Id].p_flags |= Sec->getPhdrFlags();
885bbe38602SEugene Leviant     }
886bbe38602SEugene Leviant   }
887edebbdf1SRui Ueyama   return Ret;
888bbe38602SEugene Leviant }
889bbe38602SEugene Leviant 
890b8dd23f5SRui Ueyama bool LinkerScript::ignoreInterpSection() {
891f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
892f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
893e31d9886SRui Ueyama   if (Opt.PhdrsCommands.empty())
894e31d9886SRui Ueyama     return false;
895e31d9886SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands)
896e31d9886SRui Ueyama     if (Cmd.Type == PT_INTERP)
897e31d9886SRui Ueyama       return false;
898e31d9886SRui Ueyama   return true;
899f9bc3bd2SEugene Leviant }
900f9bc3bd2SEugene Leviant 
901d7dc2258SRafael Espindola OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) const {
902d7dc2258SRafael Espindola   auto I = SecToCommand.find(Sec);
903d7dc2258SRafael Espindola   if (I == SecToCommand.end())
904fa948c72SRafael Espindola     return nullptr;
905d7dc2258SRafael Espindola   return I->second;
906fa948c72SRafael Espindola }
907fa948c72SRafael Espindola 
90855b169bfSRafael Espindola uint32_t OutputSectionCommand::getFiller() {
90955b169bfSRafael Espindola   if (Filler)
91055b169bfSRafael Espindola     return *Filler;
91155b169bfSRafael Espindola   if (Sec->Flags & SHF_EXECINSTR)
91255b169bfSRafael Espindola     return Target->TrapInstr;
91355b169bfSRafael Espindola   return 0;
914e2ee72b5SGeorge Rimar }
915e2ee72b5SGeorge Rimar 
916e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
917f62d2607SRui Ueyama   if (Size == 1)
918f62d2607SRui Ueyama     *Buf = Data;
919f62d2607SRui Ueyama   else if (Size == 2)
920f93ed4deSRui Ueyama     write16(Buf, Data, Config->Endianness);
921f62d2607SRui Ueyama   else if (Size == 4)
922f93ed4deSRui Ueyama     write32(Buf, Data, Config->Endianness);
923f62d2607SRui Ueyama   else if (Size == 8)
924f93ed4deSRui Ueyama     write64(Buf, Data, Config->Endianness);
925f62d2607SRui Ueyama   else
926e38cbab5SGeorge Rimar     llvm_unreachable("unsupported Size argument");
927e38cbab5SGeorge Rimar }
928e38cbab5SGeorge Rimar 
9298c284acfSRafael Espindola static bool compareByFilePosition(InputSection *A, InputSection *B) {
9308c284acfSRafael Espindola   // Synthetic doesn't have link order dependecy, stable_sort will keep it last
9318c284acfSRafael Espindola   if (A->kind() == InputSectionBase::Synthetic ||
9328c284acfSRafael Espindola       B->kind() == InputSectionBase::Synthetic)
9338c284acfSRafael Espindola     return false;
9348c284acfSRafael Espindola   InputSection *LA = A->getLinkOrderDep();
9358c284acfSRafael Espindola   InputSection *LB = B->getLinkOrderDep();
9368c284acfSRafael Espindola   OutputSection *AOut = LA->getParent();
9378c284acfSRafael Espindola   OutputSection *BOut = LB->getParent();
9388c284acfSRafael Espindola   if (AOut != BOut)
9398c284acfSRafael Espindola     return AOut->SectionIndex < BOut->SectionIndex;
9408c284acfSRafael Espindola   return LA->OutSecOff < LB->OutSecOff;
9418c284acfSRafael Espindola }
9428c284acfSRafael Espindola 
943658a0c74SRafael Espindola template <class ELFT>
944658a0c74SRafael Espindola static void finalizeShtGroup(OutputSection *OS,
945658a0c74SRafael Espindola                              ArrayRef<InputSection *> Sections) {
94682143d3fSRui Ueyama   assert(Config->Relocatable && Sections.size() == 1);
94782143d3fSRui Ueyama 
9488c284acfSRafael Espindola   // sh_link field for SHT_GROUP sections should contain the section index of
9498c284acfSRafael Espindola   // the symbol table.
950658a0c74SRafael Espindola   OS->Link = InX::SymTab->getParent()->SectionIndex;
9518c284acfSRafael Espindola 
9528c284acfSRafael Espindola   // sh_info then contain index of an entry in symbol table section which
9538c284acfSRafael Espindola   // provides signature of the section group.
954658a0c74SRafael Espindola   elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>();
9558c284acfSRafael Espindola   ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
956658a0c74SRafael Espindola   OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]);
9578c284acfSRafael Espindola }
9588c284acfSRafael Espindola 
9598c284acfSRafael Espindola template <class ELFT> void OutputSectionCommand::finalize() {
9608c284acfSRafael Espindola   // Link order may be distributed across several InputSectionDescriptions
9618c284acfSRafael Espindola   // but sort must consider them all at once.
9628c284acfSRafael Espindola   std::vector<InputSection **> ScriptSections;
9638c284acfSRafael Espindola   std::vector<InputSection *> Sections;
9648c284acfSRafael Espindola   for (BaseCommand *Base : Commands)
9658c284acfSRafael Espindola     if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
9668c284acfSRafael Espindola       for (InputSection *&IS : ISD->Sections) {
9678c284acfSRafael Espindola         ScriptSections.push_back(&IS);
9688c284acfSRafael Espindola         Sections.push_back(IS);
9698c284acfSRafael Espindola       }
970658a0c74SRafael Espindola 
971658a0c74SRafael Espindola   if ((Sec->Flags & SHF_LINK_ORDER)) {
9728c284acfSRafael Espindola     std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
9738c284acfSRafael Espindola     for (int I = 0, N = Sections.size(); I < N; ++I)
9748c284acfSRafael Espindola       *ScriptSections[I] = Sections[I];
9758c284acfSRafael Espindola 
9768c284acfSRafael Espindola     // We must preserve the link order dependency of sections with the
9778c284acfSRafael Espindola     // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
9788c284acfSRafael Espindola     // need to translate the InputSection sh_link to the OutputSection sh_link,
9798c284acfSRafael Espindola     // all InputSections in the OutputSection have the same dependency.
980658a0c74SRafael Espindola     if (auto *D = Sections.front()->getLinkOrderDep())
9818c284acfSRafael Espindola       Sec->Link = D->getParent()->SectionIndex;
9828c284acfSRafael Espindola   }
9838c284acfSRafael Espindola 
9848c284acfSRafael Espindola   uint32_t Type = Sec->Type;
9858c284acfSRafael Espindola   if (Type == SHT_GROUP) {
986658a0c74SRafael Espindola     finalizeShtGroup<ELFT>(Sec, Sections);
9878c284acfSRafael Espindola     return;
9888c284acfSRafael Espindola   }
9898c284acfSRafael Espindola 
9908c284acfSRafael Espindola   if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
9918c284acfSRafael Espindola     return;
9928c284acfSRafael Espindola 
993658a0c74SRafael Espindola   InputSection *First = Sections[0];
9948c284acfSRafael Espindola   if (isa<SyntheticSection>(First))
9958c284acfSRafael Espindola     return;
9968c284acfSRafael Espindola 
9978c284acfSRafael Espindola   Sec->Link = InX::SymTab->getParent()->SectionIndex;
9988c284acfSRafael Espindola   // sh_info for SHT_REL[A] sections should contain the section header index of
9998c284acfSRafael Espindola   // the section to which the relocation applies.
10008c284acfSRafael Espindola   InputSectionBase *S = First->getRelocatedSection();
10018c284acfSRafael Espindola   Sec->Info = S->getOutputSection()->SectionIndex;
10028c284acfSRafael Espindola   Sec->Flags |= SHF_INFO_LINK;
10038c284acfSRafael Espindola }
10048c284acfSRafael Espindola 
100568880728SRafael Espindola // Compress section contents if this section contains debug info.
100668880728SRafael Espindola template <class ELFT> void OutputSectionCommand::maybeCompress() {
100768880728SRafael Espindola   typedef typename ELFT::Chdr Elf_Chdr;
100868880728SRafael Espindola 
100968880728SRafael Espindola   // Compress only DWARF debug sections.
101068880728SRafael Espindola   if (!Config->CompressDebugSections || (Sec->Flags & SHF_ALLOC) ||
101168880728SRafael Espindola       !Name.startswith(".debug_"))
101268880728SRafael Espindola     return;
101368880728SRafael Espindola 
101468880728SRafael Espindola   // Create a section header.
101568880728SRafael Espindola   Sec->ZDebugHeader.resize(sizeof(Elf_Chdr));
101668880728SRafael Espindola   auto *Hdr = reinterpret_cast<Elf_Chdr *>(Sec->ZDebugHeader.data());
101768880728SRafael Espindola   Hdr->ch_type = ELFCOMPRESS_ZLIB;
101868880728SRafael Espindola   Hdr->ch_size = Sec->Size;
101968880728SRafael Espindola   Hdr->ch_addralign = Sec->Alignment;
102068880728SRafael Espindola 
102168880728SRafael Espindola   // Write section contents to a temporary buffer and compress it.
102268880728SRafael Espindola   std::vector<uint8_t> Buf(Sec->Size);
102368880728SRafael Espindola   writeTo<ELFT>(Buf.data());
102468880728SRafael Espindola   if (Error E = zlib::compress(toStringRef(Buf), Sec->CompressedData))
102568880728SRafael Espindola     fatal("compress failed: " + llvm::toString(std::move(E)));
102668880728SRafael Espindola 
102768880728SRafael Espindola   // Update section headers.
102868880728SRafael Espindola   Sec->Size = sizeof(Elf_Chdr) + Sec->CompressedData.size();
102968880728SRafael Espindola   Sec->Flags |= SHF_COMPRESSED;
103068880728SRafael Espindola }
103168880728SRafael Espindola 
103255b169bfSRafael Espindola template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
10331124001cSGeorge Rimar   if (Sec->Type == SHT_NOBITS)
10341124001cSGeorge Rimar     return;
10351124001cSGeorge Rimar 
103655b169bfSRafael Espindola   Sec->Loc = Buf;
103755b169bfSRafael Espindola 
1038e6d8c1cbSRui Ueyama   // If -compress-debug-section is specified and if this is a debug seciton,
1039e6d8c1cbSRui Ueyama   // we've already compressed section contents. If that's the case,
1040e6d8c1cbSRui Ueyama   // just write it down.
104155b169bfSRafael Espindola   if (!Sec->CompressedData.empty()) {
104255b169bfSRafael Espindola     memcpy(Buf, Sec->ZDebugHeader.data(), Sec->ZDebugHeader.size());
104355b169bfSRafael Espindola     memcpy(Buf + Sec->ZDebugHeader.size(), Sec->CompressedData.data(),
104455b169bfSRafael Espindola            Sec->CompressedData.size());
104555b169bfSRafael Espindola     return;
104655b169bfSRafael Espindola   }
104755b169bfSRafael Espindola 
104855b169bfSRafael Espindola   // Write leading padding.
1049969c6512SRafael Espindola   std::vector<InputSection *> Sections;
1050969c6512SRafael Espindola   for (BaseCommand *Cmd : Commands)
1051969c6512SRafael Espindola     if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
1052969c6512SRafael Espindola       for (InputSection *IS : ISD->Sections)
1053969c6512SRafael Espindola         if (IS->Live)
1054969c6512SRafael Espindola           Sections.push_back(IS);
105555b169bfSRafael Espindola   uint32_t Filler = getFiller();
105655b169bfSRafael Espindola   if (Filler)
105755b169bfSRafael Espindola     fill(Buf, Sections.empty() ? Sec->Size : Sections[0]->OutSecOff, Filler);
105855b169bfSRafael Espindola 
105955b169bfSRafael Espindola   parallelForEachN(0, Sections.size(), [=](size_t I) {
106055b169bfSRafael Espindola     InputSection *IS = Sections[I];
106155b169bfSRafael Espindola     IS->writeTo<ELFT>(Buf);
106255b169bfSRafael Espindola 
106355b169bfSRafael Espindola     // Fill gaps between sections.
106455b169bfSRafael Espindola     if (Filler) {
106555b169bfSRafael Espindola       uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
106655b169bfSRafael Espindola       uint8_t *End;
106755b169bfSRafael Espindola       if (I + 1 == Sections.size())
106855b169bfSRafael Espindola         End = Buf + Sec->Size;
106955b169bfSRafael Espindola       else
107055b169bfSRafael Espindola         End = Buf + Sections[I + 1]->OutSecOff;
107155b169bfSRafael Espindola       fill(Start, End - Start, Filler);
107255b169bfSRafael Espindola     }
107355b169bfSRafael Espindola   });
107455b169bfSRafael Espindola 
107555b169bfSRafael Espindola   // Linker scripts may have BYTE()-family commands with which you
107655b169bfSRafael Espindola   // can write arbitrary bytes to the output. Process them if any.
107755b169bfSRafael Espindola   for (BaseCommand *Base : Commands)
10788f99f73cSRui Ueyama     if (auto *Data = dyn_cast<BytesDataCommand>(Base))
1079a8dba487SGeorge Rimar       writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
1080e38cbab5SGeorge Rimar }
1081e38cbab5SGeorge Rimar 
1082dc1ed120SRafael Espindola bool LinkerScript::hasLMA(OutputSection *Sec) {
1083fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec))
1084fa948c72SRafael Espindola     if (Cmd->LMAExpr)
1085b71d6f7aSEugene Leviant       return true;
1086b71d6f7aSEugene Leviant   return false;
10878ceadb38SGeorge Rimar }
10888ceadb38SGeorge Rimar 
1089b8dd23f5SRui Ueyama ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
10904595df94SRafael Espindola   if (S == ".")
109141c7ab4aSGeorge Rimar     return {CurOutSec, Dot - CurOutSec->Addr, Loc};
1092a8dba487SGeorge Rimar   if (SymbolBody *B = findSymbol(S)) {
109372dc195dSRafael Espindola     if (auto *D = dyn_cast<DefinedRegular>(B))
109441c7ab4aSGeorge Rimar       return {D->Section, D->Value, Loc};
109530f16b23SPetr Hosek     if (auto *C = dyn_cast<DefinedCommon>(B))
109641c7ab4aSGeorge Rimar       return {InX::Common, C->Offset, Loc};
109772dc195dSRafael Espindola   }
1098f6aeed36SEugene Leviant   error(Loc + ": symbol not found: " + S);
1099884e786dSGeorge Rimar   return 0;
1100884e786dSGeorge Rimar }
1101884e786dSGeorge Rimar 
1102b8dd23f5SRui Ueyama bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
1103f34f45fdSGeorge Rimar 
11046e9f98c1SAndrew Ng static const size_t NoPhdr = -1;
11056e9f98c1SAndrew Ng 
11062c923c2cSRafael Espindola // Returns indices of ELF headers containing specific section. Each index is a
11072c923c2cSRafael Espindola // zero based number of ELF header listed within PHDRS {} script block.
11082c923c2cSRafael Espindola std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) {
1109fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec)) {
111029c5a2a9SRui Ueyama     std::vector<size_t> Ret;
11116e9f98c1SAndrew Ng     for (StringRef PhdrName : Cmd->Phdrs) {
11126e9f98c1SAndrew Ng       size_t Index = getPhdrIndex(Cmd->Location, PhdrName);
11136e9f98c1SAndrew Ng       if (Index != NoPhdr)
11146e9f98c1SAndrew Ng         Ret.push_back(Index);
11156e9f98c1SAndrew Ng     }
111629c5a2a9SRui Ueyama     return Ret;
1117bbe38602SEugene Leviant   }
111831d842f5SGeorge Rimar   return {};
111931d842f5SGeorge Rimar }
1120bbe38602SEugene Leviant 
11216e9f98c1SAndrew Ng // Returns the index of the segment named PhdrName if found otherwise
11226e9f98c1SAndrew Ng // NoPhdr. When not found, if PhdrName is not the special case value 'NONE'
11236e9f98c1SAndrew Ng // (which can be used to explicitly specify that a section isn't assigned to a
11246e9f98c1SAndrew Ng // segment) then error.
1125b8dd23f5SRui Ueyama size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
112629c5a2a9SRui Ueyama   size_t I = 0;
112729c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
112829c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
112929c5a2a9SRui Ueyama       return I;
113029c5a2a9SRui Ueyama     ++I;
113129c5a2a9SRui Ueyama   }
11326e9f98c1SAndrew Ng   if (PhdrName != "NONE")
11332a942c4bSEugene Leviant     error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
11346e9f98c1SAndrew Ng   return NoPhdr;
113529c5a2a9SRui Ueyama }
113655b169bfSRafael Espindola 
113755b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);
113855b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32BE>(uint8_t *Buf);
113955b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64LE>(uint8_t *Buf);
114055b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64BE>(uint8_t *Buf);
114168880728SRafael Espindola 
114268880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32LE>();
114368880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32BE>();
114468880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64LE>();
114568880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64BE>();
11468c284acfSRafael Espindola 
11478c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF32LE>();
11488c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF32BE>();
11498c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF64LE>();
11508c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF64BE>();
1151