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 
4407320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig;
45717677afSRui Ueyama 
46ceabe80eSEugene Leviant template <class ELFT>
471602421cSRui Ueyama 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 
591602421cSRui Ueyama // If a symbol was in PROVIDE(), we need to define it only when
601602421cSRui Ueyama // it is an undefined symbol.
611602421cSRui Ueyama template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) {
621602421cSRui Ueyama   if (Cmd->Name == ".")
63ceabe80eSEugene Leviant     return false;
641602421cSRui Ueyama   if (!Cmd->Provide)
65ceabe80eSEugene Leviant     return true;
661602421cSRui Ueyama   SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name);
671602421cSRui Ueyama   return B && B->isUndefined();
68ceabe80eSEugene Leviant }
69ceabe80eSEugene Leviant 
70076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
71076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
72076fe157SGeorge Rimar }
73076fe157SGeorge Rimar 
74076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
75076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
76076fe157SGeorge Rimar }
77076fe157SGeorge Rimar 
78eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
79eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
80eea3114fSGeorge Rimar }
81eea3114fSGeorge Rimar 
82eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) {
83eefa758eSGeorge Rimar   return C->Kind == AssertKind;
84eefa758eSGeorge Rimar }
85eefa758eSGeorge Rimar 
8636a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) {
87eea3114fSGeorge Rimar   return !S || !S->Live;
88717677afSRui Ueyama }
89717677afSRui Ueyama 
90f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::LinkerScript() {}
91f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::~LinkerScript() {}
92f34d0e08SRui Ueyama 
9307320e40SRui Ueyama template <class ELFT>
9407320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) {
95c91930a1SGeorge Rimar   for (Regex *Re : Opt.KeptSections)
96c91930a1SGeorge Rimar     if (Re->match(S->getSectionName()))
97eea3114fSGeorge Rimar       return true;
98eea3114fSGeorge Rimar   return false;
99eea3114fSGeorge Rimar }
100eea3114fSGeorge Rimar 
1010659800eSGeorge Rimar static bool fileMatches(const InputSectionDescription *Desc,
1020659800eSGeorge Rimar                         StringRef Filename) {
103c91930a1SGeorge Rimar   return const_cast<Regex &>(Desc->FileRe).match(Filename) &&
104c91930a1SGeorge Rimar          !const_cast<Regex &>(Desc->ExcludedFileRe).match(Filename);
1050659800eSGeorge Rimar }
1060659800eSGeorge Rimar 
1076b274810SRui Ueyama // Returns input sections filtered by given glob patterns.
1086b274810SRui Ueyama template <class ELFT>
1096b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *>
110ad10c3d8SRui Ueyama LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) {
111c91930a1SGeorge Rimar   const Regex &Re = I->SectionRe;
1126b274810SRui Ueyama   std::vector<InputSectionBase<ELFT> *> Ret;
1136b274810SRui Ueyama   for (const std::unique_ptr<ObjectFile<ELFT>> &F :
1140659800eSGeorge Rimar        Symtab<ELFT>::X->getObjectFiles()) {
1150659800eSGeorge Rimar     if (fileMatches(I, sys::path::filename(F->getName())))
1166b274810SRui Ueyama       for (InputSectionBase<ELFT> *S : F->getSections())
1170659800eSGeorge Rimar         if (!isDiscarded(S) && !S->OutSec &&
118c91930a1SGeorge Rimar             const_cast<Regex &>(Re).match(S->getSectionName()))
1196b274810SRui Ueyama           Ret.push_back(S);
1200659800eSGeorge Rimar   }
1213e6b0277SEugene Leviant 
122c91930a1SGeorge Rimar   if (const_cast<Regex &>(Re).match("COMMON"))
123ad10c3d8SRui Ueyama     Ret.push_back(CommonInputSection<ELFT>::X);
1246b274810SRui Ueyama   return Ret;
1256b274810SRui Ueyama }
1266b274810SRui Ueyama 
127ceabe80eSEugene Leviant template <class ELFT>
128742c3836SRui Ueyama static bool compareName(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) {
129742c3836SRui Ueyama   return A->getSectionName() < B->getSectionName();
1300702c4e8SGeorge Rimar }
131742c3836SRui Ueyama 
132742c3836SRui Ueyama template <class ELFT>
133742c3836SRui Ueyama static bool compareAlignment(InputSectionBase<ELFT> *A,
134742c3836SRui Ueyama                              InputSectionBase<ELFT> *B) {
135742c3836SRui Ueyama   // ">" is not a mistake. Larger alignments are placed before smaller
136742c3836SRui Ueyama   // alignments in order to reduce the amount of padding necessary.
137742c3836SRui Ueyama   // This is compatible with GNU.
138742c3836SRui Ueyama   return A->Alignment > B->Alignment;
139742c3836SRui Ueyama }
140742c3836SRui Ueyama 
141742c3836SRui Ueyama template <class ELFT>
142742c3836SRui Ueyama static std::function<bool(InputSectionBase<ELFT> *, InputSectionBase<ELFT> *)>
143742c3836SRui Ueyama getComparator(SortKind K) {
144742c3836SRui Ueyama   if (K == SortByName)
145742c3836SRui Ueyama     return compareName<ELFT>;
146742c3836SRui Ueyama   return compareAlignment<ELFT>;
147742c3836SRui Ueyama }
1480702c4e8SGeorge Rimar 
1490702c4e8SGeorge Rimar template <class ELFT>
15048c3f1ceSRui Ueyama void LinkerScript<ELFT>::discard(OutputSectionCommand &Cmd) {
15148c3f1ceSRui Ueyama   for (const std::unique_ptr<BaseCommand> &Base : Cmd.Commands) {
15248c3f1ceSRui Ueyama     if (auto *Cmd = dyn_cast<InputSectionDescription>(Base.get())) {
15348c3f1ceSRui Ueyama       for (InputSectionBase<ELFT> *S : getInputSections(Cmd)) {
15448c3f1ceSRui Ueyama         S->Live = false;
15548c3f1ceSRui Ueyama         reportDiscarded(S);
15648c3f1ceSRui Ueyama       }
15748c3f1ceSRui Ueyama     }
15848c3f1ceSRui Ueyama   }
15948c3f1ceSRui Ueyama }
16048c3f1ceSRui Ueyama 
1618f66df92SGeorge Rimar static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) {
1628f66df92SGeorge Rimar   bool RO = (Kind == ConstraintKind::ReadOnly);
1638f66df92SGeorge Rimar   bool RW = (Kind == ConstraintKind::ReadWrite);
1648f66df92SGeorge Rimar   bool Writable = Flags & SHF_WRITE;
1658f66df92SGeorge Rimar   return !((RO && Writable) || (RW && !Writable));
1668f66df92SGeorge Rimar }
1678f66df92SGeorge Rimar 
16848c3f1ceSRui Ueyama template <class ELFT>
16906ae6836SGeorge Rimar static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections,
17006ae6836SGeorge Rimar                              ConstraintKind Kind) {
1718f66df92SGeorge Rimar   if (Kind == ConstraintKind::NoConstraint)
1728f66df92SGeorge Rimar     return true;
1738f66df92SGeorge Rimar   return llvm::all_of(Sections, [=](InputSectionBase<ELFT> *Sec) {
1748f66df92SGeorge Rimar     return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind);
17506ae6836SGeorge Rimar   });
17606ae6836SGeorge Rimar }
17706ae6836SGeorge Rimar 
17806ae6836SGeorge Rimar template <class ELFT>
1790b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *>
18006ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
1810b9ce6a4SRui Ueyama   std::vector<InputSectionBase<ELFT> *> Ret;
18297403d15SEugene Leviant   DenseSet<InputSectionBase<ELFT> *> SectionIndex;
183e7f912cdSRui Ueyama 
18406ae6836SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) {
18506ae6836SGeorge Rimar     if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) {
18606ae6836SGeorge Rimar       if (shouldDefine<ELFT>(OutCmd))
18706ae6836SGeorge Rimar         addSynthetic<ELFT>(OutCmd);
18897403d15SEugene Leviant       OutCmd->GoesAfter = Ret.empty() ? nullptr : Ret.back();
1890b9ce6a4SRui Ueyama       continue;
1900b9ce6a4SRui Ueyama     }
1910b9ce6a4SRui Ueyama 
1920b9ce6a4SRui Ueyama     auto *Cmd = cast<InputSectionDescription>(Base.get());
1930b9ce6a4SRui Ueyama     std::vector<InputSectionBase<ELFT> *> V = getInputSections(Cmd);
19406ae6836SGeorge Rimar     if (!matchConstraints<ELFT>(V, OutCmd.Constraint))
19506ae6836SGeorge Rimar       continue;
1960b9ce6a4SRui Ueyama     if (Cmd->SortInner)
1970b9ce6a4SRui Ueyama       std::stable_sort(V.begin(), V.end(), getComparator<ELFT>(Cmd->SortInner));
1980b9ce6a4SRui Ueyama     if (Cmd->SortOuter)
1990b9ce6a4SRui Ueyama       std::stable_sort(V.begin(), V.end(), getComparator<ELFT>(Cmd->SortOuter));
20097403d15SEugene Leviant 
20197403d15SEugene Leviant     // Add all input sections corresponding to rule 'Cmd' to
20297403d15SEugene Leviant     // resulting vector. We do not add duplicate input sections.
20397403d15SEugene Leviant     for (InputSectionBase<ELFT> *S : V)
20497403d15SEugene Leviant       if (SectionIndex.insert(S).second)
20597403d15SEugene Leviant         Ret.push_back(S);
2060b9ce6a4SRui Ueyama   }
2070b9ce6a4SRui Ueyama   return Ret;
2080b9ce6a4SRui Ueyama }
2090b9ce6a4SRui Ueyama 
2100b9ce6a4SRui Ueyama template <class ELFT>
211e5d3ca50SPetr Hosek void LinkerScript<ELFT>::createAssignments() {
212e5d3ca50SPetr Hosek   for (const std::unique_ptr<SymbolAssignment> &Cmd : Opt.Assignments) {
213e5d3ca50SPetr Hosek     if (shouldDefine<ELFT>(Cmd.get()))
214e5d3ca50SPetr Hosek       addRegular<ELFT>(Cmd.get());
215e5d3ca50SPetr Hosek     if (Cmd->Sym)
216e5d3ca50SPetr Hosek       cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0);
217e5d3ca50SPetr Hosek   }
218e5d3ca50SPetr Hosek }
219e5d3ca50SPetr Hosek 
220e5d3ca50SPetr Hosek template <class ELFT>
2210b9ce6a4SRui Ueyama void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
22248c3f1ceSRui Ueyama   for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) {
2232ab5f73dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) {
2242ab5f73dSRui Ueyama       if (shouldDefine<ELFT>(Cmd))
2252ab5f73dSRui Ueyama         addRegular<ELFT>(Cmd);
2262ab5f73dSRui Ueyama       continue;
2272ab5f73dSRui Ueyama     }
2282ab5f73dSRui Ueyama 
229ceabe80eSEugene Leviant     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) {
23048c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
23148c3f1ceSRui Ueyama         discard(*Cmd);
23248c3f1ceSRui Ueyama         continue;
23348c3f1ceSRui Ueyama       }
2340b9ce6a4SRui Ueyama 
2350b9ce6a4SRui Ueyama       std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd);
23697403d15SEugene Leviant       if (V.empty())
2370b9ce6a4SRui Ueyama         continue;
2380b9ce6a4SRui Ueyama 
2390b9ce6a4SRui Ueyama       OutputSectionBase<ELFT> *OutSec;
2400b9ce6a4SRui Ueyama       bool IsNew;
24197403d15SEugene Leviant       std::tie(OutSec, IsNew) = Factory.create(V.front(), Cmd->Name);
2420b9ce6a4SRui Ueyama       if (IsNew)
2430b9ce6a4SRui Ueyama         OutputSections->push_back(OutSec);
244db24d9c3SGeorge Rimar 
245db24d9c3SGeorge Rimar       uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0;
246db24d9c3SGeorge Rimar       for (InputSectionBase<ELFT> *Sec : V) {
247db24d9c3SGeorge Rimar         if (Subalign)
248db24d9c3SGeorge Rimar           Sec->Alignment = Subalign;
2490b9ce6a4SRui Ueyama         OutSec->addSection(Sec);
250eea3114fSGeorge Rimar       }
25148c3f1ceSRui Ueyama     }
252db24d9c3SGeorge Rimar   }
253e63d81bdSEugene Leviant 
2540b9ce6a4SRui Ueyama   // Add orphan sections.
2556b274810SRui Ueyama   for (const std::unique_ptr<ObjectFile<ELFT>> &F :
2560b9ce6a4SRui Ueyama        Symtab<ELFT>::X->getObjectFiles()) {
2570b9ce6a4SRui Ueyama     for (InputSectionBase<ELFT> *S : F->getSections()) {
2582ab5f73dSRui Ueyama       if (isDiscarded(S) || S->OutSec)
2592ab5f73dSRui Ueyama         continue;
2600b9ce6a4SRui Ueyama       OutputSectionBase<ELFT> *OutSec;
2610b9ce6a4SRui Ueyama       bool IsNew;
2620b9ce6a4SRui Ueyama       std::tie(OutSec, IsNew) = Factory.create(S, getOutputSectionName(S));
2630b9ce6a4SRui Ueyama       if (IsNew)
2640b9ce6a4SRui Ueyama         OutputSections->push_back(OutSec);
2650b9ce6a4SRui Ueyama       OutSec->addSection(S);
2660b9ce6a4SRui Ueyama     }
2670b9ce6a4SRui Ueyama   }
268e63d81bdSEugene Leviant }
269e63d81bdSEugene Leviant 
27020889c51SEugene Leviant // Linker script may define start and end symbols for special section types,
27120889c51SEugene Leviant // like .got, .eh_frame_hdr, .eh_frame and others. Those sections are not a list
27220889c51SEugene Leviant // of regular input input sections, therefore our way of defining symbols for
27320889c51SEugene Leviant // regular sections will not work. The approach we use for special section types
27420889c51SEugene Leviant // is not perfect - it handles only start and end symbols.
27520889c51SEugene Leviant template <class ELFT>
27620889c51SEugene Leviant void addStartEndSymbols(OutputSectionCommand *Cmd,
27720889c51SEugene Leviant                         OutputSectionBase<ELFT> *Sec) {
27820889c51SEugene Leviant   bool Start = true;
27920889c51SEugene Leviant   BaseCommand *PrevCmd = nullptr;
28020889c51SEugene Leviant 
28120889c51SEugene Leviant   for (std::unique_ptr<BaseCommand> &Base : Cmd->Commands) {
28220889c51SEugene Leviant     if (auto *AssignCmd = dyn_cast<SymbolAssignment>(Base.get())) {
28320889c51SEugene Leviant       if (auto *Sym = cast_or_null<DefinedSynthetic<ELFT>>(AssignCmd->Sym)) {
28420889c51SEugene Leviant         Sym->Section = Sec;
28520889c51SEugene Leviant         Sym->Value =
28620889c51SEugene Leviant             AssignCmd->Expression(Sec->getVA() + (Start ? 0 : Sec->getSize())) -
28720889c51SEugene Leviant             Sec->getVA();
28820889c51SEugene Leviant       }
28920889c51SEugene Leviant     } else {
29020889c51SEugene Leviant       if (!Start && isa<SymbolAssignment>(PrevCmd))
29120889c51SEugene Leviant         error("section '" + Sec->getName() +
29220889c51SEugene Leviant               "' supports only start and end symbols");
29320889c51SEugene Leviant       Start = false;
29420889c51SEugene Leviant     }
29520889c51SEugene Leviant     PrevCmd = Base.get();
29620889c51SEugene Leviant   }
29720889c51SEugene Leviant }
29820889c51SEugene Leviant 
29920889c51SEugene Leviant template <class ELFT>
30020889c51SEugene Leviant void assignOffsets(OutputSectionCommand *Cmd, OutputSectionBase<ELFT> *Sec) {
301ceabe80eSEugene Leviant   auto *OutSec = dyn_cast<OutputSection<ELFT>>(Sec);
3022de509c3SRui Ueyama   if (!OutSec) {
3032de509c3SRui Ueyama     Sec->assignOffsets();
30420889c51SEugene Leviant     // This section is not regular output section. However linker script may
30520889c51SEugene Leviant     // have defined start/end symbols for it. This case is handled below.
30620889c51SEugene Leviant     addStartEndSymbols(Cmd, Sec);
307ceabe80eSEugene Leviant     return;
3082de509c3SRui Ueyama   }
309ceabe80eSEugene Leviant   typedef typename ELFT::uint uintX_t;
310ceabe80eSEugene Leviant   uintX_t Off = 0;
31197403d15SEugene Leviant   auto ItCmd = Cmd->Commands.begin();
312ceabe80eSEugene Leviant 
31397403d15SEugene Leviant   // Assigns values to all symbols following the given
31497403d15SEugene Leviant   // input section 'D' in output section 'Sec'. When symbols
31597403d15SEugene Leviant   // are in the beginning of output section the value of 'D'
31697403d15SEugene Leviant   // is nullptr.
31797403d15SEugene Leviant   auto AssignSuccessors = [&](InputSectionData *D) {
31897403d15SEugene Leviant     for (; ItCmd != Cmd->Commands.end(); ++ItCmd) {
31997403d15SEugene Leviant       auto *AssignCmd = dyn_cast<SymbolAssignment>(ItCmd->get());
32097403d15SEugene Leviant       if (!AssignCmd)
32197403d15SEugene Leviant         continue;
32297403d15SEugene Leviant       if (D != AssignCmd->GoesAfter)
32397403d15SEugene Leviant         break;
32497403d15SEugene Leviant 
32597403d15SEugene Leviant       uintX_t Value = AssignCmd->Expression(Sec->getVA() + Off) - Sec->getVA();
32697403d15SEugene Leviant       if (AssignCmd->Name == ".") {
32797403d15SEugene Leviant         // Update to location counter means update to section size.
328ceabe80eSEugene Leviant         Off = Value;
32997403d15SEugene Leviant         Sec->setSize(Off);
33097403d15SEugene Leviant         continue;
33197403d15SEugene Leviant       }
33297403d15SEugene Leviant 
33397403d15SEugene Leviant       if (DefinedSynthetic<ELFT> *Sym =
33497403d15SEugene Leviant               cast_or_null<DefinedSynthetic<ELFT>>(AssignCmd->Sym)) {
3350c70d3ccSRui Ueyama         Sym->Section = OutSec;
3360c70d3ccSRui Ueyama         Sym->Value = Value;
3370c70d3ccSRui Ueyama       }
33897403d15SEugene Leviant     }
33997403d15SEugene Leviant   };
34097403d15SEugene Leviant 
34197403d15SEugene Leviant   AssignSuccessors(nullptr);
34297403d15SEugene Leviant   for (InputSection<ELFT> *I : OutSec->Sections) {
343ceabe80eSEugene Leviant     Off = alignTo(Off, I->Alignment);
344ceabe80eSEugene Leviant     I->OutSecOff = Off;
345ceabe80eSEugene Leviant     Off += I->getSize();
346ceabe80eSEugene Leviant     // Update section size inside for-loop, so that SIZEOF
347ceabe80eSEugene Leviant     // works correctly in the case below:
348ceabe80eSEugene Leviant     // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
349ceabe80eSEugene Leviant     Sec->setSize(Off);
35097403d15SEugene Leviant     // Add symbols following current input section.
35197403d15SEugene Leviant     AssignSuccessors(I);
352ceabe80eSEugene Leviant   }
353ceabe80eSEugene Leviant }
354ceabe80eSEugene Leviant 
3558f66df92SGeorge Rimar template <class ELFT>
3568f66df92SGeorge Rimar static OutputSectionBase<ELFT> *
3578f66df92SGeorge Rimar findSection(OutputSectionCommand &Cmd,
3588f66df92SGeorge Rimar             ArrayRef<OutputSectionBase<ELFT> *> Sections) {
3598f66df92SGeorge Rimar   for (OutputSectionBase<ELFT> *Sec : Sections) {
3608f66df92SGeorge Rimar     if (Sec->getName() != Cmd.Name)
3618f66df92SGeorge Rimar       continue;
3628f66df92SGeorge Rimar     if (checkConstraint(Sec->getFlags(), Cmd.Constraint))
3638f66df92SGeorge Rimar       return Sec;
3648f66df92SGeorge Rimar   }
3658f66df92SGeorge Rimar   return nullptr;
3668f66df92SGeorge Rimar }
3678f66df92SGeorge Rimar 
368a4b41dcaSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::assignAddresses() {
369652852c5SGeorge Rimar   // Orphan sections are sections present in the input files which
3707c18c28cSRui Ueyama   // are not explicitly placed into the output file by the linker script.
3717c18c28cSRui Ueyama   // We place orphan sections at end of file.
3727c18c28cSRui Ueyama   // Other linkers places them using some heuristics as described in
373652852c5SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections.
374e5cc668eSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
375652852c5SGeorge Rimar     StringRef Name = Sec->getName();
376c3e2a4b0SRui Ueyama     if (getSectionIndex(Name) == INT_MAX)
377076fe157SGeorge Rimar       Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name));
378652852c5SGeorge Rimar   }
379652852c5SGeorge Rimar 
3807c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
3814f7500bfSRui Ueyama   Dot = getHeaderSize();
382467c4d55SEugene Leviant   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
383652852c5SGeorge Rimar   uintX_t ThreadBssOffset = 0;
384652852c5SGeorge Rimar 
385076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
386076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
3878d083e6aSRui Ueyama       if (Cmd->Name == ".") {
3888d083e6aSRui Ueyama         Dot = Cmd->Expression(Dot);
3898d083e6aSRui Ueyama       } else if (Cmd->Sym) {
3908d083e6aSRui Ueyama         cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot);
3918d083e6aSRui Ueyama       }
39205ef4cffSRui Ueyama       continue;
393652852c5SGeorge Rimar     }
394652852c5SGeorge Rimar 
395eefa758eSGeorge Rimar     if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) {
396eefa758eSGeorge Rimar       Cmd->Expression(Dot);
397eefa758eSGeorge Rimar       continue;
398eefa758eSGeorge Rimar     }
399eefa758eSGeorge Rimar 
400076fe157SGeorge Rimar     auto *Cmd = cast<OutputSectionCommand>(Base.get());
4018f66df92SGeorge Rimar     OutputSectionBase<ELFT> *Sec = findSection<ELFT>(*Cmd, *OutputSections);
4028f66df92SGeorge Rimar     if (!Sec)
403652852c5SGeorge Rimar       continue;
404652852c5SGeorge Rimar 
40558e5c4dcSGeorge Rimar     if (Cmd->AddrExpr)
40658e5c4dcSGeorge Rimar       Dot = Cmd->AddrExpr(Dot);
40758e5c4dcSGeorge Rimar 
408630c6179SGeorge Rimar     if (Cmd->AlignExpr)
409630c6179SGeorge Rimar       Sec->updateAlignment(Cmd->AlignExpr(Dot));
410630c6179SGeorge Rimar 
411652852c5SGeorge Rimar     if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
412c998a8c0SRui Ueyama       uintX_t TVA = Dot + ThreadBssOffset;
413424b4081SRui Ueyama       TVA = alignTo(TVA, Sec->getAlignment());
414652852c5SGeorge Rimar       Sec->setVA(TVA);
41520889c51SEugene Leviant       assignOffsets(Cmd, Sec);
416c998a8c0SRui Ueyama       ThreadBssOffset = TVA - Dot + Sec->getSize();
417652852c5SGeorge Rimar       continue;
418652852c5SGeorge Rimar     }
419652852c5SGeorge Rimar 
420b6c52e8dSGeorge Rimar     if (!(Sec->getFlags() & SHF_ALLOC)) {
42120889c51SEugene Leviant       assignOffsets(Cmd, Sec);
422b6c52e8dSGeorge Rimar       continue;
423b6c52e8dSGeorge Rimar     }
424b6c52e8dSGeorge Rimar 
425424b4081SRui Ueyama     Dot = alignTo(Dot, Sec->getAlignment());
426c998a8c0SRui Ueyama     Sec->setVA(Dot);
42720889c51SEugene Leviant     assignOffsets(Cmd, Sec);
428467c4d55SEugene Leviant     MinVA = std::min(MinVA, Dot);
429c998a8c0SRui Ueyama     Dot += Sec->getSize();
430652852c5SGeorge Rimar   }
431467c4d55SEugene Leviant 
43264c32d6fSRafael Espindola   // ELF and Program headers need to be right before the first section in
433b91e7118SGeorge Rimar   // memory. Set their addresses accordingly.
434467c4d55SEugene Leviant   MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() -
435467c4d55SEugene Leviant                         Out<ELFT>::ProgramHeaders->getSize(),
436467c4d55SEugene Leviant                     Target->PageSize);
437467c4d55SEugene Leviant   Out<ELFT>::ElfHeader->setVA(MinVA);
438467c4d55SEugene Leviant   Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA);
439fb8978fcSDima Stepanov }
440652852c5SGeorge Rimar 
441464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
44207320e40SRui Ueyama template <class ELFT>
443a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() {
444edebbdf1SRui Ueyama   std::vector<PhdrEntry<ELFT>> Ret;
445bbe38602SEugene Leviant 
446464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
447464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
448bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
449edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
450edebbdf1SRui Ueyama     PhdrEntry<ELFT> &Phdr = Ret.back();
451bbe38602SEugene Leviant 
452bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
453adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ElfHeader);
454bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
455adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ProgramHeaders);
456bbe38602SEugene Leviant   }
457bbe38602SEugene Leviant 
458464daadcSRui Ueyama   // Add output sections to program headers.
459edebbdf1SRui Ueyama   PhdrEntry<ELFT> *Load = nullptr;
460edebbdf1SRui Ueyama   uintX_t Flags = PF_R;
461464daadcSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
462bbe38602SEugene Leviant     if (!(Sec->getFlags() & SHF_ALLOC))
463bbe38602SEugene Leviant       break;
464bbe38602SEugene Leviant 
465edebbdf1SRui Ueyama     std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName());
466bbe38602SEugene Leviant     if (!PhdrIds.empty()) {
467bbe38602SEugene Leviant       // Assign headers specified by linker script
468bbe38602SEugene Leviant       for (size_t Id : PhdrIds) {
469edebbdf1SRui Ueyama         Ret[Id].add(Sec);
470865bf863SEugene Leviant         if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
4710b113671SRafael Espindola           Ret[Id].H.p_flags |= Sec->getPhdrFlags();
472bbe38602SEugene Leviant       }
473bbe38602SEugene Leviant     } else {
474bbe38602SEugene Leviant       // If we have no load segment or flags've changed then we want new load
475bbe38602SEugene Leviant       // segment.
4760b113671SRafael Espindola       uintX_t NewFlags = Sec->getPhdrFlags();
477bbe38602SEugene Leviant       if (Load == nullptr || Flags != NewFlags) {
478edebbdf1SRui Ueyama         Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags);
479bbe38602SEugene Leviant         Flags = NewFlags;
480bbe38602SEugene Leviant       }
48118f084ffSRui Ueyama       Load->add(Sec);
482bbe38602SEugene Leviant     }
483bbe38602SEugene Leviant   }
484edebbdf1SRui Ueyama   return Ret;
485bbe38602SEugene Leviant }
486bbe38602SEugene Leviant 
487f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() {
488f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
489f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
490f9bc3bd2SEugene Leviant   return !Opt.PhdrsCommands.empty() &&
491f9bc3bd2SEugene Leviant          llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) {
492f9bc3bd2SEugene Leviant            return Cmd.Type == PT_INTERP;
493f9bc3bd2SEugene Leviant          }) == Opt.PhdrsCommands.end();
494f9bc3bd2SEugene Leviant }
495f9bc3bd2SEugene Leviant 
496bbe38602SEugene Leviant template <class ELFT>
49707320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) {
498f6c3ccefSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
499f6c3ccefSGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
500f6c3ccefSGeorge Rimar       if (Cmd->Name == Name)
501f6c3ccefSGeorge Rimar         return Cmd->Filler;
502e2ee72b5SGeorge Rimar   return {};
503e2ee72b5SGeorge Rimar }
504e2ee72b5SGeorge Rimar 
505206fffa1SGeorge Rimar template <class ELFT> Expr LinkerScript<ELFT>::getLma(StringRef Name) {
5068ceadb38SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
5078ceadb38SGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
5088ceadb38SGeorge Rimar       if (Cmd->LmaExpr && Cmd->Name == Name)
5098ceadb38SGeorge Rimar         return Cmd->LmaExpr;
5108ceadb38SGeorge Rimar   return {};
5118ceadb38SGeorge Rimar }
5128ceadb38SGeorge Rimar 
513c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script
514c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they
515c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script,
516c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file.
517076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) {
518f510fa6bSRui Ueyama   int I = 0;
519f510fa6bSRui Ueyama   for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
520076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
521076fe157SGeorge Rimar       if (Cmd->Name == Name)
522f510fa6bSRui Ueyama         return I;
523f510fa6bSRui Ueyama     ++I;
524f510fa6bSRui Ueyama   }
525f510fa6bSRui Ueyama   return INT_MAX;
52671b26e94SGeorge Rimar }
52771b26e94SGeorge Rimar 
52871b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if
52971b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0.
53007320e40SRui Ueyama template <class ELFT>
53107320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) {
532c3e2a4b0SRui Ueyama   int I = getSectionIndex(A);
533c3e2a4b0SRui Ueyama   int J = getSectionIndex(B);
534c3e2a4b0SRui Ueyama   if (I == INT_MAX && J == INT_MAX)
535717677afSRui Ueyama     return 0;
536717677afSRui Ueyama   return I < J ? -1 : 1;
537717677afSRui Ueyama }
538717677afSRui Ueyama 
539bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
540bbe38602SEugene Leviant   return !Opt.PhdrsCommands.empty();
541bbe38602SEugene Leviant }
542bbe38602SEugene Leviant 
5439e69450eSGeorge Rimar template <class ELFT>
54496659df0SGeorge Rimar typename ELFT::uint
54596659df0SGeorge Rimar LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) {
54696659df0SGeorge Rimar   for (OutputSectionBase<ELFT> *Sec : *OutputSections)
54796659df0SGeorge Rimar     if (Sec->getName() == Name)
54896659df0SGeorge Rimar       return Sec->getVA();
54996659df0SGeorge Rimar   error("undefined section " + Name);
55096659df0SGeorge Rimar   return 0;
55196659df0SGeorge Rimar }
55296659df0SGeorge Rimar 
55396659df0SGeorge Rimar template <class ELFT>
5549e69450eSGeorge Rimar typename ELFT::uint LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
5559e69450eSGeorge Rimar   for (OutputSectionBase<ELFT> *Sec : *OutputSections)
5569e69450eSGeorge Rimar     if (Sec->getName() == Name)
5579e69450eSGeorge Rimar       return Sec->getSize();
5589e69450eSGeorge Rimar   error("undefined section " + Name);
5599e69450eSGeorge Rimar   return 0;
5609e69450eSGeorge Rimar }
5619e69450eSGeorge Rimar 
562e32a3598SGeorge Rimar template <class ELFT>
5634f7500bfSRui Ueyama typename ELFT::uint LinkerScript<ELFT>::getHeaderSize() {
564e32a3598SGeorge Rimar   return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
565e32a3598SGeorge Rimar }
566e32a3598SGeorge Rimar 
567bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified
568bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within
569bbe38602SEugene Leviant // PHDRS {} script block.
570bbe38602SEugene Leviant template <class ELFT>
571edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) {
572076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
573076fe157SGeorge Rimar     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
574edebbdf1SRui Ueyama     if (!Cmd || Cmd->Name != SectionName)
57531d842f5SGeorge Rimar       continue;
57631d842f5SGeorge Rimar 
57729c5a2a9SRui Ueyama     std::vector<size_t> Ret;
57829c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
57929c5a2a9SRui Ueyama       Ret.push_back(getPhdrIndex(PhdrName));
58029c5a2a9SRui Ueyama     return Ret;
581bbe38602SEugene Leviant   }
58231d842f5SGeorge Rimar   return {};
58331d842f5SGeorge Rimar }
584bbe38602SEugene Leviant 
58529c5a2a9SRui Ueyama template <class ELFT>
58629c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) {
58729c5a2a9SRui Ueyama   size_t I = 0;
58829c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
58929c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
59029c5a2a9SRui Ueyama       return I;
59129c5a2a9SRui Ueyama     ++I;
59229c5a2a9SRui Ueyama   }
59329c5a2a9SRui Ueyama   error("section header '" + PhdrName + "' is not listed in PHDRS");
59429c5a2a9SRui Ueyama   return 0;
59529c5a2a9SRui Ueyama }
59629c5a2a9SRui Ueyama 
59707320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase {
598c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
599c3794e58SGeorge Rimar 
600f7c5fbb1SRui Ueyama public:
60107320e40SRui Ueyama   ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {}
602f23b2320SGeorge Rimar 
60320b6598cSGeorge Rimar   void readLinkerScript();
60420b6598cSGeorge Rimar   void readVersionScript();
605f7c5fbb1SRui Ueyama 
606f7c5fbb1SRui Ueyama private:
60752a1509eSRui Ueyama   void addFile(StringRef Path);
60852a1509eSRui Ueyama 
609f7c5fbb1SRui Ueyama   void readAsNeeded();
61090c5099eSDenis Protivensky   void readEntry();
61183f406cfSGeorge Rimar   void readExtern();
612f7c5fbb1SRui Ueyama   void readGroup();
61331aa1f83SRui Ueyama   void readInclude();
614ee59282bSRui Ueyama   void readOutput();
6159159ce93SDavide Italiano   void readOutputArch();
616f7c5fbb1SRui Ueyama   void readOutputFormat();
617bbe38602SEugene Leviant   void readPhdrs();
61868a39a65SDavide Italiano   void readSearchDir();
6198e3b38abSDenis Protivensky   void readSections();
62095769b4aSRui Ueyama   void readVersion();
62195769b4aSRui Ueyama   void readVersionScriptCommand();
6228e3b38abSDenis Protivensky 
623113cdec9SRui Ueyama   SymbolAssignment *readAssignment(StringRef Name);
62410416564SRui Ueyama   OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
625f71caa2bSRui Ueyama   std::vector<uint8_t> readOutputSectionFiller();
626bbe38602SEugene Leviant   std::vector<StringRef> readOutputSectionPhdrs();
627a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionDescription(StringRef Tok);
628c91930a1SGeorge Rimar   Regex readFilePatterns();
629a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionRules(StringRef FilePattern);
630bbe38602SEugene Leviant   unsigned readPhdrType();
631742c3836SRui Ueyama   SortKind readSortKind();
632a35e39caSPetr Hosek   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
633ceabe80eSEugene Leviant   SymbolAssignment *readProvideOrAssignment(StringRef Tok);
63403fc010eSGeorge Rimar   void readSort();
635eefa758eSGeorge Rimar   Expr readAssert();
636708019c4SRui Ueyama 
637708019c4SRui Ueyama   Expr readExpr();
638708019c4SRui Ueyama   Expr readExpr1(Expr Lhs, int MinPrec);
639708019c4SRui Ueyama   Expr readPrimary();
640708019c4SRui Ueyama   Expr readTernary(Expr Cond);
6416ad7dfccSRui Ueyama   Expr readParenExpr();
642f7c5fbb1SRui Ueyama 
64320b6598cSGeorge Rimar   // For parsing version script.
64420b6598cSGeorge Rimar   void readExtern(std::vector<SymbolVersion> *Globals);
64595769b4aSRui Ueyama   void readVersionDeclaration(StringRef VerStr);
64620b6598cSGeorge Rimar   void readGlobal(StringRef VerStr);
64720b6598cSGeorge Rimar   void readLocal();
64820b6598cSGeorge Rimar 
64907320e40SRui Ueyama   ScriptConfiguration &Opt = *ScriptConfig;
65007320e40SRui Ueyama   StringSaver Saver = {ScriptConfig->Alloc};
65116b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
652f7c5fbb1SRui Ueyama };
653f7c5fbb1SRui Ueyama 
65420b6598cSGeorge Rimar void ScriptParser::readVersionScript() {
65595769b4aSRui Ueyama   readVersionScriptCommand();
65620b6598cSGeorge Rimar   if (!atEOF())
65795769b4aSRui Ueyama     setError("EOF expected, but got " + next());
65895769b4aSRui Ueyama }
65995769b4aSRui Ueyama 
66095769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() {
66195769b4aSRui Ueyama   if (skip("{")) {
66295769b4aSRui Ueyama     readVersionDeclaration("");
66320b6598cSGeorge Rimar     return;
66420b6598cSGeorge Rimar   }
66520b6598cSGeorge Rimar 
66695769b4aSRui Ueyama   while (!atEOF() && !Error && peek() != "}") {
66720b6598cSGeorge Rimar     StringRef VerStr = next();
66820b6598cSGeorge Rimar     if (VerStr == "{") {
66995769b4aSRui Ueyama       setError("anonymous version definition is used in "
67095769b4aSRui Ueyama                "combination with other version definitions");
67120b6598cSGeorge Rimar       return;
67220b6598cSGeorge Rimar     }
67320b6598cSGeorge Rimar     expect("{");
67495769b4aSRui Ueyama     readVersionDeclaration(VerStr);
67520b6598cSGeorge Rimar   }
67620b6598cSGeorge Rimar }
67720b6598cSGeorge Rimar 
67895769b4aSRui Ueyama void ScriptParser::readVersion() {
67995769b4aSRui Ueyama   expect("{");
68095769b4aSRui Ueyama   readVersionScriptCommand();
68195769b4aSRui Ueyama   expect("}");
68295769b4aSRui Ueyama }
68395769b4aSRui Ueyama 
68420b6598cSGeorge Rimar void ScriptParser::readLinkerScript() {
685f7c5fbb1SRui Ueyama   while (!atEOF()) {
686f7c5fbb1SRui Ueyama     StringRef Tok = next();
687a27eeccaSRui Ueyama     if (Tok == ";")
688a27eeccaSRui Ueyama       continue;
689a27eeccaSRui Ueyama 
690a27eeccaSRui Ueyama     if (Tok == "ENTRY") {
691a27eeccaSRui Ueyama       readEntry();
692a27eeccaSRui Ueyama     } else if (Tok == "EXTERN") {
693a27eeccaSRui Ueyama       readExtern();
694a27eeccaSRui Ueyama     } else if (Tok == "GROUP" || Tok == "INPUT") {
695a27eeccaSRui Ueyama       readGroup();
696a27eeccaSRui Ueyama     } else if (Tok == "INCLUDE") {
697a27eeccaSRui Ueyama       readInclude();
698a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT") {
699a27eeccaSRui Ueyama       readOutput();
700a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_ARCH") {
701a27eeccaSRui Ueyama       readOutputArch();
702a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_FORMAT") {
703a27eeccaSRui Ueyama       readOutputFormat();
704a27eeccaSRui Ueyama     } else if (Tok == "PHDRS") {
705a27eeccaSRui Ueyama       readPhdrs();
706a27eeccaSRui Ueyama     } else if (Tok == "SEARCH_DIR") {
707a27eeccaSRui Ueyama       readSearchDir();
708a27eeccaSRui Ueyama     } else if (Tok == "SECTIONS") {
709a27eeccaSRui Ueyama       readSections();
710a27eeccaSRui Ueyama     } else if (Tok == "VERSION") {
711a27eeccaSRui Ueyama       readVersion();
712e5d3ca50SPetr Hosek     } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) {
713e5d3ca50SPetr Hosek       if (Opt.HasContents)
7140df80befSPetr Hosek         Opt.Commands.emplace_back(Cmd);
715c3794e58SGeorge Rimar       else
716e5d3ca50SPetr Hosek         Opt.Assignments.emplace_back(Cmd);
717e5d3ca50SPetr Hosek     } else {
7185761042dSGeorge Rimar       setError("unknown directive: " + Tok);
719f7c5fbb1SRui Ueyama     }
720f7c5fbb1SRui Ueyama   }
721e5d3ca50SPetr Hosek }
722f7c5fbb1SRui Ueyama 
723717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
72416b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
72516b0cc9eSSimon Atanasyan     SmallString<128> Path;
72616b0cc9eSSimon Atanasyan     (Config->Sysroot + S).toStringRef(Path);
72716b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
72816b0cc9eSSimon Atanasyan       Driver->addFile(Saver.save(Path.str()));
72916b0cc9eSSimon Atanasyan       return;
73016b0cc9eSSimon Atanasyan     }
73116b0cc9eSSimon Atanasyan   }
73216b0cc9eSSimon Atanasyan 
733f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
73452a1509eSRui Ueyama     Driver->addFile(S);
73552a1509eSRui Ueyama   } else if (S.startswith("=")) {
73652a1509eSRui Ueyama     if (Config->Sysroot.empty())
73752a1509eSRui Ueyama       Driver->addFile(S.substr(1));
73852a1509eSRui Ueyama     else
73952a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
74052a1509eSRui Ueyama   } else if (S.startswith("-l")) {
74121eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
742a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
743a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
74452a1509eSRui Ueyama   } else {
74552a1509eSRui Ueyama     std::string Path = findFromSearchPaths(S);
74652a1509eSRui Ueyama     if (Path.empty())
747777f9630SGeorge Rimar       setError("unable to find " + S);
748025d59b1SRui Ueyama     else
74952a1509eSRui Ueyama       Driver->addFile(Saver.save(Path));
75052a1509eSRui Ueyama   }
75152a1509eSRui Ueyama }
75252a1509eSRui Ueyama 
753717677afSRui Ueyama void ScriptParser::readAsNeeded() {
754f7c5fbb1SRui Ueyama   expect("(");
75535da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
75635da9b6eSRui Ueyama   Config->AsNeeded = true;
757a2acc931SRui Ueyama   while (!Error && !skip(")"))
758a2acc931SRui Ueyama     addFile(next());
75935da9b6eSRui Ueyama   Config->AsNeeded = Orig;
760f7c5fbb1SRui Ueyama }
761f7c5fbb1SRui Ueyama 
762717677afSRui Ueyama void ScriptParser::readEntry() {
76390c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
76490c5099eSDenis Protivensky   expect("(");
76590c5099eSDenis Protivensky   StringRef Tok = next();
76690c5099eSDenis Protivensky   if (Config->Entry.empty())
76790c5099eSDenis Protivensky     Config->Entry = Tok;
76890c5099eSDenis Protivensky   expect(")");
76990c5099eSDenis Protivensky }
77090c5099eSDenis Protivensky 
771717677afSRui Ueyama void ScriptParser::readExtern() {
77283f406cfSGeorge Rimar   expect("(");
773a2acc931SRui Ueyama   while (!Error && !skip(")"))
774a2acc931SRui Ueyama     Config->Undefined.push_back(next());
77583f406cfSGeorge Rimar }
77683f406cfSGeorge Rimar 
777717677afSRui Ueyama void ScriptParser::readGroup() {
778f7c5fbb1SRui Ueyama   expect("(");
779a2acc931SRui Ueyama   while (!Error && !skip(")")) {
780f7c5fbb1SRui Ueyama     StringRef Tok = next();
781a2acc931SRui Ueyama     if (Tok == "AS_NEEDED")
782f7c5fbb1SRui Ueyama       readAsNeeded();
783a2acc931SRui Ueyama     else
78452a1509eSRui Ueyama       addFile(Tok);
785f7c5fbb1SRui Ueyama   }
786f7c5fbb1SRui Ueyama }
787f7c5fbb1SRui Ueyama 
788717677afSRui Ueyama void ScriptParser::readInclude() {
78931aa1f83SRui Ueyama   StringRef Tok = next();
79031aa1f83SRui Ueyama   auto MBOrErr = MemoryBuffer::getFile(Tok);
791025d59b1SRui Ueyama   if (!MBOrErr) {
7925761042dSGeorge Rimar     setError("cannot open " + Tok);
793025d59b1SRui Ueyama     return;
794025d59b1SRui Ueyama   }
79531aa1f83SRui Ueyama   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
796a47ee68dSRui Ueyama   StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
797a47ee68dSRui Ueyama   std::vector<StringRef> V = tokenize(S);
79831aa1f83SRui Ueyama   Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
79931aa1f83SRui Ueyama }
80031aa1f83SRui Ueyama 
801717677afSRui Ueyama void ScriptParser::readOutput() {
802ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
803ee59282bSRui Ueyama   expect("(");
804ee59282bSRui Ueyama   StringRef Tok = next();
805ee59282bSRui Ueyama   if (Config->OutputFile.empty())
806ee59282bSRui Ueyama     Config->OutputFile = Tok;
807ee59282bSRui Ueyama   expect(")");
808ee59282bSRui Ueyama }
809ee59282bSRui Ueyama 
810717677afSRui Ueyama void ScriptParser::readOutputArch() {
8119159ce93SDavide Italiano   // Error checking only for now.
8129159ce93SDavide Italiano   expect("(");
8139159ce93SDavide Italiano   next();
8149159ce93SDavide Italiano   expect(")");
8159159ce93SDavide Italiano }
8169159ce93SDavide Italiano 
817717677afSRui Ueyama void ScriptParser::readOutputFormat() {
818f7c5fbb1SRui Ueyama   // Error checking only for now.
819f7c5fbb1SRui Ueyama   expect("(");
820f7c5fbb1SRui Ueyama   next();
8216836c618SDavide Italiano   StringRef Tok = next();
8226836c618SDavide Italiano   if (Tok == ")")
8236836c618SDavide Italiano    return;
824025d59b1SRui Ueyama   if (Tok != ",") {
8255761042dSGeorge Rimar     setError("unexpected token: " + Tok);
826025d59b1SRui Ueyama     return;
827025d59b1SRui Ueyama   }
8286836c618SDavide Italiano   next();
8296836c618SDavide Italiano   expect(",");
8306836c618SDavide Italiano   next();
831f7c5fbb1SRui Ueyama   expect(")");
832f7c5fbb1SRui Ueyama }
833f7c5fbb1SRui Ueyama 
834bbe38602SEugene Leviant void ScriptParser::readPhdrs() {
835bbe38602SEugene Leviant   expect("{");
836bbe38602SEugene Leviant   while (!Error && !skip("}")) {
837bbe38602SEugene Leviant     StringRef Tok = next();
838865bf863SEugene Leviant     Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX});
839bbe38602SEugene Leviant     PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back();
840bbe38602SEugene Leviant 
841bbe38602SEugene Leviant     PhdrCmd.Type = readPhdrType();
842bbe38602SEugene Leviant     do {
843bbe38602SEugene Leviant       Tok = next();
844bbe38602SEugene Leviant       if (Tok == ";")
845bbe38602SEugene Leviant         break;
846bbe38602SEugene Leviant       if (Tok == "FILEHDR")
847bbe38602SEugene Leviant         PhdrCmd.HasFilehdr = true;
848bbe38602SEugene Leviant       else if (Tok == "PHDRS")
849bbe38602SEugene Leviant         PhdrCmd.HasPhdrs = true;
850865bf863SEugene Leviant       else if (Tok == "FLAGS") {
851865bf863SEugene Leviant         expect("(");
852eb685cd7SRafael Espindola         // Passing 0 for the value of dot is a bit of a hack. It means that
853eb685cd7SRafael Espindola         // we accept expressions like ".|1".
854eb685cd7SRafael Espindola         PhdrCmd.Flags = readExpr()(0);
855865bf863SEugene Leviant         expect(")");
856865bf863SEugene Leviant       } else
857bbe38602SEugene Leviant         setError("unexpected header attribute: " + Tok);
858bbe38602SEugene Leviant     } while (!Error);
859bbe38602SEugene Leviant   }
860bbe38602SEugene Leviant }
861bbe38602SEugene Leviant 
862717677afSRui Ueyama void ScriptParser::readSearchDir() {
86368a39a65SDavide Italiano   expect("(");
8646c7ad13fSRui Ueyama   if (!Config->Nostdlib)
86506501920SRafael Espindola     Config->SearchPaths.push_back(next());
86668a39a65SDavide Italiano   expect(")");
86768a39a65SDavide Italiano }
86868a39a65SDavide Italiano 
869717677afSRui Ueyama void ScriptParser::readSections() {
8703de0a330SRui Ueyama   Opt.HasContents = true;
8718e3b38abSDenis Protivensky   expect("{");
872652852c5SGeorge Rimar   while (!Error && !skip("}")) {
873113cdec9SRui Ueyama     StringRef Tok = next();
874ceabe80eSEugene Leviant     BaseCommand *Cmd = readProvideOrAssignment(Tok);
875ceabe80eSEugene Leviant     if (!Cmd) {
876ceabe80eSEugene Leviant       if (Tok == "ASSERT")
877eefa758eSGeorge Rimar         Cmd = new AssertCommand(readAssert());
878ceabe80eSEugene Leviant       else
87910416564SRui Ueyama         Cmd = readOutputSectionDescription(Tok);
8808e3b38abSDenis Protivensky     }
88110416564SRui Ueyama     Opt.Commands.emplace_back(Cmd);
882652852c5SGeorge Rimar   }
883708019c4SRui Ueyama }
8848e3b38abSDenis Protivensky 
885708019c4SRui Ueyama static int precedence(StringRef Op) {
886708019c4SRui Ueyama   return StringSwitch<int>(Op)
887708019c4SRui Ueyama       .Case("*", 4)
888708019c4SRui Ueyama       .Case("/", 4)
889708019c4SRui Ueyama       .Case("+", 3)
890708019c4SRui Ueyama       .Case("-", 3)
891708019c4SRui Ueyama       .Case("<", 2)
892708019c4SRui Ueyama       .Case(">", 2)
893708019c4SRui Ueyama       .Case(">=", 2)
894708019c4SRui Ueyama       .Case("<=", 2)
895708019c4SRui Ueyama       .Case("==", 2)
896708019c4SRui Ueyama       .Case("!=", 2)
897708019c4SRui Ueyama       .Case("&", 1)
898cc3dd629SRafael Espindola       .Case("|", 1)
899708019c4SRui Ueyama       .Default(-1);
900708019c4SRui Ueyama }
901708019c4SRui Ueyama 
902c91930a1SGeorge Rimar Regex ScriptParser::readFilePatterns() {
90310416564SRui Ueyama   std::vector<StringRef> V;
90410416564SRui Ueyama   while (!Error && !skip(")"))
90510416564SRui Ueyama     V.push_back(next());
906c91930a1SGeorge Rimar   return compileGlobPatterns(V);
9070702c4e8SGeorge Rimar }
9080702c4e8SGeorge Rimar 
909742c3836SRui Ueyama SortKind ScriptParser::readSortKind() {
910742c3836SRui Ueyama   if (skip("SORT") || skip("SORT_BY_NAME"))
911742c3836SRui Ueyama     return SortByName;
912742c3836SRui Ueyama   if (skip("SORT_BY_ALIGNMENT"))
913742c3836SRui Ueyama     return SortByAlignment;
914742c3836SRui Ueyama   return SortNone;
915742c3836SRui Ueyama }
916742c3836SRui Ueyama 
917a2496cbeSGeorge Rimar InputSectionDescription *
918a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) {
919c91930a1SGeorge Rimar   auto *Cmd = new InputSectionDescription(FilePattern);
9200ed42b0cSDavide Italiano   expect("(");
921e7282797SDavide Italiano 
922742c3836SRui Ueyama   // Read EXCLUDE_FILE().
923e7282797SDavide Italiano   if (skip("EXCLUDE_FILE")) {
924e7282797SDavide Italiano     expect("(");
925c91930a1SGeorge Rimar     Cmd->ExcludedFileRe = readFilePatterns();
926e7282797SDavide Italiano   }
927e7282797SDavide Italiano 
928742c3836SRui Ueyama   // Read SORT().
929742c3836SRui Ueyama   if (SortKind K1 = readSortKind()) {
930742c3836SRui Ueyama     Cmd->SortOuter = K1;
9310702c4e8SGeorge Rimar     expect("(");
932742c3836SRui Ueyama     if (SortKind K2 = readSortKind()) {
933742c3836SRui Ueyama       Cmd->SortInner = K2;
934350ece4eSGeorge Rimar       expect("(");
935c91930a1SGeorge Rimar       Cmd->SectionRe = readFilePatterns();
9360702c4e8SGeorge Rimar       expect(")");
937350ece4eSGeorge Rimar     } else {
938c91930a1SGeorge Rimar       Cmd->SectionRe = readFilePatterns();
939350ece4eSGeorge Rimar     }
940350ece4eSGeorge Rimar     expect(")");
94110416564SRui Ueyama     return Cmd;
9420659800eSGeorge Rimar   }
9430702c4e8SGeorge Rimar 
944c91930a1SGeorge Rimar   Cmd->SectionRe = readFilePatterns();
94510416564SRui Ueyama   return Cmd;
9460659800eSGeorge Rimar }
9470659800eSGeorge Rimar 
948a2496cbeSGeorge Rimar InputSectionDescription *
949a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) {
9500659800eSGeorge Rimar   // Input section wildcard can be surrounded by KEEP.
9510659800eSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
952a2496cbeSGeorge Rimar   if (Tok == "KEEP") {
953e7282797SDavide Italiano     expect("(");
954a2496cbeSGeorge Rimar     StringRef FilePattern = next();
955a2496cbeSGeorge Rimar     InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
9560ed42b0cSDavide Italiano     expect(")");
957c91930a1SGeorge Rimar     Opt.KeptSections.push_back(&Cmd->SectionRe);
95810416564SRui Ueyama     return Cmd;
95910416564SRui Ueyama   }
960a2496cbeSGeorge Rimar   return readInputSectionRules(Tok);
9610659800eSGeorge Rimar }
9620659800eSGeorge Rimar 
96303fc010eSGeorge Rimar void ScriptParser::readSort() {
96403fc010eSGeorge Rimar   expect("(");
96503fc010eSGeorge Rimar   expect("CONSTRUCTORS");
96603fc010eSGeorge Rimar   expect(")");
96703fc010eSGeorge Rimar }
96803fc010eSGeorge Rimar 
969eefa758eSGeorge Rimar Expr ScriptParser::readAssert() {
970eefa758eSGeorge Rimar   expect("(");
971eefa758eSGeorge Rimar   Expr E = readExpr();
972eefa758eSGeorge Rimar   expect(",");
973eefa758eSGeorge Rimar   StringRef Msg = next();
974eefa758eSGeorge Rimar   expect(")");
975eefa758eSGeorge Rimar   return [=](uint64_t Dot) {
976eefa758eSGeorge Rimar     uint64_t V = E(Dot);
977eefa758eSGeorge Rimar     if (!V)
978eefa758eSGeorge Rimar       error(Msg);
979eefa758eSGeorge Rimar     return V;
980eefa758eSGeorge Rimar   };
981eefa758eSGeorge Rimar }
982eefa758eSGeorge Rimar 
98310416564SRui Ueyama OutputSectionCommand *
98410416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) {
985076fe157SGeorge Rimar   OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
98658e5c4dcSGeorge Rimar 
98758e5c4dcSGeorge Rimar   // Read an address expression.
98858e5c4dcSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address
98958e5c4dcSGeorge Rimar   if (peek() != ":")
99058e5c4dcSGeorge Rimar     Cmd->AddrExpr = readExpr();
99158e5c4dcSGeorge Rimar 
9928e3b38abSDenis Protivensky   expect(":");
993246f681eSDavide Italiano 
9948ceadb38SGeorge Rimar   if (skip("AT"))
9956ad7dfccSRui Ueyama     Cmd->LmaExpr = readParenExpr();
996630c6179SGeorge Rimar   if (skip("ALIGN"))
9976ad7dfccSRui Ueyama     Cmd->AlignExpr = readParenExpr();
998db24d9c3SGeorge Rimar   if (skip("SUBALIGN"))
999db24d9c3SGeorge Rimar     Cmd->SubalignExpr = readParenExpr();
1000630c6179SGeorge Rimar 
1001246f681eSDavide Italiano   // Parse constraints.
1002246f681eSDavide Italiano   if (skip("ONLY_IF_RO"))
1003efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadOnly;
1004246f681eSDavide Italiano   if (skip("ONLY_IF_RW"))
1005efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadWrite;
10068e3b38abSDenis Protivensky   expect("{");
10078ec77e64SRui Ueyama 
1008025d59b1SRui Ueyama   while (!Error && !skip("}")) {
1009ceabe80eSEugene Leviant     StringRef Tok = next();
1010ceabe80eSEugene Leviant     if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok))
1011ceabe80eSEugene Leviant       Cmd->Commands.emplace_back(Assignment);
1012ceabe80eSEugene Leviant     else if (Tok == "SORT")
101303fc010eSGeorge Rimar       readSort();
1014a2496cbeSGeorge Rimar     else if (peek() == "(")
1015a2496cbeSGeorge Rimar       Cmd->Commands.emplace_back(readInputSectionDescription(Tok));
1016ceabe80eSEugene Leviant     else
1017ceabe80eSEugene Leviant       setError("unknown command " + Tok);
10188e3b38abSDenis Protivensky   }
1019076fe157SGeorge Rimar   Cmd->Phdrs = readOutputSectionPhdrs();
1020f71caa2bSRui Ueyama   Cmd->Filler = readOutputSectionFiller();
102110416564SRui Ueyama   return Cmd;
1022f71caa2bSRui Ueyama }
10238ec77e64SRui Ueyama 
10242c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number.
10252c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
10262c8f1f04SRui Ueyama //
10272c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles
10282c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them
10292c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does
10302c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does.
1031f71caa2bSRui Ueyama std::vector<uint8_t> ScriptParser::readOutputSectionFiller() {
10322c8f1f04SRui Ueyama   if (!peek().startswith("="))
1033f71caa2bSRui Ueyama     return {};
1034965827d6SRui Ueyama 
10352c8f1f04SRui Ueyama   StringRef Tok = next();
1036965827d6SRui Ueyama   uint32_t V;
1037965827d6SRui Ueyama   if (Tok.substr(1).getAsInteger(0, V)) {
1038965827d6SRui Ueyama     setError("invalid filler expression: " + Tok);
1039f71caa2bSRui Ueyama     return {};
1040e2ee72b5SGeorge Rimar   }
1041965827d6SRui Ueyama   return {uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V)};
10428e3b38abSDenis Protivensky }
10438e3b38abSDenis Protivensky 
1044a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
1045a31c91b1SEugene Leviant   expect("(");
1046174e0a16SRui Ueyama   SymbolAssignment *Cmd = readAssignment(next());
1047a35e39caSPetr Hosek   Cmd->Provide = Provide;
1048174e0a16SRui Ueyama   Cmd->Hidden = Hidden;
1049a31c91b1SEugene Leviant   expect(")");
1050a31c91b1SEugene Leviant   expect(";");
105110416564SRui Ueyama   return Cmd;
1052eda81a1bSEugene Leviant }
1053eda81a1bSEugene Leviant 
1054ceabe80eSEugene Leviant SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
1055ceabe80eSEugene Leviant   SymbolAssignment *Cmd = nullptr;
1056ceabe80eSEugene Leviant   if (peek() == "=" || peek() == "+=") {
1057ceabe80eSEugene Leviant     Cmd = readAssignment(Tok);
1058ceabe80eSEugene Leviant     expect(";");
1059ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE") {
1060a35e39caSPetr Hosek     Cmd = readProvideHidden(true, false);
1061a35e39caSPetr Hosek   } else if (Tok == "HIDDEN") {
1062a35e39caSPetr Hosek     Cmd = readProvideHidden(false, true);
1063ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE_HIDDEN") {
1064a35e39caSPetr Hosek     Cmd = readProvideHidden(true, true);
1065ceabe80eSEugene Leviant   }
1066ceabe80eSEugene Leviant   return Cmd;
1067ceabe80eSEugene Leviant }
1068ceabe80eSEugene Leviant 
106930835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) {
107030835ea4SGeorge Rimar   if (S == ".")
107130835ea4SGeorge Rimar     return Dot;
1072a31c91b1SEugene Leviant 
1073a9c5a528SGeorge Rimar   switch (Config->EKind) {
1074a9c5a528SGeorge Rimar   case ELF32LEKind:
1075a9c5a528SGeorge Rimar     if (SymbolBody *B = Symtab<ELF32LE>::X->find(S))
1076a9c5a528SGeorge Rimar       return B->getVA<ELF32LE>();
1077a9c5a528SGeorge Rimar     break;
1078a9c5a528SGeorge Rimar   case ELF32BEKind:
1079a9c5a528SGeorge Rimar     if (SymbolBody *B = Symtab<ELF32BE>::X->find(S))
1080a9c5a528SGeorge Rimar       return B->getVA<ELF32BE>();
1081a9c5a528SGeorge Rimar     break;
1082a9c5a528SGeorge Rimar   case ELF64LEKind:
1083a9c5a528SGeorge Rimar     if (SymbolBody *B = Symtab<ELF64LE>::X->find(S))
1084a9c5a528SGeorge Rimar       return B->getVA<ELF64LE>();
1085a9c5a528SGeorge Rimar     break;
1086a9c5a528SGeorge Rimar   case ELF64BEKind:
1087a9c5a528SGeorge Rimar     if (SymbolBody *B = Symtab<ELF64BE>::X->find(S))
1088a9c5a528SGeorge Rimar       return B->getVA<ELF64BE>();
1089a9c5a528SGeorge Rimar     break;
10906930a6dcSGeorge Rimar   default:
1091b567b628SGeorge Rimar     llvm_unreachable("unsupported target");
1092a9c5a528SGeorge Rimar   }
1093a9c5a528SGeorge Rimar   error("symbol not found: " + S);
1094a9c5a528SGeorge Rimar   return 0;
1095a9c5a528SGeorge Rimar }
1096a9c5a528SGeorge Rimar 
10979e69450eSGeorge Rimar static uint64_t getSectionSize(StringRef Name) {
10989e69450eSGeorge Rimar   switch (Config->EKind) {
10999e69450eSGeorge Rimar   case ELF32LEKind:
11009e69450eSGeorge Rimar     return Script<ELF32LE>::X->getOutputSectionSize(Name);
11019e69450eSGeorge Rimar   case ELF32BEKind:
11029e69450eSGeorge Rimar     return Script<ELF32BE>::X->getOutputSectionSize(Name);
11039e69450eSGeorge Rimar   case ELF64LEKind:
11049e69450eSGeorge Rimar     return Script<ELF64LE>::X->getOutputSectionSize(Name);
11059e69450eSGeorge Rimar   case ELF64BEKind:
11069e69450eSGeorge Rimar     return Script<ELF64BE>::X->getOutputSectionSize(Name);
11079e69450eSGeorge Rimar   default:
11089e69450eSGeorge Rimar     llvm_unreachable("unsupported target");
11099e69450eSGeorge Rimar   }
11109e69450eSGeorge Rimar }
11119e69450eSGeorge Rimar 
111296659df0SGeorge Rimar static uint64_t getSectionAddress(StringRef Name) {
111396659df0SGeorge Rimar   switch (Config->EKind) {
111496659df0SGeorge Rimar   case ELF32LEKind:
111596659df0SGeorge Rimar     return Script<ELF32LE>::X->getOutputSectionAddress(Name);
111696659df0SGeorge Rimar   case ELF32BEKind:
111796659df0SGeorge Rimar     return Script<ELF32BE>::X->getOutputSectionAddress(Name);
111896659df0SGeorge Rimar   case ELF64LEKind:
111996659df0SGeorge Rimar     return Script<ELF64LE>::X->getOutputSectionAddress(Name);
112096659df0SGeorge Rimar   case ELF64BEKind:
112196659df0SGeorge Rimar     return Script<ELF64BE>::X->getOutputSectionAddress(Name);
112296659df0SGeorge Rimar   default:
112396659df0SGeorge Rimar     llvm_unreachable("unsupported target");
112496659df0SGeorge Rimar   }
112596659df0SGeorge Rimar }
112696659df0SGeorge Rimar 
11274f7500bfSRui Ueyama static uint64_t getHeaderSize() {
1128e32a3598SGeorge Rimar   switch (Config->EKind) {
1129e32a3598SGeorge Rimar   case ELF32LEKind:
11304f7500bfSRui Ueyama     return Script<ELF32LE>::X->getHeaderSize();
1131e32a3598SGeorge Rimar   case ELF32BEKind:
11324f7500bfSRui Ueyama     return Script<ELF32BE>::X->getHeaderSize();
1133e32a3598SGeorge Rimar   case ELF64LEKind:
11344f7500bfSRui Ueyama     return Script<ELF64LE>::X->getHeaderSize();
1135e32a3598SGeorge Rimar   case ELF64BEKind:
11364f7500bfSRui Ueyama     return Script<ELF64BE>::X->getHeaderSize();
1137e32a3598SGeorge Rimar   default:
1138e32a3598SGeorge Rimar     llvm_unreachable("unsupported target");
1139e32a3598SGeorge Rimar   }
1140e32a3598SGeorge Rimar }
1141e32a3598SGeorge Rimar 
114230835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
114330835ea4SGeorge Rimar   StringRef Op = next();
114430835ea4SGeorge Rimar   assert(Op == "=" || Op == "+=");
114530835ea4SGeorge Rimar   Expr E = readExpr();
114630835ea4SGeorge Rimar   if (Op == "+=")
114730835ea4SGeorge Rimar     E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); };
114810416564SRui Ueyama   return new SymbolAssignment(Name, E);
114930835ea4SGeorge Rimar }
115030835ea4SGeorge Rimar 
115130835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker
115230835ea4SGeorge Rimar // script expression.
115330835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
115430835ea4SGeorge Rimar 
115536c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) {
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) -> uint64_t {
116036c1cd23SRui Ueyama       uint64_t RHS = R(Dot);
116136c1cd23SRui Ueyama       if (RHS == 0) {
116236c1cd23SRui Ueyama         error("division by zero");
116336c1cd23SRui Ueyama         return 0;
116436c1cd23SRui Ueyama       }
116536c1cd23SRui Ueyama       return L(Dot) / RHS;
116636c1cd23SRui Ueyama     };
116736c1cd23SRui Ueyama   }
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); };
117436c1cd23SRui Ueyama   if (Op == ">")
117536c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) > R(Dot); };
117636c1cd23SRui Ueyama   if (Op == ">=")
117736c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) >= R(Dot); };
117836c1cd23SRui Ueyama   if (Op == "<=")
117936c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) <= R(Dot); };
118036c1cd23SRui Ueyama   if (Op == "==")
118136c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) == R(Dot); };
118236c1cd23SRui Ueyama   if (Op == "!=")
118336c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) != R(Dot); };
118436c1cd23SRui Ueyama   if (Op == "&")
118536c1cd23SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) & R(Dot); };
1186cc3dd629SRafael Espindola   if (Op == "|")
1187cc3dd629SRafael Espindola     return [=](uint64_t Dot) { return L(Dot) | R(Dot); };
118836c1cd23SRui Ueyama   llvm_unreachable("invalid operator");
118936c1cd23SRui Ueyama }
119036c1cd23SRui Ueyama 
1191708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function
1192708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator.
1193708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
1194708019c4SRui Ueyama   while (!atEOF() && !Error) {
1195708019c4SRui Ueyama     // Read an operator and an expression.
1196708019c4SRui Ueyama     StringRef Op1 = peek();
1197708019c4SRui Ueyama     if (Op1 == "?")
1198708019c4SRui Ueyama       return readTernary(Lhs);
1199708019c4SRui Ueyama     if (precedence(Op1) < MinPrec)
1200a31c91b1SEugene Leviant       break;
1201a31c91b1SEugene Leviant     next();
1202708019c4SRui Ueyama     Expr Rhs = readPrimary();
1203708019c4SRui Ueyama 
1204708019c4SRui Ueyama     // Evaluate the remaining part of the expression first if the
1205708019c4SRui Ueyama     // next operator has greater precedence than the previous one.
1206708019c4SRui Ueyama     // For example, if we have read "+" and "3", and if the next
1207708019c4SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
1208708019c4SRui Ueyama     while (!atEOF()) {
1209708019c4SRui Ueyama       StringRef Op2 = peek();
1210708019c4SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
1211eda81a1bSEugene Leviant         break;
1212708019c4SRui Ueyama       Rhs = readExpr1(Rhs, precedence(Op2));
1213eda81a1bSEugene Leviant     }
1214708019c4SRui Ueyama 
1215708019c4SRui Ueyama     Lhs = combine(Op1, Lhs, Rhs);
1216708019c4SRui Ueyama   }
1217708019c4SRui Ueyama   return Lhs;
1218708019c4SRui Ueyama }
1219708019c4SRui Ueyama 
1220708019c4SRui Ueyama uint64_t static getConstant(StringRef S) {
1221e2cc07bcSMichael J. Spencer   if (S == "COMMONPAGESIZE")
1222708019c4SRui Ueyama     return Target->PageSize;
1223e2cc07bcSMichael J. Spencer   if (S == "MAXPAGESIZE")
1224e2cc07bcSMichael J. Spencer     return Target->MaxPageSize;
1225708019c4SRui Ueyama   error("unknown constant: " + S);
1226708019c4SRui Ueyama   return 0;
1227708019c4SRui Ueyama }
1228708019c4SRui Ueyama 
1229626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful.
1230626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H")
1231626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or
1232626e0b08SRui Ueyama // "M" (mega) prefixes.
12339f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) {
1234*eaeafb2bSSimon Atanasyan   if (Tok.startswith("-")) {
1235*eaeafb2bSSimon Atanasyan     if (!readInteger(Tok.substr(1), Result))
1236*eaeafb2bSSimon Atanasyan       return false;
1237*eaeafb2bSSimon Atanasyan     Result = -Result;
1238*eaeafb2bSSimon Atanasyan     return true;
1239*eaeafb2bSSimon Atanasyan   }
12409f2f7ad9SGeorge Rimar   if (Tok.startswith_lower("0x"))
12419f2f7ad9SGeorge Rimar     return !Tok.substr(2).getAsInteger(16, Result);
12429f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("H"))
12439f2f7ad9SGeorge Rimar     return !Tok.drop_back().getAsInteger(16, Result);
12449f2f7ad9SGeorge Rimar 
12459f2f7ad9SGeorge Rimar   int Suffix = 1;
12469f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("K")) {
12479f2f7ad9SGeorge Rimar     Suffix = 1024;
12489f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
12499f2f7ad9SGeorge Rimar   } else if (Tok.endswith_lower("M")) {
12509f2f7ad9SGeorge Rimar     Suffix = 1024 * 1024;
12519f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
12529f2f7ad9SGeorge Rimar   }
12539f2f7ad9SGeorge Rimar   if (Tok.getAsInteger(10, Result))
12549f2f7ad9SGeorge Rimar     return false;
12559f2f7ad9SGeorge Rimar   Result *= Suffix;
12569f2f7ad9SGeorge Rimar   return true;
12579f2f7ad9SGeorge Rimar }
12589f2f7ad9SGeorge Rimar 
1259708019c4SRui Ueyama Expr ScriptParser::readPrimary() {
12606ad7dfccSRui Ueyama   if (peek() == "(")
12616ad7dfccSRui Ueyama     return readParenExpr();
1262708019c4SRui Ueyama 
12636ad7dfccSRui Ueyama   StringRef Tok = next();
1264708019c4SRui Ueyama 
1265*eaeafb2bSSimon Atanasyan   if (Tok == "~") {
1266*eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
1267*eaeafb2bSSimon Atanasyan     return [=](uint64_t Dot) { return ~E(Dot); };
1268*eaeafb2bSSimon Atanasyan   }
1269*eaeafb2bSSimon Atanasyan   if (Tok == "-") {
1270*eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
1271*eaeafb2bSSimon Atanasyan     return [=](uint64_t Dot) { return -E(Dot); };
1272*eaeafb2bSSimon Atanasyan   }
1273*eaeafb2bSSimon Atanasyan 
1274708019c4SRui Ueyama   // Built-in functions are parsed here.
1275708019c4SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
127696659df0SGeorge Rimar   if (Tok == "ADDR") {
127796659df0SGeorge Rimar     expect("(");
127896659df0SGeorge Rimar     StringRef Name = next();
127996659df0SGeorge Rimar     expect(")");
128096659df0SGeorge Rimar     return [=](uint64_t Dot) { return getSectionAddress(Name); };
128196659df0SGeorge Rimar   }
1282eefa758eSGeorge Rimar   if (Tok == "ASSERT")
1283eefa758eSGeorge Rimar     return readAssert();
1284708019c4SRui Ueyama   if (Tok == "ALIGN") {
12856ad7dfccSRui Ueyama     Expr E = readParenExpr();
1286708019c4SRui Ueyama     return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
1287708019c4SRui Ueyama   }
1288708019c4SRui Ueyama   if (Tok == "CONSTANT") {
1289708019c4SRui Ueyama     expect("(");
1290708019c4SRui Ueyama     StringRef Tok = next();
1291708019c4SRui Ueyama     expect(")");
1292708019c4SRui Ueyama     return [=](uint64_t Dot) { return getConstant(Tok); };
1293708019c4SRui Ueyama   }
129454c145ceSRafael Espindola   if (Tok == "SEGMENT_START") {
129554c145ceSRafael Espindola     expect("(");
129654c145ceSRafael Espindola     next();
129754c145ceSRafael Espindola     expect(",");
129854c145ceSRafael Espindola     uint64_t Val;
129954c145ceSRafael Espindola     next().getAsInteger(0, Val);
130054c145ceSRafael Espindola     expect(")");
130154c145ceSRafael Espindola     return [=](uint64_t Dot) { return Val; };
130254c145ceSRafael Espindola   }
1303708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_ALIGN") {
1304708019c4SRui Ueyama     expect("(");
1305708019c4SRui Ueyama     Expr E = readExpr();
1306708019c4SRui Ueyama     expect(",");
1307708019c4SRui Ueyama     readExpr();
1308708019c4SRui Ueyama     expect(")");
1309f7791bb9SRui Ueyama     return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
1310708019c4SRui Ueyama   }
1311708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_END") {
1312708019c4SRui Ueyama     expect("(");
1313708019c4SRui Ueyama     expect(".");
1314708019c4SRui Ueyama     expect(")");
1315708019c4SRui Ueyama     return [](uint64_t Dot) { return Dot; };
1316708019c4SRui Ueyama   }
1317276b4e64SGeorge Rimar   // GNU linkers implements more complicated logic to handle
1318276b4e64SGeorge Rimar   // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to
1319276b4e64SGeorge Rimar   // the next page boundary for simplicity.
1320276b4e64SGeorge Rimar   if (Tok == "DATA_SEGMENT_RELRO_END") {
1321276b4e64SGeorge Rimar     expect("(");
1322276b4e64SGeorge Rimar     next();
1323276b4e64SGeorge Rimar     expect(",");
1324276b4e64SGeorge Rimar     readExpr();
1325276b4e64SGeorge Rimar     expect(")");
1326276b4e64SGeorge Rimar     return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); };
1327276b4e64SGeorge Rimar   }
13289e69450eSGeorge Rimar   if (Tok == "SIZEOF") {
13299e69450eSGeorge Rimar     expect("(");
13309e69450eSGeorge Rimar     StringRef Name = next();
13319e69450eSGeorge Rimar     expect(")");
13329e69450eSGeorge Rimar     return [=](uint64_t Dot) { return getSectionSize(Name); };
13339e69450eSGeorge Rimar   }
1334e32a3598SGeorge Rimar   if (Tok == "SIZEOF_HEADERS")
13354f7500bfSRui Ueyama     return [=](uint64_t Dot) { return getHeaderSize(); };
1336708019c4SRui Ueyama 
13379f2f7ad9SGeorge Rimar   // Tok is a literal number.
13389f2f7ad9SGeorge Rimar   uint64_t V;
13399f2f7ad9SGeorge Rimar   if (readInteger(Tok, V))
13409f2f7ad9SGeorge Rimar     return [=](uint64_t Dot) { return V; };
13419f2f7ad9SGeorge Rimar 
13429f2f7ad9SGeorge Rimar   // Tok is a symbol name.
134330835ea4SGeorge Rimar   if (Tok != "." && !isValidCIdentifier(Tok))
1344708019c4SRui Ueyama     setError("malformed number: " + Tok);
134530835ea4SGeorge Rimar   return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); };
1346a9c5a528SGeorge Rimar }
1347708019c4SRui Ueyama 
1348708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) {
1349708019c4SRui Ueyama   next();
1350708019c4SRui Ueyama   Expr L = readExpr();
1351708019c4SRui Ueyama   expect(":");
1352708019c4SRui Ueyama   Expr R = readExpr();
1353708019c4SRui Ueyama   return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); };
1354708019c4SRui Ueyama }
1355708019c4SRui Ueyama 
13566ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() {
13576ad7dfccSRui Ueyama   expect("(");
13586ad7dfccSRui Ueyama   Expr E = readExpr();
13596ad7dfccSRui Ueyama   expect(")");
13606ad7dfccSRui Ueyama   return E;
13616ad7dfccSRui Ueyama }
13626ad7dfccSRui Ueyama 
1363bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
1364bbe38602SEugene Leviant   std::vector<StringRef> Phdrs;
1365bbe38602SEugene Leviant   while (!Error && peek().startswith(":")) {
1366bbe38602SEugene Leviant     StringRef Tok = next();
1367bbe38602SEugene Leviant     Tok = (Tok.size() == 1) ? next() : Tok.substr(1);
1368bbe38602SEugene Leviant     if (Tok.empty()) {
1369bbe38602SEugene Leviant       setError("section header name is empty");
1370bbe38602SEugene Leviant       break;
1371bbe38602SEugene Leviant     }
1372bbe38602SEugene Leviant     Phdrs.push_back(Tok);
1373bbe38602SEugene Leviant   }
1374bbe38602SEugene Leviant   return Phdrs;
1375bbe38602SEugene Leviant }
1376bbe38602SEugene Leviant 
1377bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() {
1378bbe38602SEugene Leviant   StringRef Tok = next();
1379b0f6c590SRui Ueyama   unsigned Ret = StringSwitch<unsigned>(Tok)
1380b0f6c590SRui Ueyama       .Case("PT_NULL", PT_NULL)
1381b0f6c590SRui Ueyama       .Case("PT_LOAD", PT_LOAD)
1382b0f6c590SRui Ueyama       .Case("PT_DYNAMIC", PT_DYNAMIC)
1383b0f6c590SRui Ueyama       .Case("PT_INTERP", PT_INTERP)
1384b0f6c590SRui Ueyama       .Case("PT_NOTE", PT_NOTE)
1385b0f6c590SRui Ueyama       .Case("PT_SHLIB", PT_SHLIB)
1386b0f6c590SRui Ueyama       .Case("PT_PHDR", PT_PHDR)
1387b0f6c590SRui Ueyama       .Case("PT_TLS", PT_TLS)
1388b0f6c590SRui Ueyama       .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
1389b0f6c590SRui Ueyama       .Case("PT_GNU_STACK", PT_GNU_STACK)
1390b0f6c590SRui Ueyama       .Case("PT_GNU_RELRO", PT_GNU_RELRO)
1391b0f6c590SRui Ueyama       .Default(-1);
1392bbe38602SEugene Leviant 
1393b0f6c590SRui Ueyama   if (Ret == (unsigned)-1) {
1394b0f6c590SRui Ueyama     setError("invalid program header type: " + Tok);
1395b0f6c590SRui Ueyama     return PT_NULL;
1396b0f6c590SRui Ueyama   }
1397b0f6c590SRui Ueyama   return Ret;
1398bbe38602SEugene Leviant }
1399bbe38602SEugene Leviant 
140095769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) {
140120b6598cSGeorge Rimar   // Identifiers start at 2 because 0 and 1 are reserved
140220b6598cSGeorge Rimar   // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants.
140320b6598cSGeorge Rimar   size_t VersionId = Config->VersionDefinitions.size() + 2;
140420b6598cSGeorge Rimar   Config->VersionDefinitions.push_back({VerStr, VersionId});
140520b6598cSGeorge Rimar 
140620b6598cSGeorge Rimar   if (skip("global:") || peek() != "local:")
140720b6598cSGeorge Rimar     readGlobal(VerStr);
140820b6598cSGeorge Rimar   if (skip("local:"))
140920b6598cSGeorge Rimar     readLocal();
141020b6598cSGeorge Rimar   expect("}");
141120b6598cSGeorge Rimar 
141220b6598cSGeorge Rimar   // Each version may have a parent version. For example, "Ver2" defined as
141320b6598cSGeorge Rimar   // "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This
141420b6598cSGeorge Rimar   // version hierarchy is, probably against your instinct, purely for human; the
141520b6598cSGeorge Rimar   // runtime doesn't care about them at all. In LLD, we simply skip the token.
141620b6598cSGeorge Rimar   if (!VerStr.empty() && peek() != ";")
141720b6598cSGeorge Rimar     next();
141820b6598cSGeorge Rimar   expect(";");
141920b6598cSGeorge Rimar }
142020b6598cSGeorge Rimar 
142120b6598cSGeorge Rimar void ScriptParser::readLocal() {
142220b6598cSGeorge Rimar   Config->DefaultSymbolVersion = VER_NDX_LOCAL;
142320b6598cSGeorge Rimar   expect("*");
142420b6598cSGeorge Rimar   expect(";");
142520b6598cSGeorge Rimar }
142620b6598cSGeorge Rimar 
142720b6598cSGeorge Rimar void ScriptParser::readExtern(std::vector<SymbolVersion> *Globals) {
142820b6598cSGeorge Rimar   expect("C++");
142920b6598cSGeorge Rimar   expect("{");
143020b6598cSGeorge Rimar 
143120b6598cSGeorge Rimar   for (;;) {
143220b6598cSGeorge Rimar     if (peek() == "}" || Error)
143320b6598cSGeorge Rimar       break;
143420b6598cSGeorge Rimar     Globals->push_back({next(), true});
143520b6598cSGeorge Rimar     expect(";");
143620b6598cSGeorge Rimar   }
143720b6598cSGeorge Rimar 
143820b6598cSGeorge Rimar   expect("}");
143920b6598cSGeorge Rimar   expect(";");
144020b6598cSGeorge Rimar }
144120b6598cSGeorge Rimar 
144220b6598cSGeorge Rimar void ScriptParser::readGlobal(StringRef VerStr) {
144320b6598cSGeorge Rimar   std::vector<SymbolVersion> *Globals;
144420b6598cSGeorge Rimar   if (VerStr.empty())
144520b6598cSGeorge Rimar     Globals = &Config->VersionScriptGlobals;
144620b6598cSGeorge Rimar   else
144720b6598cSGeorge Rimar     Globals = &Config->VersionDefinitions.back().Globals;
144820b6598cSGeorge Rimar 
144920b6598cSGeorge Rimar   for (;;) {
145020b6598cSGeorge Rimar     if (skip("extern"))
145120b6598cSGeorge Rimar       readExtern(Globals);
145220b6598cSGeorge Rimar 
145320b6598cSGeorge Rimar     StringRef Cur = peek();
145420b6598cSGeorge Rimar     if (Cur == "}" || Cur == "local:" || Error)
145520b6598cSGeorge Rimar       return;
145620b6598cSGeorge Rimar     next();
145720b6598cSGeorge Rimar     Globals->push_back({Cur, false});
145820b6598cSGeorge Rimar     expect(";");
145920b6598cSGeorge Rimar   }
146020b6598cSGeorge Rimar }
146120b6598cSGeorge Rimar 
146216b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) {
146316b0cc9eSSimon Atanasyan   if (Config->Sysroot == "")
146416b0cc9eSSimon Atanasyan     return false;
146516b0cc9eSSimon Atanasyan   for (; !Path.empty(); Path = sys::path::parent_path(Path))
146616b0cc9eSSimon Atanasyan     if (sys::fs::equivalent(Config->Sysroot, Path))
146716b0cc9eSSimon Atanasyan       return true;
146816b0cc9eSSimon Atanasyan   return false;
146916b0cc9eSSimon Atanasyan }
147016b0cc9eSSimon Atanasyan 
147107320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) {
147216b0cc9eSSimon Atanasyan   StringRef Path = MB.getBufferIdentifier();
147320b6598cSGeorge Rimar   ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).readLinkerScript();
147420b6598cSGeorge Rimar }
147520b6598cSGeorge Rimar 
147620b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) {
147720b6598cSGeorge Rimar   ScriptParser(MB.getBuffer(), false).readVersionScript();
1478f7c5fbb1SRui Ueyama }
14791ebc8ed7SRui Ueyama 
148007320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>;
148107320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>;
148207320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>;
148307320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>;
1484