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"
20e77b5bf6SAdhemerval Zanella #include "ScriptParser.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) {
603dabfc6bSRafael Espindola   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
618f1f3c40SMeador Inge   Symbol *Sym = Symtab<ELFT>::X->addUndefined(
628f1f3c40SMeador Inge       Cmd->Name, /*IsLocal=*/false, STB_GLOBAL, Visibility,
638f1f3c40SMeador Inge       /*Type*/ 0,
648f1f3c40SMeador Inge       /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
6520d03194SEugene Leviant 
668f1f3c40SMeador Inge   replaceBody<DefinedRegular<ELFT>>(Sym, Cmd->Name, /*IsLocal=*/false,
678f1f3c40SMeador Inge                                     Visibility, STT_NOTYPE, 0, 0, nullptr,
688f1f3c40SMeador Inge                                     nullptr);
698f1f3c40SMeador Inge   return Sym->body();
70ceabe80eSEugene Leviant }
71ceabe80eSEugene Leviant 
728f1f3c40SMeador Inge template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment *Cmd) {
738f1f3c40SMeador Inge   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
74afaa9343SEugene Leviant   const OutputSectionBase *Sec =
75afaa9343SEugene Leviant       ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section();
768f1f3c40SMeador Inge   Symbol *Sym = Symtab<ELFT>::X->addUndefined(
778f1f3c40SMeador Inge       Cmd->Name, /*IsLocal=*/false, STB_GLOBAL, Visibility,
788f1f3c40SMeador Inge       /*Type*/ 0,
798f1f3c40SMeador Inge       /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
80afaa9343SEugene Leviant 
818f1f3c40SMeador Inge   replaceBody<DefinedSynthetic>(Sym, Cmd->Name, 0, Sec);
828f1f3c40SMeador Inge   return Sym->body();
83ceabe80eSEugene Leviant }
84ceabe80eSEugene Leviant 
8522375f24SRui Ueyama static bool isUnderSysroot(StringRef Path) {
8622375f24SRui Ueyama   if (Config->Sysroot == "")
8722375f24SRui Ueyama     return false;
8822375f24SRui Ueyama   for (; !Path.empty(); Path = sys::path::parent_path(Path))
8922375f24SRui Ueyama     if (sys::fs::equivalent(Config->Sysroot, Path))
9022375f24SRui Ueyama       return true;
9122375f24SRui Ueyama   return false;
9222375f24SRui Ueyama }
9322375f24SRui Ueyama 
948f1f3c40SMeador Inge template <class ELFT> static void assignSymbol(SymbolAssignment *Cmd) {
958f1f3c40SMeador Inge   // If there are sections, then let the value be assigned later in
968f1f3c40SMeador Inge   // `assignAddresses`.
978f1f3c40SMeador Inge   if (ScriptConfig->HasSections)
988f1f3c40SMeador Inge     return;
998f1f3c40SMeador Inge 
1008f1f3c40SMeador Inge   uint64_t Value = Cmd->Expression(0);
1018f1f3c40SMeador Inge   if (Cmd->Expression.IsAbsolute()) {
1028f1f3c40SMeador Inge     cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Value;
1038f1f3c40SMeador Inge   } else {
1048f1f3c40SMeador Inge     const OutputSectionBase *Sec = Cmd->Expression.Section();
1058f1f3c40SMeador Inge     if (Sec)
1068f1f3c40SMeador Inge       cast<DefinedSynthetic>(Cmd->Sym)->Value = Value - Sec->Addr;
107db741e72SEugene Leviant   }
1088f1f3c40SMeador Inge }
1098f1f3c40SMeador Inge 
1108f1f3c40SMeador Inge template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) {
1111602421cSRui Ueyama   if (Cmd->Name == ".")
1128f1f3c40SMeador Inge     return;
1138f1f3c40SMeador Inge 
1148f1f3c40SMeador Inge   // If a symbol was in PROVIDE(), we need to define it only when
1158f1f3c40SMeador Inge   // it is a referenced undefined symbol.
1161602421cSRui Ueyama   SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name);
1178f1f3c40SMeador Inge   if (Cmd->Provide && (!B || B->isDefined()))
1188f1f3c40SMeador Inge     return;
1198f1f3c40SMeador Inge 
1208f1f3c40SMeador Inge   // Otherwise, create a new symbol if one does not exist or an
1218f1f3c40SMeador Inge   // undefined one does exist.
1228f1f3c40SMeador Inge   if (Cmd->Expression.IsAbsolute())
1238f1f3c40SMeador Inge     Cmd->Sym = addRegular<ELFT>(Cmd);
1248f1f3c40SMeador Inge   else
1258f1f3c40SMeador Inge     Cmd->Sym = addSynthetic<ELFT>(Cmd);
1268f1f3c40SMeador Inge   assignSymbol<ELFT>(Cmd);
127ceabe80eSEugene Leviant }
128ceabe80eSEugene Leviant 
129076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
130076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
131076fe157SGeorge Rimar }
132076fe157SGeorge Rimar 
133076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
134076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
135076fe157SGeorge Rimar }
136076fe157SGeorge Rimar 
137eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
138eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
139eea3114fSGeorge Rimar }
140eea3114fSGeorge Rimar 
141eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) {
142eefa758eSGeorge Rimar   return C->Kind == AssertKind;
143eefa758eSGeorge Rimar }
144eefa758eSGeorge Rimar 
145e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) {
146e38cbab5SGeorge Rimar   return C->Kind == BytesDataKind;
147e38cbab5SGeorge Rimar }
148e38cbab5SGeorge Rimar 
14922886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::LinkerScript() = default;
15022886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::~LinkerScript() = default;
151f34d0e08SRui Ueyama 
152e0be2901SRui Ueyama template <class ELFT> static StringRef basename(InputSectionBase<ELFT> *S) {
153e0be2901SRui Ueyama   if (S->getFile())
154e0be2901SRui Ueyama     return sys::path::filename(S->getFile()->getName());
155e0be2901SRui Ueyama   return "";
156e0be2901SRui Ueyama }
157e0be2901SRui Ueyama 
15807320e40SRui Ueyama template <class ELFT>
15907320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) {
160e0be2901SRui Ueyama   for (InputSectionDescription *ID : Opt.KeptSections)
161e0be2901SRui Ueyama     if (ID->FilePat.match(basename(S)))
162cf43f179SEugene Leviant       for (SectionPattern &P : ID->SectionPatterns)
163f91282e1SRui Ueyama         if (P.SectionPat.match(S->Name))
164eea3114fSGeorge Rimar           return true;
165eea3114fSGeorge Rimar   return false;
166eea3114fSGeorge Rimar }
167eea3114fSGeorge Rimar 
168575208caSGeorge Rimar static bool comparePriority(InputSectionData *A, InputSectionData *B) {
169575208caSGeorge Rimar   return getPriority(A->Name) < getPriority(B->Name);
170575208caSGeorge Rimar }
171575208caSGeorge Rimar 
172c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) {
173042a3f20SRafael Espindola   return A->Name < B->Name;
1740702c4e8SGeorge Rimar }
175742c3836SRui Ueyama 
176c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) {
177742c3836SRui Ueyama   // ">" is not a mistake. Larger alignments are placed before smaller
178742c3836SRui Ueyama   // alignments in order to reduce the amount of padding necessary.
179742c3836SRui Ueyama   // This is compatible with GNU.
180742c3836SRui Ueyama   return A->Alignment > B->Alignment;
181742c3836SRui Ueyama }
182742c3836SRui Ueyama 
183c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)>
184be394db3SGeorge Rimar getComparator(SortSectionPolicy K) {
185be394db3SGeorge Rimar   switch (K) {
186be394db3SGeorge Rimar   case SortSectionPolicy::Alignment:
187c0028d3dSRafael Espindola     return compareAlignment;
188be394db3SGeorge Rimar   case SortSectionPolicy::Name:
189be394db3SGeorge Rimar     return compareName;
190be394db3SGeorge Rimar   case SortSectionPolicy::Priority:
191be394db3SGeorge Rimar     return comparePriority;
192be394db3SGeorge Rimar   default:
193be394db3SGeorge Rimar     llvm_unreachable("unknown sort policy");
194be394db3SGeorge Rimar   }
195742c3836SRui Ueyama }
1960702c4e8SGeorge Rimar 
19748c3f1ceSRui Ueyama template <class ELFT>
198e71a3f8aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections,
19906ae6836SGeorge Rimar                              ConstraintKind Kind) {
2008f66df92SGeorge Rimar   if (Kind == ConstraintKind::NoConstraint)
2018f66df92SGeorge Rimar     return true;
202e746e52cSRafael Espindola   bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) {
203d3190795SRafael Espindola     auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2);
2041854a8ebSRafael Espindola     return Sec->Flags & SHF_WRITE;
20506ae6836SGeorge Rimar   });
206e746e52cSRafael Espindola   return (IsRW && Kind == ConstraintKind::ReadWrite) ||
207e746e52cSRafael Espindola          (!IsRW && Kind == ConstraintKind::ReadOnly);
20806ae6836SGeorge Rimar }
20906ae6836SGeorge Rimar 
21007171f21SGeorge Rimar static void sortSections(InputSectionData **Begin, InputSectionData **End,
211ee924709SRui Ueyama                          SortSectionPolicy K) {
212ee924709SRui Ueyama   if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
21307171f21SGeorge Rimar     std::stable_sort(Begin, End, getComparator(K));
214ee924709SRui Ueyama }
215ee924709SRui Ueyama 
216d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches.
217be94e1b6SRafael Espindola template <class ELFT>
218e71a3f8aSRafael Espindola void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) {
2194dc07becSRui Ueyama   // Collects all sections that satisfy constraints of I
2204dc07becSRui Ueyama   // and attach them to I.
2214dc07becSRui Ueyama   for (SectionPattern &Pat : I->SectionPatterns) {
22207171f21SGeorge Rimar     size_t SizeBefore = I->Sections.size();
2238c6a5aafSRui Ueyama 
2248c6a5aafSRui Ueyama     for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) {
225f94efdddSRui Ueyama       if (!S->Live || S->Assigned)
2268c6a5aafSRui Ueyama         continue;
2278c6a5aafSRui Ueyama 
228e0be2901SRui Ueyama       StringRef Filename = basename(S);
229e0be2901SRui Ueyama       if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename))
230e0be2901SRui Ueyama         continue;
231e0be2901SRui Ueyama       if (!Pat.SectionPat.match(S->Name))
232e0be2901SRui Ueyama         continue;
233d3190795SRafael Espindola       I->Sections.push_back(S);
234f94efdddSRui Ueyama       S->Assigned = true;
235f94efdddSRui Ueyama     }
236d3190795SRafael Espindola 
237ee924709SRui Ueyama     // Sort sections as instructed by SORT-family commands and --sort-section
238ee924709SRui Ueyama     // option. Because SORT-family commands can be nested at most two depth
239ee924709SRui Ueyama     // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
240ee924709SRui Ueyama     // line option is respected even if a SORT command is given, the exact
241ee924709SRui Ueyama     // behavior we have here is a bit complicated. Here are the rules.
242ee924709SRui Ueyama     //
243ee924709SRui Ueyama     // 1. If two SORT commands are given, --sort-section is ignored.
244ee924709SRui Ueyama     // 2. If one SORT command is given, and if it is not SORT_NONE,
245ee924709SRui Ueyama     //    --sort-section is handled as an inner SORT command.
246ee924709SRui Ueyama     // 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
247ee924709SRui Ueyama     // 4. If no SORT command is given, sort according to --sort-section.
24807171f21SGeorge Rimar     InputSectionData **Begin = I->Sections.data() + SizeBefore;
24907171f21SGeorge Rimar     InputSectionData **End = I->Sections.data() + I->Sections.size();
25007171f21SGeorge Rimar     if (Pat.SortOuter != SortSectionPolicy::None) {
25107171f21SGeorge Rimar       if (Pat.SortInner == SortSectionPolicy::Default)
25207171f21SGeorge Rimar         sortSections(Begin, End, Config->SortSection);
253ee924709SRui Ueyama       else
25407171f21SGeorge Rimar         sortSections(Begin, End, Pat.SortInner);
25507171f21SGeorge Rimar       sortSections(Begin, End, Pat.SortOuter);
25607171f21SGeorge Rimar     }
257ee924709SRui Ueyama   }
258be94e1b6SRafael Espindola }
259be94e1b6SRafael Espindola 
260be94e1b6SRafael Espindola template <class ELFT>
261be94e1b6SRafael Espindola void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) {
262be94e1b6SRafael Espindola   for (InputSectionBase<ELFT> *S : V) {
263be94e1b6SRafael Espindola     S->Live = false;
264be94e1b6SRafael Espindola     reportDiscarded(S);
265be94e1b6SRafael Espindola   }
266be94e1b6SRafael Espindola }
267be94e1b6SRafael Espindola 
26806ae6836SGeorge Rimar template <class ELFT>
2690b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *>
27006ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
2710b9ce6a4SRui Ueyama   std::vector<InputSectionBase<ELFT> *> Ret;
272e7f912cdSRui Ueyama 
27306ae6836SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) {
2747c3ff2ebSRafael Espindola     auto *Cmd = dyn_cast<InputSectionDescription>(Base.get());
2757c3ff2ebSRafael Espindola     if (!Cmd)
2760b9ce6a4SRui Ueyama       continue;
277e71a3f8aSRafael Espindola     computeInputSections(Cmd);
278d3190795SRafael Espindola     for (InputSectionData *S : Cmd->Sections)
279d3190795SRafael Espindola       Ret.push_back(static_cast<InputSectionBase<ELFT> *>(S));
2800b9ce6a4SRui Ueyama   }
281e71a3f8aSRafael Espindola 
2820b9ce6a4SRui Ueyama   return Ret;
2830b9ce6a4SRui Ueyama }
2840b9ce6a4SRui Ueyama 
285e5d3ca50SPetr Hosek template <class ELFT>
28620d03194SEugene Leviant void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory,
28720d03194SEugene Leviant                                     InputSectionBase<ELFT> *Sec,
28820d03194SEugene Leviant                                     StringRef Name) {
289e08e78dfSRafael Espindola   OutputSectionBase *OutSec;
29028c1597aSRafael Espindola   bool IsNew;
29133713983SRafael Espindola   std::tie(OutSec, IsNew) = Factory.create(Sec, Name);
29228c1597aSRafael Espindola   if (IsNew)
29328c1597aSRafael Espindola     OutputSections->push_back(OutSec);
29420d03194SEugene Leviant   OutSec->addSection(Sec);
29520d03194SEugene Leviant }
29620d03194SEugene Leviant 
29720d03194SEugene Leviant template <class ELFT>
29820d03194SEugene Leviant void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
2997c3ff2ebSRafael Espindola   for (unsigned I = 0; I < Opt.Commands.size(); ++I) {
3007c3ff2ebSRafael Espindola     auto Iter = Opt.Commands.begin() + I;
3017c3ff2ebSRafael Espindola     const std::unique_ptr<BaseCommand> &Base1 = *Iter;
3020b1b695aSRui Ueyama 
3030b1b695aSRui Ueyama     // Handle symbol assignments outside of any output section.
3042ab5f73dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) {
305b0de56b5SRafael Espindola       addSymbol<ELFT>(Cmd);
3062ab5f73dSRui Ueyama       continue;
3072ab5f73dSRui Ueyama     }
3080b1b695aSRui Ueyama 
30920d03194SEugene Leviant     if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) {
31020d03194SEugene Leviant       // If we don't have SECTIONS then output sections have already been
311194470cdSGeorge Rimar       // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses
31220d03194SEugene Leviant       // will not be called, so ASSERT should be evaluated now.
31320d03194SEugene Leviant       if (!Opt.HasSections)
31420d03194SEugene Leviant         Cmd->Expression(0);
31520d03194SEugene Leviant       continue;
31620d03194SEugene Leviant     }
3172ab5f73dSRui Ueyama 
318ceabe80eSEugene Leviant     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) {
3197bd37870SRafael Espindola       std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd);
3207bd37870SRafael Espindola 
3210b1b695aSRui Ueyama       // The output section name `/DISCARD/' is special.
3220b1b695aSRui Ueyama       // Any input section assigned to it is discarded.
32348c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
3247bd37870SRafael Espindola         discard(V);
32548c3f1ceSRui Ueyama         continue;
32648c3f1ceSRui Ueyama       }
3270b9ce6a4SRui Ueyama 
3280b1b695aSRui Ueyama       // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
3290b1b695aSRui Ueyama       // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
3300b1b695aSRui Ueyama       // sections satisfy a given constraint. If not, a directive is handled
3310b1b695aSRui Ueyama       // as if it wasn't present from the beginning.
3320b1b695aSRui Ueyama       //
3330b1b695aSRui Ueyama       // Because we'll iterate over Commands many more times, the easiest
3340b1b695aSRui Ueyama       // way to "make it as if it wasn't present" is to just remove it.
3357c3ff2ebSRafael Espindola       if (!matchConstraints<ELFT>(V, Cmd->Constraint)) {
3367c3ff2ebSRafael Espindola         for (InputSectionBase<ELFT> *S : V)
337f94efdddSRui Ueyama           S->Assigned = false;
3387c3ff2ebSRafael Espindola         Opt.Commands.erase(Iter);
339dfbbbc86SGeorge Rimar         --I;
3407c3ff2ebSRafael Espindola         continue;
3417c3ff2ebSRafael Espindola       }
3427c3ff2ebSRafael Espindola 
3430b1b695aSRui Ueyama       // A directive may contain symbol definitions like this:
3440b1b695aSRui Ueyama       // ".foo : { ...; bar = .; }". Handle them.
3457c3ff2ebSRafael Espindola       for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands)
3467c3ff2ebSRafael Espindola         if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get()))
3477c3ff2ebSRafael Espindola           addSymbol<ELFT>(OutCmd);
3487c3ff2ebSRafael Espindola 
3490b1b695aSRui Ueyama       // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
3500b1b695aSRui Ueyama       // is given, input sections are aligned to that value, whether the
3510b1b695aSRui Ueyama       // given value is larger or smaller than the original section alignment.
3520b1b695aSRui Ueyama       if (Cmd->SubalignExpr) {
3530b1b695aSRui Ueyama         uint32_t Subalign = Cmd->SubalignExpr(0);
3540b1b695aSRui Ueyama         for (InputSectionBase<ELFT> *S : V)
3550b1b695aSRui Ueyama           S->Alignment = Subalign;
35620d03194SEugene Leviant       }
3570b1b695aSRui Ueyama 
3580b1b695aSRui Ueyama       // Add input sections to an output section.
3590b1b695aSRui Ueyama       for (InputSectionBase<ELFT> *S : V)
3600b1b695aSRui Ueyama         addSection(Factory, S, Cmd->Name);
361eea3114fSGeorge Rimar     }
36248c3f1ceSRui Ueyama   }
363db24d9c3SGeorge Rimar }
364e63d81bdSEugene Leviant 
3650b1b695aSRui Ueyama // Add sections that didn't match any sections command.
36620d03194SEugene Leviant template <class ELFT>
36793c64025SGeorge Rimar void LinkerScript<ELFT>::addOrphanSections(
36893c64025SGeorge Rimar     OutputSectionFactory<ELFT> &Factory) {
3698c6a5aafSRui Ueyama   for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections)
3708f9026baSRafael Espindola     if (S->Live && !S->OutSec)
37155518e7dSRui Ueyama       addSection(Factory, S, getOutputSectionName(S->Name));
372e63d81bdSEugene Leviant }
373e63d81bdSEugene Leviant 
374db741e72SEugene Leviant // Sets value of a section-defined symbol. Two kinds of
375db741e72SEugene Leviant // symbols are processed: synthetic symbols, whose value
376db741e72SEugene Leviant // is an offset from beginning of section and regular
377db741e72SEugene Leviant // symbols whose value is absolute.
378db741e72SEugene Leviant template <class ELFT>
379afaa9343SEugene Leviant static void assignSectionSymbol(SymbolAssignment *Cmd,
380498ed714SRafael Espindola                                 typename ELFT::uint Value) {
381db741e72SEugene Leviant   if (!Cmd->Sym)
382db741e72SEugene Leviant     return;
383db741e72SEugene Leviant 
3844f2f50dcSRui Ueyama   if (auto *Body = dyn_cast<DefinedSynthetic>(Cmd->Sym)) {
385afaa9343SEugene Leviant     Body->Section = Cmd->Expression.Section();
386afaa9343SEugene Leviant     Body->Value = Cmd->Expression(Value) - Body->Section->Addr;
387db741e72SEugene Leviant     return;
388db741e72SEugene Leviant   }
389db741e72SEugene Leviant   auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym);
390498ed714SRafael Espindola   Body->Value = Cmd->Expression(Value);
391db741e72SEugene Leviant }
392db741e72SEugene Leviant 
393e08e78dfSRafael Espindola template <class ELFT> static bool isTbss(OutputSectionBase *Sec) {
39404a2e348SRafael Espindola   return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
395a940e539SRafael Espindola }
396a940e539SRafael Espindola 
397d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) {
398d3190795SRafael Espindola   if (!AlreadyOutputIS.insert(S).second)
399ceabe80eSEugene Leviant     return;
400e08e78dfSRafael Espindola   bool IsTbss = isTbss<ELFT>(CurOutSec);
401d3190795SRafael Espindola 
402d3190795SRafael Espindola   uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot;
403d3190795SRafael Espindola   Pos = alignTo(Pos, S->Alignment);
40404a2e348SRafael Espindola   S->OutSecOff = Pos - CurOutSec->Addr;
405d3190795SRafael Espindola   Pos += S->getSize();
406d3190795SRafael Espindola 
407d3190795SRafael Espindola   // Update output section size after adding each section. This is so that
408d3190795SRafael Espindola   // SIZEOF works correctly in the case below:
409d3190795SRafael Espindola   // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
41004a2e348SRafael Espindola   CurOutSec->Size = Pos - CurOutSec->Addr;
411d3190795SRafael Espindola 
412b889744eSMeador Inge   // If there is a memory region associated with this input section, then
413b889744eSMeador Inge   // place the section in that region and update the region index.
414b889744eSMeador Inge   if (CurMemRegion) {
415b889744eSMeador Inge     CurMemRegion->Offset += CurOutSec->Size;
416b889744eSMeador Inge     uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin;
417b889744eSMeador Inge     if (CurSize > CurMemRegion->Length) {
418b889744eSMeador Inge       uint64_t OverflowAmt = CurSize - CurMemRegion->Length;
419b889744eSMeador Inge       error("section '" + CurOutSec->Name + "' will not fit in region '" +
420b889744eSMeador Inge             CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
421b889744eSMeador Inge             " bytes");
422b889744eSMeador Inge     }
423b889744eSMeador Inge   }
424b889744eSMeador Inge 
4257252ae52SRafael Espindola   if (IsTbss)
4267252ae52SRafael Espindola     ThreadBssOffset = Pos - Dot;
4277252ae52SRafael Espindola   else
428d3190795SRafael Espindola     Dot = Pos;
4292de509c3SRui Ueyama }
430ceabe80eSEugene Leviant 
431d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::flush() {
43265499b90SRafael Espindola   if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second)
43365499b90SRafael Espindola     return;
43465499b90SRafael Espindola   if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) {
435d3190795SRafael Espindola     for (InputSection<ELFT> *I : OutSec->Sections)
436d3190795SRafael Espindola       output(I);
43765499b90SRafael Espindola   } else {
43804a2e348SRafael Espindola     Dot += CurOutSec->Size;
439d3190795SRafael Espindola   }
440d3190795SRafael Espindola }
44197403d15SEugene Leviant 
442d3190795SRafael Espindola template <class ELFT>
443e08e78dfSRafael Espindola void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) {
444d3190795SRafael Espindola   if (CurOutSec == Sec)
445d3190795SRafael Espindola     return;
446d3190795SRafael Espindola   if (AlreadyOutputOS.count(Sec))
447d3190795SRafael Espindola     return;
448d3190795SRafael Espindola 
449d3190795SRafael Espindola   flush();
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
459b71d6f7aSEugene Leviant   CurOutSec->setLMAOffset(LMAOffset);
460d3190795SRafael Espindola }
461d3190795SRafael Espindola 
462d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) {
463e38cbab5SGeorge Rimar   // This handles the assignments to symbol or to a location counter (.)
464d3190795SRafael Espindola   if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) {
46597403d15SEugene Leviant     if (AssignCmd->Name == ".") {
46697403d15SEugene Leviant       // Update to location counter means update to section size.
46714460e02SGeorge Rimar       uintX_t Val = AssignCmd->Expression(Dot);
46814460e02SGeorge Rimar       if (Val < Dot)
46914460e02SGeorge Rimar         error("unable to move location counter backward for: " +
47014460e02SGeorge Rimar               CurOutSec->Name);
47114460e02SGeorge Rimar       Dot = Val;
47204a2e348SRafael Espindola       CurOutSec->Size = Dot - CurOutSec->Addr;
473d3190795SRafael Espindola       return;
47497403d15SEugene Leviant     }
475afaa9343SEugene Leviant     assignSectionSymbol<ELFT>(AssignCmd, Dot);
476d3190795SRafael Espindola     return;
47797403d15SEugene Leviant   }
478e38cbab5SGeorge Rimar 
479e38cbab5SGeorge Rimar   // Handle BYTE(), SHORT(), LONG(), or QUAD().
480e38cbab5SGeorge Rimar   if (auto *DataCmd = dyn_cast<BytesDataCommand>(&Base)) {
48104a2e348SRafael Espindola     DataCmd->Offset = Dot - CurOutSec->Addr;
482e38cbab5SGeorge Rimar     Dot += DataCmd->Size;
48304a2e348SRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
484e38cbab5SGeorge Rimar     return;
485e38cbab5SGeorge Rimar   }
486e38cbab5SGeorge Rimar 
487b2d99d6aSMeador Inge   if (auto *AssertCmd = dyn_cast<AssertCommand>(&Base)) {
488b2d99d6aSMeador Inge     AssertCmd->Expression(Dot);
489b2d99d6aSMeador Inge     return;
490b2d99d6aSMeador Inge   }
491b2d99d6aSMeador Inge 
492e38cbab5SGeorge Rimar   // It handles single input section description command,
493e38cbab5SGeorge Rimar   // calculates and assigns the offsets for each section and also
494e38cbab5SGeorge Rimar   // updates the output section size.
495d3190795SRafael Espindola   auto &ICmd = cast<InputSectionDescription>(Base);
496d3190795SRafael Espindola   for (InputSectionData *ID : ICmd.Sections) {
4973fb5a6dcSGeorge Rimar     // We tentatively added all synthetic sections at the beginning and removed
4983fb5a6dcSGeorge Rimar     // empty ones afterwards (because there is no way to know whether they were
4993fb5a6dcSGeorge Rimar     // going be empty or not other than actually running linker scripts.)
5003fb5a6dcSGeorge Rimar     // We need to ignore remains of empty sections.
5013fb5a6dcSGeorge Rimar     if (auto *Sec = dyn_cast<SyntheticSection<ELFT>>(ID))
5023fb5a6dcSGeorge Rimar       if (Sec->empty())
5033fb5a6dcSGeorge Rimar         continue;
5043fb5a6dcSGeorge Rimar 
505d3190795SRafael Espindola     auto *IB = static_cast<InputSectionBase<ELFT> *>(ID);
506d3190795SRafael Espindola     switchTo(IB->OutSec);
507d3190795SRafael Espindola     if (auto *I = dyn_cast<InputSection<ELFT>>(IB))
508d3190795SRafael Espindola       output(I);
50965499b90SRafael Espindola     else
51065499b90SRafael Espindola       flush();
511ceabe80eSEugene Leviant   }
512ceabe80eSEugene Leviant }
513ceabe80eSEugene Leviant 
5148f66df92SGeorge Rimar template <class ELFT>
515e08e78dfSRafael Espindola static std::vector<OutputSectionBase *>
516e08e78dfSRafael Espindola findSections(StringRef Name, const std::vector<OutputSectionBase *> &Sections) {
517e08e78dfSRafael Espindola   std::vector<OutputSectionBase *> Ret;
518e08e78dfSRafael Espindola   for (OutputSectionBase *Sec : Sections)
5199257764dSEugene Leviant     if (Sec->getName() == Name)
520a14b13d8SGeorge Rimar       Ret.push_back(Sec);
521a14b13d8SGeorge Rimar   return Ret;
5228f66df92SGeorge Rimar }
5238f66df92SGeorge Rimar 
524b889744eSMeador Inge // This function searches for a memory region to place the given output
525b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is
526b889744eSMeador Inge // returned. Otherwise, a nullptr is returned.
527b889744eSMeador Inge template <class ELFT>
528b889744eSMeador Inge MemoryRegion *LinkerScript<ELFT>::findMemoryRegion(OutputSectionCommand *Cmd,
529b889744eSMeador Inge                                                    OutputSectionBase *Sec) {
530b889744eSMeador Inge   // If a memory region name was specified in the output section command,
531b889744eSMeador Inge   // then try to find that region first.
532b889744eSMeador Inge   if (!Cmd->MemoryRegionName.empty()) {
533b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
534b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
535b889744eSMeador Inge       return &It->second;
536b889744eSMeador Inge     error("memory region '" + Cmd->MemoryRegionName + "' not declared");
537b889744eSMeador Inge     return nullptr;
538b889744eSMeador Inge   }
539b889744eSMeador Inge 
540b889744eSMeador Inge   // The memory region name is empty, thus a suitable region must be
541b889744eSMeador Inge   // searched for in the region map. If the region map is empty, just
542b889744eSMeador Inge   // return. Note that this check doesn't happen at the very beginning
543b889744eSMeador Inge   // so that uses of undeclared regions can be caught.
544b889744eSMeador Inge   if (!Opt.MemoryRegions.size())
545b889744eSMeador Inge     return nullptr;
546b889744eSMeador Inge 
547b889744eSMeador Inge   // See if a region can be found by matching section flags.
548b889744eSMeador Inge   for (auto &MRI : Opt.MemoryRegions) {
549b889744eSMeador Inge     MemoryRegion &MR = MRI.second;
550*8a8a953eSRui Ueyama     if ((MR.Flags & Sec->Flags) != 0 && (MR.NegFlags & Sec->Flags) == 0)
551b889744eSMeador Inge       return &MR;
552b889744eSMeador Inge   }
553b889744eSMeador Inge 
554b889744eSMeador Inge   // Otherwise, no suitable region was found.
555b889744eSMeador Inge   if (Sec->Flags & SHF_ALLOC)
556b889744eSMeador Inge     error("no memory region specified for section '" + Sec->Name + "'");
557b889744eSMeador Inge   return nullptr;
558b889744eSMeador Inge }
559b889744eSMeador Inge 
5600b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section
5610b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }").
562d3190795SRafael Espindola template <class ELFT>
563d3190795SRafael Espindola void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) {
564b71d6f7aSEugene Leviant   if (Cmd->LMAExpr)
565b71d6f7aSEugene Leviant     LMAOffset = Cmd->LMAExpr(Dot) - Dot;
566e08e78dfSRafael Espindola   std::vector<OutputSectionBase *> Sections =
567e08e78dfSRafael Espindola       findSections<ELFT>(Cmd->Name, *OutputSections);
568d3190795SRafael Espindola   if (Sections.empty())
569d3190795SRafael Espindola     return;
570b889744eSMeador Inge 
571b889744eSMeador Inge   OutputSectionBase *Sec = Sections[0];
572b889744eSMeador Inge   // Try and find an appropriate memory region to assign offsets in.
573b889744eSMeador Inge   CurMemRegion = findMemoryRegion(Cmd, Sec);
574b889744eSMeador Inge   if (CurMemRegion)
575b889744eSMeador Inge     Dot = CurMemRegion->Offset;
576b889744eSMeador Inge   switchTo(Sec);
5770b1b695aSRui Ueyama 
578d3190795SRafael Espindola   // Find the last section output location. We will output orphan sections
579d3190795SRafael Espindola   // there so that end symbols point to the correct location.
580d3190795SRafael Espindola   auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(),
581d3190795SRafael Espindola                         [](const std::unique_ptr<BaseCommand> &Cmd) {
582d3190795SRafael Espindola                           return !isa<SymbolAssignment>(*Cmd);
583d3190795SRafael Espindola                         })
584d3190795SRafael Espindola                .base();
585d3190795SRafael Espindola   for (auto I = Cmd->Commands.begin(); I != E; ++I)
586d3190795SRafael Espindola     process(**I);
587e08e78dfSRafael Espindola   for (OutputSectionBase *Base : Sections)
588d3190795SRafael Espindola     switchTo(Base);
5892506cb4dSEugene Leviant   flush();
590b31dd370SGeorge Rimar   std::for_each(E, Cmd->Commands.end(),
591b31dd370SGeorge Rimar                 [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); });
592d3190795SRafael Espindola }
593d3190795SRafael Espindola 
59407fe6129SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::removeEmptyCommands() {
5956d38e4dbSRafael Espindola   // It is common practice to use very generic linker scripts. So for any
5966d38e4dbSRafael Espindola   // given run some of the output sections in the script will be empty.
5976d38e4dbSRafael Espindola   // We could create corresponding empty output sections, but that would
5986d38e4dbSRafael Espindola   // clutter the output.
5996d38e4dbSRafael Espindola   // We instead remove trivially empty sections. The bfd linker seems even
6006d38e4dbSRafael Espindola   // more aggressive at removing them.
6016d38e4dbSRafael Espindola   auto Pos = std::remove_if(
6026d38e4dbSRafael Espindola       Opt.Commands.begin(), Opt.Commands.end(),
6036d38e4dbSRafael Espindola       [&](const std::unique_ptr<BaseCommand> &Base) {
6040b1b695aSRui Ueyama         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
6056a53737cSRafael Espindola           return findSections<ELFT>(Cmd->Name, *OutputSections).empty();
6060b1b695aSRui Ueyama         return false;
6076d38e4dbSRafael Espindola       });
6086d38e4dbSRafael Espindola   Opt.Commands.erase(Pos, Opt.Commands.end());
60907fe6129SRafael Espindola }
61007fe6129SRafael Espindola 
6116a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
6126a53737cSRafael Espindola   for (const std::unique_ptr<BaseCommand> &I : Cmd.Commands)
6136a53737cSRafael Espindola     if (!isa<InputSectionDescription>(*I))
6146a53737cSRafael Espindola       return false;
6156a53737cSRafael Espindola   return true;
6166a53737cSRafael Espindola }
6176d38e4dbSRafael Espindola 
6186a53737cSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() {
6199546fffbSRafael Espindola   // If the output section contains only symbol assignments, create a
6209546fffbSRafael Espindola   // corresponding output section. The bfd linker seems to only create them if
6219546fffbSRafael Espindola   // '.' is assigned to, but creating these section should not have any bad
6229546fffbSRafael Espindola   // consequeces and gives us a section to put the symbol in.
6239546fffbSRafael Espindola   uintX_t Flags = SHF_ALLOC;
624f93b8c29SRafael Espindola   uint32_t Type = SHT_NOBITS;
6259546fffbSRafael Espindola   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
6269546fffbSRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
6279546fffbSRafael Espindola     if (!Cmd)
6289546fffbSRafael Espindola       continue;
629e08e78dfSRafael Espindola     std::vector<OutputSectionBase *> Secs =
630e08e78dfSRafael Espindola         findSections<ELFT>(Cmd->Name, *OutputSections);
6319546fffbSRafael Espindola     if (!Secs.empty()) {
63204a2e348SRafael Espindola       Flags = Secs[0]->Flags;
63304a2e348SRafael Espindola       Type = Secs[0]->Type;
6349546fffbSRafael Espindola       continue;
6359546fffbSRafael Espindola     }
6369546fffbSRafael Espindola 
6376a53737cSRafael Espindola     if (isAllSectionDescription(*Cmd))
6386a53737cSRafael Espindola       continue;
6396a53737cSRafael Espindola 
64095642b95SRui Ueyama     auto *OutSec = make<OutputSection<ELFT>>(Cmd->Name, Type, Flags);
6419546fffbSRafael Espindola     OutputSections->push_back(OutSec);
6429546fffbSRafael Espindola   }
643f7a17448SRafael Espindola }
644f7a17448SRafael Espindola 
645f7a17448SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsAfterSorting() {
646f7a17448SRafael Espindola   placeOrphanSections();
647f7a17448SRafael Espindola 
648f7a17448SRafael Espindola   // If output section command doesn't specify any segments,
649f7a17448SRafael Espindola   // and we haven't previously assigned any section to segment,
650f7a17448SRafael Espindola   // then we simply assign section to the very first load segment.
651f7a17448SRafael Espindola   // Below is an example of such linker script:
652f7a17448SRafael Espindola   // PHDRS { seg PT_LOAD; }
653f7a17448SRafael Espindola   // SECTIONS { .aaa : { *(.aaa) } }
654f7a17448SRafael Espindola   std::vector<StringRef> DefPhdrs;
655f7a17448SRafael Espindola   auto FirstPtLoad =
656f7a17448SRafael Espindola       std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(),
657f7a17448SRafael Espindola                    [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; });
658f7a17448SRafael Espindola   if (FirstPtLoad != Opt.PhdrsCommands.end())
659f7a17448SRafael Espindola     DefPhdrs.push_back(FirstPtLoad->Name);
660f7a17448SRafael Espindola 
661f7a17448SRafael Espindola   // Walk the commands and propagate the program headers to commands that don't
662f7a17448SRafael Espindola   // explicitly specify them.
663f7a17448SRafael Espindola   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
664f7a17448SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
665f7a17448SRafael Espindola     if (!Cmd)
666f7a17448SRafael Espindola       continue;
667f7a17448SRafael Espindola     if (Cmd->Phdrs.empty())
668f7a17448SRafael Espindola       Cmd->Phdrs = DefPhdrs;
669f7a17448SRafael Espindola     else
670f7a17448SRafael Espindola       DefPhdrs = Cmd->Phdrs;
671f7a17448SRafael Espindola   }
6726a53737cSRafael Espindola 
6736a53737cSRafael Espindola   removeEmptyCommands();
6749546fffbSRafael Espindola }
6759546fffbSRafael Espindola 
67615c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments
67715c57951SRafael Espindola // so that an orphan after
67815c57951SRafael Espindola //   begin_foo = .;
67915c57951SRafael Espindola //   foo : { *(foo) }
68015c57951SRafael Espindola //   end_foo = .;
68115c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols.
68215c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the
68315c57951SRafael Espindola // one in charge of deciding the order of the sections.
68415c57951SRafael Espindola // We don't want to go over alignments, since doing so in
68515c57951SRafael Espindola //  rx_sec : { *(rx_sec) }
68615c57951SRafael Espindola //  . = ALIGN(0x1000);
68715c57951SRafael Espindola //  /* The RW PT_LOAD starts here*/
68815c57951SRafael Espindola //  rw_sec : { *(rw_sec) }
68915c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned.
6905fcc99c2SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) {
69115c57951SRafael Espindola   if (isa<OutputSectionCommand>(Cmd))
69215c57951SRafael Espindola     return false;
69315c57951SRafael Espindola   const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd);
69415c57951SRafael Espindola   if (!Assign)
69515c57951SRafael Espindola     return true;
6965fcc99c2SRafael Espindola   return Assign->Name != ".";
69715c57951SRafael Espindola }
69815c57951SRafael Espindola 
699337f903cSRafael Espindola // Orphan sections are sections present in the input files which are not
700337f903cSRafael Espindola // explicitly placed into the output file by the linker script. This just
701337f903cSRafael Espindola // places them in the order already decided in OutputSections.
70293c64025SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::placeOrphanSections() {
703aab6d5c5SRafael Espindola   // The OutputSections are already in the correct order.
704aab6d5c5SRafael Espindola   // This loops creates or moves commands as needed so that they are in the
705aab6d5c5SRafael Espindola   // correct order.
706aab6d5c5SRafael Espindola   int CmdIndex = 0;
7075fcc99c2SRafael Espindola 
7085fcc99c2SRafael Espindola   // As a horrible special case, skip the first . assignment if it is before any
7095fcc99c2SRafael Espindola   // section. We do this because it is common to set a load address by starting
7105fcc99c2SRafael Espindola   // the script with ". = 0xabcd" and the expectation is that every section is
7115fcc99c2SRafael Espindola   // after that.
7125fcc99c2SRafael Espindola   auto FirstSectionOrDotAssignment =
7135fcc99c2SRafael Espindola       std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
7145fcc99c2SRafael Espindola                    [](const std::unique_ptr<BaseCommand> &Cmd) {
7155fcc99c2SRafael Espindola                      if (isa<OutputSectionCommand>(*Cmd))
7165fcc99c2SRafael Espindola                        return true;
7175fcc99c2SRafael Espindola                      const auto *Assign = dyn_cast<SymbolAssignment>(Cmd.get());
7185fcc99c2SRafael Espindola                      if (!Assign)
7195fcc99c2SRafael Espindola                        return false;
7205fcc99c2SRafael Espindola                      return Assign->Name == ".";
7215fcc99c2SRafael Espindola                    });
7225fcc99c2SRafael Espindola   if (FirstSectionOrDotAssignment != Opt.Commands.end()) {
7235fcc99c2SRafael Espindola     CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin();
7245fcc99c2SRafael Espindola     if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
7255fcc99c2SRafael Espindola       ++CmdIndex;
7265fcc99c2SRafael Espindola   }
7275fcc99c2SRafael Espindola 
728e08e78dfSRafael Espindola   for (OutputSectionBase *Sec : *OutputSections) {
729652852c5SGeorge Rimar     StringRef Name = Sec->getName();
730aab6d5c5SRafael Espindola 
731aab6d5c5SRafael Espindola     // Find the last spot where we can insert a command and still get the
73215c57951SRafael Espindola     // correct result.
733aab6d5c5SRafael Espindola     auto CmdIter = Opt.Commands.begin() + CmdIndex;
734aab6d5c5SRafael Espindola     auto E = Opt.Commands.end();
7355fcc99c2SRafael Espindola     while (CmdIter != E && shouldSkip(**CmdIter)) {
736aab6d5c5SRafael Espindola       ++CmdIter;
737aab6d5c5SRafael Espindola       ++CmdIndex;
738aab6d5c5SRafael Espindola     }
739aab6d5c5SRafael Espindola 
740aab6d5c5SRafael Espindola     auto Pos =
741aab6d5c5SRafael Espindola         std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) {
742aab6d5c5SRafael Espindola           auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
743aab6d5c5SRafael Espindola           return Cmd && Cmd->Name == Name;
744aab6d5c5SRafael Espindola         });
745aab6d5c5SRafael Espindola     if (Pos == E) {
746aab6d5c5SRafael Espindola       Opt.Commands.insert(CmdIter,
747aab6d5c5SRafael Espindola                           llvm::make_unique<OutputSectionCommand>(Name));
748aab6d5c5SRafael Espindola       ++CmdIndex;
74915c57951SRafael Espindola       continue;
75015c57951SRafael Espindola     }
75115c57951SRafael Espindola 
75215c57951SRafael Espindola     // Continue from where we found it.
75315c57951SRafael Espindola     CmdIndex = (Pos - Opt.Commands.begin()) + 1;
754652852c5SGeorge Rimar   }
755337f903cSRafael Espindola }
756337f903cSRafael Espindola 
757337f903cSRafael Espindola template <class ELFT>
75817cb7c0aSRafael Espindola void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
7597c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
760be607334SRafael Espindola   Dot = 0;
761652852c5SGeorge Rimar 
762076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
763076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
7648d083e6aSRui Ueyama       if (Cmd->Name == ".") {
7658d083e6aSRui Ueyama         Dot = Cmd->Expression(Dot);
7668d083e6aSRui Ueyama       } else if (Cmd->Sym) {
767afaa9343SEugene Leviant         assignSectionSymbol<ELFT>(Cmd, Dot);
7688d083e6aSRui Ueyama       }
76905ef4cffSRui Ueyama       continue;
770652852c5SGeorge Rimar     }
771652852c5SGeorge Rimar 
772eefa758eSGeorge Rimar     if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) {
773eefa758eSGeorge Rimar       Cmd->Expression(Dot);
774eefa758eSGeorge Rimar       continue;
775eefa758eSGeorge Rimar     }
776eefa758eSGeorge Rimar 
777076fe157SGeorge Rimar     auto *Cmd = cast<OutputSectionCommand>(Base.get());
77858e5c4dcSGeorge Rimar     if (Cmd->AddrExpr)
77958e5c4dcSGeorge Rimar       Dot = Cmd->AddrExpr(Dot);
780d3190795SRafael Espindola     assignOffsets(Cmd);
781a14b13d8SGeorge Rimar   }
782467c4d55SEugene Leviant 
783aab6d5c5SRafael Espindola   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
784e08e78dfSRafael Espindola   for (OutputSectionBase *Sec : *OutputSections) {
78504a2e348SRafael Espindola     if (Sec->Flags & SHF_ALLOC)
786e08e78dfSRafael Espindola       MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
787aab6d5c5SRafael Espindola     else
78804a2e348SRafael Espindola       Sec->Addr = 0;
789aab6d5c5SRafael Espindola   }
790aab6d5c5SRafael Espindola 
7918c495e20SRafael Espindola   allocateHeaders<ELFT>(Phdrs, *OutputSections, MinVA);
792fb8978fcSDima Stepanov }
793652852c5SGeorge Rimar 
794464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
79517cb7c0aSRafael Espindola template <class ELFT> std::vector<PhdrEntry> LinkerScript<ELFT>::createPhdrs() {
79617cb7c0aSRafael Espindola   std::vector<PhdrEntry> Ret;
797bbe38602SEugene Leviant 
798464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
799464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
800bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
801edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
80217cb7c0aSRafael Espindola     PhdrEntry &Phdr = Ret.back();
803bbe38602SEugene Leviant 
804bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
805adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ElfHeader);
806bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
807adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ProgramHeaders);
80856b21c86SEugene Leviant 
80956b21c86SEugene Leviant     if (Cmd.LMAExpr) {
81017cb7c0aSRafael Espindola       Phdr.p_paddr = Cmd.LMAExpr(0);
81156b21c86SEugene Leviant       Phdr.HasLMA = true;
81256b21c86SEugene Leviant     }
813bbe38602SEugene Leviant   }
814bbe38602SEugene Leviant 
815464daadcSRui Ueyama   // Add output sections to program headers.
816e08e78dfSRafael Espindola   for (OutputSectionBase *Sec : *OutputSections) {
81704a2e348SRafael Espindola     if (!(Sec->Flags & SHF_ALLOC))
818bbe38602SEugene Leviant       break;
819bbe38602SEugene Leviant 
820bbe38602SEugene Leviant     // Assign headers specified by linker script
821f7a17448SRafael Espindola     for (size_t Id : getPhdrIndices(Sec->getName())) {
822edebbdf1SRui Ueyama       Ret[Id].add(Sec);
823865bf863SEugene Leviant       if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
82417cb7c0aSRafael Espindola         Ret[Id].p_flags |= Sec->getPhdrFlags();
825bbe38602SEugene Leviant     }
826bbe38602SEugene Leviant   }
827edebbdf1SRui Ueyama   return Ret;
828bbe38602SEugene Leviant }
829bbe38602SEugene Leviant 
830f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() {
831f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
832f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
833f9bc3bd2SEugene Leviant   return !Opt.PhdrsCommands.empty() &&
834f9bc3bd2SEugene Leviant          llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) {
835f9bc3bd2SEugene Leviant            return Cmd.Type == PT_INTERP;
836f9bc3bd2SEugene Leviant          }) == Opt.PhdrsCommands.end();
837f9bc3bd2SEugene Leviant }
838f9bc3bd2SEugene Leviant 
83993c64025SGeorge Rimar template <class ELFT> uint32_t LinkerScript<ELFT>::getFiller(StringRef Name) {
840f6c3ccefSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
841f6c3ccefSGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
842f6c3ccefSGeorge Rimar       if (Cmd->Name == Name)
843f6c3ccefSGeorge Rimar         return Cmd->Filler;
84416068aebSRui Ueyama   return 0;
845e2ee72b5SGeorge Rimar }
846e2ee72b5SGeorge Rimar 
847e38cbab5SGeorge Rimar template <class ELFT>
848e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
849e38cbab5SGeorge Rimar   const endianness E = ELFT::TargetEndianness;
850e38cbab5SGeorge Rimar 
851e38cbab5SGeorge Rimar   switch (Size) {
852e38cbab5SGeorge Rimar   case 1:
853e38cbab5SGeorge Rimar     *Buf = (uint8_t)Data;
854e38cbab5SGeorge Rimar     break;
855e38cbab5SGeorge Rimar   case 2:
856e38cbab5SGeorge Rimar     write16<E>(Buf, Data);
857e38cbab5SGeorge Rimar     break;
858e38cbab5SGeorge Rimar   case 4:
859e38cbab5SGeorge Rimar     write32<E>(Buf, Data);
860e38cbab5SGeorge Rimar     break;
861e38cbab5SGeorge Rimar   case 8:
862e38cbab5SGeorge Rimar     write64<E>(Buf, Data);
863e38cbab5SGeorge Rimar     break;
864e38cbab5SGeorge Rimar   default:
865e38cbab5SGeorge Rimar     llvm_unreachable("unsupported Size argument");
866e38cbab5SGeorge Rimar   }
867e38cbab5SGeorge Rimar }
868e38cbab5SGeorge Rimar 
869e38cbab5SGeorge Rimar template <class ELFT>
870e38cbab5SGeorge Rimar void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) {
871e38cbab5SGeorge Rimar   int I = getSectionIndex(Name);
872e38cbab5SGeorge Rimar   if (I == INT_MAX)
873e38cbab5SGeorge Rimar     return;
874e38cbab5SGeorge Rimar 
8756e68c5e5SRui Ueyama   auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get());
8766e68c5e5SRui Ueyama   for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands)
8776e68c5e5SRui Ueyama     if (auto *Data = dyn_cast<BytesDataCommand>(Base.get()))
87895c7d8d2SMeador Inge       writeInt<ELFT>(Buf + Data->Offset, Data->Expression(0), Data->Size);
879e38cbab5SGeorge Rimar }
880e38cbab5SGeorge Rimar 
881b71d6f7aSEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasLMA(StringRef Name) {
8828ceadb38SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
8838ceadb38SGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
884b71d6f7aSEugene Leviant       if (Cmd->LMAExpr && Cmd->Name == Name)
885b71d6f7aSEugene Leviant         return true;
886b71d6f7aSEugene Leviant   return false;
8878ceadb38SGeorge Rimar }
8888ceadb38SGeorge Rimar 
889c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script
890c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they
891c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script,
892c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file.
893076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) {
8946e68c5e5SRui Ueyama   for (int I = 0, E = Opt.Commands.size(); I != E; ++I)
8956e68c5e5SRui Ueyama     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()))
896076fe157SGeorge Rimar       if (Cmd->Name == Name)
897f510fa6bSRui Ueyama         return I;
898f510fa6bSRui Ueyama   return INT_MAX;
89971b26e94SGeorge Rimar }
90071b26e94SGeorge Rimar 
901bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
902bbe38602SEugene Leviant   return !Opt.PhdrsCommands.empty();
903bbe38602SEugene Leviant }
904bbe38602SEugene Leviant 
9059e69450eSGeorge Rimar template <class ELFT>
906ed30ce7aSEugene Leviant const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(const Twine &Loc,
907ed30ce7aSEugene Leviant                                                               StringRef Name) {
908afaa9343SEugene Leviant   static OutputSectionBase FakeSec("", 0, 0);
90996659df0SGeorge Rimar 
910e08e78dfSRafael Espindola   for (OutputSectionBase *Sec : *OutputSections)
911b71d6f7aSEugene Leviant     if (Sec->getName() == Name)
912afaa9343SEugene Leviant       return Sec;
913ed30ce7aSEugene Leviant 
914ed30ce7aSEugene Leviant   error(Loc + ": undefined section " + Name);
915afaa9343SEugene Leviant   return &FakeSec;
91636fac7f0SEugene Leviant }
91736fac7f0SEugene Leviant 
918edf75e79SRui Ueyama // This function is essentially the same as getOutputSection(Name)->Size,
919edf75e79SRui Ueyama // but it won't print out an error message if a given section is not found.
920edf75e79SRui Ueyama //
921edf75e79SRui Ueyama // Linker script does not create an output section if its content is empty.
922edf75e79SRui Ueyama // We want to allow SIZEOF(.foo) where .foo is a section which happened to
923edf75e79SRui Ueyama // be empty. That is why this function is different from getOutputSection().
924edf75e79SRui Ueyama template <class ELFT>
925edf75e79SRui Ueyama uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
926edf75e79SRui Ueyama   for (OutputSectionBase *Sec : *OutputSections)
927edf75e79SRui Ueyama     if (Sec->getName() == Name)
928edf75e79SRui Ueyama       return Sec->Size;
929edf75e79SRui Ueyama   return 0;
930edf75e79SRui Ueyama }
931edf75e79SRui Ueyama 
932884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() {
9330d4b6d5cSRafael Espindola   return elf::getHeaderSize<ELFT>();
934e32a3598SGeorge Rimar }
935e32a3598SGeorge Rimar 
936f6aeed36SEugene Leviant template <class ELFT>
937f6aeed36SEugene Leviant uint64_t LinkerScript<ELFT>::getSymbolValue(const Twine &Loc, StringRef S) {
938884e786dSGeorge Rimar   if (SymbolBody *B = Symtab<ELFT>::X->find(S))
939884e786dSGeorge Rimar     return B->getVA<ELFT>();
940f6aeed36SEugene Leviant   error(Loc + ": symbol not found: " + S);
941884e786dSGeorge Rimar   return 0;
942884e786dSGeorge Rimar }
943884e786dSGeorge Rimar 
944f34f45fdSGeorge Rimar template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) {
945f34f45fdSGeorge Rimar   return Symtab<ELFT>::X->find(S) != nullptr;
946f34f45fdSGeorge Rimar }
947f34f45fdSGeorge Rimar 
9482f831dcaSRafael Espindola template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) {
9492f831dcaSRafael Espindola   SymbolBody *Sym = Symtab<ELFT>::X->find(S);
9502f831dcaSRafael Espindola   auto *DR = dyn_cast_or_null<DefinedRegular<ELFT>>(Sym);
9512f831dcaSRafael Espindola   return DR && !DR->Section;
9522f831dcaSRafael Espindola }
9532f831dcaSRafael Espindola 
954afaa9343SEugene Leviant // Gets section symbol belongs to. Symbol "." doesn't belong to any
955afaa9343SEugene Leviant // specific section but isn't absolute at the same time, so we try
956afaa9343SEugene Leviant // to find suitable section for it as well.
957afaa9343SEugene Leviant template <class ELFT>
958afaa9343SEugene Leviant const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
959afaa9343SEugene Leviant   SymbolBody *Sym = Symtab<ELFT>::X->find(S);
960afaa9343SEugene Leviant   if (!Sym) {
961afaa9343SEugene Leviant     if (OutputSections->empty())
962afaa9343SEugene Leviant       return nullptr;
963afaa9343SEugene Leviant     return CurOutSec ? CurOutSec : (*OutputSections)[0];
964afaa9343SEugene Leviant   }
965afaa9343SEugene Leviant 
96660aed443SGeorge Rimar   return SymbolTableSection<ELFT>::getOutputSection(Sym);
967afaa9343SEugene Leviant }
968afaa9343SEugene Leviant 
969bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified
970bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within
971bbe38602SEugene Leviant // PHDRS {} script block.
972bbe38602SEugene Leviant template <class ELFT>
973edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) {
974076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
975076fe157SGeorge Rimar     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
976edebbdf1SRui Ueyama     if (!Cmd || Cmd->Name != SectionName)
97731d842f5SGeorge Rimar       continue;
97831d842f5SGeorge Rimar 
97929c5a2a9SRui Ueyama     std::vector<size_t> Ret;
98029c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
9812a942c4bSEugene Leviant       Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
98229c5a2a9SRui Ueyama     return Ret;
983bbe38602SEugene Leviant   }
98431d842f5SGeorge Rimar   return {};
98531d842f5SGeorge Rimar }
986bbe38602SEugene Leviant 
98729c5a2a9SRui Ueyama template <class ELFT>
9882a942c4bSEugene Leviant size_t LinkerScript<ELFT>::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
98929c5a2a9SRui Ueyama   size_t I = 0;
99029c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
99129c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
99229c5a2a9SRui Ueyama       return I;
99329c5a2a9SRui Ueyama     ++I;
99429c5a2a9SRui Ueyama   }
9952a942c4bSEugene Leviant   error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
99629c5a2a9SRui Ueyama   return 0;
99729c5a2a9SRui Ueyama }
99829c5a2a9SRui Ueyama 
99903ff0166SEugene Leviant class elf::ScriptParser final : public ScriptParserBase {
1000c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
1001c3794e58SGeorge Rimar 
1002f7c5fbb1SRui Ueyama public:
100322375f24SRui Ueyama   ScriptParser(MemoryBufferRef MB)
100422375f24SRui Ueyama       : ScriptParserBase(MB),
100522375f24SRui Ueyama         IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {}
1006f23b2320SGeorge Rimar 
100720b6598cSGeorge Rimar   void readLinkerScript();
100820b6598cSGeorge Rimar   void readVersionScript();
1009d0ebd84cSRafael Espindola   void readDynamicList();
1010f7c5fbb1SRui Ueyama 
1011f7c5fbb1SRui Ueyama private:
101252a1509eSRui Ueyama   void addFile(StringRef Path);
101352a1509eSRui Ueyama 
1014f7c5fbb1SRui Ueyama   void readAsNeeded();
101590c5099eSDenis Protivensky   void readEntry();
101683f406cfSGeorge Rimar   void readExtern();
1017f7c5fbb1SRui Ueyama   void readGroup();
101831aa1f83SRui Ueyama   void readInclude();
1019b889744eSMeador Inge   void readMemory();
1020ee59282bSRui Ueyama   void readOutput();
10219159ce93SDavide Italiano   void readOutputArch();
1022f7c5fbb1SRui Ueyama   void readOutputFormat();
1023bbe38602SEugene Leviant   void readPhdrs();
102468a39a65SDavide Italiano   void readSearchDir();
10258e3b38abSDenis Protivensky   void readSections();
102695769b4aSRui Ueyama   void readVersion();
102795769b4aSRui Ueyama   void readVersionScriptCommand();
10288e3b38abSDenis Protivensky 
1029113cdec9SRui Ueyama   SymbolAssignment *readAssignment(StringRef Name);
1030e38cbab5SGeorge Rimar   BytesDataCommand *readBytesDataCommand(StringRef Tok);
103116068aebSRui Ueyama   uint32_t readFill();
103210416564SRui Ueyama   OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
103316068aebSRui Ueyama   uint32_t readOutputSectionFiller(StringRef Tok);
1034bbe38602SEugene Leviant   std::vector<StringRef> readOutputSectionPhdrs();
1035a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionDescription(StringRef Tok);
1036db688454SEugene Leviant   StringMatcher readFilePatterns();
103707171f21SGeorge Rimar   std::vector<SectionPattern> readInputSectionsList();
1038a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionRules(StringRef FilePattern);
1039bbe38602SEugene Leviant   unsigned readPhdrType();
1040be394db3SGeorge Rimar   SortSectionPolicy readSortKind();
1041a35e39caSPetr Hosek   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
1042c96da110SRafael Espindola   SymbolAssignment *readProvideOrAssignment(StringRef Tok);
104303fc010eSGeorge Rimar   void readSort();
1044eefa758eSGeorge Rimar   Expr readAssert();
1045708019c4SRui Ueyama 
104624e626ccSRui Ueyama   uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
104724e626ccSRui Ueyama   std::pair<uint32_t, uint32_t> readMemoryAttributes();
104824e626ccSRui Ueyama 
1049708019c4SRui Ueyama   Expr readExpr();
1050708019c4SRui Ueyama   Expr readExpr1(Expr Lhs, int MinPrec);
1051b71d6f7aSEugene Leviant   StringRef readParenLiteral();
1052708019c4SRui Ueyama   Expr readPrimary();
1053708019c4SRui Ueyama   Expr readTernary(Expr Cond);
10546ad7dfccSRui Ueyama   Expr readParenExpr();
1055f7c5fbb1SRui Ueyama 
105620b6598cSGeorge Rimar   // For parsing version script.
105712450b20SRui Ueyama   std::vector<SymbolVersion> readVersionExtern();
105812450b20SRui Ueyama   void readAnonymousDeclaration();
105995769b4aSRui Ueyama   void readVersionDeclaration(StringRef VerStr);
106012450b20SRui Ueyama   std::vector<SymbolVersion> readSymbols();
1061e999ddb8SRafael Espindola   void readLocals();
106220b6598cSGeorge Rimar 
106307320e40SRui Ueyama   ScriptConfiguration &Opt = *ScriptConfig;
106416b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
1065f7c5fbb1SRui Ueyama };
1066f7c5fbb1SRui Ueyama 
1067d0ebd84cSRafael Espindola void ScriptParser::readDynamicList() {
1068d0ebd84cSRafael Espindola   expect("{");
1069d0ebd84cSRafael Espindola   readAnonymousDeclaration();
1070d0ebd84cSRafael Espindola   if (!atEOF())
1071d0ebd84cSRafael Espindola     setError("EOF expected, but got " + next());
1072d0ebd84cSRafael Espindola }
1073d0ebd84cSRafael Espindola 
107420b6598cSGeorge Rimar void ScriptParser::readVersionScript() {
107595769b4aSRui Ueyama   readVersionScriptCommand();
107620b6598cSGeorge Rimar   if (!atEOF())
107795769b4aSRui Ueyama     setError("EOF expected, but got " + next());
107895769b4aSRui Ueyama }
107995769b4aSRui Ueyama 
108095769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() {
108183043f23SRui Ueyama   if (consume("{")) {
108212450b20SRui Ueyama     readAnonymousDeclaration();
108320b6598cSGeorge Rimar     return;
108420b6598cSGeorge Rimar   }
108520b6598cSGeorge Rimar 
108695769b4aSRui Ueyama   while (!atEOF() && !Error && peek() != "}") {
108720b6598cSGeorge Rimar     StringRef VerStr = next();
108820b6598cSGeorge Rimar     if (VerStr == "{") {
108995769b4aSRui Ueyama       setError("anonymous version definition is used in "
109095769b4aSRui Ueyama                "combination with other version definitions");
109120b6598cSGeorge Rimar       return;
109220b6598cSGeorge Rimar     }
109320b6598cSGeorge Rimar     expect("{");
109495769b4aSRui Ueyama     readVersionDeclaration(VerStr);
109520b6598cSGeorge Rimar   }
109620b6598cSGeorge Rimar }
109720b6598cSGeorge Rimar 
109895769b4aSRui Ueyama void ScriptParser::readVersion() {
109995769b4aSRui Ueyama   expect("{");
110095769b4aSRui Ueyama   readVersionScriptCommand();
110195769b4aSRui Ueyama   expect("}");
110295769b4aSRui Ueyama }
110395769b4aSRui Ueyama 
110420b6598cSGeorge Rimar void ScriptParser::readLinkerScript() {
1105f7c5fbb1SRui Ueyama   while (!atEOF()) {
1106f7c5fbb1SRui Ueyama     StringRef Tok = next();
1107a27eeccaSRui Ueyama     if (Tok == ";")
1108a27eeccaSRui Ueyama       continue;
1109a27eeccaSRui Ueyama 
111020d03194SEugene Leviant     if (Tok == "ASSERT") {
111120d03194SEugene Leviant       Opt.Commands.emplace_back(new AssertCommand(readAssert()));
111220d03194SEugene Leviant     } else if (Tok == "ENTRY") {
1113a27eeccaSRui Ueyama       readEntry();
1114a27eeccaSRui Ueyama     } else if (Tok == "EXTERN") {
1115a27eeccaSRui Ueyama       readExtern();
1116a27eeccaSRui Ueyama     } else if (Tok == "GROUP" || Tok == "INPUT") {
1117a27eeccaSRui Ueyama       readGroup();
1118a27eeccaSRui Ueyama     } else if (Tok == "INCLUDE") {
1119a27eeccaSRui Ueyama       readInclude();
1120b889744eSMeador Inge     } else if (Tok == "MEMORY") {
1121b889744eSMeador Inge       readMemory();
1122a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT") {
1123a27eeccaSRui Ueyama       readOutput();
1124a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_ARCH") {
1125a27eeccaSRui Ueyama       readOutputArch();
1126a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_FORMAT") {
1127a27eeccaSRui Ueyama       readOutputFormat();
1128a27eeccaSRui Ueyama     } else if (Tok == "PHDRS") {
1129a27eeccaSRui Ueyama       readPhdrs();
1130a27eeccaSRui Ueyama     } else if (Tok == "SEARCH_DIR") {
1131a27eeccaSRui Ueyama       readSearchDir();
1132a27eeccaSRui Ueyama     } else if (Tok == "SECTIONS") {
1133a27eeccaSRui Ueyama       readSections();
1134a27eeccaSRui Ueyama     } else if (Tok == "VERSION") {
1135a27eeccaSRui Ueyama       readVersion();
1136c96da110SRafael Espindola     } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) {
11370df80befSPetr Hosek       Opt.Commands.emplace_back(Cmd);
1138e5d3ca50SPetr Hosek     } else {
11395761042dSGeorge Rimar       setError("unknown directive: " + Tok);
1140f7c5fbb1SRui Ueyama     }
1141f7c5fbb1SRui Ueyama   }
1142e5d3ca50SPetr Hosek }
1143f7c5fbb1SRui Ueyama 
1144717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
114516b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
11465af1687fSJustin Bogner     SmallString<128> PathData;
11475af1687fSJustin Bogner     StringRef Path = (Config->Sysroot + S).toStringRef(PathData);
114816b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
11495af1687fSJustin Bogner       Driver->addFile(Saver.save(Path));
115016b0cc9eSSimon Atanasyan       return;
115116b0cc9eSSimon Atanasyan     }
115216b0cc9eSSimon Atanasyan   }
115316b0cc9eSSimon Atanasyan 
1154f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
115552a1509eSRui Ueyama     Driver->addFile(S);
115652a1509eSRui Ueyama   } else if (S.startswith("=")) {
115752a1509eSRui Ueyama     if (Config->Sysroot.empty())
115852a1509eSRui Ueyama       Driver->addFile(S.substr(1));
115952a1509eSRui Ueyama     else
116052a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
116152a1509eSRui Ueyama   } else if (S.startswith("-l")) {
116221eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
1163a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
1164a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
116552a1509eSRui Ueyama   } else {
1166061f9286SRui Ueyama     if (Optional<std::string> Path = findFromSearchPaths(S))
1167061f9286SRui Ueyama       Driver->addFile(Saver.save(*Path));
1168025d59b1SRui Ueyama     else
1169061f9286SRui Ueyama       setError("unable to find " + S);
117052a1509eSRui Ueyama   }
117152a1509eSRui Ueyama }
117252a1509eSRui Ueyama 
1173717677afSRui Ueyama void ScriptParser::readAsNeeded() {
1174f7c5fbb1SRui Ueyama   expect("(");
117535da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
117635da9b6eSRui Ueyama   Config->AsNeeded = true;
117783043f23SRui Ueyama   while (!Error && !consume(")"))
1178cd574a5eSGeorge Rimar     addFile(unquote(next()));
117935da9b6eSRui Ueyama   Config->AsNeeded = Orig;
1180f7c5fbb1SRui Ueyama }
1181f7c5fbb1SRui Ueyama 
1182717677afSRui Ueyama void ScriptParser::readEntry() {
118390c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
118490c5099eSDenis Protivensky   expect("(");
118590c5099eSDenis Protivensky   StringRef Tok = next();
118690c5099eSDenis Protivensky   if (Config->Entry.empty())
118790c5099eSDenis Protivensky     Config->Entry = Tok;
118890c5099eSDenis Protivensky   expect(")");
118990c5099eSDenis Protivensky }
119090c5099eSDenis Protivensky 
1191717677afSRui Ueyama void ScriptParser::readExtern() {
119283f406cfSGeorge Rimar   expect("(");
119383043f23SRui Ueyama   while (!Error && !consume(")"))
1194a2acc931SRui Ueyama     Config->Undefined.push_back(next());
119583f406cfSGeorge Rimar }
119683f406cfSGeorge Rimar 
1197717677afSRui Ueyama void ScriptParser::readGroup() {
1198f7c5fbb1SRui Ueyama   expect("(");
119983043f23SRui Ueyama   while (!Error && !consume(")")) {
1200f7c5fbb1SRui Ueyama     StringRef Tok = next();
1201a2acc931SRui Ueyama     if (Tok == "AS_NEEDED")
1202f7c5fbb1SRui Ueyama       readAsNeeded();
1203a2acc931SRui Ueyama     else
1204cd574a5eSGeorge Rimar       addFile(unquote(Tok));
1205f7c5fbb1SRui Ueyama   }
1206f7c5fbb1SRui Ueyama }
1207f7c5fbb1SRui Ueyama 
1208717677afSRui Ueyama void ScriptParser::readInclude() {
1209d4500653SGeorge Rimar   StringRef Tok = unquote(next());
1210ec1c75e0SRui Ueyama 
1211d4500653SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/File-Commands.html:
1212d4500653SGeorge Rimar   // The file will be searched for in the current directory, and in any
1213d4500653SGeorge Rimar   // directory specified with the -L option.
1214ec1c75e0SRui Ueyama   if (sys::fs::exists(Tok)) {
1215ec1c75e0SRui Ueyama     if (Optional<MemoryBufferRef> MB = readFile(Tok))
1216ec1c75e0SRui Ueyama       tokenize(*MB);
1217025d59b1SRui Ueyama     return;
1218025d59b1SRui Ueyama   }
1219ec1c75e0SRui Ueyama   if (Optional<std::string> Path = findFromSearchPaths(Tok)) {
1220ec1c75e0SRui Ueyama     if (Optional<MemoryBufferRef> MB = readFile(*Path))
1221ec1c75e0SRui Ueyama       tokenize(*MB);
1222ec1c75e0SRui Ueyama     return;
1223ec1c75e0SRui Ueyama   }
1224ec1c75e0SRui Ueyama   setError("cannot open " + Tok);
122531aa1f83SRui Ueyama }
122631aa1f83SRui Ueyama 
1227717677afSRui Ueyama void ScriptParser::readOutput() {
1228ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
1229ee59282bSRui Ueyama   expect("(");
1230ee59282bSRui Ueyama   StringRef Tok = next();
1231ee59282bSRui Ueyama   if (Config->OutputFile.empty())
1232cd574a5eSGeorge Rimar     Config->OutputFile = unquote(Tok);
1233ee59282bSRui Ueyama   expect(")");
1234ee59282bSRui Ueyama }
1235ee59282bSRui Ueyama 
1236717677afSRui Ueyama void ScriptParser::readOutputArch() {
12379159ce93SDavide Italiano   // Error checking only for now.
12389159ce93SDavide Italiano   expect("(");
12395424e7c7SJustin Bogner   skip();
12409159ce93SDavide Italiano   expect(")");
12419159ce93SDavide Italiano }
12429159ce93SDavide Italiano 
1243717677afSRui Ueyama void ScriptParser::readOutputFormat() {
1244f7c5fbb1SRui Ueyama   // Error checking only for now.
1245f7c5fbb1SRui Ueyama   expect("(");
12465424e7c7SJustin Bogner   skip();
12476836c618SDavide Italiano   StringRef Tok = next();
12486836c618SDavide Italiano   if (Tok == ")")
12496836c618SDavide Italiano     return;
1250025d59b1SRui Ueyama   if (Tok != ",") {
12515761042dSGeorge Rimar     setError("unexpected token: " + Tok);
1252025d59b1SRui Ueyama     return;
1253025d59b1SRui Ueyama   }
12545424e7c7SJustin Bogner   skip();
12556836c618SDavide Italiano   expect(",");
12565424e7c7SJustin Bogner   skip();
1257f7c5fbb1SRui Ueyama   expect(")");
1258f7c5fbb1SRui Ueyama }
1259f7c5fbb1SRui Ueyama 
1260bbe38602SEugene Leviant void ScriptParser::readPhdrs() {
1261bbe38602SEugene Leviant   expect("{");
126283043f23SRui Ueyama   while (!Error && !consume("}")) {
1263bbe38602SEugene Leviant     StringRef Tok = next();
126456b21c86SEugene Leviant     Opt.PhdrsCommands.push_back(
126556b21c86SEugene Leviant         {Tok, PT_NULL, false, false, UINT_MAX, nullptr});
1266bbe38602SEugene Leviant     PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back();
1267bbe38602SEugene Leviant 
1268bbe38602SEugene Leviant     PhdrCmd.Type = readPhdrType();
1269bbe38602SEugene Leviant     do {
1270bbe38602SEugene Leviant       Tok = next();
1271bbe38602SEugene Leviant       if (Tok == ";")
1272bbe38602SEugene Leviant         break;
1273bbe38602SEugene Leviant       if (Tok == "FILEHDR")
1274bbe38602SEugene Leviant         PhdrCmd.HasFilehdr = true;
1275bbe38602SEugene Leviant       else if (Tok == "PHDRS")
1276bbe38602SEugene Leviant         PhdrCmd.HasPhdrs = true;
127756b21c86SEugene Leviant       else if (Tok == "AT")
127856b21c86SEugene Leviant         PhdrCmd.LMAExpr = readParenExpr();
1279865bf863SEugene Leviant       else if (Tok == "FLAGS") {
1280865bf863SEugene Leviant         expect("(");
1281eb685cd7SRafael Espindola         // Passing 0 for the value of dot is a bit of a hack. It means that
1282eb685cd7SRafael Espindola         // we accept expressions like ".|1".
1283eb685cd7SRafael Espindola         PhdrCmd.Flags = readExpr()(0);
1284865bf863SEugene Leviant         expect(")");
1285865bf863SEugene Leviant       } else
1286bbe38602SEugene Leviant         setError("unexpected header attribute: " + Tok);
1287bbe38602SEugene Leviant     } while (!Error);
1288bbe38602SEugene Leviant   }
1289bbe38602SEugene Leviant }
1290bbe38602SEugene Leviant 
1291717677afSRui Ueyama void ScriptParser::readSearchDir() {
129268a39a65SDavide Italiano   expect("(");
129386c5fb82SRui Ueyama   StringRef Tok = next();
12946c7ad13fSRui Ueyama   if (!Config->Nostdlib)
1295cd574a5eSGeorge Rimar     Config->SearchPaths.push_back(unquote(Tok));
129668a39a65SDavide Italiano   expect(")");
129768a39a65SDavide Italiano }
129868a39a65SDavide Italiano 
1299717677afSRui Ueyama void ScriptParser::readSections() {
1300e05336ffSEugene Leviant   Opt.HasSections = true;
130118a30962SGeorge Rimar   // -no-rosegment is used to avoid placing read only non-executable sections in
130218a30962SGeorge Rimar   // their own segment. We do the same if SECTIONS command is present in linker
130318a30962SGeorge Rimar   // script. See comment for computeFlags().
130418a30962SGeorge Rimar   Config->SingleRoRx = true;
130518a30962SGeorge Rimar 
13068e3b38abSDenis Protivensky   expect("{");
130783043f23SRui Ueyama   while (!Error && !consume("}")) {
1308113cdec9SRui Ueyama     StringRef Tok = next();
1309c96da110SRafael Espindola     BaseCommand *Cmd = readProvideOrAssignment(Tok);
1310ceabe80eSEugene Leviant     if (!Cmd) {
1311ceabe80eSEugene Leviant       if (Tok == "ASSERT")
1312eefa758eSGeorge Rimar         Cmd = new AssertCommand(readAssert());
1313ceabe80eSEugene Leviant       else
131410416564SRui Ueyama         Cmd = readOutputSectionDescription(Tok);
13158e3b38abSDenis Protivensky     }
131610416564SRui Ueyama     Opt.Commands.emplace_back(Cmd);
1317652852c5SGeorge Rimar   }
1318708019c4SRui Ueyama }
13198e3b38abSDenis Protivensky 
1320708019c4SRui Ueyama static int precedence(StringRef Op) {
1321708019c4SRui Ueyama   return StringSwitch<int>(Op)
13220120e3f2SRui Ueyama       .Cases("*", "/", 5)
13230120e3f2SRui Ueyama       .Cases("+", "-", 4)
13240120e3f2SRui Ueyama       .Cases("<<", ">>", 3)
13259c4ac5f2SRui Ueyama       .Cases("<", "<=", ">", ">=", "==", "!=", 2)
13260120e3f2SRui Ueyama       .Cases("&", "|", 1)
1327708019c4SRui Ueyama       .Default(-1);
1328708019c4SRui Ueyama }
1329708019c4SRui Ueyama 
1330db688454SEugene Leviant StringMatcher ScriptParser::readFilePatterns() {
133110416564SRui Ueyama   std::vector<StringRef> V;
133283043f23SRui Ueyama   while (!Error && !consume(")"))
133310416564SRui Ueyama     V.push_back(next());
1334f91282e1SRui Ueyama   return StringMatcher(V);
13350702c4e8SGeorge Rimar }
13360702c4e8SGeorge Rimar 
1337be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() {
133883043f23SRui Ueyama   if (consume("SORT") || consume("SORT_BY_NAME"))
1339be394db3SGeorge Rimar     return SortSectionPolicy::Name;
134083043f23SRui Ueyama   if (consume("SORT_BY_ALIGNMENT"))
1341be394db3SGeorge Rimar     return SortSectionPolicy::Alignment;
134283043f23SRui Ueyama   if (consume("SORT_BY_INIT_PRIORITY"))
1343be394db3SGeorge Rimar     return SortSectionPolicy::Priority;
134483043f23SRui Ueyama   if (consume("SORT_NONE"))
1345be394db3SGeorge Rimar     return SortSectionPolicy::None;
1346b2a0abdfSRui Ueyama   return SortSectionPolicy::Default;
1347be394db3SGeorge Rimar }
1348be394db3SGeorge Rimar 
1349395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in
1350395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+
1351395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3)
1352af03be19SGeorge Rimar // The semantics of that is next:
1353af03be19SGeorge Rimar // * Include .foo.1 from every file.
1354af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o
1355af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o
135607171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
135707171f21SGeorge Rimar   std::vector<SectionPattern> Ret;
1358601e9898SGeorge Rimar   while (!Error && peek() != ")") {
1359f91282e1SRui Ueyama     StringMatcher ExcludeFilePat;
136083043f23SRui Ueyama     if (consume("EXCLUDE_FILE")) {
1361395281cfSGeorge Rimar       expect("(");
1362f91282e1SRui Ueyama       ExcludeFilePat = readFilePatterns();
1363395281cfSGeorge Rimar     }
1364395281cfSGeorge Rimar 
1365601e9898SGeorge Rimar     std::vector<StringRef> V;
1366601e9898SGeorge Rimar     while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE")
1367395281cfSGeorge Rimar       V.push_back(next());
1368601e9898SGeorge Rimar 
1369601e9898SGeorge Rimar     if (!V.empty())
1370f91282e1SRui Ueyama       Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)});
1371601e9898SGeorge Rimar     else
1372601e9898SGeorge Rimar       setError("section pattern is expected");
1373395281cfSGeorge Rimar   }
137407171f21SGeorge Rimar   return Ret;
1375395281cfSGeorge Rimar }
1376395281cfSGeorge Rimar 
1377f8f6f1e7SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a
1378f8f6f1e7SRui Ueyama // list of glob patterns for input sections. The grammar is as follows.
1379f8f6f1e7SRui Ueyama //
1380f8f6f1e7SRui Ueyama // <patterns> ::= <section-list>
1381f8f6f1e7SRui Ueyama //              | <sort> "(" <section-list> ")"
1382f8f6f1e7SRui Ueyama //              | <sort> "(" <sort> "(" <section-list> ")" ")"
1383f8f6f1e7SRui Ueyama //
1384f8f6f1e7SRui Ueyama // <sort>     ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
1385f8f6f1e7SRui Ueyama //              | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
1386f8f6f1e7SRui Ueyama //
1387f8f6f1e7SRui Ueyama // <section-list> is parsed by readInputSectionsList().
1388a2496cbeSGeorge Rimar InputSectionDescription *
1389a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) {
1390c91930a1SGeorge Rimar   auto *Cmd = new InputSectionDescription(FilePattern);
13910ed42b0cSDavide Italiano   expect("(");
1392f373dd76SRui Ueyama   while (!Error && !consume(")")) {
139307171f21SGeorge Rimar     SortSectionPolicy Outer = readSortKind();
139407171f21SGeorge Rimar     SortSectionPolicy Inner = SortSectionPolicy::Default;
139507171f21SGeorge Rimar     std::vector<SectionPattern> V;
139607171f21SGeorge Rimar     if (Outer != SortSectionPolicy::Default) {
13970702c4e8SGeorge Rimar       expect("(");
139807171f21SGeorge Rimar       Inner = readSortKind();
139907171f21SGeorge Rimar       if (Inner != SortSectionPolicy::Default) {
1400350ece4eSGeorge Rimar         expect("(");
140107171f21SGeorge Rimar         V = readInputSectionsList();
14020702c4e8SGeorge Rimar         expect(")");
1403350ece4eSGeorge Rimar       } else {
140407171f21SGeorge Rimar         V = readInputSectionsList();
1405350ece4eSGeorge Rimar       }
1406350ece4eSGeorge Rimar       expect(")");
140707171f21SGeorge Rimar     } else {
140807171f21SGeorge Rimar       V = readInputSectionsList();
14090659800eSGeorge Rimar     }
14100702c4e8SGeorge Rimar 
141107171f21SGeorge Rimar     for (SectionPattern &Pat : V) {
141207171f21SGeorge Rimar       Pat.SortInner = Inner;
141307171f21SGeorge Rimar       Pat.SortOuter = Outer;
141407171f21SGeorge Rimar     }
141507171f21SGeorge Rimar 
141607171f21SGeorge Rimar     std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns));
141707171f21SGeorge Rimar   }
141810416564SRui Ueyama   return Cmd;
14190659800eSGeorge Rimar }
14200659800eSGeorge Rimar 
1421a2496cbeSGeorge Rimar InputSectionDescription *
1422a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) {
14230659800eSGeorge Rimar   // Input section wildcard can be surrounded by KEEP.
14240659800eSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
1425a2496cbeSGeorge Rimar   if (Tok == "KEEP") {
1426e7282797SDavide Italiano     expect("(");
1427a2496cbeSGeorge Rimar     StringRef FilePattern = next();
1428a2496cbeSGeorge Rimar     InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
14290ed42b0cSDavide Italiano     expect(")");
1430cf43f179SEugene Leviant     Opt.KeptSections.push_back(Cmd);
143110416564SRui Ueyama     return Cmd;
143210416564SRui Ueyama   }
1433a2496cbeSGeorge Rimar   return readInputSectionRules(Tok);
14340659800eSGeorge Rimar }
14350659800eSGeorge Rimar 
143603fc010eSGeorge Rimar void ScriptParser::readSort() {
143703fc010eSGeorge Rimar   expect("(");
143803fc010eSGeorge Rimar   expect("CONSTRUCTORS");
143903fc010eSGeorge Rimar   expect(")");
144003fc010eSGeorge Rimar }
144103fc010eSGeorge Rimar 
1442eefa758eSGeorge Rimar Expr ScriptParser::readAssert() {
1443eefa758eSGeorge Rimar   expect("(");
1444eefa758eSGeorge Rimar   Expr E = readExpr();
1445eefa758eSGeorge Rimar   expect(",");
1446cd574a5eSGeorge Rimar   StringRef Msg = unquote(next());
1447eefa758eSGeorge Rimar   expect(")");
1448eefa758eSGeorge Rimar   return [=](uint64_t Dot) {
1449eefa758eSGeorge Rimar     uint64_t V = E(Dot);
1450eefa758eSGeorge Rimar     if (!V)
1451eefa758eSGeorge Rimar       error(Msg);
1452eefa758eSGeorge Rimar     return V;
1453eefa758eSGeorge Rimar   };
1454eefa758eSGeorge Rimar }
1455eefa758eSGeorge Rimar 
145625150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an
145725150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from
145825150e8bSRui Ueyama // what GNU linkers do.
145925150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
146016068aebSRui Ueyama uint32_t ScriptParser::readFill() {
1461ff1f29e0SGeorge Rimar   expect("(");
146216068aebSRui Ueyama   uint32_t V = readOutputSectionFiller(next());
1463ff1f29e0SGeorge Rimar   expect(")");
1464ff1f29e0SGeorge Rimar   expect(";");
1465ff1f29e0SGeorge Rimar   return V;
1466ff1f29e0SGeorge Rimar }
1467ff1f29e0SGeorge Rimar 
146810416564SRui Ueyama OutputSectionCommand *
146910416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) {
1470076fe157SGeorge Rimar   OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
14712a942c4bSEugene Leviant   Cmd->Location = getCurrentLocation();
147258e5c4dcSGeorge Rimar 
147358e5c4dcSGeorge Rimar   // Read an address expression.
147458e5c4dcSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address
147558e5c4dcSGeorge Rimar   if (peek() != ":")
147658e5c4dcSGeorge Rimar     Cmd->AddrExpr = readExpr();
147758e5c4dcSGeorge Rimar 
14788e3b38abSDenis Protivensky   expect(":");
1479246f681eSDavide Italiano 
148083043f23SRui Ueyama   if (consume("AT"))
1481b71d6f7aSEugene Leviant     Cmd->LMAExpr = readParenExpr();
148283043f23SRui Ueyama   if (consume("ALIGN"))
14836ad7dfccSRui Ueyama     Cmd->AlignExpr = readParenExpr();
148483043f23SRui Ueyama   if (consume("SUBALIGN"))
1485db24d9c3SGeorge Rimar     Cmd->SubalignExpr = readParenExpr();
1486630c6179SGeorge Rimar 
1487246f681eSDavide Italiano   // Parse constraints.
148883043f23SRui Ueyama   if (consume("ONLY_IF_RO"))
1489efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadOnly;
149083043f23SRui Ueyama   if (consume("ONLY_IF_RW"))
1491efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadWrite;
14928e3b38abSDenis Protivensky   expect("{");
14938ec77e64SRui Ueyama 
149483043f23SRui Ueyama   while (!Error && !consume("}")) {
1495ceabe80eSEugene Leviant     StringRef Tok = next();
1496b2d99d6aSMeador Inge     if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) {
1497ceabe80eSEugene Leviant       Cmd->Commands.emplace_back(Assignment);
1498b2d99d6aSMeador Inge     } else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) {
1499e38cbab5SGeorge Rimar       Cmd->Commands.emplace_back(Data);
1500b2d99d6aSMeador Inge     } else if (Tok == "ASSERT") {
1501b2d99d6aSMeador Inge       Cmd->Commands.emplace_back(new AssertCommand(readAssert()));
1502b2d99d6aSMeador Inge       expect(";");
15038e2eca22SGeorge Rimar     } else if (Tok == "CONSTRUCTORS") {
15048e2eca22SGeorge Rimar       // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
15058e2eca22SGeorge Rimar       // by name. This is for very old file formats such as ECOFF/XCOFF.
15068e2eca22SGeorge Rimar       // For ELF, we should ignore.
1507b2d99d6aSMeador Inge     } else if (Tok == "FILL") {
1508ff1f29e0SGeorge Rimar       Cmd->Filler = readFill();
1509b2d99d6aSMeador Inge     } else if (Tok == "SORT") {
151003fc010eSGeorge Rimar       readSort();
1511b2d99d6aSMeador Inge     } else if (peek() == "(") {
1512a2496cbeSGeorge Rimar       Cmd->Commands.emplace_back(readInputSectionDescription(Tok));
1513b2d99d6aSMeador Inge     } else {
1514ceabe80eSEugene Leviant       setError("unknown command " + Tok);
15158e3b38abSDenis Protivensky     }
1516b2d99d6aSMeador Inge   }
1517b889744eSMeador Inge 
1518b889744eSMeador Inge   if (consume(">"))
1519b889744eSMeador Inge     Cmd->MemoryRegionName = next();
1520b889744eSMeador Inge 
1521076fe157SGeorge Rimar   Cmd->Phdrs = readOutputSectionPhdrs();
15224ebc5620SGeorge Rimar 
152383043f23SRui Ueyama   if (consume("="))
15244ebc5620SGeorge Rimar     Cmd->Filler = readOutputSectionFiller(next());
15254ebc5620SGeorge Rimar   else if (peek().startswith("="))
1526ff1f29e0SGeorge Rimar     Cmd->Filler = readOutputSectionFiller(next().drop_front());
15274ebc5620SGeorge Rimar 
15287185a1acSGeorge Rimar   // Consume optional comma following output section command.
15297185a1acSGeorge Rimar   consume(",");
15307185a1acSGeorge Rimar 
153110416564SRui Ueyama   return Cmd;
1532f71caa2bSRui Ueyama }
15338ec77e64SRui Ueyama 
15342c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number.
15352c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
15362c8f1f04SRui Ueyama //
15372c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles
15382c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them
15392c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does
15402c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does.
154116068aebSRui Ueyama uint32_t ScriptParser::readOutputSectionFiller(StringRef Tok) {
1542965827d6SRui Ueyama   uint32_t V;
154316068aebSRui Ueyama   if (!Tok.getAsInteger(0, V))
154416068aebSRui Ueyama     return V;
1545965827d6SRui Ueyama   setError("invalid filler expression: " + Tok);
154616068aebSRui Ueyama   return 0;
15478e3b38abSDenis Protivensky }
15488e3b38abSDenis Protivensky 
1549a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
1550a31c91b1SEugene Leviant   expect("(");
1551174e0a16SRui Ueyama   SymbolAssignment *Cmd = readAssignment(next());
1552a35e39caSPetr Hosek   Cmd->Provide = Provide;
1553174e0a16SRui Ueyama   Cmd->Hidden = Hidden;
1554a31c91b1SEugene Leviant   expect(")");
1555a31c91b1SEugene Leviant   expect(";");
155610416564SRui Ueyama   return Cmd;
1557eda81a1bSEugene Leviant }
1558eda81a1bSEugene Leviant 
1559c96da110SRafael Espindola SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
1560ceabe80eSEugene Leviant   SymbolAssignment *Cmd = nullptr;
1561ceabe80eSEugene Leviant   if (peek() == "=" || peek() == "+=") {
1562ceabe80eSEugene Leviant     Cmd = readAssignment(Tok);
1563ceabe80eSEugene Leviant     expect(";");
1564ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE") {
1565a35e39caSPetr Hosek     Cmd = readProvideHidden(true, false);
1566a35e39caSPetr Hosek   } else if (Tok == "HIDDEN") {
1567a35e39caSPetr Hosek     Cmd = readProvideHidden(false, true);
1568ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE_HIDDEN") {
1569a35e39caSPetr Hosek     Cmd = readProvideHidden(true, true);
1570ceabe80eSEugene Leviant   }
1571ceabe80eSEugene Leviant   return Cmd;
1572ceabe80eSEugene Leviant }
1573ceabe80eSEugene Leviant 
1574f6aeed36SEugene Leviant static uint64_t getSymbolValue(const Twine &Loc, StringRef S, uint64_t Dot) {
157530835ea4SGeorge Rimar   if (S == ".")
157630835ea4SGeorge Rimar     return Dot;
1577f6aeed36SEugene Leviant   return ScriptBase->getSymbolValue(Loc, S);
1578e32a3598SGeorge Rimar }
1579e32a3598SGeorge Rimar 
15802f831dcaSRafael Espindola static bool isAbsolute(StringRef S) {
15812f831dcaSRafael Espindola   if (S == ".")
15822f831dcaSRafael Espindola     return false;
15832f831dcaSRafael Espindola   return ScriptBase->isAbsolute(S);
15842f831dcaSRafael Espindola }
15852f831dcaSRafael Espindola 
158630835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
158730835ea4SGeorge Rimar   StringRef Op = next();
1588db741e72SEugene Leviant   Expr E;
158930835ea4SGeorge Rimar   assert(Op == "=" || Op == "+=");
159083043f23SRui Ueyama   if (consume("ABSOLUTE")) {
15917c1381a0SRui Ueyama     // The RHS may be something like "ABSOLUTE(.) & 0xff".
15927c1381a0SRui Ueyama     // Call readExpr1 to read the whole expression.
15937c1381a0SRui Ueyama     E = readExpr1(readParenExpr(), 0);
1594009d1742SRui Ueyama     E.IsAbsolute = [] { return true; };
1595db741e72SEugene Leviant   } else {
1596db741e72SEugene Leviant     E = readExpr();
1597db741e72SEugene Leviant   }
1598f6aeed36SEugene Leviant   if (Op == "+=") {
1599f6aeed36SEugene Leviant     std::string Loc = getCurrentLocation();
1600f6aeed36SEugene Leviant     E = [=](uint64_t Dot) {
1601f6aeed36SEugene Leviant       return getSymbolValue(Loc, Name, Dot) + E(Dot);
1602f6aeed36SEugene Leviant     };
1603f6aeed36SEugene Leviant   }
1604f661393aSRafael Espindola   return new SymbolAssignment(Name, E);
160530835ea4SGeorge Rimar }
160630835ea4SGeorge Rimar 
160730835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker
160830835ea4SGeorge Rimar // script expression.
160930835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
161030835ea4SGeorge Rimar 
161136c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) {
161236c1cd23SRui Ueyama   if (Op == "*")
161336c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) * R(Dot); };
161436c1cd23SRui Ueyama   if (Op == "/") {
161536c1cd23SRui Ueyama     return [=](uint64_t Dot) -> uint64_t {
161636c1cd23SRui Ueyama       uint64_t RHS = R(Dot);
161736c1cd23SRui Ueyama       if (RHS == 0) {
161836c1cd23SRui Ueyama         error("division by zero");
161936c1cd23SRui Ueyama         return 0;
162036c1cd23SRui Ueyama       }
162136c1cd23SRui Ueyama       return L(Dot) / RHS;
162236c1cd23SRui Ueyama     };
162336c1cd23SRui Ueyama   }
162436c1cd23SRui Ueyama   if (Op == "+")
16252f831dcaSRafael Espindola     return {[=](uint64_t Dot) { return L(Dot) + R(Dot); },
1626009d1742SRui Ueyama             [=] { return L.IsAbsolute() && R.IsAbsolute(); },
1627009d1742SRui Ueyama             [=] {
1628afaa9343SEugene Leviant               const OutputSectionBase *S = L.Section();
1629afaa9343SEugene Leviant               return S ? S : R.Section();
1630afaa9343SEugene Leviant             }};
163136c1cd23SRui Ueyama   if (Op == "-")
163236c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) - R(Dot); };
1633c8ccd1f1SGeorge Rimar   if (Op == "<<")
1634c8ccd1f1SGeorge Rimar     return [=](uint64_t Dot) { return L(Dot) << R(Dot); };
1635c8ccd1f1SGeorge Rimar   if (Op == ">>")
1636c8ccd1f1SGeorge Rimar     return [=](uint64_t Dot) { return L(Dot) >> R(Dot); };
163736c1cd23SRui Ueyama   if (Op == "<")
163836c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) < R(Dot); };
163936c1cd23SRui Ueyama   if (Op == ">")
164036c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) > R(Dot); };
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) { return L(Dot) <= R(Dot); };
164536c1cd23SRui Ueyama   if (Op == "==")
164636c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) == R(Dot); };
164736c1cd23SRui Ueyama   if (Op == "!=")
164836c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) != R(Dot); };
164936c1cd23SRui Ueyama   if (Op == "&")
165036c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) & R(Dot); };
1651cc3dd629SRafael Espindola   if (Op == "|")
1652cc3dd629SRafael Espindola     return [=](uint64_t Dot) { return L(Dot) | R(Dot); };
165336c1cd23SRui Ueyama   llvm_unreachable("invalid operator");
165436c1cd23SRui Ueyama }
165536c1cd23SRui Ueyama 
1656708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function
1657708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator.
1658708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
1659708019c4SRui Ueyama   while (!atEOF() && !Error) {
1660708019c4SRui Ueyama     // Read an operator and an expression.
166146247b85SRui Ueyama     if (consume("?"))
1662708019c4SRui Ueyama       return readTernary(Lhs);
166346247b85SRui Ueyama     StringRef Op1 = peek();
1664708019c4SRui Ueyama     if (precedence(Op1) < MinPrec)
1665a31c91b1SEugene Leviant       break;
16665424e7c7SJustin Bogner     skip();
1667708019c4SRui Ueyama     Expr Rhs = readPrimary();
1668708019c4SRui Ueyama 
1669708019c4SRui Ueyama     // Evaluate the remaining part of the expression first if the
1670708019c4SRui Ueyama     // next operator has greater precedence than the previous one.
1671708019c4SRui Ueyama     // For example, if we have read "+" and "3", and if the next
1672708019c4SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
1673708019c4SRui Ueyama     while (!atEOF()) {
1674708019c4SRui Ueyama       StringRef Op2 = peek();
1675708019c4SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
1676eda81a1bSEugene Leviant         break;
1677708019c4SRui Ueyama       Rhs = readExpr1(Rhs, precedence(Op2));
1678eda81a1bSEugene Leviant     }
1679708019c4SRui Ueyama 
1680708019c4SRui Ueyama     Lhs = combine(Op1, Lhs, Rhs);
1681708019c4SRui Ueyama   }
1682708019c4SRui Ueyama   return Lhs;
1683708019c4SRui Ueyama }
1684708019c4SRui Ueyama 
1685708019c4SRui Ueyama uint64_t static getConstant(StringRef S) {
1686e2cc07bcSMichael J. Spencer   if (S == "COMMONPAGESIZE")
1687708019c4SRui Ueyama     return Target->PageSize;
1688e2cc07bcSMichael J. Spencer   if (S == "MAXPAGESIZE")
1689997f8838SPetr Hosek     return Config->MaxPageSize;
1690708019c4SRui Ueyama   error("unknown constant: " + S);
1691708019c4SRui Ueyama   return 0;
1692708019c4SRui Ueyama }
1693708019c4SRui Ueyama 
1694626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful.
1695626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H")
1696626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or
1697626e0b08SRui Ueyama // "M" (mega) prefixes.
16989f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) {
169946247b85SRui Ueyama   // Negative number
1700eaeafb2bSSimon Atanasyan   if (Tok.startswith("-")) {
1701eaeafb2bSSimon Atanasyan     if (!readInteger(Tok.substr(1), Result))
1702eaeafb2bSSimon Atanasyan       return false;
1703eaeafb2bSSimon Atanasyan     Result = -Result;
1704eaeafb2bSSimon Atanasyan     return true;
1705eaeafb2bSSimon Atanasyan   }
170646247b85SRui Ueyama 
170746247b85SRui Ueyama   // Hexadecimal
17089f2f7ad9SGeorge Rimar   if (Tok.startswith_lower("0x"))
17099f2f7ad9SGeorge Rimar     return !Tok.substr(2).getAsInteger(16, Result);
17109f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("H"))
17119f2f7ad9SGeorge Rimar     return !Tok.drop_back().getAsInteger(16, Result);
17129f2f7ad9SGeorge Rimar 
171346247b85SRui Ueyama   // Decimal
17149f2f7ad9SGeorge Rimar   int Suffix = 1;
17159f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("K")) {
17169f2f7ad9SGeorge Rimar     Suffix = 1024;
17179f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
17189f2f7ad9SGeorge Rimar   } else if (Tok.endswith_lower("M")) {
17199f2f7ad9SGeorge Rimar     Suffix = 1024 * 1024;
17209f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
17219f2f7ad9SGeorge Rimar   }
17229f2f7ad9SGeorge Rimar   if (Tok.getAsInteger(10, Result))
17239f2f7ad9SGeorge Rimar     return false;
17249f2f7ad9SGeorge Rimar   Result *= Suffix;
17259f2f7ad9SGeorge Rimar   return true;
17269f2f7ad9SGeorge Rimar }
17279f2f7ad9SGeorge Rimar 
1728e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) {
1729e38cbab5SGeorge Rimar   int Size = StringSwitch<unsigned>(Tok)
1730e38cbab5SGeorge Rimar                  .Case("BYTE", 1)
1731e38cbab5SGeorge Rimar                  .Case("SHORT", 2)
1732e38cbab5SGeorge Rimar                  .Case("LONG", 4)
1733e38cbab5SGeorge Rimar                  .Case("QUAD", 8)
1734e38cbab5SGeorge Rimar                  .Default(-1);
1735e38cbab5SGeorge Rimar   if (Size == -1)
1736e38cbab5SGeorge Rimar     return nullptr;
1737e38cbab5SGeorge Rimar 
173895c7d8d2SMeador Inge   return new BytesDataCommand(readParenExpr(), Size);
1739e38cbab5SGeorge Rimar }
1740e38cbab5SGeorge Rimar 
1741b71d6f7aSEugene Leviant StringRef ScriptParser::readParenLiteral() {
1742b71d6f7aSEugene Leviant   expect("(");
1743b71d6f7aSEugene Leviant   StringRef Tok = next();
1744b71d6f7aSEugene Leviant   expect(")");
1745b71d6f7aSEugene Leviant   return Tok;
1746b71d6f7aSEugene Leviant }
1747b71d6f7aSEugene Leviant 
1748708019c4SRui Ueyama Expr ScriptParser::readPrimary() {
17496ad7dfccSRui Ueyama   if (peek() == "(")
17506ad7dfccSRui Ueyama     return readParenExpr();
1751708019c4SRui Ueyama 
17526ad7dfccSRui Ueyama   StringRef Tok = next();
1753b5f1c3ecSRui Ueyama   std::string Location = getCurrentLocation();
1754708019c4SRui Ueyama 
1755eaeafb2bSSimon Atanasyan   if (Tok == "~") {
1756eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
1757eaeafb2bSSimon Atanasyan     return [=](uint64_t Dot) { return ~E(Dot); };
1758eaeafb2bSSimon Atanasyan   }
1759eaeafb2bSSimon Atanasyan   if (Tok == "-") {
1760eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
1761eaeafb2bSSimon Atanasyan     return [=](uint64_t Dot) { return -E(Dot); };
1762eaeafb2bSSimon Atanasyan   }
1763eaeafb2bSSimon Atanasyan 
1764708019c4SRui Ueyama   // Built-in functions are parsed here.
1765708019c4SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
176696659df0SGeorge Rimar   if (Tok == "ADDR") {
1767b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1768ed30ce7aSEugene Leviant     return {[=](uint64_t Dot) {
1769ed30ce7aSEugene Leviant               return ScriptBase->getOutputSection(Location, Name)->Addr;
1770ed30ce7aSEugene Leviant             },
1771009d1742SRui Ueyama             [=] { return false; },
1772ed30ce7aSEugene Leviant             [=] { return ScriptBase->getOutputSection(Location, Name); }};
177396659df0SGeorge Rimar   }
1774b71d6f7aSEugene Leviant   if (Tok == "LOADADDR") {
1775b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1776afaa9343SEugene Leviant     return [=](uint64_t Dot) {
1777ed30ce7aSEugene Leviant       return ScriptBase->getOutputSection(Location, Name)->getLMA();
1778afaa9343SEugene Leviant     };
1779b71d6f7aSEugene Leviant   }
1780eefa758eSGeorge Rimar   if (Tok == "ASSERT")
1781eefa758eSGeorge Rimar     return readAssert();
1782708019c4SRui Ueyama   if (Tok == "ALIGN") {
17835d804dc8SRui Ueyama     expect("(");
17845d804dc8SRui Ueyama     Expr E = readExpr();
17855d804dc8SRui Ueyama     if (consume(",")) {
17865d804dc8SRui Ueyama       Expr E2 = readExpr();
17875d804dc8SRui Ueyama       expect(")");
17885d804dc8SRui Ueyama       return [=](uint64_t Dot) { return alignTo(E(Dot), E2(Dot)); };
17895d804dc8SRui Ueyama     }
17905d804dc8SRui Ueyama     expect(")");
1791708019c4SRui Ueyama     return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
1792708019c4SRui Ueyama   }
1793708019c4SRui Ueyama   if (Tok == "CONSTANT") {
1794b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1795b0de56b5SRafael Espindola     return [=](uint64_t Dot) { return getConstant(Name); };
1796708019c4SRui Ueyama   }
1797f34f45fdSGeorge Rimar   if (Tok == "DEFINED") {
17980ee25a69SRui Ueyama     StringRef Name = readParenLiteral();
17990ee25a69SRui Ueyama     return [=](uint64_t Dot) { return ScriptBase->isDefined(Name) ? 1 : 0; };
1800f34f45fdSGeorge Rimar   }
180154c145ceSRafael Espindola   if (Tok == "SEGMENT_START") {
180254c145ceSRafael Espindola     expect("(");
18035424e7c7SJustin Bogner     skip();
180454c145ceSRafael Espindola     expect(",");
18058c658bf8SGeorge Rimar     Expr E = readExpr();
180654c145ceSRafael Espindola     expect(")");
18078c658bf8SGeorge Rimar     return [=](uint64_t Dot) { return E(Dot); };
180854c145ceSRafael Espindola   }
1809708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_ALIGN") {
1810708019c4SRui Ueyama     expect("(");
1811708019c4SRui Ueyama     Expr E = readExpr();
1812708019c4SRui Ueyama     expect(",");
1813708019c4SRui Ueyama     readExpr();
1814708019c4SRui Ueyama     expect(")");
1815f7791bb9SRui Ueyama     return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
1816708019c4SRui Ueyama   }
1817708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_END") {
1818708019c4SRui Ueyama     expect("(");
1819708019c4SRui Ueyama     expect(".");
1820708019c4SRui Ueyama     expect(")");
1821708019c4SRui Ueyama     return [](uint64_t Dot) { return Dot; };
1822708019c4SRui Ueyama   }
1823276b4e64SGeorge Rimar   // GNU linkers implements more complicated logic to handle
1824276b4e64SGeorge Rimar   // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to
1825276b4e64SGeorge Rimar   // the next page boundary for simplicity.
1826276b4e64SGeorge Rimar   if (Tok == "DATA_SEGMENT_RELRO_END") {
1827276b4e64SGeorge Rimar     expect("(");
182897bdc722SRafael Espindola     readExpr();
1829276b4e64SGeorge Rimar     expect(",");
1830276b4e64SGeorge Rimar     readExpr();
1831276b4e64SGeorge Rimar     expect(")");
1832276b4e64SGeorge Rimar     return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); };
1833276b4e64SGeorge Rimar   }
18349e69450eSGeorge Rimar   if (Tok == "SIZEOF") {
1835b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1836edf75e79SRui Ueyama     return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); };
18379e69450eSGeorge Rimar   }
183836fac7f0SEugene Leviant   if (Tok == "ALIGNOF") {
1839b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1840afaa9343SEugene Leviant     return [=](uint64_t Dot) {
1841ed30ce7aSEugene Leviant       return ScriptBase->getOutputSection(Location, Name)->Addralign;
1842afaa9343SEugene Leviant     };
184336fac7f0SEugene Leviant   }
1844e32a3598SGeorge Rimar   if (Tok == "SIZEOF_HEADERS")
1845b0de56b5SRafael Espindola     return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); };
1846708019c4SRui Ueyama 
18479f2f7ad9SGeorge Rimar   // Tok is a literal number.
18489f2f7ad9SGeorge Rimar   uint64_t V;
18499f2f7ad9SGeorge Rimar   if (readInteger(Tok, V))
1850b0de56b5SRafael Espindola     return [=](uint64_t Dot) { return V; };
18519f2f7ad9SGeorge Rimar 
18529f2f7ad9SGeorge Rimar   // Tok is a symbol name.
185330835ea4SGeorge Rimar   if (Tok != "." && !isValidCIdentifier(Tok))
1854708019c4SRui Ueyama     setError("malformed number: " + Tok);
1855f6aeed36SEugene Leviant   return {[=](uint64_t Dot) { return getSymbolValue(Location, Tok, Dot); },
1856009d1742SRui Ueyama           [=] { return isAbsolute(Tok); },
1857009d1742SRui Ueyama           [=] { return ScriptBase->getSymbolSection(Tok); }};
1858a9c5a528SGeorge Rimar }
1859708019c4SRui Ueyama 
1860708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) {
1861708019c4SRui Ueyama   Expr L = readExpr();
1862708019c4SRui Ueyama   expect(":");
1863708019c4SRui Ueyama   Expr R = readExpr();
1864708019c4SRui Ueyama   return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); };
1865708019c4SRui Ueyama }
1866708019c4SRui Ueyama 
18676ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() {
18686ad7dfccSRui Ueyama   expect("(");
18696ad7dfccSRui Ueyama   Expr E = readExpr();
18706ad7dfccSRui Ueyama   expect(")");
18716ad7dfccSRui Ueyama   return E;
18726ad7dfccSRui Ueyama }
18736ad7dfccSRui Ueyama 
1874bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
1875bbe38602SEugene Leviant   std::vector<StringRef> Phdrs;
1876bbe38602SEugene Leviant   while (!Error && peek().startswith(":")) {
1877bbe38602SEugene Leviant     StringRef Tok = next();
1878da841c16SGeorge Rimar     Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
1879bbe38602SEugene Leviant   }
1880bbe38602SEugene Leviant   return Phdrs;
1881bbe38602SEugene Leviant }
1882bbe38602SEugene Leviant 
188395dd718cSGeorge Rimar // Read a program header type name. The next token must be a
188495dd718cSGeorge Rimar // name of a program header type or a constant (e.g. "0x3").
1885bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() {
1886bbe38602SEugene Leviant   StringRef Tok = next();
188795dd718cSGeorge Rimar   uint64_t Val;
188895dd718cSGeorge Rimar   if (readInteger(Tok, Val))
188995dd718cSGeorge Rimar     return Val;
189095dd718cSGeorge Rimar 
1891b0f6c590SRui Ueyama   unsigned Ret = StringSwitch<unsigned>(Tok)
1892b0f6c590SRui Ueyama                      .Case("PT_NULL", PT_NULL)
1893b0f6c590SRui Ueyama                      .Case("PT_LOAD", PT_LOAD)
1894b0f6c590SRui Ueyama                      .Case("PT_DYNAMIC", PT_DYNAMIC)
1895b0f6c590SRui Ueyama                      .Case("PT_INTERP", PT_INTERP)
1896b0f6c590SRui Ueyama                      .Case("PT_NOTE", PT_NOTE)
1897b0f6c590SRui Ueyama                      .Case("PT_SHLIB", PT_SHLIB)
1898b0f6c590SRui Ueyama                      .Case("PT_PHDR", PT_PHDR)
1899b0f6c590SRui Ueyama                      .Case("PT_TLS", PT_TLS)
1900b0f6c590SRui Ueyama                      .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
1901b0f6c590SRui Ueyama                      .Case("PT_GNU_STACK", PT_GNU_STACK)
1902b0f6c590SRui Ueyama                      .Case("PT_GNU_RELRO", PT_GNU_RELRO)
1903270173f2SGeorge Rimar                      .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
1904cc6e567cSGeorge Rimar                      .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
1905a2a32c2cSGeorge Rimar                      .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
1906b0f6c590SRui Ueyama                      .Default(-1);
1907bbe38602SEugene Leviant 
1908b0f6c590SRui Ueyama   if (Ret == (unsigned)-1) {
1909b0f6c590SRui Ueyama     setError("invalid program header type: " + Tok);
1910b0f6c590SRui Ueyama     return PT_NULL;
1911b0f6c590SRui Ueyama   }
1912b0f6c590SRui Ueyama   return Ret;
1913bbe38602SEugene Leviant }
1914bbe38602SEugene Leviant 
191512450b20SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
191612450b20SRui Ueyama void ScriptParser::readAnonymousDeclaration() {
191712450b20SRui Ueyama   // Read global symbols first. "global:" is default, so if there's
191812450b20SRui Ueyama   // no label, we assume global symbols.
191912450b20SRui Ueyama   if (consume("global:") || peek() != "local:")
192012450b20SRui Ueyama     Config->VersionScriptGlobals = readSymbols();
192112450b20SRui Ueyama 
1922e999ddb8SRafael Espindola   readLocals();
192312450b20SRui Ueyama   expect("}");
192412450b20SRui Ueyama   expect(";");
192512450b20SRui Ueyama }
192612450b20SRui Ueyama 
1927e999ddb8SRafael Espindola void ScriptParser::readLocals() {
1928e999ddb8SRafael Espindola   if (!consume("local:"))
1929e999ddb8SRafael Espindola     return;
1930e999ddb8SRafael Espindola   std::vector<SymbolVersion> Locals = readSymbols();
1931e999ddb8SRafael Espindola   for (SymbolVersion V : Locals) {
1932e999ddb8SRafael Espindola     if (V.Name == "*") {
1933e999ddb8SRafael Espindola       Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1934e999ddb8SRafael Espindola       continue;
1935e999ddb8SRafael Espindola     }
1936e999ddb8SRafael Espindola     Config->VersionScriptLocals.push_back(V);
1937e999ddb8SRafael Espindola   }
1938e999ddb8SRafael Espindola }
1939e999ddb8SRafael Espindola 
194012450b20SRui Ueyama // Reads a list of symbols, e.g. "VerStr { global: foo; bar; local: *; };".
194195769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) {
194220b6598cSGeorge Rimar   // Identifiers start at 2 because 0 and 1 are reserved
194320b6598cSGeorge Rimar   // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants.
1944da805c48SRui Ueyama   uint16_t VersionId = Config->VersionDefinitions.size() + 2;
194520b6598cSGeorge Rimar   Config->VersionDefinitions.push_back({VerStr, VersionId});
194620b6598cSGeorge Rimar 
194712450b20SRui Ueyama   // Read global symbols.
194883043f23SRui Ueyama   if (consume("global:") || peek() != "local:")
194912450b20SRui Ueyama     Config->VersionDefinitions.back().Globals = readSymbols();
195012450b20SRui Ueyama 
1951e999ddb8SRafael Espindola   readLocals();
195220b6598cSGeorge Rimar   expect("}");
195320b6598cSGeorge Rimar 
195412450b20SRui Ueyama   // Each version may have a parent version. For example, "Ver2"
195512450b20SRui Ueyama   // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
195612450b20SRui Ueyama   // as a parent. This version hierarchy is, probably against your
195712450b20SRui Ueyama   // instinct, purely for hint; the runtime doesn't care about it
195812450b20SRui Ueyama   // at all. In LLD, we simply ignore it.
195912450b20SRui Ueyama   if (peek() != ";")
19605424e7c7SJustin Bogner     skip();
196120b6598cSGeorge Rimar   expect(";");
196220b6598cSGeorge Rimar }
196320b6598cSGeorge Rimar 
196412450b20SRui Ueyama // Reads a list of symbols for a versions cript.
196512450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readSymbols() {
196612450b20SRui Ueyama   std::vector<SymbolVersion> Ret;
1967e0fc2421SGeorge Rimar   for (;;) {
19681ef90d2fSRafael Espindola     if (consume("extern")) {
196912450b20SRui Ueyama       for (SymbolVersion V : readVersionExtern())
197012450b20SRui Ueyama         Ret.push_back(V);
19711ef90d2fSRafael Espindola       continue;
19721ef90d2fSRafael Espindola     }
1973e0fc2421SGeorge Rimar 
19740ee25a69SRui Ueyama     if (peek() == "}" || peek() == "local:" || Error)
197512450b20SRui Ueyama       break;
19760ee25a69SRui Ueyama     StringRef Tok = next();
197712450b20SRui Ueyama     Ret.push_back({unquote(Tok), false, hasWildcard(Tok)});
1978e0fc2421SGeorge Rimar     expect(";");
1979e0fc2421SGeorge Rimar   }
198012450b20SRui Ueyama   return Ret;
1981e0fc2421SGeorge Rimar }
1982e0fc2421SGeorge Rimar 
198312450b20SRui Ueyama // Reads an "extern C++" directive, e.g.,
198412450b20SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };"
198512450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
19867e71415cSRafael Espindola   StringRef Tok = next();
19877e71415cSRafael Espindola   bool IsCXX = Tok == "\"C++\"";
19887e71415cSRafael Espindola   if (!IsCXX && Tok != "\"C\"")
1989d0ebd84cSRafael Espindola     setError("Unknown language");
199020b6598cSGeorge Rimar   expect("{");
199120b6598cSGeorge Rimar 
199212450b20SRui Ueyama   std::vector<SymbolVersion> Ret;
19930ee25a69SRui Ueyama   while (!Error && peek() != "}") {
19940ee25a69SRui Ueyama     StringRef Tok = next();
19950ee25a69SRui Ueyama     bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok);
19967e71415cSRafael Espindola     Ret.push_back({unquote(Tok), IsCXX, HasWildcard});
199720b6598cSGeorge Rimar     expect(";");
199820b6598cSGeorge Rimar   }
199920b6598cSGeorge Rimar 
200020b6598cSGeorge Rimar   expect("}");
200120b6598cSGeorge Rimar   expect(";");
200212450b20SRui Ueyama   return Ret;
200320b6598cSGeorge Rimar }
200420b6598cSGeorge Rimar 
200524e626ccSRui Ueyama uint64_t ScriptParser::readMemoryAssignment(
200624e626ccSRui Ueyama     StringRef S1, StringRef S2, StringRef S3) {
200724e626ccSRui Ueyama   if (!(consume(S1) || consume(S2) || consume(S3))) {
200824e626ccSRui Ueyama     setError("expected one of: " + S1 + ", " + S2 + ", or " + S3);
200924e626ccSRui Ueyama     return 0;
201024e626ccSRui Ueyama   }
201124e626ccSRui Ueyama   expect("=");
201224e626ccSRui Ueyama 
201324e626ccSRui Ueyama   // TODO: Fully support constant expressions.
201424e626ccSRui Ueyama   uint64_t Val;
201524e626ccSRui Ueyama   if (!readInteger(next(), Val))
201624e626ccSRui Ueyama     setError("nonconstant expression for "+ S1);
201724e626ccSRui Ueyama   return Val;
201824e626ccSRui Ueyama }
201924e626ccSRui Ueyama 
202024e626ccSRui Ueyama // Parse the MEMORY command as specified in:
202124e626ccSRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html
202224e626ccSRui Ueyama //
202324e626ccSRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
2024b889744eSMeador Inge void ScriptParser::readMemory() {
2025b889744eSMeador Inge   expect("{");
2026b889744eSMeador Inge   while (!Error && !consume("}")) {
2027b889744eSMeador Inge     StringRef Name = next();
202824e626ccSRui Ueyama 
2029b889744eSMeador Inge     uint32_t Flags = 0;
2030*8a8a953eSRui Ueyama     uint32_t NegFlags = 0;
2031b889744eSMeador Inge     if (consume("(")) {
2032*8a8a953eSRui Ueyama       std::tie(Flags, NegFlags) = readMemoryAttributes();
2033b889744eSMeador Inge       expect(")");
2034b889744eSMeador Inge     }
2035b889744eSMeador Inge     expect(":");
2036b889744eSMeador Inge 
203724e626ccSRui Ueyama     uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o");
2038b889744eSMeador Inge     expect(",");
203924e626ccSRui Ueyama     uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
2040b889744eSMeador Inge 
2041b889744eSMeador Inge     // Add the memory region to the region map (if it doesn't already exist).
2042b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Name);
2043b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
2044b889744eSMeador Inge       setError("region '" + Name + "' already defined");
2045b889744eSMeador Inge     else
2046*8a8a953eSRui Ueyama       Opt.MemoryRegions[Name] = {Name, Origin, Length, Origin, Flags, NegFlags};
2047b889744eSMeador Inge   }
2048b889744eSMeador Inge }
2049b889744eSMeador Inge 
2050b889744eSMeador Inge // This function parses the attributes used to match against section
2051b889744eSMeador Inge // flags when placing output sections in a memory region. These flags
2052b889744eSMeador Inge // are only used when an explicit memory region name is not used.
2053b889744eSMeador Inge std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
2054b889744eSMeador Inge   uint32_t Flags = 0;
2055*8a8a953eSRui Ueyama   uint32_t NegFlags = 0;
2056b889744eSMeador Inge   bool Invert = false;
2057481ac996SRui Ueyama 
2058481ac996SRui Ueyama   for (char C : next().lower()) {
2059b889744eSMeador Inge     uint32_t Flag = 0;
2060b889744eSMeador Inge     if (C == '!')
2061b889744eSMeador Inge       Invert = !Invert;
2062481ac996SRui Ueyama     else if (C == 'w')
2063b889744eSMeador Inge       Flag = SHF_WRITE;
2064481ac996SRui Ueyama     else if (C == 'x')
2065b889744eSMeador Inge       Flag = SHF_EXECINSTR;
2066481ac996SRui Ueyama     else if (C == 'a')
2067b889744eSMeador Inge       Flag = SHF_ALLOC;
2068481ac996SRui Ueyama     else if (C != 'r')
2069b889744eSMeador Inge       setError("invalid memory region attribute");
2070481ac996SRui Ueyama 
2071b889744eSMeador Inge     if (Invert)
2072*8a8a953eSRui Ueyama       NegFlags |= Flag;
2073b889744eSMeador Inge     else
2074b889744eSMeador Inge       Flags |= Flag;
2075b889744eSMeador Inge   }
2076*8a8a953eSRui Ueyama   return {Flags, NegFlags};
2077b889744eSMeador Inge }
2078b889744eSMeador Inge 
207907320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) {
208022375f24SRui Ueyama   ScriptParser(MB).readLinkerScript();
208120b6598cSGeorge Rimar }
208220b6598cSGeorge Rimar 
208320b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) {
208422375f24SRui Ueyama   ScriptParser(MB).readVersionScript();
2085f7c5fbb1SRui Ueyama }
20861ebc8ed7SRui Ueyama 
2087d0ebd84cSRafael Espindola void elf::readDynamicList(MemoryBufferRef MB) {
2088d0ebd84cSRafael Espindola   ScriptParser(MB).readDynamicList();
2089d0ebd84cSRafael Espindola }
2090d0ebd84cSRafael Espindola 
209107320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>;
209207320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>;
209307320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>;
209407320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>;
2095