1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===// 2f7c5fbb1SRui Ueyama // 3f7c5fbb1SRui Ueyama // The LLVM Linker 4f7c5fbb1SRui Ueyama // 5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source 6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details. 7f7c5fbb1SRui Ueyama // 8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 9f7c5fbb1SRui Ueyama // 10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script. 11629e0aa5SRui Ueyama // It parses a linker script and write the result to Config or ScriptConfig 12629e0aa5SRui Ueyama // objects. 13629e0aa5SRui Ueyama // 14629e0aa5SRui Ueyama // If SECTIONS command is used, a ScriptConfig contains an AST 15629e0aa5SRui Ueyama // of the command which will later be consumed by createSections() and 16629e0aa5SRui Ueyama // assignAddresses(). 17f7c5fbb1SRui Ueyama // 18f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 19f7c5fbb1SRui Ueyama 20717677afSRui Ueyama #include "LinkerScript.h" 21f7c5fbb1SRui Ueyama #include "Config.h" 22f7c5fbb1SRui Ueyama #include "Driver.h" 231ebc8ed7SRui Ueyama #include "InputSection.h" 24652852c5SGeorge Rimar #include "OutputSections.h" 25e77b5bf6SAdhemerval Zanella #include "ScriptParser.h" 2693c9af42SRui Ueyama #include "Strings.h" 27eda81a1bSEugene Leviant #include "Symbols.h" 28f7c5fbb1SRui Ueyama #include "SymbolTable.h" 29467c4d55SEugene Leviant #include "Target.h" 30bbe38602SEugene Leviant #include "Writer.h" 31960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 32652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 33f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 34f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h" 35f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 36a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h" 37f7c5fbb1SRui Ueyama 38f7c5fbb1SRui Ueyama using namespace llvm; 39652852c5SGeorge Rimar using namespace llvm::ELF; 401ebc8ed7SRui Ueyama using namespace llvm::object; 41e38cbab5SGeorge Rimar using namespace llvm::support::endian; 42f7c5fbb1SRui Ueyama using namespace lld; 43e0df00b9SRafael Espindola using namespace lld::elf; 44f7c5fbb1SRui Ueyama 45884e786dSGeorge Rimar LinkerScriptBase *elf::ScriptBase; 4607320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 47717677afSRui Ueyama 486c55f0e3SGeorge Rimar template <class ELFT> static void addRegular(SymbolAssignment *Cmd) { 491602421cSRui Ueyama Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, STB_GLOBAL, STV_DEFAULT); 501602421cSRui Ueyama Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; 511602421cSRui Ueyama Cmd->Sym = Sym->body(); 5220d03194SEugene Leviant 5320d03194SEugene Leviant // If we have no SECTIONS then we don't have '.' and don't call 5420d03194SEugene Leviant // assignAddresses(). We calculate symbol value immediately in this case. 5520d03194SEugene Leviant if (!ScriptConfig->HasSections) 5620d03194SEugene Leviant cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0); 57ceabe80eSEugene Leviant } 58ceabe80eSEugene Leviant 590c70d3ccSRui Ueyama template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) { 60e1937bb5SGeorge Rimar Symbol *Sym = Symtab<ELFT>::X->addSynthetic( 61e1937bb5SGeorge Rimar Cmd->Name, nullptr, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT); 621602421cSRui Ueyama Cmd->Sym = Sym->body(); 63ceabe80eSEugene Leviant } 64ceabe80eSEugene Leviant 65db741e72SEugene Leviant template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) { 66db741e72SEugene Leviant if (Cmd->IsAbsolute) 67db741e72SEugene Leviant addRegular<ELFT>(Cmd); 68db741e72SEugene Leviant else 69db741e72SEugene Leviant addSynthetic<ELFT>(Cmd); 70db741e72SEugene Leviant } 711602421cSRui Ueyama // If a symbol was in PROVIDE(), we need to define it only when 721602421cSRui Ueyama // it is an undefined symbol. 731602421cSRui Ueyama template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) { 741602421cSRui Ueyama if (Cmd->Name == ".") 75ceabe80eSEugene Leviant return false; 761602421cSRui Ueyama if (!Cmd->Provide) 77ceabe80eSEugene Leviant return true; 781602421cSRui Ueyama SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 791602421cSRui Ueyama return B && B->isUndefined(); 80ceabe80eSEugene Leviant } 81ceabe80eSEugene Leviant 82076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 83076fe157SGeorge Rimar return C->Kind == AssignmentKind; 84076fe157SGeorge Rimar } 85076fe157SGeorge Rimar 86076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 87076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 88076fe157SGeorge Rimar } 89076fe157SGeorge Rimar 90eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 91eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 92eea3114fSGeorge Rimar } 93eea3114fSGeorge Rimar 94eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 95eefa758eSGeorge Rimar return C->Kind == AssertKind; 96eefa758eSGeorge Rimar } 97eefa758eSGeorge Rimar 98e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) { 99e38cbab5SGeorge Rimar return C->Kind == BytesDataKind; 100e38cbab5SGeorge Rimar } 101e38cbab5SGeorge Rimar 10236a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) { 103eea3114fSGeorge Rimar return !S || !S->Live; 104717677afSRui Ueyama } 105717677afSRui Ueyama 106f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::LinkerScript() {} 107f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::~LinkerScript() {} 108f34d0e08SRui Ueyama 10907320e40SRui Ueyama template <class ELFT> 11007320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 111c91930a1SGeorge Rimar for (Regex *Re : Opt.KeptSections) 112042a3f20SRafael Espindola if (Re->match(S->Name)) 113eea3114fSGeorge Rimar return true; 114eea3114fSGeorge Rimar return false; 115eea3114fSGeorge Rimar } 116eea3114fSGeorge Rimar 117575208caSGeorge Rimar static bool comparePriority(InputSectionData *A, InputSectionData *B) { 118575208caSGeorge Rimar return getPriority(A->Name) < getPriority(B->Name); 119575208caSGeorge Rimar } 120575208caSGeorge Rimar 121c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) { 122042a3f20SRafael Espindola return A->Name < B->Name; 1230702c4e8SGeorge Rimar } 124742c3836SRui Ueyama 125c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) { 126742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 127742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 128742c3836SRui Ueyama // This is compatible with GNU. 129742c3836SRui Ueyama return A->Alignment > B->Alignment; 130742c3836SRui Ueyama } 131742c3836SRui Ueyama 132c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)> 133be394db3SGeorge Rimar getComparator(SortSectionPolicy K) { 134be394db3SGeorge Rimar switch (K) { 135be394db3SGeorge Rimar case SortSectionPolicy::Alignment: 136c0028d3dSRafael Espindola return compareAlignment; 137be394db3SGeorge Rimar case SortSectionPolicy::Name: 138be394db3SGeorge Rimar return compareName; 139be394db3SGeorge Rimar case SortSectionPolicy::Priority: 140be394db3SGeorge Rimar return comparePriority; 141be394db3SGeorge Rimar default: 142be394db3SGeorge Rimar llvm_unreachable("unknown sort policy"); 143be394db3SGeorge Rimar } 144742c3836SRui Ueyama } 1450702c4e8SGeorge Rimar 14648c3f1ceSRui Ueyama template <class ELFT> 147e71a3f8aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 14806ae6836SGeorge Rimar ConstraintKind Kind) { 1498f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 1508f66df92SGeorge Rimar return true; 151e746e52cSRafael Espindola bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) { 152d3190795SRafael Espindola auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2); 153e746e52cSRafael Espindola return Sec->getSectionHdr()->sh_flags & SHF_WRITE; 15406ae6836SGeorge Rimar }); 155e746e52cSRafael Espindola return (IsRW && Kind == ConstraintKind::ReadWrite) || 156e746e52cSRafael Espindola (!IsRW && Kind == ConstraintKind::ReadOnly); 15706ae6836SGeorge Rimar } 15806ae6836SGeorge Rimar 15907171f21SGeorge Rimar static void sortSections(InputSectionData **Begin, InputSectionData **End, 160ee924709SRui Ueyama SortSectionPolicy K) { 161ee924709SRui Ueyama if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None) 16207171f21SGeorge Rimar std::stable_sort(Begin, End, getComparator(K)); 163ee924709SRui Ueyama } 164ee924709SRui Ueyama 165d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches. 166be94e1b6SRafael Espindola template <class ELFT> 167e71a3f8aSRafael Espindola void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) { 1684dc07becSRui Ueyama // Collects all sections that satisfy constraints of I 1694dc07becSRui Ueyama // and attach them to I. 1704dc07becSRui Ueyama for (SectionPattern &Pat : I->SectionPatterns) { 17107171f21SGeorge Rimar size_t SizeBefore = I->Sections.size(); 172395281cfSGeorge Rimar for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) { 1733ff27f49SRui Ueyama StringRef Filename = sys::path::filename(F->getName()); 174f135f0ecSRafael Espindola if (!I->FileRe.match(Filename) || Pat.ExcludedFileRe.match(Filename)) 1753ff27f49SRui Ueyama continue; 1764dc07becSRui Ueyama 177be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : F->getSections()) 178f135f0ecSRafael Espindola if (!isDiscarded(S) && !S->OutSec && Pat.SectionRe.match(S->Name)) 179d3190795SRafael Espindola I->Sections.push_back(S); 180f135f0ecSRafael Espindola if (Pat.SectionRe.match("COMMON")) 181d3190795SRafael Espindola I->Sections.push_back(CommonInputSection<ELFT>::X); 182395281cfSGeorge Rimar } 183d3190795SRafael Espindola 184ee924709SRui Ueyama // Sort sections as instructed by SORT-family commands and --sort-section 185ee924709SRui Ueyama // option. Because SORT-family commands can be nested at most two depth 186ee924709SRui Ueyama // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command 187ee924709SRui Ueyama // line option is respected even if a SORT command is given, the exact 188ee924709SRui Ueyama // behavior we have here is a bit complicated. Here are the rules. 189ee924709SRui Ueyama // 190ee924709SRui Ueyama // 1. If two SORT commands are given, --sort-section is ignored. 191ee924709SRui Ueyama // 2. If one SORT command is given, and if it is not SORT_NONE, 192ee924709SRui Ueyama // --sort-section is handled as an inner SORT command. 193ee924709SRui Ueyama // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. 194ee924709SRui Ueyama // 4. If no SORT command is given, sort according to --sort-section. 19507171f21SGeorge Rimar InputSectionData **Begin = I->Sections.data() + SizeBefore; 19607171f21SGeorge Rimar InputSectionData **End = I->Sections.data() + I->Sections.size(); 19707171f21SGeorge Rimar if (Pat.SortOuter != SortSectionPolicy::None) { 19807171f21SGeorge Rimar if (Pat.SortInner == SortSectionPolicy::Default) 19907171f21SGeorge Rimar sortSections(Begin, End, Config->SortSection); 200ee924709SRui Ueyama else 20107171f21SGeorge Rimar sortSections(Begin, End, Pat.SortInner); 20207171f21SGeorge Rimar sortSections(Begin, End, Pat.SortOuter); 20307171f21SGeorge Rimar } 204ee924709SRui Ueyama } 205d3190795SRafael Espindola 206d3190795SRafael Espindola // We do not add duplicate input sections, so mark them with a dummy output 207d3190795SRafael Espindola // section for now. 208d3190795SRafael Espindola for (InputSectionData *S : I->Sections) { 209d3190795SRafael Espindola auto *S2 = static_cast<InputSectionBase<ELFT> *>(S); 210d3190795SRafael Espindola S2->OutSec = (OutputSectionBase<ELFT> *)-1; 211d3190795SRafael Espindola } 212be94e1b6SRafael Espindola } 213be94e1b6SRafael Espindola 214be94e1b6SRafael Espindola template <class ELFT> 215be94e1b6SRafael Espindola void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) { 216be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : V) { 217be94e1b6SRafael Espindola S->Live = false; 218be94e1b6SRafael Espindola reportDiscarded(S); 219be94e1b6SRafael Espindola } 220be94e1b6SRafael Espindola } 221be94e1b6SRafael Espindola 22206ae6836SGeorge Rimar template <class ELFT> 2230b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 22406ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 2250b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 226e7f912cdSRui Ueyama 22706ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 2287c3ff2ebSRafael Espindola auto *Cmd = dyn_cast<InputSectionDescription>(Base.get()); 2297c3ff2ebSRafael Espindola if (!Cmd) 2300b9ce6a4SRui Ueyama continue; 231e71a3f8aSRafael Espindola computeInputSections(Cmd); 232d3190795SRafael Espindola for (InputSectionData *S : Cmd->Sections) 233d3190795SRafael Espindola Ret.push_back(static_cast<InputSectionBase<ELFT> *>(S)); 2340b9ce6a4SRui Ueyama } 235e71a3f8aSRafael Espindola 2360b9ce6a4SRui Ueyama return Ret; 2370b9ce6a4SRui Ueyama } 2380b9ce6a4SRui Ueyama 239e5d3ca50SPetr Hosek template <class ELFT> 24010897f18SRafael Espindola static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C, 24110897f18SRafael Espindola StringRef OutsecName) { 24210897f18SRafael Espindola // When using linker script the merge rules are different. 24310897f18SRafael Espindola // Unfortunately, linker scripts are name based. This means that expressions 24410897f18SRafael Espindola // like *(.foo*) can refer to multiple input sections that would normally be 24510897f18SRafael Espindola // placed in different output sections. We cannot put them in different 24610897f18SRafael Espindola // output sections or we would produce wrong results for 24710897f18SRafael Espindola // start = .; *(.foo.*) end = .; *(.bar) 24810897f18SRafael Espindola // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to 24910897f18SRafael Espindola // another. The problem is that there is no way to layout those output 25010897f18SRafael Espindola // sections such that the .foo sections are the only thing between the 25110897f18SRafael Espindola // start and end symbols. 25210897f18SRafael Espindola 25310897f18SRafael Espindola // An extra annoyance is that we cannot simply disable merging of the contents 25410897f18SRafael Espindola // of SHF_MERGE sections, but our implementation requires one output section 25510897f18SRafael Espindola // per "kind" (string or not, which size/aligment). 25610897f18SRafael Espindola // Fortunately, creating symbols in the middle of a merge section is not 25710897f18SRafael Espindola // supported by bfd or gold, so we can just create multiple section in that 25810897f18SRafael Espindola // case. 25910897f18SRafael Espindola const typename ELFT::Shdr *H = C->getSectionHdr(); 26010897f18SRafael Espindola typedef typename ELFT::uint uintX_t; 26110897f18SRafael Espindola uintX_t Flags = H->sh_flags & (SHF_MERGE | SHF_STRINGS); 26210897f18SRafael Espindola 26310897f18SRafael Espindola uintX_t Alignment = 0; 26410897f18SRafael Espindola if (isa<MergeInputSection<ELFT>>(C)) 26510897f18SRafael Espindola Alignment = std::max(H->sh_addralign, H->sh_entsize); 26610897f18SRafael Espindola 26710897f18SRafael Espindola return SectionKey<ELFT::Is64Bits>{OutsecName, /*Type*/ 0, Flags, Alignment}; 26810897f18SRafael Espindola } 26910897f18SRafael Espindola 27010897f18SRafael Espindola template <class ELFT> 27120d03194SEugene Leviant void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory, 27220d03194SEugene Leviant InputSectionBase<ELFT> *Sec, 27320d03194SEugene Leviant StringRef Name) { 27428c1597aSRafael Espindola OutputSectionBase<ELFT> *OutSec; 27528c1597aSRafael Espindola bool IsNew; 27610897f18SRafael Espindola std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec); 27728c1597aSRafael Espindola if (IsNew) 27828c1597aSRafael Espindola OutputSections->push_back(OutSec); 27920d03194SEugene Leviant OutSec->addSection(Sec); 28020d03194SEugene Leviant } 28120d03194SEugene Leviant 28220d03194SEugene Leviant template <class ELFT> 28320d03194SEugene Leviant void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { 28428c1597aSRafael Espindola 2857c3ff2ebSRafael Espindola for (unsigned I = 0; I < Opt.Commands.size(); ++I) { 2867c3ff2ebSRafael Espindola auto Iter = Opt.Commands.begin() + I; 2877c3ff2ebSRafael Espindola const std::unique_ptr<BaseCommand> &Base1 = *Iter; 2882ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 2892ab5f73dSRui Ueyama if (shouldDefine<ELFT>(Cmd)) 2902ab5f73dSRui Ueyama addRegular<ELFT>(Cmd); 2912ab5f73dSRui Ueyama continue; 2922ab5f73dSRui Ueyama } 29320d03194SEugene Leviant if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) { 29420d03194SEugene Leviant // If we don't have SECTIONS then output sections have already been 295194470cdSGeorge Rimar // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses 29620d03194SEugene Leviant // will not be called, so ASSERT should be evaluated now. 29720d03194SEugene Leviant if (!Opt.HasSections) 29820d03194SEugene Leviant Cmd->Expression(0); 29920d03194SEugene Leviant continue; 30020d03194SEugene Leviant } 3012ab5f73dSRui Ueyama 302ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 3037bd37870SRafael Espindola std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 3047bd37870SRafael Espindola 30548c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 3067bd37870SRafael Espindola discard(V); 30748c3f1ceSRui Ueyama continue; 30848c3f1ceSRui Ueyama } 3090b9ce6a4SRui Ueyama 3107c3ff2ebSRafael Espindola if (!matchConstraints<ELFT>(V, Cmd->Constraint)) { 3117c3ff2ebSRafael Espindola for (InputSectionBase<ELFT> *S : V) 3127c3ff2ebSRafael Espindola S->OutSec = nullptr; 3137c3ff2ebSRafael Espindola Opt.Commands.erase(Iter); 314dfbbbc86SGeorge Rimar --I; 3157c3ff2ebSRafael Espindola continue; 3167c3ff2ebSRafael Espindola } 3177c3ff2ebSRafael Espindola 3187c3ff2ebSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 3197c3ff2ebSRafael Espindola if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) 3207c3ff2ebSRafael Espindola if (shouldDefine<ELFT>(OutCmd)) 3217c3ff2ebSRafael Espindola addSymbol<ELFT>(OutCmd); 3227c3ff2ebSRafael Espindola 32397403d15SEugene Leviant if (V.empty()) 3240b9ce6a4SRui Ueyama continue; 3250b9ce6a4SRui Ueyama 326a14b13d8SGeorge Rimar for (InputSectionBase<ELFT> *Sec : V) { 32720d03194SEugene Leviant addSection(Factory, Sec, Cmd->Name); 32820d03194SEugene Leviant if (uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0) 329db24d9c3SGeorge Rimar Sec->Alignment = Subalign; 33020d03194SEugene Leviant } 331eea3114fSGeorge Rimar } 33248c3f1ceSRui Ueyama } 333db24d9c3SGeorge Rimar } 334e63d81bdSEugene Leviant 33520d03194SEugene Leviant template <class ELFT> 33620d03194SEugene Leviant void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 33720d03194SEugene Leviant processCommands(Factory); 3380b9ce6a4SRui Ueyama // Add orphan sections. 33920d03194SEugene Leviant for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) 34020d03194SEugene Leviant for (InputSectionBase<ELFT> *S : F->getSections()) 34120d03194SEugene Leviant if (!isDiscarded(S) && !S->OutSec) 34220d03194SEugene Leviant addSection(Factory, S, getOutputSectionName(S)); 343e63d81bdSEugene Leviant } 344e63d81bdSEugene Leviant 345db741e72SEugene Leviant // Sets value of a section-defined symbol. Two kinds of 346db741e72SEugene Leviant // symbols are processed: synthetic symbols, whose value 347db741e72SEugene Leviant // is an offset from beginning of section and regular 348db741e72SEugene Leviant // symbols whose value is absolute. 349db741e72SEugene Leviant template <class ELFT> 350db741e72SEugene Leviant static void assignSectionSymbol(SymbolAssignment *Cmd, 351db741e72SEugene Leviant OutputSectionBase<ELFT> *Sec, 352db741e72SEugene Leviant typename ELFT::uint Off) { 353db741e72SEugene Leviant if (!Cmd->Sym) 354db741e72SEugene Leviant return; 355db741e72SEugene Leviant 356db741e72SEugene Leviant if (auto *Body = dyn_cast<DefinedSynthetic<ELFT>>(Cmd->Sym)) { 357db741e72SEugene Leviant Body->Section = Sec; 358db741e72SEugene Leviant Body->Value = Cmd->Expression(Sec->getVA() + Off) - Sec->getVA(); 359db741e72SEugene Leviant return; 360db741e72SEugene Leviant } 361db741e72SEugene Leviant auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym); 362db741e72SEugene Leviant Body->Value = Cmd->Expression(Sec->getVA() + Off); 363db741e72SEugene Leviant } 364db741e72SEugene Leviant 365a940e539SRafael Espindola template <class ELFT> static bool isTbss(OutputSectionBase<ELFT> *Sec) { 366a940e539SRafael Espindola return (Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS; 367a940e539SRafael Espindola } 368a940e539SRafael Espindola 369d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) { 370d3190795SRafael Espindola if (!AlreadyOutputIS.insert(S).second) 371ceabe80eSEugene Leviant return; 372a940e539SRafael Espindola bool IsTbss = isTbss(CurOutSec); 373d3190795SRafael Espindola 374d3190795SRafael Espindola uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; 375d3190795SRafael Espindola Pos = alignTo(Pos, S->Alignment); 376d3190795SRafael Espindola S->OutSecOff = Pos - CurOutSec->getVA(); 377d3190795SRafael Espindola Pos += S->getSize(); 378d3190795SRafael Espindola 379d3190795SRafael Espindola // Update output section size after adding each section. This is so that 380d3190795SRafael Espindola // SIZEOF works correctly in the case below: 381d3190795SRafael Espindola // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 382d3190795SRafael Espindola CurOutSec->setSize(Pos - CurOutSec->getVA()); 383d3190795SRafael Espindola 3847252ae52SRafael Espindola if (IsTbss) 3857252ae52SRafael Espindola ThreadBssOffset = Pos - Dot; 3867252ae52SRafael Espindola else 387d3190795SRafael Espindola Dot = Pos; 3882de509c3SRui Ueyama } 389ceabe80eSEugene Leviant 390d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::flush() { 39165499b90SRafael Espindola if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second) 39265499b90SRafael Espindola return; 39365499b90SRafael Espindola if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) { 394d3190795SRafael Espindola for (InputSection<ELFT> *I : OutSec->Sections) 395d3190795SRafael Espindola output(I); 39665499b90SRafael Espindola } else { 39765499b90SRafael Espindola Dot += CurOutSec->getSize(); 398d3190795SRafael Espindola } 399d3190795SRafael Espindola } 40097403d15SEugene Leviant 401d3190795SRafael Espindola template <class ELFT> 402d3190795SRafael Espindola void LinkerScript<ELFT>::switchTo(OutputSectionBase<ELFT> *Sec) { 403d3190795SRafael Espindola if (CurOutSec == Sec) 404d3190795SRafael Espindola return; 405d3190795SRafael Espindola if (AlreadyOutputOS.count(Sec)) 406d3190795SRafael Espindola return; 407d3190795SRafael Espindola 408d3190795SRafael Espindola flush(); 409d3190795SRafael Espindola CurOutSec = Sec; 410d3190795SRafael Espindola 411d3190795SRafael Espindola Dot = alignTo(Dot, CurOutSec->getAlignment()); 412a940e539SRafael Espindola CurOutSec->setVA(isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot); 413d3190795SRafael Espindola } 414d3190795SRafael Espindola 415d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) { 416e38cbab5SGeorge Rimar // This handles the assignments to symbol or to a location counter (.) 417d3190795SRafael Espindola if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) { 41897403d15SEugene Leviant if (AssignCmd->Name == ".") { 41997403d15SEugene Leviant // Update to location counter means update to section size. 420d3190795SRafael Espindola Dot = AssignCmd->Expression(Dot); 421d3190795SRafael Espindola CurOutSec->setSize(Dot - CurOutSec->getVA()); 422d3190795SRafael Espindola return; 42397403d15SEugene Leviant } 424d3190795SRafael Espindola assignSectionSymbol<ELFT>(AssignCmd, CurOutSec, Dot - CurOutSec->getVA()); 425d3190795SRafael Espindola return; 42697403d15SEugene Leviant } 427e38cbab5SGeorge Rimar 428e38cbab5SGeorge Rimar // Handle BYTE(), SHORT(), LONG(), or QUAD(). 429e38cbab5SGeorge Rimar if (auto *DataCmd = dyn_cast<BytesDataCommand>(&Base)) { 430e38cbab5SGeorge Rimar DataCmd->Offset = Dot - CurOutSec->getVA(); 431e38cbab5SGeorge Rimar Dot += DataCmd->Size; 432e38cbab5SGeorge Rimar CurOutSec->setSize(Dot - CurOutSec->getVA()); 433e38cbab5SGeorge Rimar return; 434e38cbab5SGeorge Rimar } 435e38cbab5SGeorge Rimar 436e38cbab5SGeorge Rimar // It handles single input section description command, 437e38cbab5SGeorge Rimar // calculates and assigns the offsets for each section and also 438e38cbab5SGeorge Rimar // updates the output section size. 439d3190795SRafael Espindola auto &ICmd = cast<InputSectionDescription>(Base); 440d3190795SRafael Espindola for (InputSectionData *ID : ICmd.Sections) { 441d3190795SRafael Espindola auto *IB = static_cast<InputSectionBase<ELFT> *>(ID); 442d3190795SRafael Espindola switchTo(IB->OutSec); 443d3190795SRafael Espindola if (auto *I = dyn_cast<InputSection<ELFT>>(IB)) 444d3190795SRafael Espindola output(I); 44565499b90SRafael Espindola else 44665499b90SRafael Espindola flush(); 447ceabe80eSEugene Leviant } 448ceabe80eSEugene Leviant } 449ceabe80eSEugene Leviant 4508f66df92SGeorge Rimar template <class ELFT> 451a14b13d8SGeorge Rimar static std::vector<OutputSectionBase<ELFT> *> 452a14b13d8SGeorge Rimar findSections(OutputSectionCommand &Cmd, 453d3190795SRafael Espindola const std::vector<OutputSectionBase<ELFT> *> &Sections) { 454a14b13d8SGeorge Rimar std::vector<OutputSectionBase<ELFT> *> Ret; 455a14b13d8SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : Sections) 4567c3ff2ebSRafael Espindola if (Sec->getName() == Cmd.Name) 457a14b13d8SGeorge Rimar Ret.push_back(Sec); 458a14b13d8SGeorge Rimar return Ret; 4598f66df92SGeorge Rimar } 4608f66df92SGeorge Rimar 461d3190795SRafael Espindola template <class ELFT> 462d3190795SRafael Espindola void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) { 463d3190795SRafael Espindola std::vector<OutputSectionBase<ELFT> *> Sections = 464d3190795SRafael Espindola findSections(*Cmd, *OutputSections); 465d3190795SRafael Espindola if (Sections.empty()) 466d3190795SRafael Espindola return; 467d3190795SRafael Espindola switchTo(Sections[0]); 468d3190795SRafael Espindola 469d3190795SRafael Espindola // Find the last section output location. We will output orphan sections 470d3190795SRafael Espindola // there so that end symbols point to the correct location. 471d3190795SRafael Espindola auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(), 472d3190795SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 473d3190795SRafael Espindola return !isa<SymbolAssignment>(*Cmd); 474d3190795SRafael Espindola }) 475d3190795SRafael Espindola .base(); 476d3190795SRafael Espindola for (auto I = Cmd->Commands.begin(); I != E; ++I) 477d3190795SRafael Espindola process(**I); 47865499b90SRafael Espindola for (OutputSectionBase<ELFT> *Base : Sections) 479d3190795SRafael Espindola switchTo(Base); 4802506cb4dSEugene Leviant flush(); 481b31dd370SGeorge Rimar std::for_each(E, Cmd->Commands.end(), 482b31dd370SGeorge Rimar [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); }); 483d3190795SRafael Espindola } 484d3190795SRafael Espindola 4859546fffbSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() { 4866d38e4dbSRafael Espindola // It is common practice to use very generic linker scripts. So for any 4876d38e4dbSRafael Espindola // given run some of the output sections in the script will be empty. 4886d38e4dbSRafael Espindola // We could create corresponding empty output sections, but that would 4896d38e4dbSRafael Espindola // clutter the output. 4906d38e4dbSRafael Espindola // We instead remove trivially empty sections. The bfd linker seems even 4916d38e4dbSRafael Espindola // more aggressive at removing them. 4926d38e4dbSRafael Espindola auto Pos = std::remove_if( 4936d38e4dbSRafael Espindola Opt.Commands.begin(), Opt.Commands.end(), 4946d38e4dbSRafael Espindola [&](const std::unique_ptr<BaseCommand> &Base) { 4956d38e4dbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 4966d38e4dbSRafael Espindola if (!Cmd) 4976d38e4dbSRafael Espindola return false; 4986d38e4dbSRafael Espindola std::vector<OutputSectionBase<ELFT> *> Secs = 4996d38e4dbSRafael Espindola findSections(*Cmd, *OutputSections); 5006d38e4dbSRafael Espindola if (!Secs.empty()) 5016d38e4dbSRafael Espindola return false; 5026d38e4dbSRafael Espindola for (const std::unique_ptr<BaseCommand> &I : Cmd->Commands) 5036d38e4dbSRafael Espindola if (!isa<InputSectionDescription>(I.get())) 5046d38e4dbSRafael Espindola return false; 5056d38e4dbSRafael Espindola return true; 5066d38e4dbSRafael Espindola }); 5076d38e4dbSRafael Espindola Opt.Commands.erase(Pos, Opt.Commands.end()); 5086d38e4dbSRafael Espindola 5099546fffbSRafael Espindola // If the output section contains only symbol assignments, create a 5109546fffbSRafael Espindola // corresponding output section. The bfd linker seems to only create them if 5119546fffbSRafael Espindola // '.' is assigned to, but creating these section should not have any bad 5129546fffbSRafael Espindola // consequeces and gives us a section to put the symbol in. 5139546fffbSRafael Espindola uintX_t Flags = SHF_ALLOC; 5149546fffbSRafael Espindola uint32_t Type = 0; 5159546fffbSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 5169546fffbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 5179546fffbSRafael Espindola if (!Cmd) 5189546fffbSRafael Espindola continue; 5199546fffbSRafael Espindola std::vector<OutputSectionBase<ELFT> *> Secs = 5209546fffbSRafael Espindola findSections(*Cmd, *OutputSections); 5219546fffbSRafael Espindola if (!Secs.empty()) { 5229546fffbSRafael Espindola Flags = Secs[0]->getFlags(); 5239546fffbSRafael Espindola Type = Secs[0]->getType(); 5249546fffbSRafael Espindola continue; 5259546fffbSRafael Espindola } 5269546fffbSRafael Espindola 5279546fffbSRafael Espindola auto *OutSec = new OutputSection<ELFT>(Cmd->Name, Type, Flags); 5289546fffbSRafael Espindola Out<ELFT>::Pool.emplace_back(OutSec); 5299546fffbSRafael Espindola OutputSections->push_back(OutSec); 5309546fffbSRafael Espindola } 5319546fffbSRafael Espindola } 5329546fffbSRafael Espindola 53315c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments 53415c57951SRafael Espindola // so that an orphan after 53515c57951SRafael Espindola // begin_foo = .; 53615c57951SRafael Espindola // foo : { *(foo) } 53715c57951SRafael Espindola // end_foo = .; 53815c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols. 53915c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the 54015c57951SRafael Espindola // one in charge of deciding the order of the sections. 54115c57951SRafael Espindola // We don't want to go over alignments, since doing so in 54215c57951SRafael Espindola // rx_sec : { *(rx_sec) } 54315c57951SRafael Espindola // . = ALIGN(0x1000); 54415c57951SRafael Espindola // /* The RW PT_LOAD starts here*/ 54515c57951SRafael Espindola // rw_sec : { *(rw_sec) } 54615c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned. 54715c57951SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) { 54815c57951SRafael Espindola if (isa<OutputSectionCommand>(Cmd)) 54915c57951SRafael Espindola return false; 55015c57951SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd); 55115c57951SRafael Espindola if (!Assign) 55215c57951SRafael Espindola return true; 55315c57951SRafael Espindola return Assign->Name != "."; 55415c57951SRafael Espindola } 55515c57951SRafael Espindola 556*6d91fce5SRafael Espindola template <class ELFT> 557*6d91fce5SRafael Espindola void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs) { 558652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 5597c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 5607c18c28cSRui Ueyama // We place orphan sections at end of file. 5617c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 562652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 563aab6d5c5SRafael Espindola 564aab6d5c5SRafael Espindola // The OutputSections are already in the correct order. 565aab6d5c5SRafael Espindola // This loops creates or moves commands as needed so that they are in the 566aab6d5c5SRafael Espindola // correct order. 567aab6d5c5SRafael Espindola int CmdIndex = 0; 568e5cc668eSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 569652852c5SGeorge Rimar StringRef Name = Sec->getName(); 570aab6d5c5SRafael Espindola 571aab6d5c5SRafael Espindola // Find the last spot where we can insert a command and still get the 57215c57951SRafael Espindola // correct result. 573aab6d5c5SRafael Espindola auto CmdIter = Opt.Commands.begin() + CmdIndex; 574aab6d5c5SRafael Espindola auto E = Opt.Commands.end(); 57515c57951SRafael Espindola while (CmdIter != E && shouldSkip(**CmdIter)) { 576aab6d5c5SRafael Espindola ++CmdIter; 577aab6d5c5SRafael Espindola ++CmdIndex; 578aab6d5c5SRafael Espindola } 579aab6d5c5SRafael Espindola 580aab6d5c5SRafael Espindola auto Pos = 581aab6d5c5SRafael Espindola std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) { 582aab6d5c5SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 583aab6d5c5SRafael Espindola return Cmd && Cmd->Name == Name; 584aab6d5c5SRafael Espindola }); 585aab6d5c5SRafael Espindola if (Pos == E) { 586aab6d5c5SRafael Espindola Opt.Commands.insert(CmdIter, 587aab6d5c5SRafael Espindola llvm::make_unique<OutputSectionCommand>(Name)); 588aab6d5c5SRafael Espindola ++CmdIndex; 58915c57951SRafael Espindola continue; 59015c57951SRafael Espindola } 59115c57951SRafael Espindola 59215c57951SRafael Espindola // Continue from where we found it. 59315c57951SRafael Espindola CmdIndex = (Pos - Opt.Commands.begin()) + 1; 59415c57951SRafael Espindola continue; 595652852c5SGeorge Rimar } 596652852c5SGeorge Rimar 5977c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 5984f7500bfSRui Ueyama Dot = getHeaderSize(); 599652852c5SGeorge Rimar 600076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 601076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 6028d083e6aSRui Ueyama if (Cmd->Name == ".") { 6038d083e6aSRui Ueyama Dot = Cmd->Expression(Dot); 6048d083e6aSRui Ueyama } else if (Cmd->Sym) { 6058d083e6aSRui Ueyama cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot); 6068d083e6aSRui Ueyama } 60705ef4cffSRui Ueyama continue; 608652852c5SGeorge Rimar } 609652852c5SGeorge Rimar 610eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 611eefa758eSGeorge Rimar Cmd->Expression(Dot); 612eefa758eSGeorge Rimar continue; 613eefa758eSGeorge Rimar } 614eefa758eSGeorge Rimar 615076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 616652852c5SGeorge Rimar 61758e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 61858e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 61958e5c4dcSGeorge Rimar 620d3190795SRafael Espindola assignOffsets(Cmd); 621a14b13d8SGeorge Rimar } 622467c4d55SEugene Leviant 623aab6d5c5SRafael Espindola uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 624aab6d5c5SRafael Espindola for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 625aab6d5c5SRafael Espindola if (Sec->getFlags() & SHF_ALLOC) 626aab6d5c5SRafael Espindola MinVA = std::min(MinVA, Sec->getVA()); 627aab6d5c5SRafael Espindola else 628d3190795SRafael Espindola Sec->setVA(0); 629aab6d5c5SRafael Espindola } 630aab6d5c5SRafael Espindola 6310d4b6d5cSRafael Espindola uintX_t HeaderSize = getHeaderSize(); 632*6d91fce5SRafael Espindola auto FirstPTLoad = 633*6d91fce5SRafael Espindola std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry<ELFT> &E) { 634*6d91fce5SRafael Espindola return E.H.p_type == PT_LOAD; 635*6d91fce5SRafael Espindola }); 636*6d91fce5SRafael Espindola if (HeaderSize <= MinVA && FirstPTLoad != Phdrs.end()) { 63764c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 638b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 6394ec013acSRafael Espindola MinVA = alignDown(MinVA - HeaderSize, Target->PageSize); 640467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 641467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 642*6d91fce5SRafael Espindola FirstPTLoad->First = Out<ELFT>::ElfHeader; 643*6d91fce5SRafael Espindola if (!FirstPTLoad->Last) 644*6d91fce5SRafael Espindola FirstPTLoad->Last = Out<ELFT>::ProgramHeaders; 645*6d91fce5SRafael Espindola } 646fb8978fcSDima Stepanov } 647652852c5SGeorge Rimar 648464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 64907320e40SRui Ueyama template <class ELFT> 650a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { 651edebbdf1SRui Ueyama std::vector<PhdrEntry<ELFT>> Ret; 652bbe38602SEugene Leviant 653464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 654464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 655bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 656edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 657edebbdf1SRui Ueyama PhdrEntry<ELFT> &Phdr = Ret.back(); 658bbe38602SEugene Leviant 659bbe38602SEugene Leviant if (Cmd.HasFilehdr) 660adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 661bbe38602SEugene Leviant if (Cmd.HasPhdrs) 662adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 66356b21c86SEugene Leviant 66456b21c86SEugene Leviant if (Cmd.LMAExpr) { 66556b21c86SEugene Leviant Phdr.H.p_paddr = Cmd.LMAExpr(0); 66656b21c86SEugene Leviant Phdr.HasLMA = true; 66756b21c86SEugene Leviant } 668bbe38602SEugene Leviant } 669bbe38602SEugene Leviant 670464daadcSRui Ueyama // Add output sections to program headers. 671edebbdf1SRui Ueyama PhdrEntry<ELFT> *Load = nullptr; 672edebbdf1SRui Ueyama uintX_t Flags = PF_R; 673464daadcSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 674bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 675bbe38602SEugene Leviant break; 676bbe38602SEugene Leviant 677edebbdf1SRui Ueyama std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName()); 678bbe38602SEugene Leviant if (!PhdrIds.empty()) { 679bbe38602SEugene Leviant // Assign headers specified by linker script 680bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 681edebbdf1SRui Ueyama Ret[Id].add(Sec); 682865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 6830b113671SRafael Espindola Ret[Id].H.p_flags |= Sec->getPhdrFlags(); 684bbe38602SEugene Leviant } 685bbe38602SEugene Leviant } else { 686bbe38602SEugene Leviant // If we have no load segment or flags've changed then we want new load 687bbe38602SEugene Leviant // segment. 6880b113671SRafael Espindola uintX_t NewFlags = Sec->getPhdrFlags(); 689bbe38602SEugene Leviant if (Load == nullptr || Flags != NewFlags) { 690edebbdf1SRui Ueyama Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags); 691bbe38602SEugene Leviant Flags = NewFlags; 692bbe38602SEugene Leviant } 69318f084ffSRui Ueyama Load->add(Sec); 694bbe38602SEugene Leviant } 695bbe38602SEugene Leviant } 696edebbdf1SRui Ueyama return Ret; 697bbe38602SEugene Leviant } 698bbe38602SEugene Leviant 699f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 700f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 701f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 702f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 703f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 704f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 705f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 706f9bc3bd2SEugene Leviant } 707f9bc3bd2SEugene Leviant 708bbe38602SEugene Leviant template <class ELFT> 70907320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 710f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 711f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 712f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 713f6c3ccefSGeorge Rimar return Cmd->Filler; 714e2ee72b5SGeorge Rimar return {}; 715e2ee72b5SGeorge Rimar } 716e2ee72b5SGeorge Rimar 717e38cbab5SGeorge Rimar template <class ELFT> 718e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { 719e38cbab5SGeorge Rimar const endianness E = ELFT::TargetEndianness; 720e38cbab5SGeorge Rimar 721e38cbab5SGeorge Rimar switch (Size) { 722e38cbab5SGeorge Rimar case 1: 723e38cbab5SGeorge Rimar *Buf = (uint8_t)Data; 724e38cbab5SGeorge Rimar break; 725e38cbab5SGeorge Rimar case 2: 726e38cbab5SGeorge Rimar write16<E>(Buf, Data); 727e38cbab5SGeorge Rimar break; 728e38cbab5SGeorge Rimar case 4: 729e38cbab5SGeorge Rimar write32<E>(Buf, Data); 730e38cbab5SGeorge Rimar break; 731e38cbab5SGeorge Rimar case 8: 732e38cbab5SGeorge Rimar write64<E>(Buf, Data); 733e38cbab5SGeorge Rimar break; 734e38cbab5SGeorge Rimar default: 735e38cbab5SGeorge Rimar llvm_unreachable("unsupported Size argument"); 736e38cbab5SGeorge Rimar } 737e38cbab5SGeorge Rimar } 738e38cbab5SGeorge Rimar 739e38cbab5SGeorge Rimar template <class ELFT> 740e38cbab5SGeorge Rimar void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) { 741e38cbab5SGeorge Rimar int I = getSectionIndex(Name); 742e38cbab5SGeorge Rimar if (I == INT_MAX) 743e38cbab5SGeorge Rimar return; 744e38cbab5SGeorge Rimar 745e38cbab5SGeorge Rimar OutputSectionCommand *Cmd = 746e38cbab5SGeorge Rimar dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()); 747e38cbab5SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base2 : Cmd->Commands) 748e38cbab5SGeorge Rimar if (auto *DataCmd = dyn_cast<BytesDataCommand>(Base2.get())) 749e38cbab5SGeorge Rimar writeInt<ELFT>(&Buf[DataCmd->Offset], DataCmd->Data, DataCmd->Size); 750e38cbab5SGeorge Rimar } 751e38cbab5SGeorge Rimar 752206fffa1SGeorge Rimar template <class ELFT> Expr LinkerScript<ELFT>::getLma(StringRef Name) { 7538ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 7548ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 7558ceadb38SGeorge Rimar if (Cmd->LmaExpr && Cmd->Name == Name) 7568ceadb38SGeorge Rimar return Cmd->LmaExpr; 7578ceadb38SGeorge Rimar return {}; 7588ceadb38SGeorge Rimar } 7598ceadb38SGeorge Rimar 760c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 761c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 762c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 763c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 764076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 765f510fa6bSRui Ueyama int I = 0; 766f510fa6bSRui Ueyama for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 767076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 768076fe157SGeorge Rimar if (Cmd->Name == Name) 769f510fa6bSRui Ueyama return I; 770f510fa6bSRui Ueyama ++I; 771f510fa6bSRui Ueyama } 772f510fa6bSRui Ueyama return INT_MAX; 77371b26e94SGeorge Rimar } 77471b26e94SGeorge Rimar 775bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 776bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 777bbe38602SEugene Leviant } 778bbe38602SEugene Leviant 7799e69450eSGeorge Rimar template <class ELFT> 780884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) { 78196659df0SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 78296659df0SGeorge Rimar if (Sec->getName() == Name) 78396659df0SGeorge Rimar return Sec->getVA(); 78496659df0SGeorge Rimar error("undefined section " + Name); 78596659df0SGeorge Rimar return 0; 78696659df0SGeorge Rimar } 78796659df0SGeorge Rimar 78896659df0SGeorge Rimar template <class ELFT> 789884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 7909e69450eSGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 7919e69450eSGeorge Rimar if (Sec->getName() == Name) 7929e69450eSGeorge Rimar return Sec->getSize(); 7939e69450eSGeorge Rimar error("undefined section " + Name); 7949e69450eSGeorge Rimar return 0; 7959e69450eSGeorge Rimar } 7969e69450eSGeorge Rimar 79736fac7f0SEugene Leviant template <class ELFT> 79836fac7f0SEugene Leviant uint64_t LinkerScript<ELFT>::getOutputSectionAlign(StringRef Name) { 79936fac7f0SEugene Leviant for (OutputSectionBase<ELFT> *Sec : *OutputSections) 80036fac7f0SEugene Leviant if (Sec->getName() == Name) 80136fac7f0SEugene Leviant return Sec->getAlignment(); 80236fac7f0SEugene Leviant error("undefined section " + Name); 80336fac7f0SEugene Leviant return 0; 80436fac7f0SEugene Leviant } 80536fac7f0SEugene Leviant 806884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() { 8070d4b6d5cSRafael Espindola return elf::getHeaderSize<ELFT>(); 808e32a3598SGeorge Rimar } 809e32a3598SGeorge Rimar 810884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) { 811884e786dSGeorge Rimar if (SymbolBody *B = Symtab<ELFT>::X->find(S)) 812884e786dSGeorge Rimar return B->getVA<ELFT>(); 813884e786dSGeorge Rimar error("symbol not found: " + S); 814884e786dSGeorge Rimar return 0; 815884e786dSGeorge Rimar } 816884e786dSGeorge Rimar 817f34f45fdSGeorge Rimar template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) { 818f34f45fdSGeorge Rimar return Symtab<ELFT>::X->find(S) != nullptr; 819f34f45fdSGeorge Rimar } 820f34f45fdSGeorge Rimar 821bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 822bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 823bbe38602SEugene Leviant // PHDRS {} script block. 824bbe38602SEugene Leviant template <class ELFT> 825edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 826076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 827076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 828edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 82931d842f5SGeorge Rimar continue; 83031d842f5SGeorge Rimar 83129c5a2a9SRui Ueyama std::vector<size_t> Ret; 83229c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 83329c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 83429c5a2a9SRui Ueyama return Ret; 835bbe38602SEugene Leviant } 83631d842f5SGeorge Rimar return {}; 83731d842f5SGeorge Rimar } 838bbe38602SEugene Leviant 83929c5a2a9SRui Ueyama template <class ELFT> 84029c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 84129c5a2a9SRui Ueyama size_t I = 0; 84229c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 84329c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 84429c5a2a9SRui Ueyama return I; 84529c5a2a9SRui Ueyama ++I; 84629c5a2a9SRui Ueyama } 84729c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 84829c5a2a9SRui Ueyama return 0; 84929c5a2a9SRui Ueyama } 85029c5a2a9SRui Ueyama 85107320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 852c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 853c3794e58SGeorge Rimar 854f7c5fbb1SRui Ueyama public: 85507320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 856f23b2320SGeorge Rimar 85720b6598cSGeorge Rimar void readLinkerScript(); 85820b6598cSGeorge Rimar void readVersionScript(); 859f7c5fbb1SRui Ueyama 860f7c5fbb1SRui Ueyama private: 86152a1509eSRui Ueyama void addFile(StringRef Path); 86252a1509eSRui Ueyama 863f7c5fbb1SRui Ueyama void readAsNeeded(); 86490c5099eSDenis Protivensky void readEntry(); 86583f406cfSGeorge Rimar void readExtern(); 866f7c5fbb1SRui Ueyama void readGroup(); 86731aa1f83SRui Ueyama void readInclude(); 868ee59282bSRui Ueyama void readOutput(); 8699159ce93SDavide Italiano void readOutputArch(); 870f7c5fbb1SRui Ueyama void readOutputFormat(); 871bbe38602SEugene Leviant void readPhdrs(); 87268a39a65SDavide Italiano void readSearchDir(); 8738e3b38abSDenis Protivensky void readSections(); 87495769b4aSRui Ueyama void readVersion(); 87595769b4aSRui Ueyama void readVersionScriptCommand(); 8768e3b38abSDenis Protivensky 877113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 878e38cbab5SGeorge Rimar BytesDataCommand *readBytesDataCommand(StringRef Tok); 879ff1f29e0SGeorge Rimar std::vector<uint8_t> readFill(); 88010416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 881ff1f29e0SGeorge Rimar std::vector<uint8_t> readOutputSectionFiller(StringRef Tok); 882bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 883a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 884c91930a1SGeorge Rimar Regex readFilePatterns(); 88507171f21SGeorge Rimar std::vector<SectionPattern> readInputSectionsList(); 886a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 887bbe38602SEugene Leviant unsigned readPhdrType(); 888be394db3SGeorge Rimar SortSectionPolicy readSortKind(); 889a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 890db741e72SEugene Leviant SymbolAssignment *readProvideOrAssignment(StringRef Tok, bool MakeAbsolute); 89103fc010eSGeorge Rimar void readSort(); 892eefa758eSGeorge Rimar Expr readAssert(); 893708019c4SRui Ueyama 894708019c4SRui Ueyama Expr readExpr(); 895708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 896708019c4SRui Ueyama Expr readPrimary(); 897708019c4SRui Ueyama Expr readTernary(Expr Cond); 8986ad7dfccSRui Ueyama Expr readParenExpr(); 899f7c5fbb1SRui Ueyama 90020b6598cSGeorge Rimar // For parsing version script. 90120b6598cSGeorge Rimar void readExtern(std::vector<SymbolVersion> *Globals); 90295769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 90320b6598cSGeorge Rimar void readGlobal(StringRef VerStr); 90420b6598cSGeorge Rimar void readLocal(); 90520b6598cSGeorge Rimar 90607320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 90707320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 90816b0cc9eSSimon Atanasyan bool IsUnderSysroot; 909f7c5fbb1SRui Ueyama }; 910f7c5fbb1SRui Ueyama 91120b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 91295769b4aSRui Ueyama readVersionScriptCommand(); 91320b6598cSGeorge Rimar if (!atEOF()) 91495769b4aSRui Ueyama setError("EOF expected, but got " + next()); 91595769b4aSRui Ueyama } 91695769b4aSRui Ueyama 91795769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 91895769b4aSRui Ueyama if (skip("{")) { 91995769b4aSRui Ueyama readVersionDeclaration(""); 92020b6598cSGeorge Rimar return; 92120b6598cSGeorge Rimar } 92220b6598cSGeorge Rimar 92395769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 92420b6598cSGeorge Rimar StringRef VerStr = next(); 92520b6598cSGeorge Rimar if (VerStr == "{") { 92695769b4aSRui Ueyama setError("anonymous version definition is used in " 92795769b4aSRui Ueyama "combination with other version definitions"); 92820b6598cSGeorge Rimar return; 92920b6598cSGeorge Rimar } 93020b6598cSGeorge Rimar expect("{"); 93195769b4aSRui Ueyama readVersionDeclaration(VerStr); 93220b6598cSGeorge Rimar } 93320b6598cSGeorge Rimar } 93420b6598cSGeorge Rimar 93595769b4aSRui Ueyama void ScriptParser::readVersion() { 93695769b4aSRui Ueyama expect("{"); 93795769b4aSRui Ueyama readVersionScriptCommand(); 93895769b4aSRui Ueyama expect("}"); 93995769b4aSRui Ueyama } 94095769b4aSRui Ueyama 94120b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 942f7c5fbb1SRui Ueyama while (!atEOF()) { 943f7c5fbb1SRui Ueyama StringRef Tok = next(); 944a27eeccaSRui Ueyama if (Tok == ";") 945a27eeccaSRui Ueyama continue; 946a27eeccaSRui Ueyama 94720d03194SEugene Leviant if (Tok == "ASSERT") { 94820d03194SEugene Leviant Opt.Commands.emplace_back(new AssertCommand(readAssert())); 94920d03194SEugene Leviant } else if (Tok == "ENTRY") { 950a27eeccaSRui Ueyama readEntry(); 951a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 952a27eeccaSRui Ueyama readExtern(); 953a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 954a27eeccaSRui Ueyama readGroup(); 955a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 956a27eeccaSRui Ueyama readInclude(); 957a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 958a27eeccaSRui Ueyama readOutput(); 959a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 960a27eeccaSRui Ueyama readOutputArch(); 961a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 962a27eeccaSRui Ueyama readOutputFormat(); 963a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 964a27eeccaSRui Ueyama readPhdrs(); 965a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 966a27eeccaSRui Ueyama readSearchDir(); 967a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 968a27eeccaSRui Ueyama readSections(); 969a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 970a27eeccaSRui Ueyama readVersion(); 971db741e72SEugene Leviant } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok, true)) { 9720df80befSPetr Hosek Opt.Commands.emplace_back(Cmd); 973e5d3ca50SPetr Hosek } else { 9745761042dSGeorge Rimar setError("unknown directive: " + Tok); 975f7c5fbb1SRui Ueyama } 976f7c5fbb1SRui Ueyama } 977e5d3ca50SPetr Hosek } 978f7c5fbb1SRui Ueyama 979717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 98016b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 98116b0cc9eSSimon Atanasyan SmallString<128> Path; 98216b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 98316b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 98416b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 98516b0cc9eSSimon Atanasyan return; 98616b0cc9eSSimon Atanasyan } 98716b0cc9eSSimon Atanasyan } 98816b0cc9eSSimon Atanasyan 989f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 99052a1509eSRui Ueyama Driver->addFile(S); 99152a1509eSRui Ueyama } else if (S.startswith("=")) { 99252a1509eSRui Ueyama if (Config->Sysroot.empty()) 99352a1509eSRui Ueyama Driver->addFile(S.substr(1)); 99452a1509eSRui Ueyama else 99552a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 99652a1509eSRui Ueyama } else if (S.startswith("-l")) { 99721eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 998a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 999a1b8fc3bSSimon Atanasyan Driver->addFile(S); 100052a1509eSRui Ueyama } else { 100152a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 100252a1509eSRui Ueyama if (Path.empty()) 1003777f9630SGeorge Rimar setError("unable to find " + S); 1004025d59b1SRui Ueyama else 100552a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 100652a1509eSRui Ueyama } 100752a1509eSRui Ueyama } 100852a1509eSRui Ueyama 1009717677afSRui Ueyama void ScriptParser::readAsNeeded() { 1010f7c5fbb1SRui Ueyama expect("("); 101135da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 101235da9b6eSRui Ueyama Config->AsNeeded = true; 1013a2acc931SRui Ueyama while (!Error && !skip(")")) 1014cd574a5eSGeorge Rimar addFile(unquote(next())); 101535da9b6eSRui Ueyama Config->AsNeeded = Orig; 1016f7c5fbb1SRui Ueyama } 1017f7c5fbb1SRui Ueyama 1018717677afSRui Ueyama void ScriptParser::readEntry() { 101990c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 102090c5099eSDenis Protivensky expect("("); 102190c5099eSDenis Protivensky StringRef Tok = next(); 102290c5099eSDenis Protivensky if (Config->Entry.empty()) 102390c5099eSDenis Protivensky Config->Entry = Tok; 102490c5099eSDenis Protivensky expect(")"); 102590c5099eSDenis Protivensky } 102690c5099eSDenis Protivensky 1027717677afSRui Ueyama void ScriptParser::readExtern() { 102883f406cfSGeorge Rimar expect("("); 1029a2acc931SRui Ueyama while (!Error && !skip(")")) 1030a2acc931SRui Ueyama Config->Undefined.push_back(next()); 103183f406cfSGeorge Rimar } 103283f406cfSGeorge Rimar 1033717677afSRui Ueyama void ScriptParser::readGroup() { 1034f7c5fbb1SRui Ueyama expect("("); 1035a2acc931SRui Ueyama while (!Error && !skip(")")) { 1036f7c5fbb1SRui Ueyama StringRef Tok = next(); 1037a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 1038f7c5fbb1SRui Ueyama readAsNeeded(); 1039a2acc931SRui Ueyama else 1040cd574a5eSGeorge Rimar addFile(unquote(Tok)); 1041f7c5fbb1SRui Ueyama } 1042f7c5fbb1SRui Ueyama } 1043f7c5fbb1SRui Ueyama 1044717677afSRui Ueyama void ScriptParser::readInclude() { 104531aa1f83SRui Ueyama StringRef Tok = next(); 1046cd574a5eSGeorge Rimar auto MBOrErr = MemoryBuffer::getFile(unquote(Tok)); 1047025d59b1SRui Ueyama if (!MBOrErr) { 10485761042dSGeorge Rimar setError("cannot open " + Tok); 1049025d59b1SRui Ueyama return; 1050025d59b1SRui Ueyama } 105131aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 1052a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 1053a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 105431aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 105531aa1f83SRui Ueyama } 105631aa1f83SRui Ueyama 1057717677afSRui Ueyama void ScriptParser::readOutput() { 1058ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 1059ee59282bSRui Ueyama expect("("); 1060ee59282bSRui Ueyama StringRef Tok = next(); 1061ee59282bSRui Ueyama if (Config->OutputFile.empty()) 1062cd574a5eSGeorge Rimar Config->OutputFile = unquote(Tok); 1063ee59282bSRui Ueyama expect(")"); 1064ee59282bSRui Ueyama } 1065ee59282bSRui Ueyama 1066717677afSRui Ueyama void ScriptParser::readOutputArch() { 10679159ce93SDavide Italiano // Error checking only for now. 10689159ce93SDavide Italiano expect("("); 10699159ce93SDavide Italiano next(); 10709159ce93SDavide Italiano expect(")"); 10719159ce93SDavide Italiano } 10729159ce93SDavide Italiano 1073717677afSRui Ueyama void ScriptParser::readOutputFormat() { 1074f7c5fbb1SRui Ueyama // Error checking only for now. 1075f7c5fbb1SRui Ueyama expect("("); 1076f7c5fbb1SRui Ueyama next(); 10776836c618SDavide Italiano StringRef Tok = next(); 10786836c618SDavide Italiano if (Tok == ")") 10796836c618SDavide Italiano return; 1080025d59b1SRui Ueyama if (Tok != ",") { 10815761042dSGeorge Rimar setError("unexpected token: " + Tok); 1082025d59b1SRui Ueyama return; 1083025d59b1SRui Ueyama } 10846836c618SDavide Italiano next(); 10856836c618SDavide Italiano expect(","); 10866836c618SDavide Italiano next(); 1087f7c5fbb1SRui Ueyama expect(")"); 1088f7c5fbb1SRui Ueyama } 1089f7c5fbb1SRui Ueyama 1090bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 1091bbe38602SEugene Leviant expect("{"); 1092bbe38602SEugene Leviant while (!Error && !skip("}")) { 1093bbe38602SEugene Leviant StringRef Tok = next(); 109456b21c86SEugene Leviant Opt.PhdrsCommands.push_back( 109556b21c86SEugene Leviant {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 1096bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 1097bbe38602SEugene Leviant 1098bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 1099bbe38602SEugene Leviant do { 1100bbe38602SEugene Leviant Tok = next(); 1101bbe38602SEugene Leviant if (Tok == ";") 1102bbe38602SEugene Leviant break; 1103bbe38602SEugene Leviant if (Tok == "FILEHDR") 1104bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 1105bbe38602SEugene Leviant else if (Tok == "PHDRS") 1106bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 110756b21c86SEugene Leviant else if (Tok == "AT") 110856b21c86SEugene Leviant PhdrCmd.LMAExpr = readParenExpr(); 1109865bf863SEugene Leviant else if (Tok == "FLAGS") { 1110865bf863SEugene Leviant expect("("); 1111eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 1112eb685cd7SRafael Espindola // we accept expressions like ".|1". 1113eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 1114865bf863SEugene Leviant expect(")"); 1115865bf863SEugene Leviant } else 1116bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 1117bbe38602SEugene Leviant } while (!Error); 1118bbe38602SEugene Leviant } 1119bbe38602SEugene Leviant } 1120bbe38602SEugene Leviant 1121717677afSRui Ueyama void ScriptParser::readSearchDir() { 112268a39a65SDavide Italiano expect("("); 112386c5fb82SRui Ueyama StringRef Tok = next(); 11246c7ad13fSRui Ueyama if (!Config->Nostdlib) 1125cd574a5eSGeorge Rimar Config->SearchPaths.push_back(unquote(Tok)); 112668a39a65SDavide Italiano expect(")"); 112768a39a65SDavide Italiano } 112868a39a65SDavide Italiano 1129717677afSRui Ueyama void ScriptParser::readSections() { 1130e05336ffSEugene Leviant Opt.HasSections = true; 11318e3b38abSDenis Protivensky expect("{"); 1132652852c5SGeorge Rimar while (!Error && !skip("}")) { 1133113cdec9SRui Ueyama StringRef Tok = next(); 1134db741e72SEugene Leviant BaseCommand *Cmd = readProvideOrAssignment(Tok, true); 1135ceabe80eSEugene Leviant if (!Cmd) { 1136ceabe80eSEugene Leviant if (Tok == "ASSERT") 1137eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 1138ceabe80eSEugene Leviant else 113910416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 11408e3b38abSDenis Protivensky } 114110416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 1142652852c5SGeorge Rimar } 1143708019c4SRui Ueyama } 11448e3b38abSDenis Protivensky 1145708019c4SRui Ueyama static int precedence(StringRef Op) { 1146708019c4SRui Ueyama return StringSwitch<int>(Op) 11470120e3f2SRui Ueyama .Cases("*", "/", 5) 11480120e3f2SRui Ueyama .Cases("+", "-", 4) 11490120e3f2SRui Ueyama .Cases("<<", ">>", 3) 11509c4ac5f2SRui Ueyama .Cases("<", "<=", ">", ">=", "==", "!=", 2) 11510120e3f2SRui Ueyama .Cases("&", "|", 1) 1152708019c4SRui Ueyama .Default(-1); 1153708019c4SRui Ueyama } 1154708019c4SRui Ueyama 1155c91930a1SGeorge Rimar Regex ScriptParser::readFilePatterns() { 115610416564SRui Ueyama std::vector<StringRef> V; 115710416564SRui Ueyama while (!Error && !skip(")")) 115810416564SRui Ueyama V.push_back(next()); 1159c91930a1SGeorge Rimar return compileGlobPatterns(V); 11600702c4e8SGeorge Rimar } 11610702c4e8SGeorge Rimar 1162be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() { 1163742c3836SRui Ueyama if (skip("SORT") || skip("SORT_BY_NAME")) 1164be394db3SGeorge Rimar return SortSectionPolicy::Name; 1165742c3836SRui Ueyama if (skip("SORT_BY_ALIGNMENT")) 1166be394db3SGeorge Rimar return SortSectionPolicy::Alignment; 1167575208caSGeorge Rimar if (skip("SORT_BY_INIT_PRIORITY")) 1168be394db3SGeorge Rimar return SortSectionPolicy::Priority; 1169be394db3SGeorge Rimar if (skip("SORT_NONE")) 1170be394db3SGeorge Rimar return SortSectionPolicy::None; 1171b2a0abdfSRui Ueyama return SortSectionPolicy::Default; 1172be394db3SGeorge Rimar } 1173be394db3SGeorge Rimar 1174395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in 1175395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ 1176395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) 1177af03be19SGeorge Rimar // The semantics of that is next: 1178af03be19SGeorge Rimar // * Include .foo.1 from every file. 1179af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o 1180af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o 118107171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 118207171f21SGeorge Rimar std::vector<SectionPattern> Ret; 1183601e9898SGeorge Rimar while (!Error && peek() != ")") { 1184027a9e87SRui Ueyama Regex ExcludeFileRe; 1185395281cfSGeorge Rimar if (skip("EXCLUDE_FILE")) { 1186395281cfSGeorge Rimar expect("("); 1187395281cfSGeorge Rimar ExcludeFileRe = readFilePatterns(); 1188395281cfSGeorge Rimar } 1189395281cfSGeorge Rimar 1190601e9898SGeorge Rimar std::vector<StringRef> V; 1191601e9898SGeorge Rimar while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE") 1192395281cfSGeorge Rimar V.push_back(next()); 1193601e9898SGeorge Rimar 1194601e9898SGeorge Rimar if (!V.empty()) 119507171f21SGeorge Rimar Ret.push_back({std::move(ExcludeFileRe), compileGlobPatterns(V)}); 1196601e9898SGeorge Rimar else 1197601e9898SGeorge Rimar setError("section pattern is expected"); 1198395281cfSGeorge Rimar } 119907171f21SGeorge Rimar return Ret; 1200395281cfSGeorge Rimar } 1201395281cfSGeorge Rimar 120207171f21SGeorge Rimar // Section pattern grammar can have complex expressions, for example: 120307171f21SGeorge Rimar // *(SORT(.foo.* EXCLUDE_FILE (*file1.o) .bar.*) .bar.* SORT(.zed.*)) 120407171f21SGeorge Rimar // Generally is a sequence of globs and excludes that may be wrapped in a SORT() 120507171f21SGeorge Rimar // commands, like: SORT(glob0) glob1 glob2 SORT(glob4) 120607171f21SGeorge Rimar // This methods handles wrapping sequences of excluded files and section globs 120707171f21SGeorge Rimar // into SORT() if that needed and reads them all. 1208a2496cbeSGeorge Rimar InputSectionDescription * 1209a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 1210c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 12110ed42b0cSDavide Italiano expect("("); 121207171f21SGeorge Rimar while (!HasError && !skip(")")) { 121307171f21SGeorge Rimar SortSectionPolicy Outer = readSortKind(); 121407171f21SGeorge Rimar SortSectionPolicy Inner = SortSectionPolicy::Default; 121507171f21SGeorge Rimar std::vector<SectionPattern> V; 121607171f21SGeorge Rimar if (Outer != SortSectionPolicy::Default) { 12170702c4e8SGeorge Rimar expect("("); 121807171f21SGeorge Rimar Inner = readSortKind(); 121907171f21SGeorge Rimar if (Inner != SortSectionPolicy::Default) { 1220350ece4eSGeorge Rimar expect("("); 122107171f21SGeorge Rimar V = readInputSectionsList(); 12220702c4e8SGeorge Rimar expect(")"); 1223350ece4eSGeorge Rimar } else { 122407171f21SGeorge Rimar V = readInputSectionsList(); 1225350ece4eSGeorge Rimar } 1226350ece4eSGeorge Rimar expect(")"); 122707171f21SGeorge Rimar } else { 122807171f21SGeorge Rimar V = readInputSectionsList(); 12290659800eSGeorge Rimar } 12300702c4e8SGeorge Rimar 123107171f21SGeorge Rimar for (SectionPattern &Pat : V) { 123207171f21SGeorge Rimar Pat.SortInner = Inner; 123307171f21SGeorge Rimar Pat.SortOuter = Outer; 123407171f21SGeorge Rimar } 123507171f21SGeorge Rimar 123607171f21SGeorge Rimar std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 123707171f21SGeorge Rimar } 123810416564SRui Ueyama return Cmd; 12390659800eSGeorge Rimar } 12400659800eSGeorge Rimar 1241a2496cbeSGeorge Rimar InputSectionDescription * 1242a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 12430659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 12440659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 1245a2496cbeSGeorge Rimar if (Tok == "KEEP") { 1246e7282797SDavide Italiano expect("("); 1247a2496cbeSGeorge Rimar StringRef FilePattern = next(); 1248a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 12490ed42b0cSDavide Italiano expect(")"); 12504dc07becSRui Ueyama for (SectionPattern &Pat : Cmd->SectionPatterns) 12514dc07becSRui Ueyama Opt.KeptSections.push_back(&Pat.SectionRe); 125210416564SRui Ueyama return Cmd; 125310416564SRui Ueyama } 1254a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 12550659800eSGeorge Rimar } 12560659800eSGeorge Rimar 125703fc010eSGeorge Rimar void ScriptParser::readSort() { 125803fc010eSGeorge Rimar expect("("); 125903fc010eSGeorge Rimar expect("CONSTRUCTORS"); 126003fc010eSGeorge Rimar expect(")"); 126103fc010eSGeorge Rimar } 126203fc010eSGeorge Rimar 1263eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 1264eefa758eSGeorge Rimar expect("("); 1265eefa758eSGeorge Rimar Expr E = readExpr(); 1266eefa758eSGeorge Rimar expect(","); 1267cd574a5eSGeorge Rimar StringRef Msg = unquote(next()); 1268eefa758eSGeorge Rimar expect(")"); 1269eefa758eSGeorge Rimar return [=](uint64_t Dot) { 1270eefa758eSGeorge Rimar uint64_t V = E(Dot); 1271eefa758eSGeorge Rimar if (!V) 1272eefa758eSGeorge Rimar error(Msg); 1273eefa758eSGeorge Rimar return V; 1274eefa758eSGeorge Rimar }; 1275eefa758eSGeorge Rimar } 1276eefa758eSGeorge Rimar 127725150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 127825150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from 127925150e8bSRui Ueyama // what GNU linkers do. 128025150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 1281ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readFill() { 1282ff1f29e0SGeorge Rimar expect("("); 1283ff1f29e0SGeorge Rimar std::vector<uint8_t> V = readOutputSectionFiller(next()); 1284ff1f29e0SGeorge Rimar expect(")"); 1285ff1f29e0SGeorge Rimar expect(";"); 1286ff1f29e0SGeorge Rimar return V; 1287ff1f29e0SGeorge Rimar } 1288ff1f29e0SGeorge Rimar 128910416564SRui Ueyama OutputSectionCommand * 129010416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 1291076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 129258e5c4dcSGeorge Rimar 129358e5c4dcSGeorge Rimar // Read an address expression. 129458e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 129558e5c4dcSGeorge Rimar if (peek() != ":") 129658e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 129758e5c4dcSGeorge Rimar 12988e3b38abSDenis Protivensky expect(":"); 1299246f681eSDavide Italiano 13008ceadb38SGeorge Rimar if (skip("AT")) 13016ad7dfccSRui Ueyama Cmd->LmaExpr = readParenExpr(); 1302630c6179SGeorge Rimar if (skip("ALIGN")) 13036ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 1304db24d9c3SGeorge Rimar if (skip("SUBALIGN")) 1305db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1306630c6179SGeorge Rimar 1307246f681eSDavide Italiano // Parse constraints. 1308246f681eSDavide Italiano if (skip("ONLY_IF_RO")) 1309efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 1310246f681eSDavide Italiano if (skip("ONLY_IF_RW")) 1311efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 13128e3b38abSDenis Protivensky expect("{"); 13138ec77e64SRui Ueyama 1314025d59b1SRui Ueyama while (!Error && !skip("}")) { 1315ceabe80eSEugene Leviant StringRef Tok = next(); 1316db741e72SEugene Leviant if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok, false)) 1317ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1318e38cbab5SGeorge Rimar else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) 1319e38cbab5SGeorge Rimar Cmd->Commands.emplace_back(Data); 1320ff1f29e0SGeorge Rimar else if (Tok == "FILL") 1321ff1f29e0SGeorge Rimar Cmd->Filler = readFill(); 1322ceabe80eSEugene Leviant else if (Tok == "SORT") 132303fc010eSGeorge Rimar readSort(); 1324a2496cbeSGeorge Rimar else if (peek() == "(") 1325a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1326ceabe80eSEugene Leviant else 1327ceabe80eSEugene Leviant setError("unknown command " + Tok); 13288e3b38abSDenis Protivensky } 1329076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 13304ebc5620SGeorge Rimar 13314ebc5620SGeorge Rimar if (skip("=")) 13324ebc5620SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next()); 13334ebc5620SGeorge Rimar else if (peek().startswith("=")) 1334ff1f29e0SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next().drop_front()); 13354ebc5620SGeorge Rimar 133610416564SRui Ueyama return Cmd; 1337f71caa2bSRui Ueyama } 13388ec77e64SRui Ueyama 13392c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 13402c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 13412c8f1f04SRui Ueyama // 13422c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 13432c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 13442c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 13452c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 1346ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readOutputSectionFiller(StringRef Tok) { 1347965827d6SRui Ueyama uint32_t V; 1348ff1f29e0SGeorge Rimar if (Tok.getAsInteger(0, V)) { 1349965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 1350f71caa2bSRui Ueyama return {}; 1351e2ee72b5SGeorge Rimar } 1352965827d6SRui Ueyama return {uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V)}; 13538e3b38abSDenis Protivensky } 13548e3b38abSDenis Protivensky 1355a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1356a31c91b1SEugene Leviant expect("("); 1357174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1358a35e39caSPetr Hosek Cmd->Provide = Provide; 1359174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1360a31c91b1SEugene Leviant expect(")"); 1361a31c91b1SEugene Leviant expect(";"); 136210416564SRui Ueyama return Cmd; 1363eda81a1bSEugene Leviant } 1364eda81a1bSEugene Leviant 1365db741e72SEugene Leviant SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok, 1366db741e72SEugene Leviant bool MakeAbsolute) { 1367ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1368ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1369ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1370ceabe80eSEugene Leviant expect(";"); 1371ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1372a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1373a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1374a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1375ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1376a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1377ceabe80eSEugene Leviant } 1378db741e72SEugene Leviant if (Cmd && MakeAbsolute) 1379db741e72SEugene Leviant Cmd->IsAbsolute = true; 1380ceabe80eSEugene Leviant return Cmd; 1381ceabe80eSEugene Leviant } 1382ceabe80eSEugene Leviant 138330835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { 138430835ea4SGeorge Rimar if (S == ".") 138530835ea4SGeorge Rimar return Dot; 1386884e786dSGeorge Rimar return ScriptBase->getSymbolValue(S); 1387e32a3598SGeorge Rimar } 1388e32a3598SGeorge Rimar 138930835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 139030835ea4SGeorge Rimar StringRef Op = next(); 1391db741e72SEugene Leviant bool IsAbsolute = false; 1392db741e72SEugene Leviant Expr E; 139330835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 1394db741e72SEugene Leviant if (skip("ABSOLUTE")) { 1395db741e72SEugene Leviant E = readParenExpr(); 1396db741e72SEugene Leviant IsAbsolute = true; 1397db741e72SEugene Leviant } else { 1398db741e72SEugene Leviant E = readExpr(); 1399db741e72SEugene Leviant } 140030835ea4SGeorge Rimar if (Op == "+=") 140130835ea4SGeorge Rimar E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; 1402db741e72SEugene Leviant return new SymbolAssignment(Name, E, IsAbsolute); 140330835ea4SGeorge Rimar } 140430835ea4SGeorge Rimar 140530835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 140630835ea4SGeorge Rimar // script expression. 140730835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 140830835ea4SGeorge Rimar 140936c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 141036c1cd23SRui Ueyama if (Op == "*") 141136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 141236c1cd23SRui Ueyama if (Op == "/") { 141336c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 141436c1cd23SRui Ueyama uint64_t RHS = R(Dot); 141536c1cd23SRui Ueyama if (RHS == 0) { 141636c1cd23SRui Ueyama error("division by zero"); 141736c1cd23SRui Ueyama return 0; 141836c1cd23SRui Ueyama } 141936c1cd23SRui Ueyama return L(Dot) / RHS; 142036c1cd23SRui Ueyama }; 142136c1cd23SRui Ueyama } 142236c1cd23SRui Ueyama if (Op == "+") 142336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) + R(Dot); }; 142436c1cd23SRui Ueyama if (Op == "-") 142536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 1426c8ccd1f1SGeorge Rimar if (Op == "<<") 1427c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) << R(Dot); }; 1428c8ccd1f1SGeorge Rimar if (Op == ">>") 1429c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) >> R(Dot); }; 143036c1cd23SRui Ueyama if (Op == "<") 143136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 143236c1cd23SRui Ueyama if (Op == ">") 143336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 143436c1cd23SRui Ueyama if (Op == ">=") 143536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 143636c1cd23SRui Ueyama if (Op == "<=") 143736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 143836c1cd23SRui Ueyama if (Op == "==") 143936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 144036c1cd23SRui Ueyama if (Op == "!=") 144136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 144236c1cd23SRui Ueyama if (Op == "&") 144336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 1444cc3dd629SRafael Espindola if (Op == "|") 1445cc3dd629SRafael Espindola return [=](uint64_t Dot) { return L(Dot) | R(Dot); }; 144636c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 144736c1cd23SRui Ueyama } 144836c1cd23SRui Ueyama 1449708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1450708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1451708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1452708019c4SRui Ueyama while (!atEOF() && !Error) { 1453708019c4SRui Ueyama // Read an operator and an expression. 1454708019c4SRui Ueyama StringRef Op1 = peek(); 1455708019c4SRui Ueyama if (Op1 == "?") 1456708019c4SRui Ueyama return readTernary(Lhs); 1457708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1458a31c91b1SEugene Leviant break; 1459a31c91b1SEugene Leviant next(); 1460708019c4SRui Ueyama Expr Rhs = readPrimary(); 1461708019c4SRui Ueyama 1462708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1463708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1464708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1465708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1466708019c4SRui Ueyama while (!atEOF()) { 1467708019c4SRui Ueyama StringRef Op2 = peek(); 1468708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1469eda81a1bSEugene Leviant break; 1470708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1471eda81a1bSEugene Leviant } 1472708019c4SRui Ueyama 1473708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1474708019c4SRui Ueyama } 1475708019c4SRui Ueyama return Lhs; 1476708019c4SRui Ueyama } 1477708019c4SRui Ueyama 1478708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1479e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1480708019c4SRui Ueyama return Target->PageSize; 1481e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1482997f8838SPetr Hosek return Config->MaxPageSize; 1483708019c4SRui Ueyama error("unknown constant: " + S); 1484708019c4SRui Ueyama return 0; 1485708019c4SRui Ueyama } 1486708019c4SRui Ueyama 1487626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1488626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1489626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1490626e0b08SRui Ueyama // "M" (mega) prefixes. 14919f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 1492eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1493eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1494eaeafb2bSSimon Atanasyan return false; 1495eaeafb2bSSimon Atanasyan Result = -Result; 1496eaeafb2bSSimon Atanasyan return true; 1497eaeafb2bSSimon Atanasyan } 14989f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 14999f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 15009f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 15019f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 15029f2f7ad9SGeorge Rimar 15039f2f7ad9SGeorge Rimar int Suffix = 1; 15049f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 15059f2f7ad9SGeorge Rimar Suffix = 1024; 15069f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 15079f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 15089f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 15099f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 15109f2f7ad9SGeorge Rimar } 15119f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 15129f2f7ad9SGeorge Rimar return false; 15139f2f7ad9SGeorge Rimar Result *= Suffix; 15149f2f7ad9SGeorge Rimar return true; 15159f2f7ad9SGeorge Rimar } 15169f2f7ad9SGeorge Rimar 1517e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { 1518e38cbab5SGeorge Rimar int Size = StringSwitch<unsigned>(Tok) 1519e38cbab5SGeorge Rimar .Case("BYTE", 1) 1520e38cbab5SGeorge Rimar .Case("SHORT", 2) 1521e38cbab5SGeorge Rimar .Case("LONG", 4) 1522e38cbab5SGeorge Rimar .Case("QUAD", 8) 1523e38cbab5SGeorge Rimar .Default(-1); 1524e38cbab5SGeorge Rimar if (Size == -1) 1525e38cbab5SGeorge Rimar return nullptr; 1526e38cbab5SGeorge Rimar 1527e38cbab5SGeorge Rimar expect("("); 1528e38cbab5SGeorge Rimar uint64_t Val = 0; 1529e38cbab5SGeorge Rimar StringRef S = next(); 1530e38cbab5SGeorge Rimar if (!readInteger(S, Val)) 1531e38cbab5SGeorge Rimar setError("unexpected value: " + S); 1532e38cbab5SGeorge Rimar expect(")"); 1533e38cbab5SGeorge Rimar return new BytesDataCommand(Val, Size); 1534e38cbab5SGeorge Rimar } 1535e38cbab5SGeorge Rimar 1536708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 15376ad7dfccSRui Ueyama if (peek() == "(") 15386ad7dfccSRui Ueyama return readParenExpr(); 1539708019c4SRui Ueyama 15406ad7dfccSRui Ueyama StringRef Tok = next(); 1541708019c4SRui Ueyama 1542eaeafb2bSSimon Atanasyan if (Tok == "~") { 1543eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1544eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return ~E(Dot); }; 1545eaeafb2bSSimon Atanasyan } 1546eaeafb2bSSimon Atanasyan if (Tok == "-") { 1547eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1548eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return -E(Dot); }; 1549eaeafb2bSSimon Atanasyan } 1550eaeafb2bSSimon Atanasyan 1551708019c4SRui Ueyama // Built-in functions are parsed here. 1552708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 155396659df0SGeorge Rimar if (Tok == "ADDR") { 155496659df0SGeorge Rimar expect("("); 155596659df0SGeorge Rimar StringRef Name = next(); 155696659df0SGeorge Rimar expect(")"); 1557884e786dSGeorge Rimar return 1558884e786dSGeorge Rimar [=](uint64_t Dot) { return ScriptBase->getOutputSectionAddress(Name); }; 155996659df0SGeorge Rimar } 1560eefa758eSGeorge Rimar if (Tok == "ASSERT") 1561eefa758eSGeorge Rimar return readAssert(); 1562708019c4SRui Ueyama if (Tok == "ALIGN") { 15636ad7dfccSRui Ueyama Expr E = readParenExpr(); 1564708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1565708019c4SRui Ueyama } 1566708019c4SRui Ueyama if (Tok == "CONSTANT") { 1567708019c4SRui Ueyama expect("("); 1568708019c4SRui Ueyama StringRef Tok = next(); 1569708019c4SRui Ueyama expect(")"); 1570708019c4SRui Ueyama return [=](uint64_t Dot) { return getConstant(Tok); }; 1571708019c4SRui Ueyama } 1572f34f45fdSGeorge Rimar if (Tok == "DEFINED") { 1573f34f45fdSGeorge Rimar expect("("); 1574f34f45fdSGeorge Rimar StringRef Tok = next(); 1575f34f45fdSGeorge Rimar expect(")"); 1576f2821028SGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->isDefined(Tok) ? 1 : 0; }; 1577f34f45fdSGeorge Rimar } 157854c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 157954c145ceSRafael Espindola expect("("); 158054c145ceSRafael Espindola next(); 158154c145ceSRafael Espindola expect(","); 15828c658bf8SGeorge Rimar Expr E = readExpr(); 158354c145ceSRafael Espindola expect(")"); 15848c658bf8SGeorge Rimar return [=](uint64_t Dot) { return E(Dot); }; 158554c145ceSRafael Espindola } 1586708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1587708019c4SRui Ueyama expect("("); 1588708019c4SRui Ueyama Expr E = readExpr(); 1589708019c4SRui Ueyama expect(","); 1590708019c4SRui Ueyama readExpr(); 1591708019c4SRui Ueyama expect(")"); 1592f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1593708019c4SRui Ueyama } 1594708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1595708019c4SRui Ueyama expect("("); 1596708019c4SRui Ueyama expect("."); 1597708019c4SRui Ueyama expect(")"); 1598708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1599708019c4SRui Ueyama } 1600276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1601276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1602276b4e64SGeorge Rimar // the next page boundary for simplicity. 1603276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1604276b4e64SGeorge Rimar expect("("); 160597bdc722SRafael Espindola readExpr(); 1606276b4e64SGeorge Rimar expect(","); 1607276b4e64SGeorge Rimar readExpr(); 1608276b4e64SGeorge Rimar expect(")"); 1609276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1610276b4e64SGeorge Rimar } 16119e69450eSGeorge Rimar if (Tok == "SIZEOF") { 16129e69450eSGeorge Rimar expect("("); 16139e69450eSGeorge Rimar StringRef Name = next(); 16149e69450eSGeorge Rimar expect(")"); 1615884e786dSGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; 16169e69450eSGeorge Rimar } 161736fac7f0SEugene Leviant if (Tok == "ALIGNOF") { 161836fac7f0SEugene Leviant expect("("); 161936fac7f0SEugene Leviant StringRef Name = next(); 162036fac7f0SEugene Leviant expect(")"); 162136fac7f0SEugene Leviant return 162236fac7f0SEugene Leviant [=](uint64_t Dot) { return ScriptBase->getOutputSectionAlign(Name); }; 162336fac7f0SEugene Leviant } 1624e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 1625884e786dSGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; 1626708019c4SRui Ueyama 16279f2f7ad9SGeorge Rimar // Tok is a literal number. 16289f2f7ad9SGeorge Rimar uint64_t V; 16299f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 16309f2f7ad9SGeorge Rimar return [=](uint64_t Dot) { return V; }; 16319f2f7ad9SGeorge Rimar 16329f2f7ad9SGeorge Rimar // Tok is a symbol name. 163330835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1634708019c4SRui Ueyama setError("malformed number: " + Tok); 163530835ea4SGeorge Rimar return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }; 1636a9c5a528SGeorge Rimar } 1637708019c4SRui Ueyama 1638708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1639708019c4SRui Ueyama next(); 1640708019c4SRui Ueyama Expr L = readExpr(); 1641708019c4SRui Ueyama expect(":"); 1642708019c4SRui Ueyama Expr R = readExpr(); 1643708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1644708019c4SRui Ueyama } 1645708019c4SRui Ueyama 16466ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 16476ad7dfccSRui Ueyama expect("("); 16486ad7dfccSRui Ueyama Expr E = readExpr(); 16496ad7dfccSRui Ueyama expect(")"); 16506ad7dfccSRui Ueyama return E; 16516ad7dfccSRui Ueyama } 16526ad7dfccSRui Ueyama 1653bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1654bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1655bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1656bbe38602SEugene Leviant StringRef Tok = next(); 1657bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 1658bbe38602SEugene Leviant if (Tok.empty()) { 1659bbe38602SEugene Leviant setError("section header name is empty"); 1660bbe38602SEugene Leviant break; 1661bbe38602SEugene Leviant } 1662bbe38602SEugene Leviant Phdrs.push_back(Tok); 1663bbe38602SEugene Leviant } 1664bbe38602SEugene Leviant return Phdrs; 1665bbe38602SEugene Leviant } 1666bbe38602SEugene Leviant 1667bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1668bbe38602SEugene Leviant StringRef Tok = next(); 1669b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1670b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1671b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1672b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1673b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1674b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1675b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1676b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1677b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1678b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1679b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1680b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1681b0f6c590SRui Ueyama .Default(-1); 1682bbe38602SEugene Leviant 1683b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1684b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1685b0f6c590SRui Ueyama return PT_NULL; 1686b0f6c590SRui Ueyama } 1687b0f6c590SRui Ueyama return Ret; 1688bbe38602SEugene Leviant } 1689bbe38602SEugene Leviant 169095769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 169120b6598cSGeorge Rimar // Identifiers start at 2 because 0 and 1 are reserved 169220b6598cSGeorge Rimar // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. 169320b6598cSGeorge Rimar size_t VersionId = Config->VersionDefinitions.size() + 2; 169420b6598cSGeorge Rimar Config->VersionDefinitions.push_back({VerStr, VersionId}); 169520b6598cSGeorge Rimar 169620b6598cSGeorge Rimar if (skip("global:") || peek() != "local:") 169720b6598cSGeorge Rimar readGlobal(VerStr); 169820b6598cSGeorge Rimar if (skip("local:")) 169920b6598cSGeorge Rimar readLocal(); 170020b6598cSGeorge Rimar expect("}"); 170120b6598cSGeorge Rimar 170220b6598cSGeorge Rimar // Each version may have a parent version. For example, "Ver2" defined as 170320b6598cSGeorge Rimar // "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This 170420b6598cSGeorge Rimar // version hierarchy is, probably against your instinct, purely for human; the 170520b6598cSGeorge Rimar // runtime doesn't care about them at all. In LLD, we simply skip the token. 170620b6598cSGeorge Rimar if (!VerStr.empty() && peek() != ";") 170720b6598cSGeorge Rimar next(); 170820b6598cSGeorge Rimar expect(";"); 170920b6598cSGeorge Rimar } 171020b6598cSGeorge Rimar 171120b6598cSGeorge Rimar void ScriptParser::readLocal() { 171220b6598cSGeorge Rimar Config->DefaultSymbolVersion = VER_NDX_LOCAL; 171320b6598cSGeorge Rimar expect("*"); 171420b6598cSGeorge Rimar expect(";"); 171520b6598cSGeorge Rimar } 171620b6598cSGeorge Rimar 171720b6598cSGeorge Rimar void ScriptParser::readExtern(std::vector<SymbolVersion> *Globals) { 1718cd574a5eSGeorge Rimar expect("\"C++\""); 171920b6598cSGeorge Rimar expect("{"); 172020b6598cSGeorge Rimar 172120b6598cSGeorge Rimar for (;;) { 172220b6598cSGeorge Rimar if (peek() == "}" || Error) 172320b6598cSGeorge Rimar break; 1724cd574a5eSGeorge Rimar bool HasWildcard = !peek().startswith("\"") && hasWildcard(peek()); 1725cd574a5eSGeorge Rimar Globals->push_back({unquote(next()), true, HasWildcard}); 172620b6598cSGeorge Rimar expect(";"); 172720b6598cSGeorge Rimar } 172820b6598cSGeorge Rimar 172920b6598cSGeorge Rimar expect("}"); 173020b6598cSGeorge Rimar expect(";"); 173120b6598cSGeorge Rimar } 173220b6598cSGeorge Rimar 173320b6598cSGeorge Rimar void ScriptParser::readGlobal(StringRef VerStr) { 173420b6598cSGeorge Rimar std::vector<SymbolVersion> *Globals; 173520b6598cSGeorge Rimar if (VerStr.empty()) 173620b6598cSGeorge Rimar Globals = &Config->VersionScriptGlobals; 173720b6598cSGeorge Rimar else 173820b6598cSGeorge Rimar Globals = &Config->VersionDefinitions.back().Globals; 173920b6598cSGeorge Rimar 174020b6598cSGeorge Rimar for (;;) { 174120b6598cSGeorge Rimar if (skip("extern")) 174220b6598cSGeorge Rimar readExtern(Globals); 174320b6598cSGeorge Rimar 174420b6598cSGeorge Rimar StringRef Cur = peek(); 174520b6598cSGeorge Rimar if (Cur == "}" || Cur == "local:" || Error) 174620b6598cSGeorge Rimar return; 174720b6598cSGeorge Rimar next(); 1748cd574a5eSGeorge Rimar Globals->push_back({unquote(Cur), false, hasWildcard(Cur)}); 174920b6598cSGeorge Rimar expect(";"); 175020b6598cSGeorge Rimar } 175120b6598cSGeorge Rimar } 175220b6598cSGeorge Rimar 175316b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 175416b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 175516b0cc9eSSimon Atanasyan return false; 175616b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 175716b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 175816b0cc9eSSimon Atanasyan return true; 175916b0cc9eSSimon Atanasyan return false; 176016b0cc9eSSimon Atanasyan } 176116b0cc9eSSimon Atanasyan 176207320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 176316b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 176420b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).readLinkerScript(); 176520b6598cSGeorge Rimar } 176620b6598cSGeorge Rimar 176720b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 176820b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), false).readVersionScript(); 1769f7c5fbb1SRui Ueyama } 17701ebc8ed7SRui Ueyama 177107320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 177207320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 177307320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 177407320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1775