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;
434*fbb0463fSGeorge Rimar         if (Cmd->Noload)
435*fbb0463fSGeorge 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
44702ed7575SRafael Espindola   uint64_t StartAddr = Config->ImageBase + elf::getHeaderSize();
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 
455cbfe9e94SPeter Smith   Commands.push_back(
456cbfe9e94SPeter Smith       make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
457cbfe9e94SPeter Smith 
458cbfe9e94SPeter Smith   // For each OutputSection that needs a VA fabricate an OutputSectionCommand
459cbfe9e94SPeter Smith   // with an InputSectionDescription describing the InputSections
460cbfe9e94SPeter Smith   for (OutputSection *Sec : *OutputSections) {
46105c4f67cSRafael Espindola     auto *OSCmd = createOutputSectionCommand(Sec->Name, "<internal>");
462c60b4510SPeter Smith     OSCmd->Sec = Sec;
463d7dc2258SRafael Espindola     SecToCommand[Sec] = OSCmd;
464c60b4510SPeter Smith 
465c60b4510SPeter Smith     // Prefer user supplied address over additional alignment constraint
466cbfe9e94SPeter Smith     auto I = Config->SectionStartMap.find(Sec->Name);
467cbfe9e94SPeter Smith     if (I != Config->SectionStartMap.end())
468bb7bd3eeSRafael Espindola       OSCmd->AddrExpr = [=] { return I->second; };
469c60b4510SPeter Smith 
470cbfe9e94SPeter Smith     Commands.push_back(OSCmd);
471cbfe9e94SPeter Smith     if (Sec->Sections.size()) {
472cbfe9e94SPeter Smith       auto *ISD = make<InputSectionDescription>("");
473cbfe9e94SPeter Smith       OSCmd->Commands.push_back(ISD);
474cbfe9e94SPeter Smith       for (InputSection *ISec : Sec->Sections) {
475cbfe9e94SPeter Smith         ISD->Sections.push_back(ISec);
476cbfe9e94SPeter Smith         ISec->Assigned = true;
477cbfe9e94SPeter Smith       }
478cbfe9e94SPeter Smith     }
479cbfe9e94SPeter Smith   }
480cbfe9e94SPeter Smith   // SECTIONS commands run before other non SECTIONS commands
481cbfe9e94SPeter Smith   Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end());
482cbfe9e94SPeter Smith   Opt.Commands = std::move(Commands);
483cbfe9e94SPeter Smith }
484cbfe9e94SPeter Smith 
4850b1b695aSRui Ueyama // Add sections that didn't match any sections command.
486b8dd23f5SRui Ueyama void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
4874f013bb3SRafael Espindola   for (InputSectionBase *S : InputSections) {
488db5e56f7SRafael Espindola     if (!S->Live || S->Parent)
4894f013bb3SRafael Espindola       continue;
4904f013bb3SRafael Espindola     StringRef Name = getOutputSectionName(S->Name);
4914f013bb3SRafael Espindola     auto I = std::find_if(
4924f013bb3SRafael Espindola         Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
4934f013bb3SRafael Espindola           if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
4944f013bb3SRafael Espindola             return Cmd->Name == Name;
4954f013bb3SRafael Espindola           return false;
4964f013bb3SRafael Espindola         });
497de8d9897SRafael Espindola     if (I == Opt.Commands.end()) {
4984f013bb3SRafael Espindola       Factory.addInputSec(S, Name);
499de8d9897SRafael Espindola     } else {
500de8d9897SRafael Espindola       auto *Cmd = cast<OutputSectionCommand>(*I);
501de8d9897SRafael Espindola       Factory.addInputSec(S, Name, Cmd->Sec);
502660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
503d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
504660c9ab9SRafael Espindola         unsigned Index = std::distance(Opt.Commands.begin(), I);
505660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index);
506660c9ab9SRafael Espindola         Sec->SectionIndex = Index;
507660c9ab9SRafael Espindola       }
508de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
5096a1aa8d9SRafael Espindola       ISD->Sections.push_back(cast<InputSection>(S));
510de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
511de8d9897SRafael Espindola     }
5124f013bb3SRafael Espindola   }
513e63d81bdSEugene Leviant }
514e63d81bdSEugene Leviant 
5157c4eafa3SRafael Espindola uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
5167c4eafa3SRafael Espindola   bool IsTbss = (CurOutSec->Flags & SHF_TLS) && CurOutSec->Type == SHT_NOBITS;
5177c4eafa3SRafael Espindola   uint64_t Start = IsTbss ? Dot + ThreadBssOffset : Dot;
5187c4eafa3SRafael Espindola   Start = alignTo(Start, Align);
5197c4eafa3SRafael Espindola   uint64_t End = Start + Size;
5207c4eafa3SRafael Espindola 
5217c4eafa3SRafael Espindola   if (IsTbss)
5227c4eafa3SRafael Espindola     ThreadBssOffset = End - Dot;
5237c4eafa3SRafael Espindola   else
5247c4eafa3SRafael Espindola     Dot = End;
5257c4eafa3SRafael Espindola   return End;
526a940e539SRafael Espindola }
527a940e539SRafael Espindola 
528b8dd23f5SRui Ueyama void LinkerScript::output(InputSection *S) {
5297c4eafa3SRafael Espindola   uint64_t Pos = advance(S->getSize(), S->Alignment);
5307c4eafa3SRafael Espindola   S->OutSecOff = Pos - S->getSize() - CurOutSec->Addr;
531d3190795SRafael Espindola 
532d3190795SRafael Espindola   // Update output section size after adding each section. This is so that
533d3190795SRafael Espindola   // SIZEOF works correctly in the case below:
534d3190795SRafael Espindola   // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
53504a2e348SRafael Espindola   CurOutSec->Size = Pos - CurOutSec->Addr;
536d3190795SRafael Espindola 
537b889744eSMeador Inge   // If there is a memory region associated with this input section, then
538b889744eSMeador Inge   // place the section in that region and update the region index.
539b889744eSMeador Inge   if (CurMemRegion) {
540b889744eSMeador Inge     CurMemRegion->Offset += CurOutSec->Size;
541b889744eSMeador Inge     uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin;
542b889744eSMeador Inge     if (CurSize > CurMemRegion->Length) {
543b889744eSMeador Inge       uint64_t OverflowAmt = CurSize - CurMemRegion->Length;
544b889744eSMeador Inge       error("section '" + CurOutSec->Name + "' will not fit in region '" +
545b889744eSMeador Inge             CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
546b889744eSMeador Inge             " bytes");
547b889744eSMeador Inge     }
548b889744eSMeador Inge   }
5492de509c3SRui Ueyama }
550ceabe80eSEugene Leviant 
551b8dd23f5SRui Ueyama void LinkerScript::switchTo(OutputSection *Sec) {
552d3190795SRafael Espindola   if (CurOutSec == Sec)
553d3190795SRafael Espindola     return;
554d3190795SRafael Espindola 
555d3190795SRafael Espindola   CurOutSec = Sec;
5567c4eafa3SRafael Espindola   CurOutSec->Addr = advance(0, CurOutSec->Alignment);
557b71d6f7aSEugene Leviant 
558b71d6f7aSEugene Leviant   // If neither AT nor AT> is specified for an allocatable section, the linker
559b71d6f7aSEugene Leviant   // will set the LMA such that the difference between VMA and LMA for the
560b71d6f7aSEugene Leviant   // section is the same as the preceding output section in the same region
561b71d6f7aSEugene Leviant   // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
56221467876SGeorge Rimar   if (LMAOffset)
56329c1afb8SRafael Espindola     CurOutSec->LMAOffset = LMAOffset();
564d3190795SRafael Espindola }
565d3190795SRafael Espindola 
566b8dd23f5SRui Ueyama void LinkerScript::process(BaseCommand &Base) {
5672e081a4fSRui Ueyama   // This handles the assignments to symbol or to the dot.
5682e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<SymbolAssignment>(&Base)) {
5692e081a4fSRui Ueyama     assignSymbol(Cmd, true);
570d3190795SRafael Espindola     return;
57197403d15SEugene Leviant   }
572e38cbab5SGeorge Rimar 
573e38cbab5SGeorge Rimar   // Handle BYTE(), SHORT(), LONG(), or QUAD().
5742e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) {
5752e081a4fSRui Ueyama     Cmd->Offset = Dot - CurOutSec->Addr;
5762e081a4fSRui Ueyama     Dot += Cmd->Size;
57704a2e348SRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
578e38cbab5SGeorge Rimar     return;
579e38cbab5SGeorge Rimar   }
580e38cbab5SGeorge Rimar 
5812e081a4fSRui Ueyama   // Handle ASSERT().
5822e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<AssertCommand>(&Base)) {
5832e081a4fSRui Ueyama     Cmd->Expression();
584b2d99d6aSMeador Inge     return;
585b2d99d6aSMeador Inge   }
586b2d99d6aSMeador Inge 
5872e081a4fSRui Ueyama   // Handle a single input section description command.
5882e081a4fSRui Ueyama   // It calculates and assigns the offsets for each section and also
589e38cbab5SGeorge Rimar   // updates the output section size.
5902e081a4fSRui Ueyama   auto &Cmd = cast<InputSectionDescription>(Base);
591a85e8ddaSRafael Espindola   for (InputSection *Sec : Cmd.Sections) {
5923fb5a6dcSGeorge Rimar     // We tentatively added all synthetic sections at the beginning and removed
5933fb5a6dcSGeorge Rimar     // empty ones afterwards (because there is no way to know whether they were
5943fb5a6dcSGeorge Rimar     // going be empty or not other than actually running linker scripts.)
5953fb5a6dcSGeorge Rimar     // We need to ignore remains of empty sections.
5962e081a4fSRui Ueyama     if (auto *S = dyn_cast<SyntheticSection>(Sec))
5972e081a4fSRui Ueyama       if (S->empty())
5983fb5a6dcSGeorge Rimar         continue;
5993fb5a6dcSGeorge Rimar 
6002e081a4fSRui Ueyama     if (!Sec->Live)
60178ef645fSGeorge Rimar       continue;
602db5e56f7SRafael Espindola     assert(CurOutSec == Sec->getParent());
603a85e8ddaSRafael Espindola     output(Sec);
604ceabe80eSEugene Leviant   }
605ceabe80eSEugene Leviant }
606ceabe80eSEugene Leviant 
607b889744eSMeador Inge // This function searches for a memory region to place the given output
608b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is
609b889744eSMeador Inge // returned. Otherwise, a nullptr is returned.
6101902b337SRafael Espindola MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd) {
611b889744eSMeador Inge   // If a memory region name was specified in the output section command,
612b889744eSMeador Inge   // then try to find that region first.
613b889744eSMeador Inge   if (!Cmd->MemoryRegionName.empty()) {
614b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
615b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
616b889744eSMeador Inge       return &It->second;
617b889744eSMeador Inge     error("memory region '" + Cmd->MemoryRegionName + "' not declared");
618b889744eSMeador Inge     return nullptr;
619b889744eSMeador Inge   }
620b889744eSMeador Inge 
621d7c5400fSRui Ueyama   // If at least one memory region is defined, all sections must
622d7c5400fSRui Ueyama   // belong to some memory region. Otherwise, we don't need to do
623d7c5400fSRui Ueyama   // anything for memory regions.
624cc400cc8SRui Ueyama   if (Opt.MemoryRegions.empty())
625b889744eSMeador Inge     return nullptr;
626b889744eSMeador Inge 
6271902b337SRafael Espindola   OutputSection *Sec = Cmd->Sec;
628b889744eSMeador Inge   // See if a region can be found by matching section flags.
6292e081a4fSRui Ueyama   for (auto &Pair : Opt.MemoryRegions) {
6302e081a4fSRui Ueyama     MemoryRegion &M = Pair.second;
6312e081a4fSRui Ueyama     if ((M.Flags & Sec->Flags) && (M.NegFlags & Sec->Flags) == 0)
6322e081a4fSRui Ueyama       return &M;
633b889744eSMeador Inge   }
634b889744eSMeador Inge 
635b889744eSMeador Inge   // Otherwise, no suitable region was found.
636b889744eSMeador Inge   if (Sec->Flags & SHF_ALLOC)
637b889744eSMeador Inge     error("no memory region specified for section '" + Sec->Name + "'");
638b889744eSMeador Inge   return nullptr;
639b889744eSMeador Inge }
640b889744eSMeador Inge 
6410b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section
6420b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }").
643b8dd23f5SRui Ueyama void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) {
6449b980095SRafael Espindola   OutputSection *Sec = Cmd->Sec;
6452b074553SRafael Espindola   if (!Sec)
646d3190795SRafael Espindola     return;
647b889744eSMeador Inge 
648cba41013SRui Ueyama   if (Cmd->AddrExpr && (Sec->Flags & SHF_ALLOC))
649d379f735SRui Ueyama     setDot(Cmd->AddrExpr, Cmd->Location, false);
650679828ffSRafael Espindola 
6515784e96fSEugene Leviant   if (Cmd->LMAExpr) {
6520c1c8085SGeorge Rimar     uint64_t D = Dot;
65372dc195dSRafael Espindola     LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; };
6545784e96fSEugene Leviant   }
6555784e96fSEugene Leviant 
656feed7506SRafael Espindola   CurMemRegion = Cmd->MemRegion;
657b889744eSMeador Inge   if (CurMemRegion)
658b889744eSMeador Inge     Dot = CurMemRegion->Offset;
659b889744eSMeador Inge   switchTo(Sec);
6600b1b695aSRui Ueyama 
661d86a4e50SGeorge Rimar   // We do not support custom layout for compressed debug sectons.
662d86a4e50SGeorge Rimar   // At this point we already know their size and have compressed content.
663d86a4e50SGeorge Rimar   if (CurOutSec->Flags & SHF_COMPRESSED)
664d86a4e50SGeorge Rimar     return;
665d86a4e50SGeorge Rimar 
666de8d9897SRafael Espindola   for (BaseCommand *C : Cmd->Commands)
667de8d9897SRafael Espindola     process(*C);
668d3190795SRafael Espindola }
669d3190795SRafael Espindola 
670b8dd23f5SRui Ueyama void LinkerScript::removeEmptyCommands() {
6716d38e4dbSRafael Espindola   // It is common practice to use very generic linker scripts. So for any
6726d38e4dbSRafael Espindola   // given run some of the output sections in the script will be empty.
6736d38e4dbSRafael Espindola   // We could create corresponding empty output sections, but that would
6746d38e4dbSRafael Espindola   // clutter the output.
6756d38e4dbSRafael Espindola   // We instead remove trivially empty sections. The bfd linker seems even
6766d38e4dbSRafael Espindola   // more aggressive at removing them.
6776d38e4dbSRafael Espindola   auto Pos = std::remove_if(
6788f99f73cSRui Ueyama       Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
6798f99f73cSRui Ueyama         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
6804f013bb3SRafael Espindola           return std::find(OutputSections->begin(), OutputSections->end(),
6814f013bb3SRafael Espindola                            Cmd->Sec) == OutputSections->end();
6820b1b695aSRui Ueyama         return false;
6836d38e4dbSRafael Espindola       });
6846d38e4dbSRafael Espindola   Opt.Commands.erase(Pos, Opt.Commands.end());
68507fe6129SRafael Espindola }
68607fe6129SRafael Espindola 
6876a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
6888f99f73cSRui Ueyama   for (BaseCommand *Base : Cmd.Commands)
6898f99f73cSRui Ueyama     if (!isa<InputSectionDescription>(*Base))
6906a53737cSRafael Espindola       return false;
6916a53737cSRafael Espindola   return true;
6926a53737cSRafael Espindola }
6936d38e4dbSRafael Espindola 
694b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsBeforeSorting() {
6959546fffbSRafael Espindola   // If the output section contains only symbol assignments, create a
6969546fffbSRafael Espindola   // corresponding output section. The bfd linker seems to only create them if
6979546fffbSRafael Espindola   // '.' is assigned to, but creating these section should not have any bad
6989546fffbSRafael Espindola   // consequeces and gives us a section to put the symbol in.
6990c1c8085SGeorge Rimar   uint64_t Flags = SHF_ALLOC;
700660c9ab9SRafael Espindola 
701660c9ab9SRafael Espindola   for (int I = 0, E = Opt.Commands.size(); I != E; ++I) {
702660c9ab9SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
7039546fffbSRafael Espindola     if (!Cmd)
7049546fffbSRafael Espindola       continue;
7054f013bb3SRafael Espindola     if (OutputSection *Sec = Cmd->Sec) {
7062b074553SRafael Espindola       Flags = Sec->Flags;
7079546fffbSRafael Espindola       continue;
7089546fffbSRafael Espindola     }
7099546fffbSRafael Espindola 
7106a53737cSRafael Espindola     if (isAllSectionDescription(*Cmd))
7116a53737cSRafael Espindola       continue;
7126a53737cSRafael Espindola 
713fd0c844fSDmitry Mikulin     auto *OutSec = make<OutputSection>(Cmd->Name, SHT_PROGBITS, Flags);
714660c9ab9SRafael Espindola     OutSec->SectionIndex = I;
7159546fffbSRafael Espindola     OutputSections->push_back(OutSec);
7169b980095SRafael Espindola     Cmd->Sec = OutSec;
717d7dc2258SRafael Espindola     SecToCommand[OutSec] = Cmd;
7189546fffbSRafael Espindola   }
719f7a17448SRafael Espindola }
720f7a17448SRafael Espindola 
721b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsAfterSorting() {
722f7a17448SRafael Espindola   placeOrphanSections();
723f7a17448SRafael Espindola 
724feed7506SRafael Espindola   // Try and find an appropriate memory region to assign offsets in.
725d1960dc0SRafael Espindola   for (BaseCommand *Base : Opt.Commands) {
726d1960dc0SRafael Espindola     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) {
727feed7506SRafael Espindola       Cmd->MemRegion = findMemoryRegion(Cmd);
728d1960dc0SRafael Espindola       // Handle align (e.g. ".foo : ALIGN(16) { ... }").
729d1960dc0SRafael Espindola       if (Cmd->AlignExpr)
730d1960dc0SRafael Espindola 	Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue());
731d1960dc0SRafael Espindola     }
732d1960dc0SRafael Espindola   }
733feed7506SRafael Espindola 
734f7a17448SRafael Espindola   // If output section command doesn't specify any segments,
735f7a17448SRafael Espindola   // and we haven't previously assigned any section to segment,
736f7a17448SRafael Espindola   // then we simply assign section to the very first load segment.
737f7a17448SRafael Espindola   // Below is an example of such linker script:
738f7a17448SRafael Espindola   // PHDRS { seg PT_LOAD; }
739f7a17448SRafael Espindola   // SECTIONS { .aaa : { *(.aaa) } }
740f7a17448SRafael Espindola   std::vector<StringRef> DefPhdrs;
741f7a17448SRafael Espindola   auto FirstPtLoad =
742f7a17448SRafael Espindola       std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(),
743f7a17448SRafael Espindola                    [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; });
744f7a17448SRafael Espindola   if (FirstPtLoad != Opt.PhdrsCommands.end())
745f7a17448SRafael Espindola     DefPhdrs.push_back(FirstPtLoad->Name);
746f7a17448SRafael Espindola 
747f7a17448SRafael Espindola   // Walk the commands and propagate the program headers to commands that don't
748f7a17448SRafael Espindola   // explicitly specify them.
7498f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
7508f99f73cSRui Ueyama     auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
751f7a17448SRafael Espindola     if (!Cmd)
752f7a17448SRafael Espindola       continue;
7538f99f73cSRui Ueyama 
754f7a17448SRafael Espindola     if (Cmd->Phdrs.empty())
755f7a17448SRafael Espindola       Cmd->Phdrs = DefPhdrs;
756f7a17448SRafael Espindola     else
757f7a17448SRafael Espindola       DefPhdrs = Cmd->Phdrs;
758f7a17448SRafael Espindola   }
7596a53737cSRafael Espindola 
7606a53737cSRafael Espindola   removeEmptyCommands();
7619546fffbSRafael Espindola }
7629546fffbSRafael Espindola 
76315c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments
76415c57951SRafael Espindola // so that an orphan after
76515c57951SRafael Espindola //   begin_foo = .;
76615c57951SRafael Espindola //   foo : { *(foo) }
76715c57951SRafael Espindola //   end_foo = .;
76815c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols.
76915c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the
77015c57951SRafael Espindola // one in charge of deciding the order of the sections.
77115c57951SRafael Espindola // We don't want to go over alignments, since doing so in
77215c57951SRafael Espindola //  rx_sec : { *(rx_sec) }
77315c57951SRafael Espindola //  . = ALIGN(0x1000);
77415c57951SRafael Espindola //  /* The RW PT_LOAD starts here*/
77515c57951SRafael Espindola //  rw_sec : { *(rw_sec) }
77615c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned.
7774e1e88e3SRui Ueyama static bool shouldSkip(BaseCommand *Cmd) {
77815c57951SRafael Espindola   if (isa<OutputSectionCommand>(Cmd))
77915c57951SRafael Espindola     return false;
7804e1e88e3SRui Ueyama   if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd))
7815fcc99c2SRafael Espindola     return Assign->Name != ".";
7824e1e88e3SRui Ueyama   return true;
78315c57951SRafael Espindola }
78415c57951SRafael Espindola 
7856697ec29SRui Ueyama // Orphan sections are sections present in the input files which are
7866697ec29SRui Ueyama // not explicitly placed into the output file by the linker script.
7876697ec29SRui Ueyama //
7886697ec29SRui Ueyama // When the control reaches this function, Opt.Commands contains
7896697ec29SRui Ueyama // output section commands for non-orphan sections only. This function
79081cb7107SRui Ueyama // adds new elements for orphan sections so that all sections are
79181cb7107SRui Ueyama // explicitly handled by Opt.Commands.
7926697ec29SRui Ueyama //
7936697ec29SRui Ueyama // Writer<ELFT>::sortSections has already sorted output sections.
7946697ec29SRui Ueyama // What we need to do is to scan OutputSections vector and
7956697ec29SRui Ueyama // Opt.Commands in parallel to find orphan sections. If there is an
7966697ec29SRui Ueyama // output section that doesn't have a corresponding entry in
7976697ec29SRui Ueyama // Opt.Commands, we will insert a new entry to Opt.Commands.
7986697ec29SRui Ueyama //
7996697ec29SRui Ueyama // There is some ambiguity as to where exactly a new entry should be
8006697ec29SRui Ueyama // inserted, because Opt.Commands contains not only output section
80181cb7107SRui Ueyama // commands but also other types of commands such as symbol assignment
8026697ec29SRui Ueyama // expressions. There's no correct answer here due to the lack of the
8036697ec29SRui Ueyama // formal specification of the linker script. We use heuristics to
8046697ec29SRui Ueyama // determine whether a new output command should be added before or
8056697ec29SRui Ueyama // after another commands. For the details, look at shouldSkip
8066697ec29SRui Ueyama // function.
807b8dd23f5SRui Ueyama void LinkerScript::placeOrphanSections() {
808aab6d5c5SRafael Espindola   // The OutputSections are already in the correct order.
809aab6d5c5SRafael Espindola   // This loops creates or moves commands as needed so that they are in the
810aab6d5c5SRafael Espindola   // correct order.
811aab6d5c5SRafael Espindola   int CmdIndex = 0;
8125fcc99c2SRafael Espindola 
8135fcc99c2SRafael Espindola   // As a horrible special case, skip the first . assignment if it is before any
8145fcc99c2SRafael Espindola   // section. We do this because it is common to set a load address by starting
8155fcc99c2SRafael Espindola   // the script with ". = 0xabcd" and the expectation is that every section is
8165fcc99c2SRafael Espindola   // after that.
8174e1e88e3SRui Ueyama   auto FirstSectionOrDotAssignment =
8184e1e88e3SRui Ueyama       std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
8194e1e88e3SRui Ueyama                    [](BaseCommand *Cmd) { return !shouldSkip(Cmd); });
8205fcc99c2SRafael Espindola   if (FirstSectionOrDotAssignment != Opt.Commands.end()) {
8215fcc99c2SRafael Espindola     CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin();
8225fcc99c2SRafael Espindola     if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
8235fcc99c2SRafael Espindola       ++CmdIndex;
8245fcc99c2SRafael Espindola   }
8255fcc99c2SRafael Espindola 
82624e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
82740849419SRafael Espindola     StringRef Name = Sec->Name;
828aab6d5c5SRafael Espindola 
829aab6d5c5SRafael Espindola     // Find the last spot where we can insert a command and still get the
83015c57951SRafael Espindola     // correct result.
831aab6d5c5SRafael Espindola     auto CmdIter = Opt.Commands.begin() + CmdIndex;
832aab6d5c5SRafael Espindola     auto E = Opt.Commands.end();
8334e1e88e3SRui Ueyama     while (CmdIter != E && shouldSkip(*CmdIter)) {
834aab6d5c5SRafael Espindola       ++CmdIter;
835aab6d5c5SRafael Espindola       ++CmdIndex;
836aab6d5c5SRafael Espindola     }
837aab6d5c5SRafael Espindola 
838de8d9897SRafael Espindola     // If there is no command corresponding to this output section,
839de8d9897SRafael Espindola     // create one and put a InputSectionDescription in it so that both
840de8d9897SRafael Espindola     // representations agree on which input sections to use.
841fa948c72SRafael Espindola     OutputSectionCommand *Cmd = getCmd(Sec);
842fa948c72SRafael Espindola     if (!Cmd) {
84305c4f67cSRafael Espindola       Cmd = createOutputSectionCommand(Name, "<internal>");
8449b980095SRafael Espindola       Opt.Commands.insert(CmdIter, Cmd);
845aab6d5c5SRafael Espindola       ++CmdIndex;
846de8d9897SRafael Espindola 
847de8d9897SRafael Espindola       Cmd->Sec = Sec;
848d7dc2258SRafael Espindola       SecToCommand[Sec] = Cmd;
849de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
850de8d9897SRafael Espindola       for (InputSection *IS : Sec->Sections)
851de8d9897SRafael Espindola         ISD->Sections.push_back(IS);
852de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
853de8d9897SRafael Espindola 
85415c57951SRafael Espindola       continue;
85515c57951SRafael Espindola     }
85615c57951SRafael Espindola 
85715c57951SRafael Espindola     // Continue from where we found it.
858fa948c72SRafael Espindola     while (*CmdIter != Cmd) {
859fa948c72SRafael Espindola       ++CmdIter;
860fa948c72SRafael Espindola       ++CmdIndex;
861fa948c72SRafael Espindola     }
862fa948c72SRafael Espindola     ++CmdIndex;
863652852c5SGeorge Rimar   }
864337f903cSRafael Espindola }
865337f903cSRafael Espindola 
866b8dd23f5SRui Ueyama void LinkerScript::processNonSectionCommands() {
8678f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
8688f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
869d379f735SRui Ueyama       assignSymbol(Cmd, false);
8708f99f73cSRui Ueyama     else if (auto *Cmd = dyn_cast<AssertCommand>(Base))
87102ad516bSPetr Hosek       Cmd->Expression();
87202ad516bSPetr Hosek   }
87302ad516bSPetr Hosek }
87402ad516bSPetr Hosek 
875faf25a72SRafael Espindola static bool
876faf25a72SRafael Espindola allocateHeaders(std::vector<PhdrEntry> &Phdrs,
877faf25a72SRafael Espindola                 ArrayRef<OutputSectionCommand *> OutputSectionCommands,
87802ed7575SRafael Espindola                 uint64_t Min) {
87902ed7575SRafael Espindola   auto FirstPTLoad =
88002ed7575SRafael Espindola       std::find_if(Phdrs.begin(), Phdrs.end(),
88102ed7575SRafael Espindola                    [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
88202ed7575SRafael Espindola   if (FirstPTLoad == Phdrs.end())
88302ed7575SRafael Espindola     return false;
88402ed7575SRafael Espindola 
88502ed7575SRafael Espindola   uint64_t HeaderSize = getHeaderSize();
88602ed7575SRafael Espindola   if (HeaderSize <= Min || Script->hasPhdrsCommands()) {
88702ed7575SRafael Espindola     Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
88802ed7575SRafael Espindola     Out::ElfHeader->Addr = Min;
88902ed7575SRafael Espindola     Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
89002ed7575SRafael Espindola     return true;
89102ed7575SRafael Espindola   }
89202ed7575SRafael Espindola 
89302ed7575SRafael Espindola   assert(FirstPTLoad->First == Out::ElfHeader);
89402ed7575SRafael Espindola   OutputSection *ActualFirst = nullptr;
895faf25a72SRafael Espindola   for (OutputSectionCommand *Cmd : OutputSectionCommands) {
896faf25a72SRafael Espindola     OutputSection *Sec = Cmd->Sec;
89702ed7575SRafael Espindola     if (Sec->FirstInPtLoad == Out::ElfHeader) {
89802ed7575SRafael Espindola       ActualFirst = Sec;
89902ed7575SRafael Espindola       break;
90002ed7575SRafael Espindola     }
90102ed7575SRafael Espindola   }
90202ed7575SRafael Espindola   if (ActualFirst) {
903faf25a72SRafael Espindola     for (OutputSectionCommand *Cmd : OutputSectionCommands) {
904faf25a72SRafael Espindola       OutputSection *Sec = Cmd->Sec;
90502ed7575SRafael Espindola       if (Sec->FirstInPtLoad == Out::ElfHeader)
90602ed7575SRafael Espindola         Sec->FirstInPtLoad = ActualFirst;
907faf25a72SRafael Espindola     }
90802ed7575SRafael Espindola     FirstPTLoad->First = ActualFirst;
90902ed7575SRafael Espindola   } else {
91002ed7575SRafael Espindola     Phdrs.erase(FirstPTLoad);
91102ed7575SRafael Espindola   }
91202ed7575SRafael Espindola 
91302ed7575SRafael Espindola   auto PhdrI = std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry &E) {
91402ed7575SRafael Espindola     return E.p_type == PT_PHDR;
91502ed7575SRafael Espindola   });
91602ed7575SRafael Espindola   if (PhdrI != Phdrs.end())
91702ed7575SRafael Espindola     Phdrs.erase(PhdrI);
91802ed7575SRafael Espindola   return false;
91902ed7575SRafael Espindola }
92002ed7575SRafael Espindola 
921faf25a72SRafael Espindola void LinkerScript::assignAddresses(
922faf25a72SRafael Espindola     std::vector<PhdrEntry> &Phdrs,
923faf25a72SRafael Espindola     ArrayRef<OutputSectionCommand *> OutputSectionCommands) {
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     else
950ea590d91SRafael Espindola       Sec->Addr = 0;
951ea590d91SRafael Espindola   }
952aab6d5c5SRafael Espindola 
953faf25a72SRafael Espindola   allocateHeaders(Phdrs, OutputSectionCommands, MinVA);
954fb8978fcSDima Stepanov }
955652852c5SGeorge Rimar 
956464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
957b8dd23f5SRui Ueyama std::vector<PhdrEntry> LinkerScript::createPhdrs() {
95817cb7c0aSRafael Espindola   std::vector<PhdrEntry> Ret;
959bbe38602SEugene Leviant 
960464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
961464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
962bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
963edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
96417cb7c0aSRafael Espindola     PhdrEntry &Phdr = Ret.back();
965bbe38602SEugene Leviant 
966bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
9679d1bacb1SRui Ueyama       Phdr.add(Out::ElfHeader);
968bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
9699d1bacb1SRui Ueyama       Phdr.add(Out::ProgramHeaders);
97056b21c86SEugene Leviant 
97156b21c86SEugene Leviant     if (Cmd.LMAExpr) {
97272dc195dSRafael Espindola       Phdr.p_paddr = Cmd.LMAExpr().getValue();
97356b21c86SEugene Leviant       Phdr.HasLMA = true;
97456b21c86SEugene Leviant     }
975bbe38602SEugene Leviant   }
976bbe38602SEugene Leviant 
977464daadcSRui Ueyama   // Add output sections to program headers.
97824e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
97904a2e348SRafael Espindola     if (!(Sec->Flags & SHF_ALLOC))
980bbe38602SEugene Leviant       break;
981bbe38602SEugene Leviant 
982bbe38602SEugene Leviant     // Assign headers specified by linker script
9832c923c2cSRafael Espindola     for (size_t Id : getPhdrIndices(Sec)) {
984edebbdf1SRui Ueyama       Ret[Id].add(Sec);
985865bf863SEugene Leviant       if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
98617cb7c0aSRafael Espindola         Ret[Id].p_flags |= Sec->getPhdrFlags();
987bbe38602SEugene Leviant     }
988bbe38602SEugene Leviant   }
989edebbdf1SRui Ueyama   return Ret;
990bbe38602SEugene Leviant }
991bbe38602SEugene Leviant 
992b8dd23f5SRui Ueyama bool LinkerScript::ignoreInterpSection() {
993f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
994f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
995e31d9886SRui Ueyama   if (Opt.PhdrsCommands.empty())
996e31d9886SRui Ueyama     return false;
997e31d9886SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands)
998e31d9886SRui Ueyama     if (Cmd.Type == PT_INTERP)
999e31d9886SRui Ueyama       return false;
1000e31d9886SRui Ueyama   return true;
1001f9bc3bd2SEugene Leviant }
1002f9bc3bd2SEugene Leviant 
1003d7dc2258SRafael Espindola OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) const {
1004d7dc2258SRafael Espindola   auto I = SecToCommand.find(Sec);
1005d7dc2258SRafael Espindola   if (I == SecToCommand.end())
1006fa948c72SRafael Espindola     return nullptr;
1007d7dc2258SRafael Espindola   return I->second;
1008fa948c72SRafael Espindola }
1009fa948c72SRafael Espindola 
101055b169bfSRafael Espindola uint32_t OutputSectionCommand::getFiller() {
101155b169bfSRafael Espindola   if (Filler)
101255b169bfSRafael Espindola     return *Filler;
101355b169bfSRafael Espindola   if (Sec->Flags & SHF_EXECINSTR)
101455b169bfSRafael Espindola     return Target->TrapInstr;
101555b169bfSRafael Espindola   return 0;
1016e2ee72b5SGeorge Rimar }
1017e2ee72b5SGeorge Rimar 
1018e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
1019f62d2607SRui Ueyama   if (Size == 1)
1020f62d2607SRui Ueyama     *Buf = Data;
1021f62d2607SRui Ueyama   else if (Size == 2)
1022f93ed4deSRui Ueyama     write16(Buf, Data, Config->Endianness);
1023f62d2607SRui Ueyama   else if (Size == 4)
1024f93ed4deSRui Ueyama     write32(Buf, Data, Config->Endianness);
1025f62d2607SRui Ueyama   else if (Size == 8)
1026f93ed4deSRui Ueyama     write64(Buf, Data, Config->Endianness);
1027f62d2607SRui Ueyama   else
1028e38cbab5SGeorge Rimar     llvm_unreachable("unsupported Size argument");
1029e38cbab5SGeorge Rimar }
1030e38cbab5SGeorge Rimar 
10318c284acfSRafael Espindola static bool compareByFilePosition(InputSection *A, InputSection *B) {
10328c284acfSRafael Espindola   // Synthetic doesn't have link order dependecy, stable_sort will keep it last
10338c284acfSRafael Espindola   if (A->kind() == InputSectionBase::Synthetic ||
10348c284acfSRafael Espindola       B->kind() == InputSectionBase::Synthetic)
10358c284acfSRafael Espindola     return false;
10368c284acfSRafael Espindola   InputSection *LA = A->getLinkOrderDep();
10378c284acfSRafael Espindola   InputSection *LB = B->getLinkOrderDep();
10388c284acfSRafael Espindola   OutputSection *AOut = LA->getParent();
10398c284acfSRafael Espindola   OutputSection *BOut = LB->getParent();
10408c284acfSRafael Espindola   if (AOut != BOut)
10418c284acfSRafael Espindola     return AOut->SectionIndex < BOut->SectionIndex;
10428c284acfSRafael Espindola   return LA->OutSecOff < LB->OutSecOff;
10438c284acfSRafael Espindola }
10448c284acfSRafael Espindola 
1045658a0c74SRafael Espindola template <class ELFT>
1046658a0c74SRafael Espindola static void finalizeShtGroup(OutputSection *OS,
1047658a0c74SRafael Espindola                              ArrayRef<InputSection *> Sections) {
10488c284acfSRafael Espindola   // sh_link field for SHT_GROUP sections should contain the section index of
10498c284acfSRafael Espindola   // the symbol table.
1050658a0c74SRafael Espindola   OS->Link = InX::SymTab->getParent()->SectionIndex;
10518c284acfSRafael Espindola 
10528c284acfSRafael Espindola   // sh_info then contain index of an entry in symbol table section which
10538c284acfSRafael Espindola   // provides signature of the section group.
1054658a0c74SRafael Espindola   elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>();
1055658a0c74SRafael Espindola   assert(Config->Relocatable && Sections.size() == 1);
10568c284acfSRafael Espindola   ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
1057658a0c74SRafael Espindola   OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]);
10588c284acfSRafael Espindola }
10598c284acfSRafael Espindola 
10608c284acfSRafael Espindola template <class ELFT> void OutputSectionCommand::finalize() {
10618c284acfSRafael Espindola   // Link order may be distributed across several InputSectionDescriptions
10628c284acfSRafael Espindola   // but sort must consider them all at once.
10638c284acfSRafael Espindola   std::vector<InputSection **> ScriptSections;
10648c284acfSRafael Espindola   std::vector<InputSection *> Sections;
10658c284acfSRafael Espindola   for (BaseCommand *Base : Commands)
10668c284acfSRafael Espindola     if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
10678c284acfSRafael Espindola       for (InputSection *&IS : ISD->Sections) {
10688c284acfSRafael Espindola         ScriptSections.push_back(&IS);
10698c284acfSRafael Espindola         Sections.push_back(IS);
10708c284acfSRafael Espindola       }
1071658a0c74SRafael Espindola 
1072658a0c74SRafael Espindola   if ((Sec->Flags & SHF_LINK_ORDER)) {
10738c284acfSRafael Espindola     std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
10748c284acfSRafael Espindola     for (int I = 0, N = Sections.size(); I < N; ++I)
10758c284acfSRafael Espindola       *ScriptSections[I] = Sections[I];
10768c284acfSRafael Espindola 
10778c284acfSRafael Espindola     // We must preserve the link order dependency of sections with the
10788c284acfSRafael Espindola     // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
10798c284acfSRafael Espindola     // need to translate the InputSection sh_link to the OutputSection sh_link,
10808c284acfSRafael Espindola     // all InputSections in the OutputSection have the same dependency.
1081658a0c74SRafael Espindola     if (auto *D = Sections.front()->getLinkOrderDep())
10828c284acfSRafael Espindola       Sec->Link = D->getParent()->SectionIndex;
10838c284acfSRafael Espindola   }
10848c284acfSRafael Espindola 
10858c284acfSRafael Espindola   uint32_t Type = Sec->Type;
10868c284acfSRafael Espindola   if (Type == SHT_GROUP) {
1087658a0c74SRafael Espindola     finalizeShtGroup<ELFT>(Sec, Sections);
10888c284acfSRafael Espindola     return;
10898c284acfSRafael Espindola   }
10908c284acfSRafael Espindola 
10918c284acfSRafael Espindola   if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
10928c284acfSRafael Espindola     return;
10938c284acfSRafael Espindola 
1094658a0c74SRafael Espindola   InputSection *First = Sections[0];
10958c284acfSRafael Espindola   if (isa<SyntheticSection>(First))
10968c284acfSRafael Espindola     return;
10978c284acfSRafael Espindola 
10988c284acfSRafael Espindola   Sec->Link = InX::SymTab->getParent()->SectionIndex;
10998c284acfSRafael Espindola   // sh_info for SHT_REL[A] sections should contain the section header index of
11008c284acfSRafael Espindola   // the section to which the relocation applies.
11018c284acfSRafael Espindola   InputSectionBase *S = First->getRelocatedSection();
11028c284acfSRafael Espindola   Sec->Info = S->getOutputSection()->SectionIndex;
11038c284acfSRafael Espindola   Sec->Flags |= SHF_INFO_LINK;
11048c284acfSRafael Espindola }
11058c284acfSRafael Espindola 
110668880728SRafael Espindola // Compress section contents if this section contains debug info.
110768880728SRafael Espindola template <class ELFT> void OutputSectionCommand::maybeCompress() {
110868880728SRafael Espindola   typedef typename ELFT::Chdr Elf_Chdr;
110968880728SRafael Espindola 
111068880728SRafael Espindola   // Compress only DWARF debug sections.
111168880728SRafael Espindola   if (!Config->CompressDebugSections || (Sec->Flags & SHF_ALLOC) ||
111268880728SRafael Espindola       !Name.startswith(".debug_"))
111368880728SRafael Espindola     return;
111468880728SRafael Espindola 
111568880728SRafael Espindola   // Create a section header.
111668880728SRafael Espindola   Sec->ZDebugHeader.resize(sizeof(Elf_Chdr));
111768880728SRafael Espindola   auto *Hdr = reinterpret_cast<Elf_Chdr *>(Sec->ZDebugHeader.data());
111868880728SRafael Espindola   Hdr->ch_type = ELFCOMPRESS_ZLIB;
111968880728SRafael Espindola   Hdr->ch_size = Sec->Size;
112068880728SRafael Espindola   Hdr->ch_addralign = Sec->Alignment;
112168880728SRafael Espindola 
112268880728SRafael Espindola   // Write section contents to a temporary buffer and compress it.
112368880728SRafael Espindola   std::vector<uint8_t> Buf(Sec->Size);
112468880728SRafael Espindola   writeTo<ELFT>(Buf.data());
112568880728SRafael Espindola   if (Error E = zlib::compress(toStringRef(Buf), Sec->CompressedData))
112668880728SRafael Espindola     fatal("compress failed: " + llvm::toString(std::move(E)));
112768880728SRafael Espindola 
112868880728SRafael Espindola   // Update section headers.
112968880728SRafael Espindola   Sec->Size = sizeof(Elf_Chdr) + Sec->CompressedData.size();
113068880728SRafael Espindola   Sec->Flags |= SHF_COMPRESSED;
113168880728SRafael Espindola }
113268880728SRafael Espindola 
113355b169bfSRafael Espindola template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
11341124001cSGeorge Rimar   if (Sec->Type == SHT_NOBITS)
11351124001cSGeorge Rimar     return;
11361124001cSGeorge Rimar 
113755b169bfSRafael Espindola   Sec->Loc = Buf;
113855b169bfSRafael Espindola 
113955b169bfSRafael Espindola   // We may have already rendered compressed content when using
114055b169bfSRafael Espindola   // -compress-debug-sections option. Write it together with header.
114155b169bfSRafael Espindola   if (!Sec->CompressedData.empty()) {
114255b169bfSRafael Espindola     memcpy(Buf, Sec->ZDebugHeader.data(), Sec->ZDebugHeader.size());
114355b169bfSRafael Espindola     memcpy(Buf + Sec->ZDebugHeader.size(), Sec->CompressedData.data(),
114455b169bfSRafael Espindola            Sec->CompressedData.size());
114555b169bfSRafael Espindola     return;
114655b169bfSRafael Espindola   }
114755b169bfSRafael Espindola 
114855b169bfSRafael Espindola   // Write leading padding.
1149969c6512SRafael Espindola   std::vector<InputSection *> Sections;
1150969c6512SRafael Espindola   for (BaseCommand *Cmd : Commands)
1151969c6512SRafael Espindola     if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
1152969c6512SRafael Espindola       for (InputSection *IS : ISD->Sections)
1153969c6512SRafael Espindola         if (IS->Live)
1154969c6512SRafael Espindola           Sections.push_back(IS);
115555b169bfSRafael Espindola   uint32_t Filler = getFiller();
115655b169bfSRafael Espindola   if (Filler)
115755b169bfSRafael Espindola     fill(Buf, Sections.empty() ? Sec->Size : Sections[0]->OutSecOff, Filler);
115855b169bfSRafael Espindola 
115955b169bfSRafael Espindola   parallelForEachN(0, Sections.size(), [=](size_t I) {
116055b169bfSRafael Espindola     InputSection *IS = Sections[I];
116155b169bfSRafael Espindola     IS->writeTo<ELFT>(Buf);
116255b169bfSRafael Espindola 
116355b169bfSRafael Espindola     // Fill gaps between sections.
116455b169bfSRafael Espindola     if (Filler) {
116555b169bfSRafael Espindola       uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
116655b169bfSRafael Espindola       uint8_t *End;
116755b169bfSRafael Espindola       if (I + 1 == Sections.size())
116855b169bfSRafael Espindola         End = Buf + Sec->Size;
116955b169bfSRafael Espindola       else
117055b169bfSRafael Espindola         End = Buf + Sections[I + 1]->OutSecOff;
117155b169bfSRafael Espindola       fill(Start, End - Start, Filler);
117255b169bfSRafael Espindola     }
117355b169bfSRafael Espindola   });
117455b169bfSRafael Espindola 
117555b169bfSRafael Espindola   // Linker scripts may have BYTE()-family commands with which you
117655b169bfSRafael Espindola   // can write arbitrary bytes to the output. Process them if any.
117755b169bfSRafael Espindola   for (BaseCommand *Base : Commands)
11788f99f73cSRui Ueyama     if (auto *Data = dyn_cast<BytesDataCommand>(Base))
1179a8dba487SGeorge Rimar       writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
1180e38cbab5SGeorge Rimar }
1181e38cbab5SGeorge Rimar 
1182dc1ed120SRafael Espindola bool LinkerScript::hasLMA(OutputSection *Sec) {
1183fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec))
1184fa948c72SRafael Espindola     if (Cmd->LMAExpr)
1185b71d6f7aSEugene Leviant       return true;
1186b71d6f7aSEugene Leviant   return false;
11878ceadb38SGeorge Rimar }
11888ceadb38SGeorge Rimar 
1189b8dd23f5SRui Ueyama ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
11904595df94SRafael Espindola   if (S == ".")
119141c7ab4aSGeorge Rimar     return {CurOutSec, Dot - CurOutSec->Addr, Loc};
1192a8dba487SGeorge Rimar   if (SymbolBody *B = findSymbol(S)) {
119372dc195dSRafael Espindola     if (auto *D = dyn_cast<DefinedRegular>(B))
119441c7ab4aSGeorge Rimar       return {D->Section, D->Value, Loc};
119530f16b23SPetr Hosek     if (auto *C = dyn_cast<DefinedCommon>(B))
119641c7ab4aSGeorge Rimar       return {InX::Common, C->Offset, Loc};
119772dc195dSRafael Espindola   }
1198f6aeed36SEugene Leviant   error(Loc + ": symbol not found: " + S);
1199884e786dSGeorge Rimar   return 0;
1200884e786dSGeorge Rimar }
1201884e786dSGeorge Rimar 
1202b8dd23f5SRui Ueyama bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
1203f34f45fdSGeorge Rimar 
12042c923c2cSRafael Espindola // Returns indices of ELF headers containing specific section. Each index is a
12052c923c2cSRafael Espindola // zero based number of ELF header listed within PHDRS {} script block.
12062c923c2cSRafael Espindola std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) {
1207fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec)) {
120829c5a2a9SRui Ueyama     std::vector<size_t> Ret;
120929c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
12102a942c4bSEugene Leviant       Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
121129c5a2a9SRui Ueyama     return Ret;
1212bbe38602SEugene Leviant   }
121331d842f5SGeorge Rimar   return {};
121431d842f5SGeorge Rimar }
1215bbe38602SEugene Leviant 
1216b8dd23f5SRui Ueyama size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
121729c5a2a9SRui Ueyama   size_t I = 0;
121829c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
121929c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
122029c5a2a9SRui Ueyama       return I;
122129c5a2a9SRui Ueyama     ++I;
122229c5a2a9SRui Ueyama   }
12232a942c4bSEugene Leviant   error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
122429c5a2a9SRui Ueyama   return 0;
122529c5a2a9SRui Ueyama }
122655b169bfSRafael Espindola 
122755b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);
122855b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF32BE>(uint8_t *Buf);
122955b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64LE>(uint8_t *Buf);
123055b169bfSRafael Espindola template void OutputSectionCommand::writeTo<ELF64BE>(uint8_t *Buf);
123168880728SRafael Espindola 
123268880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32LE>();
123368880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF32BE>();
123468880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64LE>();
123568880728SRafael Espindola template void OutputSectionCommand::maybeCompress<ELF64BE>();
12368c284acfSRafael Espindola 
12378c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF32LE>();
12388c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF32BE>();
12398c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF64LE>();
12408c284acfSRafael Espindola template void OutputSectionCommand::finalize<ELF64BE>();
1241