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"
16f7c5fbb1SRui Ueyama #include "Driver.h"
171ebc8ed7SRui Ueyama #include "InputSection.h"
189381eb10SRui Ueyama #include "Memory.h"
19652852c5SGeorge Rimar #include "OutputSections.h"
20794366a2SRui Ueyama #include "ScriptLexer.h"
2193c9af42SRui Ueyama #include "Strings.h"
22f7c5fbb1SRui Ueyama #include "SymbolTable.h"
2355518e7dSRui Ueyama #include "Symbols.h"
243fb5a6dcSGeorge Rimar #include "SyntheticSections.h"
25467c4d55SEugene Leviant #include "Target.h"
26bbe38602SEugene Leviant #include "Writer.h"
2722886a28SEugene Zelenko #include "llvm/ADT/STLExtras.h"
288c6a5aafSRui Ueyama #include "llvm/ADT/SmallString.h"
2922886a28SEugene Zelenko #include "llvm/ADT/StringRef.h"
30960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h"
3122886a28SEugene Zelenko #include "llvm/Support/Casting.h"
32652852c5SGeorge Rimar #include "llvm/Support/ELF.h"
3322886a28SEugene Zelenko #include "llvm/Support/Endian.h"
3422886a28SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
35f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h"
3622886a28SEugene Zelenko #include "llvm/Support/MathExtras.h"
37f03f3cc1SRui Ueyama #include "llvm/Support/Path.h"
3822886a28SEugene Zelenko #include <algorithm>
3922886a28SEugene Zelenko #include <cassert>
4022886a28SEugene Zelenko #include <cstddef>
4122886a28SEugene Zelenko #include <cstdint>
4222886a28SEugene Zelenko #include <iterator>
4322886a28SEugene Zelenko #include <limits>
4422886a28SEugene Zelenko #include <memory>
4522886a28SEugene Zelenko #include <string>
4622886a28SEugene Zelenko #include <tuple>
4722886a28SEugene Zelenko #include <vector>
48f7c5fbb1SRui Ueyama 
49f7c5fbb1SRui Ueyama using namespace llvm;
50652852c5SGeorge Rimar using namespace llvm::ELF;
511ebc8ed7SRui Ueyama using namespace llvm::object;
52e38cbab5SGeorge Rimar using namespace llvm::support::endian;
53f7c5fbb1SRui Ueyama using namespace lld;
54e0df00b9SRafael Espindola using namespace lld::elf;
55f7c5fbb1SRui Ueyama 
56884e786dSGeorge Rimar LinkerScriptBase *elf::ScriptBase;
5707320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig;
58717677afSRui Ueyama 
598f1f3c40SMeador Inge template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
605e51f7d2SPetr Hosek   Symbol *Sym;
613dabfc6bSRafael Espindola   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
625e51f7d2SPetr Hosek   std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
635e51f7d2SPetr Hosek       Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
645e51f7d2SPetr Hosek       /*File*/ nullptr);
655e51f7d2SPetr Hosek   Sym->Binding = STB_GLOBAL;
6680474a26SRui Ueyama   replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility,
6780474a26SRui Ueyama                               STT_NOTYPE, 0, 0, nullptr, nullptr);
688f1f3c40SMeador Inge   return Sym->body();
69ceabe80eSEugene Leviant }
70ceabe80eSEugene Leviant 
718f1f3c40SMeador Inge template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment *Cmd) {
725e51f7d2SPetr Hosek   Symbol *Sym;
738f1f3c40SMeador Inge   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
7424e6f363SRafael Espindola   const OutputSection *Sec =
75afaa9343SEugene Leviant       ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section();
765e51f7d2SPetr Hosek   std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
775e51f7d2SPetr Hosek       Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
785e51f7d2SPetr Hosek       /*File*/ nullptr);
795e51f7d2SPetr Hosek   Sym->Binding = STB_GLOBAL;
808f1f3c40SMeador Inge   replaceBody<DefinedSynthetic>(Sym, Cmd->Name, 0, Sec);
818f1f3c40SMeador Inge   return Sym->body();
82ceabe80eSEugene Leviant }
83ceabe80eSEugene Leviant 
8422375f24SRui Ueyama static bool isUnderSysroot(StringRef Path) {
8522375f24SRui Ueyama   if (Config->Sysroot == "")
8622375f24SRui Ueyama     return false;
8722375f24SRui Ueyama   for (; !Path.empty(); Path = sys::path::parent_path(Path))
8822375f24SRui Ueyama     if (sys::fs::equivalent(Config->Sysroot, Path))
8922375f24SRui Ueyama       return true;
9022375f24SRui Ueyama   return false;
9122375f24SRui Ueyama }
9222375f24SRui Ueyama 
932ee2d2dcSGeorge Rimar template <class ELFT>
942ee2d2dcSGeorge Rimar void LinkerScript<ELFT>::setDot(Expr E, const Twine &Loc, bool InSec) {
95679828ffSRafael Espindola   uintX_t Val = E(Dot);
964cd7352cSRafael Espindola   if (Val < Dot) {
974cd7352cSRafael Espindola     if (InSec)
982ee2d2dcSGeorge Rimar       error(Loc + ": unable to move location counter backward for: " +
992ee2d2dcSGeorge Rimar             CurOutSec->Name);
1004cd7352cSRafael Espindola     else
1012ee2d2dcSGeorge Rimar       error(Loc + ": unable to move location counter backward");
1024cd7352cSRafael Espindola   }
1034cd7352cSRafael Espindola   Dot = Val;
1044cd7352cSRafael Espindola   // Update to location counter means update to section size.
1054cd7352cSRafael Espindola   if (InSec)
1064cd7352cSRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
107679828ffSRafael Espindola }
108679828ffSRafael Espindola 
109679828ffSRafael Espindola // Sets value of a symbol. Two kinds of symbols are processed: synthetic
110679828ffSRafael Espindola // symbols, whose value is an offset from beginning of section and regular
111679828ffSRafael Espindola // symbols whose value is absolute.
112679828ffSRafael Espindola template <class ELFT>
113679828ffSRafael Espindola void LinkerScript<ELFT>::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
114679828ffSRafael Espindola   if (Cmd->Name == ".") {
1152ee2d2dcSGeorge Rimar     setDot(Cmd->Expression, Cmd->Location, InSec);
1164cd7352cSRafael Espindola     return;
1174cd7352cSRafael Espindola   }
1184cd7352cSRafael Espindola 
119b2b70975SGeorge Rimar   if (!Cmd->Sym)
1208f1f3c40SMeador Inge     return;
1218f1f3c40SMeador Inge 
122b2b70975SGeorge Rimar   if (auto *Body = dyn_cast<DefinedSynthetic>(Cmd->Sym)) {
123b2b70975SGeorge Rimar     Body->Section = Cmd->Expression.Section();
124ea590d91SRafael Espindola     if (Body->Section) {
125ea590d91SRafael Espindola       uint64_t VA = 0;
126ea590d91SRafael Espindola       if (Body->Section->Flags & SHF_ALLOC)
127ea590d91SRafael Espindola         VA = Body->Section->Addr;
128ea590d91SRafael Espindola       Body->Value = Cmd->Expression(Dot) - VA;
129ea590d91SRafael Espindola     }
130b2b70975SGeorge Rimar     return;
131db741e72SEugene Leviant   }
132b2b70975SGeorge Rimar 
13380474a26SRui Ueyama   cast<DefinedRegular>(Cmd->Sym)->Value = Cmd->Expression(Dot);
1348f1f3c40SMeador Inge }
1358f1f3c40SMeador Inge 
1364cd7352cSRafael Espindola template <class ELFT>
1374cd7352cSRafael Espindola void LinkerScript<ELFT>::addSymbol(SymbolAssignment *Cmd) {
1381602421cSRui Ueyama   if (Cmd->Name == ".")
1398f1f3c40SMeador Inge     return;
1408f1f3c40SMeador Inge 
1418f1f3c40SMeador Inge   // If a symbol was in PROVIDE(), we need to define it only when
1428f1f3c40SMeador Inge   // it is a referenced undefined symbol.
1431602421cSRui Ueyama   SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name);
1448f1f3c40SMeador Inge   if (Cmd->Provide && (!B || B->isDefined()))
1458f1f3c40SMeador Inge     return;
1468f1f3c40SMeador Inge 
1478f1f3c40SMeador Inge   // Otherwise, create a new symbol if one does not exist or an
1488f1f3c40SMeador Inge   // undefined one does exist.
1498f1f3c40SMeador Inge   if (Cmd->Expression.IsAbsolute())
1508f1f3c40SMeador Inge     Cmd->Sym = addRegular<ELFT>(Cmd);
1518f1f3c40SMeador Inge   else
1528f1f3c40SMeador Inge     Cmd->Sym = addSynthetic<ELFT>(Cmd);
153b2b70975SGeorge Rimar 
154b2b70975SGeorge Rimar   // If there are sections, then let the value be assigned later in
155b2b70975SGeorge Rimar   // `assignAddresses`.
156b2b70975SGeorge Rimar   if (!ScriptConfig->HasSections)
1574cd7352cSRafael Espindola     assignSymbol(Cmd);
158ceabe80eSEugene Leviant }
159ceabe80eSEugene Leviant 
160076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
161076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
162076fe157SGeorge Rimar }
163076fe157SGeorge Rimar 
164076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
165076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
166076fe157SGeorge Rimar }
167076fe157SGeorge Rimar 
168eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
169eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
170eea3114fSGeorge Rimar }
171eea3114fSGeorge Rimar 
172eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) {
173eefa758eSGeorge Rimar   return C->Kind == AssertKind;
174eefa758eSGeorge Rimar }
175eefa758eSGeorge Rimar 
176e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) {
177e38cbab5SGeorge Rimar   return C->Kind == BytesDataKind;
178e38cbab5SGeorge Rimar }
179e38cbab5SGeorge Rimar 
18022886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::LinkerScript() = default;
18122886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::~LinkerScript() = default;
182f34d0e08SRui Ueyama 
183b4c9b81aSRafael Espindola static StringRef basename(InputSectionBase *S) {
184b4c9b81aSRafael Espindola   if (S->File)
185b4c9b81aSRafael Espindola     return sys::path::filename(S->File->getName());
186e0be2901SRui Ueyama   return "";
187e0be2901SRui Ueyama }
188e0be2901SRui Ueyama 
189b4c9b81aSRafael Espindola template <class ELFT> bool LinkerScript<ELFT>::shouldKeep(InputSectionBase *S) {
190e0be2901SRui Ueyama   for (InputSectionDescription *ID : Opt.KeptSections)
191e0be2901SRui Ueyama     if (ID->FilePat.match(basename(S)))
192cf43f179SEugene Leviant       for (SectionPattern &P : ID->SectionPatterns)
193f91282e1SRui Ueyama         if (P.SectionPat.match(S->Name))
194eea3114fSGeorge Rimar           return true;
195eea3114fSGeorge Rimar   return false;
196eea3114fSGeorge Rimar }
197eea3114fSGeorge Rimar 
198c404d50dSRafael Espindola static bool comparePriority(InputSectionBase *A, InputSectionBase *B) {
199575208caSGeorge Rimar   return getPriority(A->Name) < getPriority(B->Name);
200575208caSGeorge Rimar }
201575208caSGeorge Rimar 
202c404d50dSRafael Espindola static bool compareName(InputSectionBase *A, InputSectionBase *B) {
203042a3f20SRafael Espindola   return A->Name < B->Name;
2040702c4e8SGeorge Rimar }
205742c3836SRui Ueyama 
206c404d50dSRafael Espindola static bool compareAlignment(InputSectionBase *A, InputSectionBase *B) {
207742c3836SRui Ueyama   // ">" is not a mistake. Larger alignments are placed before smaller
208742c3836SRui Ueyama   // alignments in order to reduce the amount of padding necessary.
209742c3836SRui Ueyama   // This is compatible with GNU.
210742c3836SRui Ueyama   return A->Alignment > B->Alignment;
211742c3836SRui Ueyama }
212742c3836SRui Ueyama 
213c404d50dSRafael Espindola static std::function<bool(InputSectionBase *, InputSectionBase *)>
214be394db3SGeorge Rimar getComparator(SortSectionPolicy K) {
215be394db3SGeorge Rimar   switch (K) {
216be394db3SGeorge Rimar   case SortSectionPolicy::Alignment:
217c0028d3dSRafael Espindola     return compareAlignment;
218be394db3SGeorge Rimar   case SortSectionPolicy::Name:
219be394db3SGeorge Rimar     return compareName;
220be394db3SGeorge Rimar   case SortSectionPolicy::Priority:
221be394db3SGeorge Rimar     return comparePriority;
222be394db3SGeorge Rimar   default:
223be394db3SGeorge Rimar     llvm_unreachable("unknown sort policy");
224be394db3SGeorge Rimar   }
225742c3836SRui Ueyama }
2260702c4e8SGeorge Rimar 
22748c3f1ceSRui Ueyama template <class ELFT>
228b4c9b81aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase *> Sections,
22906ae6836SGeorge Rimar                              ConstraintKind Kind) {
2308f66df92SGeorge Rimar   if (Kind == ConstraintKind::NoConstraint)
2318f66df92SGeorge Rimar     return true;
232c404d50dSRafael Espindola   bool IsRW = llvm::any_of(Sections, [=](InputSectionBase *Sec2) {
233b4c9b81aSRafael Espindola     auto *Sec = static_cast<InputSectionBase *>(Sec2);
2341854a8ebSRafael Espindola     return Sec->Flags & SHF_WRITE;
23506ae6836SGeorge Rimar   });
236e746e52cSRafael Espindola   return (IsRW && Kind == ConstraintKind::ReadWrite) ||
237e746e52cSRafael Espindola          (!IsRW && Kind == ConstraintKind::ReadOnly);
23806ae6836SGeorge Rimar }
23906ae6836SGeorge Rimar 
240c404d50dSRafael Espindola static void sortSections(InputSectionBase **Begin, InputSectionBase **End,
241ee924709SRui Ueyama                          SortSectionPolicy K) {
242ee924709SRui Ueyama   if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
24307171f21SGeorge Rimar     std::stable_sort(Begin, End, getComparator(K));
244ee924709SRui Ueyama }
245ee924709SRui Ueyama 
246d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches.
247be94e1b6SRafael Espindola template <class ELFT>
248e71a3f8aSRafael Espindola void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) {
2494dc07becSRui Ueyama   // Collects all sections that satisfy constraints of I
2504dc07becSRui Ueyama   // and attach them to I.
2514dc07becSRui Ueyama   for (SectionPattern &Pat : I->SectionPatterns) {
25207171f21SGeorge Rimar     size_t SizeBefore = I->Sections.size();
2538c6a5aafSRui Ueyama 
254536a2670SRui Ueyama     for (InputSectionBase *S : InputSections) {
2553773bcacSRafael Espindola       if (S->Assigned)
2568c6a5aafSRui Ueyama         continue;
257908a3d34SRafael Espindola       // For -emit-relocs we have to ignore entries like
258908a3d34SRafael Espindola       //   .rela.dyn : { *(.rela.data) }
259908a3d34SRafael Espindola       // which are common because they are in the default bfd script.
260908a3d34SRafael Espindola       if (S->Type == SHT_REL || S->Type == SHT_RELA)
261908a3d34SRafael Espindola         continue;
2628c6a5aafSRui Ueyama 
263e0be2901SRui Ueyama       StringRef Filename = basename(S);
264e0be2901SRui Ueyama       if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename))
265e0be2901SRui Ueyama         continue;
266e0be2901SRui Ueyama       if (!Pat.SectionPat.match(S->Name))
267e0be2901SRui Ueyama         continue;
268d3190795SRafael Espindola       I->Sections.push_back(S);
269f94efdddSRui Ueyama       S->Assigned = true;
270f94efdddSRui Ueyama     }
271d3190795SRafael Espindola 
272ee924709SRui Ueyama     // Sort sections as instructed by SORT-family commands and --sort-section
273ee924709SRui Ueyama     // option. Because SORT-family commands can be nested at most two depth
274ee924709SRui Ueyama     // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
275ee924709SRui Ueyama     // line option is respected even if a SORT command is given, the exact
276ee924709SRui Ueyama     // behavior we have here is a bit complicated. Here are the rules.
277ee924709SRui Ueyama     //
278ee924709SRui Ueyama     // 1. If two SORT commands are given, --sort-section is ignored.
279ee924709SRui Ueyama     // 2. If one SORT command is given, and if it is not SORT_NONE,
280ee924709SRui Ueyama     //    --sort-section is handled as an inner SORT command.
281ee924709SRui Ueyama     // 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
282ee924709SRui Ueyama     // 4. If no SORT command is given, sort according to --sort-section.
283c404d50dSRafael Espindola     InputSectionBase **Begin = I->Sections.data() + SizeBefore;
284c404d50dSRafael Espindola     InputSectionBase **End = I->Sections.data() + I->Sections.size();
28507171f21SGeorge Rimar     if (Pat.SortOuter != SortSectionPolicy::None) {
28607171f21SGeorge Rimar       if (Pat.SortInner == SortSectionPolicy::Default)
28707171f21SGeorge Rimar         sortSections(Begin, End, Config->SortSection);
288ee924709SRui Ueyama       else
28907171f21SGeorge Rimar         sortSections(Begin, End, Pat.SortInner);
29007171f21SGeorge Rimar       sortSections(Begin, End, Pat.SortOuter);
29107171f21SGeorge Rimar     }
292ee924709SRui Ueyama   }
293be94e1b6SRafael Espindola }
294be94e1b6SRafael Espindola 
295be94e1b6SRafael Espindola template <class ELFT>
296b4c9b81aSRafael Espindola void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase *> V) {
297b4c9b81aSRafael Espindola   for (InputSectionBase *S : V) {
298be94e1b6SRafael Espindola     S->Live = false;
299ecbfd871SRafael Espindola     if (S == In<ELFT>::ShStrTab)
300ecbfd871SRafael Espindola       error("discarding .shstrtab section is not allowed");
301647c1685SGeorge Rimar     discard(S->DependentSections);
302be94e1b6SRafael Espindola   }
303be94e1b6SRafael Espindola }
304be94e1b6SRafael Espindola 
30506ae6836SGeorge Rimar template <class ELFT>
306b4c9b81aSRafael Espindola std::vector<InputSectionBase *>
30706ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
308b4c9b81aSRafael Espindola   std::vector<InputSectionBase *> Ret;
309e7f912cdSRui Ueyama 
31006ae6836SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) {
3117c3ff2ebSRafael Espindola     auto *Cmd = dyn_cast<InputSectionDescription>(Base.get());
3127c3ff2ebSRafael Espindola     if (!Cmd)
3130b9ce6a4SRui Ueyama       continue;
314e71a3f8aSRafael Espindola     computeInputSections(Cmd);
315c404d50dSRafael Espindola     for (InputSectionBase *S : Cmd->Sections)
316b4c9b81aSRafael Espindola       Ret.push_back(static_cast<InputSectionBase *>(S));
3170b9ce6a4SRui Ueyama   }
318e71a3f8aSRafael Espindola 
3190b9ce6a4SRui Ueyama   return Ret;
3200b9ce6a4SRui Ueyama }
3210b9ce6a4SRui Ueyama 
322e5d3ca50SPetr Hosek template <class ELFT>
32302a036f2SRui Ueyama void LinkerScript<ELFT>::processCommands(OutputSectionFactory &Factory) {
3247c3ff2ebSRafael Espindola   for (unsigned I = 0; I < Opt.Commands.size(); ++I) {
3257c3ff2ebSRafael Espindola     auto Iter = Opt.Commands.begin() + I;
3267c3ff2ebSRafael Espindola     const std::unique_ptr<BaseCommand> &Base1 = *Iter;
3270b1b695aSRui Ueyama 
3280b1b695aSRui Ueyama     // Handle symbol assignments outside of any output section.
3292ab5f73dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) {
3304cd7352cSRafael Espindola       addSymbol(Cmd);
3312ab5f73dSRui Ueyama       continue;
3322ab5f73dSRui Ueyama     }
3330b1b695aSRui Ueyama 
33420d03194SEugene Leviant     if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) {
33520d03194SEugene Leviant       // If we don't have SECTIONS then output sections have already been
336194470cdSGeorge Rimar       // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses
33720d03194SEugene Leviant       // will not be called, so ASSERT should be evaluated now.
33820d03194SEugene Leviant       if (!Opt.HasSections)
33920d03194SEugene Leviant         Cmd->Expression(0);
34020d03194SEugene Leviant       continue;
34120d03194SEugene Leviant     }
3422ab5f73dSRui Ueyama 
343ceabe80eSEugene Leviant     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) {
344b4c9b81aSRafael Espindola       std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
3457bd37870SRafael Espindola 
3460b1b695aSRui Ueyama       // The output section name `/DISCARD/' is special.
3470b1b695aSRui Ueyama       // Any input section assigned to it is discarded.
34848c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
3497bd37870SRafael Espindola         discard(V);
35048c3f1ceSRui Ueyama         continue;
35148c3f1ceSRui Ueyama       }
3520b9ce6a4SRui Ueyama 
3530b1b695aSRui Ueyama       // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
3540b1b695aSRui Ueyama       // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
3550b1b695aSRui Ueyama       // sections satisfy a given constraint. If not, a directive is handled
3560b1b695aSRui Ueyama       // as if it wasn't present from the beginning.
3570b1b695aSRui Ueyama       //
3580b1b695aSRui Ueyama       // Because we'll iterate over Commands many more times, the easiest
3590b1b695aSRui Ueyama       // way to "make it as if it wasn't present" is to just remove it.
3607c3ff2ebSRafael Espindola       if (!matchConstraints<ELFT>(V, Cmd->Constraint)) {
361b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
362f94efdddSRui Ueyama           S->Assigned = false;
3637c3ff2ebSRafael Espindola         Opt.Commands.erase(Iter);
364dfbbbc86SGeorge Rimar         --I;
3657c3ff2ebSRafael Espindola         continue;
3667c3ff2ebSRafael Espindola       }
3677c3ff2ebSRafael Espindola 
3680b1b695aSRui Ueyama       // A directive may contain symbol definitions like this:
3690b1b695aSRui Ueyama       // ".foo : { ...; bar = .; }". Handle them.
3707c3ff2ebSRafael Espindola       for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands)
3717c3ff2ebSRafael Espindola         if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get()))
3724cd7352cSRafael Espindola           addSymbol(OutCmd);
3737c3ff2ebSRafael Espindola 
3740b1b695aSRui Ueyama       // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
3750b1b695aSRui Ueyama       // is given, input sections are aligned to that value, whether the
3760b1b695aSRui Ueyama       // given value is larger or smaller than the original section alignment.
3770b1b695aSRui Ueyama       if (Cmd->SubalignExpr) {
3780b1b695aSRui Ueyama         uint32_t Subalign = Cmd->SubalignExpr(0);
379b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
3800b1b695aSRui Ueyama           S->Alignment = Subalign;
38120d03194SEugene Leviant       }
3820b1b695aSRui Ueyama 
3830b1b695aSRui Ueyama       // Add input sections to an output section.
384b4c9b81aSRafael Espindola       for (InputSectionBase *S : V)
38502a036f2SRui Ueyama         Factory.addInputSec<ELFT>(S, Cmd->Name);
386eea3114fSGeorge Rimar     }
38748c3f1ceSRui Ueyama   }
388db24d9c3SGeorge Rimar }
389e63d81bdSEugene Leviant 
3900b1b695aSRui Ueyama // Add sections that didn't match any sections command.
39120d03194SEugene Leviant template <class ELFT>
39202a036f2SRui Ueyama void LinkerScript<ELFT>::addOrphanSections(OutputSectionFactory &Factory) {
393536a2670SRui Ueyama   for (InputSectionBase *S : InputSections)
3948f9026baSRafael Espindola     if (S->Live && !S->OutSec)
39502a036f2SRui Ueyama       Factory.addInputSec<ELFT>(S, getOutputSectionName(S->Name));
396e63d81bdSEugene Leviant }
397e63d81bdSEugene Leviant 
39824e6f363SRafael Espindola template <class ELFT> static bool isTbss(OutputSection *Sec) {
39904a2e348SRafael Espindola   return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
400a940e539SRafael Espindola }
401a940e539SRafael Espindola 
402774ea7d0SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::output(InputSection *S) {
403d3190795SRafael Espindola   if (!AlreadyOutputIS.insert(S).second)
404ceabe80eSEugene Leviant     return;
405e08e78dfSRafael Espindola   bool IsTbss = isTbss<ELFT>(CurOutSec);
406d3190795SRafael Espindola 
407d3190795SRafael Espindola   uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot;
408d3190795SRafael Espindola   Pos = alignTo(Pos, S->Alignment);
40904a2e348SRafael Espindola   S->OutSecOff = Pos - CurOutSec->Addr;
410b4c9b81aSRafael Espindola   Pos += S->template getSize<ELFT>();
411d3190795SRafael Espindola 
412d3190795SRafael Espindola   // Update output section size after adding each section. This is so that
413d3190795SRafael Espindola   // SIZEOF works correctly in the case below:
414d3190795SRafael Espindola   // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
41504a2e348SRafael Espindola   CurOutSec->Size = Pos - CurOutSec->Addr;
416d3190795SRafael Espindola 
417b889744eSMeador Inge   // If there is a memory region associated with this input section, then
418b889744eSMeador Inge   // place the section in that region and update the region index.
419b889744eSMeador Inge   if (CurMemRegion) {
420b889744eSMeador Inge     CurMemRegion->Offset += CurOutSec->Size;
421b889744eSMeador Inge     uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin;
422b889744eSMeador Inge     if (CurSize > CurMemRegion->Length) {
423b889744eSMeador Inge       uint64_t OverflowAmt = CurSize - CurMemRegion->Length;
424b889744eSMeador Inge       error("section '" + CurOutSec->Name + "' will not fit in region '" +
425b889744eSMeador Inge             CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
426b889744eSMeador Inge             " bytes");
427b889744eSMeador Inge     }
428b889744eSMeador Inge   }
429b889744eSMeador Inge 
4307252ae52SRafael Espindola   if (IsTbss)
4317252ae52SRafael Espindola     ThreadBssOffset = Pos - Dot;
4327252ae52SRafael Espindola   else
433d3190795SRafael Espindola     Dot = Pos;
4342de509c3SRui Ueyama }
435ceabe80eSEugene Leviant 
436d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::flush() {
437*bd12e2a0SRafael Espindola   assert(CurOutSec);
438*bd12e2a0SRafael Espindola   if (!AlreadyOutputOS.insert(CurOutSec).second)
43965499b90SRafael Espindola     return;
44024e6f363SRafael Espindola   for (InputSection *I : CurOutSec->Sections)
441d3190795SRafael Espindola     output(I);
442d3190795SRafael Espindola }
44397403d15SEugene Leviant 
44424e6f363SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::switchTo(OutputSection *Sec) {
445d3190795SRafael Espindola   if (CurOutSec == Sec)
446d3190795SRafael Espindola     return;
447d3190795SRafael Espindola   if (AlreadyOutputOS.count(Sec))
448d3190795SRafael Espindola     return;
449d3190795SRafael Espindola 
450d3190795SRafael Espindola   CurOutSec = Sec;
451d3190795SRafael Espindola 
45204a2e348SRafael Espindola   Dot = alignTo(Dot, CurOutSec->Addralign);
453e08e78dfSRafael Espindola   CurOutSec->Addr = isTbss<ELFT>(CurOutSec) ? Dot + ThreadBssOffset : Dot;
454b71d6f7aSEugene Leviant 
455b71d6f7aSEugene Leviant   // If neither AT nor AT> is specified for an allocatable section, the linker
456b71d6f7aSEugene Leviant   // will set the LMA such that the difference between VMA and LMA for the
457b71d6f7aSEugene Leviant   // section is the same as the preceding output section in the same region
458b71d6f7aSEugene Leviant   // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
45921467876SGeorge Rimar   if (LMAOffset)
46029c1afb8SRafael Espindola     CurOutSec->LMAOffset = LMAOffset();
461d3190795SRafael Espindola }
462d3190795SRafael Espindola 
463d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) {
464e38cbab5SGeorge Rimar   // This handles the assignments to symbol or to a location counter (.)
465d3190795SRafael Espindola   if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) {
4664cd7352cSRafael Espindola     assignSymbol(AssignCmd, true);
467d3190795SRafael Espindola     return;
46897403d15SEugene Leviant   }
469e38cbab5SGeorge Rimar 
470e38cbab5SGeorge Rimar   // Handle BYTE(), SHORT(), LONG(), or QUAD().
471e38cbab5SGeorge Rimar   if (auto *DataCmd = dyn_cast<BytesDataCommand>(&Base)) {
47204a2e348SRafael Espindola     DataCmd->Offset = Dot - CurOutSec->Addr;
473e38cbab5SGeorge Rimar     Dot += DataCmd->Size;
47404a2e348SRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
475e38cbab5SGeorge Rimar     return;
476e38cbab5SGeorge Rimar   }
477e38cbab5SGeorge Rimar 
478b2d99d6aSMeador Inge   if (auto *AssertCmd = dyn_cast<AssertCommand>(&Base)) {
479b2d99d6aSMeador Inge     AssertCmd->Expression(Dot);
480b2d99d6aSMeador Inge     return;
481b2d99d6aSMeador Inge   }
482b2d99d6aSMeador Inge 
483e38cbab5SGeorge Rimar   // It handles single input section description command,
484e38cbab5SGeorge Rimar   // calculates and assigns the offsets for each section and also
485e38cbab5SGeorge Rimar   // updates the output section size.
486d3190795SRafael Espindola   auto &ICmd = cast<InputSectionDescription>(Base);
487*bd12e2a0SRafael Espindola   for (InputSectionBase *IB : ICmd.Sections) {
4883fb5a6dcSGeorge Rimar     // We tentatively added all synthetic sections at the beginning and removed
4893fb5a6dcSGeorge Rimar     // empty ones afterwards (because there is no way to know whether they were
4903fb5a6dcSGeorge Rimar     // going be empty or not other than actually running linker scripts.)
4913fb5a6dcSGeorge Rimar     // We need to ignore remains of empty sections.
492*bd12e2a0SRafael Espindola     if (auto *Sec = dyn_cast<SyntheticSection>(IB))
4933fb5a6dcSGeorge Rimar       if (Sec->empty())
4943fb5a6dcSGeorge Rimar         continue;
4953fb5a6dcSGeorge Rimar 
49678ef645fSGeorge Rimar     if (!IB->Live)
49778ef645fSGeorge Rimar       continue;
498d3190795SRafael Espindola     switchTo(IB->OutSec);
499*bd12e2a0SRafael Espindola     output(cast<InputSection>(IB));
500ceabe80eSEugene Leviant   }
501ceabe80eSEugene Leviant }
502ceabe80eSEugene Leviant 
5038f66df92SGeorge Rimar template <class ELFT>
50424e6f363SRafael Espindola static OutputSection *
50524e6f363SRafael Espindola findSection(StringRef Name, const std::vector<OutputSection *> &Sections) {
5062b074553SRafael Espindola   auto End = Sections.end();
50724e6f363SRafael Espindola   auto HasName = [=](OutputSection *Sec) { return Sec->Name == Name; };
5082b074553SRafael Espindola   auto I = std::find_if(Sections.begin(), End, HasName);
50924e6f363SRafael Espindola   std::vector<OutputSection *> Ret;
5102b074553SRafael Espindola   if (I == End)
5112b074553SRafael Espindola     return nullptr;
5122b074553SRafael Espindola   assert(std::find_if(I + 1, End, HasName) == End);
5132b074553SRafael Espindola   return *I;
5148f66df92SGeorge Rimar }
5158f66df92SGeorge Rimar 
516b889744eSMeador Inge // This function searches for a memory region to place the given output
517b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is
518b889744eSMeador Inge // returned. Otherwise, a nullptr is returned.
519b889744eSMeador Inge template <class ELFT>
520b889744eSMeador Inge MemoryRegion *LinkerScript<ELFT>::findMemoryRegion(OutputSectionCommand *Cmd,
52124e6f363SRafael Espindola                                                    OutputSection *Sec) {
522b889744eSMeador Inge   // If a memory region name was specified in the output section command,
523b889744eSMeador Inge   // then try to find that region first.
524b889744eSMeador Inge   if (!Cmd->MemoryRegionName.empty()) {
525b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
526b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
527b889744eSMeador Inge       return &It->second;
528b889744eSMeador Inge     error("memory region '" + Cmd->MemoryRegionName + "' not declared");
529b889744eSMeador Inge     return nullptr;
530b889744eSMeador Inge   }
531b889744eSMeador Inge 
532b889744eSMeador Inge   // The memory region name is empty, thus a suitable region must be
533b889744eSMeador Inge   // searched for in the region map. If the region map is empty, just
534b889744eSMeador Inge   // return. Note that this check doesn't happen at the very beginning
535b889744eSMeador Inge   // so that uses of undeclared regions can be caught.
536b889744eSMeador Inge   if (!Opt.MemoryRegions.size())
537b889744eSMeador Inge     return nullptr;
538b889744eSMeador Inge 
539b889744eSMeador Inge   // See if a region can be found by matching section flags.
540b889744eSMeador Inge   for (auto &MRI : Opt.MemoryRegions) {
541b889744eSMeador Inge     MemoryRegion &MR = MRI.second;
5428a8a953eSRui Ueyama     if ((MR.Flags & Sec->Flags) != 0 && (MR.NegFlags & Sec->Flags) == 0)
543b889744eSMeador Inge       return &MR;
544b889744eSMeador Inge   }
545b889744eSMeador Inge 
546b889744eSMeador Inge   // Otherwise, no suitable region was found.
547b889744eSMeador Inge   if (Sec->Flags & SHF_ALLOC)
548b889744eSMeador Inge     error("no memory region specified for section '" + Sec->Name + "'");
549b889744eSMeador Inge   return nullptr;
550b889744eSMeador Inge }
551b889744eSMeador Inge 
5520b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section
5530b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }").
554d3190795SRafael Espindola template <class ELFT>
555d3190795SRafael Espindola void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) {
55621467876SGeorge Rimar   if (Cmd->LMAExpr) {
55721467876SGeorge Rimar     uintX_t D = Dot;
55821467876SGeorge Rimar     LMAOffset = [=] { return Cmd->LMAExpr(D) - D; };
55921467876SGeorge Rimar   }
56024e6f363SRafael Espindola   OutputSection *Sec = findSection<ELFT>(Cmd->Name, *OutputSections);
5612b074553SRafael Espindola   if (!Sec)
562d3190795SRafael Espindola     return;
563b889744eSMeador Inge 
564679828ffSRafael Espindola   if (Cmd->AddrExpr && Sec->Flags & SHF_ALLOC)
5652ee2d2dcSGeorge Rimar     setDot(Cmd->AddrExpr, Cmd->Location);
566679828ffSRafael Espindola 
567165088aaSPetr Hosek   // Handle align (e.g. ".foo : ALIGN(16) { ... }").
568165088aaSPetr Hosek   if (Cmd->AlignExpr)
569165088aaSPetr Hosek     Sec->updateAlignment(Cmd->AlignExpr(0));
570165088aaSPetr Hosek 
571b889744eSMeador Inge   // Try and find an appropriate memory region to assign offsets in.
572b889744eSMeador Inge   CurMemRegion = findMemoryRegion(Cmd, Sec);
573b889744eSMeador Inge   if (CurMemRegion)
574b889744eSMeador Inge     Dot = CurMemRegion->Offset;
575b889744eSMeador Inge   switchTo(Sec);
5760b1b695aSRui Ueyama 
577d3190795SRafael Espindola   // Find the last section output location. We will output orphan sections
578d3190795SRafael Espindola   // there so that end symbols point to the correct location.
579d3190795SRafael Espindola   auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(),
580d3190795SRafael Espindola                         [](const std::unique_ptr<BaseCommand> &Cmd) {
581d3190795SRafael Espindola                           return !isa<SymbolAssignment>(*Cmd);
582d3190795SRafael Espindola                         })
583d3190795SRafael Espindola                .base();
584d3190795SRafael Espindola   for (auto I = Cmd->Commands.begin(); I != E; ++I)
585d3190795SRafael Espindola     process(**I);
5862506cb4dSEugene Leviant   flush();
587b31dd370SGeorge Rimar   std::for_each(E, Cmd->Commands.end(),
588b31dd370SGeorge Rimar                 [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); });
589d3190795SRafael Espindola }
590d3190795SRafael Espindola 
59107fe6129SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::removeEmptyCommands() {
5926d38e4dbSRafael Espindola   // It is common practice to use very generic linker scripts. So for any
5936d38e4dbSRafael Espindola   // given run some of the output sections in the script will be empty.
5946d38e4dbSRafael Espindola   // We could create corresponding empty output sections, but that would
5956d38e4dbSRafael Espindola   // clutter the output.
5966d38e4dbSRafael Espindola   // We instead remove trivially empty sections. The bfd linker seems even
5976d38e4dbSRafael Espindola   // more aggressive at removing them.
5986d38e4dbSRafael Espindola   auto Pos = std::remove_if(
5996d38e4dbSRafael Espindola       Opt.Commands.begin(), Opt.Commands.end(),
6006d38e4dbSRafael Espindola       [&](const std::unique_ptr<BaseCommand> &Base) {
6010b1b695aSRui Ueyama         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
6022b074553SRafael Espindola           return !findSection<ELFT>(Cmd->Name, *OutputSections);
6030b1b695aSRui Ueyama         return false;
6046d38e4dbSRafael Espindola       });
6056d38e4dbSRafael Espindola   Opt.Commands.erase(Pos, Opt.Commands.end());
60607fe6129SRafael Espindola }
60707fe6129SRafael Espindola 
6086a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
6096a53737cSRafael Espindola   for (const std::unique_ptr<BaseCommand> &I : Cmd.Commands)
6106a53737cSRafael Espindola     if (!isa<InputSectionDescription>(*I))
6116a53737cSRafael Espindola       return false;
6126a53737cSRafael Espindola   return true;
6136a53737cSRafael Espindola }
6146d38e4dbSRafael Espindola 
6156a53737cSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() {
6169546fffbSRafael Espindola   // If the output section contains only symbol assignments, create a
6179546fffbSRafael Espindola   // corresponding output section. The bfd linker seems to only create them if
6189546fffbSRafael Espindola   // '.' is assigned to, but creating these section should not have any bad
6199546fffbSRafael Espindola   // consequeces and gives us a section to put the symbol in.
6209546fffbSRafael Espindola   uintX_t Flags = SHF_ALLOC;
621f93b8c29SRafael Espindola   uint32_t Type = SHT_NOBITS;
6229546fffbSRafael Espindola   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
6239546fffbSRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
6249546fffbSRafael Espindola     if (!Cmd)
6259546fffbSRafael Espindola       continue;
62624e6f363SRafael Espindola     if (OutputSection *Sec = findSection<ELFT>(Cmd->Name, *OutputSections)) {
6272b074553SRafael Espindola       Flags = Sec->Flags;
6282b074553SRafael Espindola       Type = Sec->Type;
6299546fffbSRafael Espindola       continue;
6309546fffbSRafael Espindola     }
6319546fffbSRafael Espindola 
6326a53737cSRafael Espindola     if (isAllSectionDescription(*Cmd))
6336a53737cSRafael Espindola       continue;
6346a53737cSRafael Espindola 
63524e6f363SRafael Espindola     auto *OutSec = make<OutputSection>(Cmd->Name, Type, Flags);
6369546fffbSRafael Espindola     OutputSections->push_back(OutSec);
6379546fffbSRafael Espindola   }
638f7a17448SRafael Espindola }
639f7a17448SRafael Espindola 
640f7a17448SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsAfterSorting() {
641f7a17448SRafael Espindola   placeOrphanSections();
642f7a17448SRafael Espindola 
643f7a17448SRafael Espindola   // If output section command doesn't specify any segments,
644f7a17448SRafael Espindola   // and we haven't previously assigned any section to segment,
645f7a17448SRafael Espindola   // then we simply assign section to the very first load segment.
646f7a17448SRafael Espindola   // Below is an example of such linker script:
647f7a17448SRafael Espindola   // PHDRS { seg PT_LOAD; }
648f7a17448SRafael Espindola   // SECTIONS { .aaa : { *(.aaa) } }
649f7a17448SRafael Espindola   std::vector<StringRef> DefPhdrs;
650f7a17448SRafael Espindola   auto FirstPtLoad =
651f7a17448SRafael Espindola       std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(),
652f7a17448SRafael Espindola                    [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; });
653f7a17448SRafael Espindola   if (FirstPtLoad != Opt.PhdrsCommands.end())
654f7a17448SRafael Espindola     DefPhdrs.push_back(FirstPtLoad->Name);
655f7a17448SRafael Espindola 
656f7a17448SRafael Espindola   // Walk the commands and propagate the program headers to commands that don't
657f7a17448SRafael Espindola   // explicitly specify them.
658f7a17448SRafael Espindola   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
659f7a17448SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
660f7a17448SRafael Espindola     if (!Cmd)
661f7a17448SRafael Espindola       continue;
662f7a17448SRafael Espindola     if (Cmd->Phdrs.empty())
663f7a17448SRafael Espindola       Cmd->Phdrs = DefPhdrs;
664f7a17448SRafael Espindola     else
665f7a17448SRafael Espindola       DefPhdrs = Cmd->Phdrs;
666f7a17448SRafael Espindola   }
6676a53737cSRafael Espindola 
6686a53737cSRafael Espindola   removeEmptyCommands();
6699546fffbSRafael Espindola }
6709546fffbSRafael Espindola 
67115c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments
67215c57951SRafael Espindola // so that an orphan after
67315c57951SRafael Espindola //   begin_foo = .;
67415c57951SRafael Espindola //   foo : { *(foo) }
67515c57951SRafael Espindola //   end_foo = .;
67615c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols.
67715c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the
67815c57951SRafael Espindola // one in charge of deciding the order of the sections.
67915c57951SRafael Espindola // We don't want to go over alignments, since doing so in
68015c57951SRafael Espindola //  rx_sec : { *(rx_sec) }
68115c57951SRafael Espindola //  . = ALIGN(0x1000);
68215c57951SRafael Espindola //  /* The RW PT_LOAD starts here*/
68315c57951SRafael Espindola //  rw_sec : { *(rw_sec) }
68415c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned.
6855fcc99c2SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) {
68615c57951SRafael Espindola   if (isa<OutputSectionCommand>(Cmd))
68715c57951SRafael Espindola     return false;
68815c57951SRafael Espindola   const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd);
68915c57951SRafael Espindola   if (!Assign)
69015c57951SRafael Espindola     return true;
6915fcc99c2SRafael Espindola   return Assign->Name != ".";
69215c57951SRafael Espindola }
69315c57951SRafael Espindola 
6946697ec29SRui Ueyama // Orphan sections are sections present in the input files which are
6956697ec29SRui Ueyama // not explicitly placed into the output file by the linker script.
6966697ec29SRui Ueyama //
6976697ec29SRui Ueyama // When the control reaches this function, Opt.Commands contains
6986697ec29SRui Ueyama // output section commands for non-orphan sections only. This function
6996697ec29SRui Ueyama // adds new elements for orphan sections to Opt.Commands so that all
7006697ec29SRui Ueyama // sections are explicitly handled by Opt.Commands.
7016697ec29SRui Ueyama //
7026697ec29SRui Ueyama // Writer<ELFT>::sortSections has already sorted output sections.
7036697ec29SRui Ueyama // What we need to do is to scan OutputSections vector and
7046697ec29SRui Ueyama // Opt.Commands in parallel to find orphan sections. If there is an
7056697ec29SRui Ueyama // output section that doesn't have a corresponding entry in
7066697ec29SRui Ueyama // Opt.Commands, we will insert a new entry to Opt.Commands.
7076697ec29SRui Ueyama //
7086697ec29SRui Ueyama // There is some ambiguity as to where exactly a new entry should be
7096697ec29SRui Ueyama // inserted, because Opt.Commands contains not only output section
7106697ec29SRui Ueyama // commands but other types of commands such as symbol assignment
7116697ec29SRui Ueyama // expressions. There's no correct answer here due to the lack of the
7126697ec29SRui Ueyama // formal specification of the linker script. We use heuristics to
7136697ec29SRui Ueyama // determine whether a new output command should be added before or
7146697ec29SRui Ueyama // after another commands. For the details, look at shouldSkip
7156697ec29SRui Ueyama // function.
71693c64025SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::placeOrphanSections() {
717aab6d5c5SRafael Espindola   // The OutputSections are already in the correct order.
718aab6d5c5SRafael Espindola   // This loops creates or moves commands as needed so that they are in the
719aab6d5c5SRafael Espindola   // correct order.
720aab6d5c5SRafael Espindola   int CmdIndex = 0;
7215fcc99c2SRafael Espindola 
7225fcc99c2SRafael Espindola   // As a horrible special case, skip the first . assignment if it is before any
7235fcc99c2SRafael Espindola   // section. We do this because it is common to set a load address by starting
7245fcc99c2SRafael Espindola   // the script with ". = 0xabcd" and the expectation is that every section is
7255fcc99c2SRafael Espindola   // after that.
7265fcc99c2SRafael Espindola   auto FirstSectionOrDotAssignment =
7275fcc99c2SRafael Espindola       std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
7285fcc99c2SRafael Espindola                    [](const std::unique_ptr<BaseCommand> &Cmd) {
7295fcc99c2SRafael Espindola                      if (isa<OutputSectionCommand>(*Cmd))
7305fcc99c2SRafael Espindola                        return true;
7315fcc99c2SRafael Espindola                      const auto *Assign = dyn_cast<SymbolAssignment>(Cmd.get());
7325fcc99c2SRafael Espindola                      if (!Assign)
7335fcc99c2SRafael Espindola                        return false;
7345fcc99c2SRafael Espindola                      return Assign->Name == ".";
7355fcc99c2SRafael Espindola                    });
7365fcc99c2SRafael Espindola   if (FirstSectionOrDotAssignment != Opt.Commands.end()) {
7375fcc99c2SRafael Espindola     CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin();
7385fcc99c2SRafael Espindola     if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
7395fcc99c2SRafael Espindola       ++CmdIndex;
7405fcc99c2SRafael Espindola   }
7415fcc99c2SRafael Espindola 
74224e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
74340849419SRafael Espindola     StringRef Name = Sec->Name;
744aab6d5c5SRafael Espindola 
745aab6d5c5SRafael Espindola     // Find the last spot where we can insert a command and still get the
74615c57951SRafael Espindola     // correct result.
747aab6d5c5SRafael Espindola     auto CmdIter = Opt.Commands.begin() + CmdIndex;
748aab6d5c5SRafael Espindola     auto E = Opt.Commands.end();
7495fcc99c2SRafael Espindola     while (CmdIter != E && shouldSkip(**CmdIter)) {
750aab6d5c5SRafael Espindola       ++CmdIter;
751aab6d5c5SRafael Espindola       ++CmdIndex;
752aab6d5c5SRafael Espindola     }
753aab6d5c5SRafael Espindola 
754aab6d5c5SRafael Espindola     auto Pos =
755aab6d5c5SRafael Espindola         std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) {
756aab6d5c5SRafael Espindola           auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
757aab6d5c5SRafael Espindola           return Cmd && Cmd->Name == Name;
758aab6d5c5SRafael Espindola         });
759aab6d5c5SRafael Espindola     if (Pos == E) {
760aab6d5c5SRafael Espindola       Opt.Commands.insert(CmdIter,
761aab6d5c5SRafael Espindola                           llvm::make_unique<OutputSectionCommand>(Name));
762aab6d5c5SRafael Espindola       ++CmdIndex;
76315c57951SRafael Espindola       continue;
76415c57951SRafael Espindola     }
76515c57951SRafael Espindola 
76615c57951SRafael Espindola     // Continue from where we found it.
76715c57951SRafael Espindola     CmdIndex = (Pos - Opt.Commands.begin()) + 1;
768652852c5SGeorge Rimar   }
769337f903cSRafael Espindola }
770337f903cSRafael Espindola 
771337f903cSRafael Espindola template <class ELFT>
77217cb7c0aSRafael Espindola void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
7737c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
774be607334SRafael Espindola   Dot = 0;
775652852c5SGeorge Rimar 
77606f4743aSRafael Espindola   // A symbol can be assigned before any section is mentioned in the linker
77706f4743aSRafael Espindola   // script. In an DSO, the symbol values are addresses, so the only important
77806f4743aSRafael Espindola   // section values are:
77906f4743aSRafael Espindola   // * SHN_UNDEF
78006f4743aSRafael Espindola   // * SHN_ABS
78106f4743aSRafael Espindola   // * Any value meaning a regular section.
78206f4743aSRafael Espindola   // To handle that, create a dummy aether section that fills the void before
78306f4743aSRafael Espindola   // the linker scripts switches to another section. It has an index of one
78406f4743aSRafael Espindola   // which will map to whatever the first actual section is.
78524e6f363SRafael Espindola   auto *Aether = make<OutputSection>("", 0, SHF_ALLOC);
78606f4743aSRafael Espindola   Aether->SectionIndex = 1;
78706f4743aSRafael Espindola   switchTo(Aether);
78806f4743aSRafael Espindola 
789076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
790076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
7914cd7352cSRafael Espindola       assignSymbol(Cmd);
79205ef4cffSRui Ueyama       continue;
793652852c5SGeorge Rimar     }
794652852c5SGeorge Rimar 
795eefa758eSGeorge Rimar     if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) {
796eefa758eSGeorge Rimar       Cmd->Expression(Dot);
797eefa758eSGeorge Rimar       continue;
798eefa758eSGeorge Rimar     }
799eefa758eSGeorge Rimar 
800076fe157SGeorge Rimar     auto *Cmd = cast<OutputSectionCommand>(Base.get());
801d3190795SRafael Espindola     assignOffsets(Cmd);
802a14b13d8SGeorge Rimar   }
803467c4d55SEugene Leviant 
804aab6d5c5SRafael Espindola   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
80524e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
80604a2e348SRafael Espindola     if (Sec->Flags & SHF_ALLOC)
807e08e78dfSRafael Espindola       MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
808ea590d91SRafael Espindola     else
809ea590d91SRafael Espindola       Sec->Addr = 0;
810ea590d91SRafael Espindola   }
811aab6d5c5SRafael Espindola 
8128c495e20SRafael Espindola   allocateHeaders<ELFT>(Phdrs, *OutputSections, MinVA);
813fb8978fcSDima Stepanov }
814652852c5SGeorge Rimar 
815464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
81617cb7c0aSRafael Espindola template <class ELFT> std::vector<PhdrEntry> LinkerScript<ELFT>::createPhdrs() {
81717cb7c0aSRafael Espindola   std::vector<PhdrEntry> Ret;
818bbe38602SEugene Leviant 
819464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
820464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
821bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
822edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
82317cb7c0aSRafael Espindola     PhdrEntry &Phdr = Ret.back();
824bbe38602SEugene Leviant 
825bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
8269d1bacb1SRui Ueyama       Phdr.add(Out::ElfHeader);
827bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
8289d1bacb1SRui Ueyama       Phdr.add(Out::ProgramHeaders);
82956b21c86SEugene Leviant 
83056b21c86SEugene Leviant     if (Cmd.LMAExpr) {
83117cb7c0aSRafael Espindola       Phdr.p_paddr = Cmd.LMAExpr(0);
83256b21c86SEugene Leviant       Phdr.HasLMA = true;
83356b21c86SEugene Leviant     }
834bbe38602SEugene Leviant   }
835bbe38602SEugene Leviant 
836464daadcSRui Ueyama   // Add output sections to program headers.
83724e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
83804a2e348SRafael Espindola     if (!(Sec->Flags & SHF_ALLOC))
839bbe38602SEugene Leviant       break;
840bbe38602SEugene Leviant 
841bbe38602SEugene Leviant     // Assign headers specified by linker script
84240849419SRafael Espindola     for (size_t Id : getPhdrIndices(Sec->Name)) {
843edebbdf1SRui Ueyama       Ret[Id].add(Sec);
844865bf863SEugene Leviant       if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
84517cb7c0aSRafael Espindola         Ret[Id].p_flags |= Sec->getPhdrFlags();
846bbe38602SEugene Leviant     }
847bbe38602SEugene Leviant   }
848edebbdf1SRui Ueyama   return Ret;
849bbe38602SEugene Leviant }
850bbe38602SEugene Leviant 
851f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() {
852f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
853f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
854f9bc3bd2SEugene Leviant   return !Opt.PhdrsCommands.empty() &&
855f9bc3bd2SEugene Leviant          llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) {
856f9bc3bd2SEugene Leviant            return Cmd.Type == PT_INTERP;
857f9bc3bd2SEugene Leviant          }) == Opt.PhdrsCommands.end();
858f9bc3bd2SEugene Leviant }
859f9bc3bd2SEugene Leviant 
86093c64025SGeorge Rimar template <class ELFT> uint32_t LinkerScript<ELFT>::getFiller(StringRef Name) {
861f6c3ccefSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
862f6c3ccefSGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
863f6c3ccefSGeorge Rimar       if (Cmd->Name == Name)
864f6c3ccefSGeorge Rimar         return Cmd->Filler;
86516068aebSRui Ueyama   return 0;
866e2ee72b5SGeorge Rimar }
867e2ee72b5SGeorge Rimar 
868e38cbab5SGeorge Rimar template <class ELFT>
869e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
870e38cbab5SGeorge Rimar   const endianness E = ELFT::TargetEndianness;
871e38cbab5SGeorge Rimar 
872e38cbab5SGeorge Rimar   switch (Size) {
873e38cbab5SGeorge Rimar   case 1:
874e38cbab5SGeorge Rimar     *Buf = (uint8_t)Data;
875e38cbab5SGeorge Rimar     break;
876e38cbab5SGeorge Rimar   case 2:
877e38cbab5SGeorge Rimar     write16<E>(Buf, Data);
878e38cbab5SGeorge Rimar     break;
879e38cbab5SGeorge Rimar   case 4:
880e38cbab5SGeorge Rimar     write32<E>(Buf, Data);
881e38cbab5SGeorge Rimar     break;
882e38cbab5SGeorge Rimar   case 8:
883e38cbab5SGeorge Rimar     write64<E>(Buf, Data);
884e38cbab5SGeorge Rimar     break;
885e38cbab5SGeorge Rimar   default:
886e38cbab5SGeorge Rimar     llvm_unreachable("unsupported Size argument");
887e38cbab5SGeorge Rimar   }
888e38cbab5SGeorge Rimar }
889e38cbab5SGeorge Rimar 
890e38cbab5SGeorge Rimar template <class ELFT>
891e38cbab5SGeorge Rimar void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) {
892e38cbab5SGeorge Rimar   int I = getSectionIndex(Name);
893e38cbab5SGeorge Rimar   if (I == INT_MAX)
894e38cbab5SGeorge Rimar     return;
895e38cbab5SGeorge Rimar 
8966e68c5e5SRui Ueyama   auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get());
8976e68c5e5SRui Ueyama   for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands)
8986e68c5e5SRui Ueyama     if (auto *Data = dyn_cast<BytesDataCommand>(Base.get()))
89995c7d8d2SMeador Inge       writeInt<ELFT>(Buf + Data->Offset, Data->Expression(0), Data->Size);
900e38cbab5SGeorge Rimar }
901e38cbab5SGeorge Rimar 
902b71d6f7aSEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasLMA(StringRef Name) {
9038ceadb38SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
9048ceadb38SGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
905b71d6f7aSEugene Leviant       if (Cmd->LMAExpr && Cmd->Name == Name)
906b71d6f7aSEugene Leviant         return true;
907b71d6f7aSEugene Leviant   return false;
9088ceadb38SGeorge Rimar }
9098ceadb38SGeorge Rimar 
910c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script
911c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they
912c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script,
913c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file.
914076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) {
9156e68c5e5SRui Ueyama   for (int I = 0, E = Opt.Commands.size(); I != E; ++I)
9166e68c5e5SRui Ueyama     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()))
917076fe157SGeorge Rimar       if (Cmd->Name == Name)
918f510fa6bSRui Ueyama         return I;
919f510fa6bSRui Ueyama   return INT_MAX;
92071b26e94SGeorge Rimar }
92171b26e94SGeorge Rimar 
922bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
923bbe38602SEugene Leviant   return !Opt.PhdrsCommands.empty();
924bbe38602SEugene Leviant }
925bbe38602SEugene Leviant 
9269e69450eSGeorge Rimar template <class ELFT>
92724e6f363SRafael Espindola const OutputSection *LinkerScript<ELFT>::getOutputSection(const Twine &Loc,
928ed30ce7aSEugene Leviant                                                           StringRef Name) {
92924e6f363SRafael Espindola   static OutputSection FakeSec("", 0, 0);
93096659df0SGeorge Rimar 
93124e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections)
93240849419SRafael Espindola     if (Sec->Name == Name)
933afaa9343SEugene Leviant       return Sec;
934ed30ce7aSEugene Leviant 
935ed30ce7aSEugene Leviant   error(Loc + ": undefined section " + Name);
936afaa9343SEugene Leviant   return &FakeSec;
93736fac7f0SEugene Leviant }
93836fac7f0SEugene Leviant 
939edf75e79SRui Ueyama // This function is essentially the same as getOutputSection(Name)->Size,
940edf75e79SRui Ueyama // but it won't print out an error message if a given section is not found.
941edf75e79SRui Ueyama //
942edf75e79SRui Ueyama // Linker script does not create an output section if its content is empty.
943edf75e79SRui Ueyama // We want to allow SIZEOF(.foo) where .foo is a section which happened to
944edf75e79SRui Ueyama // be empty. That is why this function is different from getOutputSection().
945edf75e79SRui Ueyama template <class ELFT>
946edf75e79SRui Ueyama uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
94724e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections)
94840849419SRafael Espindola     if (Sec->Name == Name)
949edf75e79SRui Ueyama       return Sec->Size;
950edf75e79SRui Ueyama   return 0;
951edf75e79SRui Ueyama }
952edf75e79SRui Ueyama 
953884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() {
9540d4b6d5cSRafael Espindola   return elf::getHeaderSize<ELFT>();
955e32a3598SGeorge Rimar }
956e32a3598SGeorge Rimar 
957f6aeed36SEugene Leviant template <class ELFT>
958f6aeed36SEugene Leviant uint64_t LinkerScript<ELFT>::getSymbolValue(const Twine &Loc, StringRef S) {
959884e786dSGeorge Rimar   if (SymbolBody *B = Symtab<ELFT>::X->find(S))
960884e786dSGeorge Rimar     return B->getVA<ELFT>();
961f6aeed36SEugene Leviant   error(Loc + ": symbol not found: " + S);
962884e786dSGeorge Rimar   return 0;
963884e786dSGeorge Rimar }
964884e786dSGeorge Rimar 
965f34f45fdSGeorge Rimar template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) {
966f34f45fdSGeorge Rimar   return Symtab<ELFT>::X->find(S) != nullptr;
967f34f45fdSGeorge Rimar }
968f34f45fdSGeorge Rimar 
9692f831dcaSRafael Espindola template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) {
9702f831dcaSRafael Espindola   SymbolBody *Sym = Symtab<ELFT>::X->find(S);
97180474a26SRui Ueyama   auto *DR = dyn_cast_or_null<DefinedRegular>(Sym);
9722f831dcaSRafael Espindola   return DR && !DR->Section;
9732f831dcaSRafael Espindola }
9742f831dcaSRafael Espindola 
975afaa9343SEugene Leviant // Gets section symbol belongs to. Symbol "." doesn't belong to any
976afaa9343SEugene Leviant // specific section but isn't absolute at the same time, so we try
977afaa9343SEugene Leviant // to find suitable section for it as well.
978afaa9343SEugene Leviant template <class ELFT>
97924e6f363SRafael Espindola const OutputSection *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
98006f4743aSRafael Espindola   if (SymbolBody *Sym = Symtab<ELFT>::X->find(S))
981968db48cSRui Ueyama     return Sym->getOutputSection<ELFT>();
98206f4743aSRafael Espindola   return CurOutSec;
983afaa9343SEugene Leviant }
984afaa9343SEugene Leviant 
985bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified
986bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within
987bbe38602SEugene Leviant // PHDRS {} script block.
988bbe38602SEugene Leviant template <class ELFT>
989edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) {
990076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
991076fe157SGeorge Rimar     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
992edebbdf1SRui Ueyama     if (!Cmd || Cmd->Name != SectionName)
99331d842f5SGeorge Rimar       continue;
99431d842f5SGeorge Rimar 
99529c5a2a9SRui Ueyama     std::vector<size_t> Ret;
99629c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
9972a942c4bSEugene Leviant       Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
99829c5a2a9SRui Ueyama     return Ret;
999bbe38602SEugene Leviant   }
100031d842f5SGeorge Rimar   return {};
100131d842f5SGeorge Rimar }
1002bbe38602SEugene Leviant 
100329c5a2a9SRui Ueyama template <class ELFT>
10042a942c4bSEugene Leviant size_t LinkerScript<ELFT>::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
100529c5a2a9SRui Ueyama   size_t I = 0;
100629c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
100729c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
100829c5a2a9SRui Ueyama       return I;
100929c5a2a9SRui Ueyama     ++I;
101029c5a2a9SRui Ueyama   }
10112a942c4bSEugene Leviant   error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
101229c5a2a9SRui Ueyama   return 0;
101329c5a2a9SRui Ueyama }
101429c5a2a9SRui Ueyama 
1015794366a2SRui Ueyama class elf::ScriptParser final : public ScriptLexer {
1016c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
1017c3794e58SGeorge Rimar 
1018f7c5fbb1SRui Ueyama public:
101922375f24SRui Ueyama   ScriptParser(MemoryBufferRef MB)
1020794366a2SRui Ueyama       : ScriptLexer(MB),
102122375f24SRui Ueyama         IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {}
1022f23b2320SGeorge Rimar 
102320b6598cSGeorge Rimar   void readLinkerScript();
102420b6598cSGeorge Rimar   void readVersionScript();
1025d0ebd84cSRafael Espindola   void readDynamicList();
1026f7c5fbb1SRui Ueyama 
1027f7c5fbb1SRui Ueyama private:
102852a1509eSRui Ueyama   void addFile(StringRef Path);
102952a1509eSRui Ueyama 
1030f7c5fbb1SRui Ueyama   void readAsNeeded();
103190c5099eSDenis Protivensky   void readEntry();
103283f406cfSGeorge Rimar   void readExtern();
1033f7c5fbb1SRui Ueyama   void readGroup();
103431aa1f83SRui Ueyama   void readInclude();
1035b889744eSMeador Inge   void readMemory();
1036ee59282bSRui Ueyama   void readOutput();
10379159ce93SDavide Italiano   void readOutputArch();
1038f7c5fbb1SRui Ueyama   void readOutputFormat();
1039bbe38602SEugene Leviant   void readPhdrs();
104068a39a65SDavide Italiano   void readSearchDir();
10418e3b38abSDenis Protivensky   void readSections();
104295769b4aSRui Ueyama   void readVersion();
104395769b4aSRui Ueyama   void readVersionScriptCommand();
10448e3b38abSDenis Protivensky 
1045113cdec9SRui Ueyama   SymbolAssignment *readAssignment(StringRef Name);
1046e38cbab5SGeorge Rimar   BytesDataCommand *readBytesDataCommand(StringRef Tok);
104716068aebSRui Ueyama   uint32_t readFill();
104810416564SRui Ueyama   OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
104916068aebSRui Ueyama   uint32_t readOutputSectionFiller(StringRef Tok);
1050bbe38602SEugene Leviant   std::vector<StringRef> readOutputSectionPhdrs();
1051a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionDescription(StringRef Tok);
1052db688454SEugene Leviant   StringMatcher readFilePatterns();
105307171f21SGeorge Rimar   std::vector<SectionPattern> readInputSectionsList();
1054a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionRules(StringRef FilePattern);
1055bbe38602SEugene Leviant   unsigned readPhdrType();
1056be394db3SGeorge Rimar   SortSectionPolicy readSortKind();
1057a35e39caSPetr Hosek   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
1058c96da110SRafael Espindola   SymbolAssignment *readProvideOrAssignment(StringRef Tok);
105903fc010eSGeorge Rimar   void readSort();
1060eefa758eSGeorge Rimar   Expr readAssert();
1061708019c4SRui Ueyama 
106224e626ccSRui Ueyama   uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
106324e626ccSRui Ueyama   std::pair<uint32_t, uint32_t> readMemoryAttributes();
106424e626ccSRui Ueyama 
1065708019c4SRui Ueyama   Expr readExpr();
1066708019c4SRui Ueyama   Expr readExpr1(Expr Lhs, int MinPrec);
1067b71d6f7aSEugene Leviant   StringRef readParenLiteral();
1068708019c4SRui Ueyama   Expr readPrimary();
1069708019c4SRui Ueyama   Expr readTernary(Expr Cond);
10706ad7dfccSRui Ueyama   Expr readParenExpr();
1071f7c5fbb1SRui Ueyama 
107220b6598cSGeorge Rimar   // For parsing version script.
107312450b20SRui Ueyama   std::vector<SymbolVersion> readVersionExtern();
107412450b20SRui Ueyama   void readAnonymousDeclaration();
107595769b4aSRui Ueyama   void readVersionDeclaration(StringRef VerStr);
107612450b20SRui Ueyama   std::vector<SymbolVersion> readSymbols();
1077e999ddb8SRafael Espindola   void readLocals();
107820b6598cSGeorge Rimar 
107907320e40SRui Ueyama   ScriptConfiguration &Opt = *ScriptConfig;
108016b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
1081f7c5fbb1SRui Ueyama };
1082f7c5fbb1SRui Ueyama 
1083d0ebd84cSRafael Espindola void ScriptParser::readDynamicList() {
1084d0ebd84cSRafael Espindola   expect("{");
1085d0ebd84cSRafael Espindola   readAnonymousDeclaration();
1086d0ebd84cSRafael Espindola   if (!atEOF())
1087d0ebd84cSRafael Espindola     setError("EOF expected, but got " + next());
1088d0ebd84cSRafael Espindola }
1089d0ebd84cSRafael Espindola 
109020b6598cSGeorge Rimar void ScriptParser::readVersionScript() {
109195769b4aSRui Ueyama   readVersionScriptCommand();
109220b6598cSGeorge Rimar   if (!atEOF())
109395769b4aSRui Ueyama     setError("EOF expected, but got " + next());
109495769b4aSRui Ueyama }
109595769b4aSRui Ueyama 
109695769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() {
109783043f23SRui Ueyama   if (consume("{")) {
109812450b20SRui Ueyama     readAnonymousDeclaration();
109920b6598cSGeorge Rimar     return;
110020b6598cSGeorge Rimar   }
110120b6598cSGeorge Rimar 
110295769b4aSRui Ueyama   while (!atEOF() && !Error && peek() != "}") {
110320b6598cSGeorge Rimar     StringRef VerStr = next();
110420b6598cSGeorge Rimar     if (VerStr == "{") {
110595769b4aSRui Ueyama       setError("anonymous version definition is used in "
110695769b4aSRui Ueyama                "combination with other version definitions");
110720b6598cSGeorge Rimar       return;
110820b6598cSGeorge Rimar     }
110920b6598cSGeorge Rimar     expect("{");
111095769b4aSRui Ueyama     readVersionDeclaration(VerStr);
111120b6598cSGeorge Rimar   }
111220b6598cSGeorge Rimar }
111320b6598cSGeorge Rimar 
111495769b4aSRui Ueyama void ScriptParser::readVersion() {
111595769b4aSRui Ueyama   expect("{");
111695769b4aSRui Ueyama   readVersionScriptCommand();
111795769b4aSRui Ueyama   expect("}");
111895769b4aSRui Ueyama }
111995769b4aSRui Ueyama 
112020b6598cSGeorge Rimar void ScriptParser::readLinkerScript() {
1121f7c5fbb1SRui Ueyama   while (!atEOF()) {
1122f7c5fbb1SRui Ueyama     StringRef Tok = next();
1123a27eeccaSRui Ueyama     if (Tok == ";")
1124a27eeccaSRui Ueyama       continue;
1125a27eeccaSRui Ueyama 
112620d03194SEugene Leviant     if (Tok == "ASSERT") {
112720d03194SEugene Leviant       Opt.Commands.emplace_back(new AssertCommand(readAssert()));
112820d03194SEugene Leviant     } else if (Tok == "ENTRY") {
1129a27eeccaSRui Ueyama       readEntry();
1130a27eeccaSRui Ueyama     } else if (Tok == "EXTERN") {
1131a27eeccaSRui Ueyama       readExtern();
1132a27eeccaSRui Ueyama     } else if (Tok == "GROUP" || Tok == "INPUT") {
1133a27eeccaSRui Ueyama       readGroup();
1134a27eeccaSRui Ueyama     } else if (Tok == "INCLUDE") {
1135a27eeccaSRui Ueyama       readInclude();
1136b889744eSMeador Inge     } else if (Tok == "MEMORY") {
1137b889744eSMeador Inge       readMemory();
1138a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT") {
1139a27eeccaSRui Ueyama       readOutput();
1140a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_ARCH") {
1141a27eeccaSRui Ueyama       readOutputArch();
1142a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_FORMAT") {
1143a27eeccaSRui Ueyama       readOutputFormat();
1144a27eeccaSRui Ueyama     } else if (Tok == "PHDRS") {
1145a27eeccaSRui Ueyama       readPhdrs();
1146a27eeccaSRui Ueyama     } else if (Tok == "SEARCH_DIR") {
1147a27eeccaSRui Ueyama       readSearchDir();
1148a27eeccaSRui Ueyama     } else if (Tok == "SECTIONS") {
1149a27eeccaSRui Ueyama       readSections();
1150a27eeccaSRui Ueyama     } else if (Tok == "VERSION") {
1151a27eeccaSRui Ueyama       readVersion();
1152c96da110SRafael Espindola     } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) {
11530df80befSPetr Hosek       Opt.Commands.emplace_back(Cmd);
1154e5d3ca50SPetr Hosek     } else {
11555761042dSGeorge Rimar       setError("unknown directive: " + Tok);
1156f7c5fbb1SRui Ueyama     }
1157f7c5fbb1SRui Ueyama   }
1158e5d3ca50SPetr Hosek }
1159f7c5fbb1SRui Ueyama 
1160717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
116116b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
11625af1687fSJustin Bogner     SmallString<128> PathData;
11635af1687fSJustin Bogner     StringRef Path = (Config->Sysroot + S).toStringRef(PathData);
116416b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
11655af1687fSJustin Bogner       Driver->addFile(Saver.save(Path));
116616b0cc9eSSimon Atanasyan       return;
116716b0cc9eSSimon Atanasyan     }
116816b0cc9eSSimon Atanasyan   }
116916b0cc9eSSimon Atanasyan 
1170f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
117152a1509eSRui Ueyama     Driver->addFile(S);
117252a1509eSRui Ueyama   } else if (S.startswith("=")) {
117352a1509eSRui Ueyama     if (Config->Sysroot.empty())
117452a1509eSRui Ueyama       Driver->addFile(S.substr(1));
117552a1509eSRui Ueyama     else
117652a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
117752a1509eSRui Ueyama   } else if (S.startswith("-l")) {
117821eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
1179a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
1180a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
118152a1509eSRui Ueyama   } else {
1182061f9286SRui Ueyama     if (Optional<std::string> Path = findFromSearchPaths(S))
1183061f9286SRui Ueyama       Driver->addFile(Saver.save(*Path));
1184025d59b1SRui Ueyama     else
1185061f9286SRui Ueyama       setError("unable to find " + S);
118652a1509eSRui Ueyama   }
118752a1509eSRui Ueyama }
118852a1509eSRui Ueyama 
1189717677afSRui Ueyama void ScriptParser::readAsNeeded() {
1190f7c5fbb1SRui Ueyama   expect("(");
119135da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
119235da9b6eSRui Ueyama   Config->AsNeeded = true;
119383043f23SRui Ueyama   while (!Error && !consume(")"))
1194cd574a5eSGeorge Rimar     addFile(unquote(next()));
119535da9b6eSRui Ueyama   Config->AsNeeded = Orig;
1196f7c5fbb1SRui Ueyama }
1197f7c5fbb1SRui Ueyama 
1198717677afSRui Ueyama void ScriptParser::readEntry() {
119990c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
120090c5099eSDenis Protivensky   expect("(");
120190c5099eSDenis Protivensky   StringRef Tok = next();
120290c5099eSDenis Protivensky   if (Config->Entry.empty())
120390c5099eSDenis Protivensky     Config->Entry = Tok;
120490c5099eSDenis Protivensky   expect(")");
120590c5099eSDenis Protivensky }
120690c5099eSDenis Protivensky 
1207717677afSRui Ueyama void ScriptParser::readExtern() {
120883f406cfSGeorge Rimar   expect("(");
120983043f23SRui Ueyama   while (!Error && !consume(")"))
1210a2acc931SRui Ueyama     Config->Undefined.push_back(next());
121183f406cfSGeorge Rimar }
121283f406cfSGeorge Rimar 
1213717677afSRui Ueyama void ScriptParser::readGroup() {
1214f7c5fbb1SRui Ueyama   expect("(");
121583043f23SRui Ueyama   while (!Error && !consume(")")) {
1216f7c5fbb1SRui Ueyama     StringRef Tok = next();
1217a2acc931SRui Ueyama     if (Tok == "AS_NEEDED")
1218f7c5fbb1SRui Ueyama       readAsNeeded();
1219a2acc931SRui Ueyama     else
1220cd574a5eSGeorge Rimar       addFile(unquote(Tok));
1221f7c5fbb1SRui Ueyama   }
1222f7c5fbb1SRui Ueyama }
1223f7c5fbb1SRui Ueyama 
1224717677afSRui Ueyama void ScriptParser::readInclude() {
1225d4500653SGeorge Rimar   StringRef Tok = unquote(next());
1226ec1c75e0SRui Ueyama 
1227d4500653SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/File-Commands.html:
1228d4500653SGeorge Rimar   // The file will be searched for in the current directory, and in any
1229d4500653SGeorge Rimar   // directory specified with the -L option.
1230ec1c75e0SRui Ueyama   if (sys::fs::exists(Tok)) {
1231ec1c75e0SRui Ueyama     if (Optional<MemoryBufferRef> MB = readFile(Tok))
1232ec1c75e0SRui Ueyama       tokenize(*MB);
1233025d59b1SRui Ueyama     return;
1234025d59b1SRui Ueyama   }
1235ec1c75e0SRui Ueyama   if (Optional<std::string> Path = findFromSearchPaths(Tok)) {
1236ec1c75e0SRui Ueyama     if (Optional<MemoryBufferRef> MB = readFile(*Path))
1237ec1c75e0SRui Ueyama       tokenize(*MB);
1238ec1c75e0SRui Ueyama     return;
1239ec1c75e0SRui Ueyama   }
1240ec1c75e0SRui Ueyama   setError("cannot open " + Tok);
124131aa1f83SRui Ueyama }
124231aa1f83SRui Ueyama 
1243717677afSRui Ueyama void ScriptParser::readOutput() {
1244ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
1245ee59282bSRui Ueyama   expect("(");
1246ee59282bSRui Ueyama   StringRef Tok = next();
1247ee59282bSRui Ueyama   if (Config->OutputFile.empty())
1248cd574a5eSGeorge Rimar     Config->OutputFile = unquote(Tok);
1249ee59282bSRui Ueyama   expect(")");
1250ee59282bSRui Ueyama }
1251ee59282bSRui Ueyama 
1252717677afSRui Ueyama void ScriptParser::readOutputArch() {
12534e01c3e8SGeorge Rimar   // OUTPUT_ARCH is ignored for now.
12549159ce93SDavide Italiano   expect("(");
12554e01c3e8SGeorge Rimar   while (!Error && !consume(")"))
12565424e7c7SJustin Bogner     skip();
12579159ce93SDavide Italiano }
12589159ce93SDavide Italiano 
1259717677afSRui Ueyama void ScriptParser::readOutputFormat() {
1260f7c5fbb1SRui Ueyama   // Error checking only for now.
1261f7c5fbb1SRui Ueyama   expect("(");
12625424e7c7SJustin Bogner   skip();
12636836c618SDavide Italiano   StringRef Tok = next();
12646836c618SDavide Italiano   if (Tok == ")")
12656836c618SDavide Italiano     return;
1266025d59b1SRui Ueyama   if (Tok != ",") {
12675761042dSGeorge Rimar     setError("unexpected token: " + Tok);
1268025d59b1SRui Ueyama     return;
1269025d59b1SRui Ueyama   }
12705424e7c7SJustin Bogner   skip();
12716836c618SDavide Italiano   expect(",");
12725424e7c7SJustin Bogner   skip();
1273f7c5fbb1SRui Ueyama   expect(")");
1274f7c5fbb1SRui Ueyama }
1275f7c5fbb1SRui Ueyama 
1276bbe38602SEugene Leviant void ScriptParser::readPhdrs() {
1277bbe38602SEugene Leviant   expect("{");
127883043f23SRui Ueyama   while (!Error && !consume("}")) {
1279bbe38602SEugene Leviant     StringRef Tok = next();
128056b21c86SEugene Leviant     Opt.PhdrsCommands.push_back(
128156b21c86SEugene Leviant         {Tok, PT_NULL, false, false, UINT_MAX, nullptr});
1282bbe38602SEugene Leviant     PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back();
1283bbe38602SEugene Leviant 
1284bbe38602SEugene Leviant     PhdrCmd.Type = readPhdrType();
1285bbe38602SEugene Leviant     do {
1286bbe38602SEugene Leviant       Tok = next();
1287bbe38602SEugene Leviant       if (Tok == ";")
1288bbe38602SEugene Leviant         break;
1289bbe38602SEugene Leviant       if (Tok == "FILEHDR")
1290bbe38602SEugene Leviant         PhdrCmd.HasFilehdr = true;
1291bbe38602SEugene Leviant       else if (Tok == "PHDRS")
1292bbe38602SEugene Leviant         PhdrCmd.HasPhdrs = true;
129356b21c86SEugene Leviant       else if (Tok == "AT")
129456b21c86SEugene Leviant         PhdrCmd.LMAExpr = readParenExpr();
1295865bf863SEugene Leviant       else if (Tok == "FLAGS") {
1296865bf863SEugene Leviant         expect("(");
1297eb685cd7SRafael Espindola         // Passing 0 for the value of dot is a bit of a hack. It means that
1298eb685cd7SRafael Espindola         // we accept expressions like ".|1".
1299eb685cd7SRafael Espindola         PhdrCmd.Flags = readExpr()(0);
1300865bf863SEugene Leviant         expect(")");
1301865bf863SEugene Leviant       } else
1302bbe38602SEugene Leviant         setError("unexpected header attribute: " + Tok);
1303bbe38602SEugene Leviant     } while (!Error);
1304bbe38602SEugene Leviant   }
1305bbe38602SEugene Leviant }
1306bbe38602SEugene Leviant 
1307717677afSRui Ueyama void ScriptParser::readSearchDir() {
130868a39a65SDavide Italiano   expect("(");
130986c5fb82SRui Ueyama   StringRef Tok = next();
13106c7ad13fSRui Ueyama   if (!Config->Nostdlib)
1311cd574a5eSGeorge Rimar     Config->SearchPaths.push_back(unquote(Tok));
131268a39a65SDavide Italiano   expect(")");
131368a39a65SDavide Italiano }
131468a39a65SDavide Italiano 
1315717677afSRui Ueyama void ScriptParser::readSections() {
1316e05336ffSEugene Leviant   Opt.HasSections = true;
131718a30962SGeorge Rimar   // -no-rosegment is used to avoid placing read only non-executable sections in
131818a30962SGeorge Rimar   // their own segment. We do the same if SECTIONS command is present in linker
131918a30962SGeorge Rimar   // script. See comment for computeFlags().
132018a30962SGeorge Rimar   Config->SingleRoRx = true;
132118a30962SGeorge Rimar 
13228e3b38abSDenis Protivensky   expect("{");
132383043f23SRui Ueyama   while (!Error && !consume("}")) {
1324113cdec9SRui Ueyama     StringRef Tok = next();
1325c96da110SRafael Espindola     BaseCommand *Cmd = readProvideOrAssignment(Tok);
1326ceabe80eSEugene Leviant     if (!Cmd) {
1327ceabe80eSEugene Leviant       if (Tok == "ASSERT")
1328eefa758eSGeorge Rimar         Cmd = new AssertCommand(readAssert());
1329ceabe80eSEugene Leviant       else
133010416564SRui Ueyama         Cmd = readOutputSectionDescription(Tok);
13318e3b38abSDenis Protivensky     }
133210416564SRui Ueyama     Opt.Commands.emplace_back(Cmd);
1333652852c5SGeorge Rimar   }
1334708019c4SRui Ueyama }
13358e3b38abSDenis Protivensky 
1336708019c4SRui Ueyama static int precedence(StringRef Op) {
1337708019c4SRui Ueyama   return StringSwitch<int>(Op)
13380120e3f2SRui Ueyama       .Cases("*", "/", 5)
13390120e3f2SRui Ueyama       .Cases("+", "-", 4)
13400120e3f2SRui Ueyama       .Cases("<<", ">>", 3)
13419c4ac5f2SRui Ueyama       .Cases("<", "<=", ">", ">=", "==", "!=", 2)
13420120e3f2SRui Ueyama       .Cases("&", "|", 1)
1343708019c4SRui Ueyama       .Default(-1);
1344708019c4SRui Ueyama }
1345708019c4SRui Ueyama 
1346db688454SEugene Leviant StringMatcher ScriptParser::readFilePatterns() {
134710416564SRui Ueyama   std::vector<StringRef> V;
134883043f23SRui Ueyama   while (!Error && !consume(")"))
134910416564SRui Ueyama     V.push_back(next());
1350f91282e1SRui Ueyama   return StringMatcher(V);
13510702c4e8SGeorge Rimar }
13520702c4e8SGeorge Rimar 
1353be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() {
135483043f23SRui Ueyama   if (consume("SORT") || consume("SORT_BY_NAME"))
1355be394db3SGeorge Rimar     return SortSectionPolicy::Name;
135683043f23SRui Ueyama   if (consume("SORT_BY_ALIGNMENT"))
1357be394db3SGeorge Rimar     return SortSectionPolicy::Alignment;
135883043f23SRui Ueyama   if (consume("SORT_BY_INIT_PRIORITY"))
1359be394db3SGeorge Rimar     return SortSectionPolicy::Priority;
136083043f23SRui Ueyama   if (consume("SORT_NONE"))
1361be394db3SGeorge Rimar     return SortSectionPolicy::None;
1362b2a0abdfSRui Ueyama   return SortSectionPolicy::Default;
1363be394db3SGeorge Rimar }
1364be394db3SGeorge Rimar 
1365395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in
1366395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+
1367395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3)
1368af03be19SGeorge Rimar // The semantics of that is next:
1369af03be19SGeorge Rimar // * Include .foo.1 from every file.
1370af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o
1371af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o
137207171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
137307171f21SGeorge Rimar   std::vector<SectionPattern> Ret;
1374601e9898SGeorge Rimar   while (!Error && peek() != ")") {
1375f91282e1SRui Ueyama     StringMatcher ExcludeFilePat;
137683043f23SRui Ueyama     if (consume("EXCLUDE_FILE")) {
1377395281cfSGeorge Rimar       expect("(");
1378f91282e1SRui Ueyama       ExcludeFilePat = readFilePatterns();
1379395281cfSGeorge Rimar     }
1380395281cfSGeorge Rimar 
1381601e9898SGeorge Rimar     std::vector<StringRef> V;
1382601e9898SGeorge Rimar     while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE")
1383395281cfSGeorge Rimar       V.push_back(next());
1384601e9898SGeorge Rimar 
1385601e9898SGeorge Rimar     if (!V.empty())
1386f91282e1SRui Ueyama       Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)});
1387601e9898SGeorge Rimar     else
1388601e9898SGeorge Rimar       setError("section pattern is expected");
1389395281cfSGeorge Rimar   }
139007171f21SGeorge Rimar   return Ret;
1391395281cfSGeorge Rimar }
1392395281cfSGeorge Rimar 
1393f8f6f1e7SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a
1394f8f6f1e7SRui Ueyama // list of glob patterns for input sections. The grammar is as follows.
1395f8f6f1e7SRui Ueyama //
1396f8f6f1e7SRui Ueyama // <patterns> ::= <section-list>
1397f8f6f1e7SRui Ueyama //              | <sort> "(" <section-list> ")"
1398f8f6f1e7SRui Ueyama //              | <sort> "(" <sort> "(" <section-list> ")" ")"
1399f8f6f1e7SRui Ueyama //
1400f8f6f1e7SRui Ueyama // <sort>     ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
1401f8f6f1e7SRui Ueyama //              | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
1402f8f6f1e7SRui Ueyama //
1403f8f6f1e7SRui Ueyama // <section-list> is parsed by readInputSectionsList().
1404a2496cbeSGeorge Rimar InputSectionDescription *
1405a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) {
1406c91930a1SGeorge Rimar   auto *Cmd = new InputSectionDescription(FilePattern);
14070ed42b0cSDavide Italiano   expect("(");
1408f373dd76SRui Ueyama   while (!Error && !consume(")")) {
140907171f21SGeorge Rimar     SortSectionPolicy Outer = readSortKind();
141007171f21SGeorge Rimar     SortSectionPolicy Inner = SortSectionPolicy::Default;
141107171f21SGeorge Rimar     std::vector<SectionPattern> V;
141207171f21SGeorge Rimar     if (Outer != SortSectionPolicy::Default) {
14130702c4e8SGeorge Rimar       expect("(");
141407171f21SGeorge Rimar       Inner = readSortKind();
141507171f21SGeorge Rimar       if (Inner != SortSectionPolicy::Default) {
1416350ece4eSGeorge Rimar         expect("(");
141707171f21SGeorge Rimar         V = readInputSectionsList();
14180702c4e8SGeorge Rimar         expect(")");
1419350ece4eSGeorge Rimar       } else {
142007171f21SGeorge Rimar         V = readInputSectionsList();
1421350ece4eSGeorge Rimar       }
1422350ece4eSGeorge Rimar       expect(")");
142307171f21SGeorge Rimar     } else {
142407171f21SGeorge Rimar       V = readInputSectionsList();
14250659800eSGeorge Rimar     }
14260702c4e8SGeorge Rimar 
142707171f21SGeorge Rimar     for (SectionPattern &Pat : V) {
142807171f21SGeorge Rimar       Pat.SortInner = Inner;
142907171f21SGeorge Rimar       Pat.SortOuter = Outer;
143007171f21SGeorge Rimar     }
143107171f21SGeorge Rimar 
143207171f21SGeorge Rimar     std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns));
143307171f21SGeorge Rimar   }
143410416564SRui Ueyama   return Cmd;
14350659800eSGeorge Rimar }
14360659800eSGeorge Rimar 
1437a2496cbeSGeorge Rimar InputSectionDescription *
1438a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) {
14390659800eSGeorge Rimar   // Input section wildcard can be surrounded by KEEP.
14400659800eSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
1441a2496cbeSGeorge Rimar   if (Tok == "KEEP") {
1442e7282797SDavide Italiano     expect("(");
1443a2496cbeSGeorge Rimar     StringRef FilePattern = next();
1444a2496cbeSGeorge Rimar     InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
14450ed42b0cSDavide Italiano     expect(")");
1446cf43f179SEugene Leviant     Opt.KeptSections.push_back(Cmd);
144710416564SRui Ueyama     return Cmd;
144810416564SRui Ueyama   }
1449a2496cbeSGeorge Rimar   return readInputSectionRules(Tok);
14500659800eSGeorge Rimar }
14510659800eSGeorge Rimar 
145203fc010eSGeorge Rimar void ScriptParser::readSort() {
145303fc010eSGeorge Rimar   expect("(");
145403fc010eSGeorge Rimar   expect("CONSTRUCTORS");
145503fc010eSGeorge Rimar   expect(")");
145603fc010eSGeorge Rimar }
145703fc010eSGeorge Rimar 
1458eefa758eSGeorge Rimar Expr ScriptParser::readAssert() {
1459eefa758eSGeorge Rimar   expect("(");
1460eefa758eSGeorge Rimar   Expr E = readExpr();
1461eefa758eSGeorge Rimar   expect(",");
1462cd574a5eSGeorge Rimar   StringRef Msg = unquote(next());
1463eefa758eSGeorge Rimar   expect(")");
1464eefa758eSGeorge Rimar   return [=](uint64_t Dot) {
146560f1fe84SGeorge Rimar     if (!E(Dot))
1466eefa758eSGeorge Rimar       error(Msg);
146760f1fe84SGeorge Rimar     return Dot;
1468eefa758eSGeorge Rimar   };
1469eefa758eSGeorge Rimar }
1470eefa758eSGeorge Rimar 
147125150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an
147225150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from
147325150e8bSRui Ueyama // what GNU linkers do.
147425150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
147516068aebSRui Ueyama uint32_t ScriptParser::readFill() {
1476ff1f29e0SGeorge Rimar   expect("(");
147716068aebSRui Ueyama   uint32_t V = readOutputSectionFiller(next());
1478ff1f29e0SGeorge Rimar   expect(")");
1479ff1f29e0SGeorge Rimar   expect(";");
1480ff1f29e0SGeorge Rimar   return V;
1481ff1f29e0SGeorge Rimar }
1482ff1f29e0SGeorge Rimar 
148310416564SRui Ueyama OutputSectionCommand *
148410416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) {
1485076fe157SGeorge Rimar   OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
14862a942c4bSEugene Leviant   Cmd->Location = getCurrentLocation();
148758e5c4dcSGeorge Rimar 
148858e5c4dcSGeorge Rimar   // Read an address expression.
148958e5c4dcSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address
149058e5c4dcSGeorge Rimar   if (peek() != ":")
149158e5c4dcSGeorge Rimar     Cmd->AddrExpr = readExpr();
149258e5c4dcSGeorge Rimar 
14938e3b38abSDenis Protivensky   expect(":");
1494246f681eSDavide Italiano 
149583043f23SRui Ueyama   if (consume("AT"))
1496b71d6f7aSEugene Leviant     Cmd->LMAExpr = readParenExpr();
149783043f23SRui Ueyama   if (consume("ALIGN"))
14986ad7dfccSRui Ueyama     Cmd->AlignExpr = readParenExpr();
149983043f23SRui Ueyama   if (consume("SUBALIGN"))
1500db24d9c3SGeorge Rimar     Cmd->SubalignExpr = readParenExpr();
1501630c6179SGeorge Rimar 
1502246f681eSDavide Italiano   // Parse constraints.
150383043f23SRui Ueyama   if (consume("ONLY_IF_RO"))
1504efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadOnly;
150583043f23SRui Ueyama   if (consume("ONLY_IF_RW"))
1506efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadWrite;
15078e3b38abSDenis Protivensky   expect("{");
15088ec77e64SRui Ueyama 
150983043f23SRui Ueyama   while (!Error && !consume("}")) {
1510ceabe80eSEugene Leviant     StringRef Tok = next();
15112fe07923SGeorge Rimar     if (Tok == ";") {
151269750755SGeorge Rimar       // Empty commands are allowed. Do nothing here.
15132fe07923SGeorge Rimar     } else if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) {
1514ceabe80eSEugene Leviant       Cmd->Commands.emplace_back(Assignment);
1515b2d99d6aSMeador Inge     } else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) {
1516e38cbab5SGeorge Rimar       Cmd->Commands.emplace_back(Data);
1517b2d99d6aSMeador Inge     } else if (Tok == "ASSERT") {
1518b2d99d6aSMeador Inge       Cmd->Commands.emplace_back(new AssertCommand(readAssert()));
1519b2d99d6aSMeador Inge       expect(";");
15208e2eca22SGeorge Rimar     } else if (Tok == "CONSTRUCTORS") {
15218e2eca22SGeorge Rimar       // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
15228e2eca22SGeorge Rimar       // by name. This is for very old file formats such as ECOFF/XCOFF.
15238e2eca22SGeorge Rimar       // For ELF, we should ignore.
1524b2d99d6aSMeador Inge     } else if (Tok == "FILL") {
1525ff1f29e0SGeorge Rimar       Cmd->Filler = readFill();
1526b2d99d6aSMeador Inge     } else if (Tok == "SORT") {
152703fc010eSGeorge Rimar       readSort();
1528b2d99d6aSMeador Inge     } else if (peek() == "(") {
1529a2496cbeSGeorge Rimar       Cmd->Commands.emplace_back(readInputSectionDescription(Tok));
1530b2d99d6aSMeador Inge     } else {
1531ceabe80eSEugene Leviant       setError("unknown command " + Tok);
15328e3b38abSDenis Protivensky     }
1533b2d99d6aSMeador Inge   }
1534b889744eSMeador Inge 
1535b889744eSMeador Inge   if (consume(">"))
1536b889744eSMeador Inge     Cmd->MemoryRegionName = next();
1537b889744eSMeador Inge 
1538076fe157SGeorge Rimar   Cmd->Phdrs = readOutputSectionPhdrs();
15394ebc5620SGeorge Rimar 
154083043f23SRui Ueyama   if (consume("="))
15414ebc5620SGeorge Rimar     Cmd->Filler = readOutputSectionFiller(next());
15424ebc5620SGeorge Rimar   else if (peek().startswith("="))
1543ff1f29e0SGeorge Rimar     Cmd->Filler = readOutputSectionFiller(next().drop_front());
15444ebc5620SGeorge Rimar 
15457185a1acSGeorge Rimar   // Consume optional comma following output section command.
15467185a1acSGeorge Rimar   consume(",");
15477185a1acSGeorge Rimar 
154810416564SRui Ueyama   return Cmd;
1549f71caa2bSRui Ueyama }
15508ec77e64SRui Ueyama 
15512c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number.
15522c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
15532c8f1f04SRui Ueyama //
15542c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles
15552c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them
15562c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does
15572c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does.
155816068aebSRui Ueyama uint32_t ScriptParser::readOutputSectionFiller(StringRef Tok) {
1559965827d6SRui Ueyama   uint32_t V;
156016068aebSRui Ueyama   if (!Tok.getAsInteger(0, V))
156116068aebSRui Ueyama     return V;
1562965827d6SRui Ueyama   setError("invalid filler expression: " + Tok);
156316068aebSRui Ueyama   return 0;
15648e3b38abSDenis Protivensky }
15658e3b38abSDenis Protivensky 
1566a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
1567a31c91b1SEugene Leviant   expect("(");
1568174e0a16SRui Ueyama   SymbolAssignment *Cmd = readAssignment(next());
1569a35e39caSPetr Hosek   Cmd->Provide = Provide;
1570174e0a16SRui Ueyama   Cmd->Hidden = Hidden;
1571a31c91b1SEugene Leviant   expect(")");
1572a31c91b1SEugene Leviant   expect(";");
157310416564SRui Ueyama   return Cmd;
1574eda81a1bSEugene Leviant }
1575eda81a1bSEugene Leviant 
1576c96da110SRafael Espindola SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
1577ceabe80eSEugene Leviant   SymbolAssignment *Cmd = nullptr;
1578ceabe80eSEugene Leviant   if (peek() == "=" || peek() == "+=") {
1579ceabe80eSEugene Leviant     Cmd = readAssignment(Tok);
1580ceabe80eSEugene Leviant     expect(";");
1581ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE") {
1582a35e39caSPetr Hosek     Cmd = readProvideHidden(true, false);
1583a35e39caSPetr Hosek   } else if (Tok == "HIDDEN") {
1584a35e39caSPetr Hosek     Cmd = readProvideHidden(false, true);
1585ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE_HIDDEN") {
1586a35e39caSPetr Hosek     Cmd = readProvideHidden(true, true);
1587ceabe80eSEugene Leviant   }
1588ceabe80eSEugene Leviant   return Cmd;
1589ceabe80eSEugene Leviant }
1590ceabe80eSEugene Leviant 
1591f6aeed36SEugene Leviant static uint64_t getSymbolValue(const Twine &Loc, StringRef S, uint64_t Dot) {
159230835ea4SGeorge Rimar   if (S == ".")
159330835ea4SGeorge Rimar     return Dot;
1594f6aeed36SEugene Leviant   return ScriptBase->getSymbolValue(Loc, S);
1595e32a3598SGeorge Rimar }
1596e32a3598SGeorge Rimar 
15972f831dcaSRafael Espindola static bool isAbsolute(StringRef S) {
15982f831dcaSRafael Espindola   if (S == ".")
15992f831dcaSRafael Espindola     return false;
16002f831dcaSRafael Espindola   return ScriptBase->isAbsolute(S);
16012f831dcaSRafael Espindola }
16022f831dcaSRafael Espindola 
160330835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
160430835ea4SGeorge Rimar   StringRef Op = next();
1605db741e72SEugene Leviant   Expr E;
160630835ea4SGeorge Rimar   assert(Op == "=" || Op == "+=");
160783043f23SRui Ueyama   if (consume("ABSOLUTE")) {
1608731a66aeSRui Ueyama     E = readExpr();
1609009d1742SRui Ueyama     E.IsAbsolute = [] { return true; };
1610db741e72SEugene Leviant   } else {
1611db741e72SEugene Leviant     E = readExpr();
1612db741e72SEugene Leviant   }
1613f6aeed36SEugene Leviant   if (Op == "+=") {
1614f6aeed36SEugene Leviant     std::string Loc = getCurrentLocation();
1615f6aeed36SEugene Leviant     E = [=](uint64_t Dot) {
1616f6aeed36SEugene Leviant       return getSymbolValue(Loc, Name, Dot) + E(Dot);
1617f6aeed36SEugene Leviant     };
1618f6aeed36SEugene Leviant   }
16192ee2d2dcSGeorge Rimar   return new SymbolAssignment(Name, E, getCurrentLocation());
162030835ea4SGeorge Rimar }
162130835ea4SGeorge Rimar 
162230835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker
162330835ea4SGeorge Rimar // script expression.
1624731a66aeSRui Ueyama Expr ScriptParser::readExpr() {
1625731a66aeSRui Ueyama   // Our lexer is context-aware. Set the in-expression bit so that
1626731a66aeSRui Ueyama   // they apply different tokenization rules.
1627731a66aeSRui Ueyama   bool Orig = InExpr;
1628731a66aeSRui Ueyama   InExpr = true;
1629731a66aeSRui Ueyama   Expr E = readExpr1(readPrimary(), 0);
1630731a66aeSRui Ueyama   InExpr = Orig;
1631731a66aeSRui Ueyama   return E;
1632731a66aeSRui Ueyama }
163330835ea4SGeorge Rimar 
163436c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) {
1635cc4d3e57SGeorge Rimar   auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); };
1636cc4d3e57SGeorge Rimar   auto GetOutSec = [=] {
163724e6f363SRafael Espindola     const OutputSection *S = L.Section();
1638cc4d3e57SGeorge Rimar     return S ? S : R.Section();
1639cc4d3e57SGeorge Rimar   };
1640cc4d3e57SGeorge Rimar 
164136c1cd23SRui Ueyama   if (Op == "*")
164236c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) * R(Dot); };
164336c1cd23SRui Ueyama   if (Op == "/") {
164436c1cd23SRui Ueyama     return [=](uint64_t Dot) -> uint64_t {
164536c1cd23SRui Ueyama       uint64_t RHS = R(Dot);
164636c1cd23SRui Ueyama       if (RHS == 0) {
164736c1cd23SRui Ueyama         error("division by zero");
164836c1cd23SRui Ueyama         return 0;
164936c1cd23SRui Ueyama       }
165036c1cd23SRui Ueyama       return L(Dot) / RHS;
165136c1cd23SRui Ueyama     };
165236c1cd23SRui Ueyama   }
165336c1cd23SRui Ueyama   if (Op == "+")
1654cc4d3e57SGeorge Rimar     return {[=](uint64_t Dot) { return L(Dot) + R(Dot); }, IsAbs, GetOutSec};
165536c1cd23SRui Ueyama   if (Op == "-")
1656cc4d3e57SGeorge Rimar     return {[=](uint64_t Dot) { return L(Dot) - R(Dot); }, IsAbs, GetOutSec};
1657c8ccd1f1SGeorge Rimar   if (Op == "<<")
1658c8ccd1f1SGeorge Rimar     return [=](uint64_t Dot) { return L(Dot) << R(Dot); };
1659c8ccd1f1SGeorge Rimar   if (Op == ">>")
1660c8ccd1f1SGeorge Rimar     return [=](uint64_t Dot) { return L(Dot) >> R(Dot); };
166136c1cd23SRui Ueyama   if (Op == "<")
166236c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) < R(Dot); };
166336c1cd23SRui Ueyama   if (Op == ">")
166436c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) > R(Dot); };
166536c1cd23SRui Ueyama   if (Op == ">=")
166636c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) >= R(Dot); };
166736c1cd23SRui Ueyama   if (Op == "<=")
166836c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) <= R(Dot); };
166936c1cd23SRui Ueyama   if (Op == "==")
167036c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) == R(Dot); };
167136c1cd23SRui Ueyama   if (Op == "!=")
167236c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) != R(Dot); };
167336c1cd23SRui Ueyama   if (Op == "&")
167436c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) & R(Dot); };
1675cc3dd629SRafael Espindola   if (Op == "|")
1676cc3dd629SRafael Espindola     return [=](uint64_t Dot) { return L(Dot) | R(Dot); };
167736c1cd23SRui Ueyama   llvm_unreachable("invalid operator");
167836c1cd23SRui Ueyama }
167936c1cd23SRui Ueyama 
1680708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function
1681708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator.
1682708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
1683708019c4SRui Ueyama   while (!atEOF() && !Error) {
1684708019c4SRui Ueyama     // Read an operator and an expression.
168546247b85SRui Ueyama     if (consume("?"))
1686708019c4SRui Ueyama       return readTernary(Lhs);
168746247b85SRui Ueyama     StringRef Op1 = peek();
1688708019c4SRui Ueyama     if (precedence(Op1) < MinPrec)
1689a31c91b1SEugene Leviant       break;
16905424e7c7SJustin Bogner     skip();
1691708019c4SRui Ueyama     Expr Rhs = readPrimary();
1692708019c4SRui Ueyama 
1693708019c4SRui Ueyama     // Evaluate the remaining part of the expression first if the
1694708019c4SRui Ueyama     // next operator has greater precedence than the previous one.
1695708019c4SRui Ueyama     // For example, if we have read "+" and "3", and if the next
1696708019c4SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
1697708019c4SRui Ueyama     while (!atEOF()) {
1698708019c4SRui Ueyama       StringRef Op2 = peek();
1699708019c4SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
1700eda81a1bSEugene Leviant         break;
1701708019c4SRui Ueyama       Rhs = readExpr1(Rhs, precedence(Op2));
1702eda81a1bSEugene Leviant     }
1703708019c4SRui Ueyama 
1704708019c4SRui Ueyama     Lhs = combine(Op1, Lhs, Rhs);
1705708019c4SRui Ueyama   }
1706708019c4SRui Ueyama   return Lhs;
1707708019c4SRui Ueyama }
1708708019c4SRui Ueyama 
1709708019c4SRui Ueyama uint64_t static getConstant(StringRef S) {
1710e2cc07bcSMichael J. Spencer   if (S == "COMMONPAGESIZE")
1711708019c4SRui Ueyama     return Target->PageSize;
1712e2cc07bcSMichael J. Spencer   if (S == "MAXPAGESIZE")
1713997f8838SPetr Hosek     return Config->MaxPageSize;
1714708019c4SRui Ueyama   error("unknown constant: " + S);
1715708019c4SRui Ueyama   return 0;
1716708019c4SRui Ueyama }
1717708019c4SRui Ueyama 
1718626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful.
1719626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H")
1720626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or
1721626e0b08SRui Ueyama // "M" (mega) prefixes.
17229f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) {
172346247b85SRui Ueyama   // Negative number
1724eaeafb2bSSimon Atanasyan   if (Tok.startswith("-")) {
1725eaeafb2bSSimon Atanasyan     if (!readInteger(Tok.substr(1), Result))
1726eaeafb2bSSimon Atanasyan       return false;
1727eaeafb2bSSimon Atanasyan     Result = -Result;
1728eaeafb2bSSimon Atanasyan     return true;
1729eaeafb2bSSimon Atanasyan   }
173046247b85SRui Ueyama 
173146247b85SRui Ueyama   // Hexadecimal
17329f2f7ad9SGeorge Rimar   if (Tok.startswith_lower("0x"))
17339f2f7ad9SGeorge Rimar     return !Tok.substr(2).getAsInteger(16, Result);
17349f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("H"))
17359f2f7ad9SGeorge Rimar     return !Tok.drop_back().getAsInteger(16, Result);
17369f2f7ad9SGeorge Rimar 
173746247b85SRui Ueyama   // Decimal
17389f2f7ad9SGeorge Rimar   int Suffix = 1;
17399f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("K")) {
17409f2f7ad9SGeorge Rimar     Suffix = 1024;
17419f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
17429f2f7ad9SGeorge Rimar   } else if (Tok.endswith_lower("M")) {
17439f2f7ad9SGeorge Rimar     Suffix = 1024 * 1024;
17449f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
17459f2f7ad9SGeorge Rimar   }
17469f2f7ad9SGeorge Rimar   if (Tok.getAsInteger(10, Result))
17479f2f7ad9SGeorge Rimar     return false;
17489f2f7ad9SGeorge Rimar   Result *= Suffix;
17499f2f7ad9SGeorge Rimar   return true;
17509f2f7ad9SGeorge Rimar }
17519f2f7ad9SGeorge Rimar 
1752e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) {
1753e38cbab5SGeorge Rimar   int Size = StringSwitch<unsigned>(Tok)
1754e38cbab5SGeorge Rimar                  .Case("BYTE", 1)
1755e38cbab5SGeorge Rimar                  .Case("SHORT", 2)
1756e38cbab5SGeorge Rimar                  .Case("LONG", 4)
1757e38cbab5SGeorge Rimar                  .Case("QUAD", 8)
1758e38cbab5SGeorge Rimar                  .Default(-1);
1759e38cbab5SGeorge Rimar   if (Size == -1)
1760e38cbab5SGeorge Rimar     return nullptr;
1761e38cbab5SGeorge Rimar 
176295c7d8d2SMeador Inge   return new BytesDataCommand(readParenExpr(), Size);
1763e38cbab5SGeorge Rimar }
1764e38cbab5SGeorge Rimar 
1765b71d6f7aSEugene Leviant StringRef ScriptParser::readParenLiteral() {
1766b71d6f7aSEugene Leviant   expect("(");
1767b71d6f7aSEugene Leviant   StringRef Tok = next();
1768b71d6f7aSEugene Leviant   expect(")");
1769b71d6f7aSEugene Leviant   return Tok;
1770b71d6f7aSEugene Leviant }
1771b71d6f7aSEugene Leviant 
1772708019c4SRui Ueyama Expr ScriptParser::readPrimary() {
17736ad7dfccSRui Ueyama   if (peek() == "(")
17746ad7dfccSRui Ueyama     return readParenExpr();
1775708019c4SRui Ueyama 
17766ad7dfccSRui Ueyama   StringRef Tok = next();
1777b5f1c3ecSRui Ueyama   std::string Location = getCurrentLocation();
1778708019c4SRui Ueyama 
1779eaeafb2bSSimon Atanasyan   if (Tok == "~") {
1780eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
1781eaeafb2bSSimon Atanasyan     return [=](uint64_t Dot) { return ~E(Dot); };
1782eaeafb2bSSimon Atanasyan   }
1783eaeafb2bSSimon Atanasyan   if (Tok == "-") {
1784eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
1785eaeafb2bSSimon Atanasyan     return [=](uint64_t Dot) { return -E(Dot); };
1786eaeafb2bSSimon Atanasyan   }
1787eaeafb2bSSimon Atanasyan 
1788708019c4SRui Ueyama   // Built-in functions are parsed here.
1789708019c4SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
179096659df0SGeorge Rimar   if (Tok == "ADDR") {
1791b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1792ed30ce7aSEugene Leviant     return {[=](uint64_t Dot) {
1793ed30ce7aSEugene Leviant               return ScriptBase->getOutputSection(Location, Name)->Addr;
1794ed30ce7aSEugene Leviant             },
1795009d1742SRui Ueyama             [=] { return false; },
1796ed30ce7aSEugene Leviant             [=] { return ScriptBase->getOutputSection(Location, Name); }};
179796659df0SGeorge Rimar   }
1798b71d6f7aSEugene Leviant   if (Tok == "LOADADDR") {
1799b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1800afaa9343SEugene Leviant     return [=](uint64_t Dot) {
1801ed30ce7aSEugene Leviant       return ScriptBase->getOutputSection(Location, Name)->getLMA();
1802afaa9343SEugene Leviant     };
1803b71d6f7aSEugene Leviant   }
1804eefa758eSGeorge Rimar   if (Tok == "ASSERT")
1805eefa758eSGeorge Rimar     return readAssert();
1806708019c4SRui Ueyama   if (Tok == "ALIGN") {
18075d804dc8SRui Ueyama     expect("(");
18085d804dc8SRui Ueyama     Expr E = readExpr();
18095d804dc8SRui Ueyama     if (consume(",")) {
18105d804dc8SRui Ueyama       Expr E2 = readExpr();
18115d804dc8SRui Ueyama       expect(")");
18125d804dc8SRui Ueyama       return [=](uint64_t Dot) { return alignTo(E(Dot), E2(Dot)); };
18135d804dc8SRui Ueyama     }
18145d804dc8SRui Ueyama     expect(")");
1815708019c4SRui Ueyama     return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
1816708019c4SRui Ueyama   }
1817708019c4SRui Ueyama   if (Tok == "CONSTANT") {
1818b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1819b0de56b5SRafael Espindola     return [=](uint64_t Dot) { return getConstant(Name); };
1820708019c4SRui Ueyama   }
1821f34f45fdSGeorge Rimar   if (Tok == "DEFINED") {
18220ee25a69SRui Ueyama     StringRef Name = readParenLiteral();
18230ee25a69SRui Ueyama     return [=](uint64_t Dot) { return ScriptBase->isDefined(Name) ? 1 : 0; };
1824f34f45fdSGeorge Rimar   }
182554c145ceSRafael Espindola   if (Tok == "SEGMENT_START") {
182654c145ceSRafael Espindola     expect("(");
18275424e7c7SJustin Bogner     skip();
182854c145ceSRafael Espindola     expect(",");
18298c658bf8SGeorge Rimar     Expr E = readExpr();
183054c145ceSRafael Espindola     expect(")");
18318c658bf8SGeorge Rimar     return [=](uint64_t Dot) { return E(Dot); };
183254c145ceSRafael Espindola   }
1833708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_ALIGN") {
1834708019c4SRui Ueyama     expect("(");
1835708019c4SRui Ueyama     Expr E = readExpr();
1836708019c4SRui Ueyama     expect(",");
1837708019c4SRui Ueyama     readExpr();
1838708019c4SRui Ueyama     expect(")");
1839f7791bb9SRui Ueyama     return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
1840708019c4SRui Ueyama   }
1841708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_END") {
1842708019c4SRui Ueyama     expect("(");
1843708019c4SRui Ueyama     expect(".");
1844708019c4SRui Ueyama     expect(")");
1845708019c4SRui Ueyama     return [](uint64_t Dot) { return Dot; };
1846708019c4SRui Ueyama   }
1847276b4e64SGeorge Rimar   // GNU linkers implements more complicated logic to handle
1848276b4e64SGeorge Rimar   // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to
1849276b4e64SGeorge Rimar   // the next page boundary for simplicity.
1850276b4e64SGeorge Rimar   if (Tok == "DATA_SEGMENT_RELRO_END") {
1851276b4e64SGeorge Rimar     expect("(");
185297bdc722SRafael Espindola     readExpr();
1853276b4e64SGeorge Rimar     expect(",");
1854276b4e64SGeorge Rimar     readExpr();
1855276b4e64SGeorge Rimar     expect(")");
1856276b4e64SGeorge Rimar     return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); };
1857276b4e64SGeorge Rimar   }
18589e69450eSGeorge Rimar   if (Tok == "SIZEOF") {
1859b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1860edf75e79SRui Ueyama     return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); };
18619e69450eSGeorge Rimar   }
186236fac7f0SEugene Leviant   if (Tok == "ALIGNOF") {
1863b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1864afaa9343SEugene Leviant     return [=](uint64_t Dot) {
1865ed30ce7aSEugene Leviant       return ScriptBase->getOutputSection(Location, Name)->Addralign;
1866afaa9343SEugene Leviant     };
186736fac7f0SEugene Leviant   }
1868e32a3598SGeorge Rimar   if (Tok == "SIZEOF_HEADERS")
1869b0de56b5SRafael Espindola     return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); };
1870708019c4SRui Ueyama 
18719f2f7ad9SGeorge Rimar   // Tok is a literal number.
18729f2f7ad9SGeorge Rimar   uint64_t V;
18739f2f7ad9SGeorge Rimar   if (readInteger(Tok, V))
1874b0de56b5SRafael Espindola     return [=](uint64_t Dot) { return V; };
18759f2f7ad9SGeorge Rimar 
18769f2f7ad9SGeorge Rimar   // Tok is a symbol name.
187730835ea4SGeorge Rimar   if (Tok != "." && !isValidCIdentifier(Tok))
1878708019c4SRui Ueyama     setError("malformed number: " + Tok);
1879f6aeed36SEugene Leviant   return {[=](uint64_t Dot) { return getSymbolValue(Location, Tok, Dot); },
1880009d1742SRui Ueyama           [=] { return isAbsolute(Tok); },
1881009d1742SRui Ueyama           [=] { return ScriptBase->getSymbolSection(Tok); }};
1882a9c5a528SGeorge Rimar }
1883708019c4SRui Ueyama 
1884708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) {
1885708019c4SRui Ueyama   Expr L = readExpr();
1886708019c4SRui Ueyama   expect(":");
1887708019c4SRui Ueyama   Expr R = readExpr();
1888708019c4SRui Ueyama   return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); };
1889708019c4SRui Ueyama }
1890708019c4SRui Ueyama 
18916ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() {
18926ad7dfccSRui Ueyama   expect("(");
18936ad7dfccSRui Ueyama   Expr E = readExpr();
18946ad7dfccSRui Ueyama   expect(")");
18956ad7dfccSRui Ueyama   return E;
18966ad7dfccSRui Ueyama }
18976ad7dfccSRui Ueyama 
1898bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
1899bbe38602SEugene Leviant   std::vector<StringRef> Phdrs;
1900bbe38602SEugene Leviant   while (!Error && peek().startswith(":")) {
1901bbe38602SEugene Leviant     StringRef Tok = next();
1902da841c16SGeorge Rimar     Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
1903bbe38602SEugene Leviant   }
1904bbe38602SEugene Leviant   return Phdrs;
1905bbe38602SEugene Leviant }
1906bbe38602SEugene Leviant 
190795dd718cSGeorge Rimar // Read a program header type name. The next token must be a
190895dd718cSGeorge Rimar // name of a program header type or a constant (e.g. "0x3").
1909bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() {
1910bbe38602SEugene Leviant   StringRef Tok = next();
191195dd718cSGeorge Rimar   uint64_t Val;
191295dd718cSGeorge Rimar   if (readInteger(Tok, Val))
191395dd718cSGeorge Rimar     return Val;
191495dd718cSGeorge Rimar 
1915b0f6c590SRui Ueyama   unsigned Ret = StringSwitch<unsigned>(Tok)
1916b0f6c590SRui Ueyama                      .Case("PT_NULL", PT_NULL)
1917b0f6c590SRui Ueyama                      .Case("PT_LOAD", PT_LOAD)
1918b0f6c590SRui Ueyama                      .Case("PT_DYNAMIC", PT_DYNAMIC)
1919b0f6c590SRui Ueyama                      .Case("PT_INTERP", PT_INTERP)
1920b0f6c590SRui Ueyama                      .Case("PT_NOTE", PT_NOTE)
1921b0f6c590SRui Ueyama                      .Case("PT_SHLIB", PT_SHLIB)
1922b0f6c590SRui Ueyama                      .Case("PT_PHDR", PT_PHDR)
1923b0f6c590SRui Ueyama                      .Case("PT_TLS", PT_TLS)
1924b0f6c590SRui Ueyama                      .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
1925b0f6c590SRui Ueyama                      .Case("PT_GNU_STACK", PT_GNU_STACK)
1926b0f6c590SRui Ueyama                      .Case("PT_GNU_RELRO", PT_GNU_RELRO)
1927270173f2SGeorge Rimar                      .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
1928cc6e567cSGeorge Rimar                      .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
1929a2a32c2cSGeorge Rimar                      .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
1930b0f6c590SRui Ueyama                      .Default(-1);
1931bbe38602SEugene Leviant 
1932b0f6c590SRui Ueyama   if (Ret == (unsigned)-1) {
1933b0f6c590SRui Ueyama     setError("invalid program header type: " + Tok);
1934b0f6c590SRui Ueyama     return PT_NULL;
1935b0f6c590SRui Ueyama   }
1936b0f6c590SRui Ueyama   return Ret;
1937bbe38602SEugene Leviant }
1938bbe38602SEugene Leviant 
193912450b20SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
194012450b20SRui Ueyama void ScriptParser::readAnonymousDeclaration() {
194112450b20SRui Ueyama   // Read global symbols first. "global:" is default, so if there's
194212450b20SRui Ueyama   // no label, we assume global symbols.
19434524268cSRafael Espindola   if (peek() != "local") {
19444524268cSRafael Espindola     if (consume("global"))
19454524268cSRafael Espindola       expect(":");
1946904c5ed5SPeter Collingbourne     for (SymbolVersion V : readSymbols())
1947904c5ed5SPeter Collingbourne       Config->VersionScriptGlobals.push_back(V);
19484524268cSRafael Espindola   }
1949e999ddb8SRafael Espindola   readLocals();
195012450b20SRui Ueyama   expect("}");
195112450b20SRui Ueyama   expect(";");
195212450b20SRui Ueyama }
195312450b20SRui Ueyama 
1954e999ddb8SRafael Espindola void ScriptParser::readLocals() {
19554524268cSRafael Espindola   if (!consume("local"))
1956e999ddb8SRafael Espindola     return;
19574524268cSRafael Espindola   expect(":");
1958e999ddb8SRafael Espindola   std::vector<SymbolVersion> Locals = readSymbols();
1959e999ddb8SRafael Espindola   for (SymbolVersion V : Locals) {
1960e999ddb8SRafael Espindola     if (V.Name == "*") {
1961e999ddb8SRafael Espindola       Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1962e999ddb8SRafael Espindola       continue;
1963e999ddb8SRafael Espindola     }
1964e999ddb8SRafael Espindola     Config->VersionScriptLocals.push_back(V);
1965e999ddb8SRafael Espindola   }
1966e999ddb8SRafael Espindola }
1967e999ddb8SRafael Espindola 
196812450b20SRui Ueyama // Reads a list of symbols, e.g. "VerStr { global: foo; bar; local: *; };".
196995769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) {
197020b6598cSGeorge Rimar   // Identifiers start at 2 because 0 and 1 are reserved
197120b6598cSGeorge Rimar   // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants.
1972da805c48SRui Ueyama   uint16_t VersionId = Config->VersionDefinitions.size() + 2;
197320b6598cSGeorge Rimar   Config->VersionDefinitions.push_back({VerStr, VersionId});
197420b6598cSGeorge Rimar 
197512450b20SRui Ueyama   // Read global symbols.
19764524268cSRafael Espindola   if (peek() != "local") {
19774524268cSRafael Espindola     if (consume("global"))
19784524268cSRafael Espindola       expect(":");
197912450b20SRui Ueyama     Config->VersionDefinitions.back().Globals = readSymbols();
19804524268cSRafael Espindola   }
1981e999ddb8SRafael Espindola   readLocals();
198220b6598cSGeorge Rimar   expect("}");
198320b6598cSGeorge Rimar 
198412450b20SRui Ueyama   // Each version may have a parent version. For example, "Ver2"
198512450b20SRui Ueyama   // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
198612450b20SRui Ueyama   // as a parent. This version hierarchy is, probably against your
198712450b20SRui Ueyama   // instinct, purely for hint; the runtime doesn't care about it
198812450b20SRui Ueyama   // at all. In LLD, we simply ignore it.
198912450b20SRui Ueyama   if (peek() != ";")
19905424e7c7SJustin Bogner     skip();
199120b6598cSGeorge Rimar   expect(";");
199220b6598cSGeorge Rimar }
199320b6598cSGeorge Rimar 
199412450b20SRui Ueyama // Reads a list of symbols for a versions cript.
199512450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readSymbols() {
199612450b20SRui Ueyama   std::vector<SymbolVersion> Ret;
1997e0fc2421SGeorge Rimar   for (;;) {
19981ef90d2fSRafael Espindola     if (consume("extern")) {
199912450b20SRui Ueyama       for (SymbolVersion V : readVersionExtern())
200012450b20SRui Ueyama         Ret.push_back(V);
20011ef90d2fSRafael Espindola       continue;
20021ef90d2fSRafael Espindola     }
2003e0fc2421SGeorge Rimar 
2004f3965c02SDmitry Mikulin     if (peek() == "}" || (peek() == "local" && peek(1) == ":") || Error)
200512450b20SRui Ueyama       break;
20060ee25a69SRui Ueyama     StringRef Tok = next();
200712450b20SRui Ueyama     Ret.push_back({unquote(Tok), false, hasWildcard(Tok)});
2008e0fc2421SGeorge Rimar     expect(";");
2009e0fc2421SGeorge Rimar   }
201012450b20SRui Ueyama   return Ret;
2011e0fc2421SGeorge Rimar }
2012e0fc2421SGeorge Rimar 
201312450b20SRui Ueyama // Reads an "extern C++" directive, e.g.,
201412450b20SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };"
201512450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
20167e71415cSRafael Espindola   StringRef Tok = next();
20177e71415cSRafael Espindola   bool IsCXX = Tok == "\"C++\"";
20187e71415cSRafael Espindola   if (!IsCXX && Tok != "\"C\"")
2019d0ebd84cSRafael Espindola     setError("Unknown language");
202020b6598cSGeorge Rimar   expect("{");
202120b6598cSGeorge Rimar 
202212450b20SRui Ueyama   std::vector<SymbolVersion> Ret;
20230ee25a69SRui Ueyama   while (!Error && peek() != "}") {
20240ee25a69SRui Ueyama     StringRef Tok = next();
20250ee25a69SRui Ueyama     bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok);
20267e71415cSRafael Espindola     Ret.push_back({unquote(Tok), IsCXX, HasWildcard});
202720b6598cSGeorge Rimar     expect(";");
202820b6598cSGeorge Rimar   }
202920b6598cSGeorge Rimar 
203020b6598cSGeorge Rimar   expect("}");
203120b6598cSGeorge Rimar   expect(";");
203212450b20SRui Ueyama   return Ret;
203320b6598cSGeorge Rimar }
203420b6598cSGeorge Rimar 
203524e626ccSRui Ueyama uint64_t ScriptParser::readMemoryAssignment(
203624e626ccSRui Ueyama     StringRef S1, StringRef S2, StringRef S3) {
203724e626ccSRui Ueyama   if (!(consume(S1) || consume(S2) || consume(S3))) {
203824e626ccSRui Ueyama     setError("expected one of: " + S1 + ", " + S2 + ", or " + S3);
203924e626ccSRui Ueyama     return 0;
204024e626ccSRui Ueyama   }
204124e626ccSRui Ueyama   expect("=");
204224e626ccSRui Ueyama 
204324e626ccSRui Ueyama   // TODO: Fully support constant expressions.
204424e626ccSRui Ueyama   uint64_t Val;
204524e626ccSRui Ueyama   if (!readInteger(next(), Val))
204624e626ccSRui Ueyama     setError("nonconstant expression for "+ S1);
204724e626ccSRui Ueyama   return Val;
204824e626ccSRui Ueyama }
204924e626ccSRui Ueyama 
205024e626ccSRui Ueyama // Parse the MEMORY command as specified in:
205124e626ccSRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html
205224e626ccSRui Ueyama //
205324e626ccSRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
2054b889744eSMeador Inge void ScriptParser::readMemory() {
2055b889744eSMeador Inge   expect("{");
2056b889744eSMeador Inge   while (!Error && !consume("}")) {
2057b889744eSMeador Inge     StringRef Name = next();
205824e626ccSRui Ueyama 
2059b889744eSMeador Inge     uint32_t Flags = 0;
20608a8a953eSRui Ueyama     uint32_t NegFlags = 0;
2061b889744eSMeador Inge     if (consume("(")) {
20628a8a953eSRui Ueyama       std::tie(Flags, NegFlags) = readMemoryAttributes();
2063b889744eSMeador Inge       expect(")");
2064b889744eSMeador Inge     }
2065b889744eSMeador Inge     expect(":");
2066b889744eSMeador Inge 
206724e626ccSRui Ueyama     uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o");
2068b889744eSMeador Inge     expect(",");
206924e626ccSRui Ueyama     uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
2070b889744eSMeador Inge 
2071b889744eSMeador Inge     // Add the memory region to the region map (if it doesn't already exist).
2072b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Name);
2073b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
2074b889744eSMeador Inge       setError("region '" + Name + "' already defined");
2075b889744eSMeador Inge     else
20768a8a953eSRui Ueyama       Opt.MemoryRegions[Name] = {Name, Origin, Length, Origin, Flags, NegFlags};
2077b889744eSMeador Inge   }
2078b889744eSMeador Inge }
2079b889744eSMeador Inge 
2080b889744eSMeador Inge // This function parses the attributes used to match against section
2081b889744eSMeador Inge // flags when placing output sections in a memory region. These flags
2082b889744eSMeador Inge // are only used when an explicit memory region name is not used.
2083b889744eSMeador Inge std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
2084b889744eSMeador Inge   uint32_t Flags = 0;
20858a8a953eSRui Ueyama   uint32_t NegFlags = 0;
2086b889744eSMeador Inge   bool Invert = false;
2087481ac996SRui Ueyama 
2088481ac996SRui Ueyama   for (char C : next().lower()) {
2089b889744eSMeador Inge     uint32_t Flag = 0;
2090b889744eSMeador Inge     if (C == '!')
2091b889744eSMeador Inge       Invert = !Invert;
2092481ac996SRui Ueyama     else if (C == 'w')
2093b889744eSMeador Inge       Flag = SHF_WRITE;
2094481ac996SRui Ueyama     else if (C == 'x')
2095b889744eSMeador Inge       Flag = SHF_EXECINSTR;
2096481ac996SRui Ueyama     else if (C == 'a')
2097b889744eSMeador Inge       Flag = SHF_ALLOC;
2098481ac996SRui Ueyama     else if (C != 'r')
2099b889744eSMeador Inge       setError("invalid memory region attribute");
2100481ac996SRui Ueyama 
2101b889744eSMeador Inge     if (Invert)
21028a8a953eSRui Ueyama       NegFlags |= Flag;
2103b889744eSMeador Inge     else
2104b889744eSMeador Inge       Flags |= Flag;
2105b889744eSMeador Inge   }
21068a8a953eSRui Ueyama   return {Flags, NegFlags};
2107b889744eSMeador Inge }
2108b889744eSMeador Inge 
210907320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) {
211022375f24SRui Ueyama   ScriptParser(MB).readLinkerScript();
211120b6598cSGeorge Rimar }
211220b6598cSGeorge Rimar 
211320b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) {
211422375f24SRui Ueyama   ScriptParser(MB).readVersionScript();
2115f7c5fbb1SRui Ueyama }
21161ebc8ed7SRui Ueyama 
2117d0ebd84cSRafael Espindola void elf::readDynamicList(MemoryBufferRef MB) {
2118d0ebd84cSRafael Espindola   ScriptParser(MB).readDynamicList();
2119d0ebd84cSRafael Espindola }
2120d0ebd84cSRafael Espindola 
212107320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>;
212207320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>;
212307320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>;
212407320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>;
2125