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 
46076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
47076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
48076fe157SGeorge Rimar }
49076fe157SGeorge Rimar 
50076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
51076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
52076fe157SGeorge Rimar }
53076fe157SGeorge Rimar 
54eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
55eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
56eea3114fSGeorge Rimar }
57eea3114fSGeorge Rimar 
5836a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) {
59eea3114fSGeorge Rimar   return !S || !S->Live;
60717677afSRui Ueyama }
61717677afSRui Ueyama 
6207320e40SRui Ueyama template <class ELFT>
6307320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) {
648ec77e64SRui Ueyama   for (StringRef Pat : Opt.KeptSections)
65722830a5SRui Ueyama     if (globMatch(Pat, S->getSectionName()))
668ec77e64SRui Ueyama       return true;
678ec77e64SRui Ueyama   return false;
68481c2ce6SGeorge Rimar }
69481c2ce6SGeorge Rimar 
70eea3114fSGeorge Rimar static bool match(StringRef Pattern, ArrayRef<StringRef> Arr) {
71eea3114fSGeorge Rimar   for (StringRef S : Arr)
72eea3114fSGeorge Rimar     if (globMatch(S, Pattern))
73eea3114fSGeorge Rimar       return true;
74eea3114fSGeorge Rimar   return false;
75eea3114fSGeorge Rimar }
76eea3114fSGeorge Rimar 
77652852c5SGeorge Rimar template <class ELFT>
78a7f7884dSRui Ueyama std::vector<OutputSectionBase<ELFT> *>
79e63d81bdSEugene Leviant LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
80eea3114fSGeorge Rimar   typedef const std::unique_ptr<ObjectFile<ELFT>> ObjectFile;
81a7f7884dSRui Ueyama   std::vector<OutputSectionBase<ELFT> *> Result;
828a9bb7baSRui Ueyama   DenseSet<OutputSectionBase<ELFT> *> Removed;
83a7f7884dSRui Ueyama 
84e63d81bdSEugene Leviant   // Add input section to output section. If there is no output section yet,
85e63d81bdSEugene Leviant   // then create it and add to output section list.
868a9bb7baSRui Ueyama   auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name,
878a9bb7baSRui Ueyama                          ConstraintKind Constraint) {
88e63d81bdSEugene Leviant     OutputSectionBase<ELFT> *Sec;
89e63d81bdSEugene Leviant     bool IsNew;
90e63d81bdSEugene Leviant     std::tie(Sec, IsNew) = Factory.create(C, Name);
91e63d81bdSEugene Leviant     if (IsNew)
92a7f7884dSRui Ueyama       Result.push_back(Sec);
938a9bb7baSRui Ueyama     if ((!(C->getSectionHdr()->sh_flags & SHF_WRITE)) &&
948a9bb7baSRui Ueyama         Constraint == ReadWrite) {
958a9bb7baSRui Ueyama       Removed.insert(Sec);
968a9bb7baSRui Ueyama       return;
978a9bb7baSRui Ueyama     }
988a9bb7baSRui Ueyama     if ((C->getSectionHdr()->sh_flags & SHF_WRITE) && Constraint == ReadOnly) {
998a9bb7baSRui Ueyama       Removed.insert(Sec);
1008a9bb7baSRui Ueyama       return;
1018a9bb7baSRui Ueyama     }
102e63d81bdSEugene Leviant     Sec->addSection(C);
103e63d81bdSEugene Leviant   };
104e63d81bdSEugene Leviant 
105e63d81bdSEugene Leviant   // Select input sections matching rule and add them to corresponding
106e63d81bdSEugene Leviant   // output section. Section rules are processed in order they're listed
107e63d81bdSEugene Leviant   // in script, so correct input section order is maintained by design.
108eea3114fSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
109eea3114fSGeorge Rimar     auto *OutCmd = dyn_cast<OutputSectionCommand>(Base.get());
110eea3114fSGeorge Rimar     if (!OutCmd)
111eea3114fSGeorge Rimar       continue;
112eea3114fSGeorge Rimar 
113eea3114fSGeorge Rimar     for (const std::unique_ptr<BaseCommand> &Cmd : OutCmd->Commands) {
114eea3114fSGeorge Rimar       auto *InCmd = dyn_cast<InputSectionDescription>(Cmd.get());
115eea3114fSGeorge Rimar       if (!InCmd)
116eea3114fSGeorge Rimar         continue;
117eea3114fSGeorge Rimar 
118eea3114fSGeorge Rimar       for (ObjectFile &F : Symtab<ELFT>::X->getObjectFiles()) {
119eea3114fSGeorge Rimar         for (InputSectionBase<ELFT> *S : F->getSections()) {
120eea3114fSGeorge Rimar           if (isDiscarded(S) || S->OutSec)
121eea3114fSGeorge Rimar             continue;
122eea3114fSGeorge Rimar 
123eea3114fSGeorge Rimar           if (match(S->getSectionName(), InCmd->Patterns)) {
124eea3114fSGeorge Rimar             if (OutCmd->Name == "/DISCARD/")
125eea3114fSGeorge Rimar               S->Live = false;
126eea3114fSGeorge Rimar             else
1278a9bb7baSRui Ueyama               AddInputSec(S, OutCmd->Name, OutCmd->Constraint);
128eea3114fSGeorge Rimar           }
129eea3114fSGeorge Rimar         }
130eea3114fSGeorge Rimar       }
131eea3114fSGeorge Rimar     }
132eea3114fSGeorge Rimar   }
133e63d81bdSEugene Leviant 
134e63d81bdSEugene Leviant   // Add all other input sections, which are not listed in script.
135eea3114fSGeorge Rimar   for (ObjectFile &F : Symtab<ELFT>::X->getObjectFiles())
1363c944ec8SReid Kleckner     for (InputSectionBase<ELFT> *S : F->getSections()) {
137e63d81bdSEugene Leviant       if (!isDiscarded(S)) {
138e63d81bdSEugene Leviant         if (!S->OutSec)
1398a9bb7baSRui Ueyama           AddInputSec(S, getOutputSectionName(S), NoConstraint);
140e63d81bdSEugene Leviant       } else
141e63d81bdSEugene Leviant         reportDiscarded(S, F);
1423c944ec8SReid Kleckner     }
143e63d81bdSEugene Leviant 
1448a9bb7baSRui Ueyama   // Remove from the output all the sections which did not met the constraints.
1458a9bb7baSRui Ueyama   Result.erase(std::remove_if(Result.begin(), Result.end(),
1468a9bb7baSRui Ueyama                               [&](OutputSectionBase<ELFT> *Sec) {
1478a9bb7baSRui Ueyama                                 return Removed.count(Sec);
1488a9bb7baSRui Ueyama                               }),
1498a9bb7baSRui Ueyama                Result.end());
1508a9bb7baSRui Ueyama   return Result;
151e63d81bdSEugene Leviant }
152e63d81bdSEugene Leviant 
153e63d81bdSEugene Leviant template <class ELFT>
15410e576e1SGeorge Rimar void LinkerScript<ELFT>::dispatchAssignment(SymbolAssignment *Cmd) {
155708019c4SRui Ueyama   uint64_t Val = Cmd->Expression(Dot);
15610e576e1SGeorge Rimar   if (Cmd->Name == ".") {
15710e576e1SGeorge Rimar     Dot = Val;
158a31c91b1SEugene Leviant   } else if (!Cmd->Ignore) {
15910e576e1SGeorge Rimar     auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd->Name));
16010e576e1SGeorge Rimar     D->Value = Val;
16110e576e1SGeorge Rimar   }
16210e576e1SGeorge Rimar }
16310e576e1SGeorge Rimar 
16410e576e1SGeorge Rimar template <class ELFT>
16507320e40SRui Ueyama void LinkerScript<ELFT>::assignAddresses(
166dbbd8b15SGeorge Rimar     ArrayRef<OutputSectionBase<ELFT> *> Sections) {
167652852c5SGeorge Rimar   // Orphan sections are sections present in the input files which
1687c18c28cSRui Ueyama   // are not explicitly placed into the output file by the linker script.
1697c18c28cSRui Ueyama   // We place orphan sections at end of file.
1707c18c28cSRui Ueyama   // Other linkers places them using some heuristics as described in
171652852c5SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections.
1727c18c28cSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : Sections) {
173652852c5SGeorge Rimar     StringRef Name = Sec->getName();
174c3e2a4b0SRui Ueyama     if (getSectionIndex(Name) == INT_MAX)
175076fe157SGeorge Rimar       Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name));
176652852c5SGeorge Rimar   }
177652852c5SGeorge Rimar 
1787c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
179c998a8c0SRui Ueyama   Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
180467c4d55SEugene Leviant   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
181652852c5SGeorge Rimar   uintX_t ThreadBssOffset = 0;
182652852c5SGeorge Rimar 
183076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
184076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
18510e576e1SGeorge Rimar       dispatchAssignment(Cmd);
18605ef4cffSRui Ueyama       continue;
187652852c5SGeorge Rimar     }
188652852c5SGeorge Rimar 
189fb8978fcSDima Stepanov     // Find all the sections with required name. There can be more than
1906ad330acSGeorge Rimar     // one section with such name, if the alignment, flags or type
191fb8978fcSDima Stepanov     // attribute differs.
192076fe157SGeorge Rimar     auto *Cmd = cast<OutputSectionCommand>(Base.get());
193fb8978fcSDima Stepanov     for (OutputSectionBase<ELFT> *Sec : Sections) {
194076fe157SGeorge Rimar       if (Sec->getName() != Cmd->Name)
195652852c5SGeorge Rimar         continue;
196652852c5SGeorge Rimar 
197652852c5SGeorge Rimar       if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
198c998a8c0SRui Ueyama         uintX_t TVA = Dot + ThreadBssOffset;
199424b4081SRui Ueyama         TVA = alignTo(TVA, Sec->getAlignment());
200652852c5SGeorge Rimar         Sec->setVA(TVA);
201c998a8c0SRui Ueyama         ThreadBssOffset = TVA - Dot + Sec->getSize();
202652852c5SGeorge Rimar         continue;
203652852c5SGeorge Rimar       }
204652852c5SGeorge Rimar 
205652852c5SGeorge Rimar       if (Sec->getFlags() & SHF_ALLOC) {
206424b4081SRui Ueyama         Dot = alignTo(Dot, Sec->getAlignment());
207c998a8c0SRui Ueyama         Sec->setVA(Dot);
208467c4d55SEugene Leviant         MinVA = std::min(MinVA, Dot);
209c998a8c0SRui Ueyama         Dot += Sec->getSize();
210652852c5SGeorge Rimar         continue;
211652852c5SGeorge Rimar       }
212652852c5SGeorge Rimar     }
213652852c5SGeorge Rimar   }
214467c4d55SEugene Leviant 
21564c32d6fSRafael Espindola   // ELF and Program headers need to be right before the first section in
216b91e7118SGeorge Rimar   // memory. Set their addresses accordingly.
217467c4d55SEugene Leviant   MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() -
218467c4d55SEugene Leviant                         Out<ELFT>::ProgramHeaders->getSize(),
219467c4d55SEugene Leviant                     Target->PageSize);
220467c4d55SEugene Leviant   Out<ELFT>::ElfHeader->setVA(MinVA);
221467c4d55SEugene Leviant   Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA);
222fb8978fcSDima Stepanov }
223652852c5SGeorge Rimar 
22407320e40SRui Ueyama template <class ELFT>
22574df5c7eSRafael Espindola std::vector<PhdrEntry<ELFT>>
226bbe38602SEugene Leviant LinkerScript<ELFT>::createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> Sections) {
227bbe38602SEugene Leviant   int TlsNum = -1;
228bbe38602SEugene Leviant   int NoteNum = -1;
229bbe38602SEugene Leviant   int RelroNum = -1;
230adca245fSRui Ueyama   PhdrEntry<ELFT> *Load = nullptr;
231bbe38602SEugene Leviant   uintX_t Flags = PF_R;
232adca245fSRui Ueyama   std::vector<PhdrEntry<ELFT>> Phdrs;
233bbe38602SEugene Leviant 
234bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
235865bf863SEugene Leviant     Phdrs.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
236adca245fSRui Ueyama     PhdrEntry<ELFT> &Phdr = Phdrs.back();
237bbe38602SEugene Leviant 
238bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
239adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ElfHeader);
240bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
241adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ProgramHeaders);
242bbe38602SEugene Leviant 
243bbe38602SEugene Leviant     switch (Cmd.Type) {
244bbe38602SEugene Leviant     case PT_INTERP:
245fd03cfd2SRui Ueyama       if (Out<ELFT>::Interp)
246adca245fSRui Ueyama         Phdr.add(Out<ELFT>::Interp);
247bbe38602SEugene Leviant       break;
248bbe38602SEugene Leviant     case PT_DYNAMIC:
249bbe38602SEugene Leviant       if (isOutputDynamic<ELFT>()) {
250adca245fSRui Ueyama         Phdr.H.p_flags = toPhdrFlags(Out<ELFT>::Dynamic->getFlags());
251adca245fSRui Ueyama         Phdr.add(Out<ELFT>::Dynamic);
252bbe38602SEugene Leviant       }
253bbe38602SEugene Leviant       break;
254bbe38602SEugene Leviant     case PT_TLS:
255bbe38602SEugene Leviant       TlsNum = Phdrs.size() - 1;
256bbe38602SEugene Leviant       break;
257bbe38602SEugene Leviant     case PT_NOTE:
258bbe38602SEugene Leviant       NoteNum = Phdrs.size() - 1;
259bbe38602SEugene Leviant       break;
260bbe38602SEugene Leviant     case PT_GNU_RELRO:
261bbe38602SEugene Leviant       RelroNum = Phdrs.size() - 1;
262bbe38602SEugene Leviant       break;
263bbe38602SEugene Leviant     case PT_GNU_EH_FRAME:
264bbe38602SEugene Leviant       if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) {
265adca245fSRui Ueyama         Phdr.H.p_flags = toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags());
266adca245fSRui Ueyama         Phdr.add(Out<ELFT>::EhFrameHdr);
267bbe38602SEugene Leviant       }
268bbe38602SEugene Leviant       break;
269bbe38602SEugene Leviant     }
270bbe38602SEugene Leviant   }
271bbe38602SEugene Leviant 
272bbe38602SEugene Leviant   for (OutputSectionBase<ELFT> *Sec : Sections) {
273bbe38602SEugene Leviant     if (!(Sec->getFlags() & SHF_ALLOC))
274bbe38602SEugene Leviant       break;
275bbe38602SEugene Leviant 
276bbe38602SEugene Leviant     if (TlsNum != -1 && (Sec->getFlags() & SHF_TLS))
27718f084ffSRui Ueyama       Phdrs[TlsNum].add(Sec);
278bbe38602SEugene Leviant 
279bbe38602SEugene Leviant     if (!needsPtLoad<ELFT>(Sec))
280bbe38602SEugene Leviant       continue;
281bbe38602SEugene Leviant 
282bbe38602SEugene Leviant     const std::vector<size_t> &PhdrIds =
283bbe38602SEugene Leviant         getPhdrIndicesForSection(Sec->getName());
284bbe38602SEugene Leviant     if (!PhdrIds.empty()) {
285bbe38602SEugene Leviant       // Assign headers specified by linker script
286bbe38602SEugene Leviant       for (size_t Id : PhdrIds) {
28718f084ffSRui Ueyama         Phdrs[Id].add(Sec);
288865bf863SEugene Leviant         if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
289865bf863SEugene Leviant           Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags());
290bbe38602SEugene Leviant       }
291bbe38602SEugene Leviant     } else {
292bbe38602SEugene Leviant       // If we have no load segment or flags've changed then we want new load
293bbe38602SEugene Leviant       // segment.
294bbe38602SEugene Leviant       uintX_t NewFlags = toPhdrFlags(Sec->getFlags());
295bbe38602SEugene Leviant       if (Load == nullptr || Flags != NewFlags) {
296bbe38602SEugene Leviant         Load = &*Phdrs.emplace(Phdrs.end(), PT_LOAD, NewFlags);
297bbe38602SEugene Leviant         Flags = NewFlags;
298bbe38602SEugene Leviant       }
29918f084ffSRui Ueyama       Load->add(Sec);
300bbe38602SEugene Leviant     }
301bbe38602SEugene Leviant 
302bbe38602SEugene Leviant     if (RelroNum != -1 && isRelroSection(Sec))
30318f084ffSRui Ueyama       Phdrs[RelroNum].add(Sec);
304bbe38602SEugene Leviant     if (NoteNum != -1 && Sec->getType() == SHT_NOTE)
30518f084ffSRui Ueyama       Phdrs[NoteNum].add(Sec);
306bbe38602SEugene Leviant   }
307bbe38602SEugene Leviant   return Phdrs;
308bbe38602SEugene Leviant }
309bbe38602SEugene Leviant 
310bbe38602SEugene Leviant template <class ELFT>
31107320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) {
312f6c3ccefSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
313f6c3ccefSGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
314f6c3ccefSGeorge Rimar       if (Cmd->Name == Name)
315f6c3ccefSGeorge Rimar         return Cmd->Filler;
316e2ee72b5SGeorge Rimar   return {};
317e2ee72b5SGeorge Rimar }
318e2ee72b5SGeorge Rimar 
319c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script
320c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they
321c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script,
322c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file.
323076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) {
32471b26e94SGeorge Rimar   auto Begin = Opt.Commands.begin();
32571b26e94SGeorge Rimar   auto End = Opt.Commands.end();
326076fe157SGeorge Rimar   auto I =
327076fe157SGeorge Rimar       std::find_if(Begin, End, [&](const std::unique_ptr<BaseCommand> &Base) {
328076fe157SGeorge Rimar         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
329076fe157SGeorge Rimar           if (Cmd->Name == Name)
330076fe157SGeorge Rimar             return true;
331076fe157SGeorge Rimar         return false;
33271b26e94SGeorge Rimar       });
333c3e2a4b0SRui Ueyama   return I == End ? INT_MAX : (I - Begin);
33471b26e94SGeorge Rimar }
33571b26e94SGeorge Rimar 
33671b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if
33771b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0.
33807320e40SRui Ueyama template <class ELFT>
33907320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) {
340c3e2a4b0SRui Ueyama   int I = getSectionIndex(A);
341c3e2a4b0SRui Ueyama   int J = getSectionIndex(B);
342c3e2a4b0SRui Ueyama   if (I == INT_MAX && J == INT_MAX)
343717677afSRui Ueyama     return 0;
344717677afSRui Ueyama   return I < J ? -1 : 1;
345717677afSRui Ueyama }
346717677afSRui Ueyama 
347076fe157SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::addScriptedSymbols() {
348a31c91b1SEugene Leviant   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
349a31c91b1SEugene Leviant     auto *Cmd = dyn_cast<SymbolAssignment>(Base.get());
350a31c91b1SEugene Leviant     if (!Cmd || Cmd->Name == ".")
351a31c91b1SEugene Leviant       continue;
352a31c91b1SEugene Leviant 
3538ab4108dSDavide Italiano     SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name);
3548ab4108dSDavide Italiano     if (!B || B->isUndefined())
355a31c91b1SEugene Leviant       Symtab<ELFT>::X->addAbsolute(Cmd->Name,
356a31c91b1SEugene Leviant                                    Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT);
357a31c91b1SEugene Leviant     else
358a31c91b1SEugene Leviant       // Symbol already exists in symbol table. If it is provided
359a31c91b1SEugene Leviant       // then we can't override its value.
360a31c91b1SEugene Leviant       Cmd->Ignore = Cmd->Provide;
361a31c91b1SEugene Leviant   }
362eda81a1bSEugene Leviant }
363eda81a1bSEugene Leviant 
364bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
365bbe38602SEugene Leviant   return !Opt.PhdrsCommands.empty();
366bbe38602SEugene Leviant }
367bbe38602SEugene Leviant 
368bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified
369bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within
370bbe38602SEugene Leviant // PHDRS {} script block.
371bbe38602SEugene Leviant template <class ELFT>
372bbe38602SEugene Leviant std::vector<size_t>
373bbe38602SEugene Leviant LinkerScript<ELFT>::getPhdrIndicesForSection(StringRef Name) {
374076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
375076fe157SGeorge Rimar     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
376076fe157SGeorge Rimar     if (!Cmd || Cmd->Name != Name)
37731d842f5SGeorge Rimar       continue;
37831d842f5SGeorge Rimar 
379bbe38602SEugene Leviant     std::vector<size_t> Indices;
380076fe157SGeorge Rimar     for (StringRef PhdrName : Cmd->Phdrs) {
38131d842f5SGeorge Rimar       auto ItPhdr =
38231d842f5SGeorge Rimar           std::find_if(Opt.PhdrsCommands.rbegin(), Opt.PhdrsCommands.rend(),
383076fe157SGeorge Rimar                        [&](PhdrsCommand &P) { return P.Name == PhdrName; });
384bbe38602SEugene Leviant       if (ItPhdr == Opt.PhdrsCommands.rend())
385bbe38602SEugene Leviant         error("section header '" + PhdrName + "' is not listed in PHDRS");
386bbe38602SEugene Leviant       else
387bbe38602SEugene Leviant         Indices.push_back(std::distance(ItPhdr, Opt.PhdrsCommands.rend()) - 1);
388bbe38602SEugene Leviant     }
389bbe38602SEugene Leviant     return Indices;
390bbe38602SEugene Leviant   }
39131d842f5SGeorge Rimar   return {};
39231d842f5SGeorge Rimar }
393bbe38602SEugene Leviant 
39407320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase {
395c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
396c3794e58SGeorge Rimar 
397f7c5fbb1SRui Ueyama public:
39807320e40SRui Ueyama   ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {}
399f23b2320SGeorge Rimar 
4004a46539cSRui Ueyama   void run();
401f7c5fbb1SRui Ueyama 
402f7c5fbb1SRui Ueyama private:
40352a1509eSRui Ueyama   void addFile(StringRef Path);
40452a1509eSRui Ueyama 
405f7c5fbb1SRui Ueyama   void readAsNeeded();
40690c5099eSDenis Protivensky   void readEntry();
40783f406cfSGeorge Rimar   void readExtern();
408f7c5fbb1SRui Ueyama   void readGroup();
40931aa1f83SRui Ueyama   void readInclude();
410c3794e58SGeorge Rimar   void readNothing() {}
411ee59282bSRui Ueyama   void readOutput();
4129159ce93SDavide Italiano   void readOutputArch();
413f7c5fbb1SRui Ueyama   void readOutputFormat();
414bbe38602SEugene Leviant   void readPhdrs();
41568a39a65SDavide Italiano   void readSearchDir();
4168e3b38abSDenis Protivensky   void readSections();
4178e3b38abSDenis Protivensky 
418*113cdec9SRui Ueyama   SymbolAssignment *readAssignment(StringRef Name);
419eda81a1bSEugene Leviant   void readOutputSectionDescription(StringRef OutSec);
420bbe38602SEugene Leviant   std::vector<StringRef> readOutputSectionPhdrs();
421bbe38602SEugene Leviant   unsigned readPhdrType();
422a31c91b1SEugene Leviant   void readProvide(bool Hidden);
423708019c4SRui Ueyama 
424708019c4SRui Ueyama   Expr readExpr();
425708019c4SRui Ueyama   Expr readExpr1(Expr Lhs, int MinPrec);
426708019c4SRui Ueyama   Expr readPrimary();
427708019c4SRui Ueyama   Expr readTernary(Expr Cond);
428708019c4SRui Ueyama   Expr combine(StringRef Op, Expr Lhs, Expr Rhs);
429f7c5fbb1SRui Ueyama 
430c3794e58SGeorge Rimar   const static StringMap<Handler> Cmd;
43107320e40SRui Ueyama   ScriptConfiguration &Opt = *ScriptConfig;
43207320e40SRui Ueyama   StringSaver Saver = {ScriptConfig->Alloc};
43316b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
434f7c5fbb1SRui Ueyama };
435f7c5fbb1SRui Ueyama 
436e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = {
437c3794e58SGeorge Rimar     {"ENTRY", &ScriptParser::readEntry},
438c3794e58SGeorge Rimar     {"EXTERN", &ScriptParser::readExtern},
439c3794e58SGeorge Rimar     {"GROUP", &ScriptParser::readGroup},
440c3794e58SGeorge Rimar     {"INCLUDE", &ScriptParser::readInclude},
441c3794e58SGeorge Rimar     {"INPUT", &ScriptParser::readGroup},
442c3794e58SGeorge Rimar     {"OUTPUT", &ScriptParser::readOutput},
443c3794e58SGeorge Rimar     {"OUTPUT_ARCH", &ScriptParser::readOutputArch},
444c3794e58SGeorge Rimar     {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat},
445bbe38602SEugene Leviant     {"PHDRS", &ScriptParser::readPhdrs},
446c3794e58SGeorge Rimar     {"SEARCH_DIR", &ScriptParser::readSearchDir},
447c3794e58SGeorge Rimar     {"SECTIONS", &ScriptParser::readSections},
448c3794e58SGeorge Rimar     {";", &ScriptParser::readNothing}};
449c3794e58SGeorge Rimar 
450717677afSRui Ueyama void ScriptParser::run() {
451f7c5fbb1SRui Ueyama   while (!atEOF()) {
452f7c5fbb1SRui Ueyama     StringRef Tok = next();
453c3794e58SGeorge Rimar     if (Handler Fn = Cmd.lookup(Tok))
454c3794e58SGeorge Rimar       (this->*Fn)();
455c3794e58SGeorge Rimar     else
4565761042dSGeorge Rimar       setError("unknown directive: " + Tok);
457f7c5fbb1SRui Ueyama   }
458f7c5fbb1SRui Ueyama }
459f7c5fbb1SRui Ueyama 
460717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
46116b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
46216b0cc9eSSimon Atanasyan     SmallString<128> Path;
46316b0cc9eSSimon Atanasyan     (Config->Sysroot + S).toStringRef(Path);
46416b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
46516b0cc9eSSimon Atanasyan       Driver->addFile(Saver.save(Path.str()));
46616b0cc9eSSimon Atanasyan       return;
46716b0cc9eSSimon Atanasyan     }
46816b0cc9eSSimon Atanasyan   }
46916b0cc9eSSimon Atanasyan 
470f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
47152a1509eSRui Ueyama     Driver->addFile(S);
47252a1509eSRui Ueyama   } else if (S.startswith("=")) {
47352a1509eSRui Ueyama     if (Config->Sysroot.empty())
47452a1509eSRui Ueyama       Driver->addFile(S.substr(1));
47552a1509eSRui Ueyama     else
47652a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
47752a1509eSRui Ueyama   } else if (S.startswith("-l")) {
47821eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
479a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
480a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
48152a1509eSRui Ueyama   } else {
48252a1509eSRui Ueyama     std::string Path = findFromSearchPaths(S);
48352a1509eSRui Ueyama     if (Path.empty())
484777f9630SGeorge Rimar       setError("unable to find " + S);
485025d59b1SRui Ueyama     else
48652a1509eSRui Ueyama       Driver->addFile(Saver.save(Path));
48752a1509eSRui Ueyama   }
48852a1509eSRui Ueyama }
48952a1509eSRui Ueyama 
490717677afSRui Ueyama void ScriptParser::readAsNeeded() {
491f7c5fbb1SRui Ueyama   expect("(");
49235da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
49335da9b6eSRui Ueyama   Config->AsNeeded = true;
494025d59b1SRui Ueyama   while (!Error) {
495f7c5fbb1SRui Ueyama     StringRef Tok = next();
496f7c5fbb1SRui Ueyama     if (Tok == ")")
49735da9b6eSRui Ueyama       break;
49852a1509eSRui Ueyama     addFile(Tok);
499f7c5fbb1SRui Ueyama   }
50035da9b6eSRui Ueyama   Config->AsNeeded = Orig;
501f7c5fbb1SRui Ueyama }
502f7c5fbb1SRui Ueyama 
503717677afSRui Ueyama void ScriptParser::readEntry() {
50490c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
50590c5099eSDenis Protivensky   expect("(");
50690c5099eSDenis Protivensky   StringRef Tok = next();
50790c5099eSDenis Protivensky   if (Config->Entry.empty())
50890c5099eSDenis Protivensky     Config->Entry = Tok;
50990c5099eSDenis Protivensky   expect(")");
51090c5099eSDenis Protivensky }
51190c5099eSDenis Protivensky 
512717677afSRui Ueyama void ScriptParser::readExtern() {
51383f406cfSGeorge Rimar   expect("(");
514025d59b1SRui Ueyama   while (!Error) {
51583f406cfSGeorge Rimar     StringRef Tok = next();
51683f406cfSGeorge Rimar     if (Tok == ")")
51783f406cfSGeorge Rimar       return;
51883f406cfSGeorge Rimar     Config->Undefined.push_back(Tok);
51983f406cfSGeorge Rimar   }
52083f406cfSGeorge Rimar }
52183f406cfSGeorge Rimar 
522717677afSRui Ueyama void ScriptParser::readGroup() {
523f7c5fbb1SRui Ueyama   expect("(");
524025d59b1SRui Ueyama   while (!Error) {
525f7c5fbb1SRui Ueyama     StringRef Tok = next();
526f7c5fbb1SRui Ueyama     if (Tok == ")")
527f7c5fbb1SRui Ueyama       return;
528f7c5fbb1SRui Ueyama     if (Tok == "AS_NEEDED") {
529f7c5fbb1SRui Ueyama       readAsNeeded();
530f7c5fbb1SRui Ueyama       continue;
531f7c5fbb1SRui Ueyama     }
53252a1509eSRui Ueyama     addFile(Tok);
533f7c5fbb1SRui Ueyama   }
534f7c5fbb1SRui Ueyama }
535f7c5fbb1SRui Ueyama 
536717677afSRui Ueyama void ScriptParser::readInclude() {
53731aa1f83SRui Ueyama   StringRef Tok = next();
53831aa1f83SRui Ueyama   auto MBOrErr = MemoryBuffer::getFile(Tok);
539025d59b1SRui Ueyama   if (!MBOrErr) {
5405761042dSGeorge Rimar     setError("cannot open " + Tok);
541025d59b1SRui Ueyama     return;
542025d59b1SRui Ueyama   }
54331aa1f83SRui Ueyama   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
544a47ee68dSRui Ueyama   StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
545a47ee68dSRui Ueyama   std::vector<StringRef> V = tokenize(S);
54631aa1f83SRui Ueyama   Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
54731aa1f83SRui Ueyama }
54831aa1f83SRui Ueyama 
549717677afSRui Ueyama void ScriptParser::readOutput() {
550ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
551ee59282bSRui Ueyama   expect("(");
552ee59282bSRui Ueyama   StringRef Tok = next();
553ee59282bSRui Ueyama   if (Config->OutputFile.empty())
554ee59282bSRui Ueyama     Config->OutputFile = Tok;
555ee59282bSRui Ueyama   expect(")");
556ee59282bSRui Ueyama }
557ee59282bSRui Ueyama 
558717677afSRui Ueyama void ScriptParser::readOutputArch() {
5599159ce93SDavide Italiano   // Error checking only for now.
5609159ce93SDavide Italiano   expect("(");
5619159ce93SDavide Italiano   next();
5629159ce93SDavide Italiano   expect(")");
5639159ce93SDavide Italiano }
5649159ce93SDavide Italiano 
565717677afSRui Ueyama void ScriptParser::readOutputFormat() {
566f7c5fbb1SRui Ueyama   // Error checking only for now.
567f7c5fbb1SRui Ueyama   expect("(");
568f7c5fbb1SRui Ueyama   next();
5696836c618SDavide Italiano   StringRef Tok = next();
5706836c618SDavide Italiano   if (Tok == ")")
5716836c618SDavide Italiano    return;
572025d59b1SRui Ueyama   if (Tok != ",") {
5735761042dSGeorge Rimar     setError("unexpected token: " + Tok);
574025d59b1SRui Ueyama     return;
575025d59b1SRui Ueyama   }
5766836c618SDavide Italiano   next();
5776836c618SDavide Italiano   expect(",");
5786836c618SDavide Italiano   next();
579f7c5fbb1SRui Ueyama   expect(")");
580f7c5fbb1SRui Ueyama }
581f7c5fbb1SRui Ueyama 
582bbe38602SEugene Leviant void ScriptParser::readPhdrs() {
583bbe38602SEugene Leviant   expect("{");
584bbe38602SEugene Leviant   while (!Error && !skip("}")) {
585bbe38602SEugene Leviant     StringRef Tok = next();
586865bf863SEugene Leviant     Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX});
587bbe38602SEugene Leviant     PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back();
588bbe38602SEugene Leviant 
589bbe38602SEugene Leviant     PhdrCmd.Type = readPhdrType();
590bbe38602SEugene Leviant     do {
591bbe38602SEugene Leviant       Tok = next();
592bbe38602SEugene Leviant       if (Tok == ";")
593bbe38602SEugene Leviant         break;
594bbe38602SEugene Leviant       if (Tok == "FILEHDR")
595bbe38602SEugene Leviant         PhdrCmd.HasFilehdr = true;
596bbe38602SEugene Leviant       else if (Tok == "PHDRS")
597bbe38602SEugene Leviant         PhdrCmd.HasPhdrs = true;
598865bf863SEugene Leviant       else if (Tok == "FLAGS") {
599865bf863SEugene Leviant         expect("(");
600865bf863SEugene Leviant         next().getAsInteger(0, PhdrCmd.Flags);
601865bf863SEugene Leviant         expect(")");
602865bf863SEugene Leviant       } else
603bbe38602SEugene Leviant         setError("unexpected header attribute: " + Tok);
604bbe38602SEugene Leviant     } while (!Error);
605bbe38602SEugene Leviant   }
606bbe38602SEugene Leviant }
607bbe38602SEugene Leviant 
608717677afSRui Ueyama void ScriptParser::readSearchDir() {
60968a39a65SDavide Italiano   expect("(");
61006501920SRafael Espindola   Config->SearchPaths.push_back(next());
61168a39a65SDavide Italiano   expect(")");
61268a39a65SDavide Italiano }
61368a39a65SDavide Italiano 
614717677afSRui Ueyama void ScriptParser::readSections() {
61507320e40SRui Ueyama   Opt.DoLayout = true;
6168e3b38abSDenis Protivensky   expect("{");
617652852c5SGeorge Rimar   while (!Error && !skip("}")) {
618*113cdec9SRui Ueyama     StringRef Tok = next();
619*113cdec9SRui Ueyama     if (peek() == "=") {
620*113cdec9SRui Ueyama       readAssignment(Tok);
621*113cdec9SRui Ueyama       expect(";");
622*113cdec9SRui Ueyama     } else if (Tok == "PROVIDE") {
623a31c91b1SEugene Leviant       readProvide(false);
624708019c4SRui Ueyama     } else if (Tok == "PROVIDE_HIDDEN") {
625a31c91b1SEugene Leviant       readProvide(true);
626708019c4SRui Ueyama     } else {
627eda81a1bSEugene Leviant       readOutputSectionDescription(Tok);
6288e3b38abSDenis Protivensky     }
629652852c5SGeorge Rimar   }
630708019c4SRui Ueyama }
6318e3b38abSDenis Protivensky 
632708019c4SRui Ueyama static int precedence(StringRef Op) {
633708019c4SRui Ueyama   return StringSwitch<int>(Op)
634708019c4SRui Ueyama       .Case("*", 4)
635708019c4SRui Ueyama       .Case("/", 4)
636708019c4SRui Ueyama       .Case("+", 3)
637708019c4SRui Ueyama       .Case("-", 3)
638708019c4SRui Ueyama       .Case("<", 2)
639708019c4SRui Ueyama       .Case(">", 2)
640708019c4SRui Ueyama       .Case(">=", 2)
641708019c4SRui Ueyama       .Case("<=", 2)
642708019c4SRui Ueyama       .Case("==", 2)
643708019c4SRui Ueyama       .Case("!=", 2)
644708019c4SRui Ueyama       .Case("&", 1)
645708019c4SRui Ueyama       .Default(-1);
646708019c4SRui Ueyama }
647708019c4SRui Ueyama 
648eda81a1bSEugene Leviant void ScriptParser::readOutputSectionDescription(StringRef OutSec) {
649076fe157SGeorge Rimar   OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
650076fe157SGeorge Rimar   Opt.Commands.emplace_back(Cmd);
6518e3b38abSDenis Protivensky   expect(":");
652246f681eSDavide Italiano 
653246f681eSDavide Italiano   // Parse constraints.
654246f681eSDavide Italiano   if (skip("ONLY_IF_RO"))
655246f681eSDavide Italiano     Cmd->Constraint = ReadOnly;
656246f681eSDavide Italiano   if (skip("ONLY_IF_RW"))
657246f681eSDavide Italiano     Cmd->Constraint = ReadWrite;
6588e3b38abSDenis Protivensky   expect("{");
6598ec77e64SRui Ueyama 
660025d59b1SRui Ueyama   while (!Error && !skip("}")) {
661481c2ce6SGeorge Rimar     StringRef Tok = next();
662481c2ce6SGeorge Rimar     if (Tok == "*") {
663eea3114fSGeorge Rimar       auto *InCmd = new InputSectionDescription();
664eea3114fSGeorge Rimar       Cmd->Commands.emplace_back(InCmd);
6658ec77e64SRui Ueyama       expect("(");
6668ec77e64SRui Ueyama       while (!Error && !skip(")"))
667eea3114fSGeorge Rimar         InCmd->Patterns.push_back(next());
668481c2ce6SGeorge Rimar     } else if (Tok == "KEEP") {
6698e3b38abSDenis Protivensky       expect("(");
6708ec77e64SRui Ueyama       expect("*");
6718ec77e64SRui Ueyama       expect("(");
672eea3114fSGeorge Rimar       auto *InCmd = new InputSectionDescription();
673eea3114fSGeorge Rimar       Cmd->Commands.emplace_back(InCmd);
6748ec77e64SRui Ueyama       while (!Error && !skip(")")) {
675eea3114fSGeorge Rimar         Opt.KeptSections.push_back(peek());
676eea3114fSGeorge Rimar         InCmd->Patterns.push_back(next());
6778ec77e64SRui Ueyama       }
678481c2ce6SGeorge Rimar       expect(")");
679481c2ce6SGeorge Rimar     } else {
680777f9630SGeorge Rimar       setError("unknown command " + Tok);
681481c2ce6SGeorge Rimar     }
6828e3b38abSDenis Protivensky   }
683076fe157SGeorge Rimar   Cmd->Phdrs = readOutputSectionPhdrs();
6848ec77e64SRui Ueyama 
685e2ee72b5SGeorge Rimar   StringRef Tok = peek();
686e2ee72b5SGeorge Rimar   if (Tok.startswith("=")) {
687e2ee72b5SGeorge Rimar     if (!Tok.startswith("=0x")) {
6883ed2f069SRui Ueyama       setError("filler should be a hexadecimal value");
689e2ee72b5SGeorge Rimar       return;
690e2ee72b5SGeorge Rimar     }
6913e808976SRui Ueyama     Tok = Tok.substr(3);
692f6c3ccefSGeorge Rimar     Cmd->Filler = parseHex(Tok);
693e2ee72b5SGeorge Rimar     next();
694e2ee72b5SGeorge Rimar   }
6958e3b38abSDenis Protivensky }
6968e3b38abSDenis Protivensky 
697a31c91b1SEugene Leviant void ScriptParser::readProvide(bool Hidden) {
698a31c91b1SEugene Leviant   expect("(");
699*113cdec9SRui Ueyama   if (SymbolAssignment *Assignment = readAssignment(next())) {
700a31c91b1SEugene Leviant     Assignment->Provide = true;
701a31c91b1SEugene Leviant     Assignment->Hidden = Hidden;
702a31c91b1SEugene Leviant   }
703a31c91b1SEugene Leviant   expect(")");
704a31c91b1SEugene Leviant   expect(";");
705eda81a1bSEugene Leviant }
706eda81a1bSEugene Leviant 
707*113cdec9SRui Ueyama SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
708a31c91b1SEugene Leviant   expect("=");
709708019c4SRui Ueyama   Expr E = readExpr();
710*113cdec9SRui Ueyama   auto *Cmd = new SymbolAssignment(Name, E);
711*113cdec9SRui Ueyama   Opt.Commands.emplace_back(Cmd);
712*113cdec9SRui Ueyama   return Cmd;
713a31c91b1SEugene Leviant }
714a31c91b1SEugene Leviant 
715708019c4SRui Ueyama // This is an operator-precedence parser to parse a linker
716708019c4SRui Ueyama // script expression.
717708019c4SRui Ueyama Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
718a31c91b1SEugene Leviant 
719708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function
720708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator.
721708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
722708019c4SRui Ueyama   while (!atEOF() && !Error) {
723708019c4SRui Ueyama     // Read an operator and an expression.
724708019c4SRui Ueyama     StringRef Op1 = peek();
725708019c4SRui Ueyama     if (Op1 == "?")
726708019c4SRui Ueyama       return readTernary(Lhs);
727708019c4SRui Ueyama     if (precedence(Op1) < MinPrec)
728a31c91b1SEugene Leviant       break;
729a31c91b1SEugene Leviant     next();
730708019c4SRui Ueyama     Expr Rhs = readPrimary();
731708019c4SRui Ueyama 
732708019c4SRui Ueyama     // Evaluate the remaining part of the expression first if the
733708019c4SRui Ueyama     // next operator has greater precedence than the previous one.
734708019c4SRui Ueyama     // For example, if we have read "+" and "3", and if the next
735708019c4SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
736708019c4SRui Ueyama     while (!atEOF()) {
737708019c4SRui Ueyama       StringRef Op2 = peek();
738708019c4SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
739eda81a1bSEugene Leviant         break;
740708019c4SRui Ueyama       Rhs = readExpr1(Rhs, precedence(Op2));
741eda81a1bSEugene Leviant     }
742708019c4SRui Ueyama 
743708019c4SRui Ueyama     Lhs = combine(Op1, Lhs, Rhs);
744708019c4SRui Ueyama   }
745708019c4SRui Ueyama   return Lhs;
746708019c4SRui Ueyama }
747708019c4SRui Ueyama 
748708019c4SRui Ueyama uint64_t static getConstant(StringRef S) {
749708019c4SRui Ueyama   if (S == "COMMONPAGESIZE" || S == "MAXPAGESIZE")
750708019c4SRui Ueyama     return Target->PageSize;
751708019c4SRui Ueyama   error("unknown constant: " + S);
752708019c4SRui Ueyama   return 0;
753708019c4SRui Ueyama }
754708019c4SRui Ueyama 
755708019c4SRui Ueyama Expr ScriptParser::readPrimary() {
756708019c4SRui Ueyama   StringRef Tok = next();
757708019c4SRui Ueyama 
758708019c4SRui Ueyama   if (Tok == ".")
759708019c4SRui Ueyama     return [](uint64_t Dot) { return Dot; };
760708019c4SRui Ueyama 
761708019c4SRui Ueyama   if (Tok == "(") {
762708019c4SRui Ueyama     Expr E = readExpr();
763708019c4SRui Ueyama     expect(")");
764708019c4SRui Ueyama     return E;
765708019c4SRui Ueyama   }
766708019c4SRui Ueyama 
767708019c4SRui Ueyama   // Built-in functions are parsed here.
768708019c4SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
769708019c4SRui Ueyama   if (Tok == "ALIGN") {
770708019c4SRui Ueyama     expect("(");
771708019c4SRui Ueyama     Expr E = readExpr();
772708019c4SRui Ueyama     expect(")");
773708019c4SRui Ueyama     return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); };
774708019c4SRui Ueyama   }
775708019c4SRui Ueyama   if (Tok == "CONSTANT") {
776708019c4SRui Ueyama     expect("(");
777708019c4SRui Ueyama     StringRef Tok = next();
778708019c4SRui Ueyama     expect(")");
779708019c4SRui Ueyama     return [=](uint64_t Dot) { return getConstant(Tok); };
780708019c4SRui Ueyama   }
781708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_ALIGN") {
782708019c4SRui Ueyama     expect("(");
783708019c4SRui Ueyama     Expr E = readExpr();
784708019c4SRui Ueyama     expect(",");
785708019c4SRui Ueyama     readExpr();
786708019c4SRui Ueyama     expect(")");
787708019c4SRui Ueyama     return [=](uint64_t Dot) -> uint64_t {
788708019c4SRui Ueyama       uint64_t Val = E(Dot);
789708019c4SRui Ueyama       return alignTo(Dot, Val) + (Dot & (Val - 1));
790708019c4SRui Ueyama     };
791708019c4SRui Ueyama   }
792708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_END") {
793708019c4SRui Ueyama     expect("(");
794708019c4SRui Ueyama     expect(".");
795708019c4SRui Ueyama     expect(")");
796708019c4SRui Ueyama     return [](uint64_t Dot) { return Dot; };
797708019c4SRui Ueyama   }
798708019c4SRui Ueyama 
799708019c4SRui Ueyama   // Parse a number literal
800708019c4SRui Ueyama   uint64_t V = 0;
801708019c4SRui Ueyama   if (Tok.getAsInteger(0, V))
802708019c4SRui Ueyama     setError("malformed number: " + Tok);
803708019c4SRui Ueyama   return [=](uint64_t Dot) { return V; };
804708019c4SRui Ueyama }
805708019c4SRui Ueyama 
806708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) {
807708019c4SRui Ueyama   next();
808708019c4SRui Ueyama   Expr L = readExpr();
809708019c4SRui Ueyama   expect(":");
810708019c4SRui Ueyama   Expr R = readExpr();
811708019c4SRui Ueyama   return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); };
812708019c4SRui Ueyama }
813708019c4SRui Ueyama 
814708019c4SRui Ueyama Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) {
815708019c4SRui Ueyama   if (Op == "*")
816708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) * R(Dot); };
817708019c4SRui Ueyama   if (Op == "/") {
818708019c4SRui Ueyama     return [=](uint64_t Dot) -> uint64_t {
819708019c4SRui Ueyama       uint64_t RHS = R(Dot);
820708019c4SRui Ueyama       if (RHS == 0) {
821708019c4SRui Ueyama         error("division by zero");
822708019c4SRui Ueyama         return 0;
823708019c4SRui Ueyama       }
824708019c4SRui Ueyama       return L(Dot) / RHS;
825708019c4SRui Ueyama     };
826708019c4SRui Ueyama   }
827708019c4SRui Ueyama   if (Op == "+")
828708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) + R(Dot); };
829708019c4SRui Ueyama   if (Op == "-")
830708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) - R(Dot); };
831708019c4SRui Ueyama   if (Op == "<")
832708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) < R(Dot); };
833708019c4SRui Ueyama   if (Op == ">")
834708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) > R(Dot); };
835708019c4SRui Ueyama   if (Op == ">=")
836708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) >= R(Dot); };
837708019c4SRui Ueyama   if (Op == "<=")
838708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) <= R(Dot); };
839708019c4SRui Ueyama   if (Op == "==")
840708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) == R(Dot); };
841708019c4SRui Ueyama   if (Op == "!=")
842708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) != R(Dot); };
843708019c4SRui Ueyama   if (Op == "&")
844708019c4SRui Ueyama     return [=](uint64_t Dot) { return L(Dot) & R(Dot); };
845708019c4SRui Ueyama   llvm_unreachable("invalid operator");
846eda81a1bSEugene Leviant }
847eda81a1bSEugene Leviant 
848bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
849bbe38602SEugene Leviant   std::vector<StringRef> Phdrs;
850bbe38602SEugene Leviant   while (!Error && peek().startswith(":")) {
851bbe38602SEugene Leviant     StringRef Tok = next();
852bbe38602SEugene Leviant     Tok = (Tok.size() == 1) ? next() : Tok.substr(1);
853bbe38602SEugene Leviant     if (Tok.empty()) {
854bbe38602SEugene Leviant       setError("section header name is empty");
855bbe38602SEugene Leviant       break;
856bbe38602SEugene Leviant     }
857bbe38602SEugene Leviant     Phdrs.push_back(Tok);
858bbe38602SEugene Leviant   }
859bbe38602SEugene Leviant   return Phdrs;
860bbe38602SEugene Leviant }
861bbe38602SEugene Leviant 
862bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() {
863bbe38602SEugene Leviant   StringRef Tok = next();
864b0f6c590SRui Ueyama   unsigned Ret = StringSwitch<unsigned>(Tok)
865b0f6c590SRui Ueyama       .Case("PT_NULL", PT_NULL)
866b0f6c590SRui Ueyama       .Case("PT_LOAD", PT_LOAD)
867b0f6c590SRui Ueyama       .Case("PT_DYNAMIC", PT_DYNAMIC)
868b0f6c590SRui Ueyama       .Case("PT_INTERP", PT_INTERP)
869b0f6c590SRui Ueyama       .Case("PT_NOTE", PT_NOTE)
870b0f6c590SRui Ueyama       .Case("PT_SHLIB", PT_SHLIB)
871b0f6c590SRui Ueyama       .Case("PT_PHDR", PT_PHDR)
872b0f6c590SRui Ueyama       .Case("PT_TLS", PT_TLS)
873b0f6c590SRui Ueyama       .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
874b0f6c590SRui Ueyama       .Case("PT_GNU_STACK", PT_GNU_STACK)
875b0f6c590SRui Ueyama       .Case("PT_GNU_RELRO", PT_GNU_RELRO)
876b0f6c590SRui Ueyama       .Default(-1);
877bbe38602SEugene Leviant 
878b0f6c590SRui Ueyama   if (Ret == (unsigned)-1) {
879b0f6c590SRui Ueyama     setError("invalid program header type: " + Tok);
880b0f6c590SRui Ueyama     return PT_NULL;
881b0f6c590SRui Ueyama   }
882b0f6c590SRui Ueyama   return Ret;
883bbe38602SEugene Leviant }
884bbe38602SEugene Leviant 
88516b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) {
88616b0cc9eSSimon Atanasyan   if (Config->Sysroot == "")
88716b0cc9eSSimon Atanasyan     return false;
88816b0cc9eSSimon Atanasyan   for (; !Path.empty(); Path = sys::path::parent_path(Path))
88916b0cc9eSSimon Atanasyan     if (sys::fs::equivalent(Config->Sysroot, Path))
89016b0cc9eSSimon Atanasyan       return true;
89116b0cc9eSSimon Atanasyan   return false;
89216b0cc9eSSimon Atanasyan }
89316b0cc9eSSimon Atanasyan 
89407320e40SRui Ueyama // Entry point.
89507320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) {
89616b0cc9eSSimon Atanasyan   StringRef Path = MB.getBufferIdentifier();
89707320e40SRui Ueyama   ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run();
898f7c5fbb1SRui Ueyama }
8991ebc8ed7SRui Ueyama 
90007320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>;
90107320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>;
90207320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>;
90307320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>;
904