1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===//
2f7c5fbb1SRui Ueyama //
3f7c5fbb1SRui Ueyama //                             The LLVM Linker
4f7c5fbb1SRui Ueyama //
5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source
6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details.
7f7c5fbb1SRui Ueyama //
8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===//
9f7c5fbb1SRui Ueyama //
10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script.
11f7c5fbb1SRui Ueyama //
12f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===//
13f7c5fbb1SRui Ueyama 
14717677afSRui Ueyama #include "LinkerScript.h"
15f7c5fbb1SRui Ueyama #include "Config.h"
16f7c5fbb1SRui Ueyama #include "Driver.h"
171ebc8ed7SRui Ueyama #include "InputSection.h"
189381eb10SRui Ueyama #include "Memory.h"
19652852c5SGeorge Rimar #include "OutputSections.h"
20794366a2SRui Ueyama #include "ScriptLexer.h"
2193c9af42SRui Ueyama #include "Strings.h"
22f7c5fbb1SRui Ueyama #include "SymbolTable.h"
2355518e7dSRui Ueyama #include "Symbols.h"
243fb5a6dcSGeorge Rimar #include "SyntheticSections.h"
25467c4d55SEugene Leviant #include "Target.h"
26bbe38602SEugene Leviant #include "Writer.h"
2722886a28SEugene Zelenko #include "llvm/ADT/STLExtras.h"
288c6a5aafSRui Ueyama #include "llvm/ADT/SmallString.h"
2922886a28SEugene Zelenko #include "llvm/ADT/StringRef.h"
30960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h"
3122886a28SEugene Zelenko #include "llvm/Support/Casting.h"
32652852c5SGeorge Rimar #include "llvm/Support/ELF.h"
3322886a28SEugene Zelenko #include "llvm/Support/Endian.h"
3422886a28SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
35f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h"
3622886a28SEugene Zelenko #include "llvm/Support/MathExtras.h"
37f03f3cc1SRui Ueyama #include "llvm/Support/Path.h"
3822886a28SEugene Zelenko #include <algorithm>
3922886a28SEugene Zelenko #include <cassert>
4022886a28SEugene Zelenko #include <cstddef>
4122886a28SEugene Zelenko #include <cstdint>
4222886a28SEugene Zelenko #include <iterator>
4322886a28SEugene Zelenko #include <limits>
4422886a28SEugene Zelenko #include <memory>
4522886a28SEugene Zelenko #include <string>
4622886a28SEugene Zelenko #include <tuple>
4722886a28SEugene Zelenko #include <vector>
48f7c5fbb1SRui Ueyama 
49f7c5fbb1SRui Ueyama using namespace llvm;
50652852c5SGeorge Rimar using namespace llvm::ELF;
511ebc8ed7SRui Ueyama using namespace llvm::object;
52e38cbab5SGeorge Rimar using namespace llvm::support::endian;
53f7c5fbb1SRui Ueyama using namespace lld;
54e0df00b9SRafael Espindola using namespace lld::elf;
55f7c5fbb1SRui Ueyama 
56a34da938SRui Ueyama LinkerScript *elf::Script;
57a34da938SRui Ueyama 
5872dc195dSRafael Espindola uint64_t ExprValue::getValue() const {
5972dc195dSRafael Espindola   if (Sec)
6072dc195dSRafael Espindola     return Sec->getOffset(Val) + Sec->getOutputSection()->Addr;
6172dc195dSRafael Espindola   return Val;
6272dc195dSRafael Espindola }
6372dc195dSRafael Espindola 
647ba5f47eSRafael Espindola uint64_t ExprValue::getSecAddr() const {
657ba5f47eSRafael Espindola   if (Sec)
667ba5f47eSRafael Espindola     return Sec->getOffset(0) + Sec->getOutputSection()->Addr;
677ba5f47eSRafael Espindola   return 0;
687ba5f47eSRafael Espindola }
697ba5f47eSRafael Espindola 
707ba5f47eSRafael Espindola // Some operations only support one non absolute value. Move the
717ba5f47eSRafael Espindola // absolute one to the right hand side for convenience.
727ba5f47eSRafael Espindola static void moveAbsRight(ExprValue &A, ExprValue &B) {
73f2115f04SRafael Espindola   if (A.isAbsolute())
74f2115f04SRafael Espindola     std::swap(A, B);
755f08a1dcSRafael Espindola   if (!B.isAbsolute())
765f08a1dcSRafael Espindola     error("At least one side of the expression must be absolute");
777ba5f47eSRafael Espindola }
787ba5f47eSRafael Espindola 
797ba5f47eSRafael Espindola static ExprValue add(ExprValue A, ExprValue B) {
807ba5f47eSRafael Espindola   moveAbsRight(A, B);
8172dc195dSRafael Espindola   return {A.Sec, A.ForceAbsolute, A.Val + B.getValue()};
8272dc195dSRafael Espindola }
8372dc195dSRafael Espindola static ExprValue sub(ExprValue A, ExprValue B) {
8472dc195dSRafael Espindola   return {A.Sec, A.Val - B.getValue()};
8572dc195dSRafael Espindola }
8672dc195dSRafael Espindola static ExprValue mul(ExprValue A, ExprValue B) {
8772dc195dSRafael Espindola   return A.getValue() * B.getValue();
8872dc195dSRafael Espindola }
8972dc195dSRafael Espindola static ExprValue div(ExprValue A, ExprValue B) {
9072dc195dSRafael Espindola   if (uint64_t BV = B.getValue())
9172dc195dSRafael Espindola     return A.getValue() / BV;
9272dc195dSRafael Espindola   error("division by zero");
9372dc195dSRafael Espindola   return 0;
9472dc195dSRafael Espindola }
9572dc195dSRafael Espindola static ExprValue leftShift(ExprValue A, ExprValue B) {
9672dc195dSRafael Espindola   return A.getValue() << B.getValue();
9772dc195dSRafael Espindola }
9872dc195dSRafael Espindola static ExprValue rightShift(ExprValue A, ExprValue B) {
9972dc195dSRafael Espindola   return A.getValue() >> B.getValue();
10072dc195dSRafael Espindola }
10172dc195dSRafael Espindola static ExprValue bitAnd(ExprValue A, ExprValue B) {
1027ba5f47eSRafael Espindola   moveAbsRight(A, B);
1037ba5f47eSRafael Espindola   return {A.Sec, A.ForceAbsolute,
1047ba5f47eSRafael Espindola           (A.getValue() & B.getValue()) - A.getSecAddr()};
10572dc195dSRafael Espindola }
10672dc195dSRafael Espindola static ExprValue bitOr(ExprValue A, ExprValue B) {
1077ba5f47eSRafael Espindola   moveAbsRight(A, B);
1087ba5f47eSRafael Espindola   return {A.Sec, A.ForceAbsolute,
1097ba5f47eSRafael Espindola           (A.getValue() | B.getValue()) - A.getSecAddr()};
11072dc195dSRafael Espindola }
11172dc195dSRafael Espindola static ExprValue bitNot(ExprValue A) { return ~A.getValue(); }
11272dc195dSRafael Espindola static ExprValue minus(ExprValue A) { return -A.getValue(); }
11372dc195dSRafael Espindola 
1148f1f3c40SMeador Inge template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
1155e51f7d2SPetr Hosek   Symbol *Sym;
1163dabfc6bSRafael Espindola   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
1175e51f7d2SPetr Hosek   std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
1185e51f7d2SPetr Hosek       Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
1195e51f7d2SPetr Hosek       /*File*/ nullptr);
1205e51f7d2SPetr Hosek   Sym->Binding = STB_GLOBAL;
12172dc195dSRafael Espindola   ExprValue Value = Cmd->Expression();
12272dc195dSRafael Espindola   SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
12380474a26SRui Ueyama   replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility,
1245616adf6SRafael Espindola                               STT_NOTYPE, 0, 0, Sec, nullptr);
1258f1f3c40SMeador Inge   return Sym->body();
126ceabe80eSEugene Leviant }
127ceabe80eSEugene Leviant 
12822375f24SRui Ueyama static bool isUnderSysroot(StringRef Path) {
12922375f24SRui Ueyama   if (Config->Sysroot == "")
13022375f24SRui Ueyama     return false;
13122375f24SRui Ueyama   for (; !Path.empty(); Path = sys::path::parent_path(Path))
13222375f24SRui Ueyama     if (sys::fs::equivalent(Config->Sysroot, Path))
13322375f24SRui Ueyama       return true;
13422375f24SRui Ueyama   return false;
13522375f24SRui Ueyama }
13622375f24SRui Ueyama 
137b8dd23f5SRui Ueyama OutputSection *LinkerScript::getOutputSection(const Twine &Loc,
138851dc1e8SGeorge Rimar                                               StringRef Name) {
139851dc1e8SGeorge Rimar   for (OutputSection *Sec : *OutputSections)
140851dc1e8SGeorge Rimar     if (Sec->Name == Name)
141851dc1e8SGeorge Rimar       return Sec;
142851dc1e8SGeorge Rimar 
143*a08fa2ecSRui Ueyama   static OutputSection Dummy("", 0, 0);
14472dc195dSRafael Espindola   if (ErrorOnMissingSection)
145851dc1e8SGeorge Rimar     error(Loc + ": undefined section " + Name);
146*a08fa2ecSRui Ueyama   return &Dummy;
147851dc1e8SGeorge Rimar }
148851dc1e8SGeorge Rimar 
149d83ce1b4SGeorge Rimar // This function is essentially the same as getOutputSection(Name)->Size,
150d83ce1b4SGeorge Rimar // but it won't print out an error message if a given section is not found.
151d83ce1b4SGeorge Rimar //
152d83ce1b4SGeorge Rimar // Linker script does not create an output section if its content is empty.
153d83ce1b4SGeorge Rimar // We want to allow SIZEOF(.foo) where .foo is a section which happened to
154d83ce1b4SGeorge Rimar // be empty. That is why this function is different from getOutputSection().
155b8dd23f5SRui Ueyama uint64_t LinkerScript::getOutputSectionSize(StringRef Name) {
156d83ce1b4SGeorge Rimar   for (OutputSection *Sec : *OutputSections)
157d83ce1b4SGeorge Rimar     if (Sec->Name == Name)
158d83ce1b4SGeorge Rimar       return Sec->Size;
159d83ce1b4SGeorge Rimar   return 0;
160d83ce1b4SGeorge Rimar }
161d83ce1b4SGeorge Rimar 
162b8dd23f5SRui Ueyama void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
16372dc195dSRafael Espindola   uint64_t Val = E().getValue();
1644cd7352cSRafael Espindola   if (Val < Dot) {
1654cd7352cSRafael Espindola     if (InSec)
1662ee2d2dcSGeorge Rimar       error(Loc + ": unable to move location counter backward for: " +
1672ee2d2dcSGeorge Rimar             CurOutSec->Name);
1684cd7352cSRafael Espindola     else
1692ee2d2dcSGeorge Rimar       error(Loc + ": unable to move location counter backward");
1704cd7352cSRafael Espindola   }
1714cd7352cSRafael Espindola   Dot = Val;
1724cd7352cSRafael Espindola   // Update to location counter means update to section size.
1734cd7352cSRafael Espindola   if (InSec)
1744cd7352cSRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
175679828ffSRafael Espindola }
176679828ffSRafael Espindola 
177679828ffSRafael Espindola // Sets value of a symbol. Two kinds of symbols are processed: synthetic
178679828ffSRafael Espindola // symbols, whose value is an offset from beginning of section and regular
179679828ffSRafael Espindola // symbols whose value is absolute.
180b8dd23f5SRui Ueyama void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
181679828ffSRafael Espindola   if (Cmd->Name == ".") {
1822ee2d2dcSGeorge Rimar     setDot(Cmd->Expression, Cmd->Location, InSec);
1834cd7352cSRafael Espindola     return;
1844cd7352cSRafael Espindola   }
1854cd7352cSRafael Espindola 
186b2b70975SGeorge Rimar   if (!Cmd->Sym)
1878f1f3c40SMeador Inge     return;
1888f1f3c40SMeador Inge 
1895616adf6SRafael Espindola   auto *Sym = cast<DefinedRegular>(Cmd->Sym);
19072dc195dSRafael Espindola   ExprValue V = Cmd->Expression();
19172dc195dSRafael Espindola   if (V.isAbsolute()) {
19272dc195dSRafael Espindola     Sym->Value = V.getValue();
19372dc195dSRafael Espindola   } else {
19472dc195dSRafael Espindola     Sym->Section = V.Sec;
19572dc195dSRafael Espindola     if (Sym->Section->Flags & SHF_ALLOC)
19672dc195dSRafael Espindola       Sym->Value = V.Val;
19772dc195dSRafael Espindola     else
19872dc195dSRafael Espindola       Sym->Value = V.getValue();
199ea590d91SRafael Espindola   }
2008f1f3c40SMeador Inge }
2018f1f3c40SMeador Inge 
202a8dba487SGeorge Rimar static SymbolBody *findSymbol(StringRef S) {
203a8dba487SGeorge Rimar   switch (Config->EKind) {
204a8dba487SGeorge Rimar   case ELF32LEKind:
205a8dba487SGeorge Rimar     return Symtab<ELF32LE>::X->find(S);
206a8dba487SGeorge Rimar   case ELF32BEKind:
207a8dba487SGeorge Rimar     return Symtab<ELF32BE>::X->find(S);
208a8dba487SGeorge Rimar   case ELF64LEKind:
209a8dba487SGeorge Rimar     return Symtab<ELF64LE>::X->find(S);
210a8dba487SGeorge Rimar   case ELF64BEKind:
211a8dba487SGeorge Rimar     return Symtab<ELF64BE>::X->find(S);
212a8dba487SGeorge Rimar   default:
213a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
214a8dba487SGeorge Rimar   }
215a8dba487SGeorge Rimar }
216a8dba487SGeorge Rimar 
217a8dba487SGeorge Rimar static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) {
218a8dba487SGeorge Rimar   switch (Config->EKind) {
219a8dba487SGeorge Rimar   case ELF32LEKind:
220a8dba487SGeorge Rimar     return addRegular<ELF32LE>(Cmd);
221a8dba487SGeorge Rimar   case ELF32BEKind:
222a8dba487SGeorge Rimar     return addRegular<ELF32BE>(Cmd);
223a8dba487SGeorge Rimar   case ELF64LEKind:
224a8dba487SGeorge Rimar     return addRegular<ELF64LE>(Cmd);
225a8dba487SGeorge Rimar   case ELF64BEKind:
226a8dba487SGeorge Rimar     return addRegular<ELF64BE>(Cmd);
227a8dba487SGeorge Rimar   default:
228a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
229a8dba487SGeorge Rimar   }
230a8dba487SGeorge Rimar }
231a8dba487SGeorge Rimar 
232b8dd23f5SRui Ueyama void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
2331602421cSRui Ueyama   if (Cmd->Name == ".")
2348f1f3c40SMeador Inge     return;
2358f1f3c40SMeador Inge 
2368f1f3c40SMeador Inge   // If a symbol was in PROVIDE(), we need to define it only when
2378f1f3c40SMeador Inge   // it is a referenced undefined symbol.
238a8dba487SGeorge Rimar   SymbolBody *B = findSymbol(Cmd->Name);
2398f1f3c40SMeador Inge   if (Cmd->Provide && (!B || B->isDefined()))
2408f1f3c40SMeador Inge     return;
2418f1f3c40SMeador Inge 
242a8dba487SGeorge Rimar   Cmd->Sym = addRegularSymbol(Cmd);
243ceabe80eSEugene Leviant }
244ceabe80eSEugene Leviant 
245076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
246076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
247076fe157SGeorge Rimar }
248076fe157SGeorge Rimar 
249076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
250076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
251076fe157SGeorge Rimar }
252076fe157SGeorge Rimar 
253eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
254eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
255eea3114fSGeorge Rimar }
256eea3114fSGeorge Rimar 
257eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) {
258eefa758eSGeorge Rimar   return C->Kind == AssertKind;
259eefa758eSGeorge Rimar }
260eefa758eSGeorge Rimar 
261e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) {
262e38cbab5SGeorge Rimar   return C->Kind == BytesDataKind;
263e38cbab5SGeorge Rimar }
264e38cbab5SGeorge Rimar 
265b4c9b81aSRafael Espindola static StringRef basename(InputSectionBase *S) {
266b4c9b81aSRafael Espindola   if (S->File)
267b4c9b81aSRafael Espindola     return sys::path::filename(S->File->getName());
268e0be2901SRui Ueyama   return "";
269e0be2901SRui Ueyama }
270e0be2901SRui Ueyama 
271b8dd23f5SRui Ueyama bool LinkerScript::shouldKeep(InputSectionBase *S) {
272e0be2901SRui Ueyama   for (InputSectionDescription *ID : Opt.KeptSections)
273e0be2901SRui Ueyama     if (ID->FilePat.match(basename(S)))
274cf43f179SEugene Leviant       for (SectionPattern &P : ID->SectionPatterns)
275f91282e1SRui Ueyama         if (P.SectionPat.match(S->Name))
276eea3114fSGeorge Rimar           return true;
277eea3114fSGeorge Rimar   return false;
278eea3114fSGeorge Rimar }
279eea3114fSGeorge Rimar 
280c404d50dSRafael Espindola static bool comparePriority(InputSectionBase *A, InputSectionBase *B) {
281575208caSGeorge Rimar   return getPriority(A->Name) < getPriority(B->Name);
282575208caSGeorge Rimar }
283575208caSGeorge Rimar 
284c404d50dSRafael Espindola static bool compareName(InputSectionBase *A, InputSectionBase *B) {
285042a3f20SRafael Espindola   return A->Name < B->Name;
2860702c4e8SGeorge Rimar }
287742c3836SRui Ueyama 
288c404d50dSRafael Espindola static bool compareAlignment(InputSectionBase *A, InputSectionBase *B) {
289742c3836SRui Ueyama   // ">" is not a mistake. Larger alignments are placed before smaller
290742c3836SRui Ueyama   // alignments in order to reduce the amount of padding necessary.
291742c3836SRui Ueyama   // This is compatible with GNU.
292742c3836SRui Ueyama   return A->Alignment > B->Alignment;
293742c3836SRui Ueyama }
294742c3836SRui Ueyama 
295c404d50dSRafael Espindola static std::function<bool(InputSectionBase *, InputSectionBase *)>
296be394db3SGeorge Rimar getComparator(SortSectionPolicy K) {
297be394db3SGeorge Rimar   switch (K) {
298be394db3SGeorge Rimar   case SortSectionPolicy::Alignment:
299c0028d3dSRafael Espindola     return compareAlignment;
300be394db3SGeorge Rimar   case SortSectionPolicy::Name:
301be394db3SGeorge Rimar     return compareName;
302be394db3SGeorge Rimar   case SortSectionPolicy::Priority:
303be394db3SGeorge Rimar     return comparePriority;
304be394db3SGeorge Rimar   default:
305be394db3SGeorge Rimar     llvm_unreachable("unknown sort policy");
306be394db3SGeorge Rimar   }
307742c3836SRui Ueyama }
3080702c4e8SGeorge Rimar 
309b4c9b81aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase *> Sections,
31006ae6836SGeorge Rimar                              ConstraintKind Kind) {
3118f66df92SGeorge Rimar   if (Kind == ConstraintKind::NoConstraint)
3128f66df92SGeorge Rimar     return true;
313c404d50dSRafael Espindola   bool IsRW = llvm::any_of(Sections, [=](InputSectionBase *Sec2) {
314b4c9b81aSRafael Espindola     auto *Sec = static_cast<InputSectionBase *>(Sec2);
3151854a8ebSRafael Espindola     return Sec->Flags & SHF_WRITE;
31606ae6836SGeorge Rimar   });
317e746e52cSRafael Espindola   return (IsRW && Kind == ConstraintKind::ReadWrite) ||
318e746e52cSRafael Espindola          (!IsRW && Kind == ConstraintKind::ReadOnly);
31906ae6836SGeorge Rimar }
32006ae6836SGeorge Rimar 
321c404d50dSRafael Espindola static void sortSections(InputSectionBase **Begin, InputSectionBase **End,
322ee924709SRui Ueyama                          SortSectionPolicy K) {
323ee924709SRui Ueyama   if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
32407171f21SGeorge Rimar     std::stable_sort(Begin, End, getComparator(K));
325ee924709SRui Ueyama }
326ee924709SRui Ueyama 
327d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches.
328b8dd23f5SRui Ueyama void LinkerScript::computeInputSections(InputSectionDescription *I) {
3294dc07becSRui Ueyama   // Collects all sections that satisfy constraints of I
3304dc07becSRui Ueyama   // and attach them to I.
3314dc07becSRui Ueyama   for (SectionPattern &Pat : I->SectionPatterns) {
33207171f21SGeorge Rimar     size_t SizeBefore = I->Sections.size();
3338c6a5aafSRui Ueyama 
334536a2670SRui Ueyama     for (InputSectionBase *S : InputSections) {
3353773bcacSRafael Espindola       if (S->Assigned)
3368c6a5aafSRui Ueyama         continue;
337908a3d34SRafael Espindola       // For -emit-relocs we have to ignore entries like
338908a3d34SRafael Espindola       //   .rela.dyn : { *(.rela.data) }
339908a3d34SRafael Espindola       // which are common because they are in the default bfd script.
340908a3d34SRafael Espindola       if (S->Type == SHT_REL || S->Type == SHT_RELA)
341908a3d34SRafael Espindola         continue;
3428c6a5aafSRui Ueyama 
343e0be2901SRui Ueyama       StringRef Filename = basename(S);
344e0be2901SRui Ueyama       if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename))
345e0be2901SRui Ueyama         continue;
346e0be2901SRui Ueyama       if (!Pat.SectionPat.match(S->Name))
347e0be2901SRui Ueyama         continue;
348d3190795SRafael Espindola       I->Sections.push_back(S);
349f94efdddSRui Ueyama       S->Assigned = true;
350f94efdddSRui Ueyama     }
351d3190795SRafael Espindola 
352ee924709SRui Ueyama     // Sort sections as instructed by SORT-family commands and --sort-section
353ee924709SRui Ueyama     // option. Because SORT-family commands can be nested at most two depth
354ee924709SRui Ueyama     // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
355ee924709SRui Ueyama     // line option is respected even if a SORT command is given, the exact
356ee924709SRui Ueyama     // behavior we have here is a bit complicated. Here are the rules.
357ee924709SRui Ueyama     //
358ee924709SRui Ueyama     // 1. If two SORT commands are given, --sort-section is ignored.
359ee924709SRui Ueyama     // 2. If one SORT command is given, and if it is not SORT_NONE,
360ee924709SRui Ueyama     //    --sort-section is handled as an inner SORT command.
361ee924709SRui Ueyama     // 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
362ee924709SRui Ueyama     // 4. If no SORT command is given, sort according to --sort-section.
363c404d50dSRafael Espindola     InputSectionBase **Begin = I->Sections.data() + SizeBefore;
364c404d50dSRafael Espindola     InputSectionBase **End = I->Sections.data() + I->Sections.size();
36507171f21SGeorge Rimar     if (Pat.SortOuter != SortSectionPolicy::None) {
36607171f21SGeorge Rimar       if (Pat.SortInner == SortSectionPolicy::Default)
36707171f21SGeorge Rimar         sortSections(Begin, End, Config->SortSection);
368ee924709SRui Ueyama       else
36907171f21SGeorge Rimar         sortSections(Begin, End, Pat.SortInner);
37007171f21SGeorge Rimar       sortSections(Begin, End, Pat.SortOuter);
37107171f21SGeorge Rimar     }
372ee924709SRui Ueyama   }
373be94e1b6SRafael Espindola }
374be94e1b6SRafael Espindola 
375b8dd23f5SRui Ueyama void LinkerScript::discard(ArrayRef<InputSectionBase *> V) {
376b4c9b81aSRafael Espindola   for (InputSectionBase *S : V) {
377be94e1b6SRafael Espindola     S->Live = false;
378503206c5SGeorge Rimar     if (S == InX::ShStrTab)
379ecbfd871SRafael Espindola       error("discarding .shstrtab section is not allowed");
380647c1685SGeorge Rimar     discard(S->DependentSections);
381be94e1b6SRafael Espindola   }
382be94e1b6SRafael Espindola }
383be94e1b6SRafael Espindola 
384b4c9b81aSRafael Espindola std::vector<InputSectionBase *>
385b8dd23f5SRui Ueyama LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) {
386b4c9b81aSRafael Espindola   std::vector<InputSectionBase *> Ret;
387e7f912cdSRui Ueyama 
38806ae6836SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) {
3897c3ff2ebSRafael Espindola     auto *Cmd = dyn_cast<InputSectionDescription>(Base.get());
3907c3ff2ebSRafael Espindola     if (!Cmd)
3910b9ce6a4SRui Ueyama       continue;
392e71a3f8aSRafael Espindola     computeInputSections(Cmd);
393c404d50dSRafael Espindola     for (InputSectionBase *S : Cmd->Sections)
394b4c9b81aSRafael Espindola       Ret.push_back(static_cast<InputSectionBase *>(S));
3950b9ce6a4SRui Ueyama   }
396e71a3f8aSRafael Espindola 
3970b9ce6a4SRui Ueyama   return Ret;
3980b9ce6a4SRui Ueyama }
3990b9ce6a4SRui Ueyama 
400b8dd23f5SRui Ueyama void LinkerScript::processCommands(OutputSectionFactory &Factory) {
4015616adf6SRafael Espindola   // A symbol can be assigned before any section is mentioned in the linker
4025616adf6SRafael Espindola   // script. In an DSO, the symbol values are addresses, so the only important
4035616adf6SRafael Espindola   // section values are:
4045616adf6SRafael Espindola   // * SHN_UNDEF
4055616adf6SRafael Espindola   // * SHN_ABS
4065616adf6SRafael Espindola   // * Any value meaning a regular section.
4075616adf6SRafael Espindola   // To handle that, create a dummy aether section that fills the void before
4085616adf6SRafael Espindola   // the linker scripts switches to another section. It has an index of one
4095616adf6SRafael Espindola   // which will map to whatever the first actual section is.
4105616adf6SRafael Espindola   Aether = make<OutputSection>("", 0, SHF_ALLOC);
4115616adf6SRafael Espindola   Aether->SectionIndex = 1;
4125616adf6SRafael Espindola   CurOutSec = Aether;
41349592cf6SRafael Espindola   Dot = 0;
4145616adf6SRafael Espindola 
4157c3ff2ebSRafael Espindola   for (unsigned I = 0; I < Opt.Commands.size(); ++I) {
4167c3ff2ebSRafael Espindola     auto Iter = Opt.Commands.begin() + I;
4177c3ff2ebSRafael Espindola     const std::unique_ptr<BaseCommand> &Base1 = *Iter;
4180b1b695aSRui Ueyama 
4190b1b695aSRui Ueyama     // Handle symbol assignments outside of any output section.
4202ab5f73dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) {
4214cd7352cSRafael Espindola       addSymbol(Cmd);
4222ab5f73dSRui Ueyama       continue;
4232ab5f73dSRui Ueyama     }
4240b1b695aSRui Ueyama 
425ceabe80eSEugene Leviant     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) {
426b4c9b81aSRafael Espindola       std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
4277bd37870SRafael Espindola 
4280b1b695aSRui Ueyama       // The output section name `/DISCARD/' is special.
4290b1b695aSRui Ueyama       // Any input section assigned to it is discarded.
43048c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
4317bd37870SRafael Espindola         discard(V);
43248c3f1ceSRui Ueyama         continue;
43348c3f1ceSRui Ueyama       }
4340b9ce6a4SRui Ueyama 
4350b1b695aSRui Ueyama       // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
4360b1b695aSRui Ueyama       // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
4370b1b695aSRui Ueyama       // sections satisfy a given constraint. If not, a directive is handled
4380b1b695aSRui Ueyama       // as if it wasn't present from the beginning.
4390b1b695aSRui Ueyama       //
4400b1b695aSRui Ueyama       // Because we'll iterate over Commands many more times, the easiest
4410b1b695aSRui Ueyama       // way to "make it as if it wasn't present" is to just remove it.
442f7f0d088SGeorge Rimar       if (!matchConstraints(V, Cmd->Constraint)) {
443b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
444f94efdddSRui Ueyama           S->Assigned = false;
4457c3ff2ebSRafael Espindola         Opt.Commands.erase(Iter);
446dfbbbc86SGeorge Rimar         --I;
4477c3ff2ebSRafael Espindola         continue;
4487c3ff2ebSRafael Espindola       }
4497c3ff2ebSRafael Espindola 
4500b1b695aSRui Ueyama       // A directive may contain symbol definitions like this:
4510b1b695aSRui Ueyama       // ".foo : { ...; bar = .; }". Handle them.
4527c3ff2ebSRafael Espindola       for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands)
4537c3ff2ebSRafael Espindola         if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get()))
4544cd7352cSRafael Espindola           addSymbol(OutCmd);
4557c3ff2ebSRafael Espindola 
4560b1b695aSRui Ueyama       // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
4570b1b695aSRui Ueyama       // is given, input sections are aligned to that value, whether the
4580b1b695aSRui Ueyama       // given value is larger or smaller than the original section alignment.
4590b1b695aSRui Ueyama       if (Cmd->SubalignExpr) {
46072dc195dSRafael Espindola         uint32_t Subalign = Cmd->SubalignExpr().getValue();
461b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
4620b1b695aSRui Ueyama           S->Alignment = Subalign;
46320d03194SEugene Leviant       }
4640b1b695aSRui Ueyama 
4650b1b695aSRui Ueyama       // Add input sections to an output section.
466b4c9b81aSRafael Espindola       for (InputSectionBase *S : V)
467e21c3af7SGeorge Rimar         Factory.addInputSec(S, Cmd->Name);
468eea3114fSGeorge Rimar     }
46948c3f1ceSRui Ueyama   }
4705616adf6SRafael Espindola   CurOutSec = nullptr;
471db24d9c3SGeorge Rimar }
472e63d81bdSEugene Leviant 
4730b1b695aSRui Ueyama // Add sections that didn't match any sections command.
474b8dd23f5SRui Ueyama void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
475536a2670SRui Ueyama   for (InputSectionBase *S : InputSections)
4768f9026baSRafael Espindola     if (S->Live && !S->OutSec)
477e21c3af7SGeorge Rimar       Factory.addInputSec(S, getOutputSectionName(S->Name));
478e63d81bdSEugene Leviant }
479e63d81bdSEugene Leviant 
480f7f0d088SGeorge Rimar static bool isTbss(OutputSection *Sec) {
48104a2e348SRafael Espindola   return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
482a940e539SRafael Espindola }
483a940e539SRafael Espindola 
484b8dd23f5SRui Ueyama void LinkerScript::output(InputSection *S) {
485d3190795SRafael Espindola   if (!AlreadyOutputIS.insert(S).second)
486ceabe80eSEugene Leviant     return;
487f7f0d088SGeorge Rimar   bool IsTbss = isTbss(CurOutSec);
488d3190795SRafael Espindola 
4890c1c8085SGeorge Rimar   uint64_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot;
490d3190795SRafael Espindola   Pos = alignTo(Pos, S->Alignment);
49104a2e348SRafael Espindola   S->OutSecOff = Pos - CurOutSec->Addr;
49276b6bd35SRafael Espindola   Pos += S->getSize();
493d3190795SRafael Espindola 
494d3190795SRafael Espindola   // Update output section size after adding each section. This is so that
495d3190795SRafael Espindola   // SIZEOF works correctly in the case below:
496d3190795SRafael Espindola   // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
49704a2e348SRafael Espindola   CurOutSec->Size = Pos - CurOutSec->Addr;
498d3190795SRafael Espindola 
499b889744eSMeador Inge   // If there is a memory region associated with this input section, then
500b889744eSMeador Inge   // place the section in that region and update the region index.
501b889744eSMeador Inge   if (CurMemRegion) {
502b889744eSMeador Inge     CurMemRegion->Offset += CurOutSec->Size;
503b889744eSMeador Inge     uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin;
504b889744eSMeador Inge     if (CurSize > CurMemRegion->Length) {
505b889744eSMeador Inge       uint64_t OverflowAmt = CurSize - CurMemRegion->Length;
506b889744eSMeador Inge       error("section '" + CurOutSec->Name + "' will not fit in region '" +
507b889744eSMeador Inge             CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
508b889744eSMeador Inge             " bytes");
509b889744eSMeador Inge     }
510b889744eSMeador Inge   }
511b889744eSMeador Inge 
5127252ae52SRafael Espindola   if (IsTbss)
5137252ae52SRafael Espindola     ThreadBssOffset = Pos - Dot;
5147252ae52SRafael Espindola   else
515d3190795SRafael Espindola     Dot = Pos;
5162de509c3SRui Ueyama }
517ceabe80eSEugene Leviant 
518b8dd23f5SRui Ueyama void LinkerScript::flush() {
519bd12e2a0SRafael Espindola   assert(CurOutSec);
520bd12e2a0SRafael Espindola   if (!AlreadyOutputOS.insert(CurOutSec).second)
52165499b90SRafael Espindola     return;
52224e6f363SRafael Espindola   for (InputSection *I : CurOutSec->Sections)
523d3190795SRafael Espindola     output(I);
524d3190795SRafael Espindola }
52597403d15SEugene Leviant 
526b8dd23f5SRui Ueyama void LinkerScript::switchTo(OutputSection *Sec) {
527d3190795SRafael Espindola   if (CurOutSec == Sec)
528d3190795SRafael Espindola     return;
529d3190795SRafael Espindola   if (AlreadyOutputOS.count(Sec))
530d3190795SRafael Espindola     return;
531d3190795SRafael Espindola 
532d3190795SRafael Espindola   CurOutSec = Sec;
533d3190795SRafael Espindola 
5343770763cSRafael Espindola   Dot = alignTo(Dot, CurOutSec->Alignment);
535f7f0d088SGeorge Rimar   CurOutSec->Addr = isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot;
536b71d6f7aSEugene Leviant 
537b71d6f7aSEugene Leviant   // If neither AT nor AT> is specified for an allocatable section, the linker
538b71d6f7aSEugene Leviant   // will set the LMA such that the difference between VMA and LMA for the
539b71d6f7aSEugene Leviant   // section is the same as the preceding output section in the same region
540b71d6f7aSEugene Leviant   // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
54121467876SGeorge Rimar   if (LMAOffset)
54229c1afb8SRafael Espindola     CurOutSec->LMAOffset = LMAOffset();
543d3190795SRafael Espindola }
544d3190795SRafael Espindola 
545b8dd23f5SRui Ueyama void LinkerScript::process(BaseCommand &Base) {
546e38cbab5SGeorge Rimar   // This handles the assignments to symbol or to a location counter (.)
547d3190795SRafael Espindola   if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) {
5484cd7352cSRafael Espindola     assignSymbol(AssignCmd, true);
549d3190795SRafael Espindola     return;
55097403d15SEugene Leviant   }
551e38cbab5SGeorge Rimar 
552e38cbab5SGeorge Rimar   // Handle BYTE(), SHORT(), LONG(), or QUAD().
553e38cbab5SGeorge Rimar   if (auto *DataCmd = dyn_cast<BytesDataCommand>(&Base)) {
55404a2e348SRafael Espindola     DataCmd->Offset = Dot - CurOutSec->Addr;
555e38cbab5SGeorge Rimar     Dot += DataCmd->Size;
55604a2e348SRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
557e38cbab5SGeorge Rimar     return;
558e38cbab5SGeorge Rimar   }
559e38cbab5SGeorge Rimar 
560b2d99d6aSMeador Inge   if (auto *AssertCmd = dyn_cast<AssertCommand>(&Base)) {
5614595df94SRafael Espindola     AssertCmd->Expression();
562b2d99d6aSMeador Inge     return;
563b2d99d6aSMeador Inge   }
564b2d99d6aSMeador Inge 
565e38cbab5SGeorge Rimar   // It handles single input section description command,
566e38cbab5SGeorge Rimar   // calculates and assigns the offsets for each section and also
567e38cbab5SGeorge Rimar   // updates the output section size.
568d3190795SRafael Espindola   auto &ICmd = cast<InputSectionDescription>(Base);
569bd12e2a0SRafael Espindola   for (InputSectionBase *IB : ICmd.Sections) {
5703fb5a6dcSGeorge Rimar     // We tentatively added all synthetic sections at the beginning and removed
5713fb5a6dcSGeorge Rimar     // empty ones afterwards (because there is no way to know whether they were
5723fb5a6dcSGeorge Rimar     // going be empty or not other than actually running linker scripts.)
5733fb5a6dcSGeorge Rimar     // We need to ignore remains of empty sections.
574bd12e2a0SRafael Espindola     if (auto *Sec = dyn_cast<SyntheticSection>(IB))
5753fb5a6dcSGeorge Rimar       if (Sec->empty())
5763fb5a6dcSGeorge Rimar         continue;
5773fb5a6dcSGeorge Rimar 
57878ef645fSGeorge Rimar     if (!IB->Live)
57978ef645fSGeorge Rimar       continue;
580bedccb5eSRafael Espindola     assert(CurOutSec == IB->OutSec || AlreadyOutputOS.count(IB->OutSec));
581bd12e2a0SRafael Espindola     output(cast<InputSection>(IB));
582ceabe80eSEugene Leviant   }
583ceabe80eSEugene Leviant }
584ceabe80eSEugene Leviant 
58524e6f363SRafael Espindola static OutputSection *
58624e6f363SRafael Espindola findSection(StringRef Name, const std::vector<OutputSection *> &Sections) {
5872b074553SRafael Espindola   auto End = Sections.end();
58824e6f363SRafael Espindola   auto HasName = [=](OutputSection *Sec) { return Sec->Name == Name; };
5892b074553SRafael Espindola   auto I = std::find_if(Sections.begin(), End, HasName);
59024e6f363SRafael Espindola   std::vector<OutputSection *> Ret;
5912b074553SRafael Espindola   if (I == End)
5922b074553SRafael Espindola     return nullptr;
5932b074553SRafael Espindola   assert(std::find_if(I + 1, End, HasName) == End);
5942b074553SRafael Espindola   return *I;
5958f66df92SGeorge Rimar }
5968f66df92SGeorge Rimar 
597b889744eSMeador Inge // This function searches for a memory region to place the given output
598b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is
599b889744eSMeador Inge // returned. Otherwise, a nullptr is returned.
600b8dd23f5SRui Ueyama MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd,
60124e6f363SRafael Espindola                                              OutputSection *Sec) {
602b889744eSMeador Inge   // If a memory region name was specified in the output section command,
603b889744eSMeador Inge   // then try to find that region first.
604b889744eSMeador Inge   if (!Cmd->MemoryRegionName.empty()) {
605b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
606b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
607b889744eSMeador Inge       return &It->second;
608b889744eSMeador Inge     error("memory region '" + Cmd->MemoryRegionName + "' not declared");
609b889744eSMeador Inge     return nullptr;
610b889744eSMeador Inge   }
611b889744eSMeador Inge 
612b889744eSMeador Inge   // The memory region name is empty, thus a suitable region must be
613b889744eSMeador Inge   // searched for in the region map. If the region map is empty, just
614b889744eSMeador Inge   // return. Note that this check doesn't happen at the very beginning
615b889744eSMeador Inge   // so that uses of undeclared regions can be caught.
616b889744eSMeador Inge   if (!Opt.MemoryRegions.size())
617b889744eSMeador Inge     return nullptr;
618b889744eSMeador Inge 
619b889744eSMeador Inge   // See if a region can be found by matching section flags.
620b889744eSMeador Inge   for (auto &MRI : Opt.MemoryRegions) {
621b889744eSMeador Inge     MemoryRegion &MR = MRI.second;
6228a8a953eSRui Ueyama     if ((MR.Flags & Sec->Flags) != 0 && (MR.NegFlags & Sec->Flags) == 0)
623b889744eSMeador Inge       return &MR;
624b889744eSMeador Inge   }
625b889744eSMeador Inge 
626b889744eSMeador Inge   // Otherwise, no suitable region was found.
627b889744eSMeador Inge   if (Sec->Flags & SHF_ALLOC)
628b889744eSMeador Inge     error("no memory region specified for section '" + Sec->Name + "'");
629b889744eSMeador Inge   return nullptr;
630b889744eSMeador Inge }
631b889744eSMeador Inge 
6320b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section
6330b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }").
634b8dd23f5SRui Ueyama void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) {
63523e6a024SGeorge Rimar   OutputSection *Sec = findSection(Cmd->Name, *OutputSections);
6362b074553SRafael Espindola   if (!Sec)
637d3190795SRafael Espindola     return;
638b889744eSMeador Inge 
639679828ffSRafael Espindola   if (Cmd->AddrExpr && Sec->Flags & SHF_ALLOC)
6402ee2d2dcSGeorge Rimar     setDot(Cmd->AddrExpr, Cmd->Location);
641679828ffSRafael Espindola 
6425784e96fSEugene Leviant   if (Cmd->LMAExpr) {
6430c1c8085SGeorge Rimar     uint64_t D = Dot;
64472dc195dSRafael Espindola     LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; };
6455784e96fSEugene Leviant   }
6465784e96fSEugene Leviant 
647165088aaSPetr Hosek   // Handle align (e.g. ".foo : ALIGN(16) { ... }").
648165088aaSPetr Hosek   if (Cmd->AlignExpr)
64972dc195dSRafael Espindola     Sec->updateAlignment(Cmd->AlignExpr().getValue());
650165088aaSPetr Hosek 
651b889744eSMeador Inge   // Try and find an appropriate memory region to assign offsets in.
652b889744eSMeador Inge   CurMemRegion = findMemoryRegion(Cmd, Sec);
653b889744eSMeador Inge   if (CurMemRegion)
654b889744eSMeador Inge     Dot = CurMemRegion->Offset;
655b889744eSMeador Inge   switchTo(Sec);
6560b1b695aSRui Ueyama 
657d3190795SRafael Espindola   // Find the last section output location. We will output orphan sections
658d3190795SRafael Espindola   // there so that end symbols point to the correct location.
659d3190795SRafael Espindola   auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(),
660d3190795SRafael Espindola                         [](const std::unique_ptr<BaseCommand> &Cmd) {
661d3190795SRafael Espindola                           return !isa<SymbolAssignment>(*Cmd);
662d3190795SRafael Espindola                         })
663d3190795SRafael Espindola                .base();
664d3190795SRafael Espindola   for (auto I = Cmd->Commands.begin(); I != E; ++I)
665d3190795SRafael Espindola     process(**I);
6662506cb4dSEugene Leviant   flush();
667b31dd370SGeorge Rimar   std::for_each(E, Cmd->Commands.end(),
668b31dd370SGeorge Rimar                 [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); });
669d3190795SRafael Espindola }
670d3190795SRafael Espindola 
671b8dd23f5SRui Ueyama void LinkerScript::removeEmptyCommands() {
6726d38e4dbSRafael Espindola   // It is common practice to use very generic linker scripts. So for any
6736d38e4dbSRafael Espindola   // given run some of the output sections in the script will be empty.
6746d38e4dbSRafael Espindola   // We could create corresponding empty output sections, but that would
6756d38e4dbSRafael Espindola   // clutter the output.
6766d38e4dbSRafael Espindola   // We instead remove trivially empty sections. The bfd linker seems even
6776d38e4dbSRafael Espindola   // more aggressive at removing them.
6786d38e4dbSRafael Espindola   auto Pos = std::remove_if(
6796d38e4dbSRafael Espindola       Opt.Commands.begin(), Opt.Commands.end(),
6806d38e4dbSRafael Espindola       [&](const std::unique_ptr<BaseCommand> &Base) {
6810b1b695aSRui Ueyama         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
68223e6a024SGeorge Rimar           return !findSection(Cmd->Name, *OutputSections);
6830b1b695aSRui Ueyama         return false;
6846d38e4dbSRafael Espindola       });
6856d38e4dbSRafael Espindola   Opt.Commands.erase(Pos, Opt.Commands.end());
68607fe6129SRafael Espindola }
68707fe6129SRafael Espindola 
6886a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
6896a53737cSRafael Espindola   for (const std::unique_ptr<BaseCommand> &I : Cmd.Commands)
6906a53737cSRafael Espindola     if (!isa<InputSectionDescription>(*I))
6916a53737cSRafael Espindola       return false;
6926a53737cSRafael Espindola   return true;
6936a53737cSRafael Espindola }
6946d38e4dbSRafael Espindola 
695b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsBeforeSorting() {
6969546fffbSRafael Espindola   // If the output section contains only symbol assignments, create a
6979546fffbSRafael Espindola   // corresponding output section. The bfd linker seems to only create them if
6989546fffbSRafael Espindola   // '.' is assigned to, but creating these section should not have any bad
6999546fffbSRafael Espindola   // consequeces and gives us a section to put the symbol in.
7000c1c8085SGeorge Rimar   uint64_t Flags = SHF_ALLOC;
701f93b8c29SRafael Espindola   uint32_t Type = SHT_NOBITS;
7029546fffbSRafael Espindola   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
7039546fffbSRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
7049546fffbSRafael Espindola     if (!Cmd)
7059546fffbSRafael Espindola       continue;
70623e6a024SGeorge Rimar     if (OutputSection *Sec = findSection(Cmd->Name, *OutputSections)) {
7072b074553SRafael Espindola       Flags = Sec->Flags;
7082b074553SRafael Espindola       Type = Sec->Type;
7099546fffbSRafael Espindola       continue;
7109546fffbSRafael Espindola     }
7119546fffbSRafael Espindola 
7126a53737cSRafael Espindola     if (isAllSectionDescription(*Cmd))
7136a53737cSRafael Espindola       continue;
7146a53737cSRafael Espindola 
71524e6f363SRafael Espindola     auto *OutSec = make<OutputSection>(Cmd->Name, Type, Flags);
7169546fffbSRafael Espindola     OutputSections->push_back(OutSec);
7179546fffbSRafael Espindola   }
718f7a17448SRafael Espindola }
719f7a17448SRafael Espindola 
720b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsAfterSorting() {
721f7a17448SRafael Espindola   placeOrphanSections();
722f7a17448SRafael Espindola 
723f7a17448SRafael Espindola   // If output section command doesn't specify any segments,
724f7a17448SRafael Espindola   // and we haven't previously assigned any section to segment,
725f7a17448SRafael Espindola   // then we simply assign section to the very first load segment.
726f7a17448SRafael Espindola   // Below is an example of such linker script:
727f7a17448SRafael Espindola   // PHDRS { seg PT_LOAD; }
728f7a17448SRafael Espindola   // SECTIONS { .aaa : { *(.aaa) } }
729f7a17448SRafael Espindola   std::vector<StringRef> DefPhdrs;
730f7a17448SRafael Espindola   auto FirstPtLoad =
731f7a17448SRafael Espindola       std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(),
732f7a17448SRafael Espindola                    [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; });
733f7a17448SRafael Espindola   if (FirstPtLoad != Opt.PhdrsCommands.end())
734f7a17448SRafael Espindola     DefPhdrs.push_back(FirstPtLoad->Name);
735f7a17448SRafael Espindola 
736f7a17448SRafael Espindola   // Walk the commands and propagate the program headers to commands that don't
737f7a17448SRafael Espindola   // explicitly specify them.
738f7a17448SRafael Espindola   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
739f7a17448SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
740f7a17448SRafael Espindola     if (!Cmd)
741f7a17448SRafael Espindola       continue;
742f7a17448SRafael Espindola     if (Cmd->Phdrs.empty())
743f7a17448SRafael Espindola       Cmd->Phdrs = DefPhdrs;
744f7a17448SRafael Espindola     else
745f7a17448SRafael Espindola       DefPhdrs = Cmd->Phdrs;
746f7a17448SRafael Espindola   }
7476a53737cSRafael Espindola 
7486a53737cSRafael Espindola   removeEmptyCommands();
7499546fffbSRafael Espindola }
7509546fffbSRafael Espindola 
75115c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments
75215c57951SRafael Espindola // so that an orphan after
75315c57951SRafael Espindola //   begin_foo = .;
75415c57951SRafael Espindola //   foo : { *(foo) }
75515c57951SRafael Espindola //   end_foo = .;
75615c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols.
75715c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the
75815c57951SRafael Espindola // one in charge of deciding the order of the sections.
75915c57951SRafael Espindola // We don't want to go over alignments, since doing so in
76015c57951SRafael Espindola //  rx_sec : { *(rx_sec) }
76115c57951SRafael Espindola //  . = ALIGN(0x1000);
76215c57951SRafael Espindola //  /* The RW PT_LOAD starts here*/
76315c57951SRafael Espindola //  rw_sec : { *(rw_sec) }
76415c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned.
7655fcc99c2SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) {
76615c57951SRafael Espindola   if (isa<OutputSectionCommand>(Cmd))
76715c57951SRafael Espindola     return false;
76815c57951SRafael Espindola   const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd);
76915c57951SRafael Espindola   if (!Assign)
77015c57951SRafael Espindola     return true;
7715fcc99c2SRafael Espindola   return Assign->Name != ".";
77215c57951SRafael Espindola }
77315c57951SRafael Espindola 
7746697ec29SRui Ueyama // Orphan sections are sections present in the input files which are
7756697ec29SRui Ueyama // not explicitly placed into the output file by the linker script.
7766697ec29SRui Ueyama //
7776697ec29SRui Ueyama // When the control reaches this function, Opt.Commands contains
7786697ec29SRui Ueyama // output section commands for non-orphan sections only. This function
77981cb7107SRui Ueyama // adds new elements for orphan sections so that all sections are
78081cb7107SRui Ueyama // explicitly handled by Opt.Commands.
7816697ec29SRui Ueyama //
7826697ec29SRui Ueyama // Writer<ELFT>::sortSections has already sorted output sections.
7836697ec29SRui Ueyama // What we need to do is to scan OutputSections vector and
7846697ec29SRui Ueyama // Opt.Commands in parallel to find orphan sections. If there is an
7856697ec29SRui Ueyama // output section that doesn't have a corresponding entry in
7866697ec29SRui Ueyama // Opt.Commands, we will insert a new entry to Opt.Commands.
7876697ec29SRui Ueyama //
7886697ec29SRui Ueyama // There is some ambiguity as to where exactly a new entry should be
7896697ec29SRui Ueyama // inserted, because Opt.Commands contains not only output section
79081cb7107SRui Ueyama // commands but also other types of commands such as symbol assignment
7916697ec29SRui Ueyama // expressions. There's no correct answer here due to the lack of the
7926697ec29SRui Ueyama // formal specification of the linker script. We use heuristics to
7936697ec29SRui Ueyama // determine whether a new output command should be added before or
7946697ec29SRui Ueyama // after another commands. For the details, look at shouldSkip
7956697ec29SRui Ueyama // function.
796b8dd23f5SRui Ueyama void LinkerScript::placeOrphanSections() {
797aab6d5c5SRafael Espindola   // The OutputSections are already in the correct order.
798aab6d5c5SRafael Espindola   // This loops creates or moves commands as needed so that they are in the
799aab6d5c5SRafael Espindola   // correct order.
800aab6d5c5SRafael Espindola   int CmdIndex = 0;
8015fcc99c2SRafael Espindola 
8025fcc99c2SRafael Espindola   // As a horrible special case, skip the first . assignment if it is before any
8035fcc99c2SRafael Espindola   // section. We do this because it is common to set a load address by starting
8045fcc99c2SRafael Espindola   // the script with ". = 0xabcd" and the expectation is that every section is
8055fcc99c2SRafael Espindola   // after that.
8065fcc99c2SRafael Espindola   auto FirstSectionOrDotAssignment =
8075fcc99c2SRafael Espindola       std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
8085fcc99c2SRafael Espindola                    [](const std::unique_ptr<BaseCommand> &Cmd) {
8095fcc99c2SRafael Espindola                      if (isa<OutputSectionCommand>(*Cmd))
8105fcc99c2SRafael Espindola                        return true;
8115fcc99c2SRafael Espindola                      const auto *Assign = dyn_cast<SymbolAssignment>(Cmd.get());
8125fcc99c2SRafael Espindola                      if (!Assign)
8135fcc99c2SRafael Espindola                        return false;
8145fcc99c2SRafael Espindola                      return Assign->Name == ".";
8155fcc99c2SRafael Espindola                    });
8165fcc99c2SRafael Espindola   if (FirstSectionOrDotAssignment != Opt.Commands.end()) {
8175fcc99c2SRafael Espindola     CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin();
8185fcc99c2SRafael Espindola     if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
8195fcc99c2SRafael Espindola       ++CmdIndex;
8205fcc99c2SRafael Espindola   }
8215fcc99c2SRafael Espindola 
82224e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
82340849419SRafael Espindola     StringRef Name = Sec->Name;
824aab6d5c5SRafael Espindola 
825aab6d5c5SRafael Espindola     // Find the last spot where we can insert a command and still get the
82615c57951SRafael Espindola     // correct result.
827aab6d5c5SRafael Espindola     auto CmdIter = Opt.Commands.begin() + CmdIndex;
828aab6d5c5SRafael Espindola     auto E = Opt.Commands.end();
8295fcc99c2SRafael Espindola     while (CmdIter != E && shouldSkip(**CmdIter)) {
830aab6d5c5SRafael Espindola       ++CmdIter;
831aab6d5c5SRafael Espindola       ++CmdIndex;
832aab6d5c5SRafael Espindola     }
833aab6d5c5SRafael Espindola 
834aab6d5c5SRafael Espindola     auto Pos =
835aab6d5c5SRafael Espindola         std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) {
836aab6d5c5SRafael Espindola           auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
837aab6d5c5SRafael Espindola           return Cmd && Cmd->Name == Name;
838aab6d5c5SRafael Espindola         });
839aab6d5c5SRafael Espindola     if (Pos == E) {
840aab6d5c5SRafael Espindola       Opt.Commands.insert(CmdIter,
841aab6d5c5SRafael Espindola                           llvm::make_unique<OutputSectionCommand>(Name));
842aab6d5c5SRafael Espindola       ++CmdIndex;
84315c57951SRafael Espindola       continue;
84415c57951SRafael Espindola     }
84515c57951SRafael Espindola 
84615c57951SRafael Espindola     // Continue from where we found it.
84715c57951SRafael Espindola     CmdIndex = (Pos - Opt.Commands.begin()) + 1;
848652852c5SGeorge Rimar   }
849337f903cSRafael Espindola }
850337f903cSRafael Espindola 
851b8dd23f5SRui Ueyama void LinkerScript::processNonSectionCommands() {
85202ad516bSPetr Hosek   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
85302ad516bSPetr Hosek     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get()))
85402ad516bSPetr Hosek       assignSymbol(Cmd);
85502ad516bSPetr Hosek     else if (auto *Cmd = dyn_cast<AssertCommand>(Base.get()))
85602ad516bSPetr Hosek       Cmd->Expression();
85702ad516bSPetr Hosek   }
85802ad516bSPetr Hosek }
85902ad516bSPetr Hosek 
860b8dd23f5SRui Ueyama void LinkerScript::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
8617c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
862be607334SRafael Espindola   Dot = 0;
86372dc195dSRafael Espindola   ErrorOnMissingSection = true;
86406f4743aSRafael Espindola   switchTo(Aether);
86506f4743aSRafael Espindola 
866076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
867076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
8684cd7352cSRafael Espindola       assignSymbol(Cmd);
86905ef4cffSRui Ueyama       continue;
870652852c5SGeorge Rimar     }
871652852c5SGeorge Rimar 
872eefa758eSGeorge Rimar     if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) {
8734595df94SRafael Espindola       Cmd->Expression();
874eefa758eSGeorge Rimar       continue;
875eefa758eSGeorge Rimar     }
876eefa758eSGeorge Rimar 
877076fe157SGeorge Rimar     auto *Cmd = cast<OutputSectionCommand>(Base.get());
878d3190795SRafael Espindola     assignOffsets(Cmd);
879a14b13d8SGeorge Rimar   }
880467c4d55SEugene Leviant 
8810c1c8085SGeorge Rimar   uint64_t MinVA = std::numeric_limits<uint64_t>::max();
88224e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
88304a2e348SRafael Espindola     if (Sec->Flags & SHF_ALLOC)
884e08e78dfSRafael Espindola       MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
885ea590d91SRafael Espindola     else
886ea590d91SRafael Espindola       Sec->Addr = 0;
887ea590d91SRafael Espindola   }
888aab6d5c5SRafael Espindola 
8892d262109SGeorge Rimar   allocateHeaders(Phdrs, *OutputSections, MinVA);
890fb8978fcSDima Stepanov }
891652852c5SGeorge Rimar 
892464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
893b8dd23f5SRui Ueyama std::vector<PhdrEntry> LinkerScript::createPhdrs() {
89417cb7c0aSRafael Espindola   std::vector<PhdrEntry> Ret;
895bbe38602SEugene Leviant 
896464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
897464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
898bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
899edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
90017cb7c0aSRafael Espindola     PhdrEntry &Phdr = Ret.back();
901bbe38602SEugene Leviant 
902bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
9039d1bacb1SRui Ueyama       Phdr.add(Out::ElfHeader);
904bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
9059d1bacb1SRui Ueyama       Phdr.add(Out::ProgramHeaders);
90656b21c86SEugene Leviant 
90756b21c86SEugene Leviant     if (Cmd.LMAExpr) {
90872dc195dSRafael Espindola       Phdr.p_paddr = Cmd.LMAExpr().getValue();
90956b21c86SEugene Leviant       Phdr.HasLMA = true;
91056b21c86SEugene Leviant     }
911bbe38602SEugene Leviant   }
912bbe38602SEugene Leviant 
913464daadcSRui Ueyama   // Add output sections to program headers.
91424e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
91504a2e348SRafael Espindola     if (!(Sec->Flags & SHF_ALLOC))
916bbe38602SEugene Leviant       break;
917bbe38602SEugene Leviant 
918bbe38602SEugene Leviant     // Assign headers specified by linker script
91940849419SRafael Espindola     for (size_t Id : getPhdrIndices(Sec->Name)) {
920edebbdf1SRui Ueyama       Ret[Id].add(Sec);
921865bf863SEugene Leviant       if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
92217cb7c0aSRafael Espindola         Ret[Id].p_flags |= Sec->getPhdrFlags();
923bbe38602SEugene Leviant     }
924bbe38602SEugene Leviant   }
925edebbdf1SRui Ueyama   return Ret;
926bbe38602SEugene Leviant }
927bbe38602SEugene Leviant 
928b8dd23f5SRui Ueyama bool LinkerScript::ignoreInterpSection() {
929f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
930f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
931f9bc3bd2SEugene Leviant   return !Opt.PhdrsCommands.empty() &&
932f9bc3bd2SEugene Leviant          llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) {
933f9bc3bd2SEugene Leviant            return Cmd.Type == PT_INTERP;
934f9bc3bd2SEugene Leviant          }) == Opt.PhdrsCommands.end();
935f9bc3bd2SEugene Leviant }
936f9bc3bd2SEugene Leviant 
937b8dd23f5SRui Ueyama uint32_t LinkerScript::getFiller(StringRef Name) {
938f6c3ccefSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
939f6c3ccefSGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
940f6c3ccefSGeorge Rimar       if (Cmd->Name == Name)
941f6c3ccefSGeorge Rimar         return Cmd->Filler;
94216068aebSRui Ueyama   return 0;
943e2ee72b5SGeorge Rimar }
944e2ee72b5SGeorge Rimar 
945e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
946e38cbab5SGeorge Rimar   switch (Size) {
947e38cbab5SGeorge Rimar   case 1:
948e38cbab5SGeorge Rimar     *Buf = (uint8_t)Data;
949e38cbab5SGeorge Rimar     break;
950e38cbab5SGeorge Rimar   case 2:
951f93ed4deSRui Ueyama     write16(Buf, Data, Config->Endianness);
952e38cbab5SGeorge Rimar     break;
953e38cbab5SGeorge Rimar   case 4:
954f93ed4deSRui Ueyama     write32(Buf, Data, Config->Endianness);
955e38cbab5SGeorge Rimar     break;
956e38cbab5SGeorge Rimar   case 8:
957f93ed4deSRui Ueyama     write64(Buf, Data, Config->Endianness);
958e38cbab5SGeorge Rimar     break;
959e38cbab5SGeorge Rimar   default:
960e38cbab5SGeorge Rimar     llvm_unreachable("unsupported Size argument");
961e38cbab5SGeorge Rimar   }
962e38cbab5SGeorge Rimar }
963e38cbab5SGeorge Rimar 
964b8dd23f5SRui Ueyama void LinkerScript::writeDataBytes(StringRef Name, uint8_t *Buf) {
965e38cbab5SGeorge Rimar   int I = getSectionIndex(Name);
966e38cbab5SGeorge Rimar   if (I == INT_MAX)
967e38cbab5SGeorge Rimar     return;
968e38cbab5SGeorge Rimar 
9696e68c5e5SRui Ueyama   auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get());
9706e68c5e5SRui Ueyama   for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands)
9716e68c5e5SRui Ueyama     if (auto *Data = dyn_cast<BytesDataCommand>(Base.get()))
972a8dba487SGeorge Rimar       writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
973e38cbab5SGeorge Rimar }
974e38cbab5SGeorge Rimar 
975b8dd23f5SRui Ueyama bool LinkerScript::hasLMA(StringRef Name) {
9768ceadb38SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
9778ceadb38SGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
978b71d6f7aSEugene Leviant       if (Cmd->LMAExpr && Cmd->Name == Name)
979b71d6f7aSEugene Leviant         return true;
980b71d6f7aSEugene Leviant   return false;
9818ceadb38SGeorge Rimar }
9828ceadb38SGeorge Rimar 
983c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script
984c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they
985c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script,
986c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file.
987b8dd23f5SRui Ueyama int LinkerScript::getSectionIndex(StringRef Name) {
9886e68c5e5SRui Ueyama   for (int I = 0, E = Opt.Commands.size(); I != E; ++I)
9896e68c5e5SRui Ueyama     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()))
990076fe157SGeorge Rimar       if (Cmd->Name == Name)
991f510fa6bSRui Ueyama         return I;
992f510fa6bSRui Ueyama   return INT_MAX;
99371b26e94SGeorge Rimar }
99471b26e94SGeorge Rimar 
995b8dd23f5SRui Ueyama ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
9964595df94SRafael Espindola   if (S == ".")
99772dc195dSRafael Espindola     return {CurOutSec, Dot - CurOutSec->Addr};
998a8dba487SGeorge Rimar   if (SymbolBody *B = findSymbol(S)) {
99972dc195dSRafael Espindola     if (auto *D = dyn_cast<DefinedRegular>(B))
100072dc195dSRafael Espindola       return {D->Section, D->Value};
100130f16b23SPetr Hosek     if (auto *C = dyn_cast<DefinedCommon>(B))
1002a8dba487SGeorge Rimar       return {InX::Common, C->Offset};
100372dc195dSRafael Espindola   }
1004f6aeed36SEugene Leviant   error(Loc + ": symbol not found: " + S);
1005884e786dSGeorge Rimar   return 0;
1006884e786dSGeorge Rimar }
1007884e786dSGeorge Rimar 
1008b8dd23f5SRui Ueyama bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
1009f34f45fdSGeorge Rimar 
1010bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified
1011bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within
1012bbe38602SEugene Leviant // PHDRS {} script block.
1013b8dd23f5SRui Ueyama std::vector<size_t> LinkerScript::getPhdrIndices(StringRef SectionName) {
1014076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
1015076fe157SGeorge Rimar     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
1016edebbdf1SRui Ueyama     if (!Cmd || Cmd->Name != SectionName)
101731d842f5SGeorge Rimar       continue;
101831d842f5SGeorge Rimar 
101929c5a2a9SRui Ueyama     std::vector<size_t> Ret;
102029c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
10212a942c4bSEugene Leviant       Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
102229c5a2a9SRui Ueyama     return Ret;
1023bbe38602SEugene Leviant   }
102431d842f5SGeorge Rimar   return {};
102531d842f5SGeorge Rimar }
1026bbe38602SEugene Leviant 
1027b8dd23f5SRui Ueyama size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
102829c5a2a9SRui Ueyama   size_t I = 0;
102929c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
103029c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
103129c5a2a9SRui Ueyama       return I;
103229c5a2a9SRui Ueyama     ++I;
103329c5a2a9SRui Ueyama   }
10342a942c4bSEugene Leviant   error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
103529c5a2a9SRui Ueyama   return 0;
103629c5a2a9SRui Ueyama }
103729c5a2a9SRui Ueyama 
1038794366a2SRui Ueyama class elf::ScriptParser final : public ScriptLexer {
1039c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
1040c3794e58SGeorge Rimar 
1041f7c5fbb1SRui Ueyama public:
104222375f24SRui Ueyama   ScriptParser(MemoryBufferRef MB)
1043794366a2SRui Ueyama       : ScriptLexer(MB),
104422375f24SRui Ueyama         IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {}
1045f23b2320SGeorge Rimar 
104620b6598cSGeorge Rimar   void readLinkerScript();
104720b6598cSGeorge Rimar   void readVersionScript();
1048d0ebd84cSRafael Espindola   void readDynamicList();
1049f7c5fbb1SRui Ueyama 
1050f7c5fbb1SRui Ueyama private:
105152a1509eSRui Ueyama   void addFile(StringRef Path);
105252a1509eSRui Ueyama 
1053f7c5fbb1SRui Ueyama   void readAsNeeded();
105490c5099eSDenis Protivensky   void readEntry();
105583f406cfSGeorge Rimar   void readExtern();
1056f7c5fbb1SRui Ueyama   void readGroup();
105731aa1f83SRui Ueyama   void readInclude();
1058b889744eSMeador Inge   void readMemory();
1059ee59282bSRui Ueyama   void readOutput();
10609159ce93SDavide Italiano   void readOutputArch();
1061f7c5fbb1SRui Ueyama   void readOutputFormat();
1062bbe38602SEugene Leviant   void readPhdrs();
106368a39a65SDavide Italiano   void readSearchDir();
10648e3b38abSDenis Protivensky   void readSections();
106595769b4aSRui Ueyama   void readVersion();
106695769b4aSRui Ueyama   void readVersionScriptCommand();
10678e3b38abSDenis Protivensky 
1068113cdec9SRui Ueyama   SymbolAssignment *readAssignment(StringRef Name);
1069e38cbab5SGeorge Rimar   BytesDataCommand *readBytesDataCommand(StringRef Tok);
107016068aebSRui Ueyama   uint32_t readFill();
107110416564SRui Ueyama   OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
107216068aebSRui Ueyama   uint32_t readOutputSectionFiller(StringRef Tok);
1073bbe38602SEugene Leviant   std::vector<StringRef> readOutputSectionPhdrs();
1074a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionDescription(StringRef Tok);
1075db688454SEugene Leviant   StringMatcher readFilePatterns();
107607171f21SGeorge Rimar   std::vector<SectionPattern> readInputSectionsList();
1077a2496cbeSGeorge Rimar   InputSectionDescription *readInputSectionRules(StringRef FilePattern);
1078bbe38602SEugene Leviant   unsigned readPhdrType();
1079be394db3SGeorge Rimar   SortSectionPolicy readSortKind();
1080a35e39caSPetr Hosek   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
1081c96da110SRafael Espindola   SymbolAssignment *readProvideOrAssignment(StringRef Tok);
108203fc010eSGeorge Rimar   void readSort();
1083eefa758eSGeorge Rimar   Expr readAssert();
1084708019c4SRui Ueyama 
108524e626ccSRui Ueyama   uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
108624e626ccSRui Ueyama   std::pair<uint32_t, uint32_t> readMemoryAttributes();
108724e626ccSRui Ueyama 
1088708019c4SRui Ueyama   Expr readExpr();
1089708019c4SRui Ueyama   Expr readExpr1(Expr Lhs, int MinPrec);
1090b71d6f7aSEugene Leviant   StringRef readParenLiteral();
1091708019c4SRui Ueyama   Expr readPrimary();
1092708019c4SRui Ueyama   Expr readTernary(Expr Cond);
10936ad7dfccSRui Ueyama   Expr readParenExpr();
1094f7c5fbb1SRui Ueyama 
109520b6598cSGeorge Rimar   // For parsing version script.
109612450b20SRui Ueyama   std::vector<SymbolVersion> readVersionExtern();
109712450b20SRui Ueyama   void readAnonymousDeclaration();
109895769b4aSRui Ueyama   void readVersionDeclaration(StringRef VerStr);
1099f5fce486SRui Ueyama 
1100f5fce486SRui Ueyama   std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
1101f5fce486SRui Ueyama   readSymbols();
110220b6598cSGeorge Rimar 
110316b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
1104f7c5fbb1SRui Ueyama };
1105f7c5fbb1SRui Ueyama 
1106d0ebd84cSRafael Espindola void ScriptParser::readDynamicList() {
1107d0ebd84cSRafael Espindola   expect("{");
1108d0ebd84cSRafael Espindola   readAnonymousDeclaration();
1109d0ebd84cSRafael Espindola   if (!atEOF())
1110d0ebd84cSRafael Espindola     setError("EOF expected, but got " + next());
1111d0ebd84cSRafael Espindola }
1112d0ebd84cSRafael Espindola 
111320b6598cSGeorge Rimar void ScriptParser::readVersionScript() {
111495769b4aSRui Ueyama   readVersionScriptCommand();
111520b6598cSGeorge Rimar   if (!atEOF())
111695769b4aSRui Ueyama     setError("EOF expected, but got " + next());
111795769b4aSRui Ueyama }
111895769b4aSRui Ueyama 
111995769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() {
112083043f23SRui Ueyama   if (consume("{")) {
112112450b20SRui Ueyama     readAnonymousDeclaration();
112220b6598cSGeorge Rimar     return;
112320b6598cSGeorge Rimar   }
112420b6598cSGeorge Rimar 
112595769b4aSRui Ueyama   while (!atEOF() && !Error && peek() != "}") {
112620b6598cSGeorge Rimar     StringRef VerStr = next();
112720b6598cSGeorge Rimar     if (VerStr == "{") {
112895769b4aSRui Ueyama       setError("anonymous version definition is used in "
112995769b4aSRui Ueyama                "combination with other version definitions");
113020b6598cSGeorge Rimar       return;
113120b6598cSGeorge Rimar     }
113220b6598cSGeorge Rimar     expect("{");
113395769b4aSRui Ueyama     readVersionDeclaration(VerStr);
113420b6598cSGeorge Rimar   }
113520b6598cSGeorge Rimar }
113620b6598cSGeorge Rimar 
113795769b4aSRui Ueyama void ScriptParser::readVersion() {
113895769b4aSRui Ueyama   expect("{");
113995769b4aSRui Ueyama   readVersionScriptCommand();
114095769b4aSRui Ueyama   expect("}");
114195769b4aSRui Ueyama }
114295769b4aSRui Ueyama 
114320b6598cSGeorge Rimar void ScriptParser::readLinkerScript() {
1144f7c5fbb1SRui Ueyama   while (!atEOF()) {
1145f7c5fbb1SRui Ueyama     StringRef Tok = next();
1146a27eeccaSRui Ueyama     if (Tok == ";")
1147a27eeccaSRui Ueyama       continue;
1148a27eeccaSRui Ueyama 
114920d03194SEugene Leviant     if (Tok == "ASSERT") {
1150a34da938SRui Ueyama       Script->Opt.Commands.emplace_back(new AssertCommand(readAssert()));
115120d03194SEugene Leviant     } else if (Tok == "ENTRY") {
1152a27eeccaSRui Ueyama       readEntry();
1153a27eeccaSRui Ueyama     } else if (Tok == "EXTERN") {
1154a27eeccaSRui Ueyama       readExtern();
1155a27eeccaSRui Ueyama     } else if (Tok == "GROUP" || Tok == "INPUT") {
1156a27eeccaSRui Ueyama       readGroup();
1157a27eeccaSRui Ueyama     } else if (Tok == "INCLUDE") {
1158a27eeccaSRui Ueyama       readInclude();
1159b889744eSMeador Inge     } else if (Tok == "MEMORY") {
1160b889744eSMeador Inge       readMemory();
1161a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT") {
1162a27eeccaSRui Ueyama       readOutput();
1163a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_ARCH") {
1164a27eeccaSRui Ueyama       readOutputArch();
1165a27eeccaSRui Ueyama     } else if (Tok == "OUTPUT_FORMAT") {
1166a27eeccaSRui Ueyama       readOutputFormat();
1167a27eeccaSRui Ueyama     } else if (Tok == "PHDRS") {
1168a27eeccaSRui Ueyama       readPhdrs();
1169a27eeccaSRui Ueyama     } else if (Tok == "SEARCH_DIR") {
1170a27eeccaSRui Ueyama       readSearchDir();
1171a27eeccaSRui Ueyama     } else if (Tok == "SECTIONS") {
1172a27eeccaSRui Ueyama       readSections();
1173a27eeccaSRui Ueyama     } else if (Tok == "VERSION") {
1174a27eeccaSRui Ueyama       readVersion();
1175c96da110SRafael Espindola     } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) {
1176a34da938SRui Ueyama       Script->Opt.Commands.emplace_back(Cmd);
1177e5d3ca50SPetr Hosek     } else {
11785761042dSGeorge Rimar       setError("unknown directive: " + Tok);
1179f7c5fbb1SRui Ueyama     }
1180f7c5fbb1SRui Ueyama   }
1181e5d3ca50SPetr Hosek }
1182f7c5fbb1SRui Ueyama 
1183717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
118416b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
11855af1687fSJustin Bogner     SmallString<128> PathData;
11865af1687fSJustin Bogner     StringRef Path = (Config->Sysroot + S).toStringRef(PathData);
118716b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
11885af1687fSJustin Bogner       Driver->addFile(Saver.save(Path));
118916b0cc9eSSimon Atanasyan       return;
119016b0cc9eSSimon Atanasyan     }
119116b0cc9eSSimon Atanasyan   }
119216b0cc9eSSimon Atanasyan 
1193f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
119452a1509eSRui Ueyama     Driver->addFile(S);
119552a1509eSRui Ueyama   } else if (S.startswith("=")) {
119652a1509eSRui Ueyama     if (Config->Sysroot.empty())
119752a1509eSRui Ueyama       Driver->addFile(S.substr(1));
119852a1509eSRui Ueyama     else
119952a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
120052a1509eSRui Ueyama   } else if (S.startswith("-l")) {
120121eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
1202a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
1203a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
120452a1509eSRui Ueyama   } else {
1205061f9286SRui Ueyama     if (Optional<std::string> Path = findFromSearchPaths(S))
1206061f9286SRui Ueyama       Driver->addFile(Saver.save(*Path));
1207025d59b1SRui Ueyama     else
1208061f9286SRui Ueyama       setError("unable to find " + S);
120952a1509eSRui Ueyama   }
121052a1509eSRui Ueyama }
121152a1509eSRui Ueyama 
1212717677afSRui Ueyama void ScriptParser::readAsNeeded() {
1213f7c5fbb1SRui Ueyama   expect("(");
121435da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
121535da9b6eSRui Ueyama   Config->AsNeeded = true;
121683043f23SRui Ueyama   while (!Error && !consume(")"))
1217cd574a5eSGeorge Rimar     addFile(unquote(next()));
121835da9b6eSRui Ueyama   Config->AsNeeded = Orig;
1219f7c5fbb1SRui Ueyama }
1220f7c5fbb1SRui Ueyama 
1221717677afSRui Ueyama void ScriptParser::readEntry() {
122290c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
122390c5099eSDenis Protivensky   expect("(");
122490c5099eSDenis Protivensky   StringRef Tok = next();
122590c5099eSDenis Protivensky   if (Config->Entry.empty())
122690c5099eSDenis Protivensky     Config->Entry = Tok;
122790c5099eSDenis Protivensky   expect(")");
122890c5099eSDenis Protivensky }
122990c5099eSDenis Protivensky 
1230717677afSRui Ueyama void ScriptParser::readExtern() {
123183f406cfSGeorge Rimar   expect("(");
123283043f23SRui Ueyama   while (!Error && !consume(")"))
1233a2acc931SRui Ueyama     Config->Undefined.push_back(next());
123483f406cfSGeorge Rimar }
123583f406cfSGeorge Rimar 
1236717677afSRui Ueyama void ScriptParser::readGroup() {
1237f7c5fbb1SRui Ueyama   expect("(");
123883043f23SRui Ueyama   while (!Error && !consume(")")) {
1239f7c5fbb1SRui Ueyama     StringRef Tok = next();
1240a2acc931SRui Ueyama     if (Tok == "AS_NEEDED")
1241f7c5fbb1SRui Ueyama       readAsNeeded();
1242a2acc931SRui Ueyama     else
1243cd574a5eSGeorge Rimar       addFile(unquote(Tok));
1244f7c5fbb1SRui Ueyama   }
1245f7c5fbb1SRui Ueyama }
1246f7c5fbb1SRui Ueyama 
1247717677afSRui Ueyama void ScriptParser::readInclude() {
1248d4500653SGeorge Rimar   StringRef Tok = unquote(next());
1249ec1c75e0SRui Ueyama 
1250d4500653SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/File-Commands.html:
1251d4500653SGeorge Rimar   // The file will be searched for in the current directory, and in any
1252d4500653SGeorge Rimar   // directory specified with the -L option.
1253ec1c75e0SRui Ueyama   if (sys::fs::exists(Tok)) {
1254ec1c75e0SRui Ueyama     if (Optional<MemoryBufferRef> MB = readFile(Tok))
1255ec1c75e0SRui Ueyama       tokenize(*MB);
1256025d59b1SRui Ueyama     return;
1257025d59b1SRui Ueyama   }
1258ec1c75e0SRui Ueyama   if (Optional<std::string> Path = findFromSearchPaths(Tok)) {
1259ec1c75e0SRui Ueyama     if (Optional<MemoryBufferRef> MB = readFile(*Path))
1260ec1c75e0SRui Ueyama       tokenize(*MB);
1261ec1c75e0SRui Ueyama     return;
1262ec1c75e0SRui Ueyama   }
1263ec1c75e0SRui Ueyama   setError("cannot open " + Tok);
126431aa1f83SRui Ueyama }
126531aa1f83SRui Ueyama 
1266717677afSRui Ueyama void ScriptParser::readOutput() {
1267ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
1268ee59282bSRui Ueyama   expect("(");
1269ee59282bSRui Ueyama   StringRef Tok = next();
1270ee59282bSRui Ueyama   if (Config->OutputFile.empty())
1271cd574a5eSGeorge Rimar     Config->OutputFile = unquote(Tok);
1272ee59282bSRui Ueyama   expect(")");
1273ee59282bSRui Ueyama }
1274ee59282bSRui Ueyama 
1275717677afSRui Ueyama void ScriptParser::readOutputArch() {
12764e01c3e8SGeorge Rimar   // OUTPUT_ARCH is ignored for now.
12779159ce93SDavide Italiano   expect("(");
12784e01c3e8SGeorge Rimar   while (!Error && !consume(")"))
12795424e7c7SJustin Bogner     skip();
12809159ce93SDavide Italiano }
12819159ce93SDavide Italiano 
1282717677afSRui Ueyama void ScriptParser::readOutputFormat() {
1283f7c5fbb1SRui Ueyama   // Error checking only for now.
1284f7c5fbb1SRui Ueyama   expect("(");
12855424e7c7SJustin Bogner   skip();
12866836c618SDavide Italiano   StringRef Tok = next();
12876836c618SDavide Italiano   if (Tok == ")")
12886836c618SDavide Italiano     return;
1289025d59b1SRui Ueyama   if (Tok != ",") {
12905761042dSGeorge Rimar     setError("unexpected token: " + Tok);
1291025d59b1SRui Ueyama     return;
1292025d59b1SRui Ueyama   }
12935424e7c7SJustin Bogner   skip();
12946836c618SDavide Italiano   expect(",");
12955424e7c7SJustin Bogner   skip();
1296f7c5fbb1SRui Ueyama   expect(")");
1297f7c5fbb1SRui Ueyama }
1298f7c5fbb1SRui Ueyama 
1299bbe38602SEugene Leviant void ScriptParser::readPhdrs() {
1300bbe38602SEugene Leviant   expect("{");
130183043f23SRui Ueyama   while (!Error && !consume("}")) {
1302bbe38602SEugene Leviant     StringRef Tok = next();
1303a34da938SRui Ueyama     Script->Opt.PhdrsCommands.push_back(
130456b21c86SEugene Leviant         {Tok, PT_NULL, false, false, UINT_MAX, nullptr});
1305a34da938SRui Ueyama     PhdrsCommand &PhdrCmd = Script->Opt.PhdrsCommands.back();
1306bbe38602SEugene Leviant 
1307bbe38602SEugene Leviant     PhdrCmd.Type = readPhdrType();
1308bbe38602SEugene Leviant     do {
1309bbe38602SEugene Leviant       Tok = next();
1310bbe38602SEugene Leviant       if (Tok == ";")
1311bbe38602SEugene Leviant         break;
1312bbe38602SEugene Leviant       if (Tok == "FILEHDR")
1313bbe38602SEugene Leviant         PhdrCmd.HasFilehdr = true;
1314bbe38602SEugene Leviant       else if (Tok == "PHDRS")
1315bbe38602SEugene Leviant         PhdrCmd.HasPhdrs = true;
131656b21c86SEugene Leviant       else if (Tok == "AT")
131756b21c86SEugene Leviant         PhdrCmd.LMAExpr = readParenExpr();
1318865bf863SEugene Leviant       else if (Tok == "FLAGS") {
1319865bf863SEugene Leviant         expect("(");
1320eb685cd7SRafael Espindola         // Passing 0 for the value of dot is a bit of a hack. It means that
1321eb685cd7SRafael Espindola         // we accept expressions like ".|1".
132272dc195dSRafael Espindola         PhdrCmd.Flags = readExpr()().getValue();
1323865bf863SEugene Leviant         expect(")");
1324865bf863SEugene Leviant       } else
1325bbe38602SEugene Leviant         setError("unexpected header attribute: " + Tok);
1326bbe38602SEugene Leviant     } while (!Error);
1327bbe38602SEugene Leviant   }
1328bbe38602SEugene Leviant }
1329bbe38602SEugene Leviant 
1330717677afSRui Ueyama void ScriptParser::readSearchDir() {
133168a39a65SDavide Italiano   expect("(");
133286c5fb82SRui Ueyama   StringRef Tok = next();
13336c7ad13fSRui Ueyama   if (!Config->Nostdlib)
1334cd574a5eSGeorge Rimar     Config->SearchPaths.push_back(unquote(Tok));
133568a39a65SDavide Italiano   expect(")");
133668a39a65SDavide Italiano }
133768a39a65SDavide Italiano 
1338717677afSRui Ueyama void ScriptParser::readSections() {
1339a34da938SRui Ueyama   Script->Opt.HasSections = true;
134018a30962SGeorge Rimar   // -no-rosegment is used to avoid placing read only non-executable sections in
134118a30962SGeorge Rimar   // their own segment. We do the same if SECTIONS command is present in linker
134218a30962SGeorge Rimar   // script. See comment for computeFlags().
134318a30962SGeorge Rimar   Config->SingleRoRx = true;
134418a30962SGeorge Rimar 
13458e3b38abSDenis Protivensky   expect("{");
134683043f23SRui Ueyama   while (!Error && !consume("}")) {
1347113cdec9SRui Ueyama     StringRef Tok = next();
1348c96da110SRafael Espindola     BaseCommand *Cmd = readProvideOrAssignment(Tok);
1349ceabe80eSEugene Leviant     if (!Cmd) {
1350ceabe80eSEugene Leviant       if (Tok == "ASSERT")
1351eefa758eSGeorge Rimar         Cmd = new AssertCommand(readAssert());
1352ceabe80eSEugene Leviant       else
135310416564SRui Ueyama         Cmd = readOutputSectionDescription(Tok);
13548e3b38abSDenis Protivensky     }
1355a34da938SRui Ueyama     Script->Opt.Commands.emplace_back(Cmd);
1356652852c5SGeorge Rimar   }
1357708019c4SRui Ueyama }
13588e3b38abSDenis Protivensky 
1359708019c4SRui Ueyama static int precedence(StringRef Op) {
1360708019c4SRui Ueyama   return StringSwitch<int>(Op)
13610120e3f2SRui Ueyama       .Cases("*", "/", 5)
13620120e3f2SRui Ueyama       .Cases("+", "-", 4)
13630120e3f2SRui Ueyama       .Cases("<<", ">>", 3)
13649c4ac5f2SRui Ueyama       .Cases("<", "<=", ">", ">=", "==", "!=", 2)
13650120e3f2SRui Ueyama       .Cases("&", "|", 1)
1366708019c4SRui Ueyama       .Default(-1);
1367708019c4SRui Ueyama }
1368708019c4SRui Ueyama 
1369db688454SEugene Leviant StringMatcher ScriptParser::readFilePatterns() {
137010416564SRui Ueyama   std::vector<StringRef> V;
137183043f23SRui Ueyama   while (!Error && !consume(")"))
137210416564SRui Ueyama     V.push_back(next());
1373f91282e1SRui Ueyama   return StringMatcher(V);
13740702c4e8SGeorge Rimar }
13750702c4e8SGeorge Rimar 
1376be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() {
137783043f23SRui Ueyama   if (consume("SORT") || consume("SORT_BY_NAME"))
1378be394db3SGeorge Rimar     return SortSectionPolicy::Name;
137983043f23SRui Ueyama   if (consume("SORT_BY_ALIGNMENT"))
1380be394db3SGeorge Rimar     return SortSectionPolicy::Alignment;
138183043f23SRui Ueyama   if (consume("SORT_BY_INIT_PRIORITY"))
1382be394db3SGeorge Rimar     return SortSectionPolicy::Priority;
138383043f23SRui Ueyama   if (consume("SORT_NONE"))
1384be394db3SGeorge Rimar     return SortSectionPolicy::None;
1385b2a0abdfSRui Ueyama   return SortSectionPolicy::Default;
1386be394db3SGeorge Rimar }
1387be394db3SGeorge Rimar 
1388395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in
1389395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+
1390395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3)
1391af03be19SGeorge Rimar // The semantics of that is next:
1392af03be19SGeorge Rimar // * Include .foo.1 from every file.
1393af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o
1394af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o
139507171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
139607171f21SGeorge Rimar   std::vector<SectionPattern> Ret;
1397601e9898SGeorge Rimar   while (!Error && peek() != ")") {
1398f91282e1SRui Ueyama     StringMatcher ExcludeFilePat;
139983043f23SRui Ueyama     if (consume("EXCLUDE_FILE")) {
1400395281cfSGeorge Rimar       expect("(");
1401f91282e1SRui Ueyama       ExcludeFilePat = readFilePatterns();
1402395281cfSGeorge Rimar     }
1403395281cfSGeorge Rimar 
1404601e9898SGeorge Rimar     std::vector<StringRef> V;
1405601e9898SGeorge Rimar     while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE")
1406395281cfSGeorge Rimar       V.push_back(next());
1407601e9898SGeorge Rimar 
1408601e9898SGeorge Rimar     if (!V.empty())
1409f91282e1SRui Ueyama       Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)});
1410601e9898SGeorge Rimar     else
1411601e9898SGeorge Rimar       setError("section pattern is expected");
1412395281cfSGeorge Rimar   }
141307171f21SGeorge Rimar   return Ret;
1414395281cfSGeorge Rimar }
1415395281cfSGeorge Rimar 
1416f8f6f1e7SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a
1417f8f6f1e7SRui Ueyama // list of glob patterns for input sections. The grammar is as follows.
1418f8f6f1e7SRui Ueyama //
1419f8f6f1e7SRui Ueyama // <patterns> ::= <section-list>
1420f8f6f1e7SRui Ueyama //              | <sort> "(" <section-list> ")"
1421f8f6f1e7SRui Ueyama //              | <sort> "(" <sort> "(" <section-list> ")" ")"
1422f8f6f1e7SRui Ueyama //
1423f8f6f1e7SRui Ueyama // <sort>     ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
1424f8f6f1e7SRui Ueyama //              | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
1425f8f6f1e7SRui Ueyama //
1426f8f6f1e7SRui Ueyama // <section-list> is parsed by readInputSectionsList().
1427a2496cbeSGeorge Rimar InputSectionDescription *
1428a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) {
1429c91930a1SGeorge Rimar   auto *Cmd = new InputSectionDescription(FilePattern);
14300ed42b0cSDavide Italiano   expect("(");
1431f373dd76SRui Ueyama   while (!Error && !consume(")")) {
143207171f21SGeorge Rimar     SortSectionPolicy Outer = readSortKind();
143307171f21SGeorge Rimar     SortSectionPolicy Inner = SortSectionPolicy::Default;
143407171f21SGeorge Rimar     std::vector<SectionPattern> V;
143507171f21SGeorge Rimar     if (Outer != SortSectionPolicy::Default) {
14360702c4e8SGeorge Rimar       expect("(");
143707171f21SGeorge Rimar       Inner = readSortKind();
143807171f21SGeorge Rimar       if (Inner != SortSectionPolicy::Default) {
1439350ece4eSGeorge Rimar         expect("(");
144007171f21SGeorge Rimar         V = readInputSectionsList();
14410702c4e8SGeorge Rimar         expect(")");
1442350ece4eSGeorge Rimar       } else {
144307171f21SGeorge Rimar         V = readInputSectionsList();
1444350ece4eSGeorge Rimar       }
1445350ece4eSGeorge Rimar       expect(")");
144607171f21SGeorge Rimar     } else {
144707171f21SGeorge Rimar       V = readInputSectionsList();
14480659800eSGeorge Rimar     }
14490702c4e8SGeorge Rimar 
145007171f21SGeorge Rimar     for (SectionPattern &Pat : V) {
145107171f21SGeorge Rimar       Pat.SortInner = Inner;
145207171f21SGeorge Rimar       Pat.SortOuter = Outer;
145307171f21SGeorge Rimar     }
145407171f21SGeorge Rimar 
145507171f21SGeorge Rimar     std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns));
145607171f21SGeorge Rimar   }
145710416564SRui Ueyama   return Cmd;
14580659800eSGeorge Rimar }
14590659800eSGeorge Rimar 
1460a2496cbeSGeorge Rimar InputSectionDescription *
1461a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) {
14620659800eSGeorge Rimar   // Input section wildcard can be surrounded by KEEP.
14630659800eSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
1464a2496cbeSGeorge Rimar   if (Tok == "KEEP") {
1465e7282797SDavide Italiano     expect("(");
1466a2496cbeSGeorge Rimar     StringRef FilePattern = next();
1467a2496cbeSGeorge Rimar     InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
14680ed42b0cSDavide Italiano     expect(")");
1469a34da938SRui Ueyama     Script->Opt.KeptSections.push_back(Cmd);
147010416564SRui Ueyama     return Cmd;
147110416564SRui Ueyama   }
1472a2496cbeSGeorge Rimar   return readInputSectionRules(Tok);
14730659800eSGeorge Rimar }
14740659800eSGeorge Rimar 
147503fc010eSGeorge Rimar void ScriptParser::readSort() {
147603fc010eSGeorge Rimar   expect("(");
147703fc010eSGeorge Rimar   expect("CONSTRUCTORS");
147803fc010eSGeorge Rimar   expect(")");
147903fc010eSGeorge Rimar }
148003fc010eSGeorge Rimar 
1481eefa758eSGeorge Rimar Expr ScriptParser::readAssert() {
1482eefa758eSGeorge Rimar   expect("(");
1483eefa758eSGeorge Rimar   Expr E = readExpr();
1484eefa758eSGeorge Rimar   expect(",");
1485cd574a5eSGeorge Rimar   StringRef Msg = unquote(next());
1486eefa758eSGeorge Rimar   expect(")");
14874595df94SRafael Espindola   return [=] {
148872dc195dSRafael Espindola     if (!E().getValue())
1489eefa758eSGeorge Rimar       error(Msg);
1490a8dba487SGeorge Rimar     return Script->getDot();
1491eefa758eSGeorge Rimar   };
1492eefa758eSGeorge Rimar }
1493eefa758eSGeorge Rimar 
149425150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an
149525150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from
149625150e8bSRui Ueyama // what GNU linkers do.
149725150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
149816068aebSRui Ueyama uint32_t ScriptParser::readFill() {
1499ff1f29e0SGeorge Rimar   expect("(");
150016068aebSRui Ueyama   uint32_t V = readOutputSectionFiller(next());
1501ff1f29e0SGeorge Rimar   expect(")");
1502ff1f29e0SGeorge Rimar   expect(";");
1503ff1f29e0SGeorge Rimar   return V;
1504ff1f29e0SGeorge Rimar }
1505ff1f29e0SGeorge Rimar 
150610416564SRui Ueyama OutputSectionCommand *
150710416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) {
1508076fe157SGeorge Rimar   OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
15092a942c4bSEugene Leviant   Cmd->Location = getCurrentLocation();
151058e5c4dcSGeorge Rimar 
151158e5c4dcSGeorge Rimar   // Read an address expression.
151258e5c4dcSGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address
151358e5c4dcSGeorge Rimar   if (peek() != ":")
151458e5c4dcSGeorge Rimar     Cmd->AddrExpr = readExpr();
151558e5c4dcSGeorge Rimar 
15168e3b38abSDenis Protivensky   expect(":");
1517246f681eSDavide Italiano 
151883043f23SRui Ueyama   if (consume("AT"))
1519b71d6f7aSEugene Leviant     Cmd->LMAExpr = readParenExpr();
152083043f23SRui Ueyama   if (consume("ALIGN"))
15216ad7dfccSRui Ueyama     Cmd->AlignExpr = readParenExpr();
152283043f23SRui Ueyama   if (consume("SUBALIGN"))
1523db24d9c3SGeorge Rimar     Cmd->SubalignExpr = readParenExpr();
1524630c6179SGeorge Rimar 
1525246f681eSDavide Italiano   // Parse constraints.
152683043f23SRui Ueyama   if (consume("ONLY_IF_RO"))
1527efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadOnly;
152883043f23SRui Ueyama   if (consume("ONLY_IF_RW"))
1529efc4066bSRui Ueyama     Cmd->Constraint = ConstraintKind::ReadWrite;
15308e3b38abSDenis Protivensky   expect("{");
15318ec77e64SRui Ueyama 
153283043f23SRui Ueyama   while (!Error && !consume("}")) {
1533ceabe80eSEugene Leviant     StringRef Tok = next();
15342fe07923SGeorge Rimar     if (Tok == ";") {
153569750755SGeorge Rimar       // Empty commands are allowed. Do nothing here.
15362fe07923SGeorge Rimar     } else if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) {
1537ceabe80eSEugene Leviant       Cmd->Commands.emplace_back(Assignment);
1538b2d99d6aSMeador Inge     } else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) {
1539e38cbab5SGeorge Rimar       Cmd->Commands.emplace_back(Data);
1540b2d99d6aSMeador Inge     } else if (Tok == "ASSERT") {
1541b2d99d6aSMeador Inge       Cmd->Commands.emplace_back(new AssertCommand(readAssert()));
1542b2d99d6aSMeador Inge       expect(";");
15438e2eca22SGeorge Rimar     } else if (Tok == "CONSTRUCTORS") {
15448e2eca22SGeorge Rimar       // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
15458e2eca22SGeorge Rimar       // by name. This is for very old file formats such as ECOFF/XCOFF.
15468e2eca22SGeorge Rimar       // For ELF, we should ignore.
1547b2d99d6aSMeador Inge     } else if (Tok == "FILL") {
1548ff1f29e0SGeorge Rimar       Cmd->Filler = readFill();
1549b2d99d6aSMeador Inge     } else if (Tok == "SORT") {
155003fc010eSGeorge Rimar       readSort();
1551b2d99d6aSMeador Inge     } else if (peek() == "(") {
1552a2496cbeSGeorge Rimar       Cmd->Commands.emplace_back(readInputSectionDescription(Tok));
1553b2d99d6aSMeador Inge     } else {
1554ceabe80eSEugene Leviant       setError("unknown command " + Tok);
15558e3b38abSDenis Protivensky     }
1556b2d99d6aSMeador Inge   }
1557b889744eSMeador Inge 
1558b889744eSMeador Inge   if (consume(">"))
1559b889744eSMeador Inge     Cmd->MemoryRegionName = next();
1560b889744eSMeador Inge 
1561076fe157SGeorge Rimar   Cmd->Phdrs = readOutputSectionPhdrs();
15624ebc5620SGeorge Rimar 
156383043f23SRui Ueyama   if (consume("="))
15644ebc5620SGeorge Rimar     Cmd->Filler = readOutputSectionFiller(next());
15654ebc5620SGeorge Rimar   else if (peek().startswith("="))
1566ff1f29e0SGeorge Rimar     Cmd->Filler = readOutputSectionFiller(next().drop_front());
15674ebc5620SGeorge Rimar 
15687185a1acSGeorge Rimar   // Consume optional comma following output section command.
15697185a1acSGeorge Rimar   consume(",");
15707185a1acSGeorge Rimar 
157110416564SRui Ueyama   return Cmd;
1572f71caa2bSRui Ueyama }
15738ec77e64SRui Ueyama 
15742c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number.
15752c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
15762c8f1f04SRui Ueyama //
15772c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles
15782c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them
15792c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does
15802c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does.
158116068aebSRui Ueyama uint32_t ScriptParser::readOutputSectionFiller(StringRef Tok) {
1582965827d6SRui Ueyama   uint32_t V;
158316068aebSRui Ueyama   if (!Tok.getAsInteger(0, V))
158416068aebSRui Ueyama     return V;
1585965827d6SRui Ueyama   setError("invalid filler expression: " + Tok);
158616068aebSRui Ueyama   return 0;
15878e3b38abSDenis Protivensky }
15888e3b38abSDenis Protivensky 
1589a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
1590a31c91b1SEugene Leviant   expect("(");
1591174e0a16SRui Ueyama   SymbolAssignment *Cmd = readAssignment(next());
1592a35e39caSPetr Hosek   Cmd->Provide = Provide;
1593174e0a16SRui Ueyama   Cmd->Hidden = Hidden;
1594a31c91b1SEugene Leviant   expect(")");
1595a31c91b1SEugene Leviant   expect(";");
159610416564SRui Ueyama   return Cmd;
1597eda81a1bSEugene Leviant }
1598eda81a1bSEugene Leviant 
1599c96da110SRafael Espindola SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
1600ceabe80eSEugene Leviant   SymbolAssignment *Cmd = nullptr;
1601ceabe80eSEugene Leviant   if (peek() == "=" || peek() == "+=") {
1602ceabe80eSEugene Leviant     Cmd = readAssignment(Tok);
1603ceabe80eSEugene Leviant     expect(";");
1604ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE") {
1605a35e39caSPetr Hosek     Cmd = readProvideHidden(true, false);
1606a35e39caSPetr Hosek   } else if (Tok == "HIDDEN") {
1607a35e39caSPetr Hosek     Cmd = readProvideHidden(false, true);
1608ceabe80eSEugene Leviant   } else if (Tok == "PROVIDE_HIDDEN") {
1609a35e39caSPetr Hosek     Cmd = readProvideHidden(true, true);
1610ceabe80eSEugene Leviant   }
1611ceabe80eSEugene Leviant   return Cmd;
1612ceabe80eSEugene Leviant }
1613ceabe80eSEugene Leviant 
161430835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
161530835ea4SGeorge Rimar   StringRef Op = next();
161630835ea4SGeorge Rimar   assert(Op == "=" || Op == "+=");
161702ad516bSPetr Hosek   Expr E = readExpr();
1618f6aeed36SEugene Leviant   if (Op == "+=") {
1619f6aeed36SEugene Leviant     std::string Loc = getCurrentLocation();
1620a8dba487SGeorge Rimar     E = [=] { return add(Script->getSymbolValue(Loc, Name), E()); };
1621f6aeed36SEugene Leviant   }
16222ee2d2dcSGeorge Rimar   return new SymbolAssignment(Name, E, getCurrentLocation());
162330835ea4SGeorge Rimar }
162430835ea4SGeorge Rimar 
162530835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker
162630835ea4SGeorge Rimar // script expression.
1627731a66aeSRui Ueyama Expr ScriptParser::readExpr() {
1628731a66aeSRui Ueyama   // Our lexer is context-aware. Set the in-expression bit so that
1629731a66aeSRui Ueyama   // they apply different tokenization rules.
1630731a66aeSRui Ueyama   bool Orig = InExpr;
1631731a66aeSRui Ueyama   InExpr = true;
1632731a66aeSRui Ueyama   Expr E = readExpr1(readPrimary(), 0);
1633731a66aeSRui Ueyama   InExpr = Orig;
1634731a66aeSRui Ueyama   return E;
1635731a66aeSRui Ueyama }
163630835ea4SGeorge Rimar 
163736c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) {
163836c1cd23SRui Ueyama   if (Op == "*")
163972dc195dSRafael Espindola     return [=] { return mul(L(), R()); };
164036c1cd23SRui Ueyama   if (Op == "/") {
164172dc195dSRafael Espindola     return [=] { return div(L(), R()); };
164236c1cd23SRui Ueyama   }
164336c1cd23SRui Ueyama   if (Op == "+")
164472dc195dSRafael Espindola     return [=] { return add(L(), R()); };
164536c1cd23SRui Ueyama   if (Op == "-")
164672dc195dSRafael Espindola     return [=] { return sub(L(), R()); };
1647c8ccd1f1SGeorge Rimar   if (Op == "<<")
164872dc195dSRafael Espindola     return [=] { return leftShift(L(), R()); };
1649c8ccd1f1SGeorge Rimar   if (Op == ">>")
165072dc195dSRafael Espindola     return [=] { return rightShift(L(), R()); };
165136c1cd23SRui Ueyama   if (Op == "<")
1652195f23c5SRafael Espindola     return [=] { return L().getValue() < R().getValue(); };
165336c1cd23SRui Ueyama   if (Op == ">")
1654195f23c5SRafael Espindola     return [=] { return L().getValue() > R().getValue(); };
165536c1cd23SRui Ueyama   if (Op == ">=")
1656195f23c5SRafael Espindola     return [=] { return L().getValue() >= R().getValue(); };
165736c1cd23SRui Ueyama   if (Op == "<=")
1658195f23c5SRafael Espindola     return [=] { return L().getValue() <= R().getValue(); };
165936c1cd23SRui Ueyama   if (Op == "==")
1660195f23c5SRafael Espindola     return [=] { return L().getValue() == R().getValue(); };
166136c1cd23SRui Ueyama   if (Op == "!=")
1662195f23c5SRafael Espindola     return [=] { return L().getValue() != R().getValue(); };
166336c1cd23SRui Ueyama   if (Op == "&")
166472dc195dSRafael Espindola     return [=] { return bitAnd(L(), R()); };
1665cc3dd629SRafael Espindola   if (Op == "|")
166672dc195dSRafael Espindola     return [=] { return bitOr(L(), R()); };
166736c1cd23SRui Ueyama   llvm_unreachable("invalid operator");
166836c1cd23SRui Ueyama }
166936c1cd23SRui Ueyama 
1670708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function
1671708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator.
1672708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
1673708019c4SRui Ueyama   while (!atEOF() && !Error) {
1674708019c4SRui Ueyama     // Read an operator and an expression.
167546247b85SRui Ueyama     if (consume("?"))
1676708019c4SRui Ueyama       return readTernary(Lhs);
167746247b85SRui Ueyama     StringRef Op1 = peek();
1678708019c4SRui Ueyama     if (precedence(Op1) < MinPrec)
1679a31c91b1SEugene Leviant       break;
16805424e7c7SJustin Bogner     skip();
1681708019c4SRui Ueyama     Expr Rhs = readPrimary();
1682708019c4SRui Ueyama 
1683708019c4SRui Ueyama     // Evaluate the remaining part of the expression first if the
1684708019c4SRui Ueyama     // next operator has greater precedence than the previous one.
1685708019c4SRui Ueyama     // For example, if we have read "+" and "3", and if the next
1686708019c4SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
1687708019c4SRui Ueyama     while (!atEOF()) {
1688708019c4SRui Ueyama       StringRef Op2 = peek();
1689708019c4SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
1690eda81a1bSEugene Leviant         break;
1691708019c4SRui Ueyama       Rhs = readExpr1(Rhs, precedence(Op2));
1692eda81a1bSEugene Leviant     }
1693708019c4SRui Ueyama 
1694708019c4SRui Ueyama     Lhs = combine(Op1, Lhs, Rhs);
1695708019c4SRui Ueyama   }
1696708019c4SRui Ueyama   return Lhs;
1697708019c4SRui Ueyama }
1698708019c4SRui Ueyama 
1699708019c4SRui Ueyama uint64_t static getConstant(StringRef S) {
1700e2cc07bcSMichael J. Spencer   if (S == "COMMONPAGESIZE")
1701708019c4SRui Ueyama     return Target->PageSize;
1702e2cc07bcSMichael J. Spencer   if (S == "MAXPAGESIZE")
1703997f8838SPetr Hosek     return Config->MaxPageSize;
1704708019c4SRui Ueyama   error("unknown constant: " + S);
1705708019c4SRui Ueyama   return 0;
1706708019c4SRui Ueyama }
1707708019c4SRui Ueyama 
1708626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful.
1709626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H")
1710626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or
1711626e0b08SRui Ueyama // "M" (mega) prefixes.
17129f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) {
171346247b85SRui Ueyama   // Negative number
1714eaeafb2bSSimon Atanasyan   if (Tok.startswith("-")) {
1715eaeafb2bSSimon Atanasyan     if (!readInteger(Tok.substr(1), Result))
1716eaeafb2bSSimon Atanasyan       return false;
1717eaeafb2bSSimon Atanasyan     Result = -Result;
1718eaeafb2bSSimon Atanasyan     return true;
1719eaeafb2bSSimon Atanasyan   }
172046247b85SRui Ueyama 
172146247b85SRui Ueyama   // Hexadecimal
17229f2f7ad9SGeorge Rimar   if (Tok.startswith_lower("0x"))
17239f2f7ad9SGeorge Rimar     return !Tok.substr(2).getAsInteger(16, Result);
17249f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("H"))
17259f2f7ad9SGeorge Rimar     return !Tok.drop_back().getAsInteger(16, Result);
17269f2f7ad9SGeorge Rimar 
172746247b85SRui Ueyama   // Decimal
17289f2f7ad9SGeorge Rimar   int Suffix = 1;
17299f2f7ad9SGeorge Rimar   if (Tok.endswith_lower("K")) {
17309f2f7ad9SGeorge Rimar     Suffix = 1024;
17319f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
17329f2f7ad9SGeorge Rimar   } else if (Tok.endswith_lower("M")) {
17339f2f7ad9SGeorge Rimar     Suffix = 1024 * 1024;
17349f2f7ad9SGeorge Rimar     Tok = Tok.drop_back();
17359f2f7ad9SGeorge Rimar   }
17369f2f7ad9SGeorge Rimar   if (Tok.getAsInteger(10, Result))
17379f2f7ad9SGeorge Rimar     return false;
17389f2f7ad9SGeorge Rimar   Result *= Suffix;
17399f2f7ad9SGeorge Rimar   return true;
17409f2f7ad9SGeorge Rimar }
17419f2f7ad9SGeorge Rimar 
1742e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) {
1743e38cbab5SGeorge Rimar   int Size = StringSwitch<unsigned>(Tok)
1744e38cbab5SGeorge Rimar                  .Case("BYTE", 1)
1745e38cbab5SGeorge Rimar                  .Case("SHORT", 2)
1746e38cbab5SGeorge Rimar                  .Case("LONG", 4)
1747e38cbab5SGeorge Rimar                  .Case("QUAD", 8)
1748e38cbab5SGeorge Rimar                  .Default(-1);
1749e38cbab5SGeorge Rimar   if (Size == -1)
1750e38cbab5SGeorge Rimar     return nullptr;
1751e38cbab5SGeorge Rimar 
175295c7d8d2SMeador Inge   return new BytesDataCommand(readParenExpr(), Size);
1753e38cbab5SGeorge Rimar }
1754e38cbab5SGeorge Rimar 
1755b71d6f7aSEugene Leviant StringRef ScriptParser::readParenLiteral() {
1756b71d6f7aSEugene Leviant   expect("(");
1757b71d6f7aSEugene Leviant   StringRef Tok = next();
1758b71d6f7aSEugene Leviant   expect(")");
1759b71d6f7aSEugene Leviant   return Tok;
1760b71d6f7aSEugene Leviant }
1761b71d6f7aSEugene Leviant 
1762708019c4SRui Ueyama Expr ScriptParser::readPrimary() {
17636ad7dfccSRui Ueyama   if (peek() == "(")
17646ad7dfccSRui Ueyama     return readParenExpr();
1765708019c4SRui Ueyama 
17666ad7dfccSRui Ueyama   StringRef Tok = next();
1767b5f1c3ecSRui Ueyama   std::string Location = getCurrentLocation();
1768708019c4SRui Ueyama 
1769eaeafb2bSSimon Atanasyan   if (Tok == "~") {
1770eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
177172dc195dSRafael Espindola     return [=] { return bitNot(E()); };
1772eaeafb2bSSimon Atanasyan   }
1773eaeafb2bSSimon Atanasyan   if (Tok == "-") {
1774eaeafb2bSSimon Atanasyan     Expr E = readPrimary();
177572dc195dSRafael Espindola     return [=] { return minus(E()); };
1776eaeafb2bSSimon Atanasyan   }
1777eaeafb2bSSimon Atanasyan 
1778708019c4SRui Ueyama   // Built-in functions are parsed here.
1779708019c4SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
178002ad516bSPetr Hosek   if (Tok == "ABSOLUTE") {
178172dc195dSRafael Espindola     Expr Inner = readParenExpr();
178272dc195dSRafael Espindola     return [=] {
178372dc195dSRafael Espindola       ExprValue I = Inner();
178472dc195dSRafael Espindola       I.ForceAbsolute = true;
178572dc195dSRafael Espindola       return I;
178672dc195dSRafael Espindola     };
178702ad516bSPetr Hosek   }
178896659df0SGeorge Rimar   if (Tok == "ADDR") {
1789b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
179072dc195dSRafael Espindola     return [=]() -> ExprValue {
1791a8dba487SGeorge Rimar       return {Script->getOutputSection(Location, Name), 0};
179272dc195dSRafael Espindola     };
179396659df0SGeorge Rimar   }
1794708019c4SRui Ueyama   if (Tok == "ALIGN") {
17955d804dc8SRui Ueyama     expect("(");
17965d804dc8SRui Ueyama     Expr E = readExpr();
17975d804dc8SRui Ueyama     if (consume(",")) {
17985d804dc8SRui Ueyama       Expr E2 = readExpr();
17995d804dc8SRui Ueyama       expect(")");
180072dc195dSRafael Espindola       return [=] { return alignTo(E().getValue(), E2().getValue()); };
18015d804dc8SRui Ueyama     }
18025d804dc8SRui Ueyama     expect(")");
1803a8dba487SGeorge Rimar     return [=] { return alignTo(Script->getDot(), E().getValue()); };
1804708019c4SRui Ueyama   }
1805fc16173cSRui Ueyama   if (Tok == "ALIGNOF") {
1806fc16173cSRui Ueyama     StringRef Name = readParenLiteral();
1807fc16173cSRui Ueyama     return [=] { return Script->getOutputSection(Location, Name)->Alignment; };
1808fc16173cSRui Ueyama   }
1809fc16173cSRui Ueyama   if (Tok == "ASSERT")
1810fc16173cSRui Ueyama     return readAssert();
1811708019c4SRui Ueyama   if (Tok == "CONSTANT") {
1812b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
18134595df94SRafael Espindola     return [=] { return getConstant(Name); };
1814708019c4SRui Ueyama   }
1815708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_ALIGN") {
1816708019c4SRui Ueyama     expect("(");
1817708019c4SRui Ueyama     Expr E = readExpr();
1818708019c4SRui Ueyama     expect(",");
1819708019c4SRui Ueyama     readExpr();
1820708019c4SRui Ueyama     expect(")");
1821a8dba487SGeorge Rimar     return [=] { return alignTo(Script->getDot(), E().getValue()); };
1822708019c4SRui Ueyama   }
1823708019c4SRui Ueyama   if (Tok == "DATA_SEGMENT_END") {
1824708019c4SRui Ueyama     expect("(");
1825708019c4SRui Ueyama     expect(".");
1826708019c4SRui Ueyama     expect(")");
1827a8dba487SGeorge Rimar     return [] { return Script->getDot(); };
1828708019c4SRui Ueyama   }
1829276b4e64SGeorge Rimar   if (Tok == "DATA_SEGMENT_RELRO_END") {
1830fc16173cSRui Ueyama     // GNU linkers implements more complicated logic to handle
1831fc16173cSRui Ueyama     // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
1832fc16173cSRui Ueyama     // just align to the next page boundary for simplicity.
1833276b4e64SGeorge Rimar     expect("(");
183497bdc722SRafael Espindola     readExpr();
1835276b4e64SGeorge Rimar     expect(",");
1836276b4e64SGeorge Rimar     readExpr();
1837276b4e64SGeorge Rimar     expect(")");
1838a8dba487SGeorge Rimar     return [] { return alignTo(Script->getDot(), Target->PageSize); };
1839276b4e64SGeorge Rimar   }
1840fc16173cSRui Ueyama   if (Tok == "DEFINED") {
1841fc16173cSRui Ueyama     StringRef Name = readParenLiteral();
1842fc16173cSRui Ueyama     return [=] { return Script->isDefined(Name) ? 1 : 0; };
1843fc16173cSRui Ueyama   }
1844fc16173cSRui Ueyama   if (Tok == "LOADADDR") {
1845fc16173cSRui Ueyama     StringRef Name = readParenLiteral();
1846fc16173cSRui Ueyama     return [=] { return Script->getOutputSection(Location, Name)->getLMA(); };
1847fc16173cSRui Ueyama   }
1848fc16173cSRui Ueyama   if (Tok == "SEGMENT_START") {
1849fc16173cSRui Ueyama     expect("(");
1850fc16173cSRui Ueyama     skip();
1851fc16173cSRui Ueyama     expect(",");
1852fc16173cSRui Ueyama     Expr E = readExpr();
1853fc16173cSRui Ueyama     expect(")");
1854fc16173cSRui Ueyama     return [=] { return E(); };
1855fc16173cSRui Ueyama   }
18569e69450eSGeorge Rimar   if (Tok == "SIZEOF") {
1857b71d6f7aSEugene Leviant     StringRef Name = readParenLiteral();
1858a8dba487SGeorge Rimar     return [=] { return Script->getOutputSectionSize(Name); };
18599e69450eSGeorge Rimar   }
1860e32a3598SGeorge Rimar   if (Tok == "SIZEOF_HEADERS")
186178aa2700SGeorge Rimar     return [=] { return elf::getHeaderSize(); };
1862708019c4SRui Ueyama 
18639f2f7ad9SGeorge Rimar   // Tok is a literal number.
18649f2f7ad9SGeorge Rimar   uint64_t V;
18659f2f7ad9SGeorge Rimar   if (readInteger(Tok, V))
18664595df94SRafael Espindola     return [=] { return V; };
18679f2f7ad9SGeorge Rimar 
18689f2f7ad9SGeorge Rimar   // Tok is a symbol name.
186930f16b23SPetr Hosek   if (Tok != ".") {
187030f16b23SPetr Hosek     if (!isValidCIdentifier(Tok))
1871708019c4SRui Ueyama       setError("malformed number: " + Tok);
187230f16b23SPetr Hosek     Script->Opt.UndefinedSymbols.push_back(Tok);
187330f16b23SPetr Hosek   }
1874a8dba487SGeorge Rimar   return [=] { return Script->getSymbolValue(Location, Tok); };
1875a9c5a528SGeorge Rimar }
1876708019c4SRui Ueyama 
1877708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) {
1878708019c4SRui Ueyama   Expr L = readExpr();
1879708019c4SRui Ueyama   expect(":");
1880708019c4SRui Ueyama   Expr R = readExpr();
188172dc195dSRafael Espindola   return [=] { return Cond().getValue() ? L() : R(); };
1882708019c4SRui Ueyama }
1883708019c4SRui Ueyama 
18846ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() {
18856ad7dfccSRui Ueyama   expect("(");
18866ad7dfccSRui Ueyama   Expr E = readExpr();
18876ad7dfccSRui Ueyama   expect(")");
18886ad7dfccSRui Ueyama   return E;
18896ad7dfccSRui Ueyama }
18906ad7dfccSRui Ueyama 
1891bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
1892bbe38602SEugene Leviant   std::vector<StringRef> Phdrs;
1893bbe38602SEugene Leviant   while (!Error && peek().startswith(":")) {
1894bbe38602SEugene Leviant     StringRef Tok = next();
1895da841c16SGeorge Rimar     Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
1896bbe38602SEugene Leviant   }
1897bbe38602SEugene Leviant   return Phdrs;
1898bbe38602SEugene Leviant }
1899bbe38602SEugene Leviant 
190095dd718cSGeorge Rimar // Read a program header type name. The next token must be a
190195dd718cSGeorge Rimar // name of a program header type or a constant (e.g. "0x3").
1902bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() {
1903bbe38602SEugene Leviant   StringRef Tok = next();
190495dd718cSGeorge Rimar   uint64_t Val;
190595dd718cSGeorge Rimar   if (readInteger(Tok, Val))
190695dd718cSGeorge Rimar     return Val;
190795dd718cSGeorge Rimar 
1908b0f6c590SRui Ueyama   unsigned Ret = StringSwitch<unsigned>(Tok)
1909b0f6c590SRui Ueyama                      .Case("PT_NULL", PT_NULL)
1910b0f6c590SRui Ueyama                      .Case("PT_LOAD", PT_LOAD)
1911b0f6c590SRui Ueyama                      .Case("PT_DYNAMIC", PT_DYNAMIC)
1912b0f6c590SRui Ueyama                      .Case("PT_INTERP", PT_INTERP)
1913b0f6c590SRui Ueyama                      .Case("PT_NOTE", PT_NOTE)
1914b0f6c590SRui Ueyama                      .Case("PT_SHLIB", PT_SHLIB)
1915b0f6c590SRui Ueyama                      .Case("PT_PHDR", PT_PHDR)
1916b0f6c590SRui Ueyama                      .Case("PT_TLS", PT_TLS)
1917b0f6c590SRui Ueyama                      .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
1918b0f6c590SRui Ueyama                      .Case("PT_GNU_STACK", PT_GNU_STACK)
1919b0f6c590SRui Ueyama                      .Case("PT_GNU_RELRO", PT_GNU_RELRO)
1920270173f2SGeorge Rimar                      .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
1921cc6e567cSGeorge Rimar                      .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
1922a2a32c2cSGeorge Rimar                      .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
1923b0f6c590SRui Ueyama                      .Default(-1);
1924bbe38602SEugene Leviant 
1925b0f6c590SRui Ueyama   if (Ret == (unsigned)-1) {
1926b0f6c590SRui Ueyama     setError("invalid program header type: " + Tok);
1927b0f6c590SRui Ueyama     return PT_NULL;
1928b0f6c590SRui Ueyama   }
1929b0f6c590SRui Ueyama   return Ret;
1930bbe38602SEugene Leviant }
1931bbe38602SEugene Leviant 
1932f5fce486SRui Ueyama // Reads an anonymous version declaration.
193312450b20SRui Ueyama void ScriptParser::readAnonymousDeclaration() {
1934f5fce486SRui Ueyama   std::vector<SymbolVersion> Locals;
1935f5fce486SRui Ueyama   std::vector<SymbolVersion> Globals;
1936f5fce486SRui Ueyama   std::tie(Locals, Globals) = readSymbols();
1937f5fce486SRui Ueyama 
1938f5fce486SRui Ueyama   for (SymbolVersion V : Locals) {
1939f5fce486SRui Ueyama     if (V.Name == "*")
1940f5fce486SRui Ueyama       Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1941f5fce486SRui Ueyama     else
1942f5fce486SRui Ueyama       Config->VersionScriptLocals.push_back(V);
19434524268cSRafael Espindola   }
1944f5fce486SRui Ueyama 
1945f5fce486SRui Ueyama   for (SymbolVersion V : Globals)
1946f5fce486SRui Ueyama     Config->VersionScriptGlobals.push_back(V);
1947f5fce486SRui Ueyama 
194812450b20SRui Ueyama   expect(";");
194912450b20SRui Ueyama }
195012450b20SRui Ueyama 
1951f5fce486SRui Ueyama // Reads a non-anonymous version definition,
1952f5fce486SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };".
1953f5fce486SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) {
1954f5fce486SRui Ueyama   // Read a symbol list.
1955f5fce486SRui Ueyama   std::vector<SymbolVersion> Locals;
1956f5fce486SRui Ueyama   std::vector<SymbolVersion> Globals;
1957f5fce486SRui Ueyama   std::tie(Locals, Globals) = readSymbols();
1958f5fce486SRui Ueyama 
1959e999ddb8SRafael Espindola   for (SymbolVersion V : Locals) {
1960f5fce486SRui Ueyama     if (V.Name == "*")
1961e999ddb8SRafael Espindola       Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1962f5fce486SRui Ueyama     else
1963e999ddb8SRafael Espindola       Config->VersionScriptLocals.push_back(V);
1964e999ddb8SRafael Espindola   }
1965e999ddb8SRafael Espindola 
1966f5fce486SRui Ueyama   // Create a new version definition and add that to the global symbols.
1967f5fce486SRui Ueyama   VersionDefinition Ver;
1968f5fce486SRui Ueyama   Ver.Name = VerStr;
1969f5fce486SRui Ueyama   Ver.Globals = Globals;
197020b6598cSGeorge Rimar 
1971f5fce486SRui Ueyama   // User-defined version number starts from 2 because 0 and 1 are
1972f5fce486SRui Ueyama   // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively.
1973f5fce486SRui Ueyama   Ver.Id = Config->VersionDefinitions.size() + 2;
1974f5fce486SRui Ueyama   Config->VersionDefinitions.push_back(Ver);
197520b6598cSGeorge Rimar 
197612450b20SRui Ueyama   // Each version may have a parent version. For example, "Ver2"
197712450b20SRui Ueyama   // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
197812450b20SRui Ueyama   // as a parent. This version hierarchy is, probably against your
197912450b20SRui Ueyama   // instinct, purely for hint; the runtime doesn't care about it
198012450b20SRui Ueyama   // at all. In LLD, we simply ignore it.
198112450b20SRui Ueyama   if (peek() != ";")
19825424e7c7SJustin Bogner     skip();
198320b6598cSGeorge Rimar   expect(";");
198420b6598cSGeorge Rimar }
198520b6598cSGeorge Rimar 
1986f5fce486SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
1987f5fce486SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
1988f5fce486SRui Ueyama ScriptParser::readSymbols() {
1989f5fce486SRui Ueyama   std::vector<SymbolVersion> Locals;
1990f5fce486SRui Ueyama   std::vector<SymbolVersion> Globals;
1991f5fce486SRui Ueyama   std::vector<SymbolVersion> *V = &Globals;
1992f5fce486SRui Ueyama 
1993f5fce486SRui Ueyama   while (!Error) {
1994f5fce486SRui Ueyama     if (consume("}"))
1995f5fce486SRui Ueyama       break;
1996f5fce486SRui Ueyama     if (consumeLabel("local")) {
1997f5fce486SRui Ueyama       V = &Locals;
1998f5fce486SRui Ueyama       continue;
1999f5fce486SRui Ueyama     }
2000f5fce486SRui Ueyama     if (consumeLabel("global")) {
2001f5fce486SRui Ueyama       V = &Globals;
20021ef90d2fSRafael Espindola       continue;
20031ef90d2fSRafael Espindola     }
2004e0fc2421SGeorge Rimar 
2005f5fce486SRui Ueyama     if (consume("extern")) {
2006f5fce486SRui Ueyama       std::vector<SymbolVersion> Ext = readVersionExtern();
2007f5fce486SRui Ueyama       V->insert(V->end(), Ext.begin(), Ext.end());
2008f5fce486SRui Ueyama     } else {
20090ee25a69SRui Ueyama       StringRef Tok = next();
2010f5fce486SRui Ueyama       V->push_back({unquote(Tok), false, hasWildcard(Tok)});
2011f5fce486SRui Ueyama     }
2012e0fc2421SGeorge Rimar     expect(";");
2013e0fc2421SGeorge Rimar   }
2014f5fce486SRui Ueyama   return {Locals, Globals};
2015e0fc2421SGeorge Rimar }
2016e0fc2421SGeorge Rimar 
201712450b20SRui Ueyama // Reads an "extern C++" directive, e.g.,
201812450b20SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };"
201912450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
20207e71415cSRafael Espindola   StringRef Tok = next();
20217e71415cSRafael Espindola   bool IsCXX = Tok == "\"C++\"";
20227e71415cSRafael Espindola   if (!IsCXX && Tok != "\"C\"")
2023d0ebd84cSRafael Espindola     setError("Unknown language");
202420b6598cSGeorge Rimar   expect("{");
202520b6598cSGeorge Rimar 
202612450b20SRui Ueyama   std::vector<SymbolVersion> Ret;
20270ee25a69SRui Ueyama   while (!Error && peek() != "}") {
20280ee25a69SRui Ueyama     StringRef Tok = next();
20290ee25a69SRui Ueyama     bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok);
20307e71415cSRafael Espindola     Ret.push_back({unquote(Tok), IsCXX, HasWildcard});
203120b6598cSGeorge Rimar     expect(";");
203220b6598cSGeorge Rimar   }
203320b6598cSGeorge Rimar 
203420b6598cSGeorge Rimar   expect("}");
203512450b20SRui Ueyama   return Ret;
203620b6598cSGeorge Rimar }
203720b6598cSGeorge Rimar 
2038009833d3SGeorge Rimar uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
2039009833d3SGeorge Rimar                                             StringRef S3) {
204024e626ccSRui Ueyama   if (!(consume(S1) || consume(S2) || consume(S3))) {
204124e626ccSRui Ueyama     setError("expected one of: " + S1 + ", " + S2 + ", or " + S3);
204224e626ccSRui Ueyama     return 0;
204324e626ccSRui Ueyama   }
204424e626ccSRui Ueyama   expect("=");
204524e626ccSRui Ueyama 
204624e626ccSRui Ueyama   // TODO: Fully support constant expressions.
204724e626ccSRui Ueyama   uint64_t Val;
204824e626ccSRui Ueyama   if (!readInteger(next(), Val))
204924e626ccSRui Ueyama     setError("nonconstant expression for " + S1);
205024e626ccSRui Ueyama   return Val;
205124e626ccSRui Ueyama }
205224e626ccSRui Ueyama 
205324e626ccSRui Ueyama // Parse the MEMORY command as specified in:
205424e626ccSRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html
205524e626ccSRui Ueyama //
205624e626ccSRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
2057b889744eSMeador Inge void ScriptParser::readMemory() {
2058b889744eSMeador Inge   expect("{");
2059b889744eSMeador Inge   while (!Error && !consume("}")) {
2060b889744eSMeador Inge     StringRef Name = next();
206124e626ccSRui Ueyama 
2062b889744eSMeador Inge     uint32_t Flags = 0;
20638a8a953eSRui Ueyama     uint32_t NegFlags = 0;
2064b889744eSMeador Inge     if (consume("(")) {
20658a8a953eSRui Ueyama       std::tie(Flags, NegFlags) = readMemoryAttributes();
2066b889744eSMeador Inge       expect(")");
2067b889744eSMeador Inge     }
2068b889744eSMeador Inge     expect(":");
2069b889744eSMeador Inge 
207024e626ccSRui Ueyama     uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o");
2071b889744eSMeador Inge     expect(",");
207224e626ccSRui Ueyama     uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
2073b889744eSMeador Inge 
2074b889744eSMeador Inge     // Add the memory region to the region map (if it doesn't already exist).
2075a34da938SRui Ueyama     auto It = Script->Opt.MemoryRegions.find(Name);
2076a34da938SRui Ueyama     if (It != Script->Opt.MemoryRegions.end())
2077b889744eSMeador Inge       setError("region '" + Name + "' already defined");
2078b889744eSMeador Inge     else
2079a34da938SRui Ueyama       Script->Opt.MemoryRegions[Name] = {Name,   Origin, Length,
2080a34da938SRui Ueyama                                          Origin, Flags,  NegFlags};
2081b889744eSMeador Inge   }
2082b889744eSMeador Inge }
2083b889744eSMeador Inge 
2084b889744eSMeador Inge // This function parses the attributes used to match against section
2085b889744eSMeador Inge // flags when placing output sections in a memory region. These flags
2086b889744eSMeador Inge // are only used when an explicit memory region name is not used.
2087b889744eSMeador Inge std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
2088b889744eSMeador Inge   uint32_t Flags = 0;
20898a8a953eSRui Ueyama   uint32_t NegFlags = 0;
2090b889744eSMeador Inge   bool Invert = false;
2091481ac996SRui Ueyama 
2092481ac996SRui Ueyama   for (char C : next().lower()) {
2093b889744eSMeador Inge     uint32_t Flag = 0;
2094b889744eSMeador Inge     if (C == '!')
2095b889744eSMeador Inge       Invert = !Invert;
2096481ac996SRui Ueyama     else if (C == 'w')
2097b889744eSMeador Inge       Flag = SHF_WRITE;
2098481ac996SRui Ueyama     else if (C == 'x')
2099b889744eSMeador Inge       Flag = SHF_EXECINSTR;
2100481ac996SRui Ueyama     else if (C == 'a')
2101b889744eSMeador Inge       Flag = SHF_ALLOC;
2102481ac996SRui Ueyama     else if (C != 'r')
2103b889744eSMeador Inge       setError("invalid memory region attribute");
2104481ac996SRui Ueyama 
2105b889744eSMeador Inge     if (Invert)
21068a8a953eSRui Ueyama       NegFlags |= Flag;
2107b889744eSMeador Inge     else
2108b889744eSMeador Inge       Flags |= Flag;
2109b889744eSMeador Inge   }
21108a8a953eSRui Ueyama   return {Flags, NegFlags};
2111b889744eSMeador Inge }
2112b889744eSMeador Inge 
211307320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) {
211422375f24SRui Ueyama   ScriptParser(MB).readLinkerScript();
211520b6598cSGeorge Rimar }
211620b6598cSGeorge Rimar 
211720b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) {
211822375f24SRui Ueyama   ScriptParser(MB).readVersionScript();
2119f7c5fbb1SRui Ueyama }
21201ebc8ed7SRui Ueyama 
2121d0ebd84cSRafael Espindola void elf::readDynamicList(MemoryBufferRef MB) {
2122d0ebd84cSRafael Espindola   ScriptParser(MB).readDynamicList();
2123d0ebd84cSRafael Espindola }
2124