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;
14572dc195dSRafael Espindola     if (Sym->Section->Flags & SHF_ALLOC)
1463c6de1a6SPetr Hosek       Sym->Value = alignTo(V.Val, V.Alignment);
14772dc195dSRafael Espindola     else
14872dc195dSRafael Espindola       Sym->Value = V.getValue();
149ea590d91SRafael Espindola   }
1508f1f3c40SMeador Inge }
1518f1f3c40SMeador Inge 
152a8dba487SGeorge Rimar static SymbolBody *findSymbol(StringRef S) {
153a8dba487SGeorge Rimar   switch (Config->EKind) {
154a8dba487SGeorge Rimar   case ELF32LEKind:
155a8dba487SGeorge Rimar     return Symtab<ELF32LE>::X->find(S);
156a8dba487SGeorge Rimar   case ELF32BEKind:
157a8dba487SGeorge Rimar     return Symtab<ELF32BE>::X->find(S);
158a8dba487SGeorge Rimar   case ELF64LEKind:
159a8dba487SGeorge Rimar     return Symtab<ELF64LE>::X->find(S);
160a8dba487SGeorge Rimar   case ELF64BEKind:
161a8dba487SGeorge Rimar     return Symtab<ELF64BE>::X->find(S);
162a8dba487SGeorge Rimar   default:
163a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
164a8dba487SGeorge Rimar   }
165a8dba487SGeorge Rimar }
166a8dba487SGeorge Rimar 
167a8dba487SGeorge Rimar static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) {
168a8dba487SGeorge Rimar   switch (Config->EKind) {
169a8dba487SGeorge Rimar   case ELF32LEKind:
170a8dba487SGeorge Rimar     return addRegular<ELF32LE>(Cmd);
171a8dba487SGeorge Rimar   case ELF32BEKind:
172a8dba487SGeorge Rimar     return addRegular<ELF32BE>(Cmd);
173a8dba487SGeorge Rimar   case ELF64LEKind:
174a8dba487SGeorge Rimar     return addRegular<ELF64LE>(Cmd);
175a8dba487SGeorge Rimar   case ELF64BEKind:
176a8dba487SGeorge Rimar     return addRegular<ELF64BE>(Cmd);
177a8dba487SGeorge Rimar   default:
178a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
179a8dba487SGeorge Rimar   }
180a8dba487SGeorge Rimar }
181a8dba487SGeorge Rimar 
182b8dd23f5SRui Ueyama void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
1831602421cSRui Ueyama   if (Cmd->Name == ".")
1848f1f3c40SMeador Inge     return;
1858f1f3c40SMeador Inge 
1868f1f3c40SMeador Inge   // If a symbol was in PROVIDE(), we need to define it only when
1878f1f3c40SMeador Inge   // it is a referenced undefined symbol.
188a8dba487SGeorge Rimar   SymbolBody *B = findSymbol(Cmd->Name);
1898f1f3c40SMeador Inge   if (Cmd->Provide && (!B || B->isDefined()))
1908f1f3c40SMeador Inge     return;
1918f1f3c40SMeador Inge 
192a8dba487SGeorge Rimar   Cmd->Sym = addRegularSymbol(Cmd);
193ceabe80eSEugene Leviant }
194ceabe80eSEugene Leviant 
195076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
196076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
197076fe157SGeorge Rimar }
198076fe157SGeorge Rimar 
199076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
200076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
201076fe157SGeorge Rimar }
202076fe157SGeorge Rimar 
20355b169bfSRafael Espindola // Fill [Buf, Buf + Size) with Filler.
20455b169bfSRafael Espindola // This is used for linker script "=fillexp" command.
20555b169bfSRafael Espindola static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {
20655b169bfSRafael Espindola   size_t I = 0;
20755b169bfSRafael Espindola   for (; I + 4 < Size; I += 4)
20855b169bfSRafael Espindola     memcpy(Buf + I, &Filler, 4);
20955b169bfSRafael Espindola   memcpy(Buf + I, &Filler, Size - I);
21055b169bfSRafael Espindola }
21155b169bfSRafael Espindola 
212eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
213eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
214eea3114fSGeorge Rimar }
215eea3114fSGeorge Rimar 
216eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) {
217eefa758eSGeorge Rimar   return C->Kind == AssertKind;
218eefa758eSGeorge Rimar }
219eefa758eSGeorge Rimar 
220e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) {
221e38cbab5SGeorge Rimar   return C->Kind == BytesDataKind;
222e38cbab5SGeorge Rimar }
223e38cbab5SGeorge Rimar 
224b4c9b81aSRafael Espindola static StringRef basename(InputSectionBase *S) {
225b4c9b81aSRafael Espindola   if (S->File)
226b4c9b81aSRafael Espindola     return sys::path::filename(S->File->getName());
227e0be2901SRui Ueyama   return "";
228e0be2901SRui Ueyama }
229e0be2901SRui Ueyama 
230b8dd23f5SRui Ueyama bool LinkerScript::shouldKeep(InputSectionBase *S) {
231e0be2901SRui Ueyama   for (InputSectionDescription *ID : Opt.KeptSections)
232e0be2901SRui Ueyama     if (ID->FilePat.match(basename(S)))
233cf43f179SEugene Leviant       for (SectionPattern &P : ID->SectionPatterns)
234f91282e1SRui Ueyama         if (P.SectionPat.match(S->Name))
235eea3114fSGeorge Rimar           return true;
236eea3114fSGeorge Rimar   return false;
237eea3114fSGeorge Rimar }
238eea3114fSGeorge Rimar 
239ea93fe00SRui Ueyama // A helper function for the SORT() command.
240c404d50dSRafael Espindola static std::function<bool(InputSectionBase *, InputSectionBase *)>
241be394db3SGeorge Rimar getComparator(SortSectionPolicy K) {
242be394db3SGeorge Rimar   switch (K) {
243be394db3SGeorge Rimar   case SortSectionPolicy::Alignment:
244ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
245ea93fe00SRui Ueyama       // ">" is not a mistake. Sections with larger alignments are placed
246ea93fe00SRui Ueyama       // before sections with smaller alignments in order to reduce the
247ea93fe00SRui Ueyama       // amount of padding necessary. This is compatible with GNU.
248ea93fe00SRui Ueyama       return A->Alignment > B->Alignment;
249ea93fe00SRui Ueyama     };
250be394db3SGeorge Rimar   case SortSectionPolicy::Name:
251ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
252ea93fe00SRui Ueyama       return A->Name < B->Name;
253ea93fe00SRui Ueyama     };
254be394db3SGeorge Rimar   case SortSectionPolicy::Priority:
255ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
256ea93fe00SRui Ueyama       return getPriority(A->Name) < getPriority(B->Name);
257ea93fe00SRui Ueyama     };
258be394db3SGeorge Rimar   default:
259be394db3SGeorge Rimar     llvm_unreachable("unknown sort policy");
260be394db3SGeorge Rimar   }
261742c3836SRui Ueyama }
2620702c4e8SGeorge Rimar 
263ea93fe00SRui Ueyama // A helper function for the SORT() command.
264b4c9b81aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase *> Sections,
26506ae6836SGeorge Rimar                              ConstraintKind Kind) {
2668f66df92SGeorge Rimar   if (Kind == ConstraintKind::NoConstraint)
2678f66df92SGeorge Rimar     return true;
2682c7171bfSRui Ueyama 
2692c7171bfSRui Ueyama   bool IsRW = llvm::any_of(Sections, [](InputSectionBase *Sec) {
2702c7171bfSRui Ueyama     return static_cast<InputSectionBase *>(Sec)->Flags & SHF_WRITE;
27106ae6836SGeorge Rimar   });
2722c7171bfSRui Ueyama 
273e746e52cSRafael Espindola   return (IsRW && Kind == ConstraintKind::ReadWrite) ||
274e746e52cSRafael Espindola          (!IsRW && Kind == ConstraintKind::ReadOnly);
27506ae6836SGeorge Rimar }
27606ae6836SGeorge Rimar 
2776a1aa8d9SRafael Espindola static void sortSections(InputSection **Begin, InputSection **End,
278ee924709SRui Ueyama                          SortSectionPolicy K) {
279ee924709SRui Ueyama   if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
28007171f21SGeorge Rimar     std::stable_sort(Begin, End, getComparator(K));
281ee924709SRui Ueyama }
282ee924709SRui Ueyama 
283d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches.
2846a1aa8d9SRafael Espindola std::vector<InputSection *>
28572e107f3SRui Ueyama LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
2866a1aa8d9SRafael Espindola   std::vector<InputSection *> Ret;
2878c6a5aafSRui Ueyama 
28872e107f3SRui Ueyama   // Collects all sections that satisfy constraints of Cmd.
28972e107f3SRui Ueyama   for (const SectionPattern &Pat : Cmd->SectionPatterns) {
29072e107f3SRui Ueyama     size_t SizeBefore = Ret.size();
29172e107f3SRui Ueyama 
29272e107f3SRui Ueyama     for (InputSectionBase *Sec : InputSections) {
29372e107f3SRui Ueyama       if (Sec->Assigned)
2948c6a5aafSRui Ueyama         continue;
29572e107f3SRui Ueyama 
296e39709b2SRafael Espindola       if (!Sec->Live) {
297e39709b2SRafael Espindola         reportDiscarded(Sec);
298e39709b2SRafael Espindola         continue;
299e39709b2SRafael Espindola       }
300e39709b2SRafael Espindola 
301908a3d34SRafael Espindola       // For -emit-relocs we have to ignore entries like
302908a3d34SRafael Espindola       //   .rela.dyn : { *(.rela.data) }
303908a3d34SRafael Espindola       // which are common because they are in the default bfd script.
30472e107f3SRui Ueyama       if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
305908a3d34SRafael Espindola         continue;
3068c6a5aafSRui Ueyama 
30772e107f3SRui Ueyama       StringRef Filename = basename(Sec);
30872e107f3SRui Ueyama       if (!Cmd->FilePat.match(Filename) ||
30972e107f3SRui Ueyama           Pat.ExcludedFilePat.match(Filename) ||
31072e107f3SRui Ueyama           !Pat.SectionPat.match(Sec->Name))
311e0be2901SRui Ueyama         continue;
31272e107f3SRui Ueyama 
3136a1aa8d9SRafael Espindola       Ret.push_back(cast<InputSection>(Sec));
31472e107f3SRui Ueyama       Sec->Assigned = true;
315f94efdddSRui Ueyama     }
316d3190795SRafael Espindola 
317ee924709SRui Ueyama     // Sort sections as instructed by SORT-family commands and --sort-section
318ee924709SRui Ueyama     // option. Because SORT-family commands can be nested at most two depth
319ee924709SRui Ueyama     // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
320ee924709SRui Ueyama     // line option is respected even if a SORT command is given, the exact
321ee924709SRui Ueyama     // behavior we have here is a bit complicated. Here are the rules.
322ee924709SRui Ueyama     //
323ee924709SRui Ueyama     // 1. If two SORT commands are given, --sort-section is ignored.
324ee924709SRui Ueyama     // 2. If one SORT command is given, and if it is not SORT_NONE,
325ee924709SRui Ueyama     //    --sort-section is handled as an inner SORT command.
326ee924709SRui Ueyama     // 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
327ee924709SRui Ueyama     // 4. If no SORT command is given, sort according to --sort-section.
3286a1aa8d9SRafael Espindola     InputSection **Begin = Ret.data() + SizeBefore;
3296a1aa8d9SRafael Espindola     InputSection **End = Ret.data() + Ret.size();
33007171f21SGeorge Rimar     if (Pat.SortOuter != SortSectionPolicy::None) {
33107171f21SGeorge Rimar       if (Pat.SortInner == SortSectionPolicy::Default)
33207171f21SGeorge Rimar         sortSections(Begin, End, Config->SortSection);
333ee924709SRui Ueyama       else
33407171f21SGeorge Rimar         sortSections(Begin, End, Pat.SortInner);
33507171f21SGeorge Rimar       sortSections(Begin, End, Pat.SortOuter);
33607171f21SGeorge Rimar     }
337ee924709SRui Ueyama   }
33872e107f3SRui Ueyama   return Ret;
339be94e1b6SRafael Espindola }
340be94e1b6SRafael Espindola 
341b8dd23f5SRui Ueyama void LinkerScript::discard(ArrayRef<InputSectionBase *> V) {
342b4c9b81aSRafael Espindola   for (InputSectionBase *S : V) {
343be94e1b6SRafael Espindola     S->Live = false;
344503206c5SGeorge Rimar     if (S == InX::ShStrTab)
345ecbfd871SRafael Espindola       error("discarding .shstrtab section is not allowed");
346647c1685SGeorge Rimar     discard(S->DependentSections);
347be94e1b6SRafael Espindola   }
348be94e1b6SRafael Espindola }
349be94e1b6SRafael Espindola 
350b4c9b81aSRafael Espindola std::vector<InputSectionBase *>
351b8dd23f5SRui Ueyama LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) {
352b4c9b81aSRafael Espindola   std::vector<InputSectionBase *> Ret;
353e7f912cdSRui Ueyama 
3548f99f73cSRui Ueyama   for (BaseCommand *Base : OutCmd.Commands) {
3558f99f73cSRui Ueyama     auto *Cmd = dyn_cast<InputSectionDescription>(Base);
3567c3ff2ebSRafael Espindola     if (!Cmd)
3570b9ce6a4SRui Ueyama       continue;
35872e107f3SRui Ueyama 
35972e107f3SRui Ueyama     Cmd->Sections = computeInputSections(Cmd);
360e4c8b9b7SRafael Espindola     Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end());
3610b9ce6a4SRui Ueyama   }
362e71a3f8aSRafael Espindola 
3630b9ce6a4SRui Ueyama   return Ret;
3640b9ce6a4SRui Ueyama }
3650b9ce6a4SRui Ueyama 
366b8dd23f5SRui Ueyama void LinkerScript::processCommands(OutputSectionFactory &Factory) {
3675616adf6SRafael Espindola   // A symbol can be assigned before any section is mentioned in the linker
3685616adf6SRafael Espindola   // script. In an DSO, the symbol values are addresses, so the only important
3695616adf6SRafael Espindola   // section values are:
3705616adf6SRafael Espindola   // * SHN_UNDEF
3715616adf6SRafael Espindola   // * SHN_ABS
3725616adf6SRafael Espindola   // * Any value meaning a regular section.
3735616adf6SRafael Espindola   // To handle that, create a dummy aether section that fills the void before
3745616adf6SRafael Espindola   // the linker scripts switches to another section. It has an index of one
3755616adf6SRafael Espindola   // which will map to whatever the first actual section is.
3765616adf6SRafael Espindola   Aether = make<OutputSection>("", 0, SHF_ALLOC);
3775616adf6SRafael Espindola   Aether->SectionIndex = 1;
3785616adf6SRafael Espindola   CurOutSec = Aether;
37949592cf6SRafael Espindola   Dot = 0;
3805616adf6SRafael Espindola 
38192a5ba6dSRui Ueyama   for (size_t I = 0; I < Opt.Commands.size(); ++I) {
3820b1b695aSRui Ueyama     // Handle symbol assignments outside of any output section.
38392a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Opt.Commands[I])) {
3844cd7352cSRafael Espindola       addSymbol(Cmd);
3852ab5f73dSRui Ueyama       continue;
3862ab5f73dSRui Ueyama     }
3870b1b695aSRui Ueyama 
38892a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I])) {
389b4c9b81aSRafael Espindola       std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
3907bd37870SRafael Espindola 
3910b1b695aSRui Ueyama       // The output section name `/DISCARD/' is special.
3920b1b695aSRui Ueyama       // Any input section assigned to it is discarded.
39348c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
3947bd37870SRafael Espindola         discard(V);
39548c3f1ceSRui Ueyama         continue;
39648c3f1ceSRui Ueyama       }
3970b9ce6a4SRui Ueyama 
3980b1b695aSRui Ueyama       // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
3990b1b695aSRui Ueyama       // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
4000b1b695aSRui Ueyama       // sections satisfy a given constraint. If not, a directive is handled
40107d7c42cSGeorge Rimar       // as if it wasn't present from the beginning.
4020b1b695aSRui Ueyama       //
4030b1b695aSRui Ueyama       // Because we'll iterate over Commands many more times, the easiest
40407d7c42cSGeorge Rimar       // way to "make it as if it wasn't present" is to just remove it.
405f7f0d088SGeorge Rimar       if (!matchConstraints(V, Cmd->Constraint)) {
406b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
407f94efdddSRui Ueyama           S->Assigned = false;
40892a5ba6dSRui Ueyama         Opt.Commands.erase(Opt.Commands.begin() + I);
40907d7c42cSGeorge Rimar         --I;
4107c3ff2ebSRafael Espindola         continue;
4117c3ff2ebSRafael Espindola       }
4127c3ff2ebSRafael Espindola 
4130b1b695aSRui Ueyama       // A directive may contain symbol definitions like this:
4140b1b695aSRui Ueyama       // ".foo : { ...; bar = .; }". Handle them.
4158f99f73cSRui Ueyama       for (BaseCommand *Base : Cmd->Commands)
4168f99f73cSRui Ueyama         if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
4174cd7352cSRafael Espindola           addSymbol(OutCmd);
4187c3ff2ebSRafael Espindola 
4190b1b695aSRui Ueyama       // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
4200b1b695aSRui Ueyama       // is given, input sections are aligned to that value, whether the
4210b1b695aSRui Ueyama       // given value is larger or smaller than the original section alignment.
4220b1b695aSRui Ueyama       if (Cmd->SubalignExpr) {
42372dc195dSRafael Espindola         uint32_t Subalign = Cmd->SubalignExpr().getValue();
424b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
4250b1b695aSRui Ueyama           S->Alignment = Subalign;
42620d03194SEugene Leviant       }
4270b1b695aSRui Ueyama 
4280b1b695aSRui Ueyama       // Add input sections to an output section.
429d86a4e50SGeorge Rimar       for (InputSectionBase *S : V)
4304f013bb3SRafael Espindola         Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
431660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
432660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX);
433660c9ab9SRafael Espindola         Sec->SectionIndex = I;
434fbb0463fSGeorge Rimar         if (Cmd->Noload)
435fbb0463fSGeorge Rimar           Sec->Type = SHT_NOBITS;
436d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
437660c9ab9SRafael Espindola       }
43848c3f1ceSRui Ueyama     }
4394aa2ef5bSRafael Espindola   }
4405616adf6SRafael Espindola   CurOutSec = nullptr;
441db24d9c3SGeorge Rimar }
442e63d81bdSEugene Leviant 
44302ed7575SRafael Espindola void LinkerScript::fabricateDefaultCommands() {
444cbfe9e94SPeter Smith   std::vector<BaseCommand *> Commands;
445cbfe9e94SPeter Smith 
446cbfe9e94SPeter Smith   // Define start address
447e76231b6SRafael Espindola   uint64_t StartAddr = -1;
448cbfe9e94SPeter Smith 
449c60b4510SPeter Smith   // The Sections with -T<section> have been sorted in order of ascending
450c60b4510SPeter Smith   // address. We must lower StartAddr if the lowest -T<section address> as
451c60b4510SPeter Smith   // calls to setDot() must be monotonically increasing.
452c60b4510SPeter Smith   for (auto& KV : Config->SectionStartMap)
453c60b4510SPeter Smith     StartAddr = std::min(StartAddr, KV.second);
454c60b4510SPeter Smith 
455e76231b6SRafael Espindola   Commands.push_back(make<SymbolAssignment>(
456e76231b6SRafael Espindola       ".",
457e76231b6SRafael Espindola       [=] {
458e76231b6SRafael Espindola         return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize());
459e76231b6SRafael Espindola       },
460e76231b6SRafael Espindola       ""));
461cbfe9e94SPeter Smith 
462cbfe9e94SPeter Smith   // For each OutputSection that needs a VA fabricate an OutputSectionCommand
463cbfe9e94SPeter Smith   // with an InputSectionDescription describing the InputSections
464cbfe9e94SPeter Smith   for (OutputSection *Sec : *OutputSections) {
46505c4f67cSRafael Espindola     auto *OSCmd = createOutputSectionCommand(Sec->Name, "<internal>");
466c60b4510SPeter Smith     OSCmd->Sec = Sec;
467d7dc2258SRafael Espindola     SecToCommand[Sec] = OSCmd;
468c60b4510SPeter Smith 
469c60b4510SPeter Smith     // Prefer user supplied address over additional alignment constraint
470cbfe9e94SPeter Smith     auto I = Config->SectionStartMap.find(Sec->Name);
471cbfe9e94SPeter Smith     if (I != Config->SectionStartMap.end())
472bb7bd3eeSRafael Espindola       OSCmd->AddrExpr = [=] { return I->second; };
473c60b4510SPeter Smith 
474cbfe9e94SPeter Smith     Commands.push_back(OSCmd);
475cbfe9e94SPeter Smith     if (Sec->Sections.size()) {
476cbfe9e94SPeter Smith       auto *ISD = make<InputSectionDescription>("");
477cbfe9e94SPeter Smith       OSCmd->Commands.push_back(ISD);
478cbfe9e94SPeter Smith       for (InputSection *ISec : Sec->Sections) {
479cbfe9e94SPeter Smith         ISD->Sections.push_back(ISec);
480cbfe9e94SPeter Smith         ISec->Assigned = true;
481cbfe9e94SPeter Smith       }
482cbfe9e94SPeter Smith     }
483cbfe9e94SPeter Smith   }
484cbfe9e94SPeter Smith   // SECTIONS commands run before other non SECTIONS commands
485cbfe9e94SPeter Smith   Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end());
486cbfe9e94SPeter Smith   Opt.Commands = std::move(Commands);
487cbfe9e94SPeter Smith }
488cbfe9e94SPeter Smith 
4890b1b695aSRui Ueyama // Add sections that didn't match any sections command.
490b8dd23f5SRui Ueyama void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
4914f013bb3SRafael Espindola   for (InputSectionBase *S : InputSections) {
492db5e56f7SRafael Espindola     if (!S->Live || S->Parent)
4934f013bb3SRafael Espindola       continue;
4944f013bb3SRafael Espindola     StringRef Name = getOutputSectionName(S->Name);
4954f013bb3SRafael Espindola     auto I = std::find_if(
4964f013bb3SRafael Espindola         Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
4974f013bb3SRafael Espindola           if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
4984f013bb3SRafael Espindola             return Cmd->Name == Name;
4994f013bb3SRafael Espindola           return false;
5004f013bb3SRafael Espindola         });
501de8d9897SRafael Espindola     if (I == Opt.Commands.end()) {
5024f013bb3SRafael Espindola       Factory.addInputSec(S, Name);
503de8d9897SRafael Espindola     } else {
504de8d9897SRafael Espindola       auto *Cmd = cast<OutputSectionCommand>(*I);
505de8d9897SRafael Espindola       Factory.addInputSec(S, Name, Cmd->Sec);
506660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
507d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
508660c9ab9SRafael Espindola         unsigned Index = std::distance(Opt.Commands.begin(), I);
509660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index);
510660c9ab9SRafael Espindola         Sec->SectionIndex = Index;
511660c9ab9SRafael Espindola       }
512de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
5136a1aa8d9SRafael Espindola       ISD->Sections.push_back(cast<InputSection>(S));
514de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
515de8d9897SRafael Espindola     }
5164f013bb3SRafael Espindola   }
517e63d81bdSEugene Leviant }
518e63d81bdSEugene Leviant 
5197c4eafa3SRafael Espindola uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
5207c4eafa3SRafael Espindola   bool IsTbss = (CurOutSec->Flags & SHF_TLS) && CurOutSec->Type == SHT_NOBITS;
5217c4eafa3SRafael Espindola   uint64_t Start = IsTbss ? Dot + ThreadBssOffset : Dot;
5227c4eafa3SRafael Espindola   Start = alignTo(Start, Align);
5237c4eafa3SRafael Espindola   uint64_t End = Start + Size;
5247c4eafa3SRafael Espindola 
5257c4eafa3SRafael Espindola   if (IsTbss)
5267c4eafa3SRafael Espindola     ThreadBssOffset = End - Dot;
5277c4eafa3SRafael Espindola   else
5287c4eafa3SRafael Espindola     Dot = End;
5297c4eafa3SRafael Espindola   return End;
530a940e539SRafael Espindola }
531a940e539SRafael Espindola 
532b8dd23f5SRui Ueyama void LinkerScript::output(InputSection *S) {
5337c4eafa3SRafael Espindola   uint64_t Pos = advance(S->getSize(), S->Alignment);
5347c4eafa3SRafael Espindola   S->OutSecOff = Pos - S->getSize() - CurOutSec->Addr;
535d3190795SRafael Espindola 
536d3190795SRafael Espindola   // Update output section size after adding each section. This is so that
537d3190795SRafael Espindola   // SIZEOF works correctly in the case below:
538d3190795SRafael Espindola   // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
53904a2e348SRafael Espindola   CurOutSec->Size = Pos - CurOutSec->Addr;
540d3190795SRafael Espindola 
541b889744eSMeador Inge   // If there is a memory region associated with this input section, then
542b889744eSMeador Inge   // place the section in that region and update the region index.
543b889744eSMeador Inge   if (CurMemRegion) {
544b889744eSMeador Inge     CurMemRegion->Offset += CurOutSec->Size;
545b889744eSMeador Inge     uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin;
546b889744eSMeador Inge     if (CurSize > CurMemRegion->Length) {
547b889744eSMeador Inge       uint64_t OverflowAmt = CurSize - CurMemRegion->Length;
548b889744eSMeador Inge       error("section '" + CurOutSec->Name + "' will not fit in region '" +
549b889744eSMeador Inge             CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
550b889744eSMeador Inge             " bytes");
551b889744eSMeador Inge     }
552b889744eSMeador Inge   }
5532de509c3SRui Ueyama }
554ceabe80eSEugene Leviant 
555b8dd23f5SRui Ueyama void LinkerScript::switchTo(OutputSection *Sec) {
556d3190795SRafael Espindola   if (CurOutSec == Sec)
557d3190795SRafael Espindola     return;
558d3190795SRafael Espindola 
559d3190795SRafael Espindola   CurOutSec = Sec;
5607c4eafa3SRafael Espindola   CurOutSec->Addr = advance(0, CurOutSec->Alignment);
561b71d6f7aSEugene Leviant 
562b71d6f7aSEugene Leviant   // If neither AT nor AT> is specified for an allocatable section, the linker
563b71d6f7aSEugene Leviant   // will set the LMA such that the difference between VMA and LMA for the
564b71d6f7aSEugene Leviant   // section is the same as the preceding output section in the same region
565b71d6f7aSEugene Leviant   // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
56621467876SGeorge Rimar   if (LMAOffset)
56729c1afb8SRafael Espindola     CurOutSec->LMAOffset = LMAOffset();
568d3190795SRafael Espindola }
569d3190795SRafael Espindola 
570b8dd23f5SRui Ueyama void LinkerScript::process(BaseCommand &Base) {
5712e081a4fSRui Ueyama   // This handles the assignments to symbol or to the dot.
5722e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<SymbolAssignment>(&Base)) {
5732e081a4fSRui Ueyama     assignSymbol(Cmd, true);
574d3190795SRafael Espindola     return;
57597403d15SEugene Leviant   }
576e38cbab5SGeorge Rimar 
577e38cbab5SGeorge Rimar   // Handle BYTE(), SHORT(), LONG(), or QUAD().
5782e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) {
5792e081a4fSRui Ueyama     Cmd->Offset = Dot - CurOutSec->Addr;
5802e081a4fSRui Ueyama     Dot += Cmd->Size;
58104a2e348SRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
582e38cbab5SGeorge Rimar     return;
583e38cbab5SGeorge Rimar   }
584e38cbab5SGeorge Rimar 
5852e081a4fSRui Ueyama   // Handle ASSERT().
5862e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<AssertCommand>(&Base)) {
5872e081a4fSRui Ueyama     Cmd->Expression();
588b2d99d6aSMeador Inge     return;
589b2d99d6aSMeador Inge   }
590b2d99d6aSMeador Inge 
5912e081a4fSRui Ueyama   // Handle a single input section description command.
5922e081a4fSRui Ueyama   // It calculates and assigns the offsets for each section and also
593e38cbab5SGeorge Rimar   // updates the output section size.
5942e081a4fSRui Ueyama   auto &Cmd = cast<InputSectionDescription>(Base);
595a85e8ddaSRafael Espindola   for (InputSection *Sec : Cmd.Sections) {
5963fb5a6dcSGeorge Rimar     // We tentatively added all synthetic sections at the beginning and removed
5973fb5a6dcSGeorge Rimar     // empty ones afterwards (because there is no way to know whether they were
5983fb5a6dcSGeorge Rimar     // going be empty or not other than actually running linker scripts.)
5993fb5a6dcSGeorge Rimar     // We need to ignore remains of empty sections.
6002e081a4fSRui Ueyama     if (auto *S = dyn_cast<SyntheticSection>(Sec))
6012e081a4fSRui Ueyama       if (S->empty())
6023fb5a6dcSGeorge Rimar         continue;
6033fb5a6dcSGeorge Rimar 
6042e081a4fSRui Ueyama     if (!Sec->Live)
60578ef645fSGeorge Rimar       continue;
606db5e56f7SRafael Espindola     assert(CurOutSec == Sec->getParent());
607a85e8ddaSRafael Espindola     output(Sec);
608ceabe80eSEugene Leviant   }
609ceabe80eSEugene Leviant }
610ceabe80eSEugene Leviant 
611b889744eSMeador Inge // This function searches for a memory region to place the given output
612b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is
613b889744eSMeador Inge // returned. Otherwise, a nullptr is returned.
6141902b337SRafael Espindola MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd) {
615b889744eSMeador Inge   // If a memory region name was specified in the output section command,
616b889744eSMeador Inge   // then try to find that region first.
617b889744eSMeador Inge   if (!Cmd->MemoryRegionName.empty()) {
618b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
619b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
620b889744eSMeador Inge       return &It->second;
621b889744eSMeador Inge     error("memory region '" + Cmd->MemoryRegionName + "' not declared");
622b889744eSMeador Inge     return nullptr;
623b889744eSMeador Inge   }
624b889744eSMeador Inge 
625d7c5400fSRui Ueyama   // If at least one memory region is defined, all sections must
626d7c5400fSRui Ueyama   // belong to some memory region. Otherwise, we don't need to do
627d7c5400fSRui Ueyama   // anything for memory regions.
628cc400cc8SRui Ueyama   if (Opt.MemoryRegions.empty())
629b889744eSMeador Inge     return nullptr;
630b889744eSMeador Inge 
6311902b337SRafael Espindola   OutputSection *Sec = Cmd->Sec;
632b889744eSMeador Inge   // See if a region can be found by matching section flags.
6332e081a4fSRui Ueyama   for (auto &Pair : Opt.MemoryRegions) {
6342e081a4fSRui Ueyama     MemoryRegion &M = Pair.second;
6352e081a4fSRui Ueyama     if ((M.Flags & Sec->Flags) && (M.NegFlags & Sec->Flags) == 0)
6362e081a4fSRui Ueyama       return &M;
637b889744eSMeador Inge   }
638b889744eSMeador Inge 
639b889744eSMeador Inge   // Otherwise, no suitable region was found.
640b889744eSMeador Inge   if (Sec->Flags & SHF_ALLOC)
641b889744eSMeador Inge     error("no memory region specified for section '" + Sec->Name + "'");
642b889744eSMeador Inge   return nullptr;
643b889744eSMeador Inge }
644b889744eSMeador Inge 
6450b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section
6460b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }").
647b8dd23f5SRui Ueyama void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) {
6489b980095SRafael Espindola   OutputSection *Sec = Cmd->Sec;
6492b074553SRafael Espindola   if (!Sec)
650d3190795SRafael Espindola     return;
651b889744eSMeador Inge 
652cba41013SRui Ueyama   if (Cmd->AddrExpr && (Sec->Flags & SHF_ALLOC))
653d379f735SRui Ueyama     setDot(Cmd->AddrExpr, Cmd->Location, false);
654679828ffSRafael Espindola 
6555784e96fSEugene Leviant   if (Cmd->LMAExpr) {
6560c1c8085SGeorge Rimar     uint64_t D = Dot;
65772dc195dSRafael Espindola     LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; };
6585784e96fSEugene Leviant   }
6595784e96fSEugene Leviant 
660feed7506SRafael Espindola   CurMemRegion = Cmd->MemRegion;
661b889744eSMeador Inge   if (CurMemRegion)
662b889744eSMeador Inge     Dot = CurMemRegion->Offset;
663b889744eSMeador Inge   switchTo(Sec);
6640b1b695aSRui Ueyama 
665d86a4e50SGeorge Rimar   // We do not support custom layout for compressed debug sectons.
666d86a4e50SGeorge Rimar   // At this point we already know their size and have compressed content.
667d86a4e50SGeorge Rimar   if (CurOutSec->Flags & SHF_COMPRESSED)
668d86a4e50SGeorge Rimar     return;
669d86a4e50SGeorge Rimar 
670de8d9897SRafael Espindola   for (BaseCommand *C : Cmd->Commands)
671de8d9897SRafael Espindola     process(*C);
672d3190795SRafael Espindola }
673d3190795SRafael Espindola 
674b8dd23f5SRui Ueyama void LinkerScript::removeEmptyCommands() {
6756d38e4dbSRafael Espindola   // It is common practice to use very generic linker scripts. So for any
6766d38e4dbSRafael Espindola   // given run some of the output sections in the script will be empty.
6776d38e4dbSRafael Espindola   // We could create corresponding empty output sections, but that would
6786d38e4dbSRafael Espindola   // clutter the output.
6796d38e4dbSRafael Espindola   // We instead remove trivially empty sections. The bfd linker seems even
6806d38e4dbSRafael Espindola   // more aggressive at removing them.
6816d38e4dbSRafael Espindola   auto Pos = std::remove_if(
6828f99f73cSRui Ueyama       Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
6838f99f73cSRui Ueyama         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
6844f013bb3SRafael Espindola           return std::find(OutputSections->begin(), OutputSections->end(),
6854f013bb3SRafael Espindola                            Cmd->Sec) == OutputSections->end();
6860b1b695aSRui Ueyama         return false;
6876d38e4dbSRafael Espindola       });
6886d38e4dbSRafael Espindola   Opt.Commands.erase(Pos, Opt.Commands.end());
68907fe6129SRafael Espindola }
69007fe6129SRafael Espindola 
6916a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
6928f99f73cSRui Ueyama   for (BaseCommand *Base : Cmd.Commands)
6938f99f73cSRui Ueyama     if (!isa<InputSectionDescription>(*Base))
6946a53737cSRafael Espindola       return false;
6956a53737cSRafael Espindola   return true;
6966a53737cSRafael Espindola }
6976d38e4dbSRafael Espindola 
698b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsBeforeSorting() {
6999546fffbSRafael Espindola   // If the output section contains only symbol assignments, create a
7009546fffbSRafael Espindola   // corresponding output section. The bfd linker seems to only create them if
7019546fffbSRafael Espindola   // '.' is assigned to, but creating these section should not have any bad
7029546fffbSRafael Espindola   // consequeces and gives us a section to put the symbol in.
7030c1c8085SGeorge Rimar   uint64_t Flags = SHF_ALLOC;
704660c9ab9SRafael Espindola 
705660c9ab9SRafael Espindola   for (int I = 0, E = Opt.Commands.size(); I != E; ++I) {
706660c9ab9SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
7079546fffbSRafael Espindola     if (!Cmd)
7089546fffbSRafael Espindola       continue;
7094f013bb3SRafael Espindola     if (OutputSection *Sec = Cmd->Sec) {
7102b074553SRafael Espindola       Flags = Sec->Flags;
7119546fffbSRafael Espindola       continue;
7129546fffbSRafael Espindola     }
7139546fffbSRafael Espindola 
7146a53737cSRafael Espindola     if (isAllSectionDescription(*Cmd))
7156a53737cSRafael Espindola       continue;
7166a53737cSRafael Espindola 
717fd0c844fSDmitry Mikulin     auto *OutSec = make<OutputSection>(Cmd->Name, SHT_PROGBITS, Flags);
718660c9ab9SRafael Espindola     OutSec->SectionIndex = I;
7199546fffbSRafael Espindola     OutputSections->push_back(OutSec);
7209b980095SRafael Espindola     Cmd->Sec = OutSec;
721d7dc2258SRafael Espindola     SecToCommand[OutSec] = Cmd;
7229546fffbSRafael Espindola   }
723f7a17448SRafael Espindola }
724f7a17448SRafael Espindola 
725b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsAfterSorting() {
726f7a17448SRafael Espindola   placeOrphanSections();
727f7a17448SRafael Espindola 
728feed7506SRafael Espindola   // Try and find an appropriate memory region to assign offsets in.
729d1960dc0SRafael Espindola   for (BaseCommand *Base : Opt.Commands) {
730d1960dc0SRafael Espindola     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) {
731feed7506SRafael Espindola       Cmd->MemRegion = findMemoryRegion(Cmd);
732d1960dc0SRafael Espindola       // Handle align (e.g. ".foo : ALIGN(16) { ... }").
733d1960dc0SRafael Espindola       if (Cmd->AlignExpr)
734d1960dc0SRafael Espindola 	Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue());
735d1960dc0SRafael Espindola     }
736d1960dc0SRafael Espindola   }
737feed7506SRafael Espindola 
738f7a17448SRafael Espindola   // If output section command doesn't specify any segments,
739f7a17448SRafael Espindola   // and we haven't previously assigned any section to segment,
740f7a17448SRafael Espindola   // then we simply assign section to the very first load segment.
741f7a17448SRafael Espindola   // Below is an example of such linker script:
742f7a17448SRafael Espindola   // PHDRS { seg PT_LOAD; }
743f7a17448SRafael Espindola   // SECTIONS { .aaa : { *(.aaa) } }
744f7a17448SRafael Espindola   std::vector<StringRef> DefPhdrs;
745f7a17448SRafael Espindola   auto FirstPtLoad =
746f7a17448SRafael Espindola       std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(),
747f7a17448SRafael Espindola                    [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; });
748f7a17448SRafael Espindola   if (FirstPtLoad != Opt.PhdrsCommands.end())
749f7a17448SRafael Espindola     DefPhdrs.push_back(FirstPtLoad->Name);
750f7a17448SRafael Espindola 
751f7a17448SRafael Espindola   // Walk the commands and propagate the program headers to commands that don't
752f7a17448SRafael Espindola   // explicitly specify them.
7538f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
7548f99f73cSRui Ueyama     auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
755f7a17448SRafael Espindola     if (!Cmd)
756f7a17448SRafael Espindola       continue;
7578f99f73cSRui Ueyama 
758f7a17448SRafael Espindola     if (Cmd->Phdrs.empty())
759f7a17448SRafael Espindola       Cmd->Phdrs = DefPhdrs;
760f7a17448SRafael Espindola     else
761f7a17448SRafael Espindola       DefPhdrs = Cmd->Phdrs;
762f7a17448SRafael Espindola   }
7636a53737cSRafael Espindola 
7646a53737cSRafael Espindola   removeEmptyCommands();
7659546fffbSRafael Espindola }
7669546fffbSRafael Espindola 
76715c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments
76815c57951SRafael Espindola // so that an orphan after
76915c57951SRafael Espindola //   begin_foo = .;
77015c57951SRafael Espindola //   foo : { *(foo) }
77115c57951SRafael Espindola //   end_foo = .;
77215c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols.
77315c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the
77415c57951SRafael Espindola // one in charge of deciding the order of the sections.
77515c57951SRafael Espindola // We don't want to go over alignments, since doing so in
77615c57951SRafael Espindola //  rx_sec : { *(rx_sec) }
77715c57951SRafael Espindola //  . = ALIGN(0x1000);
77815c57951SRafael Espindola //  /* The RW PT_LOAD starts here*/
77915c57951SRafael Espindola //  rw_sec : { *(rw_sec) }
78015c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned.
7814e1e88e3SRui Ueyama static bool shouldSkip(BaseCommand *Cmd) {
78215c57951SRafael Espindola   if (isa<OutputSectionCommand>(Cmd))
78315c57951SRafael Espindola     return false;
7844e1e88e3SRui Ueyama   if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd))
7855fcc99c2SRafael Espindola     return Assign->Name != ".";
7864e1e88e3SRui Ueyama   return true;
78715c57951SRafael Espindola }
78815c57951SRafael Espindola 
7896697ec29SRui Ueyama // Orphan sections are sections present in the input files which are
7906697ec29SRui Ueyama // not explicitly placed into the output file by the linker script.
7916697ec29SRui Ueyama //
7926697ec29SRui Ueyama // When the control reaches this function, Opt.Commands contains
7936697ec29SRui Ueyama // output section commands for non-orphan sections only. This function
79481cb7107SRui Ueyama // adds new elements for orphan sections so that all sections are
79581cb7107SRui Ueyama // explicitly handled by Opt.Commands.
7966697ec29SRui Ueyama //
7976697ec29SRui Ueyama // Writer<ELFT>::sortSections has already sorted output sections.
7986697ec29SRui Ueyama // What we need to do is to scan OutputSections vector and
7996697ec29SRui Ueyama // Opt.Commands in parallel to find orphan sections. If there is an
8006697ec29SRui Ueyama // output section that doesn't have a corresponding entry in
8016697ec29SRui Ueyama // Opt.Commands, we will insert a new entry to Opt.Commands.
8026697ec29SRui Ueyama //
8036697ec29SRui Ueyama // There is some ambiguity as to where exactly a new entry should be
8046697ec29SRui Ueyama // inserted, because Opt.Commands contains not only output section
80581cb7107SRui Ueyama // commands but also other types of commands such as symbol assignment
8066697ec29SRui Ueyama // expressions. There's no correct answer here due to the lack of the
8076697ec29SRui Ueyama // formal specification of the linker script. We use heuristics to
8086697ec29SRui Ueyama // determine whether a new output command should be added before or
8096697ec29SRui Ueyama // after another commands. For the details, look at shouldSkip
8106697ec29SRui Ueyama // function.
811b8dd23f5SRui Ueyama void LinkerScript::placeOrphanSections() {
812aab6d5c5SRafael Espindola   // The OutputSections are already in the correct order.
813aab6d5c5SRafael Espindola   // This loops creates or moves commands as needed so that they are in the
814aab6d5c5SRafael Espindola   // correct order.
815aab6d5c5SRafael Espindola   int CmdIndex = 0;
8165fcc99c2SRafael Espindola 
8175fcc99c2SRafael Espindola   // As a horrible special case, skip the first . assignment if it is before any
8185fcc99c2SRafael Espindola   // section. We do this because it is common to set a load address by starting
8195fcc99c2SRafael Espindola   // the script with ". = 0xabcd" and the expectation is that every section is
8205fcc99c2SRafael Espindola   // after that.
8214e1e88e3SRui Ueyama   auto FirstSectionOrDotAssignment =
8224e1e88e3SRui Ueyama       std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
8234e1e88e3SRui Ueyama                    [](BaseCommand *Cmd) { return !shouldSkip(Cmd); });
8245fcc99c2SRafael Espindola   if (FirstSectionOrDotAssignment != Opt.Commands.end()) {
8255fcc99c2SRafael Espindola     CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin();
8265fcc99c2SRafael Espindola     if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
8275fcc99c2SRafael Espindola       ++CmdIndex;
8285fcc99c2SRafael Espindola   }
8295fcc99c2SRafael Espindola 
83024e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
83140849419SRafael Espindola     StringRef Name = Sec->Name;
832aab6d5c5SRafael Espindola 
833aab6d5c5SRafael Espindola     // Find the last spot where we can insert a command and still get the
83415c57951SRafael Espindola     // correct result.
835aab6d5c5SRafael Espindola     auto CmdIter = Opt.Commands.begin() + CmdIndex;
836aab6d5c5SRafael Espindola     auto E = Opt.Commands.end();
8374e1e88e3SRui Ueyama     while (CmdIter != E && shouldSkip(*CmdIter)) {
838aab6d5c5SRafael Espindola       ++CmdIter;
839aab6d5c5SRafael Espindola       ++CmdIndex;
840aab6d5c5SRafael Espindola     }
841aab6d5c5SRafael Espindola 
842de8d9897SRafael Espindola     // If there is no command corresponding to this output section,
843de8d9897SRafael Espindola     // create one and put a InputSectionDescription in it so that both
844de8d9897SRafael Espindola     // representations agree on which input sections to use.
845fa948c72SRafael Espindola     OutputSectionCommand *Cmd = getCmd(Sec);
846fa948c72SRafael Espindola     if (!Cmd) {
84705c4f67cSRafael Espindola       Cmd = createOutputSectionCommand(Name, "<internal>");
8489b980095SRafael Espindola       Opt.Commands.insert(CmdIter, Cmd);
849aab6d5c5SRafael Espindola       ++CmdIndex;
850de8d9897SRafael Espindola 
851de8d9897SRafael Espindola       Cmd->Sec = Sec;
852d7dc2258SRafael Espindola       SecToCommand[Sec] = Cmd;
853de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
854de8d9897SRafael Espindola       for (InputSection *IS : Sec->Sections)
855de8d9897SRafael Espindola         ISD->Sections.push_back(IS);
856de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
857de8d9897SRafael Espindola 
85815c57951SRafael Espindola       continue;
85915c57951SRafael Espindola     }
86015c57951SRafael Espindola 
86115c57951SRafael Espindola     // Continue from where we found it.
862fa948c72SRafael Espindola     while (*CmdIter != Cmd) {
863fa948c72SRafael Espindola       ++CmdIter;
864fa948c72SRafael Espindola       ++CmdIndex;
865fa948c72SRafael Espindola     }
866fa948c72SRafael Espindola     ++CmdIndex;
867652852c5SGeorge Rimar   }
868337f903cSRafael Espindola }
869337f903cSRafael Espindola 
870b8dd23f5SRui Ueyama void LinkerScript::processNonSectionCommands() {
8718f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
8728f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
873d379f735SRui Ueyama       assignSymbol(Cmd, false);
8748f99f73cSRui Ueyama     else if (auto *Cmd = dyn_cast<AssertCommand>(Base))
87502ad516bSPetr Hosek       Cmd->Expression();
87602ad516bSPetr Hosek   }
87702ad516bSPetr Hosek }
87802ad516bSPetr Hosek 
879faf25a72SRafael Espindola static bool
880faf25a72SRafael Espindola allocateHeaders(std::vector<PhdrEntry> &Phdrs,
881faf25a72SRafael Espindola                 ArrayRef<OutputSectionCommand *> OutputSectionCommands,
88202ed7575SRafael Espindola                 uint64_t Min) {
88302ed7575SRafael Espindola   auto FirstPTLoad =
88402ed7575SRafael Espindola       std::find_if(Phdrs.begin(), Phdrs.end(),
88502ed7575SRafael Espindola                    [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
88602ed7575SRafael Espindola   if (FirstPTLoad == Phdrs.end())
88702ed7575SRafael Espindola     return false;
88802ed7575SRafael Espindola 
88902ed7575SRafael Espindola   uint64_t HeaderSize = getHeaderSize();
89002ed7575SRafael Espindola   if (HeaderSize <= Min || Script->hasPhdrsCommands()) {
89102ed7575SRafael Espindola     Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
89202ed7575SRafael Espindola     Out::ElfHeader->Addr = Min;
89302ed7575SRafael Espindola     Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
89402ed7575SRafael Espindola     return true;
89502ed7575SRafael Espindola   }
89602ed7575SRafael Espindola 
89702ed7575SRafael Espindola   assert(FirstPTLoad->First == Out::ElfHeader);
89802ed7575SRafael Espindola   OutputSection *ActualFirst = nullptr;
899faf25a72SRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
900faf25a72SRafael Espindola     OutputSection *Sec = Cmd->Sec;
90102ed7575SRafael Espindola     if (Sec->FirstInPtLoad == Out::ElfHeader) {
90202ed7575SRafael Espindola       ActualFirst = Sec;
90302ed7575SRafael Espindola       break;
90402ed7575SRafael Espindola     }
90502ed7575SRafael Espindola   }
90602ed7575SRafael Espindola   if (ActualFirst) {
907faf25a72SRafael Espindola     for (OutputSectionCommand *Cmd : OutputSectionCommands) {
908faf25a72SRafael Espindola       OutputSection *Sec = Cmd->Sec;
90902ed7575SRafael Espindola       if (Sec->FirstInPtLoad == Out::ElfHeader)
91002ed7575SRafael Espindola         Sec->FirstInPtLoad = ActualFirst;
911faf25a72SRafael Espindola     }
91202ed7575SRafael Espindola     FirstPTLoad->First = ActualFirst;
91302ed7575SRafael Espindola   } else {
91402ed7575SRafael Espindola     Phdrs.erase(FirstPTLoad);
91502ed7575SRafael Espindola   }
91602ed7575SRafael Espindola 
91702ed7575SRafael Espindola   auto PhdrI = std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry &E) {
91802ed7575SRafael Espindola     return E.p_type == PT_PHDR;
91902ed7575SRafael Espindola   });
92002ed7575SRafael Espindola   if (PhdrI != Phdrs.end())
92102ed7575SRafael Espindola     Phdrs.erase(PhdrI);
92202ed7575SRafael Espindola   return false;
92302ed7575SRafael Espindola }
92402ed7575SRafael Espindola 
925faf25a72SRafael Espindola void LinkerScript::assignAddresses(
926faf25a72SRafael Espindola     std::vector<PhdrEntry> &Phdrs,
927faf25a72SRafael Espindola     ArrayRef<OutputSectionCommand *> OutputSectionCommands) {
9287c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
929be607334SRafael Espindola   Dot = 0;
93072dc195dSRafael Espindola   ErrorOnMissingSection = true;
93106f4743aSRafael Espindola   switchTo(Aether);
93206f4743aSRafael Espindola 
9338f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
9348f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
935d379f735SRui Ueyama       assignSymbol(Cmd, false);
93605ef4cffSRui Ueyama       continue;
937652852c5SGeorge Rimar     }
938652852c5SGeorge Rimar 
9398f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<AssertCommand>(Base)) {
9404595df94SRafael Espindola       Cmd->Expression();
941eefa758eSGeorge Rimar       continue;
942eefa758eSGeorge Rimar     }
943eefa758eSGeorge Rimar 
9448f99f73cSRui Ueyama     auto *Cmd = cast<OutputSectionCommand>(Base);
945d3190795SRafael Espindola     assignOffsets(Cmd);
946a14b13d8SGeorge Rimar   }
947467c4d55SEugene Leviant 
9480c1c8085SGeorge Rimar   uint64_t MinVA = std::numeric_limits<uint64_t>::max();
949faf25a72SRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
950faf25a72SRafael Espindola     OutputSection *Sec = Cmd->Sec;
95104a2e348SRafael Espindola     if (Sec->Flags & SHF_ALLOC)
952e08e78dfSRafael Espindola       MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
953ea590d91SRafael Espindola     else
954ea590d91SRafael Espindola       Sec->Addr = 0;
955ea590d91SRafael Espindola   }
956aab6d5c5SRafael Espindola 
957faf25a72SRafael Espindola   allocateHeaders(Phdrs, OutputSectionCommands, MinVA);
958fb8978fcSDima Stepanov }
959652852c5SGeorge Rimar 
960464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
961*7ff9329bSRafael Espindola std::vector<PhdrEntry> LinkerScript::createPhdrs(
962*7ff9329bSRafael Espindola     ArrayRef<OutputSectionCommand *> OutputSectionCommands) {
96317cb7c0aSRafael Espindola   std::vector<PhdrEntry> Ret;
964bbe38602SEugene Leviant 
965464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
966464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
967bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
968edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
96917cb7c0aSRafael Espindola     PhdrEntry &Phdr = Ret.back();
970bbe38602SEugene Leviant 
971bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
9729d1bacb1SRui Ueyama       Phdr.add(Out::ElfHeader);
973bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
9749d1bacb1SRui Ueyama       Phdr.add(Out::ProgramHeaders);
97556b21c86SEugene Leviant 
97656b21c86SEugene Leviant     if (Cmd.LMAExpr) {
97772dc195dSRafael Espindola       Phdr.p_paddr = Cmd.LMAExpr().getValue();
97856b21c86SEugene Leviant       Phdr.HasLMA = true;
97956b21c86SEugene Leviant     }
980bbe38602SEugene Leviant   }
981bbe38602SEugene Leviant 
982464daadcSRui Ueyama   // Add output sections to program headers.
983*7ff9329bSRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
984*7ff9329bSRafael Espindola     OutputSection *Sec = Cmd->Sec;
98504a2e348SRafael Espindola     if (!(Sec->Flags & SHF_ALLOC))
986bbe38602SEugene Leviant       break;
987bbe38602SEugene Leviant 
988bbe38602SEugene Leviant     // Assign headers specified by linker script
9892c923c2cSRafael Espindola     for (size_t Id : getPhdrIndices(Sec)) {
990edebbdf1SRui Ueyama       Ret[Id].add(Sec);
991865bf863SEugene Leviant       if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
99217cb7c0aSRafael Espindola         Ret[Id].p_flags |= Sec->getPhdrFlags();
993bbe38602SEugene Leviant     }
994bbe38602SEugene Leviant   }
995edebbdf1SRui Ueyama   return Ret;
996bbe38602SEugene Leviant }
997bbe38602SEugene Leviant 
998b8dd23f5SRui Ueyama bool LinkerScript::ignoreInterpSection() {
999f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
1000f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
1001e31d9886SRui Ueyama   if (Opt.PhdrsCommands.empty())
1002e31d9886SRui Ueyama     return false;
1003e31d9886SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands)
1004e31d9886SRui Ueyama     if (Cmd.Type == PT_INTERP)
1005e31d9886SRui Ueyama       return false;
1006e31d9886SRui Ueyama   return true;
1007f9bc3bd2SEugene Leviant }
1008f9bc3bd2SEugene Leviant 
1009d7dc2258SRafael Espindola OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) const {
1010d7dc2258SRafael Espindola   auto I = SecToCommand.find(Sec);
1011d7dc2258SRafael Espindola   if (I == SecToCommand.end())
1012fa948c72SRafael Espindola     return nullptr;
1013d7dc2258SRafael Espindola   return I->second;
1014fa948c72SRafael Espindola }
1015fa948c72SRafael Espindola 
101655b169bfSRafael Espindola uint32_t OutputSectionCommand::getFiller() {
101755b169bfSRafael Espindola   if (Filler)
101855b169bfSRafael Espindola     return *Filler;
101955b169bfSRafael Espindola   if (Sec->Flags & SHF_EXECINSTR)
102055b169bfSRafael Espindola     return Target->TrapInstr;
102155b169bfSRafael Espindola   return 0;
1022e2ee72b5SGeorge Rimar }
1023e2ee72b5SGeorge Rimar 
1024e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
1025f62d2607SRui Ueyama   if (Size == 1)
1026f62d2607SRui Ueyama     *Buf = Data;
1027f62d2607SRui Ueyama   else if (Size == 2)
1028f93ed4deSRui Ueyama     write16(Buf, Data, Config->Endianness);
1029f62d2607SRui Ueyama   else if (Size == 4)
1030f93ed4deSRui Ueyama     write32(Buf, Data, Config->Endianness);
1031f62d2607SRui Ueyama   else if (Size == 8)
1032f93ed4deSRui Ueyama     write64(Buf, Data, Config->Endianness);
1033f62d2607SRui Ueyama   else
1034e38cbab5SGeorge Rimar     llvm_unreachable("unsupported Size argument");
1035e38cbab5SGeorge Rimar }
1036e38cbab5SGeorge Rimar 
10378c284acfSRafael Espindola static bool compareByFilePosition(InputSection *A, InputSection *B) {
10388c284acfSRafael Espindola   // Synthetic doesn't have link order dependecy, stable_sort will keep it last
10398c284acfSRafael Espindola   if (A->kind() == InputSectionBase::Synthetic ||
10408c284acfSRafael Espindola       B->kind() == InputSectionBase::Synthetic)
10418c284acfSRafael Espindola     return false;
10428c284acfSRafael Espindola   InputSection *LA = A->getLinkOrderDep();
10438c284acfSRafael Espindola   InputSection *LB = B->getLinkOrderDep();
10448c284acfSRafael Espindola   OutputSection *AOut = LA->getParent();
10458c284acfSRafael Espindola   OutputSection *BOut = LB->getParent();
10468c284acfSRafael Espindola   if (AOut != BOut)
10478c284acfSRafael Espindola     return AOut->SectionIndex < BOut->SectionIndex;
10488c284acfSRafael Espindola   return LA->OutSecOff < LB->OutSecOff;
10498c284acfSRafael Espindola }
10508c284acfSRafael Espindola 
1051658a0c74SRafael Espindola template <class ELFT>
1052658a0c74SRafael Espindola static void finalizeShtGroup(OutputSection *OS,
1053658a0c74SRafael Espindola                              ArrayRef<InputSection *> Sections) {
10548c284acfSRafael Espindola   // sh_link field for SHT_GROUP sections should contain the section index of
10558c284acfSRafael Espindola   // the symbol table.
1056658a0c74SRafael Espindola   OS->Link = InX::SymTab->getParent()->SectionIndex;
10578c284acfSRafael Espindola 
10588c284acfSRafael Espindola   // sh_info then contain index of an entry in symbol table section which
10598c284acfSRafael Espindola   // provides signature of the section group.
1060658a0c74SRafael Espindola   elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>();
1061658a0c74SRafael Espindola   assert(Config->Relocatable && Sections.size() == 1);
10628c284acfSRafael Espindola   ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
1063658a0c74SRafael Espindola   OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]);
10648c284acfSRafael Espindola }
10658c284acfSRafael Espindola 
10668c284acfSRafael Espindola template <class ELFT> void OutputSectionCommand::finalize() {
10678c284acfSRafael Espindola   // Link order may be distributed across several InputSectionDescriptions
10688c284acfSRafael Espindola   // but sort must consider them all at once.
10698c284acfSRafael Espindola   std::vector<InputSection **> ScriptSections;
10708c284acfSRafael Espindola   std::vector<InputSection *> Sections;
10718c284acfSRafael Espindola   for (BaseCommand *Base : Commands)
10728c284acfSRafael Espindola     if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
10738c284acfSRafael Espindola       for (InputSection *&IS : ISD->Sections) {
10748c284acfSRafael Espindola         ScriptSections.push_back(&IS);
10758c284acfSRafael Espindola         Sections.push_back(IS);
10768c284acfSRafael Espindola       }
1077658a0c74SRafael Espindola 
1078658a0c74SRafael Espindola   if ((Sec->Flags & SHF_LINK_ORDER)) {
10798c284acfSRafael Espindola     std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
10808c284acfSRafael Espindola     for (int I = 0, N = Sections.size(); I < N; ++I)
10818c284acfSRafael Espindola       *ScriptSections[I] = Sections[I];
10828c284acfSRafael Espindola 
10838c284acfSRafael Espindola     // We must preserve the link order dependency of sections with the
10848c284acfSRafael Espindola     // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
10858c284acfSRafael Espindola     // need to translate the InputSection sh_link to the OutputSection sh_link,
10868c284acfSRafael Espindola     // all InputSections in the OutputSection have the same dependency.
1087658a0c74SRafael Espindola     if (auto *D = Sections.front()->getLinkOrderDep())
10888c284acfSRafael Espindola       Sec->Link = D->getParent()->SectionIndex;
10898c284acfSRafael Espindola   }
10908c284acfSRafael Espindola 
10918c284acfSRafael Espindola   uint32_t Type = Sec->Type;
10928c284acfSRafael Espindola   if (Type == SHT_GROUP) {
1093658a0c74SRafael Espindola     finalizeShtGroup<ELFT>(Sec, Sections);
10948c284acfSRafael Espindola     return;
10958c284acfSRafael Espindola   }
10968c284acfSRafael Espindola 
10978c284acfSRafael Espindola   if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
10988c284acfSRafael Espindola     return;
10998c284acfSRafael Espindola 
1100658a0c74SRafael Espindola   InputSection *First = Sections[0];
11018c284acfSRafael Espindola   if (isa<SyntheticSection>(First))
11028c284acfSRafael Espindola     return;
11038c284acfSRafael Espindola 
11048c284acfSRafael Espindola   Sec->Link = InX::SymTab->getParent()->SectionIndex;
11058c284acfSRafael Espindola   // sh_info for SHT_REL[A] sections should contain the section header index of
11068c284acfSRafael Espindola   // the section to which the relocation applies.
11078c284acfSRafael Espindola   InputSectionBase *S = First->getRelocatedSection();
11088c284acfSRafael Espindola   Sec->Info = S->getOutputSection()->SectionIndex;
11098c284acfSRafael Espindola   Sec->Flags |= SHF_INFO_LINK;
11108c284acfSRafael Espindola }
11118c284acfSRafael Espindola 
111268880728SRafael Espindola // Compress section contents if this section contains debug info.
111368880728SRafael Espindola template <class ELFT> void OutputSectionCommand::maybeCompress() {
111468880728SRafael Espindola   typedef typename ELFT::Chdr Elf_Chdr;
111568880728SRafael Espindola 
111668880728SRafael Espindola   // Compress only DWARF debug sections.
111768880728SRafael Espindola   if (!Config->CompressDebugSections || (Sec->Flags & SHF_ALLOC) ||
111868880728SRafael Espindola       !Name.startswith(".debug_"))
111968880728SRafael Espindola     return;
112068880728SRafael Espindola 
112168880728SRafael Espindola   // Create a section header.
112268880728SRafael Espindola   Sec->ZDebugHeader.resize(sizeof(Elf_Chdr));
112368880728SRafael Espindola   auto *Hdr = reinterpret_cast<Elf_Chdr *>(Sec->ZDebugHeader.data());
112468880728SRafael Espindola   Hdr->ch_type = ELFCOMPRESS_ZLIB;
112568880728SRafael Espindola   Hdr->ch_size = Sec->Size;
112668880728SRafael Espindola   Hdr->ch_addralign = Sec->Alignment;
112768880728SRafael Espindola 
112868880728SRafael Espindola   // Write section contents to a temporary buffer and compress it.
112968880728SRafael Espindola   std::vector<uint8_t> Buf(Sec->Size);
113068880728SRafael Espindola   writeTo<ELFT>(Buf.data());
113168880728SRafael Espindola   if (Error E = zlib::compress(toStringRef(Buf), Sec->CompressedData))
113268880728SRafael Espindola     fatal("compress failed: " + llvm::toString(std::move(E)));
113368880728SRafael Espindola 
113468880728SRafael Espindola   // Update section headers.
113568880728SRafael Espindola   Sec->Size = sizeof(Elf_Chdr) + Sec->CompressedData.size();
113668880728SRafael Espindola   Sec->Flags |= SHF_COMPRESSED;
113768880728SRafael Espindola }
113868880728SRafael Espindola 
113955b169bfSRafael Espindola template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
11401124001cSGeorge Rimar   if (Sec->Type == SHT_NOBITS)
11411124001cSGeorge Rimar     return;
11421124001cSGeorge Rimar 
114355b169bfSRafael Espindola   Sec->Loc = Buf;
114455b169bfSRafael Espindola 
114555b169bfSRafael Espindola   // We may have already rendered compressed content when using
114655b169bfSRafael Espindola   // -compress-debug-sections option. Write it together with header.
114755b169bfSRafael Espindola   if (!Sec->CompressedData.empty()) {
114855b169bfSRafael Espindola     memcpy(Buf, Sec->ZDebugHeader.data(), Sec->ZDebugHeader.size());
114955b169bfSRafael Espindola     memcpy(Buf + Sec->ZDebugHeader.size(), Sec->CompressedData.data(),
115055b169bfSRafael Espindola            Sec->CompressedData.size());
115155b169bfSRafael Espindola     return;
115255b169bfSRafael Espindola   }
115355b169bfSRafael Espindola 
115455b169bfSRafael Espindola   // Write leading padding.
1155969c6512SRafael Espindola   std::vector<InputSection *> Sections;
1156969c6512SRafael Espindola   for (BaseCommand *Cmd : Commands)
1157969c6512SRafael Espindola     if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
1158969c6512SRafael Espindola       for (InputSection *IS : ISD->Sections)
1159969c6512SRafael Espindola         if (IS->Live)
1160969c6512SRafael Espindola           Sections.push_back(IS);
116155b169bfSRafael Espindola   uint32_t Filler = getFiller();
116255b169bfSRafael Espindola   if (Filler)
116355b169bfSRafael Espindola     fill(Buf, Sections.empty() ? Sec->Size : Sections[0]->OutSecOff, Filler);
116455b169bfSRafael Espindola 
116555b169bfSRafael Espindola   parallelForEachN(0, Sections.size(), [=](size_t I) {
116655b169bfSRafael Espindola     InputSection *IS = Sections[I];
116755b169bfSRafael Espindola     IS->writeTo<ELFT>(Buf);
116855b169bfSRafael Espindola 
116955b169bfSRafael Espindola     // Fill gaps between sections.
117055b169bfSRafael Espindola     if (Filler) {
117155b169bfSRafael Espindola       uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
117255b169bfSRafael Espindola       uint8_t *End;
117355b169bfSRafael Espindola       if (I + 1 == Sections.size())
117455b169bfSRafael Espindola         End = Buf + Sec->Size;
117555b169bfSRafael Espindola       else
117655b169bfSRafael Espindola         End = Buf + Sections[I + 1]->OutSecOff;
117755b169bfSRafael Espindola       fill(Start, End - Start, Filler);
117855b169bfSRafael Espindola     }
117955b169bfSRafael Espindola   });
118055b169bfSRafael Espindola 
118155b169bfSRafael Espindola   // Linker scripts may have BYTE()-family commands with which you
118255b169bfSRafael Espindola   // can write arbitrary bytes to the output. Process them if any.
118355b169bfSRafael Espindola   for (BaseCommand *Base : Commands)
11848f99f73cSRui Ueyama     if (auto *Data = dyn_cast<BytesDataCommand>(Base))
1185a8dba487SGeorge Rimar       writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
1186e38cbab5SGeorge Rimar }
1187e38cbab5SGeorge Rimar 
1188dc1ed120SRafael Espindola bool LinkerScript::hasLMA(OutputSection *Sec) {
1189fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec))
1190fa948c72SRafael Espindola     if (Cmd->LMAExpr)
1191b71d6f7aSEugene Leviant       return true;
1192b71d6f7aSEugene Leviant   return false;
11938ceadb38SGeorge Rimar }
11948ceadb38SGeorge Rimar 
1195b8dd23f5SRui Ueyama ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
11964595df94SRafael Espindola   if (S == ".")
119741c7ab4aSGeorge Rimar     return {CurOutSec, Dot - CurOutSec->Addr, Loc};
1198a8dba487SGeorge Rimar   if (SymbolBody *B = findSymbol(S)) {
119972dc195dSRafael Espindola     if (auto *D = dyn_cast<DefinedRegular>(B))
120041c7ab4aSGeorge Rimar       return {D->Section, D->Value, Loc};
120130f16b23SPetr Hosek     if (auto *C = dyn_cast<DefinedCommon>(B))
120241c7ab4aSGeorge Rimar       return {InX::Common, C->Offset, Loc};
120372dc195dSRafael Espindola   }
1204f6aeed36SEugene Leviant   error(Loc + ": symbol not found: " + S);
1205884e786dSGeorge Rimar   return 0;
1206884e786dSGeorge Rimar }
1207884e786dSGeorge Rimar 
1208b8dd23f5SRui Ueyama bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
1209f34f45fdSGeorge Rimar 
12102c923c2cSRafael Espindola // Returns indices of ELF headers containing specific section. Each index is a
12112c923c2cSRafael Espindola // zero based number of ELF header listed within PHDRS {} script block.
12122c923c2cSRafael Espindola std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) {
1213fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec)) {
121429c5a2a9SRui Ueyama     std::vector<size_t> Ret;
121529c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
12162a942c4bSEugene Leviant       Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
121729c5a2a9SRui Ueyama     return Ret;
1218bbe38602SEugene Leviant   }
121931d842f5SGeorge Rimar   return {};
122031d842f5SGeorge Rimar }
1221bbe38602SEugene Leviant 
1222b8dd23f5SRui Ueyama size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
122329c5a2a9SRui Ueyama   size_t I = 0;
122429c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
122529c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
122629c5a2a9SRui Ueyama       return I;
122729c5a2a9SRui Ueyama     ++I;
122829c5a2a9SRui Ueyama   }
12292a942c4bSEugene Leviant   error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
123029c5a2a9SRui Ueyama   return 0;
123129c5a2a9SRui Ueyama }
123255b169bfSRafael Espindola 
123355b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);
123455b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32BE>(uint8_t *Buf);
123555b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64LE>(uint8_t *Buf);
123655b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64BE>(uint8_t *Buf);
123768880728SRafael Espindola 
123868880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32LE>();
123968880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32BE>();
124068880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64LE>();
124168880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64BE>();
12428c284acfSRafael Espindola 
12438c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF32LE>();
12448c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF32BE>();
12458c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF64LE>();
12468c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF64BE>();
1247