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"
161ebc8ed7SRui Ueyama #include "InputSection.h"
179381eb10SRui Ueyama #include "Memory.h"
18652852c5SGeorge Rimar #include "OutputSections.h"
1993c9af42SRui Ueyama #include "Strings.h"
20f7c5fbb1SRui Ueyama #include "SymbolTable.h"
2155518e7dSRui Ueyama #include "Symbols.h"
223fb5a6dcSGeorge Rimar #include "SyntheticSections.h"
23bbe38602SEugene Leviant #include "Writer.h"
2422886a28SEugene Zelenko #include "llvm/ADT/STLExtras.h"
2522886a28SEugene Zelenko #include "llvm/ADT/StringRef.h"
2622886a28SEugene Zelenko #include "llvm/Support/Casting.h"
27652852c5SGeorge Rimar #include "llvm/Support/ELF.h"
2822886a28SEugene Zelenko #include "llvm/Support/Endian.h"
2922886a28SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
30f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h"
31f03f3cc1SRui Ueyama #include "llvm/Support/Path.h"
3222886a28SEugene Zelenko #include <algorithm>
3322886a28SEugene Zelenko #include <cassert>
3422886a28SEugene Zelenko #include <cstddef>
3522886a28SEugene Zelenko #include <cstdint>
3622886a28SEugene Zelenko #include <iterator>
3722886a28SEugene Zelenko #include <limits>
3822886a28SEugene Zelenko #include <string>
3922886a28SEugene Zelenko #include <vector>
40f7c5fbb1SRui Ueyama 
41f7c5fbb1SRui Ueyama using namespace llvm;
42652852c5SGeorge Rimar using namespace llvm::ELF;
431ebc8ed7SRui Ueyama using namespace llvm::object;
44e38cbab5SGeorge Rimar using namespace llvm::support::endian;
45f7c5fbb1SRui Ueyama using namespace lld;
46e0df00b9SRafael Espindola using namespace lld::elf;
47f7c5fbb1SRui Ueyama 
48a34da938SRui Ueyama LinkerScript *elf::Script;
49a34da938SRui Ueyama 
5072dc195dSRafael Espindola uint64_t ExprValue::getValue() const {
51608cf670SGeorge Rimar   if (Sec) {
52608cf670SGeorge Rimar     if (Sec->getOutputSection())
5372dc195dSRafael Espindola       return Sec->getOffset(Val) + Sec->getOutputSection()->Addr;
54608cf670SGeorge Rimar     error("unable to evaluate expression: input section " + Sec->Name +
55608cf670SGeorge Rimar           " has no output section assigned");
56608cf670SGeorge Rimar   }
5772dc195dSRafael Espindola   return Val;
5872dc195dSRafael Espindola }
5972dc195dSRafael Espindola 
607ba5f47eSRafael Espindola uint64_t ExprValue::getSecAddr() const {
617ba5f47eSRafael Espindola   if (Sec)
627ba5f47eSRafael Espindola     return Sec->getOffset(0) + Sec->getOutputSection()->Addr;
637ba5f47eSRafael Espindola   return 0;
647ba5f47eSRafael Espindola }
657ba5f47eSRafael Espindola 
668f1f3c40SMeador Inge template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
675e51f7d2SPetr Hosek   Symbol *Sym;
683dabfc6bSRafael Espindola   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
695e51f7d2SPetr Hosek   std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
705e51f7d2SPetr Hosek       Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
715e51f7d2SPetr Hosek       /*File*/ nullptr);
725e51f7d2SPetr Hosek   Sym->Binding = STB_GLOBAL;
7372dc195dSRafael Espindola   ExprValue Value = Cmd->Expression();
7472dc195dSRafael Espindola   SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
7501aa795fSGeorge Rimar 
7601aa795fSGeorge Rimar   // We want to set symbol values early if we can. This allows us to use symbols
7701aa795fSGeorge Rimar   // as variables in linker scripts. Doing so allows us to write expressions
7801aa795fSGeorge Rimar   // like this: `alignment = 16; . = ALIGN(., alignment)`
7901aa795fSGeorge Rimar   uint64_t SymValue = Value.isAbsolute() ? Value.getValue() : 0;
8080474a26SRui Ueyama   replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility,
8101aa795fSGeorge Rimar                               STT_NOTYPE, SymValue, 0, Sec, nullptr);
828f1f3c40SMeador Inge   return Sym->body();
83ceabe80eSEugene Leviant }
84ceabe80eSEugene Leviant 
85b8dd23f5SRui Ueyama OutputSection *LinkerScript::getOutputSection(const Twine &Loc,
86851dc1e8SGeorge Rimar                                               StringRef Name) {
87851dc1e8SGeorge Rimar   for (OutputSection *Sec : *OutputSections)
88851dc1e8SGeorge Rimar     if (Sec->Name == Name)
89851dc1e8SGeorge Rimar       return Sec;
90851dc1e8SGeorge Rimar 
91a08fa2ecSRui Ueyama   static OutputSection Dummy("", 0, 0);
9272dc195dSRafael Espindola   if (ErrorOnMissingSection)
93851dc1e8SGeorge Rimar     error(Loc + ": undefined section " + Name);
94a08fa2ecSRui Ueyama   return &Dummy;
95851dc1e8SGeorge Rimar }
96851dc1e8SGeorge Rimar 
97d83ce1b4SGeorge Rimar // This function is essentially the same as getOutputSection(Name)->Size,
98d83ce1b4SGeorge Rimar // but it won't print out an error message if a given section is not found.
99d83ce1b4SGeorge Rimar //
100d83ce1b4SGeorge Rimar // Linker script does not create an output section if its content is empty.
101d83ce1b4SGeorge Rimar // We want to allow SIZEOF(.foo) where .foo is a section which happened to
102d83ce1b4SGeorge Rimar // be empty. That is why this function is different from getOutputSection().
103b8dd23f5SRui Ueyama uint64_t LinkerScript::getOutputSectionSize(StringRef Name) {
104d83ce1b4SGeorge Rimar   for (OutputSection *Sec : *OutputSections)
105d83ce1b4SGeorge Rimar     if (Sec->Name == Name)
106d83ce1b4SGeorge Rimar       return Sec->Size;
107d83ce1b4SGeorge Rimar   return 0;
108d83ce1b4SGeorge Rimar }
109d83ce1b4SGeorge Rimar 
110b8dd23f5SRui Ueyama void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
11172dc195dSRafael Espindola   uint64_t Val = E().getValue();
1124cd7352cSRafael Espindola   if (Val < Dot) {
1134cd7352cSRafael Espindola     if (InSec)
1142ee2d2dcSGeorge Rimar       error(Loc + ": unable to move location counter backward for: " +
1152ee2d2dcSGeorge Rimar             CurOutSec->Name);
1164cd7352cSRafael Espindola     else
1172ee2d2dcSGeorge Rimar       error(Loc + ": unable to move location counter backward");
1184cd7352cSRafael Espindola   }
1194cd7352cSRafael Espindola   Dot = Val;
1204cd7352cSRafael Espindola   // Update to location counter means update to section size.
1214cd7352cSRafael Espindola   if (InSec)
1224cd7352cSRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
123679828ffSRafael Espindola }
124679828ffSRafael Espindola 
125679828ffSRafael Espindola // Sets value of a symbol. Two kinds of symbols are processed: synthetic
126679828ffSRafael Espindola // symbols, whose value is an offset from beginning of section and regular
127679828ffSRafael Espindola // symbols whose value is absolute.
128b8dd23f5SRui Ueyama void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
129679828ffSRafael Espindola   if (Cmd->Name == ".") {
1302ee2d2dcSGeorge Rimar     setDot(Cmd->Expression, Cmd->Location, InSec);
1314cd7352cSRafael Espindola     return;
1324cd7352cSRafael Espindola   }
1334cd7352cSRafael Espindola 
134b2b70975SGeorge Rimar   if (!Cmd->Sym)
1358f1f3c40SMeador Inge     return;
1368f1f3c40SMeador Inge 
1375616adf6SRafael Espindola   auto *Sym = cast<DefinedRegular>(Cmd->Sym);
13872dc195dSRafael Espindola   ExprValue V = Cmd->Expression();
13972dc195dSRafael Espindola   if (V.isAbsolute()) {
14072dc195dSRafael Espindola     Sym->Value = V.getValue();
14172dc195dSRafael Espindola   } else {
14272dc195dSRafael Espindola     Sym->Section = V.Sec;
14372dc195dSRafael Espindola     if (Sym->Section->Flags & SHF_ALLOC)
14472dc195dSRafael Espindola       Sym->Value = V.Val;
14572dc195dSRafael Espindola     else
14672dc195dSRafael Espindola       Sym->Value = V.getValue();
147ea590d91SRafael Espindola   }
1488f1f3c40SMeador Inge }
1498f1f3c40SMeador Inge 
150a8dba487SGeorge Rimar static SymbolBody *findSymbol(StringRef S) {
151a8dba487SGeorge Rimar   switch (Config->EKind) {
152a8dba487SGeorge Rimar   case ELF32LEKind:
153a8dba487SGeorge Rimar     return Symtab<ELF32LE>::X->find(S);
154a8dba487SGeorge Rimar   case ELF32BEKind:
155a8dba487SGeorge Rimar     return Symtab<ELF32BE>::X->find(S);
156a8dba487SGeorge Rimar   case ELF64LEKind:
157a8dba487SGeorge Rimar     return Symtab<ELF64LE>::X->find(S);
158a8dba487SGeorge Rimar   case ELF64BEKind:
159a8dba487SGeorge Rimar     return Symtab<ELF64BE>::X->find(S);
160a8dba487SGeorge Rimar   default:
161a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
162a8dba487SGeorge Rimar   }
163a8dba487SGeorge Rimar }
164a8dba487SGeorge Rimar 
165a8dba487SGeorge Rimar static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) {
166a8dba487SGeorge Rimar   switch (Config->EKind) {
167a8dba487SGeorge Rimar   case ELF32LEKind:
168a8dba487SGeorge Rimar     return addRegular<ELF32LE>(Cmd);
169a8dba487SGeorge Rimar   case ELF32BEKind:
170a8dba487SGeorge Rimar     return addRegular<ELF32BE>(Cmd);
171a8dba487SGeorge Rimar   case ELF64LEKind:
172a8dba487SGeorge Rimar     return addRegular<ELF64LE>(Cmd);
173a8dba487SGeorge Rimar   case ELF64BEKind:
174a8dba487SGeorge Rimar     return addRegular<ELF64BE>(Cmd);
175a8dba487SGeorge Rimar   default:
176a8dba487SGeorge Rimar     llvm_unreachable("unknown Config->EKind");
177a8dba487SGeorge Rimar   }
178a8dba487SGeorge Rimar }
179a8dba487SGeorge Rimar 
180b8dd23f5SRui Ueyama void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
1811602421cSRui Ueyama   if (Cmd->Name == ".")
1828f1f3c40SMeador Inge     return;
1838f1f3c40SMeador Inge 
1848f1f3c40SMeador Inge   // If a symbol was in PROVIDE(), we need to define it only when
1858f1f3c40SMeador Inge   // it is a referenced undefined symbol.
186a8dba487SGeorge Rimar   SymbolBody *B = findSymbol(Cmd->Name);
1878f1f3c40SMeador Inge   if (Cmd->Provide && (!B || B->isDefined()))
1888f1f3c40SMeador Inge     return;
1898f1f3c40SMeador Inge 
190a8dba487SGeorge Rimar   Cmd->Sym = addRegularSymbol(Cmd);
191ceabe80eSEugene Leviant }
192ceabe80eSEugene Leviant 
193076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
194076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
195076fe157SGeorge Rimar }
196076fe157SGeorge Rimar 
197076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
198076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
199076fe157SGeorge Rimar }
200076fe157SGeorge Rimar 
201eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
202eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
203eea3114fSGeorge Rimar }
204eea3114fSGeorge Rimar 
205eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) {
206eefa758eSGeorge Rimar   return C->Kind == AssertKind;
207eefa758eSGeorge Rimar }
208eefa758eSGeorge Rimar 
209e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) {
210e38cbab5SGeorge Rimar   return C->Kind == BytesDataKind;
211e38cbab5SGeorge Rimar }
212e38cbab5SGeorge Rimar 
213b4c9b81aSRafael Espindola static StringRef basename(InputSectionBase *S) {
214b4c9b81aSRafael Espindola   if (S->File)
215b4c9b81aSRafael Espindola     return sys::path::filename(S->File->getName());
216e0be2901SRui Ueyama   return "";
217e0be2901SRui Ueyama }
218e0be2901SRui Ueyama 
219b8dd23f5SRui Ueyama bool LinkerScript::shouldKeep(InputSectionBase *S) {
220e0be2901SRui Ueyama   for (InputSectionDescription *ID : Opt.KeptSections)
221e0be2901SRui Ueyama     if (ID->FilePat.match(basename(S)))
222cf43f179SEugene Leviant       for (SectionPattern &P : ID->SectionPatterns)
223f91282e1SRui Ueyama         if (P.SectionPat.match(S->Name))
224eea3114fSGeorge Rimar           return true;
225eea3114fSGeorge Rimar   return false;
226eea3114fSGeorge Rimar }
227eea3114fSGeorge Rimar 
228ea93fe00SRui Ueyama // A helper function for the SORT() command.
229c404d50dSRafael Espindola static std::function<bool(InputSectionBase *, InputSectionBase *)>
230be394db3SGeorge Rimar getComparator(SortSectionPolicy K) {
231be394db3SGeorge Rimar   switch (K) {
232be394db3SGeorge Rimar   case SortSectionPolicy::Alignment:
233ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
234ea93fe00SRui Ueyama       // ">" is not a mistake. Sections with larger alignments are placed
235ea93fe00SRui Ueyama       // before sections with smaller alignments in order to reduce the
236ea93fe00SRui Ueyama       // amount of padding necessary. This is compatible with GNU.
237ea93fe00SRui Ueyama       return A->Alignment > B->Alignment;
238ea93fe00SRui Ueyama     };
239be394db3SGeorge Rimar   case SortSectionPolicy::Name:
240ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
241ea93fe00SRui Ueyama       return A->Name < B->Name;
242ea93fe00SRui Ueyama     };
243be394db3SGeorge Rimar   case SortSectionPolicy::Priority:
244ea93fe00SRui Ueyama     return [](InputSectionBase *A, InputSectionBase *B) {
245ea93fe00SRui Ueyama       return getPriority(A->Name) < getPriority(B->Name);
246ea93fe00SRui Ueyama     };
247be394db3SGeorge Rimar   default:
248be394db3SGeorge Rimar     llvm_unreachable("unknown sort policy");
249be394db3SGeorge Rimar   }
250742c3836SRui Ueyama }
2510702c4e8SGeorge Rimar 
252ea93fe00SRui Ueyama // A helper function for the SORT() command.
253b4c9b81aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase *> Sections,
25406ae6836SGeorge Rimar                              ConstraintKind Kind) {
2558f66df92SGeorge Rimar   if (Kind == ConstraintKind::NoConstraint)
2568f66df92SGeorge Rimar     return true;
2572c7171bfSRui Ueyama 
2582c7171bfSRui Ueyama   bool IsRW = llvm::any_of(Sections, [](InputSectionBase *Sec) {
2592c7171bfSRui Ueyama     return static_cast<InputSectionBase *>(Sec)->Flags & SHF_WRITE;
26006ae6836SGeorge Rimar   });
2612c7171bfSRui Ueyama 
262e746e52cSRafael Espindola   return (IsRW && Kind == ConstraintKind::ReadWrite) ||
263e746e52cSRafael Espindola          (!IsRW && Kind == ConstraintKind::ReadOnly);
26406ae6836SGeorge Rimar }
26506ae6836SGeorge Rimar 
2666a1aa8d9SRafael Espindola static void sortSections(InputSection **Begin, InputSection **End,
267ee924709SRui Ueyama                          SortSectionPolicy K) {
268ee924709SRui Ueyama   if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
26907171f21SGeorge Rimar     std::stable_sort(Begin, End, getComparator(K));
270ee924709SRui Ueyama }
271ee924709SRui Ueyama 
272d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches.
2736a1aa8d9SRafael Espindola std::vector<InputSection *>
27472e107f3SRui Ueyama LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
2756a1aa8d9SRafael Espindola   std::vector<InputSection *> Ret;
2768c6a5aafSRui Ueyama 
27772e107f3SRui Ueyama   // Collects all sections that satisfy constraints of Cmd.
27872e107f3SRui Ueyama   for (const SectionPattern &Pat : Cmd->SectionPatterns) {
27972e107f3SRui Ueyama     size_t SizeBefore = Ret.size();
28072e107f3SRui Ueyama 
28172e107f3SRui Ueyama     for (InputSectionBase *Sec : InputSections) {
28272e107f3SRui Ueyama       if (Sec->Assigned)
2838c6a5aafSRui Ueyama         continue;
28472e107f3SRui Ueyama 
285908a3d34SRafael Espindola       // For -emit-relocs we have to ignore entries like
286908a3d34SRafael Espindola       //   .rela.dyn : { *(.rela.data) }
287908a3d34SRafael Espindola       // which are common because they are in the default bfd script.
28872e107f3SRui Ueyama       if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
289908a3d34SRafael Espindola         continue;
2908c6a5aafSRui Ueyama 
29172e107f3SRui Ueyama       StringRef Filename = basename(Sec);
29272e107f3SRui Ueyama       if (!Cmd->FilePat.match(Filename) ||
29372e107f3SRui Ueyama           Pat.ExcludedFilePat.match(Filename) ||
29472e107f3SRui Ueyama           !Pat.SectionPat.match(Sec->Name))
295e0be2901SRui Ueyama         continue;
29672e107f3SRui Ueyama 
2976a1aa8d9SRafael Espindola       Ret.push_back(cast<InputSection>(Sec));
29872e107f3SRui Ueyama       Sec->Assigned = true;
299f94efdddSRui Ueyama     }
300d3190795SRafael Espindola 
301ee924709SRui Ueyama     // Sort sections as instructed by SORT-family commands and --sort-section
302ee924709SRui Ueyama     // option. Because SORT-family commands can be nested at most two depth
303ee924709SRui Ueyama     // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
304ee924709SRui Ueyama     // line option is respected even if a SORT command is given, the exact
305ee924709SRui Ueyama     // behavior we have here is a bit complicated. Here are the rules.
306ee924709SRui Ueyama     //
307ee924709SRui Ueyama     // 1. If two SORT commands are given, --sort-section is ignored.
308ee924709SRui Ueyama     // 2. If one SORT command is given, and if it is not SORT_NONE,
309ee924709SRui Ueyama     //    --sort-section is handled as an inner SORT command.
310ee924709SRui Ueyama     // 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
311ee924709SRui Ueyama     // 4. If no SORT command is given, sort according to --sort-section.
3126a1aa8d9SRafael Espindola     InputSection **Begin = Ret.data() + SizeBefore;
3136a1aa8d9SRafael Espindola     InputSection **End = Ret.data() + Ret.size();
31407171f21SGeorge Rimar     if (Pat.SortOuter != SortSectionPolicy::None) {
31507171f21SGeorge Rimar       if (Pat.SortInner == SortSectionPolicy::Default)
31607171f21SGeorge Rimar         sortSections(Begin, End, Config->SortSection);
317ee924709SRui Ueyama       else
31807171f21SGeorge Rimar         sortSections(Begin, End, Pat.SortInner);
31907171f21SGeorge Rimar       sortSections(Begin, End, Pat.SortOuter);
32007171f21SGeorge Rimar     }
321ee924709SRui Ueyama   }
32272e107f3SRui Ueyama   return Ret;
323be94e1b6SRafael Espindola }
324be94e1b6SRafael Espindola 
325b8dd23f5SRui Ueyama void LinkerScript::discard(ArrayRef<InputSectionBase *> V) {
326b4c9b81aSRafael Espindola   for (InputSectionBase *S : V) {
327be94e1b6SRafael Espindola     S->Live = false;
328503206c5SGeorge Rimar     if (S == InX::ShStrTab)
329ecbfd871SRafael Espindola       error("discarding .shstrtab section is not allowed");
330647c1685SGeorge Rimar     discard(S->DependentSections);
331be94e1b6SRafael Espindola   }
332be94e1b6SRafael Espindola }
333be94e1b6SRafael Espindola 
334b4c9b81aSRafael Espindola std::vector<InputSectionBase *>
335b8dd23f5SRui Ueyama LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) {
336b4c9b81aSRafael Espindola   std::vector<InputSectionBase *> Ret;
337e7f912cdSRui Ueyama 
3388f99f73cSRui Ueyama   for (BaseCommand *Base : OutCmd.Commands) {
3398f99f73cSRui Ueyama     auto *Cmd = dyn_cast<InputSectionDescription>(Base);
3407c3ff2ebSRafael Espindola     if (!Cmd)
3410b9ce6a4SRui Ueyama       continue;
34272e107f3SRui Ueyama 
34372e107f3SRui Ueyama     Cmd->Sections = computeInputSections(Cmd);
344e4c8b9b7SRafael Espindola     Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end());
3450b9ce6a4SRui Ueyama   }
346e71a3f8aSRafael Espindola 
3470b9ce6a4SRui Ueyama   return Ret;
3480b9ce6a4SRui Ueyama }
3490b9ce6a4SRui Ueyama 
350b8dd23f5SRui Ueyama void LinkerScript::processCommands(OutputSectionFactory &Factory) {
3515616adf6SRafael Espindola   // A symbol can be assigned before any section is mentioned in the linker
3525616adf6SRafael Espindola   // script. In an DSO, the symbol values are addresses, so the only important
3535616adf6SRafael Espindola   // section values are:
3545616adf6SRafael Espindola   // * SHN_UNDEF
3555616adf6SRafael Espindola   // * SHN_ABS
3565616adf6SRafael Espindola   // * Any value meaning a regular section.
3575616adf6SRafael Espindola   // To handle that, create a dummy aether section that fills the void before
3585616adf6SRafael Espindola   // the linker scripts switches to another section. It has an index of one
3595616adf6SRafael Espindola   // which will map to whatever the first actual section is.
3605616adf6SRafael Espindola   Aether = make<OutputSection>("", 0, SHF_ALLOC);
3615616adf6SRafael Espindola   Aether->SectionIndex = 1;
3625616adf6SRafael Espindola   CurOutSec = Aether;
36349592cf6SRafael Espindola   Dot = 0;
3645616adf6SRafael Espindola 
36592a5ba6dSRui Ueyama   for (size_t I = 0; I < Opt.Commands.size(); ++I) {
3660b1b695aSRui Ueyama     // Handle symbol assignments outside of any output section.
36792a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Opt.Commands[I])) {
3684cd7352cSRafael Espindola       addSymbol(Cmd);
3692ab5f73dSRui Ueyama       continue;
3702ab5f73dSRui Ueyama     }
3710b1b695aSRui Ueyama 
37292a5ba6dSRui Ueyama     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I])) {
373b4c9b81aSRafael Espindola       std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
3747bd37870SRafael Espindola 
3750b1b695aSRui Ueyama       // The output section name `/DISCARD/' is special.
3760b1b695aSRui Ueyama       // Any input section assigned to it is discarded.
37748c3f1ceSRui Ueyama       if (Cmd->Name == "/DISCARD/") {
3787bd37870SRafael Espindola         discard(V);
37948c3f1ceSRui Ueyama         continue;
38048c3f1ceSRui Ueyama       }
3810b9ce6a4SRui Ueyama 
3820b1b695aSRui Ueyama       // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
3830b1b695aSRui Ueyama       // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
3840b1b695aSRui Ueyama       // sections satisfy a given constraint. If not, a directive is handled
38507d7c42cSGeorge Rimar       // as if it wasn't present from the beginning.
3860b1b695aSRui Ueyama       //
3870b1b695aSRui Ueyama       // Because we'll iterate over Commands many more times, the easiest
38807d7c42cSGeorge Rimar       // way to "make it as if it wasn't present" is to just remove it.
389f7f0d088SGeorge Rimar       if (!matchConstraints(V, Cmd->Constraint)) {
390b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
391f94efdddSRui Ueyama           S->Assigned = false;
39292a5ba6dSRui Ueyama         Opt.Commands.erase(Opt.Commands.begin() + I);
39307d7c42cSGeorge Rimar         --I;
3947c3ff2ebSRafael Espindola         continue;
3957c3ff2ebSRafael Espindola       }
3967c3ff2ebSRafael Espindola 
3970b1b695aSRui Ueyama       // A directive may contain symbol definitions like this:
3980b1b695aSRui Ueyama       // ".foo : { ...; bar = .; }". Handle them.
3998f99f73cSRui Ueyama       for (BaseCommand *Base : Cmd->Commands)
4008f99f73cSRui Ueyama         if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
4014cd7352cSRafael Espindola           addSymbol(OutCmd);
4027c3ff2ebSRafael Espindola 
4030b1b695aSRui Ueyama       // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
4040b1b695aSRui Ueyama       // is given, input sections are aligned to that value, whether the
4050b1b695aSRui Ueyama       // given value is larger or smaller than the original section alignment.
4060b1b695aSRui Ueyama       if (Cmd->SubalignExpr) {
40772dc195dSRafael Espindola         uint32_t Subalign = Cmd->SubalignExpr().getValue();
408b4c9b81aSRafael Espindola         for (InputSectionBase *S : V)
4090b1b695aSRui Ueyama           S->Alignment = Subalign;
41020d03194SEugene Leviant       }
4110b1b695aSRui Ueyama 
4120b1b695aSRui Ueyama       // Add input sections to an output section.
413d86a4e50SGeorge Rimar       for (InputSectionBase *S : V)
4144f013bb3SRafael Espindola         Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
415660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
416660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX);
417660c9ab9SRafael Espindola         Sec->SectionIndex = I;
418d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
419660c9ab9SRafael Espindola       }
42048c3f1ceSRui Ueyama     }
4214aa2ef5bSRafael Espindola   }
4225616adf6SRafael Espindola   CurOutSec = nullptr;
423db24d9c3SGeorge Rimar }
424e63d81bdSEugene Leviant 
42502ed7575SRafael Espindola void LinkerScript::fabricateDefaultCommands() {
426cbfe9e94SPeter Smith   std::vector<BaseCommand *> Commands;
427cbfe9e94SPeter Smith 
428cbfe9e94SPeter Smith   // Define start address
42902ed7575SRafael Espindola   uint64_t StartAddr = Config->ImageBase + elf::getHeaderSize();
430cbfe9e94SPeter Smith 
431c60b4510SPeter Smith   // The Sections with -T<section> have been sorted in order of ascending
432c60b4510SPeter Smith   // address. We must lower StartAddr if the lowest -T<section address> as
433c60b4510SPeter Smith   // calls to setDot() must be monotonically increasing.
434c60b4510SPeter Smith   for (auto& KV : Config->SectionStartMap)
435c60b4510SPeter Smith     StartAddr = std::min(StartAddr, KV.second);
436c60b4510SPeter Smith 
437cbfe9e94SPeter Smith   Commands.push_back(
438cbfe9e94SPeter Smith       make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
439cbfe9e94SPeter Smith 
440cbfe9e94SPeter Smith   // For each OutputSection that needs a VA fabricate an OutputSectionCommand
441cbfe9e94SPeter Smith   // with an InputSectionDescription describing the InputSections
442cbfe9e94SPeter Smith   for (OutputSection *Sec : *OutputSections) {
443c60b4510SPeter Smith     auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
444c60b4510SPeter Smith     OSCmd->Sec = Sec;
445d7dc2258SRafael Espindola     SecToCommand[Sec] = OSCmd;
446c60b4510SPeter Smith 
447c60b4510SPeter Smith     // Prefer user supplied address over additional alignment constraint
448cbfe9e94SPeter Smith     auto I = Config->SectionStartMap.find(Sec->Name);
449cbfe9e94SPeter Smith     if (I != Config->SectionStartMap.end())
450cbfe9e94SPeter Smith       Commands.push_back(
451cbfe9e94SPeter Smith           make<SymbolAssignment>(".", [=] { return I->second; }, ""));
452c60b4510SPeter Smith     else if (Sec->PageAlign)
453cbfe9e94SPeter Smith       OSCmd->AddrExpr = [=] {
454cbfe9e94SPeter Smith         return alignTo(Script->getDot(), Config->MaxPageSize);
455cbfe9e94SPeter Smith       };
456c60b4510SPeter Smith 
457cbfe9e94SPeter Smith     Commands.push_back(OSCmd);
458cbfe9e94SPeter Smith     if (Sec->Sections.size()) {
459cbfe9e94SPeter Smith       auto *ISD = make<InputSectionDescription>("");
460cbfe9e94SPeter Smith       OSCmd->Commands.push_back(ISD);
461cbfe9e94SPeter Smith       for (InputSection *ISec : Sec->Sections) {
462cbfe9e94SPeter Smith         ISD->Sections.push_back(ISec);
463cbfe9e94SPeter Smith         ISec->Assigned = true;
464cbfe9e94SPeter Smith       }
465cbfe9e94SPeter Smith     }
466cbfe9e94SPeter Smith   }
467cbfe9e94SPeter Smith   // SECTIONS commands run before other non SECTIONS commands
468cbfe9e94SPeter Smith   Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end());
469cbfe9e94SPeter Smith   Opt.Commands = std::move(Commands);
470cbfe9e94SPeter Smith }
471cbfe9e94SPeter Smith 
4720b1b695aSRui Ueyama // Add sections that didn't match any sections command.
473b8dd23f5SRui Ueyama void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
4744f013bb3SRafael Espindola   for (InputSectionBase *S : InputSections) {
4754f013bb3SRafael Espindola     if (!S->Live || S->OutSec)
4764f013bb3SRafael Espindola       continue;
4774f013bb3SRafael Espindola     StringRef Name = getOutputSectionName(S->Name);
4784f013bb3SRafael Espindola     auto I = std::find_if(
4794f013bb3SRafael Espindola         Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
4804f013bb3SRafael Espindola           if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
4814f013bb3SRafael Espindola             return Cmd->Name == Name;
4824f013bb3SRafael Espindola           return false;
4834f013bb3SRafael Espindola         });
484de8d9897SRafael Espindola     if (I == Opt.Commands.end()) {
4854f013bb3SRafael Espindola       Factory.addInputSec(S, Name);
486de8d9897SRafael Espindola     } else {
487de8d9897SRafael Espindola       auto *Cmd = cast<OutputSectionCommand>(*I);
488de8d9897SRafael Espindola       Factory.addInputSec(S, Name, Cmd->Sec);
489660c9ab9SRafael Espindola       if (OutputSection *Sec = Cmd->Sec) {
490d7dc2258SRafael Espindola         SecToCommand[Sec] = Cmd;
491660c9ab9SRafael Espindola         unsigned Index = std::distance(Opt.Commands.begin(), I);
492660c9ab9SRafael Espindola         assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index);
493660c9ab9SRafael Espindola         Sec->SectionIndex = Index;
494660c9ab9SRafael Espindola       }
495de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
4966a1aa8d9SRafael Espindola       ISD->Sections.push_back(cast<InputSection>(S));
497de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
498de8d9897SRafael Espindola     }
4994f013bb3SRafael Espindola   }
500e63d81bdSEugene Leviant }
501e63d81bdSEugene Leviant 
5027c4eafa3SRafael Espindola uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
5037c4eafa3SRafael Espindola   bool IsTbss = (CurOutSec->Flags & SHF_TLS) && CurOutSec->Type == SHT_NOBITS;
5047c4eafa3SRafael Espindola   uint64_t Start = IsTbss ? Dot + ThreadBssOffset : Dot;
5057c4eafa3SRafael Espindola   Start = alignTo(Start, Align);
5067c4eafa3SRafael Espindola   uint64_t End = Start + Size;
5077c4eafa3SRafael Espindola 
5087c4eafa3SRafael Espindola   if (IsTbss)
5097c4eafa3SRafael Espindola     ThreadBssOffset = End - Dot;
5107c4eafa3SRafael Espindola   else
5117c4eafa3SRafael Espindola     Dot = End;
5127c4eafa3SRafael Espindola   return End;
513a940e539SRafael Espindola }
514a940e539SRafael Espindola 
515b8dd23f5SRui Ueyama void LinkerScript::output(InputSection *S) {
5167c4eafa3SRafael Espindola   uint64_t Pos = advance(S->getSize(), S->Alignment);
5177c4eafa3SRafael Espindola   S->OutSecOff = Pos - S->getSize() - CurOutSec->Addr;
518d3190795SRafael Espindola 
519d3190795SRafael Espindola   // Update output section size after adding each section. This is so that
520d3190795SRafael Espindola   // SIZEOF works correctly in the case below:
521d3190795SRafael Espindola   // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
52204a2e348SRafael Espindola   CurOutSec->Size = Pos - CurOutSec->Addr;
523d3190795SRafael Espindola 
524b889744eSMeador Inge   // If there is a memory region associated with this input section, then
525b889744eSMeador Inge   // place the section in that region and update the region index.
526b889744eSMeador Inge   if (CurMemRegion) {
527b889744eSMeador Inge     CurMemRegion->Offset += CurOutSec->Size;
528b889744eSMeador Inge     uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin;
529b889744eSMeador Inge     if (CurSize > CurMemRegion->Length) {
530b889744eSMeador Inge       uint64_t OverflowAmt = CurSize - CurMemRegion->Length;
531b889744eSMeador Inge       error("section '" + CurOutSec->Name + "' will not fit in region '" +
532b889744eSMeador Inge             CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) +
533b889744eSMeador Inge             " bytes");
534b889744eSMeador Inge     }
535b889744eSMeador Inge   }
5362de509c3SRui Ueyama }
537ceabe80eSEugene Leviant 
538b8dd23f5SRui Ueyama void LinkerScript::switchTo(OutputSection *Sec) {
539d3190795SRafael Espindola   if (CurOutSec == Sec)
540d3190795SRafael Espindola     return;
541d3190795SRafael Espindola 
542d3190795SRafael Espindola   CurOutSec = Sec;
5437c4eafa3SRafael Espindola   CurOutSec->Addr = advance(0, CurOutSec->Alignment);
544b71d6f7aSEugene Leviant 
545b71d6f7aSEugene Leviant   // If neither AT nor AT> is specified for an allocatable section, the linker
546b71d6f7aSEugene Leviant   // will set the LMA such that the difference between VMA and LMA for the
547b71d6f7aSEugene Leviant   // section is the same as the preceding output section in the same region
548b71d6f7aSEugene Leviant   // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
54921467876SGeorge Rimar   if (LMAOffset)
55029c1afb8SRafael Espindola     CurOutSec->LMAOffset = LMAOffset();
551d3190795SRafael Espindola }
552d3190795SRafael Espindola 
553b8dd23f5SRui Ueyama void LinkerScript::process(BaseCommand &Base) {
5542e081a4fSRui Ueyama   // This handles the assignments to symbol or to the dot.
5552e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<SymbolAssignment>(&Base)) {
5562e081a4fSRui Ueyama     assignSymbol(Cmd, true);
557d3190795SRafael Espindola     return;
55897403d15SEugene Leviant   }
559e38cbab5SGeorge Rimar 
560e38cbab5SGeorge Rimar   // Handle BYTE(), SHORT(), LONG(), or QUAD().
5612e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) {
5622e081a4fSRui Ueyama     Cmd->Offset = Dot - CurOutSec->Addr;
5632e081a4fSRui Ueyama     Dot += Cmd->Size;
56404a2e348SRafael Espindola     CurOutSec->Size = Dot - CurOutSec->Addr;
565e38cbab5SGeorge Rimar     return;
566e38cbab5SGeorge Rimar   }
567e38cbab5SGeorge Rimar 
5682e081a4fSRui Ueyama   // Handle ASSERT().
5692e081a4fSRui Ueyama   if (auto *Cmd = dyn_cast<AssertCommand>(&Base)) {
5702e081a4fSRui Ueyama     Cmd->Expression();
571b2d99d6aSMeador Inge     return;
572b2d99d6aSMeador Inge   }
573b2d99d6aSMeador Inge 
5742e081a4fSRui Ueyama   // Handle a single input section description command.
5752e081a4fSRui Ueyama   // It calculates and assigns the offsets for each section and also
576e38cbab5SGeorge Rimar   // updates the output section size.
5772e081a4fSRui Ueyama   auto &Cmd = cast<InputSectionDescription>(Base);
5782e081a4fSRui Ueyama   for (InputSectionBase *Sec : Cmd.Sections) {
5793fb5a6dcSGeorge Rimar     // We tentatively added all synthetic sections at the beginning and removed
5803fb5a6dcSGeorge Rimar     // empty ones afterwards (because there is no way to know whether they were
5813fb5a6dcSGeorge Rimar     // going be empty or not other than actually running linker scripts.)
5823fb5a6dcSGeorge Rimar     // We need to ignore remains of empty sections.
5832e081a4fSRui Ueyama     if (auto *S = dyn_cast<SyntheticSection>(Sec))
5842e081a4fSRui Ueyama       if (S->empty())
5853fb5a6dcSGeorge Rimar         continue;
5863fb5a6dcSGeorge Rimar 
5872e081a4fSRui Ueyama     if (!Sec->Live)
58878ef645fSGeorge Rimar       continue;
589de8d9897SRafael Espindola     assert(CurOutSec == Sec->OutSec);
5902e081a4fSRui Ueyama     output(cast<InputSection>(Sec));
591ceabe80eSEugene Leviant   }
592ceabe80eSEugene Leviant }
593ceabe80eSEugene Leviant 
594b889744eSMeador Inge // This function searches for a memory region to place the given output
595b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is
596b889744eSMeador Inge // returned. Otherwise, a nullptr is returned.
5971902b337SRafael Espindola MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd) {
598b889744eSMeador Inge   // If a memory region name was specified in the output section command,
599b889744eSMeador Inge   // then try to find that region first.
600b889744eSMeador Inge   if (!Cmd->MemoryRegionName.empty()) {
601b889744eSMeador Inge     auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
602b889744eSMeador Inge     if (It != Opt.MemoryRegions.end())
603b889744eSMeador Inge       return &It->second;
604b889744eSMeador Inge     error("memory region '" + Cmd->MemoryRegionName + "' not declared");
605b889744eSMeador Inge     return nullptr;
606b889744eSMeador Inge   }
607b889744eSMeador Inge 
608d7c5400fSRui Ueyama   // If at least one memory region is defined, all sections must
609d7c5400fSRui Ueyama   // belong to some memory region. Otherwise, we don't need to do
610d7c5400fSRui Ueyama   // anything for memory regions.
611cc400cc8SRui Ueyama   if (Opt.MemoryRegions.empty())
612b889744eSMeador Inge     return nullptr;
613b889744eSMeador Inge 
6141902b337SRafael Espindola   OutputSection *Sec = Cmd->Sec;
615b889744eSMeador Inge   // See if a region can be found by matching section flags.
6162e081a4fSRui Ueyama   for (auto &Pair : Opt.MemoryRegions) {
6172e081a4fSRui Ueyama     MemoryRegion &M = Pair.second;
6182e081a4fSRui Ueyama     if ((M.Flags & Sec->Flags) && (M.NegFlags & Sec->Flags) == 0)
6192e081a4fSRui Ueyama       return &M;
620b889744eSMeador Inge   }
621b889744eSMeador Inge 
622b889744eSMeador Inge   // Otherwise, no suitable region was found.
623b889744eSMeador Inge   if (Sec->Flags & SHF_ALLOC)
624b889744eSMeador Inge     error("no memory region specified for section '" + Sec->Name + "'");
625b889744eSMeador Inge   return nullptr;
626b889744eSMeador Inge }
627b889744eSMeador Inge 
6280b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section
6290b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }").
630b8dd23f5SRui Ueyama void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) {
6319b980095SRafael Espindola   OutputSection *Sec = Cmd->Sec;
6322b074553SRafael Espindola   if (!Sec)
633d3190795SRafael Espindola     return;
634b889744eSMeador Inge 
635cba41013SRui Ueyama   if (Cmd->AddrExpr && (Sec->Flags & SHF_ALLOC))
636d379f735SRui Ueyama     setDot(Cmd->AddrExpr, Cmd->Location, false);
637679828ffSRafael Espindola 
6385784e96fSEugene Leviant   if (Cmd->LMAExpr) {
6390c1c8085SGeorge Rimar     uint64_t D = Dot;
64072dc195dSRafael Espindola     LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; };
6415784e96fSEugene Leviant   }
6425784e96fSEugene Leviant 
643feed7506SRafael Espindola   CurMemRegion = Cmd->MemRegion;
644b889744eSMeador Inge   if (CurMemRegion)
645b889744eSMeador Inge     Dot = CurMemRegion->Offset;
646b889744eSMeador Inge   switchTo(Sec);
6470b1b695aSRui Ueyama 
648d86a4e50SGeorge Rimar   // We do not support custom layout for compressed debug sectons.
649d86a4e50SGeorge Rimar   // At this point we already know their size and have compressed content.
650d86a4e50SGeorge Rimar   if (CurOutSec->Flags & SHF_COMPRESSED)
651d86a4e50SGeorge Rimar     return;
652d86a4e50SGeorge Rimar 
653de8d9897SRafael Espindola   for (BaseCommand *C : Cmd->Commands)
654de8d9897SRafael Espindola     process(*C);
655d3190795SRafael Espindola }
656d3190795SRafael Espindola 
657b8dd23f5SRui Ueyama void LinkerScript::removeEmptyCommands() {
6586d38e4dbSRafael Espindola   // It is common practice to use very generic linker scripts. So for any
6596d38e4dbSRafael Espindola   // given run some of the output sections in the script will be empty.
6606d38e4dbSRafael Espindola   // We could create corresponding empty output sections, but that would
6616d38e4dbSRafael Espindola   // clutter the output.
6626d38e4dbSRafael Espindola   // We instead remove trivially empty sections. The bfd linker seems even
6636d38e4dbSRafael Espindola   // more aggressive at removing them.
6646d38e4dbSRafael Espindola   auto Pos = std::remove_if(
6658f99f73cSRui Ueyama       Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
6668f99f73cSRui Ueyama         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
6674f013bb3SRafael Espindola           return std::find(OutputSections->begin(), OutputSections->end(),
6684f013bb3SRafael Espindola                            Cmd->Sec) == OutputSections->end();
6690b1b695aSRui Ueyama         return false;
6706d38e4dbSRafael Espindola       });
6716d38e4dbSRafael Espindola   Opt.Commands.erase(Pos, Opt.Commands.end());
67207fe6129SRafael Espindola }
67307fe6129SRafael Espindola 
6746a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
6758f99f73cSRui Ueyama   for (BaseCommand *Base : Cmd.Commands)
6768f99f73cSRui Ueyama     if (!isa<InputSectionDescription>(*Base))
6776a53737cSRafael Espindola       return false;
6786a53737cSRafael Espindola   return true;
6796a53737cSRafael Espindola }
6806d38e4dbSRafael Espindola 
681b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsBeforeSorting() {
6829546fffbSRafael Espindola   // If the output section contains only symbol assignments, create a
6839546fffbSRafael Espindola   // corresponding output section. The bfd linker seems to only create them if
6849546fffbSRafael Espindola   // '.' is assigned to, but creating these section should not have any bad
6859546fffbSRafael Espindola   // consequeces and gives us a section to put the symbol in.
6860c1c8085SGeorge Rimar   uint64_t Flags = SHF_ALLOC;
687660c9ab9SRafael Espindola 
688660c9ab9SRafael Espindola   for (int I = 0, E = Opt.Commands.size(); I != E; ++I) {
689660c9ab9SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
6909546fffbSRafael Espindola     if (!Cmd)
6919546fffbSRafael Espindola       continue;
6924f013bb3SRafael Espindola     if (OutputSection *Sec = Cmd->Sec) {
6932b074553SRafael Espindola       Flags = Sec->Flags;
6949546fffbSRafael Espindola       continue;
6959546fffbSRafael Espindola     }
6969546fffbSRafael Espindola 
6976a53737cSRafael Espindola     if (isAllSectionDescription(*Cmd))
6986a53737cSRafael Espindola       continue;
6996a53737cSRafael Espindola 
700*fd0c844fSDmitry Mikulin     auto *OutSec = make<OutputSection>(Cmd->Name, SHT_PROGBITS, Flags);
701660c9ab9SRafael Espindola     OutSec->SectionIndex = I;
7029546fffbSRafael Espindola     OutputSections->push_back(OutSec);
7039b980095SRafael Espindola     Cmd->Sec = OutSec;
704d7dc2258SRafael Espindola     SecToCommand[OutSec] = Cmd;
7059546fffbSRafael Espindola   }
706f7a17448SRafael Espindola }
707f7a17448SRafael Espindola 
708b8dd23f5SRui Ueyama void LinkerScript::adjustSectionsAfterSorting() {
709f7a17448SRafael Espindola   placeOrphanSections();
710f7a17448SRafael Espindola 
711feed7506SRafael Espindola   // Try and find an appropriate memory region to assign offsets in.
712d1960dc0SRafael Espindola   for (BaseCommand *Base : Opt.Commands) {
713d1960dc0SRafael Espindola     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) {
714feed7506SRafael Espindola       Cmd->MemRegion = findMemoryRegion(Cmd);
715d1960dc0SRafael Espindola       // Handle align (e.g. ".foo : ALIGN(16) { ... }").
716d1960dc0SRafael Espindola       if (Cmd->AlignExpr)
717d1960dc0SRafael Espindola 	Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue());
718d1960dc0SRafael Espindola     }
719d1960dc0SRafael Espindola   }
720feed7506SRafael Espindola 
721f7a17448SRafael Espindola   // If output section command doesn't specify any segments,
722f7a17448SRafael Espindola   // and we haven't previously assigned any section to segment,
723f7a17448SRafael Espindola   // then we simply assign section to the very first load segment.
724f7a17448SRafael Espindola   // Below is an example of such linker script:
725f7a17448SRafael Espindola   // PHDRS { seg PT_LOAD; }
726f7a17448SRafael Espindola   // SECTIONS { .aaa : { *(.aaa) } }
727f7a17448SRafael Espindola   std::vector<StringRef> DefPhdrs;
728f7a17448SRafael Espindola   auto FirstPtLoad =
729f7a17448SRafael Espindola       std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(),
730f7a17448SRafael Espindola                    [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; });
731f7a17448SRafael Espindola   if (FirstPtLoad != Opt.PhdrsCommands.end())
732f7a17448SRafael Espindola     DefPhdrs.push_back(FirstPtLoad->Name);
733f7a17448SRafael Espindola 
734f7a17448SRafael Espindola   // Walk the commands and propagate the program headers to commands that don't
735f7a17448SRafael Espindola   // explicitly specify them.
7368f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
7378f99f73cSRui Ueyama     auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
738f7a17448SRafael Espindola     if (!Cmd)
739f7a17448SRafael Espindola       continue;
7408f99f73cSRui Ueyama 
741f7a17448SRafael Espindola     if (Cmd->Phdrs.empty())
742f7a17448SRafael Espindola       Cmd->Phdrs = DefPhdrs;
743f7a17448SRafael Espindola     else
744f7a17448SRafael Espindola       DefPhdrs = Cmd->Phdrs;
745f7a17448SRafael Espindola   }
7466a53737cSRafael Espindola 
7476a53737cSRafael Espindola   removeEmptyCommands();
7489546fffbSRafael Espindola }
7499546fffbSRafael Espindola 
75015c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments
75115c57951SRafael Espindola // so that an orphan after
75215c57951SRafael Espindola //   begin_foo = .;
75315c57951SRafael Espindola //   foo : { *(foo) }
75415c57951SRafael Espindola //   end_foo = .;
75515c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols.
75615c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the
75715c57951SRafael Espindola // one in charge of deciding the order of the sections.
75815c57951SRafael Espindola // We don't want to go over alignments, since doing so in
75915c57951SRafael Espindola //  rx_sec : { *(rx_sec) }
76015c57951SRafael Espindola //  . = ALIGN(0x1000);
76115c57951SRafael Espindola //  /* The RW PT_LOAD starts here*/
76215c57951SRafael Espindola //  rw_sec : { *(rw_sec) }
76315c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned.
7644e1e88e3SRui Ueyama static bool shouldSkip(BaseCommand *Cmd) {
76515c57951SRafael Espindola   if (isa<OutputSectionCommand>(Cmd))
76615c57951SRafael Espindola     return false;
7674e1e88e3SRui Ueyama   if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd))
7685fcc99c2SRafael Espindola     return Assign->Name != ".";
7694e1e88e3SRui Ueyama   return true;
77015c57951SRafael Espindola }
77115c57951SRafael Espindola 
7726697ec29SRui Ueyama // Orphan sections are sections present in the input files which are
7736697ec29SRui Ueyama // not explicitly placed into the output file by the linker script.
7746697ec29SRui Ueyama //
7756697ec29SRui Ueyama // When the control reaches this function, Opt.Commands contains
7766697ec29SRui Ueyama // output section commands for non-orphan sections only. This function
77781cb7107SRui Ueyama // adds new elements for orphan sections so that all sections are
77881cb7107SRui Ueyama // explicitly handled by Opt.Commands.
7796697ec29SRui Ueyama //
7806697ec29SRui Ueyama // Writer<ELFT>::sortSections has already sorted output sections.
7816697ec29SRui Ueyama // What we need to do is to scan OutputSections vector and
7826697ec29SRui Ueyama // Opt.Commands in parallel to find orphan sections. If there is an
7836697ec29SRui Ueyama // output section that doesn't have a corresponding entry in
7846697ec29SRui Ueyama // Opt.Commands, we will insert a new entry to Opt.Commands.
7856697ec29SRui Ueyama //
7866697ec29SRui Ueyama // There is some ambiguity as to where exactly a new entry should be
7876697ec29SRui Ueyama // inserted, because Opt.Commands contains not only output section
78881cb7107SRui Ueyama // commands but also other types of commands such as symbol assignment
7896697ec29SRui Ueyama // expressions. There's no correct answer here due to the lack of the
7906697ec29SRui Ueyama // formal specification of the linker script. We use heuristics to
7916697ec29SRui Ueyama // determine whether a new output command should be added before or
7926697ec29SRui Ueyama // after another commands. For the details, look at shouldSkip
7936697ec29SRui Ueyama // function.
794b8dd23f5SRui Ueyama void LinkerScript::placeOrphanSections() {
795aab6d5c5SRafael Espindola   // The OutputSections are already in the correct order.
796aab6d5c5SRafael Espindola   // This loops creates or moves commands as needed so that they are in the
797aab6d5c5SRafael Espindola   // correct order.
798aab6d5c5SRafael Espindola   int CmdIndex = 0;
7995fcc99c2SRafael Espindola 
8005fcc99c2SRafael Espindola   // As a horrible special case, skip the first . assignment if it is before any
8015fcc99c2SRafael Espindola   // section. We do this because it is common to set a load address by starting
8025fcc99c2SRafael Espindola   // the script with ". = 0xabcd" and the expectation is that every section is
8035fcc99c2SRafael Espindola   // after that.
8044e1e88e3SRui Ueyama   auto FirstSectionOrDotAssignment =
8054e1e88e3SRui Ueyama       std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
8064e1e88e3SRui Ueyama                    [](BaseCommand *Cmd) { return !shouldSkip(Cmd); });
8075fcc99c2SRafael Espindola   if (FirstSectionOrDotAssignment != Opt.Commands.end()) {
8085fcc99c2SRafael Espindola     CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin();
8095fcc99c2SRafael Espindola     if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
8105fcc99c2SRafael Espindola       ++CmdIndex;
8115fcc99c2SRafael Espindola   }
8125fcc99c2SRafael Espindola 
81324e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
81440849419SRafael Espindola     StringRef Name = Sec->Name;
815aab6d5c5SRafael Espindola 
816aab6d5c5SRafael Espindola     // Find the last spot where we can insert a command and still get the
81715c57951SRafael Espindola     // correct result.
818aab6d5c5SRafael Espindola     auto CmdIter = Opt.Commands.begin() + CmdIndex;
819aab6d5c5SRafael Espindola     auto E = Opt.Commands.end();
8204e1e88e3SRui Ueyama     while (CmdIter != E && shouldSkip(*CmdIter)) {
821aab6d5c5SRafael Espindola       ++CmdIter;
822aab6d5c5SRafael Espindola       ++CmdIndex;
823aab6d5c5SRafael Espindola     }
824aab6d5c5SRafael Espindola 
825de8d9897SRafael Espindola     // If there is no command corresponding to this output section,
826de8d9897SRafael Espindola     // create one and put a InputSectionDescription in it so that both
827de8d9897SRafael Espindola     // representations agree on which input sections to use.
828fa948c72SRafael Espindola     OutputSectionCommand *Cmd = getCmd(Sec);
829fa948c72SRafael Espindola     if (!Cmd) {
830fa948c72SRafael Espindola       Cmd = make<OutputSectionCommand>(Name);
8319b980095SRafael Espindola       Opt.Commands.insert(CmdIter, Cmd);
832aab6d5c5SRafael Espindola       ++CmdIndex;
833de8d9897SRafael Espindola 
834de8d9897SRafael Espindola       Cmd->Sec = Sec;
835d7dc2258SRafael Espindola       SecToCommand[Sec] = Cmd;
836de8d9897SRafael Espindola       auto *ISD = make<InputSectionDescription>("");
837de8d9897SRafael Espindola       for (InputSection *IS : Sec->Sections)
838de8d9897SRafael Espindola         ISD->Sections.push_back(IS);
839de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
840de8d9897SRafael Espindola 
84115c57951SRafael Espindola       continue;
84215c57951SRafael Espindola     }
84315c57951SRafael Espindola 
84415c57951SRafael Espindola     // Continue from where we found it.
845fa948c72SRafael Espindola     while (*CmdIter != Cmd) {
846fa948c72SRafael Espindola       ++CmdIter;
847fa948c72SRafael Espindola       ++CmdIndex;
848fa948c72SRafael Espindola     }
849fa948c72SRafael Espindola     ++CmdIndex;
850652852c5SGeorge Rimar   }
851337f903cSRafael Espindola }
852337f903cSRafael Espindola 
853b8dd23f5SRui Ueyama void LinkerScript::processNonSectionCommands() {
8548f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
8558f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
856d379f735SRui Ueyama       assignSymbol(Cmd, false);
8578f99f73cSRui Ueyama     else if (auto *Cmd = dyn_cast<AssertCommand>(Base))
85802ad516bSPetr Hosek       Cmd->Expression();
85902ad516bSPetr Hosek   }
86002ad516bSPetr Hosek }
86102ad516bSPetr Hosek 
862de8d9897SRafael Espindola // Do a last effort at synchronizing the linker script "AST" and the section
863de8d9897SRafael Espindola // list. This is needed to account for last minute changes, like adding a
864de8d9897SRafael Espindola // .ARM.exidx terminator and sorting SHF_LINK_ORDER sections.
865de8d9897SRafael Espindola //
866de8d9897SRafael Espindola // FIXME: We should instead create the "AST" earlier and the above changes would
867de8d9897SRafael Espindola // be done directly in the "AST".
868de8d9897SRafael Espindola //
869de8d9897SRafael Espindola // This can only handle new sections being added and sections being reordered.
870de8d9897SRafael Espindola void LinkerScript::synchronize() {
871de8d9897SRafael Espindola   for (BaseCommand *Base : Opt.Commands) {
872de8d9897SRafael Espindola     auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
873de8d9897SRafael Espindola     if (!Cmd)
874de8d9897SRafael Espindola       continue;
875de8d9897SRafael Espindola     ArrayRef<InputSection *> Sections = Cmd->Sec->Sections;
8766a1aa8d9SRafael Espindola     std::vector<InputSection **> ScriptSections;
8776a1aa8d9SRafael Espindola     DenseSet<InputSection *> ScriptSectionsSet;
878de8d9897SRafael Espindola     for (BaseCommand *Base : Cmd->Commands) {
879de8d9897SRafael Espindola       auto *ISD = dyn_cast<InputSectionDescription>(Base);
880de8d9897SRafael Espindola       if (!ISD)
881de8d9897SRafael Espindola         continue;
8826a1aa8d9SRafael Espindola       for (InputSection *&IS : ISD->Sections) {
883de8d9897SRafael Espindola         if (IS->Live) {
884de8d9897SRafael Espindola           ScriptSections.push_back(&IS);
885de8d9897SRafael Espindola           ScriptSectionsSet.insert(IS);
886de8d9897SRafael Espindola         }
887de8d9897SRafael Espindola       }
888de8d9897SRafael Espindola     }
8896a1aa8d9SRafael Espindola     std::vector<InputSection *> Missing;
890de8d9897SRafael Espindola     for (InputSection *IS : Sections)
891de8d9897SRafael Espindola       if (!ScriptSectionsSet.count(IS))
892de8d9897SRafael Espindola         Missing.push_back(IS);
893de8d9897SRafael Espindola     if (!Missing.empty()) {
894de8d9897SRafael Espindola       auto ISD = make<InputSectionDescription>("");
895de8d9897SRafael Espindola       ISD->Sections = Missing;
896de8d9897SRafael Espindola       Cmd->Commands.push_back(ISD);
8976a1aa8d9SRafael Espindola       for (InputSection *&IS : ISD->Sections)
898de8d9897SRafael Espindola         if (IS->Live)
899de8d9897SRafael Espindola           ScriptSections.push_back(&IS);
900de8d9897SRafael Espindola     }
901de8d9897SRafael Espindola     assert(ScriptSections.size() == Sections.size());
902de8d9897SRafael Espindola     for (int I = 0, N = Sections.size(); I < N; ++I)
903de8d9897SRafael Espindola       *ScriptSections[I] = Sections[I];
904de8d9897SRafael Espindola   }
905de8d9897SRafael Espindola }
906de8d9897SRafael Espindola 
90702ed7575SRafael Espindola static bool allocateHeaders(std::vector<PhdrEntry> &Phdrs,
90802ed7575SRafael Espindola                             ArrayRef<OutputSection *> OutputSections,
90902ed7575SRafael Espindola                             uint64_t Min) {
91002ed7575SRafael Espindola   auto FirstPTLoad =
91102ed7575SRafael Espindola       std::find_if(Phdrs.begin(), Phdrs.end(),
91202ed7575SRafael Espindola                    [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
91302ed7575SRafael Espindola   if (FirstPTLoad == Phdrs.end())
91402ed7575SRafael Espindola     return false;
91502ed7575SRafael Espindola 
91602ed7575SRafael Espindola   uint64_t HeaderSize = getHeaderSize();
91702ed7575SRafael Espindola   if (HeaderSize <= Min || Script->hasPhdrsCommands()) {
91802ed7575SRafael Espindola     Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
91902ed7575SRafael Espindola     Out::ElfHeader->Addr = Min;
92002ed7575SRafael Espindola     Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
92102ed7575SRafael Espindola     return true;
92202ed7575SRafael Espindola   }
92302ed7575SRafael Espindola 
92402ed7575SRafael Espindola   assert(FirstPTLoad->First == Out::ElfHeader);
92502ed7575SRafael Espindola   OutputSection *ActualFirst = nullptr;
92602ed7575SRafael Espindola   for (OutputSection *Sec : OutputSections) {
92702ed7575SRafael Espindola     if (Sec->FirstInPtLoad == Out::ElfHeader) {
92802ed7575SRafael Espindola       ActualFirst = Sec;
92902ed7575SRafael Espindola       break;
93002ed7575SRafael Espindola     }
93102ed7575SRafael Espindola   }
93202ed7575SRafael Espindola   if (ActualFirst) {
93302ed7575SRafael Espindola     for (OutputSection *Sec : OutputSections)
93402ed7575SRafael Espindola       if (Sec->FirstInPtLoad == Out::ElfHeader)
93502ed7575SRafael Espindola         Sec->FirstInPtLoad = ActualFirst;
93602ed7575SRafael Espindola     FirstPTLoad->First = ActualFirst;
93702ed7575SRafael Espindola   } else {
93802ed7575SRafael Espindola     Phdrs.erase(FirstPTLoad);
93902ed7575SRafael Espindola   }
94002ed7575SRafael Espindola 
94102ed7575SRafael Espindola   auto PhdrI = std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry &E) {
94202ed7575SRafael Espindola     return E.p_type == PT_PHDR;
94302ed7575SRafael Espindola   });
94402ed7575SRafael Espindola   if (PhdrI != Phdrs.end())
94502ed7575SRafael Espindola     Phdrs.erase(PhdrI);
94602ed7575SRafael Espindola   return false;
94702ed7575SRafael Espindola }
94802ed7575SRafael Espindola 
949b8dd23f5SRui Ueyama void LinkerScript::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
9507c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
951be607334SRafael Espindola   Dot = 0;
95272dc195dSRafael Espindola   ErrorOnMissingSection = true;
95306f4743aSRafael Espindola   switchTo(Aether);
95406f4743aSRafael Espindola 
9558f99f73cSRui Ueyama   for (BaseCommand *Base : Opt.Commands) {
9568f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
957d379f735SRui Ueyama       assignSymbol(Cmd, false);
95805ef4cffSRui Ueyama       continue;
959652852c5SGeorge Rimar     }
960652852c5SGeorge Rimar 
9618f99f73cSRui Ueyama     if (auto *Cmd = dyn_cast<AssertCommand>(Base)) {
9624595df94SRafael Espindola       Cmd->Expression();
963eefa758eSGeorge Rimar       continue;
964eefa758eSGeorge Rimar     }
965eefa758eSGeorge Rimar 
9668f99f73cSRui Ueyama     auto *Cmd = cast<OutputSectionCommand>(Base);
967d3190795SRafael Espindola     assignOffsets(Cmd);
968a14b13d8SGeorge Rimar   }
969467c4d55SEugene Leviant 
9700c1c8085SGeorge Rimar   uint64_t MinVA = std::numeric_limits<uint64_t>::max();
97124e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
97204a2e348SRafael Espindola     if (Sec->Flags & SHF_ALLOC)
973e08e78dfSRafael Espindola       MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
974ea590d91SRafael Espindola     else
975ea590d91SRafael Espindola       Sec->Addr = 0;
976ea590d91SRafael Espindola   }
977aab6d5c5SRafael Espindola 
9782d262109SGeorge Rimar   allocateHeaders(Phdrs, *OutputSections, MinVA);
979fb8978fcSDima Stepanov }
980652852c5SGeorge Rimar 
981464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command.
982b8dd23f5SRui Ueyama std::vector<PhdrEntry> LinkerScript::createPhdrs() {
98317cb7c0aSRafael Espindola   std::vector<PhdrEntry> Ret;
984bbe38602SEugene Leviant 
985464daadcSRui Ueyama   // Process PHDRS and FILEHDR keywords because they are not
986464daadcSRui Ueyama   // real output sections and cannot be added in the following loop.
987bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
988edebbdf1SRui Ueyama     Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
98917cb7c0aSRafael Espindola     PhdrEntry &Phdr = Ret.back();
990bbe38602SEugene Leviant 
991bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
9929d1bacb1SRui Ueyama       Phdr.add(Out::ElfHeader);
993bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
9949d1bacb1SRui Ueyama       Phdr.add(Out::ProgramHeaders);
99556b21c86SEugene Leviant 
99656b21c86SEugene Leviant     if (Cmd.LMAExpr) {
99772dc195dSRafael Espindola       Phdr.p_paddr = Cmd.LMAExpr().getValue();
99856b21c86SEugene Leviant       Phdr.HasLMA = true;
99956b21c86SEugene Leviant     }
1000bbe38602SEugene Leviant   }
1001bbe38602SEugene Leviant 
1002464daadcSRui Ueyama   // Add output sections to program headers.
100324e6f363SRafael Espindola   for (OutputSection *Sec : *OutputSections) {
100404a2e348SRafael Espindola     if (!(Sec->Flags & SHF_ALLOC))
1005bbe38602SEugene Leviant       break;
1006bbe38602SEugene Leviant 
1007bbe38602SEugene Leviant     // Assign headers specified by linker script
10082c923c2cSRafael Espindola     for (size_t Id : getPhdrIndices(Sec)) {
1009edebbdf1SRui Ueyama       Ret[Id].add(Sec);
1010865bf863SEugene Leviant       if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
101117cb7c0aSRafael Espindola         Ret[Id].p_flags |= Sec->getPhdrFlags();
1012bbe38602SEugene Leviant     }
1013bbe38602SEugene Leviant   }
1014edebbdf1SRui Ueyama   return Ret;
1015bbe38602SEugene Leviant }
1016bbe38602SEugene Leviant 
1017b8dd23f5SRui Ueyama bool LinkerScript::ignoreInterpSection() {
1018f9bc3bd2SEugene Leviant   // Ignore .interp section in case we have PHDRS specification
1019f9bc3bd2SEugene Leviant   // and PT_INTERP isn't listed.
1020e31d9886SRui Ueyama   if (Opt.PhdrsCommands.empty())
1021e31d9886SRui Ueyama     return false;
1022e31d9886SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands)
1023e31d9886SRui Ueyama     if (Cmd.Type == PT_INTERP)
1024e31d9886SRui Ueyama       return false;
1025e31d9886SRui Ueyama   return true;
1026f9bc3bd2SEugene Leviant }
1027f9bc3bd2SEugene Leviant 
1028d7dc2258SRafael Espindola OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) const {
1029d7dc2258SRafael Espindola   auto I = SecToCommand.find(Sec);
1030d7dc2258SRafael Espindola   if (I == SecToCommand.end())
1031fa948c72SRafael Espindola     return nullptr;
1032d7dc2258SRafael Espindola   return I->second;
1033fa948c72SRafael Espindola }
1034fa948c72SRafael Espindola 
1035fa948c72SRafael Espindola Optional<uint32_t> LinkerScript::getFiller(OutputSection *Sec) {
1036fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec))
1037f6c3ccefSGeorge Rimar     return Cmd->Filler;
10389d9a6637SJames Henderson   return None;
1039e2ee72b5SGeorge Rimar }
1040e2ee72b5SGeorge Rimar 
1041e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
1042f62d2607SRui Ueyama   if (Size == 1)
1043f62d2607SRui Ueyama     *Buf = Data;
1044f62d2607SRui Ueyama   else if (Size == 2)
1045f93ed4deSRui Ueyama     write16(Buf, Data, Config->Endianness);
1046f62d2607SRui Ueyama   else if (Size == 4)
1047f93ed4deSRui Ueyama     write32(Buf, Data, Config->Endianness);
1048f62d2607SRui Ueyama   else if (Size == 8)
1049f93ed4deSRui Ueyama     write64(Buf, Data, Config->Endianness);
1050f62d2607SRui Ueyama   else
1051e38cbab5SGeorge Rimar     llvm_unreachable("unsupported Size argument");
1052e38cbab5SGeorge Rimar }
1053e38cbab5SGeorge Rimar 
1054660c9ab9SRafael Espindola void LinkerScript::writeDataBytes(OutputSection *Sec, uint8_t *Buf) {
1055fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec))
10568f99f73cSRui Ueyama     for (BaseCommand *Base : Cmd->Commands)
10578f99f73cSRui Ueyama       if (auto *Data = dyn_cast<BytesDataCommand>(Base))
1058a8dba487SGeorge Rimar         writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
1059e38cbab5SGeorge Rimar }
1060e38cbab5SGeorge Rimar 
1061dc1ed120SRafael Espindola bool LinkerScript::hasLMA(OutputSection *Sec) {
1062fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec))
1063fa948c72SRafael Espindola     if (Cmd->LMAExpr)
1064b71d6f7aSEugene Leviant       return true;
1065b71d6f7aSEugene Leviant   return false;
10668ceadb38SGeorge Rimar }
10678ceadb38SGeorge Rimar 
1068b8dd23f5SRui Ueyama ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
10694595df94SRafael Espindola   if (S == ".")
107072dc195dSRafael Espindola     return {CurOutSec, Dot - CurOutSec->Addr};
1071a8dba487SGeorge Rimar   if (SymbolBody *B = findSymbol(S)) {
107272dc195dSRafael Espindola     if (auto *D = dyn_cast<DefinedRegular>(B))
107372dc195dSRafael Espindola       return {D->Section, D->Value};
107430f16b23SPetr Hosek     if (auto *C = dyn_cast<DefinedCommon>(B))
1075a8dba487SGeorge Rimar       return {InX::Common, C->Offset};
107672dc195dSRafael Espindola   }
1077f6aeed36SEugene Leviant   error(Loc + ": symbol not found: " + S);
1078884e786dSGeorge Rimar   return 0;
1079884e786dSGeorge Rimar }
1080884e786dSGeorge Rimar 
1081b8dd23f5SRui Ueyama bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
1082f34f45fdSGeorge Rimar 
10832c923c2cSRafael Espindola // Returns indices of ELF headers containing specific section. Each index is a
10842c923c2cSRafael Espindola // zero based number of ELF header listed within PHDRS {} script block.
10852c923c2cSRafael Espindola std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) {
1086fa948c72SRafael Espindola   if (OutputSectionCommand *Cmd = getCmd(Sec)) {
108729c5a2a9SRui Ueyama     std::vector<size_t> Ret;
108829c5a2a9SRui Ueyama     for (StringRef PhdrName : Cmd->Phdrs)
10892a942c4bSEugene Leviant       Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
109029c5a2a9SRui Ueyama     return Ret;
1091bbe38602SEugene Leviant   }
109231d842f5SGeorge Rimar   return {};
109331d842f5SGeorge Rimar }
1094bbe38602SEugene Leviant 
1095b8dd23f5SRui Ueyama size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
109629c5a2a9SRui Ueyama   size_t I = 0;
109729c5a2a9SRui Ueyama   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
109829c5a2a9SRui Ueyama     if (Cmd.Name == PhdrName)
109929c5a2a9SRui Ueyama       return I;
110029c5a2a9SRui Ueyama     ++I;
110129c5a2a9SRui Ueyama   }
11022a942c4bSEugene Leviant   error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
110329c5a2a9SRui Ueyama   return 0;
110429c5a2a9SRui Ueyama }
1105