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;
341503206c5SGeorge Rimar     if (S == InX::ShStrTab)
342ecbfd871SRafael Espindola       error("discarding .shstrtab section is not allowed");
343647c1685SGeorge Rimar     discard(S->DependentSections);
344be94e1b6SRafael Espindola   }
345be94e1b6SRafael Espindola }
346be94e1b6SRafael Espindola 
347b4c9b81aSRafael Espindola std::vector<InputSectionBase *>
348b8dd23f5SRui Ueyama LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) {
349b4c9b81aSRafael Espindola   std::vector<InputSectionBase *> Ret;
350e7f912cdSRui Ueyama 
3518f99f73cSRui Ueyama   for (BaseCommand *Base : OutCmd.Commands) {
3528f99f73cSRui Ueyama     auto *Cmd = dyn_cast<InputSectionDescription>(Base);
3537c3ff2ebSRafael Espindola     if (!Cmd)
3540b9ce6a4SRui Ueyama       continue;
35572e107f3SRui Ueyama 
35672e107f3SRui Ueyama     Cmd->Sections = computeInputSections(Cmd);
357e4c8b9b7SRafael Espindola     Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end());
3580b9ce6a4SRui Ueyama   }
359e71a3f8aSRafael Espindola 
3600b9ce6a4SRui Ueyama   return Ret;
3610b9ce6a4SRui Ueyama }
3620b9ce6a4SRui Ueyama 
363b8dd23f5SRui Ueyama void LinkerScript::processCommands(OutputSectionFactory &Factory) {
3645616adf6SRafael Espindola   // A symbol can be assigned before any section is mentioned in the linker
3655616adf6SRafael Espindola   // script. In an DSO, the symbol values are addresses, so the only important
3665616adf6SRafael Espindola   // section values are:
3675616adf6SRafael Espindola   // * SHN_UNDEF
3685616adf6SRafael Espindola   // * SHN_ABS
3695616adf6SRafael Espindola   // * Any value meaning a regular section.
3705616adf6SRafael Espindola   // To handle that, create a dummy aether section that fills the void before
3715616adf6SRafael Espindola   // the linker scripts switches to another section. It has an index of one
3725616adf6SRafael Espindola   // which will map to whatever the first actual section is.
3735616adf6SRafael Espindola   Aether = make<OutputSection>("", 0, SHF_ALLOC);
3745616adf6SRafael Espindola   Aether->SectionIndex = 1;
3755616adf6SRafael Espindola   CurOutSec = Aether;
37649592cf6SRafael Espindola   Dot = 0;
3775616adf6SRafael Espindola 
37892a5ba6dSRui Ueyama   for (size_t I = 0; I < Opt.Commands.size(); ++I) {
3790b1b695aSRui Ueyama     // Handle symbol assignments outside of any output section.
38092a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Opt.Commands[I])) {
3814cd7352cSRafael Espindola       addSymbol(Cmd);
3822ab5f73dSRui Ueyama       continue;
3832ab5f73dSRui Ueyama     }
3840b1b695aSRui Ueyama 
38592a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I])) {
386b4c9b81aSRafael Espindola       std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
3877bd37870SRafael Espindola 
3880b1b695aSRui Ueyama       // The output section name `/DISCARD/' is special.
3890b1b695aSRui Ueyama       // Any input section assigned to it is discarded.
39048c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
3917bd37870SRafael Espindola         discard(V);
39248c3f1ceSRui Ueyama         continue;
39348c3f1ceSRui Ueyama       }
3940b9ce6a4SRui Ueyama 
3950b1b695aSRui Ueyama       // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
3960b1b695aSRui Ueyama       // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
3970b1b695aSRui Ueyama       // sections satisfy a given constraint. If not, a directive is handled
39807d7c42cSGeorge Rimar       // as if it wasn't present from the beginning.
3990b1b695aSRui Ueyama       //
4000b1b695aSRui Ueyama       // Because we'll iterate over Commands many more times, the easiest
40107d7c42cSGeorge Rimar       // way to "make it as if it wasn't present" is to just remove it.
402f7f0d088SGeorge Rimar       if (!matchConstraints(V, Cmd->Constraint)) {
403b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
404f94efdddSRui Ueyama           S->Assigned = false;
40592a5ba6dSRui Ueyama         Opt.Commands.erase(Opt.Commands.begin() + I);
40607d7c42cSGeorge Rimar         --I;
4077c3ff2ebSRafael Espindola         continue;
4087c3ff2ebSRafael Espindola       }
4097c3ff2ebSRafael Espindola 
4100b1b695aSRui Ueyama       // A directive may contain symbol definitions like this:
4110b1b695aSRui Ueyama       // ".foo : { ...; bar = .; }". Handle them.
4128f99f73cSRui Ueyama       for (BaseCommand *Base : Cmd->Commands)
4138f99f73cSRui Ueyama         if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
4144cd7352cSRafael Espindola           addSymbol(OutCmd);
4157c3ff2ebSRafael Espindola 
4160b1b695aSRui Ueyama       // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
4170b1b695aSRui Ueyama       // is given, input sections are aligned to that value, whether the
4180b1b695aSRui Ueyama       // given value is larger or smaller than the original section alignment.
4190b1b695aSRui Ueyama       if (Cmd->SubalignExpr) {
42072dc195dSRafael Espindola         uint32_t Subalign = Cmd->SubalignExpr().getValue();
421b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
4220b1b695aSRui Ueyama           S->Alignment = Subalign;
42320d03194SEugene Leviant       }
4240b1b695aSRui Ueyama 
4250b1b695aSRui Ueyama       // Add input sections to an output section.
426d86a4e50SGeorge Rimar       for (InputSectionBase *S : V)
4274f013bb3SRafael Espindola         Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
428660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
429660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX);
430660c9ab9SRafael Espindola         Sec->SectionIndex = I;
431fbb0463fSGeorge Rimar         if (Cmd->Noload)
432fbb0463fSGeorge Rimar           Sec->Type = SHT_NOBITS;
433d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
434660c9ab9SRafael Espindola       }
43548c3f1ceSRui Ueyama     }
4364aa2ef5bSRafael Espindola   }
4375616adf6SRafael Espindola   CurOutSec = nullptr;
438db24d9c3SGeorge Rimar }
439e63d81bdSEugene Leviant 
44002ed7575SRafael Espindola void LinkerScript::fabricateDefaultCommands() {
441cbfe9e94SPeter Smith   std::vector<BaseCommand *> Commands;
442cbfe9e94SPeter Smith 
443cbfe9e94SPeter Smith   // Define start address
444e76231b6SRafael Espindola   uint64_t StartAddr = -1;
445cbfe9e94SPeter Smith 
446c60b4510SPeter Smith   // The Sections with -T<section> have been sorted in order of ascending
447c60b4510SPeter Smith   // address. We must lower StartAddr if the lowest -T<section address> as
448c60b4510SPeter Smith   // calls to setDot() must be monotonically increasing.
449c60b4510SPeter Smith   for (auto& KV : Config->SectionStartMap)
450c60b4510SPeter Smith     StartAddr = std::min(StartAddr, KV.second);
451c60b4510SPeter Smith 
452e76231b6SRafael Espindola   Commands.push_back(make<SymbolAssignment>(
453e76231b6SRafael Espindola       ".",
454e76231b6SRafael Espindola       [=] {
455e76231b6SRafael Espindola         return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize());
456e76231b6SRafael Espindola       },
457e76231b6SRafael Espindola       ""));
458cbfe9e94SPeter Smith 
459cbfe9e94SPeter Smith   // For each OutputSection that needs a VA fabricate an OutputSectionCommand
460cbfe9e94SPeter Smith   // with an InputSectionDescription describing the InputSections
461f51c8055SRafael Espindola   for (OutputSection *Sec : OutputSections) {
46205c4f67cSRafael Espindola     auto *OSCmd = createOutputSectionCommand(Sec->Name, "<internal>");
463c60b4510SPeter Smith     OSCmd->Sec = Sec;
464d7dc2258SRafael Espindola     SecToCommand[Sec] = OSCmd;
465c60b4510SPeter Smith 
466c60b4510SPeter Smith     // Prefer user supplied address over additional alignment constraint
467cbfe9e94SPeter Smith     auto I = Config->SectionStartMap.find(Sec->Name);
468cbfe9e94SPeter Smith     if (I != Config->SectionStartMap.end())
469bb7bd3eeSRafael Espindola       OSCmd->AddrExpr = [=] { return I->second; };
470c60b4510SPeter Smith 
471cbfe9e94SPeter Smith     Commands.push_back(OSCmd);
472cbfe9e94SPeter Smith     if (Sec->Sections.size()) {
473cbfe9e94SPeter Smith       auto *ISD = make<InputSectionDescription>("");
474cbfe9e94SPeter Smith       OSCmd->Commands.push_back(ISD);
475cbfe9e94SPeter Smith       for (InputSection *ISec : Sec->Sections) {
476cbfe9e94SPeter Smith         ISD->Sections.push_back(ISec);
477cbfe9e94SPeter Smith         ISec->Assigned = true;
478cbfe9e94SPeter Smith       }
479cbfe9e94SPeter Smith     }
480cbfe9e94SPeter Smith   }
481cbfe9e94SPeter Smith   // SECTIONS commands run before other non SECTIONS commands
482cbfe9e94SPeter Smith   Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end());
483cbfe9e94SPeter Smith   Opt.Commands = std::move(Commands);
484cbfe9e94SPeter Smith }
485cbfe9e94SPeter Smith 
4860b1b695aSRui Ueyama // Add sections that didn't match any sections command.
487b8dd23f5SRui Ueyama void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
4884f013bb3SRafael Espindola   for (InputSectionBase *S : InputSections) {
489db5e56f7SRafael Espindola     if (!S->Live || S->Parent)
4904f013bb3SRafael Espindola       continue;
4914f013bb3SRafael Espindola     StringRef Name = getOutputSectionName(S->Name);
4924f013bb3SRafael Espindola     auto I = std::find_if(
4934f013bb3SRafael Espindola         Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
4944f013bb3SRafael Espindola           if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
4954f013bb3SRafael Espindola             return Cmd->Name == Name;
4964f013bb3SRafael Espindola           return false;
4974f013bb3SRafael Espindola         });
498de8d9897SRafael Espindola     if (I == Opt.Commands.end()) {
4994f013bb3SRafael Espindola       Factory.addInputSec(S, Name);
500de8d9897SRafael Espindola     } else {
501de8d9897SRafael Espindola       auto *Cmd = cast<OutputSectionCommand>(*I);
502de8d9897SRafael Espindola       Factory.addInputSec(S, Name, Cmd->Sec);
503660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
504d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
505660c9ab9SRafael Espindola         unsigned Index = std::distance(Opt.Commands.begin(), I);
506660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index);
507660c9ab9SRafael Espindola         Sec->SectionIndex = Index;
508660c9ab9SRafael Espindola       }
509de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
5106a1aa8d9SRafael Espindola       ISD->Sections.push_back(cast<InputSection>(S));
511de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
512de8d9897SRafael Espindola     }
5134f013bb3SRafael Espindola   }
514e63d81bdSEugene Leviant }
515e63d81bdSEugene Leviant 
5167c4eafa3SRafael Espindola uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
5177c4eafa3SRafael Espindola   bool IsTbss = (CurOutSec->Flags & SHF_TLS) && CurOutSec->Type == SHT_NOBITS;
5187c4eafa3SRafael Espindola   uint64_t Start = IsTbss ? Dot + ThreadBssOffset : Dot;
5197c4eafa3SRafael Espindola   Start = alignTo(Start, Align);
5207c4eafa3SRafael Espindola   uint64_t End = Start + Size;
5217c4eafa3SRafael Espindola 
5227c4eafa3SRafael Espindola   if (IsTbss)
5237c4eafa3SRafael Espindola     ThreadBssOffset = End - Dot;
5247c4eafa3SRafael Espindola   else
5257c4eafa3SRafael Espindola     Dot = End;
5267c4eafa3SRafael Espindola   return End;
527a940e539SRafael Espindola }
528a940e539SRafael Espindola 
529b8dd23f5SRui Ueyama void LinkerScript::output(InputSection *S) {
5307c4eafa3SRafael Espindola   uint64_t Pos = advance(S->getSize(), S->Alignment);
5317c4eafa3SRafael Espindola   S->OutSecOff = Pos - S->getSize() - CurOutSec->Addr;
532d3190795SRafael Espindola 
533d3190795SRafael Espindola   // Update output section size after adding each section. This is so that
534d3190795SRafael Espindola   // SIZEOF works correctly in the case below:
535d3190795SRafael Espindola   // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
53604a2e348SRafael Espindola   CurOutSec->Size = Pos - CurOutSec->Addr;
537d3190795SRafael Espindola 
538b889744eSMeador Inge   // If there is a memory region associated with this input section, then
539b889744eSMeador Inge   // place the section in that region and update the region index.
540b889744eSMeador Inge   if (CurMemRegion) {
541b889744eSMeador Inge     CurMemRegion->Offset += CurOutSec->Size;
542b889744eSMeador Inge     uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin;
543b889744eSMeador Inge     if (CurSize > CurMemRegion->Length) {
544b889744eSMeador Inge       uint64_t OverflowAmt = CurSize - CurMemRegion->Length;
545b889744eSMeador Inge       error("section '" + CurOutSec->Name + "' will not fit in region '" +
546b889744eSMeador Inge             CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
547b889744eSMeador Inge             " bytes");
548b889744eSMeador Inge     }
549b889744eSMeador Inge   }
5502de509c3SRui Ueyama }
551ceabe80eSEugene Leviant 
552b8dd23f5SRui Ueyama void LinkerScript::switchTo(OutputSection *Sec) {
553d3190795SRafael Espindola   if (CurOutSec == Sec)
554d3190795SRafael Espindola     return;
555d3190795SRafael Espindola 
556d3190795SRafael Espindola   CurOutSec = Sec;
5577c4eafa3SRafael Espindola   CurOutSec->Addr = advance(0, CurOutSec->Alignment);
558b71d6f7aSEugene Leviant 
559b71d6f7aSEugene Leviant   // If neither AT nor AT> is specified for an allocatable section, the linker
560b71d6f7aSEugene Leviant   // will set the LMA such that the difference between VMA and LMA for the
561b71d6f7aSEugene Leviant   // section is the same as the preceding output section in the same region
562b71d6f7aSEugene Leviant   // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
56321467876SGeorge Rimar   if (LMAOffset)
56429c1afb8SRafael Espindola     CurOutSec->LMAOffset = LMAOffset();
565d3190795SRafael Espindola }
566d3190795SRafael Espindola 
567b8dd23f5SRui Ueyama void LinkerScript::process(BaseCommand &Base) {
5682e081a4fSRui Ueyama   // This handles the assignments to symbol or to the dot.
5692e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<SymbolAssignment>(&Base)) {
5702e081a4fSRui Ueyama     assignSymbol(Cmd, true);
571d3190795SRafael Espindola     return;
57297403d15SEugene Leviant   }
573e38cbab5SGeorge Rimar 
574e38cbab5SGeorge Rimar   // Handle BYTE(), SHORT(), LONG(), or QUAD().
5752e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) {
5762e081a4fSRui Ueyama     Cmd->Offset = Dot - CurOutSec->Addr;
5772e081a4fSRui Ueyama     Dot += Cmd->Size;
57804a2e348SRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
579e38cbab5SGeorge Rimar     return;
580e38cbab5SGeorge Rimar   }
581e38cbab5SGeorge Rimar 
5822e081a4fSRui Ueyama   // Handle ASSERT().
5832e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<AssertCommand>(&Base)) {
5842e081a4fSRui Ueyama     Cmd->Expression();
585b2d99d6aSMeador Inge     return;
586b2d99d6aSMeador Inge   }
587b2d99d6aSMeador Inge 
5882e081a4fSRui Ueyama   // Handle a single input section description command.
5892e081a4fSRui Ueyama   // It calculates and assigns the offsets for each section and also
590e38cbab5SGeorge Rimar   // updates the output section size.
5912e081a4fSRui Ueyama   auto &Cmd = cast<InputSectionDescription>(Base);
592a85e8ddaSRafael Espindola   for (InputSection *Sec : Cmd.Sections) {
5933fb5a6dcSGeorge Rimar     // We tentatively added all synthetic sections at the beginning and removed
5943fb5a6dcSGeorge Rimar     // empty ones afterwards (because there is no way to know whether they were
5953fb5a6dcSGeorge Rimar     // going be empty or not other than actually running linker scripts.)
5963fb5a6dcSGeorge Rimar     // We need to ignore remains of empty sections.
5972e081a4fSRui Ueyama     if (auto *S = dyn_cast<SyntheticSection>(Sec))
5982e081a4fSRui Ueyama       if (S->empty())
5993fb5a6dcSGeorge Rimar         continue;
6003fb5a6dcSGeorge Rimar 
6012e081a4fSRui Ueyama     if (!Sec->Live)
60278ef645fSGeorge Rimar       continue;
603db5e56f7SRafael Espindola     assert(CurOutSec == Sec->getParent());
604a85e8ddaSRafael Espindola     output(Sec);
605ceabe80eSEugene Leviant   }
606ceabe80eSEugene Leviant }
607ceabe80eSEugene Leviant 
608b889744eSMeador Inge // This function searches for a memory region to place the given output
609b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is
610b889744eSMeador Inge // returned. Otherwise, a nullptr is returned.
6111902b337SRafael Espindola MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd) {
612b889744eSMeador Inge   // If a memory region name was specified in the output section command,
613b889744eSMeador Inge   // then try to find that region first.
614b889744eSMeador Inge   if (!Cmd->MemoryRegionName.empty()) {
615b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
616b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
617b889744eSMeador Inge       return &It->second;
618b889744eSMeador Inge     error("memory region '" + Cmd->MemoryRegionName + "' not declared");
619b889744eSMeador Inge     return nullptr;
620b889744eSMeador Inge   }
621b889744eSMeador Inge 
622d7c5400fSRui Ueyama   // If at least one memory region is defined, all sections must
623d7c5400fSRui Ueyama   // belong to some memory region. Otherwise, we don't need to do
624d7c5400fSRui Ueyama   // anything for memory regions.
625cc400cc8SRui Ueyama   if (Opt.MemoryRegions.empty())
626b889744eSMeador Inge     return nullptr;
627b889744eSMeador Inge 
6281902b337SRafael Espindola   OutputSection *Sec = Cmd->Sec;
629b889744eSMeador Inge   // See if a region can be found by matching section flags.
6302e081a4fSRui Ueyama   for (auto &Pair : Opt.MemoryRegions) {
6312e081a4fSRui Ueyama     MemoryRegion &M = Pair.second;
6322e081a4fSRui Ueyama     if ((M.Flags & Sec->Flags) && (M.NegFlags & Sec->Flags) == 0)
6332e081a4fSRui Ueyama       return &M;
634b889744eSMeador Inge   }
635b889744eSMeador Inge 
636b889744eSMeador Inge   // Otherwise, no suitable region was found.
637b889744eSMeador Inge   if (Sec->Flags & SHF_ALLOC)
638b889744eSMeador Inge     error("no memory region specified for section '" + Sec->Name + "'");
639b889744eSMeador Inge   return nullptr;
640b889744eSMeador Inge }
641b889744eSMeador Inge 
6420b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section
6430b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }").
644b8dd23f5SRui Ueyama void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) {
6459b980095SRafael Espindola   OutputSection *Sec = Cmd->Sec;
6462b074553SRafael Espindola   if (!Sec)
647d3190795SRafael Espindola     return;
648b889744eSMeador Inge 
649dece2808SRafael Espindola   if (!(Sec->Flags & SHF_ALLOC))
650dece2808SRafael Espindola     Dot = 0;
651dece2808SRafael Espindola   else if (Cmd->AddrExpr)
652d379f735SRui Ueyama     setDot(Cmd->AddrExpr, Cmd->Location, false);
653679828ffSRafael Espindola 
6545784e96fSEugene Leviant   if (Cmd->LMAExpr) {
6550c1c8085SGeorge Rimar     uint64_t D = Dot;
65672dc195dSRafael Espindola     LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; };
6575784e96fSEugene Leviant   }
6585784e96fSEugene Leviant 
659feed7506SRafael Espindola   CurMemRegion = Cmd->MemRegion;
660b889744eSMeador Inge   if (CurMemRegion)
661b889744eSMeador Inge     Dot = CurMemRegion->Offset;
662b889744eSMeador Inge   switchTo(Sec);
6630b1b695aSRui Ueyama 
664d86a4e50SGeorge Rimar   // We do not support custom layout for compressed debug sectons.
665d86a4e50SGeorge Rimar   // At this point we already know their size and have compressed content.
666d86a4e50SGeorge Rimar   if (CurOutSec->Flags & SHF_COMPRESSED)
667d86a4e50SGeorge Rimar     return;
668d86a4e50SGeorge Rimar 
669de8d9897SRafael Espindola   for (BaseCommand *C : Cmd->Commands)
670de8d9897SRafael Espindola     process(*C);
671d3190795SRafael Espindola }
672d3190795SRafael Espindola 
673b8dd23f5SRui Ueyama void LinkerScript::removeEmptyCommands() {
6746d38e4dbSRafael Espindola   // It is common practice to use very generic linker scripts. So for any
6756d38e4dbSRafael Espindola   // given run some of the output sections in the script will be empty.
6766d38e4dbSRafael Espindola   // We could create corresponding empty output sections, but that would
6776d38e4dbSRafael Espindola   // clutter the output.
6786d38e4dbSRafael Espindola   // We instead remove trivially empty sections. The bfd linker seems even
6796d38e4dbSRafael Espindola   // more aggressive at removing them.
6806d38e4dbSRafael Espindola   auto Pos = std::remove_if(
6818f99f73cSRui Ueyama       Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
6828f99f73cSRui Ueyama         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
683*e86fddd6SRafael Espindola           return Cmd->Sec == nullptr;
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;
717f51c8055SRafael 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 
828f51c8055SRafael 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 
877faf25a72SRafael Espindola static bool
878faf25a72SRafael Espindola allocateHeaders(std::vector<PhdrEntry> &Phdrs,
879faf25a72SRafael Espindola                 ArrayRef<OutputSectionCommand *> OutputSectionCommands,
88002ed7575SRafael Espindola                 uint64_t Min) {
88102ed7575SRafael Espindola   auto FirstPTLoad =
88202ed7575SRafael Espindola       std::find_if(Phdrs.begin(), Phdrs.end(),
88302ed7575SRafael Espindola                    [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
88402ed7575SRafael Espindola   if (FirstPTLoad == Phdrs.end())
88502ed7575SRafael Espindola     return false;
88602ed7575SRafael Espindola 
88702ed7575SRafael Espindola   uint64_t HeaderSize = getHeaderSize();
88802ed7575SRafael Espindola   if (HeaderSize <= Min || Script->hasPhdrsCommands()) {
88902ed7575SRafael Espindola     Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
89002ed7575SRafael Espindola     Out::ElfHeader->Addr = Min;
89102ed7575SRafael Espindola     Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
89202ed7575SRafael Espindola     return true;
89302ed7575SRafael Espindola   }
89402ed7575SRafael Espindola 
89502ed7575SRafael Espindola   assert(FirstPTLoad->First == Out::ElfHeader);
89602ed7575SRafael Espindola   OutputSection *ActualFirst = nullptr;
897faf25a72SRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
898faf25a72SRafael Espindola     OutputSection *Sec = Cmd->Sec;
89902ed7575SRafael Espindola     if (Sec->FirstInPtLoad == Out::ElfHeader) {
90002ed7575SRafael Espindola       ActualFirst = Sec;
90102ed7575SRafael Espindola       break;
90202ed7575SRafael Espindola     }
90302ed7575SRafael Espindola   }
90402ed7575SRafael Espindola   if (ActualFirst) {
905faf25a72SRafael Espindola     for (OutputSectionCommand *Cmd : OutputSectionCommands) {
906faf25a72SRafael Espindola       OutputSection *Sec = Cmd->Sec;
90702ed7575SRafael Espindola       if (Sec->FirstInPtLoad == Out::ElfHeader)
90802ed7575SRafael Espindola         Sec->FirstInPtLoad = ActualFirst;
909faf25a72SRafael Espindola     }
91002ed7575SRafael Espindola     FirstPTLoad->First = ActualFirst;
91102ed7575SRafael Espindola   } else {
91202ed7575SRafael Espindola     Phdrs.erase(FirstPTLoad);
91302ed7575SRafael Espindola   }
91402ed7575SRafael Espindola 
91502ed7575SRafael Espindola   auto PhdrI = std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry &E) {
91602ed7575SRafael Espindola     return E.p_type == PT_PHDR;
91702ed7575SRafael Espindola   });
91802ed7575SRafael Espindola   if (PhdrI != Phdrs.end())
91902ed7575SRafael Espindola     Phdrs.erase(PhdrI);
92002ed7575SRafael Espindola   return false;
92102ed7575SRafael Espindola }
92202ed7575SRafael Espindola 
923f51c8055SRafael Espindola void LinkerScript::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
9247c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
925be607334SRafael Espindola   Dot = 0;
92672dc195dSRafael Espindola   ErrorOnMissingSection = true;
92706f4743aSRafael Espindola   switchTo(Aether);
92806f4743aSRafael Espindola 
9298f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
9308f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
931d379f735SRui Ueyama       assignSymbol(Cmd, false);
93205ef4cffSRui Ueyama       continue;
933652852c5SGeorge Rimar     }
934652852c5SGeorge Rimar 
9358f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<AssertCommand>(Base)) {
9364595df94SRafael Espindola       Cmd->Expression();
937eefa758eSGeorge Rimar       continue;
938eefa758eSGeorge Rimar     }
939eefa758eSGeorge Rimar 
9408f99f73cSRui Ueyama     auto *Cmd = cast<OutputSectionCommand>(Base);
941d3190795SRafael Espindola     assignOffsets(Cmd);
942a14b13d8SGeorge Rimar   }
943467c4d55SEugene Leviant 
9440c1c8085SGeorge Rimar   uint64_t MinVA = std::numeric_limits<uint64_t>::max();
945faf25a72SRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
946faf25a72SRafael Espindola     OutputSection *Sec = Cmd->Sec;
94704a2e348SRafael Espindola     if (Sec->Flags & SHF_ALLOC)
948e08e78dfSRafael Espindola       MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
949ea590d91SRafael Espindola   }
950aab6d5c5SRafael Espindola 
951faf25a72SRafael Espindola   allocateHeaders(Phdrs, OutputSectionCommands, MinVA);
952fb8978fcSDima Stepanov }
953652852c5SGeorge Rimar 
954464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
955f51c8055SRafael Espindola std::vector<PhdrEntry> LinkerScript::createPhdrs() {
95617cb7c0aSRafael Espindola   std::vector<PhdrEntry> Ret;
957bbe38602SEugene Leviant 
958464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
959464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
960bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
961edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
96217cb7c0aSRafael Espindola     PhdrEntry &Phdr = Ret.back();
963bbe38602SEugene Leviant 
964bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
9659d1bacb1SRui Ueyama       Phdr.add(Out::ElfHeader);
966bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
9679d1bacb1SRui Ueyama       Phdr.add(Out::ProgramHeaders);
96856b21c86SEugene Leviant 
96956b21c86SEugene Leviant     if (Cmd.LMAExpr) {
97072dc195dSRafael Espindola       Phdr.p_paddr = Cmd.LMAExpr().getValue();
97156b21c86SEugene Leviant       Phdr.HasLMA = true;
97256b21c86SEugene Leviant     }
973bbe38602SEugene Leviant   }
974bbe38602SEugene Leviant 
975464daadcSRui Ueyama   // Add output sections to program headers.
9767ff9329bSRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
9777ff9329bSRafael Espindola     OutputSection *Sec = Cmd->Sec;
97804a2e348SRafael Espindola     if (!(Sec->Flags & SHF_ALLOC))
979bbe38602SEugene Leviant       break;
980bbe38602SEugene Leviant 
981bbe38602SEugene Leviant     // Assign headers specified by linker script
9822c923c2cSRafael Espindola     for (size_t Id : getPhdrIndices(Sec)) {
983edebbdf1SRui Ueyama       Ret[Id].add(Sec);
984865bf863SEugene Leviant       if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
98517cb7c0aSRafael Espindola         Ret[Id].p_flags |= Sec->getPhdrFlags();
986bbe38602SEugene Leviant     }
987bbe38602SEugene Leviant   }
988edebbdf1SRui Ueyama   return Ret;
989bbe38602SEugene Leviant }
990bbe38602SEugene Leviant 
991b8dd23f5SRui Ueyama bool LinkerScript::ignoreInterpSection() {
992f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
993f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
994e31d9886SRui Ueyama   if (Opt.PhdrsCommands.empty())
995e31d9886SRui Ueyama     return false;
996e31d9886SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands)
997e31d9886SRui Ueyama     if (Cmd.Type == PT_INTERP)
998e31d9886SRui Ueyama       return false;
999e31d9886SRui Ueyama   return true;
1000f9bc3bd2SEugene Leviant }
1001f9bc3bd2SEugene Leviant 
1002d7dc2258SRafael Espindola OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) const {
1003d7dc2258SRafael Espindola   auto I = SecToCommand.find(Sec);
1004d7dc2258SRafael Espindola   if (I == SecToCommand.end())
1005fa948c72SRafael Espindola     return nullptr;
1006d7dc2258SRafael Espindola   return I->second;
1007fa948c72SRafael Espindola }
1008fa948c72SRafael Espindola 
100955b169bfSRafael Espindola uint32_t OutputSectionCommand::getFiller() {
101055b169bfSRafael Espindola   if (Filler)
101155b169bfSRafael Espindola     return *Filler;
101255b169bfSRafael Espindola   if (Sec->Flags & SHF_EXECINSTR)
101355b169bfSRafael Espindola     return Target->TrapInstr;
101455b169bfSRafael Espindola   return 0;
1015e2ee72b5SGeorge Rimar }
1016e2ee72b5SGeorge Rimar 
1017e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
1018f62d2607SRui Ueyama   if (Size == 1)
1019f62d2607SRui Ueyama     *Buf = Data;
1020f62d2607SRui Ueyama   else if (Size == 2)
1021f93ed4deSRui Ueyama     write16(Buf, Data, Config->Endianness);
1022f62d2607SRui Ueyama   else if (Size == 4)
1023f93ed4deSRui Ueyama     write32(Buf, Data, Config->Endianness);
1024f62d2607SRui Ueyama   else if (Size == 8)
1025f93ed4deSRui Ueyama     write64(Buf, Data, Config->Endianness);
1026f62d2607SRui Ueyama   else
1027e38cbab5SGeorge Rimar     llvm_unreachable("unsupported Size argument");
1028e38cbab5SGeorge Rimar }
1029e38cbab5SGeorge Rimar 
10308c284acfSRafael Espindola static bool compareByFilePosition(InputSection *A, InputSection *B) {
10318c284acfSRafael Espindola   // Synthetic doesn't have link order dependecy, stable_sort will keep it last
10328c284acfSRafael Espindola   if (A->kind() == InputSectionBase::Synthetic ||
10338c284acfSRafael Espindola       B->kind() == InputSectionBase::Synthetic)
10348c284acfSRafael Espindola     return false;
10358c284acfSRafael Espindola   InputSection *LA = A->getLinkOrderDep();
10368c284acfSRafael Espindola   InputSection *LB = B->getLinkOrderDep();
10378c284acfSRafael Espindola   OutputSection *AOut = LA->getParent();
10388c284acfSRafael Espindola   OutputSection *BOut = LB->getParent();
10398c284acfSRafael Espindola   if (AOut != BOut)
10408c284acfSRafael Espindola     return AOut->SectionIndex < BOut->SectionIndex;
10418c284acfSRafael Espindola   return LA->OutSecOff < LB->OutSecOff;
10428c284acfSRafael Espindola }
10438c284acfSRafael Espindola 
1044658a0c74SRafael Espindola template <class ELFT>
1045658a0c74SRafael Espindola static void finalizeShtGroup(OutputSection *OS,
1046658a0c74SRafael Espindola                              ArrayRef<InputSection *> Sections) {
10478c284acfSRafael Espindola   // sh_link field for SHT_GROUP sections should contain the section index of
10488c284acfSRafael Espindola   // the symbol table.
1049658a0c74SRafael Espindola   OS->Link = InX::SymTab->getParent()->SectionIndex;
10508c284acfSRafael Espindola 
10518c284acfSRafael Espindola   // sh_info then contain index of an entry in symbol table section which
10528c284acfSRafael Espindola   // provides signature of the section group.
1053658a0c74SRafael Espindola   elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>();
1054658a0c74SRafael Espindola   assert(Config->Relocatable && Sections.size() == 1);
10558c284acfSRafael Espindola   ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
1056658a0c74SRafael Espindola   OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]);
10578c284acfSRafael Espindola }
10588c284acfSRafael Espindola 
10598c284acfSRafael Espindola template <class ELFT> void OutputSectionCommand::finalize() {
10608c284acfSRafael Espindola   // Link order may be distributed across several InputSectionDescriptions
10618c284acfSRafael Espindola   // but sort must consider them all at once.
10628c284acfSRafael Espindola   std::vector<InputSection **> ScriptSections;
10638c284acfSRafael Espindola   std::vector<InputSection *> Sections;
10648c284acfSRafael Espindola   for (BaseCommand *Base : Commands)
10658c284acfSRafael Espindola     if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
10668c284acfSRafael Espindola       for (InputSection *&IS : ISD->Sections) {
10678c284acfSRafael Espindola         ScriptSections.push_back(&IS);
10688c284acfSRafael Espindola         Sections.push_back(IS);
10698c284acfSRafael Espindola       }
1070658a0c74SRafael Espindola 
1071658a0c74SRafael Espindola   if ((Sec->Flags & SHF_LINK_ORDER)) {
10728c284acfSRafael Espindola     std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
10738c284acfSRafael Espindola     for (int I = 0, N = Sections.size(); I < N; ++I)
10748c284acfSRafael Espindola       *ScriptSections[I] = Sections[I];
10758c284acfSRafael Espindola 
10768c284acfSRafael Espindola     // We must preserve the link order dependency of sections with the
10778c284acfSRafael Espindola     // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
10788c284acfSRafael Espindola     // need to translate the InputSection sh_link to the OutputSection sh_link,
10798c284acfSRafael Espindola     // all InputSections in the OutputSection have the same dependency.
1080658a0c74SRafael Espindola     if (auto *D = Sections.front()->getLinkOrderDep())
10818c284acfSRafael Espindola       Sec->Link = D->getParent()->SectionIndex;
10828c284acfSRafael Espindola   }
10838c284acfSRafael Espindola 
10848c284acfSRafael Espindola   uint32_t Type = Sec->Type;
10858c284acfSRafael Espindola   if (Type == SHT_GROUP) {
1086658a0c74SRafael Espindola     finalizeShtGroup<ELFT>(Sec, Sections);
10878c284acfSRafael Espindola     return;
10888c284acfSRafael Espindola   }
10898c284acfSRafael Espindola 
10908c284acfSRafael Espindola   if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
10918c284acfSRafael Espindola     return;
10928c284acfSRafael Espindola 
1093658a0c74SRafael Espindola   InputSection *First = Sections[0];
10948c284acfSRafael Espindola   if (isa<SyntheticSection>(First))
10958c284acfSRafael Espindola     return;
10968c284acfSRafael Espindola 
10978c284acfSRafael Espindola   Sec->Link = InX::SymTab->getParent()->SectionIndex;
10988c284acfSRafael Espindola   // sh_info for SHT_REL[A] sections should contain the section header index of
10998c284acfSRafael Espindola   // the section to which the relocation applies.
11008c284acfSRafael Espindola   InputSectionBase *S = First->getRelocatedSection();
11018c284acfSRafael Espindola   Sec->Info = S->getOutputSection()->SectionIndex;
11028c284acfSRafael Espindola   Sec->Flags |= SHF_INFO_LINK;
11038c284acfSRafael Espindola }
11048c284acfSRafael Espindola 
110568880728SRafael Espindola // Compress section contents if this section contains debug info.
110668880728SRafael Espindola template <class ELFT> void OutputSectionCommand::maybeCompress() {
110768880728SRafael Espindola   typedef typename ELFT::Chdr Elf_Chdr;
110868880728SRafael Espindola 
110968880728SRafael Espindola   // Compress only DWARF debug sections.
111068880728SRafael Espindola   if (!Config->CompressDebugSections || (Sec->Flags & SHF_ALLOC) ||
111168880728SRafael Espindola       !Name.startswith(".debug_"))
111268880728SRafael Espindola     return;
111368880728SRafael Espindola 
111468880728SRafael Espindola   // Create a section header.
111568880728SRafael Espindola   Sec->ZDebugHeader.resize(sizeof(Elf_Chdr));
111668880728SRafael Espindola   auto *Hdr = reinterpret_cast<Elf_Chdr *>(Sec->ZDebugHeader.data());
111768880728SRafael Espindola   Hdr->ch_type = ELFCOMPRESS_ZLIB;
111868880728SRafael Espindola   Hdr->ch_size = Sec->Size;
111968880728SRafael Espindola   Hdr->ch_addralign = Sec->Alignment;
112068880728SRafael Espindola 
112168880728SRafael Espindola   // Write section contents to a temporary buffer and compress it.
112268880728SRafael Espindola   std::vector<uint8_t> Buf(Sec->Size);
112368880728SRafael Espindola   writeTo<ELFT>(Buf.data());
112468880728SRafael Espindola   if (Error E = zlib::compress(toStringRef(Buf), Sec->CompressedData))
112568880728SRafael Espindola     fatal("compress failed: " + llvm::toString(std::move(E)));
112668880728SRafael Espindola 
112768880728SRafael Espindola   // Update section headers.
112868880728SRafael Espindola   Sec->Size = sizeof(Elf_Chdr) + Sec->CompressedData.size();
112968880728SRafael Espindola   Sec->Flags |= SHF_COMPRESSED;
113068880728SRafael Espindola }
113168880728SRafael Espindola 
113255b169bfSRafael Espindola template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
11331124001cSGeorge Rimar   if (Sec->Type == SHT_NOBITS)
11341124001cSGeorge Rimar     return;
11351124001cSGeorge Rimar 
113655b169bfSRafael Espindola   Sec->Loc = Buf;
113755b169bfSRafael Espindola 
113855b169bfSRafael Espindola   // We may have already rendered compressed content when using
113955b169bfSRafael Espindola   // -compress-debug-sections option. Write it together with header.
114055b169bfSRafael Espindola   if (!Sec->CompressedData.empty()) {
114155b169bfSRafael Espindola     memcpy(Buf, Sec->ZDebugHeader.data(), Sec->ZDebugHeader.size());
114255b169bfSRafael Espindola     memcpy(Buf + Sec->ZDebugHeader.size(), Sec->CompressedData.data(),
114355b169bfSRafael Espindola            Sec->CompressedData.size());
114455b169bfSRafael Espindola     return;
114555b169bfSRafael Espindola   }
114655b169bfSRafael Espindola 
114755b169bfSRafael Espindola   // Write leading padding.
1148969c6512SRafael Espindola   std::vector<InputSection *> Sections;
1149969c6512SRafael Espindola   for (BaseCommand *Cmd : Commands)
1150969c6512SRafael Espindola     if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
1151969c6512SRafael Espindola       for (InputSection *IS : ISD->Sections)
1152969c6512SRafael Espindola         if (IS->Live)
1153969c6512SRafael Espindola           Sections.push_back(IS);
115455b169bfSRafael Espindola   uint32_t Filler = getFiller();
115555b169bfSRafael Espindola   if (Filler)
115655b169bfSRafael Espindola     fill(Buf, Sections.empty() ? Sec->Size : Sections[0]->OutSecOff, Filler);
115755b169bfSRafael Espindola 
115855b169bfSRafael Espindola   parallelForEachN(0, Sections.size(), [=](size_t I) {
115955b169bfSRafael Espindola     InputSection *IS = Sections[I];
116055b169bfSRafael Espindola     IS->writeTo<ELFT>(Buf);
116155b169bfSRafael Espindola 
116255b169bfSRafael Espindola     // Fill gaps between sections.
116355b169bfSRafael Espindola     if (Filler) {
116455b169bfSRafael Espindola       uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
116555b169bfSRafael Espindola       uint8_t *End;
116655b169bfSRafael Espindola       if (I + 1 == Sections.size())
116755b169bfSRafael Espindola         End = Buf + Sec->Size;
116855b169bfSRafael Espindola       else
116955b169bfSRafael Espindola         End = Buf + Sections[I + 1]->OutSecOff;
117055b169bfSRafael Espindola       fill(Start, End - Start, Filler);
117155b169bfSRafael Espindola     }
117255b169bfSRafael Espindola   });
117355b169bfSRafael Espindola 
117455b169bfSRafael Espindola   // Linker scripts may have BYTE()-family commands with which you
117555b169bfSRafael Espindola   // can write arbitrary bytes to the output. Process them if any.
117655b169bfSRafael Espindola   for (BaseCommand *Base : Commands)
11778f99f73cSRui Ueyama     if (auto *Data = dyn_cast<BytesDataCommand>(Base))
1178a8dba487SGeorge Rimar       writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
1179e38cbab5SGeorge Rimar }
1180e38cbab5SGeorge Rimar 
1181dc1ed120SRafael Espindola bool LinkerScript::hasLMA(OutputSection *Sec) {
1182fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec))
1183fa948c72SRafael Espindola     if (Cmd->LMAExpr)
1184b71d6f7aSEugene Leviant       return true;
1185b71d6f7aSEugene Leviant   return false;
11868ceadb38SGeorge Rimar }
11878ceadb38SGeorge Rimar 
1188b8dd23f5SRui Ueyama ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
11894595df94SRafael Espindola   if (S == ".")
119041c7ab4aSGeorge Rimar     return {CurOutSec, Dot - CurOutSec->Addr, Loc};
1191a8dba487SGeorge Rimar   if (SymbolBody *B = findSymbol(S)) {
119272dc195dSRafael Espindola     if (auto *D = dyn_cast<DefinedRegular>(B))
119341c7ab4aSGeorge Rimar       return {D->Section, D->Value, Loc};
119430f16b23SPetr Hosek     if (auto *C = dyn_cast<DefinedCommon>(B))
119541c7ab4aSGeorge Rimar       return {InX::Common, C->Offset, Loc};
119672dc195dSRafael Espindola   }
1197f6aeed36SEugene Leviant   error(Loc + ": symbol not found: " + S);
1198884e786dSGeorge Rimar   return 0;
1199884e786dSGeorge Rimar }
1200884e786dSGeorge Rimar 
1201b8dd23f5SRui Ueyama bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
1202f34f45fdSGeorge Rimar 
12032c923c2cSRafael Espindola // Returns indices of ELF headers containing specific section. Each index is a
12042c923c2cSRafael Espindola // zero based number of ELF header listed within PHDRS {} script block.
12052c923c2cSRafael Espindola std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) {
1206fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec)) {
120729c5a2a9SRui Ueyama     std::vector<size_t> Ret;
120829c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
12092a942c4bSEugene Leviant       Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
121029c5a2a9SRui Ueyama     return Ret;
1211bbe38602SEugene Leviant   }
121231d842f5SGeorge Rimar   return {};
121331d842f5SGeorge Rimar }
1214bbe38602SEugene Leviant 
1215b8dd23f5SRui Ueyama size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
121629c5a2a9SRui Ueyama   size_t I = 0;
121729c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
121829c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
121929c5a2a9SRui Ueyama       return I;
122029c5a2a9SRui Ueyama     ++I;
122129c5a2a9SRui Ueyama   }
12222a942c4bSEugene Leviant   error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
122329c5a2a9SRui Ueyama   return 0;
122429c5a2a9SRui Ueyama }
122555b169bfSRafael Espindola 
122655b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);
122755b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32BE>(uint8_t *Buf);
122855b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64LE>(uint8_t *Buf);
122955b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64BE>(uint8_t *Buf);
123068880728SRafael Espindola 
123168880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32LE>();
123268880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32BE>();
123368880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64LE>();
123468880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64BE>();
12358c284acfSRafael Espindola 
12368c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF32LE>();
12378c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF32BE>();
12388c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF64LE>();
12398c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF64BE>();
1240