1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===// 2f7c5fbb1SRui Ueyama // 3f7c5fbb1SRui Ueyama // The LLVM Linker 4f7c5fbb1SRui Ueyama // 5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source 6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details. 7f7c5fbb1SRui Ueyama // 8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 9f7c5fbb1SRui Ueyama // 10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script. 11629e0aa5SRui Ueyama // It parses a linker script and write the result to Config or ScriptConfig 12629e0aa5SRui Ueyama // objects. 13629e0aa5SRui Ueyama // 14629e0aa5SRui Ueyama // If SECTIONS command is used, a ScriptConfig contains an AST 15629e0aa5SRui Ueyama // of the command which will later be consumed by createSections() and 16629e0aa5SRui Ueyama // assignAddresses(). 17f7c5fbb1SRui Ueyama // 18f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 19f7c5fbb1SRui Ueyama 20717677afSRui Ueyama #include "LinkerScript.h" 21f7c5fbb1SRui Ueyama #include "Config.h" 22f7c5fbb1SRui Ueyama #include "Driver.h" 231ebc8ed7SRui Ueyama #include "InputSection.h" 2455518e7dSRui Ueyama #include "Memory.h" 25652852c5SGeorge Rimar #include "OutputSections.h" 26e77b5bf6SAdhemerval Zanella #include "ScriptParser.h" 2793c9af42SRui Ueyama #include "Strings.h" 28f7c5fbb1SRui Ueyama #include "SymbolTable.h" 2955518e7dSRui Ueyama #include "Symbols.h" 30467c4d55SEugene Leviant #include "Target.h" 31bbe38602SEugene Leviant #include "Writer.h" 3222886a28SEugene Zelenko #include "llvm/ADT/STLExtras.h" 338c6a5aafSRui Ueyama #include "llvm/ADT/SmallString.h" 3422886a28SEugene Zelenko #include "llvm/ADT/StringRef.h" 35960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 3622886a28SEugene Zelenko #include "llvm/Support/Casting.h" 37652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 3822886a28SEugene Zelenko #include "llvm/Support/Endian.h" 3922886a28SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 40f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 4122886a28SEugene Zelenko #include "llvm/Support/MathExtras.h" 42f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h" 43f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 4422886a28SEugene Zelenko #include <algorithm> 4522886a28SEugene Zelenko #include <cassert> 4622886a28SEugene Zelenko #include <cstddef> 4722886a28SEugene Zelenko #include <cstdint> 4822886a28SEugene Zelenko #include <iterator> 4922886a28SEugene Zelenko #include <limits> 5022886a28SEugene Zelenko #include <memory> 5122886a28SEugene Zelenko #include <string> 5222886a28SEugene Zelenko #include <tuple> 5322886a28SEugene Zelenko #include <vector> 54f7c5fbb1SRui Ueyama 55f7c5fbb1SRui Ueyama using namespace llvm; 56652852c5SGeorge Rimar using namespace llvm::ELF; 571ebc8ed7SRui Ueyama using namespace llvm::object; 58e38cbab5SGeorge Rimar using namespace llvm::support::endian; 59f7c5fbb1SRui Ueyama using namespace lld; 60e0df00b9SRafael Espindola using namespace lld::elf; 61f7c5fbb1SRui Ueyama 62884e786dSGeorge Rimar LinkerScriptBase *elf::ScriptBase; 6307320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 64717677afSRui Ueyama 656c55f0e3SGeorge Rimar template <class ELFT> static void addRegular(SymbolAssignment *Cmd) { 663dabfc6bSRafael Espindola uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; 673dabfc6bSRafael Espindola Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, Visibility, nullptr, 68093abab8SRafael Espindola STB_GLOBAL, STT_NOTYPE, 0); 691602421cSRui Ueyama Cmd->Sym = Sym->body(); 7020d03194SEugene Leviant 7120d03194SEugene Leviant // If we have no SECTIONS then we don't have '.' and don't call 7220d03194SEugene Leviant // assignAddresses(). We calculate symbol value immediately in this case. 7320d03194SEugene Leviant if (!ScriptConfig->HasSections) 7420d03194SEugene Leviant cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0); 75ceabe80eSEugene Leviant } 76ceabe80eSEugene Leviant 770c70d3ccSRui Ueyama template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) { 78e1937bb5SGeorge Rimar Symbol *Sym = Symtab<ELFT>::X->addSynthetic( 79e1937bb5SGeorge Rimar Cmd->Name, nullptr, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT); 801602421cSRui Ueyama Cmd->Sym = Sym->body(); 81ceabe80eSEugene Leviant } 82ceabe80eSEugene Leviant 83db741e72SEugene Leviant template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) { 842f831dcaSRafael Espindola if (Cmd->Expression.IsAbsolute()) 85db741e72SEugene Leviant addRegular<ELFT>(Cmd); 86db741e72SEugene Leviant else 87db741e72SEugene Leviant addSynthetic<ELFT>(Cmd); 88db741e72SEugene Leviant } 891602421cSRui Ueyama // If a symbol was in PROVIDE(), we need to define it only when 901602421cSRui Ueyama // it is an undefined symbol. 911602421cSRui Ueyama template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) { 921602421cSRui Ueyama if (Cmd->Name == ".") 93ceabe80eSEugene Leviant return false; 941602421cSRui Ueyama if (!Cmd->Provide) 95ceabe80eSEugene Leviant return true; 961602421cSRui Ueyama SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 971602421cSRui Ueyama return B && B->isUndefined(); 98ceabe80eSEugene Leviant } 99ceabe80eSEugene Leviant 100076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 101076fe157SGeorge Rimar return C->Kind == AssignmentKind; 102076fe157SGeorge Rimar } 103076fe157SGeorge Rimar 104076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 105076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 106076fe157SGeorge Rimar } 107076fe157SGeorge Rimar 108eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 109eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 110eea3114fSGeorge Rimar } 111eea3114fSGeorge Rimar 112eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 113eefa758eSGeorge Rimar return C->Kind == AssertKind; 114eefa758eSGeorge Rimar } 115eefa758eSGeorge Rimar 116e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) { 117e38cbab5SGeorge Rimar return C->Kind == BytesDataKind; 118e38cbab5SGeorge Rimar } 119e38cbab5SGeorge Rimar 12036a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) { 121eea3114fSGeorge Rimar return !S || !S->Live; 122717677afSRui Ueyama } 123717677afSRui Ueyama 12422886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::LinkerScript() = default; 12522886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::~LinkerScript() = default; 126f34d0e08SRui Ueyama 12707320e40SRui Ueyama template <class ELFT> 12807320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 129cf43f179SEugene Leviant for (InputSectionDescription *ID : Opt.KeptSections) { 130cf43f179SEugene Leviant StringRef Filename = S->getFile()->getName(); 131f91282e1SRui Ueyama if (!ID->FilePat.match(sys::path::filename(Filename))) 132cf43f179SEugene Leviant continue; 133cf43f179SEugene Leviant 134cf43f179SEugene Leviant for (SectionPattern &P : ID->SectionPatterns) 135f91282e1SRui Ueyama if (P.SectionPat.match(S->Name)) 136eea3114fSGeorge Rimar return true; 137cf43f179SEugene Leviant } 138eea3114fSGeorge Rimar return false; 139eea3114fSGeorge Rimar } 140eea3114fSGeorge Rimar 141575208caSGeorge Rimar static bool comparePriority(InputSectionData *A, InputSectionData *B) { 142575208caSGeorge Rimar return getPriority(A->Name) < getPriority(B->Name); 143575208caSGeorge Rimar } 144575208caSGeorge Rimar 145c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) { 146042a3f20SRafael Espindola return A->Name < B->Name; 1470702c4e8SGeorge Rimar } 148742c3836SRui Ueyama 149c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) { 150742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 151742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 152742c3836SRui Ueyama // This is compatible with GNU. 153742c3836SRui Ueyama return A->Alignment > B->Alignment; 154742c3836SRui Ueyama } 155742c3836SRui Ueyama 156c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)> 157be394db3SGeorge Rimar getComparator(SortSectionPolicy K) { 158be394db3SGeorge Rimar switch (K) { 159be394db3SGeorge Rimar case SortSectionPolicy::Alignment: 160c0028d3dSRafael Espindola return compareAlignment; 161be394db3SGeorge Rimar case SortSectionPolicy::Name: 162be394db3SGeorge Rimar return compareName; 163be394db3SGeorge Rimar case SortSectionPolicy::Priority: 164be394db3SGeorge Rimar return comparePriority; 165be394db3SGeorge Rimar default: 166be394db3SGeorge Rimar llvm_unreachable("unknown sort policy"); 167be394db3SGeorge Rimar } 168742c3836SRui Ueyama } 1690702c4e8SGeorge Rimar 17048c3f1ceSRui Ueyama template <class ELFT> 171e71a3f8aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 17206ae6836SGeorge Rimar ConstraintKind Kind) { 1738f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 1748f66df92SGeorge Rimar return true; 175e746e52cSRafael Espindola bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) { 176d3190795SRafael Espindola auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2); 1771854a8ebSRafael Espindola return Sec->Flags & SHF_WRITE; 17806ae6836SGeorge Rimar }); 179e746e52cSRafael Espindola return (IsRW && Kind == ConstraintKind::ReadWrite) || 180e746e52cSRafael Espindola (!IsRW && Kind == ConstraintKind::ReadOnly); 18106ae6836SGeorge Rimar } 18206ae6836SGeorge Rimar 18307171f21SGeorge Rimar static void sortSections(InputSectionData **Begin, InputSectionData **End, 184ee924709SRui Ueyama SortSectionPolicy K) { 185ee924709SRui Ueyama if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None) 18607171f21SGeorge Rimar std::stable_sort(Begin, End, getComparator(K)); 187ee924709SRui Ueyama } 188ee924709SRui Ueyama 189d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches. 190be94e1b6SRafael Espindola template <class ELFT> 191e71a3f8aSRafael Espindola void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) { 1924dc07becSRui Ueyama // Collects all sections that satisfy constraints of I 1934dc07becSRui Ueyama // and attach them to I. 1944dc07becSRui Ueyama for (SectionPattern &Pat : I->SectionPatterns) { 19507171f21SGeorge Rimar size_t SizeBefore = I->Sections.size(); 1968c6a5aafSRui Ueyama 1978c6a5aafSRui Ueyama for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) { 1988c6a5aafSRui Ueyama if (isDiscarded(S) || S->OutSec) 1998c6a5aafSRui Ueyama continue; 2008c6a5aafSRui Ueyama 2018c6a5aafSRui Ueyama StringRef Filename; 2028c6a5aafSRui Ueyama if (elf::ObjectFile<ELFT> *F = S->getFile()) 2038c6a5aafSRui Ueyama Filename = sys::path::filename(F->getName()); 2048c6a5aafSRui Ueyama 205*e8a6102fSRui Ueyama if (I->FilePat.match(Filename) && !Pat.ExcludedFilePat.match(Filename) && 206*e8a6102fSRui Ueyama Pat.SectionPat.match(S->Name)) 207d3190795SRafael Espindola I->Sections.push_back(S); 208395281cfSGeorge Rimar } 209d3190795SRafael Espindola 210ee924709SRui Ueyama // Sort sections as instructed by SORT-family commands and --sort-section 211ee924709SRui Ueyama // option. Because SORT-family commands can be nested at most two depth 212ee924709SRui Ueyama // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command 213ee924709SRui Ueyama // line option is respected even if a SORT command is given, the exact 214ee924709SRui Ueyama // behavior we have here is a bit complicated. Here are the rules. 215ee924709SRui Ueyama // 216ee924709SRui Ueyama // 1. If two SORT commands are given, --sort-section is ignored. 217ee924709SRui Ueyama // 2. If one SORT command is given, and if it is not SORT_NONE, 218ee924709SRui Ueyama // --sort-section is handled as an inner SORT command. 219ee924709SRui Ueyama // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. 220ee924709SRui Ueyama // 4. If no SORT command is given, sort according to --sort-section. 22107171f21SGeorge Rimar InputSectionData **Begin = I->Sections.data() + SizeBefore; 22207171f21SGeorge Rimar InputSectionData **End = I->Sections.data() + I->Sections.size(); 22307171f21SGeorge Rimar if (Pat.SortOuter != SortSectionPolicy::None) { 22407171f21SGeorge Rimar if (Pat.SortInner == SortSectionPolicy::Default) 22507171f21SGeorge Rimar sortSections(Begin, End, Config->SortSection); 226ee924709SRui Ueyama else 22707171f21SGeorge Rimar sortSections(Begin, End, Pat.SortInner); 22807171f21SGeorge Rimar sortSections(Begin, End, Pat.SortOuter); 22907171f21SGeorge Rimar } 230ee924709SRui Ueyama } 231d3190795SRafael Espindola 232d3190795SRafael Espindola // We do not add duplicate input sections, so mark them with a dummy output 233d3190795SRafael Espindola // section for now. 234d3190795SRafael Espindola for (InputSectionData *S : I->Sections) { 235d3190795SRafael Espindola auto *S2 = static_cast<InputSectionBase<ELFT> *>(S); 236d3190795SRafael Espindola S2->OutSec = (OutputSectionBase<ELFT> *)-1; 237d3190795SRafael Espindola } 238be94e1b6SRafael Espindola } 239be94e1b6SRafael Espindola 240be94e1b6SRafael Espindola template <class ELFT> 241be94e1b6SRafael Espindola void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) { 242be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : V) { 243be94e1b6SRafael Espindola S->Live = false; 244be94e1b6SRafael Espindola reportDiscarded(S); 245be94e1b6SRafael Espindola } 246be94e1b6SRafael Espindola } 247be94e1b6SRafael Espindola 24806ae6836SGeorge Rimar template <class ELFT> 2490b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 25006ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 2510b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 252e7f912cdSRui Ueyama 25306ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 2547c3ff2ebSRafael Espindola auto *Cmd = dyn_cast<InputSectionDescription>(Base.get()); 2557c3ff2ebSRafael Espindola if (!Cmd) 2560b9ce6a4SRui Ueyama continue; 257e71a3f8aSRafael Espindola computeInputSections(Cmd); 258d3190795SRafael Espindola for (InputSectionData *S : Cmd->Sections) 259d3190795SRafael Espindola Ret.push_back(static_cast<InputSectionBase<ELFT> *>(S)); 2600b9ce6a4SRui Ueyama } 261e71a3f8aSRafael Espindola 262cc1ba8c7SEugene Leviant // After we created final list we should now set OutSec pointer to null, 263cc1ba8c7SEugene Leviant // instead of -1. Otherwise we may get a crash when writing relocs, in 264cc1ba8c7SEugene Leviant // case section is discarded by linker script 265cc1ba8c7SEugene Leviant for (InputSectionBase<ELFT> *S : Ret) 266cc1ba8c7SEugene Leviant S->OutSec = nullptr; 267cc1ba8c7SEugene Leviant 2680b9ce6a4SRui Ueyama return Ret; 2690b9ce6a4SRui Ueyama } 2700b9ce6a4SRui Ueyama 271e5d3ca50SPetr Hosek template <class ELFT> 27210897f18SRafael Espindola static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C, 27310897f18SRafael Espindola StringRef OutsecName) { 27410897f18SRafael Espindola // When using linker script the merge rules are different. 27510897f18SRafael Espindola // Unfortunately, linker scripts are name based. This means that expressions 27610897f18SRafael Espindola // like *(.foo*) can refer to multiple input sections that would normally be 27710897f18SRafael Espindola // placed in different output sections. We cannot put them in different 27810897f18SRafael Espindola // output sections or we would produce wrong results for 27910897f18SRafael Espindola // start = .; *(.foo.*) end = .; *(.bar) 28010897f18SRafael Espindola // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to 28110897f18SRafael Espindola // another. The problem is that there is no way to layout those output 28210897f18SRafael Espindola // sections such that the .foo sections are the only thing between the 28310897f18SRafael Espindola // start and end symbols. 28410897f18SRafael Espindola 28510897f18SRafael Espindola // An extra annoyance is that we cannot simply disable merging of the contents 28610897f18SRafael Espindola // of SHF_MERGE sections, but our implementation requires one output section 28710897f18SRafael Espindola // per "kind" (string or not, which size/aligment). 28810897f18SRafael Espindola // Fortunately, creating symbols in the middle of a merge section is not 28910897f18SRafael Espindola // supported by bfd or gold, so we can just create multiple section in that 29010897f18SRafael Espindola // case. 29110897f18SRafael Espindola typedef typename ELFT::uint uintX_t; 2921854a8ebSRafael Espindola uintX_t Flags = C->Flags & (SHF_MERGE | SHF_STRINGS); 29310897f18SRafael Espindola 29410897f18SRafael Espindola uintX_t Alignment = 0; 29510897f18SRafael Espindola if (isa<MergeInputSection<ELFT>>(C)) 2961854a8ebSRafael Espindola Alignment = std::max<uintX_t>(C->Alignment, C->Entsize); 29710897f18SRafael Espindola 29810897f18SRafael Espindola return SectionKey<ELFT::Is64Bits>{OutsecName, /*Type*/ 0, Flags, Alignment}; 29910897f18SRafael Espindola } 30010897f18SRafael Espindola 30110897f18SRafael Espindola template <class ELFT> 30220d03194SEugene Leviant void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory, 30320d03194SEugene Leviant InputSectionBase<ELFT> *Sec, 30420d03194SEugene Leviant StringRef Name) { 30528c1597aSRafael Espindola OutputSectionBase<ELFT> *OutSec; 30628c1597aSRafael Espindola bool IsNew; 30710897f18SRafael Espindola std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec); 30828c1597aSRafael Espindola if (IsNew) 30928c1597aSRafael Espindola OutputSections->push_back(OutSec); 31020d03194SEugene Leviant OutSec->addSection(Sec); 31120d03194SEugene Leviant } 31220d03194SEugene Leviant 31320d03194SEugene Leviant template <class ELFT> 31420d03194SEugene Leviant void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { 3157c3ff2ebSRafael Espindola for (unsigned I = 0; I < Opt.Commands.size(); ++I) { 3167c3ff2ebSRafael Espindola auto Iter = Opt.Commands.begin() + I; 3177c3ff2ebSRafael Espindola const std::unique_ptr<BaseCommand> &Base1 = *Iter; 3182ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 3192ab5f73dSRui Ueyama if (shouldDefine<ELFT>(Cmd)) 320b0de56b5SRafael Espindola addSymbol<ELFT>(Cmd); 3212ab5f73dSRui Ueyama continue; 3222ab5f73dSRui Ueyama } 32320d03194SEugene Leviant if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) { 32420d03194SEugene Leviant // If we don't have SECTIONS then output sections have already been 325194470cdSGeorge Rimar // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses 32620d03194SEugene Leviant // will not be called, so ASSERT should be evaluated now. 32720d03194SEugene Leviant if (!Opt.HasSections) 32820d03194SEugene Leviant Cmd->Expression(0); 32920d03194SEugene Leviant continue; 33020d03194SEugene Leviant } 3312ab5f73dSRui Ueyama 332ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 3337bd37870SRafael Espindola std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 3347bd37870SRafael Espindola 33548c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 3367bd37870SRafael Espindola discard(V); 33748c3f1ceSRui Ueyama continue; 33848c3f1ceSRui Ueyama } 3390b9ce6a4SRui Ueyama 3407c3ff2ebSRafael Espindola if (!matchConstraints<ELFT>(V, Cmd->Constraint)) { 3417c3ff2ebSRafael Espindola for (InputSectionBase<ELFT> *S : V) 3427c3ff2ebSRafael Espindola S->OutSec = nullptr; 3437c3ff2ebSRafael Espindola Opt.Commands.erase(Iter); 344dfbbbc86SGeorge Rimar --I; 3457c3ff2ebSRafael Espindola continue; 3467c3ff2ebSRafael Espindola } 3477c3ff2ebSRafael Espindola 3487c3ff2ebSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 3497c3ff2ebSRafael Espindola if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) 3507c3ff2ebSRafael Espindola if (shouldDefine<ELFT>(OutCmd)) 3517c3ff2ebSRafael Espindola addSymbol<ELFT>(OutCmd); 3527c3ff2ebSRafael Espindola 35397403d15SEugene Leviant if (V.empty()) 3540b9ce6a4SRui Ueyama continue; 3550b9ce6a4SRui Ueyama 356a14b13d8SGeorge Rimar for (InputSectionBase<ELFT> *Sec : V) { 35720d03194SEugene Leviant addSection(Factory, Sec, Cmd->Name); 35820d03194SEugene Leviant if (uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0) 359db24d9c3SGeorge Rimar Sec->Alignment = Subalign; 36020d03194SEugene Leviant } 361eea3114fSGeorge Rimar } 36248c3f1ceSRui Ueyama } 363db24d9c3SGeorge Rimar } 364e63d81bdSEugene Leviant 36520d03194SEugene Leviant template <class ELFT> 36620d03194SEugene Leviant void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 36720d03194SEugene Leviant processCommands(Factory); 3688c6a5aafSRui Ueyama 3690b9ce6a4SRui Ueyama // Add orphan sections. 3708c6a5aafSRui Ueyama for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) 37120d03194SEugene Leviant if (!isDiscarded(S) && !S->OutSec) 37255518e7dSRui Ueyama addSection(Factory, S, getOutputSectionName(S->Name)); 373e63d81bdSEugene Leviant } 374e63d81bdSEugene Leviant 375db741e72SEugene Leviant // Sets value of a section-defined symbol. Two kinds of 376db741e72SEugene Leviant // symbols are processed: synthetic symbols, whose value 377db741e72SEugene Leviant // is an offset from beginning of section and regular 378db741e72SEugene Leviant // symbols whose value is absolute. 379db741e72SEugene Leviant template <class ELFT> 380db741e72SEugene Leviant static void assignSectionSymbol(SymbolAssignment *Cmd, 381db741e72SEugene Leviant OutputSectionBase<ELFT> *Sec, 382498ed714SRafael Espindola typename ELFT::uint Value) { 383db741e72SEugene Leviant if (!Cmd->Sym) 384db741e72SEugene Leviant return; 385db741e72SEugene Leviant 386db741e72SEugene Leviant if (auto *Body = dyn_cast<DefinedSynthetic<ELFT>>(Cmd->Sym)) { 387db741e72SEugene Leviant Body->Section = Sec; 388498ed714SRafael Espindola Body->Value = Cmd->Expression(Value) - Sec->getVA(); 389db741e72SEugene Leviant return; 390db741e72SEugene Leviant } 391db741e72SEugene Leviant auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym); 392498ed714SRafael Espindola Body->Value = Cmd->Expression(Value); 393db741e72SEugene Leviant } 394db741e72SEugene Leviant 395a940e539SRafael Espindola template <class ELFT> static bool isTbss(OutputSectionBase<ELFT> *Sec) { 396a940e539SRafael Espindola return (Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS; 397a940e539SRafael Espindola } 398a940e539SRafael Espindola 399d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) { 400d3190795SRafael Espindola if (!AlreadyOutputIS.insert(S).second) 401ceabe80eSEugene Leviant return; 402a940e539SRafael Espindola bool IsTbss = isTbss(CurOutSec); 403d3190795SRafael Espindola 404d3190795SRafael Espindola uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; 405d3190795SRafael Espindola Pos = alignTo(Pos, S->Alignment); 406d3190795SRafael Espindola S->OutSecOff = Pos - CurOutSec->getVA(); 407d3190795SRafael Espindola Pos += S->getSize(); 408d3190795SRafael Espindola 409d3190795SRafael Espindola // Update output section size after adding each section. This is so that 410d3190795SRafael Espindola // SIZEOF works correctly in the case below: 411d3190795SRafael Espindola // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 412d3190795SRafael Espindola CurOutSec->setSize(Pos - CurOutSec->getVA()); 413d3190795SRafael Espindola 4147252ae52SRafael Espindola if (IsTbss) 4157252ae52SRafael Espindola ThreadBssOffset = Pos - Dot; 4167252ae52SRafael Espindola else 417d3190795SRafael Espindola Dot = Pos; 4182de509c3SRui Ueyama } 419ceabe80eSEugene Leviant 420d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::flush() { 42165499b90SRafael Espindola if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second) 42265499b90SRafael Espindola return; 42365499b90SRafael Espindola if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) { 424d3190795SRafael Espindola for (InputSection<ELFT> *I : OutSec->Sections) 425d3190795SRafael Espindola output(I); 42665499b90SRafael Espindola } else { 42765499b90SRafael Espindola Dot += CurOutSec->getSize(); 428d3190795SRafael Espindola } 429d3190795SRafael Espindola } 43097403d15SEugene Leviant 431d3190795SRafael Espindola template <class ELFT> 432d3190795SRafael Espindola void LinkerScript<ELFT>::switchTo(OutputSectionBase<ELFT> *Sec) { 433d3190795SRafael Espindola if (CurOutSec == Sec) 434d3190795SRafael Espindola return; 435d3190795SRafael Espindola if (AlreadyOutputOS.count(Sec)) 436d3190795SRafael Espindola return; 437d3190795SRafael Espindola 438d3190795SRafael Espindola flush(); 439d3190795SRafael Espindola CurOutSec = Sec; 440d3190795SRafael Espindola 441d3190795SRafael Espindola Dot = alignTo(Dot, CurOutSec->getAlignment()); 442a940e539SRafael Espindola CurOutSec->setVA(isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot); 443b71d6f7aSEugene Leviant 444b71d6f7aSEugene Leviant // If neither AT nor AT> is specified for an allocatable section, the linker 445b71d6f7aSEugene Leviant // will set the LMA such that the difference between VMA and LMA for the 446b71d6f7aSEugene Leviant // section is the same as the preceding output section in the same region 447b71d6f7aSEugene Leviant // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html 448b71d6f7aSEugene Leviant CurOutSec->setLMAOffset(LMAOffset); 449d3190795SRafael Espindola } 450d3190795SRafael Espindola 451d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) { 452e38cbab5SGeorge Rimar // This handles the assignments to symbol or to a location counter (.) 453d3190795SRafael Espindola if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) { 45497403d15SEugene Leviant if (AssignCmd->Name == ".") { 45597403d15SEugene Leviant // Update to location counter means update to section size. 456d3190795SRafael Espindola Dot = AssignCmd->Expression(Dot); 457d3190795SRafael Espindola CurOutSec->setSize(Dot - CurOutSec->getVA()); 458d3190795SRafael Espindola return; 45997403d15SEugene Leviant } 460498ed714SRafael Espindola assignSectionSymbol<ELFT>(AssignCmd, CurOutSec, Dot); 461d3190795SRafael Espindola return; 46297403d15SEugene Leviant } 463e38cbab5SGeorge Rimar 464e38cbab5SGeorge Rimar // Handle BYTE(), SHORT(), LONG(), or QUAD(). 465e38cbab5SGeorge Rimar if (auto *DataCmd = dyn_cast<BytesDataCommand>(&Base)) { 466e38cbab5SGeorge Rimar DataCmd->Offset = Dot - CurOutSec->getVA(); 467e38cbab5SGeorge Rimar Dot += DataCmd->Size; 468e38cbab5SGeorge Rimar CurOutSec->setSize(Dot - CurOutSec->getVA()); 469e38cbab5SGeorge Rimar return; 470e38cbab5SGeorge Rimar } 471e38cbab5SGeorge Rimar 472e38cbab5SGeorge Rimar // It handles single input section description command, 473e38cbab5SGeorge Rimar // calculates and assigns the offsets for each section and also 474e38cbab5SGeorge Rimar // updates the output section size. 475d3190795SRafael Espindola auto &ICmd = cast<InputSectionDescription>(Base); 476d3190795SRafael Espindola for (InputSectionData *ID : ICmd.Sections) { 477d3190795SRafael Espindola auto *IB = static_cast<InputSectionBase<ELFT> *>(ID); 478d3190795SRafael Espindola switchTo(IB->OutSec); 479d3190795SRafael Espindola if (auto *I = dyn_cast<InputSection<ELFT>>(IB)) 480d3190795SRafael Espindola output(I); 48165499b90SRafael Espindola else 48265499b90SRafael Espindola flush(); 483ceabe80eSEugene Leviant } 484ceabe80eSEugene Leviant } 485ceabe80eSEugene Leviant 4868f66df92SGeorge Rimar template <class ELFT> 487a14b13d8SGeorge Rimar static std::vector<OutputSectionBase<ELFT> *> 4889257764dSEugene Leviant findSections(StringRef Name, 489d3190795SRafael Espindola const std::vector<OutputSectionBase<ELFT> *> &Sections) { 490a14b13d8SGeorge Rimar std::vector<OutputSectionBase<ELFT> *> Ret; 491a14b13d8SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : Sections) 4929257764dSEugene Leviant if (Sec->getName() == Name) 493a14b13d8SGeorge Rimar Ret.push_back(Sec); 494a14b13d8SGeorge Rimar return Ret; 4958f66df92SGeorge Rimar } 4968f66df92SGeorge Rimar 497d3190795SRafael Espindola template <class ELFT> 498d3190795SRafael Espindola void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) { 499b71d6f7aSEugene Leviant if (Cmd->LMAExpr) 500b71d6f7aSEugene Leviant LMAOffset = Cmd->LMAExpr(Dot) - Dot; 501d3190795SRafael Espindola std::vector<OutputSectionBase<ELFT> *> Sections = 5029257764dSEugene Leviant findSections(Cmd->Name, *OutputSections); 503d3190795SRafael Espindola if (Sections.empty()) 504d3190795SRafael Espindola return; 505d3190795SRafael Espindola switchTo(Sections[0]); 506d3190795SRafael Espindola // Find the last section output location. We will output orphan sections 507d3190795SRafael Espindola // there so that end symbols point to the correct location. 508d3190795SRafael Espindola auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(), 509d3190795SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 510d3190795SRafael Espindola return !isa<SymbolAssignment>(*Cmd); 511d3190795SRafael Espindola }) 512d3190795SRafael Espindola .base(); 513d3190795SRafael Espindola for (auto I = Cmd->Commands.begin(); I != E; ++I) 514d3190795SRafael Espindola process(**I); 51565499b90SRafael Espindola for (OutputSectionBase<ELFT> *Base : Sections) 516d3190795SRafael Espindola switchTo(Base); 5172506cb4dSEugene Leviant flush(); 518b31dd370SGeorge Rimar std::for_each(E, Cmd->Commands.end(), 519b31dd370SGeorge Rimar [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); }); 520d3190795SRafael Espindola } 521d3190795SRafael Espindola 5229546fffbSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() { 5236d38e4dbSRafael Espindola // It is common practice to use very generic linker scripts. So for any 5246d38e4dbSRafael Espindola // given run some of the output sections in the script will be empty. 5256d38e4dbSRafael Espindola // We could create corresponding empty output sections, but that would 5266d38e4dbSRafael Espindola // clutter the output. 5276d38e4dbSRafael Espindola // We instead remove trivially empty sections. The bfd linker seems even 5286d38e4dbSRafael Espindola // more aggressive at removing them. 5296d38e4dbSRafael Espindola auto Pos = std::remove_if( 5306d38e4dbSRafael Espindola Opt.Commands.begin(), Opt.Commands.end(), 5316d38e4dbSRafael Espindola [&](const std::unique_ptr<BaseCommand> &Base) { 5326d38e4dbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 5336d38e4dbSRafael Espindola if (!Cmd) 5346d38e4dbSRafael Espindola return false; 5356d38e4dbSRafael Espindola std::vector<OutputSectionBase<ELFT> *> Secs = 5369257764dSEugene Leviant findSections(Cmd->Name, *OutputSections); 5376d38e4dbSRafael Espindola if (!Secs.empty()) 5386d38e4dbSRafael Espindola return false; 5396d38e4dbSRafael Espindola for (const std::unique_ptr<BaseCommand> &I : Cmd->Commands) 5406d38e4dbSRafael Espindola if (!isa<InputSectionDescription>(I.get())) 5416d38e4dbSRafael Espindola return false; 5426d38e4dbSRafael Espindola return true; 5436d38e4dbSRafael Espindola }); 5446d38e4dbSRafael Espindola Opt.Commands.erase(Pos, Opt.Commands.end()); 5456d38e4dbSRafael Espindola 5469546fffbSRafael Espindola // If the output section contains only symbol assignments, create a 5479546fffbSRafael Espindola // corresponding output section. The bfd linker seems to only create them if 5489546fffbSRafael Espindola // '.' is assigned to, but creating these section should not have any bad 5499546fffbSRafael Espindola // consequeces and gives us a section to put the symbol in. 5509546fffbSRafael Espindola uintX_t Flags = SHF_ALLOC; 5519546fffbSRafael Espindola uint32_t Type = 0; 5529546fffbSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 5539546fffbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 5549546fffbSRafael Espindola if (!Cmd) 5559546fffbSRafael Espindola continue; 5569546fffbSRafael Espindola std::vector<OutputSectionBase<ELFT> *> Secs = 5579257764dSEugene Leviant findSections(Cmd->Name, *OutputSections); 5589546fffbSRafael Espindola if (!Secs.empty()) { 5599546fffbSRafael Espindola Flags = Secs[0]->getFlags(); 5609546fffbSRafael Espindola Type = Secs[0]->getType(); 5619546fffbSRafael Espindola continue; 5629546fffbSRafael Espindola } 5639546fffbSRafael Espindola 56495642b95SRui Ueyama auto *OutSec = make<OutputSection<ELFT>>(Cmd->Name, Type, Flags); 5659546fffbSRafael Espindola OutputSections->push_back(OutSec); 5669546fffbSRafael Espindola } 5679546fffbSRafael Espindola } 5689546fffbSRafael Espindola 56915c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments 57015c57951SRafael Espindola // so that an orphan after 57115c57951SRafael Espindola // begin_foo = .; 57215c57951SRafael Espindola // foo : { *(foo) } 57315c57951SRafael Espindola // end_foo = .; 57415c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols. 57515c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the 57615c57951SRafael Espindola // one in charge of deciding the order of the sections. 57715c57951SRafael Espindola // We don't want to go over alignments, since doing so in 57815c57951SRafael Espindola // rx_sec : { *(rx_sec) } 57915c57951SRafael Espindola // . = ALIGN(0x1000); 58015c57951SRafael Espindola // /* The RW PT_LOAD starts here*/ 58115c57951SRafael Espindola // rw_sec : { *(rw_sec) } 58215c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned. 58315c57951SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) { 58415c57951SRafael Espindola if (isa<OutputSectionCommand>(Cmd)) 58515c57951SRafael Espindola return false; 58615c57951SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd); 58715c57951SRafael Espindola if (!Assign) 58815c57951SRafael Espindola return true; 58915c57951SRafael Espindola return Assign->Name != "."; 59015c57951SRafael Espindola } 59115c57951SRafael Espindola 5926d91fce5SRafael Espindola template <class ELFT> 5936d91fce5SRafael Espindola void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs) { 594652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 5957c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 5967c18c28cSRui Ueyama // We place orphan sections at end of file. 5977c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 598652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 599aab6d5c5SRafael Espindola 600aab6d5c5SRafael Espindola // The OutputSections are already in the correct order. 601aab6d5c5SRafael Espindola // This loops creates or moves commands as needed so that they are in the 602aab6d5c5SRafael Espindola // correct order. 603aab6d5c5SRafael Espindola int CmdIndex = 0; 604e5cc668eSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 605652852c5SGeorge Rimar StringRef Name = Sec->getName(); 606aab6d5c5SRafael Espindola 607aab6d5c5SRafael Espindola // Find the last spot where we can insert a command and still get the 60815c57951SRafael Espindola // correct result. 609aab6d5c5SRafael Espindola auto CmdIter = Opt.Commands.begin() + CmdIndex; 610aab6d5c5SRafael Espindola auto E = Opt.Commands.end(); 61115c57951SRafael Espindola while (CmdIter != E && shouldSkip(**CmdIter)) { 612aab6d5c5SRafael Espindola ++CmdIter; 613aab6d5c5SRafael Espindola ++CmdIndex; 614aab6d5c5SRafael Espindola } 615aab6d5c5SRafael Espindola 616aab6d5c5SRafael Espindola auto Pos = 617aab6d5c5SRafael Espindola std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) { 618aab6d5c5SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 619aab6d5c5SRafael Espindola return Cmd && Cmd->Name == Name; 620aab6d5c5SRafael Espindola }); 621aab6d5c5SRafael Espindola if (Pos == E) { 622aab6d5c5SRafael Espindola Opt.Commands.insert(CmdIter, 623aab6d5c5SRafael Espindola llvm::make_unique<OutputSectionCommand>(Name)); 624aab6d5c5SRafael Espindola ++CmdIndex; 62515c57951SRafael Espindola continue; 62615c57951SRafael Espindola } 62715c57951SRafael Espindola 62815c57951SRafael Espindola // Continue from where we found it. 62915c57951SRafael Espindola CmdIndex = (Pos - Opt.Commands.begin()) + 1; 630652852c5SGeorge Rimar } 631652852c5SGeorge Rimar 6327c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 633be607334SRafael Espindola Dot = 0; 634652852c5SGeorge Rimar 635076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 636076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 6378d083e6aSRui Ueyama if (Cmd->Name == ".") { 6388d083e6aSRui Ueyama Dot = Cmd->Expression(Dot); 6398d083e6aSRui Ueyama } else if (Cmd->Sym) { 640b0de56b5SRafael Espindola assignSectionSymbol(Cmd, CurOutSec ? CurOutSec : (*OutputSections)[0], 641b0de56b5SRafael Espindola Dot); 6428d083e6aSRui Ueyama } 64305ef4cffSRui Ueyama continue; 644652852c5SGeorge Rimar } 645652852c5SGeorge Rimar 646eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 647eefa758eSGeorge Rimar Cmd->Expression(Dot); 648eefa758eSGeorge Rimar continue; 649eefa758eSGeorge Rimar } 650eefa758eSGeorge Rimar 651076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 652652852c5SGeorge Rimar 65358e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 65458e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 65558e5c4dcSGeorge Rimar 656d3190795SRafael Espindola assignOffsets(Cmd); 657a14b13d8SGeorge Rimar } 658467c4d55SEugene Leviant 659aab6d5c5SRafael Espindola uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 660aab6d5c5SRafael Espindola for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 661aab6d5c5SRafael Espindola if (Sec->getFlags() & SHF_ALLOC) 662aab6d5c5SRafael Espindola MinVA = std::min(MinVA, Sec->getVA()); 663aab6d5c5SRafael Espindola else 664d3190795SRafael Espindola Sec->setVA(0); 665aab6d5c5SRafael Espindola } 666aab6d5c5SRafael Espindola 6670d4b6d5cSRafael Espindola uintX_t HeaderSize = getHeaderSize(); 6686d91fce5SRafael Espindola auto FirstPTLoad = 6696d91fce5SRafael Espindola std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry<ELFT> &E) { 6706d91fce5SRafael Espindola return E.H.p_type == PT_LOAD; 6716d91fce5SRafael Espindola }); 672db35fdf7SEugene Leviant 6736d91fce5SRafael Espindola if (HeaderSize <= MinVA && FirstPTLoad != Phdrs.end()) { 674db35fdf7SEugene Leviant // If linker script specifies program headers and first PT_LOAD doesn't 675db35fdf7SEugene Leviant // have both PHDRS and FILEHDR attributes then do nothing 676db35fdf7SEugene Leviant if (!Opt.PhdrsCommands.empty()) { 677db35fdf7SEugene Leviant size_t SegNum = std::distance(Phdrs.begin(), FirstPTLoad); 678db35fdf7SEugene Leviant if (!Opt.PhdrsCommands[SegNum].HasPhdrs || 679db35fdf7SEugene Leviant !Opt.PhdrsCommands[SegNum].HasFilehdr) 680db35fdf7SEugene Leviant return; 681db35fdf7SEugene Leviant } 68264c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 683b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 6844ec013acSRafael Espindola MinVA = alignDown(MinVA - HeaderSize, Target->PageSize); 685467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 686467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 6876d91fce5SRafael Espindola FirstPTLoad->First = Out<ELFT>::ElfHeader; 6886d91fce5SRafael Espindola if (!FirstPTLoad->Last) 6896d91fce5SRafael Espindola FirstPTLoad->Last = Out<ELFT>::ProgramHeaders; 690cd8eaf89SEugene Leviant } else if (!FirstPTLoad->First) { 691cd8eaf89SEugene Leviant // Sometimes the very first PT_LOAD segment can be empty. 692cd8eaf89SEugene Leviant // This happens if (all conditions met): 693cd8eaf89SEugene Leviant // - Linker script is used 694cd8eaf89SEugene Leviant // - First section in ELF image is not RO 695cd8eaf89SEugene Leviant // - Not enough space for program headers. 696cd8eaf89SEugene Leviant // The code below removes empty PT_LOAD segment and updates 697cd8eaf89SEugene Leviant // program headers size. 698cd8eaf89SEugene Leviant Phdrs.erase(FirstPTLoad); 699cd8eaf89SEugene Leviant Out<ELFT>::ProgramHeaders->setSize(sizeof(typename ELFT::Phdr) * 700cd8eaf89SEugene Leviant Phdrs.size()); 7016d91fce5SRafael Espindola } 702fb8978fcSDima Stepanov } 703652852c5SGeorge Rimar 704464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 70507320e40SRui Ueyama template <class ELFT> 706a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { 707edebbdf1SRui Ueyama std::vector<PhdrEntry<ELFT>> Ret; 708bbe38602SEugene Leviant 709464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 710464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 711ce30b1c7SEugene Leviant std::vector<size_t> DefPhdrIds; 712bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 713edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 714edebbdf1SRui Ueyama PhdrEntry<ELFT> &Phdr = Ret.back(); 715bbe38602SEugene Leviant 716bbe38602SEugene Leviant if (Cmd.HasFilehdr) 717adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 718bbe38602SEugene Leviant if (Cmd.HasPhdrs) 719adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 72056b21c86SEugene Leviant 72156b21c86SEugene Leviant if (Cmd.LMAExpr) { 72256b21c86SEugene Leviant Phdr.H.p_paddr = Cmd.LMAExpr(0); 72356b21c86SEugene Leviant Phdr.HasLMA = true; 72456b21c86SEugene Leviant } 725ce30b1c7SEugene Leviant 726ce30b1c7SEugene Leviant // If output section command doesn't specify any segments, 727ce30b1c7SEugene Leviant // and we haven't previously assigned any section to segment, 728ce30b1c7SEugene Leviant // then we simply assign section to the very first load segment. 729ce30b1c7SEugene Leviant // Below is an example of such linker script: 730ce30b1c7SEugene Leviant // PHDRS { seg PT_LOAD; } 731ce30b1c7SEugene Leviant // SECTIONS { .aaa : { *(.aaa) } } 732ce30b1c7SEugene Leviant if (DefPhdrIds.empty() && Phdr.H.p_type == PT_LOAD) 733ce30b1c7SEugene Leviant DefPhdrIds.push_back(Ret.size() - 1); 734bbe38602SEugene Leviant } 735bbe38602SEugene Leviant 736464daadcSRui Ueyama // Add output sections to program headers. 737464daadcSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 738bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 739bbe38602SEugene Leviant break; 740bbe38602SEugene Leviant 741edebbdf1SRui Ueyama std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName()); 742ce30b1c7SEugene Leviant if (PhdrIds.empty()) 743ce30b1c7SEugene Leviant PhdrIds = std::move(DefPhdrIds); 744ce30b1c7SEugene Leviant 745bbe38602SEugene Leviant // Assign headers specified by linker script 746bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 747edebbdf1SRui Ueyama Ret[Id].add(Sec); 748865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 7490b113671SRafael Espindola Ret[Id].H.p_flags |= Sec->getPhdrFlags(); 750bbe38602SEugene Leviant } 751ce30b1c7SEugene Leviant DefPhdrIds = std::move(PhdrIds); 752bbe38602SEugene Leviant } 753edebbdf1SRui Ueyama return Ret; 754bbe38602SEugene Leviant } 755bbe38602SEugene Leviant 756f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 757f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 758f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 759f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 760f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 761f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 762f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 763f9bc3bd2SEugene Leviant } 764f9bc3bd2SEugene Leviant 765bbe38602SEugene Leviant template <class ELFT> 76607320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 767f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 768f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 769f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 770f6c3ccefSGeorge Rimar return Cmd->Filler; 771e2ee72b5SGeorge Rimar return {}; 772e2ee72b5SGeorge Rimar } 773e2ee72b5SGeorge Rimar 774e38cbab5SGeorge Rimar template <class ELFT> 775e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { 776e38cbab5SGeorge Rimar const endianness E = ELFT::TargetEndianness; 777e38cbab5SGeorge Rimar 778e38cbab5SGeorge Rimar switch (Size) { 779e38cbab5SGeorge Rimar case 1: 780e38cbab5SGeorge Rimar *Buf = (uint8_t)Data; 781e38cbab5SGeorge Rimar break; 782e38cbab5SGeorge Rimar case 2: 783e38cbab5SGeorge Rimar write16<E>(Buf, Data); 784e38cbab5SGeorge Rimar break; 785e38cbab5SGeorge Rimar case 4: 786e38cbab5SGeorge Rimar write32<E>(Buf, Data); 787e38cbab5SGeorge Rimar break; 788e38cbab5SGeorge Rimar case 8: 789e38cbab5SGeorge Rimar write64<E>(Buf, Data); 790e38cbab5SGeorge Rimar break; 791e38cbab5SGeorge Rimar default: 792e38cbab5SGeorge Rimar llvm_unreachable("unsupported Size argument"); 793e38cbab5SGeorge Rimar } 794e38cbab5SGeorge Rimar } 795e38cbab5SGeorge Rimar 796e38cbab5SGeorge Rimar template <class ELFT> 797e38cbab5SGeorge Rimar void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) { 798e38cbab5SGeorge Rimar int I = getSectionIndex(Name); 799e38cbab5SGeorge Rimar if (I == INT_MAX) 800e38cbab5SGeorge Rimar return; 801e38cbab5SGeorge Rimar 802e38cbab5SGeorge Rimar OutputSectionCommand *Cmd = 803e38cbab5SGeorge Rimar dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()); 804e38cbab5SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base2 : Cmd->Commands) 805e38cbab5SGeorge Rimar if (auto *DataCmd = dyn_cast<BytesDataCommand>(Base2.get())) 806e38cbab5SGeorge Rimar writeInt<ELFT>(&Buf[DataCmd->Offset], DataCmd->Data, DataCmd->Size); 807e38cbab5SGeorge Rimar } 808e38cbab5SGeorge Rimar 809b71d6f7aSEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasLMA(StringRef Name) { 8108ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 8118ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 812b71d6f7aSEugene Leviant if (Cmd->LMAExpr && Cmd->Name == Name) 813b71d6f7aSEugene Leviant return true; 814b71d6f7aSEugene Leviant return false; 8158ceadb38SGeorge Rimar } 8168ceadb38SGeorge Rimar 817c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 818c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 819c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 820c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 821076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 822f510fa6bSRui Ueyama int I = 0; 823f510fa6bSRui Ueyama for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 824076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 825076fe157SGeorge Rimar if (Cmd->Name == Name) 826f510fa6bSRui Ueyama return I; 827f510fa6bSRui Ueyama ++I; 828f510fa6bSRui Ueyama } 829f510fa6bSRui Ueyama return INT_MAX; 83071b26e94SGeorge Rimar } 83171b26e94SGeorge Rimar 832bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 833bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 834bbe38602SEugene Leviant } 835bbe38602SEugene Leviant 8369e69450eSGeorge Rimar template <class ELFT> 837884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) { 83896659df0SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 83996659df0SGeorge Rimar if (Sec->getName() == Name) 84096659df0SGeorge Rimar return Sec->getVA(); 84196659df0SGeorge Rimar error("undefined section " + Name); 84296659df0SGeorge Rimar return 0; 84396659df0SGeorge Rimar } 84496659df0SGeorge Rimar 84596659df0SGeorge Rimar template <class ELFT> 846b71d6f7aSEugene Leviant uint64_t LinkerScript<ELFT>::getOutputSectionLMA(StringRef Name) { 847b71d6f7aSEugene Leviant for (OutputSectionBase<ELFT> *Sec : *OutputSections) 848b71d6f7aSEugene Leviant if (Sec->getName() == Name) 849b71d6f7aSEugene Leviant return Sec->getLMA(); 850b71d6f7aSEugene Leviant error("undefined section " + Name); 851b71d6f7aSEugene Leviant return 0; 852b71d6f7aSEugene Leviant } 853b71d6f7aSEugene Leviant 854b71d6f7aSEugene Leviant template <class ELFT> 855884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 8569e69450eSGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 8579e69450eSGeorge Rimar if (Sec->getName() == Name) 8589e69450eSGeorge Rimar return Sec->getSize(); 8599e69450eSGeorge Rimar error("undefined section " + Name); 8609e69450eSGeorge Rimar return 0; 8619e69450eSGeorge Rimar } 8629e69450eSGeorge Rimar 86336fac7f0SEugene Leviant template <class ELFT> 86436fac7f0SEugene Leviant uint64_t LinkerScript<ELFT>::getOutputSectionAlign(StringRef Name) { 86536fac7f0SEugene Leviant for (OutputSectionBase<ELFT> *Sec : *OutputSections) 86636fac7f0SEugene Leviant if (Sec->getName() == Name) 86736fac7f0SEugene Leviant return Sec->getAlignment(); 86836fac7f0SEugene Leviant error("undefined section " + Name); 86936fac7f0SEugene Leviant return 0; 87036fac7f0SEugene Leviant } 87136fac7f0SEugene Leviant 872884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() { 8730d4b6d5cSRafael Espindola return elf::getHeaderSize<ELFT>(); 874e32a3598SGeorge Rimar } 875e32a3598SGeorge Rimar 876884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) { 877884e786dSGeorge Rimar if (SymbolBody *B = Symtab<ELFT>::X->find(S)) 878884e786dSGeorge Rimar return B->getVA<ELFT>(); 879884e786dSGeorge Rimar error("symbol not found: " + S); 880884e786dSGeorge Rimar return 0; 881884e786dSGeorge Rimar } 882884e786dSGeorge Rimar 883f34f45fdSGeorge Rimar template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) { 884f34f45fdSGeorge Rimar return Symtab<ELFT>::X->find(S) != nullptr; 885f34f45fdSGeorge Rimar } 886f34f45fdSGeorge Rimar 8872f831dcaSRafael Espindola template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) { 8882f831dcaSRafael Espindola SymbolBody *Sym = Symtab<ELFT>::X->find(S); 8892f831dcaSRafael Espindola auto *DR = dyn_cast_or_null<DefinedRegular<ELFT>>(Sym); 8902f831dcaSRafael Espindola return DR && !DR->Section; 8912f831dcaSRafael Espindola } 8922f831dcaSRafael Espindola 893bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 894bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 895bbe38602SEugene Leviant // PHDRS {} script block. 896bbe38602SEugene Leviant template <class ELFT> 897edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 898076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 899076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 900edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 90131d842f5SGeorge Rimar continue; 90231d842f5SGeorge Rimar 90329c5a2a9SRui Ueyama std::vector<size_t> Ret; 90429c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 90529c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 90629c5a2a9SRui Ueyama return Ret; 907bbe38602SEugene Leviant } 90831d842f5SGeorge Rimar return {}; 90931d842f5SGeorge Rimar } 910bbe38602SEugene Leviant 91129c5a2a9SRui Ueyama template <class ELFT> 91229c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 91329c5a2a9SRui Ueyama size_t I = 0; 91429c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 91529c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 91629c5a2a9SRui Ueyama return I; 91729c5a2a9SRui Ueyama ++I; 91829c5a2a9SRui Ueyama } 91929c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 92029c5a2a9SRui Ueyama return 0; 92129c5a2a9SRui Ueyama } 92229c5a2a9SRui Ueyama 92307320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 924c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 925c3794e58SGeorge Rimar 926f7c5fbb1SRui Ueyama public: 92707320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 928f23b2320SGeorge Rimar 92920b6598cSGeorge Rimar void readLinkerScript(); 93020b6598cSGeorge Rimar void readVersionScript(); 931f7c5fbb1SRui Ueyama 932f7c5fbb1SRui Ueyama private: 93352a1509eSRui Ueyama void addFile(StringRef Path); 93452a1509eSRui Ueyama 935f7c5fbb1SRui Ueyama void readAsNeeded(); 93690c5099eSDenis Protivensky void readEntry(); 93783f406cfSGeorge Rimar void readExtern(); 938f7c5fbb1SRui Ueyama void readGroup(); 93931aa1f83SRui Ueyama void readInclude(); 940ee59282bSRui Ueyama void readOutput(); 9419159ce93SDavide Italiano void readOutputArch(); 942f7c5fbb1SRui Ueyama void readOutputFormat(); 943bbe38602SEugene Leviant void readPhdrs(); 94468a39a65SDavide Italiano void readSearchDir(); 9458e3b38abSDenis Protivensky void readSections(); 94695769b4aSRui Ueyama void readVersion(); 94795769b4aSRui Ueyama void readVersionScriptCommand(); 9488e3b38abSDenis Protivensky 949113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 950e38cbab5SGeorge Rimar BytesDataCommand *readBytesDataCommand(StringRef Tok); 951ff1f29e0SGeorge Rimar std::vector<uint8_t> readFill(); 95210416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 953ff1f29e0SGeorge Rimar std::vector<uint8_t> readOutputSectionFiller(StringRef Tok); 954bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 955a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 956db688454SEugene Leviant StringMatcher readFilePatterns(); 95707171f21SGeorge Rimar std::vector<SectionPattern> readInputSectionsList(); 958a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 959bbe38602SEugene Leviant unsigned readPhdrType(); 960be394db3SGeorge Rimar SortSectionPolicy readSortKind(); 961a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 962c96da110SRafael Espindola SymbolAssignment *readProvideOrAssignment(StringRef Tok); 96303fc010eSGeorge Rimar void readSort(); 964eefa758eSGeorge Rimar Expr readAssert(); 965708019c4SRui Ueyama 966708019c4SRui Ueyama Expr readExpr(); 967708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 968b71d6f7aSEugene Leviant StringRef readParenLiteral(); 969708019c4SRui Ueyama Expr readPrimary(); 970708019c4SRui Ueyama Expr readTernary(Expr Cond); 9716ad7dfccSRui Ueyama Expr readParenExpr(); 972f7c5fbb1SRui Ueyama 97320b6598cSGeorge Rimar // For parsing version script. 97420b6598cSGeorge Rimar void readExtern(std::vector<SymbolVersion> *Globals); 97595769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 97620b6598cSGeorge Rimar void readGlobal(StringRef VerStr); 97720b6598cSGeorge Rimar void readLocal(); 97820b6598cSGeorge Rimar 97907320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 98016b0cc9eSSimon Atanasyan bool IsUnderSysroot; 981f7c5fbb1SRui Ueyama }; 982f7c5fbb1SRui Ueyama 98320b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 98495769b4aSRui Ueyama readVersionScriptCommand(); 98520b6598cSGeorge Rimar if (!atEOF()) 98695769b4aSRui Ueyama setError("EOF expected, but got " + next()); 98795769b4aSRui Ueyama } 98895769b4aSRui Ueyama 98995769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 99083043f23SRui Ueyama if (consume("{")) { 99195769b4aSRui Ueyama readVersionDeclaration(""); 99220b6598cSGeorge Rimar return; 99320b6598cSGeorge Rimar } 99420b6598cSGeorge Rimar 99595769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 99620b6598cSGeorge Rimar StringRef VerStr = next(); 99720b6598cSGeorge Rimar if (VerStr == "{") { 99895769b4aSRui Ueyama setError("anonymous version definition is used in " 99995769b4aSRui Ueyama "combination with other version definitions"); 100020b6598cSGeorge Rimar return; 100120b6598cSGeorge Rimar } 100220b6598cSGeorge Rimar expect("{"); 100395769b4aSRui Ueyama readVersionDeclaration(VerStr); 100420b6598cSGeorge Rimar } 100520b6598cSGeorge Rimar } 100620b6598cSGeorge Rimar 100795769b4aSRui Ueyama void ScriptParser::readVersion() { 100895769b4aSRui Ueyama expect("{"); 100995769b4aSRui Ueyama readVersionScriptCommand(); 101095769b4aSRui Ueyama expect("}"); 101195769b4aSRui Ueyama } 101295769b4aSRui Ueyama 101320b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 1014f7c5fbb1SRui Ueyama while (!atEOF()) { 1015f7c5fbb1SRui Ueyama StringRef Tok = next(); 1016a27eeccaSRui Ueyama if (Tok == ";") 1017a27eeccaSRui Ueyama continue; 1018a27eeccaSRui Ueyama 101920d03194SEugene Leviant if (Tok == "ASSERT") { 102020d03194SEugene Leviant Opt.Commands.emplace_back(new AssertCommand(readAssert())); 102120d03194SEugene Leviant } else if (Tok == "ENTRY") { 1022a27eeccaSRui Ueyama readEntry(); 1023a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 1024a27eeccaSRui Ueyama readExtern(); 1025a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 1026a27eeccaSRui Ueyama readGroup(); 1027a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 1028a27eeccaSRui Ueyama readInclude(); 1029a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 1030a27eeccaSRui Ueyama readOutput(); 1031a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 1032a27eeccaSRui Ueyama readOutputArch(); 1033a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 1034a27eeccaSRui Ueyama readOutputFormat(); 1035a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 1036a27eeccaSRui Ueyama readPhdrs(); 1037a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 1038a27eeccaSRui Ueyama readSearchDir(); 1039a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 1040a27eeccaSRui Ueyama readSections(); 1041a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 1042a27eeccaSRui Ueyama readVersion(); 1043c96da110SRafael Espindola } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { 10440df80befSPetr Hosek Opt.Commands.emplace_back(Cmd); 1045e5d3ca50SPetr Hosek } else { 10465761042dSGeorge Rimar setError("unknown directive: " + Tok); 1047f7c5fbb1SRui Ueyama } 1048f7c5fbb1SRui Ueyama } 1049e5d3ca50SPetr Hosek } 1050f7c5fbb1SRui Ueyama 1051717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 105216b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 10535af1687fSJustin Bogner SmallString<128> PathData; 10545af1687fSJustin Bogner StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 105516b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 10565af1687fSJustin Bogner Driver->addFile(Saver.save(Path)); 105716b0cc9eSSimon Atanasyan return; 105816b0cc9eSSimon Atanasyan } 105916b0cc9eSSimon Atanasyan } 106016b0cc9eSSimon Atanasyan 1061f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 106252a1509eSRui Ueyama Driver->addFile(S); 106352a1509eSRui Ueyama } else if (S.startswith("=")) { 106452a1509eSRui Ueyama if (Config->Sysroot.empty()) 106552a1509eSRui Ueyama Driver->addFile(S.substr(1)); 106652a1509eSRui Ueyama else 106752a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 106852a1509eSRui Ueyama } else if (S.startswith("-l")) { 106921eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 1070a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 1071a1b8fc3bSSimon Atanasyan Driver->addFile(S); 107252a1509eSRui Ueyama } else { 107352a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 107452a1509eSRui Ueyama if (Path.empty()) 1075777f9630SGeorge Rimar setError("unable to find " + S); 1076025d59b1SRui Ueyama else 107752a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 107852a1509eSRui Ueyama } 107952a1509eSRui Ueyama } 108052a1509eSRui Ueyama 1081717677afSRui Ueyama void ScriptParser::readAsNeeded() { 1082f7c5fbb1SRui Ueyama expect("("); 108335da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 108435da9b6eSRui Ueyama Config->AsNeeded = true; 108583043f23SRui Ueyama while (!Error && !consume(")")) 1086cd574a5eSGeorge Rimar addFile(unquote(next())); 108735da9b6eSRui Ueyama Config->AsNeeded = Orig; 1088f7c5fbb1SRui Ueyama } 1089f7c5fbb1SRui Ueyama 1090717677afSRui Ueyama void ScriptParser::readEntry() { 109190c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 109290c5099eSDenis Protivensky expect("("); 109390c5099eSDenis Protivensky StringRef Tok = next(); 109490c5099eSDenis Protivensky if (Config->Entry.empty()) 109590c5099eSDenis Protivensky Config->Entry = Tok; 109690c5099eSDenis Protivensky expect(")"); 109790c5099eSDenis Protivensky } 109890c5099eSDenis Protivensky 1099717677afSRui Ueyama void ScriptParser::readExtern() { 110083f406cfSGeorge Rimar expect("("); 110183043f23SRui Ueyama while (!Error && !consume(")")) 1102a2acc931SRui Ueyama Config->Undefined.push_back(next()); 110383f406cfSGeorge Rimar } 110483f406cfSGeorge Rimar 1105717677afSRui Ueyama void ScriptParser::readGroup() { 1106f7c5fbb1SRui Ueyama expect("("); 110783043f23SRui Ueyama while (!Error && !consume(")")) { 1108f7c5fbb1SRui Ueyama StringRef Tok = next(); 1109a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 1110f7c5fbb1SRui Ueyama readAsNeeded(); 1111a2acc931SRui Ueyama else 1112cd574a5eSGeorge Rimar addFile(unquote(Tok)); 1113f7c5fbb1SRui Ueyama } 1114f7c5fbb1SRui Ueyama } 1115f7c5fbb1SRui Ueyama 1116717677afSRui Ueyama void ScriptParser::readInclude() { 111731aa1f83SRui Ueyama StringRef Tok = next(); 1118cd574a5eSGeorge Rimar auto MBOrErr = MemoryBuffer::getFile(unquote(Tok)); 1119025d59b1SRui Ueyama if (!MBOrErr) { 11205761042dSGeorge Rimar setError("cannot open " + Tok); 1121025d59b1SRui Ueyama return; 1122025d59b1SRui Ueyama } 112331aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 1124a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 1125a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 112631aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 112731aa1f83SRui Ueyama } 112831aa1f83SRui Ueyama 1129717677afSRui Ueyama void ScriptParser::readOutput() { 1130ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 1131ee59282bSRui Ueyama expect("("); 1132ee59282bSRui Ueyama StringRef Tok = next(); 1133ee59282bSRui Ueyama if (Config->OutputFile.empty()) 1134cd574a5eSGeorge Rimar Config->OutputFile = unquote(Tok); 1135ee59282bSRui Ueyama expect(")"); 1136ee59282bSRui Ueyama } 1137ee59282bSRui Ueyama 1138717677afSRui Ueyama void ScriptParser::readOutputArch() { 11399159ce93SDavide Italiano // Error checking only for now. 11409159ce93SDavide Italiano expect("("); 11415424e7c7SJustin Bogner skip(); 11429159ce93SDavide Italiano expect(")"); 11439159ce93SDavide Italiano } 11449159ce93SDavide Italiano 1145717677afSRui Ueyama void ScriptParser::readOutputFormat() { 1146f7c5fbb1SRui Ueyama // Error checking only for now. 1147f7c5fbb1SRui Ueyama expect("("); 11485424e7c7SJustin Bogner skip(); 11496836c618SDavide Italiano StringRef Tok = next(); 11506836c618SDavide Italiano if (Tok == ")") 11516836c618SDavide Italiano return; 1152025d59b1SRui Ueyama if (Tok != ",") { 11535761042dSGeorge Rimar setError("unexpected token: " + Tok); 1154025d59b1SRui Ueyama return; 1155025d59b1SRui Ueyama } 11565424e7c7SJustin Bogner skip(); 11576836c618SDavide Italiano expect(","); 11585424e7c7SJustin Bogner skip(); 1159f7c5fbb1SRui Ueyama expect(")"); 1160f7c5fbb1SRui Ueyama } 1161f7c5fbb1SRui Ueyama 1162bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 1163bbe38602SEugene Leviant expect("{"); 116483043f23SRui Ueyama while (!Error && !consume("}")) { 1165bbe38602SEugene Leviant StringRef Tok = next(); 116656b21c86SEugene Leviant Opt.PhdrsCommands.push_back( 116756b21c86SEugene Leviant {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 1168bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 1169bbe38602SEugene Leviant 1170bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 1171bbe38602SEugene Leviant do { 1172bbe38602SEugene Leviant Tok = next(); 1173bbe38602SEugene Leviant if (Tok == ";") 1174bbe38602SEugene Leviant break; 1175bbe38602SEugene Leviant if (Tok == "FILEHDR") 1176bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 1177bbe38602SEugene Leviant else if (Tok == "PHDRS") 1178bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 117956b21c86SEugene Leviant else if (Tok == "AT") 118056b21c86SEugene Leviant PhdrCmd.LMAExpr = readParenExpr(); 1181865bf863SEugene Leviant else if (Tok == "FLAGS") { 1182865bf863SEugene Leviant expect("("); 1183eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 1184eb685cd7SRafael Espindola // we accept expressions like ".|1". 1185eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 1186865bf863SEugene Leviant expect(")"); 1187865bf863SEugene Leviant } else 1188bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 1189bbe38602SEugene Leviant } while (!Error); 1190bbe38602SEugene Leviant } 1191bbe38602SEugene Leviant } 1192bbe38602SEugene Leviant 1193717677afSRui Ueyama void ScriptParser::readSearchDir() { 119468a39a65SDavide Italiano expect("("); 119586c5fb82SRui Ueyama StringRef Tok = next(); 11966c7ad13fSRui Ueyama if (!Config->Nostdlib) 1197cd574a5eSGeorge Rimar Config->SearchPaths.push_back(unquote(Tok)); 119868a39a65SDavide Italiano expect(")"); 119968a39a65SDavide Italiano } 120068a39a65SDavide Italiano 1201717677afSRui Ueyama void ScriptParser::readSections() { 1202e05336ffSEugene Leviant Opt.HasSections = true; 12038e3b38abSDenis Protivensky expect("{"); 120483043f23SRui Ueyama while (!Error && !consume("}")) { 1205113cdec9SRui Ueyama StringRef Tok = next(); 1206c96da110SRafael Espindola BaseCommand *Cmd = readProvideOrAssignment(Tok); 1207ceabe80eSEugene Leviant if (!Cmd) { 1208ceabe80eSEugene Leviant if (Tok == "ASSERT") 1209eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 1210ceabe80eSEugene Leviant else 121110416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 12128e3b38abSDenis Protivensky } 121310416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 1214652852c5SGeorge Rimar } 1215708019c4SRui Ueyama } 12168e3b38abSDenis Protivensky 1217708019c4SRui Ueyama static int precedence(StringRef Op) { 1218708019c4SRui Ueyama return StringSwitch<int>(Op) 12190120e3f2SRui Ueyama .Cases("*", "/", 5) 12200120e3f2SRui Ueyama .Cases("+", "-", 4) 12210120e3f2SRui Ueyama .Cases("<<", ">>", 3) 12229c4ac5f2SRui Ueyama .Cases("<", "<=", ">", ">=", "==", "!=", 2) 12230120e3f2SRui Ueyama .Cases("&", "|", 1) 1224708019c4SRui Ueyama .Default(-1); 1225708019c4SRui Ueyama } 1226708019c4SRui Ueyama 1227db688454SEugene Leviant StringMatcher ScriptParser::readFilePatterns() { 122810416564SRui Ueyama std::vector<StringRef> V; 122983043f23SRui Ueyama while (!Error && !consume(")")) 123010416564SRui Ueyama V.push_back(next()); 1231f91282e1SRui Ueyama return StringMatcher(V); 12320702c4e8SGeorge Rimar } 12330702c4e8SGeorge Rimar 1234be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() { 123583043f23SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 1236be394db3SGeorge Rimar return SortSectionPolicy::Name; 123783043f23SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 1238be394db3SGeorge Rimar return SortSectionPolicy::Alignment; 123983043f23SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 1240be394db3SGeorge Rimar return SortSectionPolicy::Priority; 124183043f23SRui Ueyama if (consume("SORT_NONE")) 1242be394db3SGeorge Rimar return SortSectionPolicy::None; 1243b2a0abdfSRui Ueyama return SortSectionPolicy::Default; 1244be394db3SGeorge Rimar } 1245be394db3SGeorge Rimar 1246395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in 1247395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ 1248395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) 1249af03be19SGeorge Rimar // The semantics of that is next: 1250af03be19SGeorge Rimar // * Include .foo.1 from every file. 1251af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o 1252af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o 125307171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 125407171f21SGeorge Rimar std::vector<SectionPattern> Ret; 1255601e9898SGeorge Rimar while (!Error && peek() != ")") { 1256f91282e1SRui Ueyama StringMatcher ExcludeFilePat; 125783043f23SRui Ueyama if (consume("EXCLUDE_FILE")) { 1258395281cfSGeorge Rimar expect("("); 1259f91282e1SRui Ueyama ExcludeFilePat = readFilePatterns(); 1260395281cfSGeorge Rimar } 1261395281cfSGeorge Rimar 1262601e9898SGeorge Rimar std::vector<StringRef> V; 1263601e9898SGeorge Rimar while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE") 1264395281cfSGeorge Rimar V.push_back(next()); 1265601e9898SGeorge Rimar 1266601e9898SGeorge Rimar if (!V.empty()) 1267f91282e1SRui Ueyama Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); 1268601e9898SGeorge Rimar else 1269601e9898SGeorge Rimar setError("section pattern is expected"); 1270395281cfSGeorge Rimar } 127107171f21SGeorge Rimar return Ret; 1272395281cfSGeorge Rimar } 1273395281cfSGeorge Rimar 127407171f21SGeorge Rimar // Section pattern grammar can have complex expressions, for example: 127507171f21SGeorge Rimar // *(SORT(.foo.* EXCLUDE_FILE (*file1.o) .bar.*) .bar.* SORT(.zed.*)) 127607171f21SGeorge Rimar // Generally is a sequence of globs and excludes that may be wrapped in a SORT() 127707171f21SGeorge Rimar // commands, like: SORT(glob0) glob1 glob2 SORT(glob4) 127807171f21SGeorge Rimar // This methods handles wrapping sequences of excluded files and section globs 127907171f21SGeorge Rimar // into SORT() if that needed and reads them all. 1280a2496cbeSGeorge Rimar InputSectionDescription * 1281a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 1282c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 12830ed42b0cSDavide Italiano expect("("); 128483043f23SRui Ueyama while (!HasError && !consume(")")) { 128507171f21SGeorge Rimar SortSectionPolicy Outer = readSortKind(); 128607171f21SGeorge Rimar SortSectionPolicy Inner = SortSectionPolicy::Default; 128707171f21SGeorge Rimar std::vector<SectionPattern> V; 128807171f21SGeorge Rimar if (Outer != SortSectionPolicy::Default) { 12890702c4e8SGeorge Rimar expect("("); 129007171f21SGeorge Rimar Inner = readSortKind(); 129107171f21SGeorge Rimar if (Inner != SortSectionPolicy::Default) { 1292350ece4eSGeorge Rimar expect("("); 129307171f21SGeorge Rimar V = readInputSectionsList(); 12940702c4e8SGeorge Rimar expect(")"); 1295350ece4eSGeorge Rimar } else { 129607171f21SGeorge Rimar V = readInputSectionsList(); 1297350ece4eSGeorge Rimar } 1298350ece4eSGeorge Rimar expect(")"); 129907171f21SGeorge Rimar } else { 130007171f21SGeorge Rimar V = readInputSectionsList(); 13010659800eSGeorge Rimar } 13020702c4e8SGeorge Rimar 130307171f21SGeorge Rimar for (SectionPattern &Pat : V) { 130407171f21SGeorge Rimar Pat.SortInner = Inner; 130507171f21SGeorge Rimar Pat.SortOuter = Outer; 130607171f21SGeorge Rimar } 130707171f21SGeorge Rimar 130807171f21SGeorge Rimar std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 130907171f21SGeorge Rimar } 131010416564SRui Ueyama return Cmd; 13110659800eSGeorge Rimar } 13120659800eSGeorge Rimar 1313a2496cbeSGeorge Rimar InputSectionDescription * 1314a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 13150659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 13160659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 1317a2496cbeSGeorge Rimar if (Tok == "KEEP") { 1318e7282797SDavide Italiano expect("("); 1319a2496cbeSGeorge Rimar StringRef FilePattern = next(); 1320a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 13210ed42b0cSDavide Italiano expect(")"); 1322cf43f179SEugene Leviant Opt.KeptSections.push_back(Cmd); 132310416564SRui Ueyama return Cmd; 132410416564SRui Ueyama } 1325a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 13260659800eSGeorge Rimar } 13270659800eSGeorge Rimar 132803fc010eSGeorge Rimar void ScriptParser::readSort() { 132903fc010eSGeorge Rimar expect("("); 133003fc010eSGeorge Rimar expect("CONSTRUCTORS"); 133103fc010eSGeorge Rimar expect(")"); 133203fc010eSGeorge Rimar } 133303fc010eSGeorge Rimar 1334eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 1335eefa758eSGeorge Rimar expect("("); 1336eefa758eSGeorge Rimar Expr E = readExpr(); 1337eefa758eSGeorge Rimar expect(","); 1338cd574a5eSGeorge Rimar StringRef Msg = unquote(next()); 1339eefa758eSGeorge Rimar expect(")"); 1340eefa758eSGeorge Rimar return [=](uint64_t Dot) { 1341eefa758eSGeorge Rimar uint64_t V = E(Dot); 1342eefa758eSGeorge Rimar if (!V) 1343eefa758eSGeorge Rimar error(Msg); 1344eefa758eSGeorge Rimar return V; 1345eefa758eSGeorge Rimar }; 1346eefa758eSGeorge Rimar } 1347eefa758eSGeorge Rimar 134825150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 134925150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from 135025150e8bSRui Ueyama // what GNU linkers do. 135125150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 1352ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readFill() { 1353ff1f29e0SGeorge Rimar expect("("); 1354ff1f29e0SGeorge Rimar std::vector<uint8_t> V = readOutputSectionFiller(next()); 1355ff1f29e0SGeorge Rimar expect(")"); 1356ff1f29e0SGeorge Rimar expect(";"); 1357ff1f29e0SGeorge Rimar return V; 1358ff1f29e0SGeorge Rimar } 1359ff1f29e0SGeorge Rimar 136010416564SRui Ueyama OutputSectionCommand * 136110416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 1362076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 136358e5c4dcSGeorge Rimar 136458e5c4dcSGeorge Rimar // Read an address expression. 136558e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 136658e5c4dcSGeorge Rimar if (peek() != ":") 136758e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 136858e5c4dcSGeorge Rimar 13698e3b38abSDenis Protivensky expect(":"); 1370246f681eSDavide Italiano 137183043f23SRui Ueyama if (consume("AT")) 1372b71d6f7aSEugene Leviant Cmd->LMAExpr = readParenExpr(); 137383043f23SRui Ueyama if (consume("ALIGN")) 13746ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 137583043f23SRui Ueyama if (consume("SUBALIGN")) 1376db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1377630c6179SGeorge Rimar 1378246f681eSDavide Italiano // Parse constraints. 137983043f23SRui Ueyama if (consume("ONLY_IF_RO")) 1380efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 138183043f23SRui Ueyama if (consume("ONLY_IF_RW")) 1382efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 13838e3b38abSDenis Protivensky expect("{"); 13848ec77e64SRui Ueyama 138583043f23SRui Ueyama while (!Error && !consume("}")) { 1386ceabe80eSEugene Leviant StringRef Tok = next(); 1387c96da110SRafael Espindola if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) 1388ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1389e38cbab5SGeorge Rimar else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) 1390e38cbab5SGeorge Rimar Cmd->Commands.emplace_back(Data); 1391ff1f29e0SGeorge Rimar else if (Tok == "FILL") 1392ff1f29e0SGeorge Rimar Cmd->Filler = readFill(); 1393ceabe80eSEugene Leviant else if (Tok == "SORT") 139403fc010eSGeorge Rimar readSort(); 1395a2496cbeSGeorge Rimar else if (peek() == "(") 1396a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1397ceabe80eSEugene Leviant else 1398ceabe80eSEugene Leviant setError("unknown command " + Tok); 13998e3b38abSDenis Protivensky } 1400076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 14014ebc5620SGeorge Rimar 140283043f23SRui Ueyama if (consume("=")) 14034ebc5620SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next()); 14044ebc5620SGeorge Rimar else if (peek().startswith("=")) 1405ff1f29e0SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next().drop_front()); 14064ebc5620SGeorge Rimar 140710416564SRui Ueyama return Cmd; 1408f71caa2bSRui Ueyama } 14098ec77e64SRui Ueyama 14102c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 14112c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 14122c8f1f04SRui Ueyama // 14132c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 14142c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 14152c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 14162c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 1417ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readOutputSectionFiller(StringRef Tok) { 1418965827d6SRui Ueyama uint32_t V; 1419ff1f29e0SGeorge Rimar if (Tok.getAsInteger(0, V)) { 1420965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 1421f71caa2bSRui Ueyama return {}; 1422e2ee72b5SGeorge Rimar } 1423965827d6SRui Ueyama return {uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V)}; 14248e3b38abSDenis Protivensky } 14258e3b38abSDenis Protivensky 1426a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1427a31c91b1SEugene Leviant expect("("); 1428174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1429a35e39caSPetr Hosek Cmd->Provide = Provide; 1430174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1431a31c91b1SEugene Leviant expect(")"); 1432a31c91b1SEugene Leviant expect(";"); 143310416564SRui Ueyama return Cmd; 1434eda81a1bSEugene Leviant } 1435eda81a1bSEugene Leviant 1436c96da110SRafael Espindola SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 1437ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1438ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1439ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1440ceabe80eSEugene Leviant expect(";"); 1441ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1442a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1443a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1444a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1445ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1446a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1447ceabe80eSEugene Leviant } 1448ceabe80eSEugene Leviant return Cmd; 1449ceabe80eSEugene Leviant } 1450ceabe80eSEugene Leviant 145130835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { 145230835ea4SGeorge Rimar if (S == ".") 145330835ea4SGeorge Rimar return Dot; 1454884e786dSGeorge Rimar return ScriptBase->getSymbolValue(S); 1455e32a3598SGeorge Rimar } 1456e32a3598SGeorge Rimar 14572f831dcaSRafael Espindola static bool isAbsolute(StringRef S) { 14582f831dcaSRafael Espindola if (S == ".") 14592f831dcaSRafael Espindola return false; 14602f831dcaSRafael Espindola return ScriptBase->isAbsolute(S); 14612f831dcaSRafael Espindola } 14622f831dcaSRafael Espindola 146330835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 146430835ea4SGeorge Rimar StringRef Op = next(); 1465db741e72SEugene Leviant Expr E; 146630835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 146783043f23SRui Ueyama if (consume("ABSOLUTE")) { 14687c1381a0SRui Ueyama // The RHS may be something like "ABSOLUTE(.) & 0xff". 14697c1381a0SRui Ueyama // Call readExpr1 to read the whole expression. 14707c1381a0SRui Ueyama E = readExpr1(readParenExpr(), 0); 14712f831dcaSRafael Espindola E.IsAbsolute = []() { return true; }; 1472db741e72SEugene Leviant } else { 1473db741e72SEugene Leviant E = readExpr(); 1474db741e72SEugene Leviant } 147530835ea4SGeorge Rimar if (Op == "+=") 147630835ea4SGeorge Rimar E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; 1477f661393aSRafael Espindola return new SymbolAssignment(Name, E); 147830835ea4SGeorge Rimar } 147930835ea4SGeorge Rimar 148030835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 148130835ea4SGeorge Rimar // script expression. 148230835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 148330835ea4SGeorge Rimar 148436c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 148536c1cd23SRui Ueyama if (Op == "*") 148636c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 148736c1cd23SRui Ueyama if (Op == "/") { 148836c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 148936c1cd23SRui Ueyama uint64_t RHS = R(Dot); 149036c1cd23SRui Ueyama if (RHS == 0) { 149136c1cd23SRui Ueyama error("division by zero"); 149236c1cd23SRui Ueyama return 0; 149336c1cd23SRui Ueyama } 149436c1cd23SRui Ueyama return L(Dot) / RHS; 149536c1cd23SRui Ueyama }; 149636c1cd23SRui Ueyama } 149736c1cd23SRui Ueyama if (Op == "+") 14982f831dcaSRafael Espindola return {[=](uint64_t Dot) { return L(Dot) + R(Dot); }, 14992f831dcaSRafael Espindola [=]() { return L.IsAbsolute() && R.IsAbsolute(); }}; 150036c1cd23SRui Ueyama if (Op == "-") 150136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 1502c8ccd1f1SGeorge Rimar if (Op == "<<") 1503c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) << R(Dot); }; 1504c8ccd1f1SGeorge Rimar if (Op == ">>") 1505c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) >> R(Dot); }; 150636c1cd23SRui Ueyama if (Op == "<") 150736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 150836c1cd23SRui Ueyama if (Op == ">") 150936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 151036c1cd23SRui Ueyama if (Op == ">=") 151136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 151236c1cd23SRui Ueyama if (Op == "<=") 151336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 151436c1cd23SRui Ueyama if (Op == "==") 151536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 151636c1cd23SRui Ueyama if (Op == "!=") 151736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 151836c1cd23SRui Ueyama if (Op == "&") 151936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 1520cc3dd629SRafael Espindola if (Op == "|") 1521cc3dd629SRafael Espindola return [=](uint64_t Dot) { return L(Dot) | R(Dot); }; 152236c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 152336c1cd23SRui Ueyama } 152436c1cd23SRui Ueyama 1525708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1526708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1527708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1528708019c4SRui Ueyama while (!atEOF() && !Error) { 1529708019c4SRui Ueyama // Read an operator and an expression. 1530708019c4SRui Ueyama StringRef Op1 = peek(); 1531708019c4SRui Ueyama if (Op1 == "?") 1532708019c4SRui Ueyama return readTernary(Lhs); 1533708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1534a31c91b1SEugene Leviant break; 15355424e7c7SJustin Bogner skip(); 1536708019c4SRui Ueyama Expr Rhs = readPrimary(); 1537708019c4SRui Ueyama 1538708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1539708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1540708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1541708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1542708019c4SRui Ueyama while (!atEOF()) { 1543708019c4SRui Ueyama StringRef Op2 = peek(); 1544708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1545eda81a1bSEugene Leviant break; 1546708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1547eda81a1bSEugene Leviant } 1548708019c4SRui Ueyama 1549708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1550708019c4SRui Ueyama } 1551708019c4SRui Ueyama return Lhs; 1552708019c4SRui Ueyama } 1553708019c4SRui Ueyama 1554708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1555e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1556708019c4SRui Ueyama return Target->PageSize; 1557e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1558997f8838SPetr Hosek return Config->MaxPageSize; 1559708019c4SRui Ueyama error("unknown constant: " + S); 1560708019c4SRui Ueyama return 0; 1561708019c4SRui Ueyama } 1562708019c4SRui Ueyama 1563626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1564626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1565626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1566626e0b08SRui Ueyama // "M" (mega) prefixes. 15679f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 1568eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1569eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1570eaeafb2bSSimon Atanasyan return false; 1571eaeafb2bSSimon Atanasyan Result = -Result; 1572eaeafb2bSSimon Atanasyan return true; 1573eaeafb2bSSimon Atanasyan } 15749f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 15759f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 15769f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 15779f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 15789f2f7ad9SGeorge Rimar 15799f2f7ad9SGeorge Rimar int Suffix = 1; 15809f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 15819f2f7ad9SGeorge Rimar Suffix = 1024; 15829f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 15839f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 15849f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 15859f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 15869f2f7ad9SGeorge Rimar } 15879f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 15889f2f7ad9SGeorge Rimar return false; 15899f2f7ad9SGeorge Rimar Result *= Suffix; 15909f2f7ad9SGeorge Rimar return true; 15919f2f7ad9SGeorge Rimar } 15929f2f7ad9SGeorge Rimar 1593e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { 1594e38cbab5SGeorge Rimar int Size = StringSwitch<unsigned>(Tok) 1595e38cbab5SGeorge Rimar .Case("BYTE", 1) 1596e38cbab5SGeorge Rimar .Case("SHORT", 2) 1597e38cbab5SGeorge Rimar .Case("LONG", 4) 1598e38cbab5SGeorge Rimar .Case("QUAD", 8) 1599e38cbab5SGeorge Rimar .Default(-1); 1600e38cbab5SGeorge Rimar if (Size == -1) 1601e38cbab5SGeorge Rimar return nullptr; 1602e38cbab5SGeorge Rimar 1603e38cbab5SGeorge Rimar expect("("); 1604e38cbab5SGeorge Rimar uint64_t Val = 0; 1605e38cbab5SGeorge Rimar StringRef S = next(); 1606e38cbab5SGeorge Rimar if (!readInteger(S, Val)) 1607e38cbab5SGeorge Rimar setError("unexpected value: " + S); 1608e38cbab5SGeorge Rimar expect(")"); 1609e38cbab5SGeorge Rimar return new BytesDataCommand(Val, Size); 1610e38cbab5SGeorge Rimar } 1611e38cbab5SGeorge Rimar 1612b71d6f7aSEugene Leviant StringRef ScriptParser::readParenLiteral() { 1613b71d6f7aSEugene Leviant expect("("); 1614b71d6f7aSEugene Leviant StringRef Tok = next(); 1615b71d6f7aSEugene Leviant expect(")"); 1616b71d6f7aSEugene Leviant return Tok; 1617b71d6f7aSEugene Leviant } 1618b71d6f7aSEugene Leviant 1619708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 16206ad7dfccSRui Ueyama if (peek() == "(") 16216ad7dfccSRui Ueyama return readParenExpr(); 1622708019c4SRui Ueyama 16236ad7dfccSRui Ueyama StringRef Tok = next(); 1624708019c4SRui Ueyama 1625eaeafb2bSSimon Atanasyan if (Tok == "~") { 1626eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1627eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return ~E(Dot); }; 1628eaeafb2bSSimon Atanasyan } 1629eaeafb2bSSimon Atanasyan if (Tok == "-") { 1630eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1631eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return -E(Dot); }; 1632eaeafb2bSSimon Atanasyan } 1633eaeafb2bSSimon Atanasyan 1634708019c4SRui Ueyama // Built-in functions are parsed here. 1635708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 163696659df0SGeorge Rimar if (Tok == "ADDR") { 1637b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1638884e786dSGeorge Rimar return 1639884e786dSGeorge Rimar [=](uint64_t Dot) { return ScriptBase->getOutputSectionAddress(Name); }; 164096659df0SGeorge Rimar } 1641b71d6f7aSEugene Leviant if (Tok == "LOADADDR") { 1642b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1643b71d6f7aSEugene Leviant return [=](uint64_t Dot) { return ScriptBase->getOutputSectionLMA(Name); }; 1644b71d6f7aSEugene Leviant } 1645eefa758eSGeorge Rimar if (Tok == "ASSERT") 1646eefa758eSGeorge Rimar return readAssert(); 1647708019c4SRui Ueyama if (Tok == "ALIGN") { 16486ad7dfccSRui Ueyama Expr E = readParenExpr(); 1649708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1650708019c4SRui Ueyama } 1651708019c4SRui Ueyama if (Tok == "CONSTANT") { 1652b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1653b0de56b5SRafael Espindola return [=](uint64_t Dot) { return getConstant(Name); }; 1654708019c4SRui Ueyama } 1655f34f45fdSGeorge Rimar if (Tok == "DEFINED") { 1656f34f45fdSGeorge Rimar expect("("); 1657f34f45fdSGeorge Rimar StringRef Tok = next(); 1658f34f45fdSGeorge Rimar expect(")"); 1659f2821028SGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->isDefined(Tok) ? 1 : 0; }; 1660f34f45fdSGeorge Rimar } 166154c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 166254c145ceSRafael Espindola expect("("); 16635424e7c7SJustin Bogner skip(); 166454c145ceSRafael Espindola expect(","); 16658c658bf8SGeorge Rimar Expr E = readExpr(); 166654c145ceSRafael Espindola expect(")"); 16678c658bf8SGeorge Rimar return [=](uint64_t Dot) { return E(Dot); }; 166854c145ceSRafael Espindola } 1669708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1670708019c4SRui Ueyama expect("("); 1671708019c4SRui Ueyama Expr E = readExpr(); 1672708019c4SRui Ueyama expect(","); 1673708019c4SRui Ueyama readExpr(); 1674708019c4SRui Ueyama expect(")"); 1675f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1676708019c4SRui Ueyama } 1677708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1678708019c4SRui Ueyama expect("("); 1679708019c4SRui Ueyama expect("."); 1680708019c4SRui Ueyama expect(")"); 1681708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1682708019c4SRui Ueyama } 1683276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1684276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1685276b4e64SGeorge Rimar // the next page boundary for simplicity. 1686276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1687276b4e64SGeorge Rimar expect("("); 168897bdc722SRafael Espindola readExpr(); 1689276b4e64SGeorge Rimar expect(","); 1690276b4e64SGeorge Rimar readExpr(); 1691276b4e64SGeorge Rimar expect(")"); 1692276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1693276b4e64SGeorge Rimar } 16949e69450eSGeorge Rimar if (Tok == "SIZEOF") { 1695b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1696b0de56b5SRafael Espindola return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; 16979e69450eSGeorge Rimar } 169836fac7f0SEugene Leviant if (Tok == "ALIGNOF") { 1699b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1700b0de56b5SRafael Espindola return 1701b0de56b5SRafael Espindola [=](uint64_t Dot) { return ScriptBase->getOutputSectionAlign(Name); }; 170236fac7f0SEugene Leviant } 1703e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 1704b0de56b5SRafael Espindola return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; 1705708019c4SRui Ueyama 17069f2f7ad9SGeorge Rimar // Tok is a literal number. 17079f2f7ad9SGeorge Rimar uint64_t V; 17089f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 1709b0de56b5SRafael Espindola return [=](uint64_t Dot) { return V; }; 17109f2f7ad9SGeorge Rimar 17119f2f7ad9SGeorge Rimar // Tok is a symbol name. 171230835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1713708019c4SRui Ueyama setError("malformed number: " + Tok); 17142f831dcaSRafael Espindola return {[=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }, 17152f831dcaSRafael Espindola [=]() { return isAbsolute(Tok); }}; 1716a9c5a528SGeorge Rimar } 1717708019c4SRui Ueyama 1718708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 17195424e7c7SJustin Bogner skip(); 1720708019c4SRui Ueyama Expr L = readExpr(); 1721708019c4SRui Ueyama expect(":"); 1722708019c4SRui Ueyama Expr R = readExpr(); 1723708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1724708019c4SRui Ueyama } 1725708019c4SRui Ueyama 17266ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 17276ad7dfccSRui Ueyama expect("("); 17286ad7dfccSRui Ueyama Expr E = readExpr(); 17296ad7dfccSRui Ueyama expect(")"); 17306ad7dfccSRui Ueyama return E; 17316ad7dfccSRui Ueyama } 17326ad7dfccSRui Ueyama 1733bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1734bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1735bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1736bbe38602SEugene Leviant StringRef Tok = next(); 1737bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 1738bbe38602SEugene Leviant if (Tok.empty()) { 1739bbe38602SEugene Leviant setError("section header name is empty"); 1740bbe38602SEugene Leviant break; 1741bbe38602SEugene Leviant } 1742bbe38602SEugene Leviant Phdrs.push_back(Tok); 1743bbe38602SEugene Leviant } 1744bbe38602SEugene Leviant return Phdrs; 1745bbe38602SEugene Leviant } 1746bbe38602SEugene Leviant 174795dd718cSGeorge Rimar // Read a program header type name. The next token must be a 174895dd718cSGeorge Rimar // name of a program header type or a constant (e.g. "0x3"). 1749bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1750bbe38602SEugene Leviant StringRef Tok = next(); 175195dd718cSGeorge Rimar uint64_t Val; 175295dd718cSGeorge Rimar if (readInteger(Tok, Val)) 175395dd718cSGeorge Rimar return Val; 175495dd718cSGeorge Rimar 1755b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1756b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1757b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1758b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1759b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1760b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1761b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1762b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1763b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1764b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1765b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1766b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1767270173f2SGeorge Rimar .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 1768cc6e567cSGeorge Rimar .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 1769b0f6c590SRui Ueyama .Default(-1); 1770bbe38602SEugene Leviant 1771b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1772b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1773b0f6c590SRui Ueyama return PT_NULL; 1774b0f6c590SRui Ueyama } 1775b0f6c590SRui Ueyama return Ret; 1776bbe38602SEugene Leviant } 1777bbe38602SEugene Leviant 177895769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 177920b6598cSGeorge Rimar // Identifiers start at 2 because 0 and 1 are reserved 178020b6598cSGeorge Rimar // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. 178120b6598cSGeorge Rimar size_t VersionId = Config->VersionDefinitions.size() + 2; 178220b6598cSGeorge Rimar Config->VersionDefinitions.push_back({VerStr, VersionId}); 178320b6598cSGeorge Rimar 178483043f23SRui Ueyama if (consume("global:") || peek() != "local:") 178520b6598cSGeorge Rimar readGlobal(VerStr); 178683043f23SRui Ueyama if (consume("local:")) 178720b6598cSGeorge Rimar readLocal(); 178820b6598cSGeorge Rimar expect("}"); 178920b6598cSGeorge Rimar 179020b6598cSGeorge Rimar // Each version may have a parent version. For example, "Ver2" defined as 179120b6598cSGeorge Rimar // "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This 179220b6598cSGeorge Rimar // version hierarchy is, probably against your instinct, purely for human; the 179320b6598cSGeorge Rimar // runtime doesn't care about them at all. In LLD, we simply skip the token. 179420b6598cSGeorge Rimar if (!VerStr.empty() && peek() != ";") 17955424e7c7SJustin Bogner skip(); 179620b6598cSGeorge Rimar expect(";"); 179720b6598cSGeorge Rimar } 179820b6598cSGeorge Rimar 179920b6598cSGeorge Rimar void ScriptParser::readLocal() { 180020b6598cSGeorge Rimar Config->DefaultSymbolVersion = VER_NDX_LOCAL; 180120b6598cSGeorge Rimar expect("*"); 180220b6598cSGeorge Rimar expect(";"); 180320b6598cSGeorge Rimar } 180420b6598cSGeorge Rimar 180520b6598cSGeorge Rimar void ScriptParser::readExtern(std::vector<SymbolVersion> *Globals) { 1806cd574a5eSGeorge Rimar expect("\"C++\""); 180720b6598cSGeorge Rimar expect("{"); 180820b6598cSGeorge Rimar 180920b6598cSGeorge Rimar for (;;) { 181020b6598cSGeorge Rimar if (peek() == "}" || Error) 181120b6598cSGeorge Rimar break; 1812cd574a5eSGeorge Rimar bool HasWildcard = !peek().startswith("\"") && hasWildcard(peek()); 1813cd574a5eSGeorge Rimar Globals->push_back({unquote(next()), true, HasWildcard}); 181420b6598cSGeorge Rimar expect(";"); 181520b6598cSGeorge Rimar } 181620b6598cSGeorge Rimar 181720b6598cSGeorge Rimar expect("}"); 181820b6598cSGeorge Rimar expect(";"); 181920b6598cSGeorge Rimar } 182020b6598cSGeorge Rimar 182120b6598cSGeorge Rimar void ScriptParser::readGlobal(StringRef VerStr) { 182220b6598cSGeorge Rimar std::vector<SymbolVersion> *Globals; 182320b6598cSGeorge Rimar if (VerStr.empty()) 182420b6598cSGeorge Rimar Globals = &Config->VersionScriptGlobals; 182520b6598cSGeorge Rimar else 182620b6598cSGeorge Rimar Globals = &Config->VersionDefinitions.back().Globals; 182720b6598cSGeorge Rimar 182820b6598cSGeorge Rimar for (;;) { 182983043f23SRui Ueyama if (consume("extern")) 183020b6598cSGeorge Rimar readExtern(Globals); 183120b6598cSGeorge Rimar 183220b6598cSGeorge Rimar StringRef Cur = peek(); 183320b6598cSGeorge Rimar if (Cur == "}" || Cur == "local:" || Error) 183420b6598cSGeorge Rimar return; 18355424e7c7SJustin Bogner skip(); 1836cd574a5eSGeorge Rimar Globals->push_back({unquote(Cur), false, hasWildcard(Cur)}); 183720b6598cSGeorge Rimar expect(";"); 183820b6598cSGeorge Rimar } 183920b6598cSGeorge Rimar } 184020b6598cSGeorge Rimar 184116b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 184216b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 184316b0cc9eSSimon Atanasyan return false; 184416b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 184516b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 184616b0cc9eSSimon Atanasyan return true; 184716b0cc9eSSimon Atanasyan return false; 184816b0cc9eSSimon Atanasyan } 184916b0cc9eSSimon Atanasyan 185007320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 185116b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 185220b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).readLinkerScript(); 185320b6598cSGeorge Rimar } 185420b6598cSGeorge Rimar 185520b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 185620b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), false).readVersionScript(); 1857f7c5fbb1SRui Ueyama } 18581ebc8ed7SRui Ueyama 185907320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 186007320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 186107320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 186207320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1863