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.
11629e0aa5SRui Ueyama // It parses a linker script and write the result to Config or ScriptConfig
12629e0aa5SRui Ueyama // objects.
13629e0aa5SRui Ueyama //
14629e0aa5SRui Ueyama // If SECTIONS command is used, a ScriptConfig contains an AST
15629e0aa5SRui Ueyama // of the command which will later be consumed by createSections() and
16629e0aa5SRui Ueyama // assignAddresses().
17f7c5fbb1SRui Ueyama //
18f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===//
19f7c5fbb1SRui Ueyama 
20717677afSRui Ueyama #include "LinkerScript.h"
21f7c5fbb1SRui Ueyama #include "Config.h"
22f7c5fbb1SRui Ueyama #include "Driver.h"
231ebc8ed7SRui Ueyama #include "InputSection.h"
24652852c5SGeorge Rimar #include "OutputSections.h"
25e77b5bf6SAdhemerval Zanella #include "ScriptParser.h"
2693c9af42SRui Ueyama #include "Strings.h"
27eda81a1bSEugene Leviant #include "Symbols.h"
28f7c5fbb1SRui Ueyama #include "SymbolTable.h"
29467c4d55SEugene Leviant #include "Target.h"
30bbe38602SEugene Leviant #include "Writer.h"
31960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h"
32652852c5SGeorge Rimar #include "llvm/Support/ELF.h"
33f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h"
34f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h"
35f03f3cc1SRui Ueyama #include "llvm/Support/Path.h"
36a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h"
37f7c5fbb1SRui Ueyama 
38f7c5fbb1SRui Ueyama using namespace llvm;
39652852c5SGeorge Rimar using namespace llvm::ELF;
401ebc8ed7SRui Ueyama using namespace llvm::object;
41f7c5fbb1SRui Ueyama using namespace lld;
42e0df00b9SRafael Espindola using namespace lld::elf;
43f7c5fbb1SRui Ueyama 
44884e786dSGeorge Rimar LinkerScriptBase *elf::ScriptBase;
4507320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig;
46717677afSRui Ueyama 
476c55f0e3SGeorge Rimar template <class ELFT> static void addRegular(SymbolAssignment *Cmd) {
481602421cSRui Ueyama   Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, STB_GLOBAL, STV_DEFAULT);
491602421cSRui Ueyama   Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
501602421cSRui Ueyama   Cmd->Sym = Sym->body();
51ceabe80eSEugene Leviant }
52ceabe80eSEugene Leviant 
530c70d3ccSRui Ueyama template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) {
54e1937bb5SGeorge Rimar   Symbol *Sym = Symtab<ELFT>::X->addSynthetic(
55e1937bb5SGeorge Rimar       Cmd->Name, nullptr, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT);
561602421cSRui Ueyama   Cmd->Sym = Sym->body();
57ceabe80eSEugene Leviant }
58ceabe80eSEugene Leviant 
59db741e72SEugene Leviant template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) {
60db741e72SEugene Leviant   if (Cmd->IsAbsolute)
61db741e72SEugene Leviant     addRegular<ELFT>(Cmd);
62db741e72SEugene Leviant   else
63db741e72SEugene Leviant     addSynthetic<ELFT>(Cmd);
64db741e72SEugene Leviant }
651602421cSRui Ueyama // If a symbol was in PROVIDE(), we need to define it only when
661602421cSRui Ueyama // it is an undefined symbol.
671602421cSRui Ueyama template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) {
681602421cSRui Ueyama   if (Cmd->Name == ".")
69ceabe80eSEugene Leviant     return false;
701602421cSRui Ueyama   if (!Cmd->Provide)
71ceabe80eSEugene Leviant     return true;
721602421cSRui Ueyama   SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name);
731602421cSRui Ueyama   return B && B->isUndefined();
74ceabe80eSEugene Leviant }
75ceabe80eSEugene Leviant 
76076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
77076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
78076fe157SGeorge Rimar }
79076fe157SGeorge Rimar 
80076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
81076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
82076fe157SGeorge Rimar }
83076fe157SGeorge Rimar 
84eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
85eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
86eea3114fSGeorge Rimar }
87eea3114fSGeorge Rimar 
88eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) {
89eefa758eSGeorge Rimar   return C->Kind == AssertKind;
90eefa758eSGeorge Rimar }
91eefa758eSGeorge Rimar 
9236a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) {
93eea3114fSGeorge Rimar   return !S || !S->Live;
94717677afSRui Ueyama }
95717677afSRui Ueyama 
96f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::LinkerScript() {}
97f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::~LinkerScript() {}
98f34d0e08SRui Ueyama 
9907320e40SRui Ueyama template <class ELFT>
10007320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) {
101c91930a1SGeorge Rimar   for (Regex *Re : Opt.KeptSections)
102042a3f20SRafael Espindola     if (Re->match(S->Name))
103eea3114fSGeorge Rimar       return true;
104eea3114fSGeorge Rimar   return false;
105eea3114fSGeorge Rimar }
106eea3114fSGeorge Rimar 
1070659800eSGeorge Rimar static bool fileMatches(const InputSectionDescription *Desc,
1080659800eSGeorge Rimar                         StringRef Filename) {
109c91930a1SGeorge Rimar   return const_cast<Regex &>(Desc->FileRe).match(Filename) &&
110c91930a1SGeorge Rimar          !const_cast<Regex &>(Desc->ExcludedFileRe).match(Filename);
1110659800eSGeorge Rimar }
1120659800eSGeorge Rimar 
1136b274810SRui Ueyama // Returns input sections filtered by given glob patterns.
1146b274810SRui Ueyama template <class ELFT>
1156b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *>
116ad10c3d8SRui Ueyama LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) {
117c91930a1SGeorge Rimar   const Regex &Re = I->SectionRe;
1186b274810SRui Ueyama   std::vector<InputSectionBase<ELFT> *> Ret;
1196b274810SRui Ueyama   for (const std::unique_ptr<ObjectFile<ELFT>> &F :
1200659800eSGeorge Rimar        Symtab<ELFT>::X->getObjectFiles()) {
1210659800eSGeorge Rimar     if (fileMatches(I, sys::path::filename(F->getName())))
1226b274810SRui Ueyama       for (InputSectionBase<ELFT> *S : F->getSections())
1230659800eSGeorge Rimar         if (!isDiscarded(S) && !S->OutSec &&
124042a3f20SRafael Espindola             const_cast<Regex &>(Re).match(S->Name))
1256b274810SRui Ueyama           Ret.push_back(S);
1260659800eSGeorge Rimar   }
1273e6b0277SEugene Leviant 
128c91930a1SGeorge Rimar   if (const_cast<Regex &>(Re).match("COMMON"))
129ad10c3d8SRui Ueyama     Ret.push_back(CommonInputSection<ELFT>::X);
1306b274810SRui Ueyama   return Ret;
1316b274810SRui Ueyama }
1326b274810SRui Ueyama 
133c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) {
134042a3f20SRafael Espindola   return A->Name < B->Name;
1350702c4e8SGeorge Rimar }
136742c3836SRui Ueyama 
137c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) {
138742c3836SRui Ueyama   // ">" is not a mistake. Larger alignments are placed before smaller
139742c3836SRui Ueyama   // alignments in order to reduce the amount of padding necessary.
140742c3836SRui Ueyama   // This is compatible with GNU.
141742c3836SRui Ueyama   return A->Alignment > B->Alignment;
142742c3836SRui Ueyama }
143742c3836SRui Ueyama 
144c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)>
145742c3836SRui Ueyama getComparator(SortKind K) {
146742c3836SRui Ueyama   if (K == SortByName)
147c0028d3dSRafael Espindola     return compareName;
148c0028d3dSRafael Espindola   return compareAlignment;
149742c3836SRui Ueyama }
1500702c4e8SGeorge Rimar 
1510702c4e8SGeorge Rimar template <class ELFT>
15248c3f1ceSRui Ueyama void LinkerScript<ELFT>::discard(OutputSectionCommand &Cmd) {
15348c3f1ceSRui Ueyama   for (const std::unique_ptr<BaseCommand> &Base : Cmd.Commands) {
15448c3f1ceSRui Ueyama     if (auto *Cmd = dyn_cast<InputSectionDescription>(Base.get())) {
15548c3f1ceSRui Ueyama       for (InputSectionBase<ELFT> *S : getInputSections(Cmd)) {
15648c3f1ceSRui Ueyama         S->Live = false;
15748c3f1ceSRui Ueyama         reportDiscarded(S);
15848c3f1ceSRui Ueyama       }
15948c3f1ceSRui Ueyama     }
16048c3f1ceSRui Ueyama   }
16148c3f1ceSRui Ueyama }
16248c3f1ceSRui Ueyama 
1638f66df92SGeorge Rimar static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) {
1648f66df92SGeorge Rimar   bool RO = (Kind == ConstraintKind::ReadOnly);
1658f66df92SGeorge Rimar   bool RW = (Kind == ConstraintKind::ReadWrite);
1668f66df92SGeorge Rimar   bool Writable = Flags & SHF_WRITE;
167adcdb664SRui Ueyama   return !(RO && Writable) && !(RW && !Writable);
1688f66df92SGeorge Rimar }
1698f66df92SGeorge Rimar 
17048c3f1ceSRui Ueyama template <class ELFT>
17106ae6836SGeorge Rimar static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections,
17206ae6836SGeorge Rimar                              ConstraintKind Kind) {
1738f66df92SGeorge Rimar   if (Kind == ConstraintKind::NoConstraint)
1748f66df92SGeorge Rimar     return true;
1758f66df92SGeorge Rimar   return llvm::all_of(Sections, [=](InputSectionBase<ELFT> *Sec) {
1768f66df92SGeorge Rimar     return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind);
17706ae6836SGeorge Rimar   });
17806ae6836SGeorge Rimar }
17906ae6836SGeorge Rimar 
18006ae6836SGeorge Rimar template <class ELFT>
1810b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *>
18206ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
1830b9ce6a4SRui Ueyama   std::vector<InputSectionBase<ELFT> *> Ret;
18497403d15SEugene Leviant   DenseSet<InputSectionBase<ELFT> *> SectionIndex;
185e7f912cdSRui Ueyama 
18606ae6836SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) {
18706ae6836SGeorge Rimar     if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) {
18806ae6836SGeorge Rimar       if (shouldDefine<ELFT>(OutCmd))
189db741e72SEugene Leviant         addSymbol<ELFT>(OutCmd);
19097403d15SEugene Leviant       OutCmd->GoesAfter = Ret.empty() ? nullptr : Ret.back();
1910b9ce6a4SRui Ueyama       continue;
1920b9ce6a4SRui Ueyama     }
1930b9ce6a4SRui Ueyama 
1940b9ce6a4SRui Ueyama     auto *Cmd = cast<InputSectionDescription>(Base.get());
1950b9ce6a4SRui Ueyama     std::vector<InputSectionBase<ELFT> *> V = getInputSections(Cmd);
19606ae6836SGeorge Rimar     if (!matchConstraints<ELFT>(V, OutCmd.Constraint))
19706ae6836SGeorge Rimar       continue;
1980b9ce6a4SRui Ueyama     if (Cmd->SortInner)
199c0028d3dSRafael Espindola       std::stable_sort(V.begin(), V.end(), getComparator(Cmd->SortInner));
2000b9ce6a4SRui Ueyama     if (Cmd->SortOuter)
201c0028d3dSRafael Espindola       std::stable_sort(V.begin(), V.end(), getComparator(Cmd->SortOuter));
20297403d15SEugene Leviant 
20397403d15SEugene Leviant     // Add all input sections corresponding to rule 'Cmd' to
20497403d15SEugene Leviant     // resulting vector. We do not add duplicate input sections.
20597403d15SEugene Leviant     for (InputSectionBase<ELFT> *S : V)
20697403d15SEugene Leviant       if (SectionIndex.insert(S).second)
20797403d15SEugene Leviant         Ret.push_back(S);
2080b9ce6a4SRui Ueyama   }
2090b9ce6a4SRui Ueyama   return Ret;
2100b9ce6a4SRui Ueyama }
2110b9ce6a4SRui Ueyama 
2126c55f0e3SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::createAssignments() {
213e5d3ca50SPetr Hosek   for (const std::unique_ptr<SymbolAssignment> &Cmd : Opt.Assignments) {
214e5d3ca50SPetr Hosek     if (shouldDefine<ELFT>(Cmd.get()))
215e5d3ca50SPetr Hosek       addRegular<ELFT>(Cmd.get());
216e5d3ca50SPetr Hosek     if (Cmd->Sym)
217e5d3ca50SPetr Hosek       cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0);
218e5d3ca50SPetr Hosek   }
219e5d3ca50SPetr Hosek }
220e5d3ca50SPetr Hosek 
221e5d3ca50SPetr Hosek template <class ELFT>
2220b9ce6a4SRui Ueyama void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
22348c3f1ceSRui Ueyama   for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) {
2242ab5f73dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) {
2252ab5f73dSRui Ueyama       if (shouldDefine<ELFT>(Cmd))
2262ab5f73dSRui Ueyama         addRegular<ELFT>(Cmd);
2272ab5f73dSRui Ueyama       continue;
2282ab5f73dSRui Ueyama     }
2292ab5f73dSRui Ueyama 
230ceabe80eSEugene Leviant     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) {
23148c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
23248c3f1ceSRui Ueyama         discard(*Cmd);
23348c3f1ceSRui Ueyama         continue;
23448c3f1ceSRui Ueyama       }
2350b9ce6a4SRui Ueyama 
2360b9ce6a4SRui Ueyama       std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd);
23797403d15SEugene Leviant       if (V.empty())
2380b9ce6a4SRui Ueyama         continue;
2390b9ce6a4SRui Ueyama 
240a14b13d8SGeorge Rimar       for (InputSectionBase<ELFT> *Sec : V) {
2410b9ce6a4SRui Ueyama         OutputSectionBase<ELFT> *OutSec;
2420b9ce6a4SRui Ueyama         bool IsNew;
243a14b13d8SGeorge Rimar         std::tie(OutSec, IsNew) = Factory.create(Sec, Cmd->Name);
2440b9ce6a4SRui Ueyama         if (IsNew)
2450b9ce6a4SRui Ueyama           OutputSections->push_back(OutSec);
246db24d9c3SGeorge Rimar 
247db24d9c3SGeorge Rimar         uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0;
248a14b13d8SGeorge Rimar 
249db24d9c3SGeorge Rimar         if (Subalign)
250db24d9c3SGeorge Rimar           Sec->Alignment = Subalign;
2510b9ce6a4SRui Ueyama         OutSec->addSection(Sec);
252eea3114fSGeorge Rimar       }
25348c3f1ceSRui Ueyama     }
254db24d9c3SGeorge Rimar   }
255e63d81bdSEugene Leviant 
2560b9ce6a4SRui Ueyama   // Add orphan sections.
2576b274810SRui Ueyama   for (const std::unique_ptr<ObjectFile<ELFT>> &F :
2580b9ce6a4SRui Ueyama        Symtab<ELFT>::X->getObjectFiles()) {
2590b9ce6a4SRui Ueyama     for (InputSectionBase<ELFT> *S : F->getSections()) {
2602ab5f73dSRui Ueyama       if (isDiscarded(S) || S->OutSec)
2612ab5f73dSRui Ueyama         continue;
2620b9ce6a4SRui Ueyama       OutputSectionBase<ELFT> *OutSec;
2630b9ce6a4SRui Ueyama       bool IsNew;
2640b9ce6a4SRui Ueyama       std::tie(OutSec, IsNew) = Factory.create(S, getOutputSectionName(S));
2650b9ce6a4SRui Ueyama       if (IsNew)
2660b9ce6a4SRui Ueyama         OutputSections->push_back(OutSec);
2670b9ce6a4SRui Ueyama       OutSec->addSection(S);
2680b9ce6a4SRui Ueyama     }
2690b9ce6a4SRui Ueyama   }
270e63d81bdSEugene Leviant }
271e63d81bdSEugene Leviant 
272db741e72SEugene Leviant // Sets value of a section-defined symbol. Two kinds of
273db741e72SEugene Leviant // symbols are processed: synthetic symbols, whose value
274db741e72SEugene Leviant // is an offset from beginning of section and regular
275db741e72SEugene Leviant // symbols whose value is absolute.
276db741e72SEugene Leviant template <class ELFT>
277db741e72SEugene Leviant static void assignSectionSymbol(SymbolAssignment *Cmd,
278db741e72SEugene Leviant                                 OutputSectionBase<ELFT> *Sec,
279db741e72SEugene Leviant                                 typename ELFT::uint Off) {
280db741e72SEugene Leviant   if (!Cmd->Sym)
281db741e72SEugene Leviant     return;
282db741e72SEugene Leviant 
283db741e72SEugene Leviant   if (auto *Body = dyn_cast<DefinedSynthetic<ELFT>>(Cmd->Sym)) {
284db741e72SEugene Leviant     Body->Section = Sec;
285db741e72SEugene Leviant     Body->Value = Cmd->Expression(Sec->getVA() + Off) - Sec->getVA();
286db741e72SEugene Leviant     return;
287db741e72SEugene Leviant   }
288db741e72SEugene Leviant   auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym);
289db741e72SEugene Leviant   Body->Value = Cmd->Expression(Sec->getVA() + Off);
290db741e72SEugene Leviant }
291db741e72SEugene Leviant 
29220889c51SEugene Leviant // Linker script may define start and end symbols for special section types,
29320889c51SEugene Leviant // like .got, .eh_frame_hdr, .eh_frame and others. Those sections are not a list
29420889c51SEugene Leviant // of regular input input sections, therefore our way of defining symbols for
29520889c51SEugene Leviant // regular sections will not work. The approach we use for special section types
29620889c51SEugene Leviant // is not perfect - it handles only start and end symbols.
29720889c51SEugene Leviant template <class ELFT>
29820889c51SEugene Leviant void addStartEndSymbols(OutputSectionCommand *Cmd,
29920889c51SEugene Leviant                         OutputSectionBase<ELFT> *Sec) {
30020889c51SEugene Leviant   bool Start = true;
30120889c51SEugene Leviant   BaseCommand *PrevCmd = nullptr;
30220889c51SEugene Leviant 
30320889c51SEugene Leviant   for (std::unique_ptr<BaseCommand> &Base : Cmd->Commands) {
30420889c51SEugene Leviant     if (auto *AssignCmd = dyn_cast<SymbolAssignment>(Base.get())) {
305db741e72SEugene Leviant       assignSectionSymbol<ELFT>(AssignCmd, Sec, Start ? 0 : Sec->getSize());
30620889c51SEugene Leviant     } else {
30720889c51SEugene Leviant       if (!Start && isa<SymbolAssignment>(PrevCmd))
30820889c51SEugene Leviant         error("section '" + Sec->getName() +
30920889c51SEugene Leviant               "' supports only start and end symbols");
31020889c51SEugene Leviant       Start = false;
31120889c51SEugene Leviant     }
31220889c51SEugene Leviant     PrevCmd = Base.get();
31320889c51SEugene Leviant   }
31420889c51SEugene Leviant }
31520889c51SEugene Leviant 
31620889c51SEugene Leviant template <class ELFT>
31720889c51SEugene Leviant void assignOffsets(OutputSectionCommand *Cmd, OutputSectionBase<ELFT> *Sec) {
318ceabe80eSEugene Leviant   auto *OutSec = dyn_cast<OutputSection<ELFT>>(Sec);
3192de509c3SRui Ueyama   if (!OutSec) {
3202de509c3SRui Ueyama     Sec->assignOffsets();
32120889c51SEugene Leviant     // This section is not regular output section. However linker script may
32220889c51SEugene Leviant     // have defined start/end symbols for it. This case is handled below.
32320889c51SEugene Leviant     addStartEndSymbols(Cmd, Sec);
324ceabe80eSEugene Leviant     return;
3252de509c3SRui Ueyama   }
326ceabe80eSEugene Leviant   typedef typename ELFT::uint uintX_t;
327ceabe80eSEugene Leviant   uintX_t Off = 0;
32897403d15SEugene Leviant   auto ItCmd = Cmd->Commands.begin();
329ceabe80eSEugene Leviant 
33097403d15SEugene Leviant   // Assigns values to all symbols following the given
33197403d15SEugene Leviant   // input section 'D' in output section 'Sec'. When symbols
33297403d15SEugene Leviant   // are in the beginning of output section the value of 'D'
33397403d15SEugene Leviant   // is nullptr.
33497403d15SEugene Leviant   auto AssignSuccessors = [&](InputSectionData *D) {
33597403d15SEugene Leviant     for (; ItCmd != Cmd->Commands.end(); ++ItCmd) {
33697403d15SEugene Leviant       auto *AssignCmd = dyn_cast<SymbolAssignment>(ItCmd->get());
33797403d15SEugene Leviant       if (!AssignCmd)
33897403d15SEugene Leviant         continue;
33997403d15SEugene Leviant       if (D != AssignCmd->GoesAfter)
34097403d15SEugene Leviant         break;
34197403d15SEugene Leviant 
34297403d15SEugene Leviant       if (AssignCmd->Name == ".") {
34397403d15SEugene Leviant         // Update to location counter means update to section size.
344db741e72SEugene Leviant         Off = AssignCmd->Expression(Sec->getVA() + Off) - Sec->getVA();
34597403d15SEugene Leviant         Sec->setSize(Off);
34697403d15SEugene Leviant         continue;
34797403d15SEugene Leviant       }
348db741e72SEugene Leviant       assignSectionSymbol<ELFT>(AssignCmd, Sec, Off);
34997403d15SEugene Leviant     }
35097403d15SEugene Leviant   };
35197403d15SEugene Leviant 
35297403d15SEugene Leviant   AssignSuccessors(nullptr);
35397403d15SEugene Leviant   for (InputSection<ELFT> *I : OutSec->Sections) {
354ceabe80eSEugene Leviant     Off = alignTo(Off, I->Alignment);
355ceabe80eSEugene Leviant     I->OutSecOff = Off;
356ceabe80eSEugene Leviant     Off += I->getSize();
357ceabe80eSEugene Leviant     // Update section size inside for-loop, so that SIZEOF
358ceabe80eSEugene Leviant     // works correctly in the case below:
359ceabe80eSEugene Leviant     // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
360ceabe80eSEugene Leviant     Sec->setSize(Off);
36197403d15SEugene Leviant     // Add symbols following current input section.
36297403d15SEugene Leviant     AssignSuccessors(I);
363ceabe80eSEugene Leviant   }
364ceabe80eSEugene Leviant }
365ceabe80eSEugene Leviant 
3668f66df92SGeorge Rimar template <class ELFT>
367a14b13d8SGeorge Rimar static std::vector<OutputSectionBase<ELFT> *>
368a14b13d8SGeorge Rimar findSections(OutputSectionCommand &Cmd,
3698f66df92SGeorge Rimar              ArrayRef<OutputSectionBase<ELFT> *> Sections) {
370a14b13d8SGeorge Rimar   std::vector<OutputSectionBase<ELFT> *> Ret;
371a14b13d8SGeorge Rimar   for (OutputSectionBase<ELFT> *Sec : Sections)
372a14b13d8SGeorge Rimar     if (Sec->getName() == Cmd.Name &&
373a14b13d8SGeorge Rimar         checkConstraint(Sec->getFlags(), Cmd.Constraint))
374a14b13d8SGeorge Rimar       Ret.push_back(Sec);
375a14b13d8SGeorge Rimar   return Ret;
3768f66df92SGeorge Rimar }
3778f66df92SGeorge Rimar 
378a4b41dcaSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::assignAddresses() {
379652852c5SGeorge Rimar   // Orphan sections are sections present in the input files which
3807c18c28cSRui Ueyama   // are not explicitly placed into the output file by the linker script.
3817c18c28cSRui Ueyama   // We place orphan sections at end of file.
3827c18c28cSRui Ueyama   // Other linkers places them using some heuristics as described in
383652852c5SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections.
384e5cc668eSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
385652852c5SGeorge Rimar     StringRef Name = Sec->getName();
386c3e2a4b0SRui Ueyama     if (getSectionIndex(Name) == INT_MAX)
387076fe157SGeorge Rimar       Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name));
388652852c5SGeorge Rimar   }
389652852c5SGeorge Rimar 
3907c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
3914f7500bfSRui Ueyama   Dot = getHeaderSize();
392467c4d55SEugene Leviant   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
393652852c5SGeorge Rimar   uintX_t ThreadBssOffset = 0;
394652852c5SGeorge Rimar 
395076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
396076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
3978d083e6aSRui Ueyama       if (Cmd->Name == ".") {
3988d083e6aSRui Ueyama         Dot = Cmd->Expression(Dot);
3998d083e6aSRui Ueyama       } else if (Cmd->Sym) {
4008d083e6aSRui Ueyama         cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot);
4018d083e6aSRui Ueyama       }
40205ef4cffSRui Ueyama       continue;
403652852c5SGeorge Rimar     }
404652852c5SGeorge Rimar 
405eefa758eSGeorge Rimar     if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) {
406eefa758eSGeorge Rimar       Cmd->Expression(Dot);
407eefa758eSGeorge Rimar       continue;
408eefa758eSGeorge Rimar     }
409eefa758eSGeorge Rimar 
410076fe157SGeorge Rimar     auto *Cmd = cast<OutputSectionCommand>(Base.get());
411a14b13d8SGeorge Rimar     for (OutputSectionBase<ELFT> *Sec :
412a14b13d8SGeorge Rimar          findSections<ELFT>(*Cmd, *OutputSections)) {
413652852c5SGeorge Rimar 
41458e5c4dcSGeorge Rimar       if (Cmd->AddrExpr)
41558e5c4dcSGeorge Rimar         Dot = Cmd->AddrExpr(Dot);
41658e5c4dcSGeorge Rimar 
417630c6179SGeorge Rimar       if (Cmd->AlignExpr)
418630c6179SGeorge Rimar         Sec->updateAlignment(Cmd->AlignExpr(Dot));
419630c6179SGeorge Rimar 
420652852c5SGeorge Rimar       if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
421c998a8c0SRui Ueyama         uintX_t TVA = Dot + ThreadBssOffset;
422424b4081SRui Ueyama         TVA = alignTo(TVA, Sec->getAlignment());
423652852c5SGeorge Rimar         Sec->setVA(TVA);
42420889c51SEugene Leviant         assignOffsets(Cmd, Sec);
425c998a8c0SRui Ueyama         ThreadBssOffset = TVA - Dot + Sec->getSize();
426652852c5SGeorge Rimar         continue;
427652852c5SGeorge Rimar       }
428652852c5SGeorge Rimar 
429b6c52e8dSGeorge Rimar       if (!(Sec->getFlags() & SHF_ALLOC)) {
43020889c51SEugene Leviant         assignOffsets(Cmd, Sec);
431b6c52e8dSGeorge Rimar         continue;
432b6c52e8dSGeorge Rimar       }
433b6c52e8dSGeorge Rimar 
434424b4081SRui Ueyama       Dot = alignTo(Dot, Sec->getAlignment());
435c998a8c0SRui Ueyama       Sec->setVA(Dot);
43620889c51SEugene Leviant       assignOffsets(Cmd, Sec);
437467c4d55SEugene Leviant       MinVA = std::min(MinVA, Dot);
438c998a8c0SRui Ueyama       Dot += Sec->getSize();
439652852c5SGeorge Rimar     }
440a14b13d8SGeorge Rimar   }
441467c4d55SEugene Leviant 
44264c32d6fSRafael Espindola   // ELF and Program headers need to be right before the first section in
443b91e7118SGeorge Rimar   // memory. Set their addresses accordingly.
444467c4d55SEugene Leviant   MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() -
445467c4d55SEugene Leviant                         Out<ELFT>::ProgramHeaders->getSize(),
446467c4d55SEugene Leviant                     Target->PageSize);
447467c4d55SEugene Leviant   Out<ELFT>::ElfHeader->setVA(MinVA);
448467c4d55SEugene Leviant   Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA);
449fb8978fcSDima Stepanov }
450652852c5SGeorge Rimar 
451464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
45207320e40SRui Ueyama template <class ELFT>
453a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() {
454edebbdf1SRui Ueyama   std::vector<PhdrEntry<ELFT>> Ret;
455bbe38602SEugene Leviant 
456464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
457464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
458bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
459edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
460edebbdf1SRui Ueyama     PhdrEntry<ELFT> &Phdr = Ret.back();
461bbe38602SEugene Leviant 
462bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
463adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ElfHeader);
464bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
465adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ProgramHeaders);
46656b21c86SEugene Leviant 
46756b21c86SEugene Leviant     if (Cmd.LMAExpr) {
46856b21c86SEugene Leviant       Phdr.H.p_paddr = Cmd.LMAExpr(0);
46956b21c86SEugene Leviant       Phdr.HasLMA = true;
47056b21c86SEugene Leviant     }
471bbe38602SEugene Leviant   }
472bbe38602SEugene Leviant 
473464daadcSRui Ueyama   // Add output sections to program headers.
474edebbdf1SRui Ueyama   PhdrEntry<ELFT> *Load = nullptr;
475edebbdf1SRui Ueyama   uintX_t Flags = PF_R;
476464daadcSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
477bbe38602SEugene Leviant     if (!(Sec->getFlags() & SHF_ALLOC))
478bbe38602SEugene Leviant       break;
479bbe38602SEugene Leviant 
480edebbdf1SRui Ueyama     std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName());
481bbe38602SEugene Leviant     if (!PhdrIds.empty()) {
482bbe38602SEugene Leviant       // Assign headers specified by linker script
483bbe38602SEugene Leviant       for (size_t Id : PhdrIds) {
484edebbdf1SRui Ueyama         Ret[Id].add(Sec);
485865bf863SEugene Leviant         if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
4860b113671SRafael Espindola           Ret[Id].H.p_flags |= Sec->getPhdrFlags();
487bbe38602SEugene Leviant       }
488bbe38602SEugene Leviant     } else {
489bbe38602SEugene Leviant       // If we have no load segment or flags've changed then we want new load
490bbe38602SEugene Leviant       // segment.
4910b113671SRafael Espindola       uintX_t NewFlags = Sec->getPhdrFlags();
492bbe38602SEugene Leviant       if (Load == nullptr || Flags != NewFlags) {
493edebbdf1SRui Ueyama         Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags);
494bbe38602SEugene Leviant         Flags = NewFlags;
495bbe38602SEugene Leviant       }
49618f084ffSRui Ueyama       Load->add(Sec);
497bbe38602SEugene Leviant     }
498bbe38602SEugene Leviant   }
499edebbdf1SRui Ueyama   return Ret;
500bbe38602SEugene Leviant }
501bbe38602SEugene Leviant 
502f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() {
503f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
504f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
505f9bc3bd2SEugene Leviant   return !Opt.PhdrsCommands.empty() &&
506f9bc3bd2SEugene Leviant          llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) {
507f9bc3bd2SEugene Leviant            return Cmd.Type == PT_INTERP;
508f9bc3bd2SEugene Leviant          }) == Opt.PhdrsCommands.end();
509f9bc3bd2SEugene Leviant }
510f9bc3bd2SEugene Leviant 
511bbe38602SEugene Leviant template <class ELFT>
51207320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) {
513f6c3ccefSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
514f6c3ccefSGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
515f6c3ccefSGeorge Rimar       if (Cmd->Name == Name)
516f6c3ccefSGeorge Rimar         return Cmd->Filler;
517e2ee72b5SGeorge Rimar   return {};
518e2ee72b5SGeorge Rimar }
519e2ee72b5SGeorge Rimar 
520206fffa1SGeorge Rimar template <class ELFT> Expr LinkerScript<ELFT>::getLma(StringRef Name) {
5218ceadb38SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
5228ceadb38SGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
5238ceadb38SGeorge Rimar       if (Cmd->LmaExpr && Cmd->Name == Name)
5248ceadb38SGeorge Rimar         return Cmd->LmaExpr;
5258ceadb38SGeorge Rimar   return {};
5268ceadb38SGeorge Rimar }
5278ceadb38SGeorge Rimar 
528c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script
529c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they
530c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script,
531c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file.
532076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) {
533f510fa6bSRui Ueyama   int I = 0;
534f510fa6bSRui Ueyama   for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
535076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
536076fe157SGeorge Rimar       if (Cmd->Name == Name)
537f510fa6bSRui Ueyama         return I;
538f510fa6bSRui Ueyama     ++I;
539f510fa6bSRui Ueyama   }
540f510fa6bSRui Ueyama   return INT_MAX;
54171b26e94SGeorge Rimar }
54271b26e94SGeorge Rimar 
54371b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if
54471b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0.
54507320e40SRui Ueyama template <class ELFT>
54607320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) {
547c3e2a4b0SRui Ueyama   int I = getSectionIndex(A);
548c3e2a4b0SRui Ueyama   int J = getSectionIndex(B);
549c3e2a4b0SRui Ueyama   if (I == INT_MAX && J == INT_MAX)
550717677afSRui Ueyama     return 0;
551717677afSRui Ueyama   return I < J ? -1 : 1;
552717677afSRui Ueyama }
553717677afSRui Ueyama 
554bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
555bbe38602SEugene Leviant   return !Opt.PhdrsCommands.empty();
556bbe38602SEugene Leviant }
557bbe38602SEugene Leviant 
5589e69450eSGeorge Rimar template <class ELFT>
559884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) {
56096659df0SGeorge Rimar   for (OutputSectionBase<ELFT> *Sec : *OutputSections)
56196659df0SGeorge Rimar     if (Sec->getName() == Name)
56296659df0SGeorge Rimar       return Sec->getVA();
56396659df0SGeorge Rimar   error("undefined section " + Name);
56496659df0SGeorge Rimar   return 0;
56596659df0SGeorge Rimar }
56696659df0SGeorge Rimar 
56796659df0SGeorge Rimar template <class ELFT>
568884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
5699e69450eSGeorge Rimar   for (OutputSectionBase<ELFT> *Sec : *OutputSections)
5709e69450eSGeorge Rimar     if (Sec->getName() == Name)
5719e69450eSGeorge Rimar       return Sec->getSize();
5729e69450eSGeorge Rimar   error("undefined section " + Name);
5739e69450eSGeorge Rimar   return 0;
5749e69450eSGeorge Rimar }
5759e69450eSGeorge Rimar 
57636fac7f0SEugene Leviant template <class ELFT>
57736fac7f0SEugene Leviant uint64_t LinkerScript<ELFT>::getOutputSectionAlign(StringRef Name) {
57836fac7f0SEugene Leviant   for (OutputSectionBase<ELFT> *Sec : *OutputSections)
57936fac7f0SEugene Leviant     if (Sec->getName() == Name)
58036fac7f0SEugene Leviant       return Sec->getAlignment();
58136fac7f0SEugene Leviant   error("undefined section " + Name);
58236fac7f0SEugene Leviant   return 0;
58336fac7f0SEugene Leviant }
58436fac7f0SEugene Leviant 
585884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() {
586e32a3598SGeorge Rimar   return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
587e32a3598SGeorge Rimar }
588e32a3598SGeorge Rimar 
589884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) {
590884e786dSGeorge Rimar   if (SymbolBody *B = Symtab<ELFT>::X->find(S))
591884e786dSGeorge Rimar     return B->getVA<ELFT>();
592884e786dSGeorge Rimar   error("symbol not found: " + S);
593884e786dSGeorge Rimar   return 0;
594884e786dSGeorge Rimar }
595884e786dSGeorge Rimar 
596bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified
597bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within
598bbe38602SEugene Leviant // PHDRS {} script block.
599bbe38602SEugene Leviant template <class ELFT>
600edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) {
601076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
602076fe157SGeorge Rimar     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
603edebbdf1SRui Ueyama     if (!Cmd || Cmd->Name != SectionName)
60431d842f5SGeorge Rimar       continue;
60531d842f5SGeorge Rimar 
60629c5a2a9SRui Ueyama     std::vector<size_t> Ret;
60729c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
60829c5a2a9SRui Ueyama       Ret.push_back(getPhdrIndex(PhdrName));
60929c5a2a9SRui Ueyama     return Ret;
610bbe38602SEugene Leviant   }
61131d842f5SGeorge Rimar   return {};
61231d842f5SGeorge Rimar }
613bbe38602SEugene Leviant 
61429c5a2a9SRui Ueyama template <class ELFT>
61529c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) {
61629c5a2a9SRui Ueyama   size_t I = 0;
61729c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
61829c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
61929c5a2a9SRui Ueyama       return I;
62029c5a2a9SRui Ueyama     ++I;
62129c5a2a9SRui Ueyama   }
62229c5a2a9SRui Ueyama   error("section header '" + PhdrName + "' is not listed in PHDRS");
62329c5a2a9SRui Ueyama   return 0;
62429c5a2a9SRui Ueyama }
62529c5a2a9SRui Ueyama 
62607320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase {
627c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
628c3794e58SGeorge Rimar 
629f7c5fbb1SRui Ueyama public:
63007320e40SRui Ueyama   ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {}
631f23b2320SGeorge Rimar 
63220b6598cSGeorge Rimar   void readLinkerScript();
63320b6598cSGeorge Rimar   void readVersionScript();
634f7c5fbb1SRui Ueyama 
635f7c5fbb1SRui Ueyama private:
63652a1509eSRui Ueyama   void addFile(StringRef Path);
63752a1509eSRui Ueyama 
638f7c5fbb1SRui Ueyama   void readAsNeeded();
63990c5099eSDenis Protivensky   void readEntry();
64083f406cfSGeorge Rimar   void readExtern();
641f7c5fbb1SRui Ueyama   void readGroup();
64231aa1f83SRui Ueyama   void readInclude();
643ee59282bSRui Ueyama   void readOutput();
6449159ce93SDavide Italiano   void readOutputArch();
645f7c5fbb1SRui Ueyama   void readOutputFormat();
646bbe38602SEugene Leviant   void readPhdrs();
64768a39a65SDavide Italiano   void readSearchDir();
6488e3b38abSDenis Protivensky   void readSections();
64995769b4aSRui Ueyama   void readVersion();
65095769b4aSRui Ueyama   void readVersionScriptCommand();
6518e3b38abSDenis Protivensky 
652113cdec9SRui Ueyama   SymbolAssignment *readAssignment(StringRef Name);
653ff1f29e0SGeorge Rimar   std::vector<uint8_t> readFill();
65410416564SRui Ueyama   OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
655ff1f29e0SGeorge Rimar   std::vector<uint8_t> readOutputSectionFiller(StringRef Tok);
656bbe38602SEugene Leviant   std::vector<StringRef> readOutputSectionPhdrs();
657a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionDescription(StringRef Tok);
658c91930a1SGeorge Rimar   Regex readFilePatterns();
659a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionRules(StringRef FilePattern);
660bbe38602SEugene Leviant   unsigned readPhdrType();
661742c3836SRui Ueyama   SortKind readSortKind();
662a35e39caSPetr Hosek   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
663db741e72SEugene Leviant   SymbolAssignment *readProvideOrAssignment(StringRef Tok, bool MakeAbsolute);
66403fc010eSGeorge Rimar   void readSort();
665eefa758eSGeorge Rimar   Expr readAssert();
666708019c4SRui Ueyama 
667708019c4SRui Ueyama   Expr readExpr();
668708019c4SRui Ueyama   Expr readExpr1(Expr Lhs, int MinPrec);
669708019c4SRui Ueyama   Expr readPrimary();
670708019c4SRui Ueyama   Expr readTernary(Expr Cond);
6716ad7dfccSRui Ueyama   Expr readParenExpr();
672f7c5fbb1SRui Ueyama 
67320b6598cSGeorge Rimar   // For parsing version script.
67420b6598cSGeorge Rimar   void readExtern(std::vector<SymbolVersion> *Globals);
67595769b4aSRui Ueyama   void readVersionDeclaration(StringRef VerStr);
67620b6598cSGeorge Rimar   void readGlobal(StringRef VerStr);
67720b6598cSGeorge Rimar   void readLocal();
67820b6598cSGeorge Rimar 
67907320e40SRui Ueyama   ScriptConfiguration &Opt = *ScriptConfig;
68007320e40SRui Ueyama   StringSaver Saver = {ScriptConfig->Alloc};
68116b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
682f7c5fbb1SRui Ueyama };
683f7c5fbb1SRui Ueyama 
68420b6598cSGeorge Rimar void ScriptParser::readVersionScript() {
68595769b4aSRui Ueyama   readVersionScriptCommand();
68620b6598cSGeorge Rimar   if (!atEOF())
68795769b4aSRui Ueyama     setError("EOF expected, but got " + next());
68895769b4aSRui Ueyama }
68995769b4aSRui Ueyama 
69095769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() {
69195769b4aSRui Ueyama   if (skip("{")) {
69295769b4aSRui Ueyama     readVersionDeclaration("");
69320b6598cSGeorge Rimar     return;
69420b6598cSGeorge Rimar   }
69520b6598cSGeorge Rimar 
69695769b4aSRui Ueyama   while (!atEOF() && !Error && peek() != "}") {
69720b6598cSGeorge Rimar     StringRef VerStr = next();
69820b6598cSGeorge Rimar     if (VerStr == "{") {
69995769b4aSRui Ueyama       setError("anonymous version definition is used in "
70095769b4aSRui Ueyama                "combination with other version definitions");
70120b6598cSGeorge Rimar       return;
70220b6598cSGeorge Rimar     }
70320b6598cSGeorge Rimar     expect("{");
70495769b4aSRui Ueyama     readVersionDeclaration(VerStr);
70520b6598cSGeorge Rimar   }
70620b6598cSGeorge Rimar }
70720b6598cSGeorge Rimar 
70895769b4aSRui Ueyama void ScriptParser::readVersion() {
70995769b4aSRui Ueyama   expect("{");
71095769b4aSRui Ueyama   readVersionScriptCommand();
71195769b4aSRui Ueyama   expect("}");
71295769b4aSRui Ueyama }
71395769b4aSRui Ueyama 
71420b6598cSGeorge Rimar void ScriptParser::readLinkerScript() {
715f7c5fbb1SRui Ueyama   while (!atEOF()) {
716f7c5fbb1SRui Ueyama     StringRef Tok = next();
717a27eeccaSRui Ueyama     if (Tok == ";")
718a27eeccaSRui Ueyama       continue;
719a27eeccaSRui Ueyama 
720a27eeccaSRui Ueyama     if (Tok == "ENTRY") {
721a27eeccaSRui Ueyama       readEntry();
722a27eeccaSRui Ueyama     } else if (Tok == "EXTERN") {
723a27eeccaSRui Ueyama       readExtern();
724a27eeccaSRui Ueyama     } else if (Tok == "GROUP" || Tok == "INPUT") {
725a27eeccaSRui Ueyama       readGroup();
726a27eeccaSRui Ueyama     } else if (Tok == "INCLUDE") {
727a27eeccaSRui Ueyama       readInclude();
728a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT") {
729a27eeccaSRui Ueyama       readOutput();
730a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_ARCH") {
731a27eeccaSRui Ueyama       readOutputArch();
732a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_FORMAT") {
733a27eeccaSRui Ueyama       readOutputFormat();
734a27eeccaSRui Ueyama     } else if (Tok == "PHDRS") {
735a27eeccaSRui Ueyama       readPhdrs();
736a27eeccaSRui Ueyama     } else if (Tok == "SEARCH_DIR") {
737a27eeccaSRui Ueyama       readSearchDir();
738a27eeccaSRui Ueyama     } else if (Tok == "SECTIONS") {
739a27eeccaSRui Ueyama       readSections();
740a27eeccaSRui Ueyama     } else if (Tok == "VERSION") {
741a27eeccaSRui Ueyama       readVersion();
742db741e72SEugene Leviant     } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok, true)) {
743e5d3ca50SPetr Hosek       if (Opt.HasContents)
7440df80befSPetr Hosek         Opt.Commands.emplace_back(Cmd);
745c3794e58SGeorge Rimar       else
746e5d3ca50SPetr Hosek         Opt.Assignments.emplace_back(Cmd);
747e5d3ca50SPetr Hosek     } else {
7485761042dSGeorge Rimar       setError("unknown directive: " + Tok);
749f7c5fbb1SRui Ueyama     }
750f7c5fbb1SRui Ueyama   }
751e5d3ca50SPetr Hosek }
752f7c5fbb1SRui Ueyama 
753717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
75416b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
75516b0cc9eSSimon Atanasyan     SmallString<128> Path;
75616b0cc9eSSimon Atanasyan     (Config->Sysroot + S).toStringRef(Path);
75716b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
75816b0cc9eSSimon Atanasyan       Driver->addFile(Saver.save(Path.str()));
75916b0cc9eSSimon Atanasyan       return;
76016b0cc9eSSimon Atanasyan     }
76116b0cc9eSSimon Atanasyan   }
76216b0cc9eSSimon Atanasyan 
763f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
76452a1509eSRui Ueyama     Driver->addFile(S);
76552a1509eSRui Ueyama   } else if (S.startswith("=")) {
76652a1509eSRui Ueyama     if (Config->Sysroot.empty())
76752a1509eSRui Ueyama       Driver->addFile(S.substr(1));
76852a1509eSRui Ueyama     else
76952a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
77052a1509eSRui Ueyama   } else if (S.startswith("-l")) {
77121eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
772a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
773a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
77452a1509eSRui Ueyama   } else {
77552a1509eSRui Ueyama     std::string Path = findFromSearchPaths(S);
77652a1509eSRui Ueyama     if (Path.empty())
777777f9630SGeorge Rimar       setError("unable to find " + S);
778025d59b1SRui Ueyama     else
77952a1509eSRui Ueyama       Driver->addFile(Saver.save(Path));
78052a1509eSRui Ueyama   }
78152a1509eSRui Ueyama }
78252a1509eSRui Ueyama 
783717677afSRui Ueyama void ScriptParser::readAsNeeded() {
784f7c5fbb1SRui Ueyama   expect("(");
78535da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
78635da9b6eSRui Ueyama   Config->AsNeeded = true;
787a2acc931SRui Ueyama   while (!Error && !skip(")"))
788*cd574a5eSGeorge Rimar     addFile(unquote(next()));
78935da9b6eSRui Ueyama   Config->AsNeeded = Orig;
790f7c5fbb1SRui Ueyama }
791f7c5fbb1SRui Ueyama 
792717677afSRui Ueyama void ScriptParser::readEntry() {
79390c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
79490c5099eSDenis Protivensky   expect("(");
79590c5099eSDenis Protivensky   StringRef Tok = next();
79690c5099eSDenis Protivensky   if (Config->Entry.empty())
79790c5099eSDenis Protivensky     Config->Entry = Tok;
79890c5099eSDenis Protivensky   expect(")");
79990c5099eSDenis Protivensky }
80090c5099eSDenis Protivensky 
801717677afSRui Ueyama void ScriptParser::readExtern() {
80283f406cfSGeorge Rimar   expect("(");
803a2acc931SRui Ueyama   while (!Error && !skip(")"))
804a2acc931SRui Ueyama     Config->Undefined.push_back(next());
80583f406cfSGeorge Rimar }
80683f406cfSGeorge Rimar 
807717677afSRui Ueyama void ScriptParser::readGroup() {
808f7c5fbb1SRui Ueyama   expect("(");
809a2acc931SRui Ueyama   while (!Error && !skip(")")) {
810f7c5fbb1SRui Ueyama     StringRef Tok = next();
811a2acc931SRui Ueyama     if (Tok == "AS_NEEDED")
812f7c5fbb1SRui Ueyama       readAsNeeded();
813a2acc931SRui Ueyama     else
814*cd574a5eSGeorge Rimar       addFile(unquote(Tok));
815f7c5fbb1SRui Ueyama   }
816f7c5fbb1SRui Ueyama }
817f7c5fbb1SRui Ueyama 
818717677afSRui Ueyama void ScriptParser::readInclude() {
81931aa1f83SRui Ueyama   StringRef Tok = next();
820*cd574a5eSGeorge Rimar   auto MBOrErr = MemoryBuffer::getFile(unquote(Tok));
821025d59b1SRui Ueyama   if (!MBOrErr) {
8225761042dSGeorge Rimar     setError("cannot open " + Tok);
823025d59b1SRui Ueyama     return;
824025d59b1SRui Ueyama   }
82531aa1f83SRui Ueyama   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
826a47ee68dSRui Ueyama   StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
827a47ee68dSRui Ueyama   std::vector<StringRef> V = tokenize(S);
82831aa1f83SRui Ueyama   Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
82931aa1f83SRui Ueyama }
83031aa1f83SRui Ueyama 
831717677afSRui Ueyama void ScriptParser::readOutput() {
832ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
833ee59282bSRui Ueyama   expect("(");
834ee59282bSRui Ueyama   StringRef Tok = next();
835ee59282bSRui Ueyama   if (Config->OutputFile.empty())
836*cd574a5eSGeorge Rimar     Config->OutputFile = unquote(Tok);
837ee59282bSRui Ueyama   expect(")");
838ee59282bSRui Ueyama }
839ee59282bSRui Ueyama 
840717677afSRui Ueyama void ScriptParser::readOutputArch() {
8419159ce93SDavide Italiano   // Error checking only for now.
8429159ce93SDavide Italiano   expect("(");
8439159ce93SDavide Italiano   next();
8449159ce93SDavide Italiano   expect(")");
8459159ce93SDavide Italiano }
8469159ce93SDavide Italiano 
847717677afSRui Ueyama void ScriptParser::readOutputFormat() {
848f7c5fbb1SRui Ueyama   // Error checking only for now.
849f7c5fbb1SRui Ueyama   expect("(");
850f7c5fbb1SRui Ueyama   next();
8516836c618SDavide Italiano   StringRef Tok = next();
8526836c618SDavide Italiano   if (Tok == ")")
8536836c618SDavide Italiano     return;
854025d59b1SRui Ueyama   if (Tok != ",") {
8555761042dSGeorge Rimar     setError("unexpected token: " + Tok);
856025d59b1SRui Ueyama     return;
857025d59b1SRui Ueyama   }
8586836c618SDavide Italiano   next();
8596836c618SDavide Italiano   expect(",");
8606836c618SDavide Italiano   next();
861f7c5fbb1SRui Ueyama   expect(")");
862f7c5fbb1SRui Ueyama }
863f7c5fbb1SRui Ueyama 
864bbe38602SEugene Leviant void ScriptParser::readPhdrs() {
865bbe38602SEugene Leviant   expect("{");
866bbe38602SEugene Leviant   while (!Error && !skip("}")) {
867bbe38602SEugene Leviant     StringRef Tok = next();
86856b21c86SEugene Leviant     Opt.PhdrsCommands.push_back(
86956b21c86SEugene Leviant         {Tok, PT_NULL, false, false, UINT_MAX, nullptr});
870bbe38602SEugene Leviant     PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back();
871bbe38602SEugene Leviant 
872bbe38602SEugene Leviant     PhdrCmd.Type = readPhdrType();
873bbe38602SEugene Leviant     do {
874bbe38602SEugene Leviant       Tok = next();
875bbe38602SEugene Leviant       if (Tok == ";")
876bbe38602SEugene Leviant         break;
877bbe38602SEugene Leviant       if (Tok == "FILEHDR")
878bbe38602SEugene Leviant         PhdrCmd.HasFilehdr = true;
879bbe38602SEugene Leviant       else if (Tok == "PHDRS")
880bbe38602SEugene Leviant         PhdrCmd.HasPhdrs = true;
88156b21c86SEugene Leviant       else if (Tok == "AT")
88256b21c86SEugene Leviant         PhdrCmd.LMAExpr = readParenExpr();
883865bf863SEugene Leviant       else if (Tok == "FLAGS") {
884865bf863SEugene Leviant         expect("(");
885eb685cd7SRafael Espindola         // Passing 0 for the value of dot is a bit of a hack. It means that
886eb685cd7SRafael Espindola         // we accept expressions like ".|1".
887eb685cd7SRafael Espindola         PhdrCmd.Flags = readExpr()(0);
888865bf863SEugene Leviant         expect(")");
889865bf863SEugene Leviant       } else
890bbe38602SEugene Leviant         setError("unexpected header attribute: " + Tok);
891bbe38602SEugene Leviant     } while (!Error);
892bbe38602SEugene Leviant   }
893bbe38602SEugene Leviant }
894bbe38602SEugene Leviant 
895717677afSRui Ueyama void ScriptParser::readSearchDir() {
89668a39a65SDavide Italiano   expect("(");
89786c5fb82SRui Ueyama   StringRef Tok = next();
8986c7ad13fSRui Ueyama   if (!Config->Nostdlib)
899*cd574a5eSGeorge Rimar     Config->SearchPaths.push_back(unquote(Tok));
90068a39a65SDavide Italiano   expect(")");
90168a39a65SDavide Italiano }
90268a39a65SDavide Italiano 
903717677afSRui Ueyama void ScriptParser::readSections() {
9043de0a330SRui Ueyama   Opt.HasContents = true;
9058e3b38abSDenis Protivensky   expect("{");
906652852c5SGeorge Rimar   while (!Error && !skip("}")) {
907113cdec9SRui Ueyama     StringRef Tok = next();
908db741e72SEugene Leviant     BaseCommand *Cmd = readProvideOrAssignment(Tok, true);
909ceabe80eSEugene Leviant     if (!Cmd) {
910ceabe80eSEugene Leviant       if (Tok == "ASSERT")
911eefa758eSGeorge Rimar         Cmd = new AssertCommand(readAssert());
912ceabe80eSEugene Leviant       else
91310416564SRui Ueyama         Cmd = readOutputSectionDescription(Tok);
9148e3b38abSDenis Protivensky     }
91510416564SRui Ueyama     Opt.Commands.emplace_back(Cmd);
916652852c5SGeorge Rimar   }
917708019c4SRui Ueyama }
9188e3b38abSDenis Protivensky 
919708019c4SRui Ueyama static int precedence(StringRef Op) {
920708019c4SRui Ueyama   return StringSwitch<int>(Op)
921708019c4SRui Ueyama       .Case("*", 4)
922708019c4SRui Ueyama       .Case("/", 4)
923708019c4SRui Ueyama       .Case("+", 3)
924708019c4SRui Ueyama       .Case("-", 3)
925708019c4SRui Ueyama       .Case("<", 2)
926708019c4SRui Ueyama       .Case(">", 2)
927708019c4SRui Ueyama       .Case(">=", 2)
928708019c4SRui Ueyama       .Case("<=", 2)
929708019c4SRui Ueyama       .Case("==", 2)
930708019c4SRui Ueyama       .Case("!=", 2)
931708019c4SRui Ueyama       .Case("&", 1)
932cc3dd629SRafael Espindola       .Case("|", 1)
933708019c4SRui Ueyama       .Default(-1);
934708019c4SRui Ueyama }
935708019c4SRui Ueyama 
936c91930a1SGeorge Rimar Regex ScriptParser::readFilePatterns() {
93710416564SRui Ueyama   std::vector<StringRef> V;
93810416564SRui Ueyama   while (!Error && !skip(")"))
93910416564SRui Ueyama     V.push_back(next());
940c91930a1SGeorge Rimar   return compileGlobPatterns(V);
9410702c4e8SGeorge Rimar }
9420702c4e8SGeorge Rimar 
943742c3836SRui Ueyama SortKind ScriptParser::readSortKind() {
944742c3836SRui Ueyama   if (skip("SORT") || skip("SORT_BY_NAME"))
945742c3836SRui Ueyama     return SortByName;
946742c3836SRui Ueyama   if (skip("SORT_BY_ALIGNMENT"))
947742c3836SRui Ueyama     return SortByAlignment;
948742c3836SRui Ueyama   return SortNone;
949742c3836SRui Ueyama }
950742c3836SRui Ueyama 
951a2496cbeSGeorge Rimar InputSectionDescription *
952a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) {
953c91930a1SGeorge Rimar   auto *Cmd = new InputSectionDescription(FilePattern);
9540ed42b0cSDavide Italiano   expect("(");
955e7282797SDavide Italiano 
956742c3836SRui Ueyama   // Read EXCLUDE_FILE().
957e7282797SDavide Italiano   if (skip("EXCLUDE_FILE")) {
958e7282797SDavide Italiano     expect("(");
959c91930a1SGeorge Rimar     Cmd->ExcludedFileRe = readFilePatterns();
960e7282797SDavide Italiano   }
961e7282797SDavide Italiano 
962742c3836SRui Ueyama   // Read SORT().
963742c3836SRui Ueyama   if (SortKind K1 = readSortKind()) {
964742c3836SRui Ueyama     Cmd->SortOuter = K1;
9650702c4e8SGeorge Rimar     expect("(");
966742c3836SRui Ueyama     if (SortKind K2 = readSortKind()) {
967742c3836SRui Ueyama       Cmd->SortInner = K2;
968350ece4eSGeorge Rimar       expect("(");
969c91930a1SGeorge Rimar       Cmd->SectionRe = readFilePatterns();
9700702c4e8SGeorge Rimar       expect(")");
971350ece4eSGeorge Rimar     } else {
972c91930a1SGeorge Rimar       Cmd->SectionRe = readFilePatterns();
973350ece4eSGeorge Rimar     }
974350ece4eSGeorge Rimar     expect(")");
97510416564SRui Ueyama     return Cmd;
9760659800eSGeorge Rimar   }
9770702c4e8SGeorge Rimar 
978c91930a1SGeorge Rimar   Cmd->SectionRe = readFilePatterns();
97910416564SRui Ueyama   return Cmd;
9800659800eSGeorge Rimar }
9810659800eSGeorge Rimar 
982a2496cbeSGeorge Rimar InputSectionDescription *
983a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) {
9840659800eSGeorge Rimar   // Input section wildcard can be surrounded by KEEP.
9850659800eSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
986a2496cbeSGeorge Rimar   if (Tok == "KEEP") {
987e7282797SDavide Italiano     expect("(");
988a2496cbeSGeorge Rimar     StringRef FilePattern = next();
989a2496cbeSGeorge Rimar     InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
9900ed42b0cSDavide Italiano     expect(")");
991c91930a1SGeorge Rimar     Opt.KeptSections.push_back(&Cmd->SectionRe);
99210416564SRui Ueyama     return Cmd;
99310416564SRui Ueyama   }
994a2496cbeSGeorge Rimar   return readInputSectionRules(Tok);
9950659800eSGeorge Rimar }
9960659800eSGeorge Rimar 
99703fc010eSGeorge Rimar void ScriptParser::readSort() {
99803fc010eSGeorge Rimar   expect("(");
99903fc010eSGeorge Rimar   expect("CONSTRUCTORS");
100003fc010eSGeorge Rimar   expect(")");
100103fc010eSGeorge Rimar }
100203fc010eSGeorge Rimar 
1003eefa758eSGeorge Rimar Expr ScriptParser::readAssert() {
1004eefa758eSGeorge Rimar   expect("(");
1005eefa758eSGeorge Rimar   Expr E = readExpr();
1006eefa758eSGeorge Rimar   expect(",");
1007*cd574a5eSGeorge Rimar   StringRef Msg = unquote(next());
1008eefa758eSGeorge Rimar   expect(")");
1009eefa758eSGeorge Rimar   return [=](uint64_t Dot) {
1010eefa758eSGeorge Rimar     uint64_t V = E(Dot);
1011eefa758eSGeorge Rimar     if (!V)
1012eefa758eSGeorge Rimar       error(Msg);
1013eefa758eSGeorge Rimar     return V;
1014eefa758eSGeorge Rimar   };
1015eefa758eSGeorge Rimar }
1016eefa758eSGeorge Rimar 
101725150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an
101825150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from
101925150e8bSRui Ueyama // what GNU linkers do.
102025150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
1021ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readFill() {
1022ff1f29e0SGeorge Rimar   expect("(");
1023ff1f29e0SGeorge Rimar   std::vector<uint8_t> V = readOutputSectionFiller(next());
1024ff1f29e0SGeorge Rimar   expect(")");
1025ff1f29e0SGeorge Rimar   expect(";");
1026ff1f29e0SGeorge Rimar   return V;
1027ff1f29e0SGeorge Rimar }
1028ff1f29e0SGeorge Rimar 
102910416564SRui Ueyama OutputSectionCommand *
103010416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) {
1031076fe157SGeorge Rimar   OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
103258e5c4dcSGeorge Rimar 
103358e5c4dcSGeorge Rimar   // Read an address expression.
103458e5c4dcSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address
103558e5c4dcSGeorge Rimar   if (peek() != ":")
103658e5c4dcSGeorge Rimar     Cmd->AddrExpr = readExpr();
103758e5c4dcSGeorge Rimar 
10388e3b38abSDenis Protivensky   expect(":");
1039246f681eSDavide Italiano 
10408ceadb38SGeorge Rimar   if (skip("AT"))
10416ad7dfccSRui Ueyama     Cmd->LmaExpr = readParenExpr();
1042630c6179SGeorge Rimar   if (skip("ALIGN"))
10436ad7dfccSRui Ueyama     Cmd->AlignExpr = readParenExpr();
1044db24d9c3SGeorge Rimar   if (skip("SUBALIGN"))
1045db24d9c3SGeorge Rimar     Cmd->SubalignExpr = readParenExpr();
1046630c6179SGeorge Rimar 
1047246f681eSDavide Italiano   // Parse constraints.
1048246f681eSDavide Italiano   if (skip("ONLY_IF_RO"))
1049efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadOnly;
1050246f681eSDavide Italiano   if (skip("ONLY_IF_RW"))
1051efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadWrite;
10528e3b38abSDenis Protivensky   expect("{");
10538ec77e64SRui Ueyama 
1054025d59b1SRui Ueyama   while (!Error && !skip("}")) {
1055ceabe80eSEugene Leviant     StringRef Tok = next();
1056db741e72SEugene Leviant     if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok, false))
1057ceabe80eSEugene Leviant       Cmd->Commands.emplace_back(Assignment);
1058ff1f29e0SGeorge Rimar     else if (Tok == "FILL")
1059ff1f29e0SGeorge Rimar       Cmd->Filler = readFill();
1060ceabe80eSEugene Leviant     else if (Tok == "SORT")
106103fc010eSGeorge Rimar       readSort();
1062a2496cbeSGeorge Rimar     else if (peek() == "(")
1063a2496cbeSGeorge Rimar       Cmd->Commands.emplace_back(readInputSectionDescription(Tok));
1064ceabe80eSEugene Leviant     else
1065ceabe80eSEugene Leviant       setError("unknown command " + Tok);
10668e3b38abSDenis Protivensky   }
1067076fe157SGeorge Rimar   Cmd->Phdrs = readOutputSectionPhdrs();
1068ff1f29e0SGeorge Rimar   if (peek().startswith("="))
1069ff1f29e0SGeorge Rimar     Cmd->Filler = readOutputSectionFiller(next().drop_front());
107010416564SRui Ueyama   return Cmd;
1071f71caa2bSRui Ueyama }
10728ec77e64SRui Ueyama 
10732c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number.
10742c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
10752c8f1f04SRui Ueyama //
10762c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles
10772c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them
10782c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does
10792c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does.
1080ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readOutputSectionFiller(StringRef Tok) {
1081965827d6SRui Ueyama   uint32_t V;
1082ff1f29e0SGeorge Rimar   if (Tok.getAsInteger(0, V)) {
1083965827d6SRui Ueyama     setError("invalid filler expression: " + Tok);
1084f71caa2bSRui Ueyama     return {};
1085e2ee72b5SGeorge Rimar   }
1086965827d6SRui Ueyama   return {uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V)};
10878e3b38abSDenis Protivensky }
10888e3b38abSDenis Protivensky 
1089a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
1090a31c91b1SEugene Leviant   expect("(");
1091174e0a16SRui Ueyama   SymbolAssignment *Cmd = readAssignment(next());
1092a35e39caSPetr Hosek   Cmd->Provide = Provide;
1093174e0a16SRui Ueyama   Cmd->Hidden = Hidden;
1094a31c91b1SEugene Leviant   expect(")");
1095a31c91b1SEugene Leviant   expect(";");
109610416564SRui Ueyama   return Cmd;
1097eda81a1bSEugene Leviant }
1098eda81a1bSEugene Leviant 
1099db741e72SEugene Leviant SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok,
1100db741e72SEugene Leviant                                                         bool MakeAbsolute) {
1101ceabe80eSEugene Leviant   SymbolAssignment *Cmd = nullptr;
1102ceabe80eSEugene Leviant   if (peek() == "=" || peek() == "+=") {
1103ceabe80eSEugene Leviant     Cmd = readAssignment(Tok);
1104ceabe80eSEugene Leviant     expect(";");
1105ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE") {
1106a35e39caSPetr Hosek     Cmd = readProvideHidden(true, false);
1107a35e39caSPetr Hosek   } else if (Tok == "HIDDEN") {
1108a35e39caSPetr Hosek     Cmd = readProvideHidden(false, true);
1109ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE_HIDDEN") {
1110a35e39caSPetr Hosek     Cmd = readProvideHidden(true, true);
1111ceabe80eSEugene Leviant   }
1112db741e72SEugene Leviant   if (Cmd && MakeAbsolute)
1113db741e72SEugene Leviant     Cmd->IsAbsolute = true;
1114ceabe80eSEugene Leviant   return Cmd;
1115ceabe80eSEugene Leviant }
1116ceabe80eSEugene Leviant 
111730835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) {
111830835ea4SGeorge Rimar   if (S == ".")
111930835ea4SGeorge Rimar     return Dot;
1120884e786dSGeorge Rimar   return ScriptBase->getSymbolValue(S);
1121e32a3598SGeorge Rimar }
1122e32a3598SGeorge Rimar 
112330835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
112430835ea4SGeorge Rimar   StringRef Op = next();
1125db741e72SEugene Leviant   bool IsAbsolute = false;
1126db741e72SEugene Leviant   Expr E;
112730835ea4SGeorge Rimar   assert(Op == "=" || Op == "+=");
1128db741e72SEugene Leviant   if (skip("ABSOLUTE")) {
1129db741e72SEugene Leviant     E = readParenExpr();
1130db741e72SEugene Leviant     IsAbsolute = true;
1131db741e72SEugene Leviant   } else {
1132db741e72SEugene Leviant     E = readExpr();
1133db741e72SEugene Leviant   }
113430835ea4SGeorge Rimar   if (Op == "+=")
113530835ea4SGeorge Rimar     E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); };
1136db741e72SEugene Leviant   return new SymbolAssignment(Name, E, IsAbsolute);
113730835ea4SGeorge Rimar }
113830835ea4SGeorge Rimar 
113930835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker
114030835ea4SGeorge Rimar // script expression.
114130835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
114230835ea4SGeorge Rimar 
114336c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) {
114436c1cd23SRui Ueyama   if (Op == "*")
114536c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) * R(Dot); };
114636c1cd23SRui Ueyama   if (Op == "/") {
114736c1cd23SRui Ueyama     return [=](uint64_t Dot) -> uint64_t {
114836c1cd23SRui Ueyama       uint64_t RHS = R(Dot);
114936c1cd23SRui Ueyama       if (RHS == 0) {
115036c1cd23SRui Ueyama         error("division by zero");
115136c1cd23SRui Ueyama         return 0;
115236c1cd23SRui Ueyama       }
115336c1cd23SRui Ueyama       return L(Dot) / RHS;
115436c1cd23SRui Ueyama     };
115536c1cd23SRui Ueyama   }
115636c1cd23SRui Ueyama   if (Op == "+")
115736c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) + R(Dot); };
115836c1cd23SRui Ueyama   if (Op == "-")
115936c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) - R(Dot); };
116036c1cd23SRui Ueyama   if (Op == "<")
116136c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) < R(Dot); };
116236c1cd23SRui Ueyama   if (Op == ">")
116336c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) > R(Dot); };
116436c1cd23SRui Ueyama   if (Op == ">=")
116536c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) >= R(Dot); };
116636c1cd23SRui Ueyama   if (Op == "<=")
116736c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) <= R(Dot); };
116836c1cd23SRui Ueyama   if (Op == "==")
116936c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) == R(Dot); };
117036c1cd23SRui Ueyama   if (Op == "!=")
117136c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) != R(Dot); };
117236c1cd23SRui Ueyama   if (Op == "&")
117336c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) & R(Dot); };
1174cc3dd629SRafael Espindola   if (Op == "|")
1175cc3dd629SRafael Espindola     return [=](uint64_t Dot) { return L(Dot) | R(Dot); };
117636c1cd23SRui Ueyama   llvm_unreachable("invalid operator");
117736c1cd23SRui Ueyama }
117836c1cd23SRui Ueyama 
1179708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function
1180708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator.
1181708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
1182708019c4SRui Ueyama   while (!atEOF() && !Error) {
1183708019c4SRui Ueyama     // Read an operator and an expression.
1184708019c4SRui Ueyama     StringRef Op1 = peek();
1185708019c4SRui Ueyama     if (Op1 == "?")
1186708019c4SRui Ueyama       return readTernary(Lhs);
1187708019c4SRui Ueyama     if (precedence(Op1) < MinPrec)
1188a31c91b1SEugene Leviant       break;
1189a31c91b1SEugene Leviant     next();
1190708019c4SRui Ueyama     Expr Rhs = readPrimary();
1191708019c4SRui Ueyama 
1192708019c4SRui Ueyama     // Evaluate the remaining part of the expression first if the
1193708019c4SRui Ueyama     // next operator has greater precedence than the previous one.
1194708019c4SRui Ueyama     // For example, if we have read "+" and "3", and if the next
1195708019c4SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
1196708019c4SRui Ueyama     while (!atEOF()) {
1197708019c4SRui Ueyama       StringRef Op2 = peek();
1198708019c4SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
1199eda81a1bSEugene Leviant         break;
1200708019c4SRui Ueyama       Rhs = readExpr1(Rhs, precedence(Op2));
1201eda81a1bSEugene Leviant     }
1202708019c4SRui Ueyama 
1203708019c4SRui Ueyama     Lhs = combine(Op1, Lhs, Rhs);
1204708019c4SRui Ueyama   }
1205708019c4SRui Ueyama   return Lhs;
1206708019c4SRui Ueyama }
1207708019c4SRui Ueyama 
1208708019c4SRui Ueyama uint64_t static getConstant(StringRef S) {
1209e2cc07bcSMichael J. Spencer   if (S == "COMMONPAGESIZE")
1210708019c4SRui Ueyama     return Target->PageSize;
1211e2cc07bcSMichael J. Spencer   if (S == "MAXPAGESIZE")
1212e2cc07bcSMichael J. Spencer     return Target->MaxPageSize;
1213708019c4SRui Ueyama   error("unknown constant: " + S);
1214708019c4SRui Ueyama   return 0;
1215708019c4SRui Ueyama }
1216708019c4SRui Ueyama 
1217626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful.
1218626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H")
1219626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or
1220626e0b08SRui Ueyama // "M" (mega) prefixes.
12219f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) {
1222eaeafb2bSSimon Atanasyan   if (Tok.startswith("-")) {
1223eaeafb2bSSimon Atanasyan     if (!readInteger(Tok.substr(1), Result))
1224eaeafb2bSSimon Atanasyan       return false;
1225eaeafb2bSSimon Atanasyan     Result = -Result;
1226eaeafb2bSSimon Atanasyan     return true;
1227eaeafb2bSSimon Atanasyan   }
12289f2f7ad9SGeorge Rimar   if (Tok.startswith_lower("0x"))
12299f2f7ad9SGeorge Rimar     return !Tok.substr(2).getAsInteger(16, Result);
12309f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("H"))
12319f2f7ad9SGeorge Rimar     return !Tok.drop_back().getAsInteger(16, Result);
12329f2f7ad9SGeorge Rimar 
12339f2f7ad9SGeorge Rimar   int Suffix = 1;
12349f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("K")) {
12359f2f7ad9SGeorge Rimar     Suffix = 1024;
12369f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
12379f2f7ad9SGeorge Rimar   } else if (Tok.endswith_lower("M")) {
12389f2f7ad9SGeorge Rimar     Suffix = 1024 * 1024;
12399f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
12409f2f7ad9SGeorge Rimar   }
12419f2f7ad9SGeorge Rimar   if (Tok.getAsInteger(10, Result))
12429f2f7ad9SGeorge Rimar     return false;
12439f2f7ad9SGeorge Rimar   Result *= Suffix;
12449f2f7ad9SGeorge Rimar   return true;
12459f2f7ad9SGeorge Rimar }
12469f2f7ad9SGeorge Rimar 
1247708019c4SRui Ueyama Expr ScriptParser::readPrimary() {
12486ad7dfccSRui Ueyama   if (peek() == "(")
12496ad7dfccSRui Ueyama     return readParenExpr();
1250708019c4SRui Ueyama 
12516ad7dfccSRui Ueyama   StringRef Tok = next();
1252708019c4SRui Ueyama 
1253eaeafb2bSSimon Atanasyan   if (Tok == "~") {
1254eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
1255eaeafb2bSSimon Atanasyan     return [=](uint64_t Dot) { return ~E(Dot); };
1256eaeafb2bSSimon Atanasyan   }
1257eaeafb2bSSimon Atanasyan   if (Tok == "-") {
1258eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
1259eaeafb2bSSimon Atanasyan     return [=](uint64_t Dot) { return -E(Dot); };
1260eaeafb2bSSimon Atanasyan   }
1261eaeafb2bSSimon Atanasyan 
1262708019c4SRui Ueyama   // Built-in functions are parsed here.
1263708019c4SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
126496659df0SGeorge Rimar   if (Tok == "ADDR") {
126596659df0SGeorge Rimar     expect("(");
126696659df0SGeorge Rimar     StringRef Name = next();
126796659df0SGeorge Rimar     expect(")");
1268884e786dSGeorge Rimar     return
1269884e786dSGeorge Rimar         [=](uint64_t Dot) { return ScriptBase->getOutputSectionAddress(Name); };
127096659df0SGeorge Rimar   }
1271eefa758eSGeorge Rimar   if (Tok == "ASSERT")
1272eefa758eSGeorge Rimar     return readAssert();
1273708019c4SRui Ueyama   if (Tok == "ALIGN") {
12746ad7dfccSRui Ueyama     Expr E = readParenExpr();
1275708019c4SRui Ueyama     return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
1276708019c4SRui Ueyama   }
1277708019c4SRui Ueyama   if (Tok == "CONSTANT") {
1278708019c4SRui Ueyama     expect("(");
1279708019c4SRui Ueyama     StringRef Tok = next();
1280708019c4SRui Ueyama     expect(")");
1281708019c4SRui Ueyama     return [=](uint64_t Dot) { return getConstant(Tok); };
1282708019c4SRui Ueyama   }
128354c145ceSRafael Espindola   if (Tok == "SEGMENT_START") {
128454c145ceSRafael Espindola     expect("(");
128554c145ceSRafael Espindola     next();
128654c145ceSRafael Espindola     expect(",");
128754c145ceSRafael Espindola     uint64_t Val;
128854c145ceSRafael Espindola     next().getAsInteger(0, Val);
128954c145ceSRafael Espindola     expect(")");
129054c145ceSRafael Espindola     return [=](uint64_t Dot) { return Val; };
129154c145ceSRafael Espindola   }
1292708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_ALIGN") {
1293708019c4SRui Ueyama     expect("(");
1294708019c4SRui Ueyama     Expr E = readExpr();
1295708019c4SRui Ueyama     expect(",");
1296708019c4SRui Ueyama     readExpr();
1297708019c4SRui Ueyama     expect(")");
1298f7791bb9SRui Ueyama     return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
1299708019c4SRui Ueyama   }
1300708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_END") {
1301708019c4SRui Ueyama     expect("(");
1302708019c4SRui Ueyama     expect(".");
1303708019c4SRui Ueyama     expect(")");
1304708019c4SRui Ueyama     return [](uint64_t Dot) { return Dot; };
1305708019c4SRui Ueyama   }
1306276b4e64SGeorge Rimar   // GNU linkers implements more complicated logic to handle
1307276b4e64SGeorge Rimar   // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to
1308276b4e64SGeorge Rimar   // the next page boundary for simplicity.
1309276b4e64SGeorge Rimar   if (Tok == "DATA_SEGMENT_RELRO_END") {
1310276b4e64SGeorge Rimar     expect("(");
1311276b4e64SGeorge Rimar     next();
1312276b4e64SGeorge Rimar     expect(",");
1313276b4e64SGeorge Rimar     readExpr();
1314276b4e64SGeorge Rimar     expect(")");
1315276b4e64SGeorge Rimar     return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); };
1316276b4e64SGeorge Rimar   }
13179e69450eSGeorge Rimar   if (Tok == "SIZEOF") {
13189e69450eSGeorge Rimar     expect("(");
13199e69450eSGeorge Rimar     StringRef Name = next();
13209e69450eSGeorge Rimar     expect(")");
1321884e786dSGeorge Rimar     return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); };
13229e69450eSGeorge Rimar   }
132336fac7f0SEugene Leviant   if (Tok == "ALIGNOF") {
132436fac7f0SEugene Leviant     expect("(");
132536fac7f0SEugene Leviant     StringRef Name = next();
132636fac7f0SEugene Leviant     expect(")");
132736fac7f0SEugene Leviant     return
132836fac7f0SEugene Leviant         [=](uint64_t Dot) { return ScriptBase->getOutputSectionAlign(Name); };
132936fac7f0SEugene Leviant   }
1330e32a3598SGeorge Rimar   if (Tok == "SIZEOF_HEADERS")
1331884e786dSGeorge Rimar     return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); };
1332708019c4SRui Ueyama 
13339f2f7ad9SGeorge Rimar   // Tok is a literal number.
13349f2f7ad9SGeorge Rimar   uint64_t V;
13359f2f7ad9SGeorge Rimar   if (readInteger(Tok, V))
13369f2f7ad9SGeorge Rimar     return [=](uint64_t Dot) { return V; };
13379f2f7ad9SGeorge Rimar 
13389f2f7ad9SGeorge Rimar   // Tok is a symbol name.
133930835ea4SGeorge Rimar   if (Tok != "." && !isValidCIdentifier(Tok))
1340708019c4SRui Ueyama     setError("malformed number: " + Tok);
134130835ea4SGeorge Rimar   return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); };
1342a9c5a528SGeorge Rimar }
1343708019c4SRui Ueyama 
1344708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) {
1345708019c4SRui Ueyama   next();
1346708019c4SRui Ueyama   Expr L = readExpr();
1347708019c4SRui Ueyama   expect(":");
1348708019c4SRui Ueyama   Expr R = readExpr();
1349708019c4SRui Ueyama   return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); };
1350708019c4SRui Ueyama }
1351708019c4SRui Ueyama 
13526ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() {
13536ad7dfccSRui Ueyama   expect("(");
13546ad7dfccSRui Ueyama   Expr E = readExpr();
13556ad7dfccSRui Ueyama   expect(")");
13566ad7dfccSRui Ueyama   return E;
13576ad7dfccSRui Ueyama }
13586ad7dfccSRui Ueyama 
1359bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
1360bbe38602SEugene Leviant   std::vector<StringRef> Phdrs;
1361bbe38602SEugene Leviant   while (!Error && peek().startswith(":")) {
1362bbe38602SEugene Leviant     StringRef Tok = next();
1363bbe38602SEugene Leviant     Tok = (Tok.size() == 1) ? next() : Tok.substr(1);
1364bbe38602SEugene Leviant     if (Tok.empty()) {
1365bbe38602SEugene Leviant       setError("section header name is empty");
1366bbe38602SEugene Leviant       break;
1367bbe38602SEugene Leviant     }
1368bbe38602SEugene Leviant     Phdrs.push_back(Tok);
1369bbe38602SEugene Leviant   }
1370bbe38602SEugene Leviant   return Phdrs;
1371bbe38602SEugene Leviant }
1372bbe38602SEugene Leviant 
1373bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() {
1374bbe38602SEugene Leviant   StringRef Tok = next();
1375b0f6c590SRui Ueyama   unsigned Ret = StringSwitch<unsigned>(Tok)
1376b0f6c590SRui Ueyama                      .Case("PT_NULL", PT_NULL)
1377b0f6c590SRui Ueyama                      .Case("PT_LOAD", PT_LOAD)
1378b0f6c590SRui Ueyama                      .Case("PT_DYNAMIC", PT_DYNAMIC)
1379b0f6c590SRui Ueyama                      .Case("PT_INTERP", PT_INTERP)
1380b0f6c590SRui Ueyama                      .Case("PT_NOTE", PT_NOTE)
1381b0f6c590SRui Ueyama                      .Case("PT_SHLIB", PT_SHLIB)
1382b0f6c590SRui Ueyama                      .Case("PT_PHDR", PT_PHDR)
1383b0f6c590SRui Ueyama                      .Case("PT_TLS", PT_TLS)
1384b0f6c590SRui Ueyama                      .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
1385b0f6c590SRui Ueyama                      .Case("PT_GNU_STACK", PT_GNU_STACK)
1386b0f6c590SRui Ueyama                      .Case("PT_GNU_RELRO", PT_GNU_RELRO)
1387b0f6c590SRui Ueyama                      .Default(-1);
1388bbe38602SEugene Leviant 
1389b0f6c590SRui Ueyama   if (Ret == (unsigned)-1) {
1390b0f6c590SRui Ueyama     setError("invalid program header type: " + Tok);
1391b0f6c590SRui Ueyama     return PT_NULL;
1392b0f6c590SRui Ueyama   }
1393b0f6c590SRui Ueyama   return Ret;
1394bbe38602SEugene Leviant }
1395bbe38602SEugene Leviant 
139695769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) {
139720b6598cSGeorge Rimar   // Identifiers start at 2 because 0 and 1 are reserved
139820b6598cSGeorge Rimar   // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants.
139920b6598cSGeorge Rimar   size_t VersionId = Config->VersionDefinitions.size() + 2;
140020b6598cSGeorge Rimar   Config->VersionDefinitions.push_back({VerStr, VersionId});
140120b6598cSGeorge Rimar 
140220b6598cSGeorge Rimar   if (skip("global:") || peek() != "local:")
140320b6598cSGeorge Rimar     readGlobal(VerStr);
140420b6598cSGeorge Rimar   if (skip("local:"))
140520b6598cSGeorge Rimar     readLocal();
140620b6598cSGeorge Rimar   expect("}");
140720b6598cSGeorge Rimar 
140820b6598cSGeorge Rimar   // Each version may have a parent version. For example, "Ver2" defined as
140920b6598cSGeorge Rimar   // "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This
141020b6598cSGeorge Rimar   // version hierarchy is, probably against your instinct, purely for human; the
141120b6598cSGeorge Rimar   // runtime doesn't care about them at all. In LLD, we simply skip the token.
141220b6598cSGeorge Rimar   if (!VerStr.empty() && peek() != ";")
141320b6598cSGeorge Rimar     next();
141420b6598cSGeorge Rimar   expect(";");
141520b6598cSGeorge Rimar }
141620b6598cSGeorge Rimar 
141720b6598cSGeorge Rimar void ScriptParser::readLocal() {
141820b6598cSGeorge Rimar   Config->DefaultSymbolVersion = VER_NDX_LOCAL;
141920b6598cSGeorge Rimar   expect("*");
142020b6598cSGeorge Rimar   expect(";");
142120b6598cSGeorge Rimar }
142220b6598cSGeorge Rimar 
142320b6598cSGeorge Rimar void ScriptParser::readExtern(std::vector<SymbolVersion> *Globals) {
1424*cd574a5eSGeorge Rimar   expect("\"C++\"");
142520b6598cSGeorge Rimar   expect("{");
142620b6598cSGeorge Rimar 
142720b6598cSGeorge Rimar   for (;;) {
142820b6598cSGeorge Rimar     if (peek() == "}" || Error)
142920b6598cSGeorge Rimar       break;
1430*cd574a5eSGeorge Rimar     bool HasWildcard = !peek().startswith("\"") && hasWildcard(peek());
1431*cd574a5eSGeorge Rimar     Globals->push_back({unquote(next()), true, HasWildcard});
143220b6598cSGeorge Rimar     expect(";");
143320b6598cSGeorge Rimar   }
143420b6598cSGeorge Rimar 
143520b6598cSGeorge Rimar   expect("}");
143620b6598cSGeorge Rimar   expect(";");
143720b6598cSGeorge Rimar }
143820b6598cSGeorge Rimar 
143920b6598cSGeorge Rimar void ScriptParser::readGlobal(StringRef VerStr) {
144020b6598cSGeorge Rimar   std::vector<SymbolVersion> *Globals;
144120b6598cSGeorge Rimar   if (VerStr.empty())
144220b6598cSGeorge Rimar     Globals = &Config->VersionScriptGlobals;
144320b6598cSGeorge Rimar   else
144420b6598cSGeorge Rimar     Globals = &Config->VersionDefinitions.back().Globals;
144520b6598cSGeorge Rimar 
144620b6598cSGeorge Rimar   for (;;) {
144720b6598cSGeorge Rimar     if (skip("extern"))
144820b6598cSGeorge Rimar       readExtern(Globals);
144920b6598cSGeorge Rimar 
145020b6598cSGeorge Rimar     StringRef Cur = peek();
145120b6598cSGeorge Rimar     if (Cur == "}" || Cur == "local:" || Error)
145220b6598cSGeorge Rimar       return;
145320b6598cSGeorge Rimar     next();
1454*cd574a5eSGeorge Rimar     Globals->push_back({unquote(Cur), false, hasWildcard(Cur)});
145520b6598cSGeorge Rimar     expect(";");
145620b6598cSGeorge Rimar   }
145720b6598cSGeorge Rimar }
145820b6598cSGeorge Rimar 
145916b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) {
146016b0cc9eSSimon Atanasyan   if (Config->Sysroot == "")
146116b0cc9eSSimon Atanasyan     return false;
146216b0cc9eSSimon Atanasyan   for (; !Path.empty(); Path = sys::path::parent_path(Path))
146316b0cc9eSSimon Atanasyan     if (sys::fs::equivalent(Config->Sysroot, Path))
146416b0cc9eSSimon Atanasyan       return true;
146516b0cc9eSSimon Atanasyan   return false;
146616b0cc9eSSimon Atanasyan }
146716b0cc9eSSimon Atanasyan 
146807320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) {
146916b0cc9eSSimon Atanasyan   StringRef Path = MB.getBufferIdentifier();
147020b6598cSGeorge Rimar   ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).readLinkerScript();
147120b6598cSGeorge Rimar }
147220b6598cSGeorge Rimar 
147320b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) {
147420b6598cSGeorge Rimar   ScriptParser(MB.getBuffer(), false).readVersionScript();
1475f7c5fbb1SRui Ueyama }
14761ebc8ed7SRui Ueyama 
147707320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>;
147807320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>;
147907320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>;
148007320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>;
1481