1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===// 2f7c5fbb1SRui Ueyama // 3f7c5fbb1SRui Ueyama // The LLVM Linker 4f7c5fbb1SRui Ueyama // 5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source 6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details. 7f7c5fbb1SRui Ueyama // 8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 9f7c5fbb1SRui Ueyama // 10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script. 11f7c5fbb1SRui Ueyama // 12f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 13f7c5fbb1SRui Ueyama 14717677afSRui Ueyama #include "LinkerScript.h" 15f7c5fbb1SRui Ueyama #include "Config.h" 16f7c5fbb1SRui Ueyama #include "Driver.h" 171ebc8ed7SRui Ueyama #include "InputSection.h" 1855518e7dSRui Ueyama #include "Memory.h" 19652852c5SGeorge Rimar #include "OutputSections.h" 20e77b5bf6SAdhemerval Zanella #include "ScriptParser.h" 2193c9af42SRui Ueyama #include "Strings.h" 22f7c5fbb1SRui Ueyama #include "SymbolTable.h" 2355518e7dSRui Ueyama #include "Symbols.h" 24467c4d55SEugene Leviant #include "Target.h" 25bbe38602SEugene Leviant #include "Writer.h" 2622886a28SEugene Zelenko #include "llvm/ADT/STLExtras.h" 278c6a5aafSRui Ueyama #include "llvm/ADT/SmallString.h" 2822886a28SEugene Zelenko #include "llvm/ADT/StringRef.h" 29960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 3022886a28SEugene Zelenko #include "llvm/Support/Casting.h" 31652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 3222886a28SEugene Zelenko #include "llvm/Support/Endian.h" 3322886a28SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 34f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 3522886a28SEugene Zelenko #include "llvm/Support/MathExtras.h" 36f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 3722886a28SEugene Zelenko #include <algorithm> 3822886a28SEugene Zelenko #include <cassert> 3922886a28SEugene Zelenko #include <cstddef> 4022886a28SEugene Zelenko #include <cstdint> 4122886a28SEugene Zelenko #include <iterator> 4222886a28SEugene Zelenko #include <limits> 4322886a28SEugene Zelenko #include <memory> 4422886a28SEugene Zelenko #include <string> 4522886a28SEugene Zelenko #include <tuple> 4622886a28SEugene Zelenko #include <vector> 47f7c5fbb1SRui Ueyama 48f7c5fbb1SRui Ueyama using namespace llvm; 49652852c5SGeorge Rimar using namespace llvm::ELF; 501ebc8ed7SRui Ueyama using namespace llvm::object; 51e38cbab5SGeorge Rimar using namespace llvm::support::endian; 52f7c5fbb1SRui Ueyama using namespace lld; 53e0df00b9SRafael Espindola using namespace lld::elf; 54f7c5fbb1SRui Ueyama 55884e786dSGeorge Rimar LinkerScriptBase *elf::ScriptBase; 5607320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 57717677afSRui Ueyama 586c55f0e3SGeorge Rimar template <class ELFT> static void addRegular(SymbolAssignment *Cmd) { 593dabfc6bSRafael Espindola uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; 601bdaf3e3SRui Ueyama Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, Visibility, STT_NOTYPE, 61463984d4SGeorge Rimar 0, 0, STB_GLOBAL, nullptr, nullptr); 621602421cSRui Ueyama Cmd->Sym = Sym->body(); 6320d03194SEugene Leviant 6420d03194SEugene Leviant // If we have no SECTIONS then we don't have '.' and don't call 6520d03194SEugene Leviant // assignAddresses(). We calculate symbol value immediately in this case. 6620d03194SEugene Leviant if (!ScriptConfig->HasSections) 6720d03194SEugene Leviant cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0); 68ceabe80eSEugene Leviant } 69ceabe80eSEugene Leviant 700c70d3ccSRui Ueyama template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) { 71afaa9343SEugene Leviant // If we have SECTIONS block then output sections haven't been created yet. 72afaa9343SEugene Leviant const OutputSectionBase *Sec = 73afaa9343SEugene Leviant ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section(); 74e1937bb5SGeorge Rimar Symbol *Sym = Symtab<ELFT>::X->addSynthetic( 75afaa9343SEugene Leviant Cmd->Name, Sec, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT); 761602421cSRui Ueyama Cmd->Sym = Sym->body(); 77afaa9343SEugene Leviant 78afaa9343SEugene Leviant // If we already know section then we can calculate symbol value immediately. 79afaa9343SEugene Leviant if (Sec) 80afaa9343SEugene Leviant cast<DefinedSynthetic<ELFT>>(Cmd->Sym)->Value = 81afaa9343SEugene Leviant Cmd->Expression(0) - Sec->Addr; 82ceabe80eSEugene Leviant } 83ceabe80eSEugene Leviant 84db741e72SEugene Leviant template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) { 852f831dcaSRafael Espindola if (Cmd->Expression.IsAbsolute()) 86db741e72SEugene Leviant addRegular<ELFT>(Cmd); 87db741e72SEugene Leviant else 88db741e72SEugene Leviant addSynthetic<ELFT>(Cmd); 89db741e72SEugene Leviant } 901602421cSRui Ueyama // If a symbol was in PROVIDE(), we need to define it only when 911602421cSRui Ueyama // it is an undefined symbol. 921602421cSRui Ueyama template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) { 931602421cSRui Ueyama if (Cmd->Name == ".") 94ceabe80eSEugene Leviant return false; 951602421cSRui Ueyama if (!Cmd->Provide) 96ceabe80eSEugene Leviant return true; 971602421cSRui Ueyama SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 981602421cSRui Ueyama return B && B->isUndefined(); 99ceabe80eSEugene Leviant } 100ceabe80eSEugene Leviant 101076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 102076fe157SGeorge Rimar return C->Kind == AssignmentKind; 103076fe157SGeorge Rimar } 104076fe157SGeorge Rimar 105076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 106076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 107076fe157SGeorge Rimar } 108076fe157SGeorge Rimar 109eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 110eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 111eea3114fSGeorge Rimar } 112eea3114fSGeorge Rimar 113eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 114eefa758eSGeorge Rimar return C->Kind == AssertKind; 115eefa758eSGeorge Rimar } 116eefa758eSGeorge Rimar 117e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) { 118e38cbab5SGeorge Rimar return C->Kind == BytesDataKind; 119e38cbab5SGeorge Rimar } 120e38cbab5SGeorge Rimar 12122886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::LinkerScript() = default; 12222886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::~LinkerScript() = default; 123f34d0e08SRui Ueyama 124e0be2901SRui Ueyama template <class ELFT> static StringRef basename(InputSectionBase<ELFT> *S) { 125e0be2901SRui Ueyama if (S->getFile()) 126e0be2901SRui Ueyama return sys::path::filename(S->getFile()->getName()); 127e0be2901SRui Ueyama return ""; 128e0be2901SRui Ueyama } 129e0be2901SRui Ueyama 13007320e40SRui Ueyama template <class ELFT> 13107320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 132e0be2901SRui Ueyama for (InputSectionDescription *ID : Opt.KeptSections) 133e0be2901SRui Ueyama if (ID->FilePat.match(basename(S))) 134cf43f179SEugene Leviant for (SectionPattern &P : ID->SectionPatterns) 135f91282e1SRui Ueyama if (P.SectionPat.match(S->Name)) 136eea3114fSGeorge Rimar return true; 137eea3114fSGeorge Rimar return false; 138eea3114fSGeorge Rimar } 139eea3114fSGeorge Rimar 140575208caSGeorge Rimar static bool comparePriority(InputSectionData *A, InputSectionData *B) { 141575208caSGeorge Rimar return getPriority(A->Name) < getPriority(B->Name); 142575208caSGeorge Rimar } 143575208caSGeorge Rimar 144c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) { 145042a3f20SRafael Espindola return A->Name < B->Name; 1460702c4e8SGeorge Rimar } 147742c3836SRui Ueyama 148c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) { 149742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 150742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 151742c3836SRui Ueyama // This is compatible with GNU. 152742c3836SRui Ueyama return A->Alignment > B->Alignment; 153742c3836SRui Ueyama } 154742c3836SRui Ueyama 155c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)> 156be394db3SGeorge Rimar getComparator(SortSectionPolicy K) { 157be394db3SGeorge Rimar switch (K) { 158be394db3SGeorge Rimar case SortSectionPolicy::Alignment: 159c0028d3dSRafael Espindola return compareAlignment; 160be394db3SGeorge Rimar case SortSectionPolicy::Name: 161be394db3SGeorge Rimar return compareName; 162be394db3SGeorge Rimar case SortSectionPolicy::Priority: 163be394db3SGeorge Rimar return comparePriority; 164be394db3SGeorge Rimar default: 165be394db3SGeorge Rimar llvm_unreachable("unknown sort policy"); 166be394db3SGeorge Rimar } 167742c3836SRui Ueyama } 1680702c4e8SGeorge Rimar 16948c3f1ceSRui Ueyama template <class ELFT> 170e71a3f8aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 17106ae6836SGeorge Rimar ConstraintKind Kind) { 1728f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 1738f66df92SGeorge Rimar return true; 174e746e52cSRafael Espindola bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) { 175d3190795SRafael Espindola auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2); 1761854a8ebSRafael Espindola return Sec->Flags & SHF_WRITE; 17706ae6836SGeorge Rimar }); 178e746e52cSRafael Espindola return (IsRW && Kind == ConstraintKind::ReadWrite) || 179e746e52cSRafael Espindola (!IsRW && Kind == ConstraintKind::ReadOnly); 18006ae6836SGeorge Rimar } 18106ae6836SGeorge Rimar 18207171f21SGeorge Rimar static void sortSections(InputSectionData **Begin, InputSectionData **End, 183ee924709SRui Ueyama SortSectionPolicy K) { 184ee924709SRui Ueyama if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None) 18507171f21SGeorge Rimar std::stable_sort(Begin, End, getComparator(K)); 186ee924709SRui Ueyama } 187ee924709SRui Ueyama 188d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches. 189be94e1b6SRafael Espindola template <class ELFT> 190e71a3f8aSRafael Espindola void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) { 1914dc07becSRui Ueyama // Collects all sections that satisfy constraints of I 1924dc07becSRui Ueyama // and attach them to I. 1934dc07becSRui Ueyama for (SectionPattern &Pat : I->SectionPatterns) { 19407171f21SGeorge Rimar size_t SizeBefore = I->Sections.size(); 1958c6a5aafSRui Ueyama 1968c6a5aafSRui Ueyama for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) { 197f94efdddSRui Ueyama if (!S->Live || S->Assigned) 1988c6a5aafSRui Ueyama continue; 1998c6a5aafSRui Ueyama 200e0be2901SRui Ueyama StringRef Filename = basename(S); 201e0be2901SRui Ueyama if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename)) 202e0be2901SRui Ueyama continue; 203e0be2901SRui Ueyama if (!Pat.SectionPat.match(S->Name)) 204e0be2901SRui Ueyama continue; 205d3190795SRafael Espindola I->Sections.push_back(S); 206f94efdddSRui Ueyama S->Assigned = true; 207f94efdddSRui Ueyama } 208d3190795SRafael Espindola 209ee924709SRui Ueyama // Sort sections as instructed by SORT-family commands and --sort-section 210ee924709SRui Ueyama // option. Because SORT-family commands can be nested at most two depth 211ee924709SRui Ueyama // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command 212ee924709SRui Ueyama // line option is respected even if a SORT command is given, the exact 213ee924709SRui Ueyama // behavior we have here is a bit complicated. Here are the rules. 214ee924709SRui Ueyama // 215ee924709SRui Ueyama // 1. If two SORT commands are given, --sort-section is ignored. 216ee924709SRui Ueyama // 2. If one SORT command is given, and if it is not SORT_NONE, 217ee924709SRui Ueyama // --sort-section is handled as an inner SORT command. 218ee924709SRui Ueyama // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. 219ee924709SRui Ueyama // 4. If no SORT command is given, sort according to --sort-section. 22007171f21SGeorge Rimar InputSectionData **Begin = I->Sections.data() + SizeBefore; 22107171f21SGeorge Rimar InputSectionData **End = I->Sections.data() + I->Sections.size(); 22207171f21SGeorge Rimar if (Pat.SortOuter != SortSectionPolicy::None) { 22307171f21SGeorge Rimar if (Pat.SortInner == SortSectionPolicy::Default) 22407171f21SGeorge Rimar sortSections(Begin, End, Config->SortSection); 225ee924709SRui Ueyama else 22607171f21SGeorge Rimar sortSections(Begin, End, Pat.SortInner); 22707171f21SGeorge Rimar sortSections(Begin, End, Pat.SortOuter); 22807171f21SGeorge Rimar } 229ee924709SRui Ueyama } 230be94e1b6SRafael Espindola } 231be94e1b6SRafael Espindola 232be94e1b6SRafael Espindola template <class ELFT> 233be94e1b6SRafael Espindola void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) { 234be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : V) { 235be94e1b6SRafael Espindola S->Live = false; 236be94e1b6SRafael Espindola reportDiscarded(S); 237be94e1b6SRafael Espindola } 238be94e1b6SRafael Espindola } 239be94e1b6SRafael Espindola 24006ae6836SGeorge Rimar template <class ELFT> 2410b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 24206ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 2430b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 244e7f912cdSRui Ueyama 24506ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 2467c3ff2ebSRafael Espindola auto *Cmd = dyn_cast<InputSectionDescription>(Base.get()); 2477c3ff2ebSRafael Espindola if (!Cmd) 2480b9ce6a4SRui Ueyama continue; 249e71a3f8aSRafael Espindola computeInputSections(Cmd); 250d3190795SRafael Espindola for (InputSectionData *S : Cmd->Sections) 251d3190795SRafael Espindola Ret.push_back(static_cast<InputSectionBase<ELFT> *>(S)); 2520b9ce6a4SRui Ueyama } 253e71a3f8aSRafael Espindola 2540b9ce6a4SRui Ueyama return Ret; 2550b9ce6a4SRui Ueyama } 2560b9ce6a4SRui Ueyama 257e5d3ca50SPetr Hosek template <class ELFT> 25810897f18SRafael Espindola static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C, 25910897f18SRafael Espindola StringRef OutsecName) { 26010897f18SRafael Espindola // When using linker script the merge rules are different. 26110897f18SRafael Espindola // Unfortunately, linker scripts are name based. This means that expressions 26210897f18SRafael Espindola // like *(.foo*) can refer to multiple input sections that would normally be 26310897f18SRafael Espindola // placed in different output sections. We cannot put them in different 26410897f18SRafael Espindola // output sections or we would produce wrong results for 26510897f18SRafael Espindola // start = .; *(.foo.*) end = .; *(.bar) 26610897f18SRafael Espindola // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to 26710897f18SRafael Espindola // another. The problem is that there is no way to layout those output 26810897f18SRafael Espindola // sections such that the .foo sections are the only thing between the 26910897f18SRafael Espindola // start and end symbols. 27010897f18SRafael Espindola 27110897f18SRafael Espindola // An extra annoyance is that we cannot simply disable merging of the contents 27210897f18SRafael Espindola // of SHF_MERGE sections, but our implementation requires one output section 27310897f18SRafael Espindola // per "kind" (string or not, which size/aligment). 27410897f18SRafael Espindola // Fortunately, creating symbols in the middle of a merge section is not 27510897f18SRafael Espindola // supported by bfd or gold, so we can just create multiple section in that 27610897f18SRafael Espindola // case. 27710897f18SRafael Espindola typedef typename ELFT::uint uintX_t; 2781854a8ebSRafael Espindola uintX_t Flags = C->Flags & (SHF_MERGE | SHF_STRINGS); 27910897f18SRafael Espindola 28010897f18SRafael Espindola uintX_t Alignment = 0; 28110897f18SRafael Espindola if (isa<MergeInputSection<ELFT>>(C)) 2821854a8ebSRafael Espindola Alignment = std::max<uintX_t>(C->Alignment, C->Entsize); 28310897f18SRafael Espindola 28410897f18SRafael Espindola return SectionKey<ELFT::Is64Bits>{OutsecName, /*Type*/ 0, Flags, Alignment}; 28510897f18SRafael Espindola } 28610897f18SRafael Espindola 28710897f18SRafael Espindola template <class ELFT> 28820d03194SEugene Leviant void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory, 28920d03194SEugene Leviant InputSectionBase<ELFT> *Sec, 29020d03194SEugene Leviant StringRef Name) { 291e08e78dfSRafael Espindola OutputSectionBase *OutSec; 29228c1597aSRafael Espindola bool IsNew; 29310897f18SRafael Espindola std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec); 29428c1597aSRafael Espindola if (IsNew) 29528c1597aSRafael Espindola OutputSections->push_back(OutSec); 29620d03194SEugene Leviant OutSec->addSection(Sec); 29720d03194SEugene Leviant } 29820d03194SEugene Leviant 29920d03194SEugene Leviant template <class ELFT> 30020d03194SEugene Leviant void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { 3017c3ff2ebSRafael Espindola for (unsigned I = 0; I < Opt.Commands.size(); ++I) { 3027c3ff2ebSRafael Espindola auto Iter = Opt.Commands.begin() + I; 3037c3ff2ebSRafael Espindola const std::unique_ptr<BaseCommand> &Base1 = *Iter; 3040b1b695aSRui Ueyama 3050b1b695aSRui Ueyama // Handle symbol assignments outside of any output section. 3062ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 3072ab5f73dSRui Ueyama if (shouldDefine<ELFT>(Cmd)) 308b0de56b5SRafael Espindola addSymbol<ELFT>(Cmd); 3092ab5f73dSRui Ueyama continue; 3102ab5f73dSRui Ueyama } 3110b1b695aSRui Ueyama 31220d03194SEugene Leviant if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) { 31320d03194SEugene Leviant // If we don't have SECTIONS then output sections have already been 314194470cdSGeorge Rimar // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses 31520d03194SEugene Leviant // will not be called, so ASSERT should be evaluated now. 31620d03194SEugene Leviant if (!Opt.HasSections) 31720d03194SEugene Leviant Cmd->Expression(0); 31820d03194SEugene Leviant continue; 31920d03194SEugene Leviant } 3202ab5f73dSRui Ueyama 321ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 3227bd37870SRafael Espindola std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 3237bd37870SRafael Espindola 3240b1b695aSRui Ueyama // The output section name `/DISCARD/' is special. 3250b1b695aSRui Ueyama // Any input section assigned to it is discarded. 32648c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 3277bd37870SRafael Espindola discard(V); 32848c3f1ceSRui Ueyama continue; 32948c3f1ceSRui Ueyama } 3300b9ce6a4SRui Ueyama 3310b1b695aSRui Ueyama // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive 3320b1b695aSRui Ueyama // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input 3330b1b695aSRui Ueyama // sections satisfy a given constraint. If not, a directive is handled 3340b1b695aSRui Ueyama // as if it wasn't present from the beginning. 3350b1b695aSRui Ueyama // 3360b1b695aSRui Ueyama // Because we'll iterate over Commands many more times, the easiest 3370b1b695aSRui Ueyama // way to "make it as if it wasn't present" is to just remove it. 3387c3ff2ebSRafael Espindola if (!matchConstraints<ELFT>(V, Cmd->Constraint)) { 3397c3ff2ebSRafael Espindola for (InputSectionBase<ELFT> *S : V) 340f94efdddSRui Ueyama S->Assigned = false; 3417c3ff2ebSRafael Espindola Opt.Commands.erase(Iter); 342dfbbbc86SGeorge Rimar --I; 3437c3ff2ebSRafael Espindola continue; 3447c3ff2ebSRafael Espindola } 3457c3ff2ebSRafael Espindola 3460b1b695aSRui Ueyama // A directive may contain symbol definitions like this: 3470b1b695aSRui Ueyama // ".foo : { ...; bar = .; }". Handle them. 3487c3ff2ebSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 3497c3ff2ebSRafael Espindola if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) 3507c3ff2ebSRafael Espindola if (shouldDefine<ELFT>(OutCmd)) 3517c3ff2ebSRafael Espindola addSymbol<ELFT>(OutCmd); 3527c3ff2ebSRafael Espindola 3530b1b695aSRui Ueyama // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign 3540b1b695aSRui Ueyama // is given, input sections are aligned to that value, whether the 3550b1b695aSRui Ueyama // given value is larger or smaller than the original section alignment. 3560b1b695aSRui Ueyama if (Cmd->SubalignExpr) { 3570b1b695aSRui Ueyama uint32_t Subalign = Cmd->SubalignExpr(0); 3580b1b695aSRui Ueyama for (InputSectionBase<ELFT> *S : V) 3590b1b695aSRui Ueyama S->Alignment = Subalign; 36020d03194SEugene Leviant } 3610b1b695aSRui Ueyama 3620b1b695aSRui Ueyama // Add input sections to an output section. 3630b1b695aSRui Ueyama for (InputSectionBase<ELFT> *S : V) 3640b1b695aSRui Ueyama addSection(Factory, S, Cmd->Name); 365eea3114fSGeorge Rimar } 36648c3f1ceSRui Ueyama } 367db24d9c3SGeorge Rimar } 368e63d81bdSEugene Leviant 3690b1b695aSRui Ueyama // Add sections that didn't match any sections command. 37020d03194SEugene Leviant template <class ELFT> 3710b1b695aSRui Ueyama void LinkerScript<ELFT>::addOrphanSections(OutputSectionFactory<ELFT> &Factory) { 3728c6a5aafSRui Ueyama for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) 3738f9026baSRafael Espindola if (S->Live && !S->OutSec) 37455518e7dSRui Ueyama addSection(Factory, S, getOutputSectionName(S->Name)); 375e63d81bdSEugene Leviant } 376e63d81bdSEugene Leviant 377db741e72SEugene Leviant // Sets value of a section-defined symbol. Two kinds of 378db741e72SEugene Leviant // symbols are processed: synthetic symbols, whose value 379db741e72SEugene Leviant // is an offset from beginning of section and regular 380db741e72SEugene Leviant // symbols whose value is absolute. 381db741e72SEugene Leviant template <class ELFT> 382afaa9343SEugene Leviant static void assignSectionSymbol(SymbolAssignment *Cmd, 383498ed714SRafael Espindola typename ELFT::uint Value) { 384db741e72SEugene Leviant if (!Cmd->Sym) 385db741e72SEugene Leviant return; 386db741e72SEugene Leviant 387db741e72SEugene Leviant if (auto *Body = dyn_cast<DefinedSynthetic<ELFT>>(Cmd->Sym)) { 388afaa9343SEugene Leviant Body->Section = Cmd->Expression.Section(); 389afaa9343SEugene Leviant Body->Value = Cmd->Expression(Value) - Body->Section->Addr; 390db741e72SEugene Leviant return; 391db741e72SEugene Leviant } 392db741e72SEugene Leviant auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym); 393498ed714SRafael Espindola Body->Value = Cmd->Expression(Value); 394db741e72SEugene Leviant } 395db741e72SEugene Leviant 396e08e78dfSRafael Espindola template <class ELFT> static bool isTbss(OutputSectionBase *Sec) { 39704a2e348SRafael Espindola return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS; 398a940e539SRafael Espindola } 399a940e539SRafael Espindola 400d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) { 401d3190795SRafael Espindola if (!AlreadyOutputIS.insert(S).second) 402ceabe80eSEugene Leviant return; 403e08e78dfSRafael Espindola bool IsTbss = isTbss<ELFT>(CurOutSec); 404d3190795SRafael Espindola 405d3190795SRafael Espindola uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; 406d3190795SRafael Espindola Pos = alignTo(Pos, S->Alignment); 40704a2e348SRafael Espindola S->OutSecOff = Pos - CurOutSec->Addr; 408d3190795SRafael Espindola Pos += S->getSize(); 409d3190795SRafael Espindola 410d3190795SRafael Espindola // Update output section size after adding each section. This is so that 411d3190795SRafael Espindola // SIZEOF works correctly in the case below: 412d3190795SRafael Espindola // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 41304a2e348SRafael Espindola CurOutSec->Size = Pos - CurOutSec->Addr; 414d3190795SRafael Espindola 4157252ae52SRafael Espindola if (IsTbss) 4167252ae52SRafael Espindola ThreadBssOffset = Pos - Dot; 4177252ae52SRafael Espindola else 418d3190795SRafael Espindola Dot = Pos; 4192de509c3SRui Ueyama } 420ceabe80eSEugene Leviant 421d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::flush() { 42265499b90SRafael Espindola if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second) 42365499b90SRafael Espindola return; 42465499b90SRafael Espindola if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) { 425d3190795SRafael Espindola for (InputSection<ELFT> *I : OutSec->Sections) 426d3190795SRafael Espindola output(I); 42765499b90SRafael Espindola } else { 42804a2e348SRafael Espindola Dot += CurOutSec->Size; 429d3190795SRafael Espindola } 430d3190795SRafael Espindola } 43197403d15SEugene Leviant 432d3190795SRafael Espindola template <class ELFT> 433e08e78dfSRafael Espindola void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) { 434d3190795SRafael Espindola if (CurOutSec == Sec) 435d3190795SRafael Espindola return; 436d3190795SRafael Espindola if (AlreadyOutputOS.count(Sec)) 437d3190795SRafael Espindola return; 438d3190795SRafael Espindola 439d3190795SRafael Espindola flush(); 440d3190795SRafael Espindola CurOutSec = Sec; 441d3190795SRafael Espindola 44204a2e348SRafael Espindola Dot = alignTo(Dot, CurOutSec->Addralign); 443e08e78dfSRafael Espindola CurOutSec->Addr = isTbss<ELFT>(CurOutSec) ? Dot + ThreadBssOffset : Dot; 444b71d6f7aSEugene Leviant 445b71d6f7aSEugene Leviant // If neither AT nor AT> is specified for an allocatable section, the linker 446b71d6f7aSEugene Leviant // will set the LMA such that the difference between VMA and LMA for the 447b71d6f7aSEugene Leviant // section is the same as the preceding output section in the same region 448b71d6f7aSEugene Leviant // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html 449b71d6f7aSEugene Leviant CurOutSec->setLMAOffset(LMAOffset); 450d3190795SRafael Espindola } 451d3190795SRafael Espindola 452d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) { 453e38cbab5SGeorge Rimar // This handles the assignments to symbol or to a location counter (.) 454d3190795SRafael Espindola if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) { 45597403d15SEugene Leviant if (AssignCmd->Name == ".") { 45697403d15SEugene Leviant // Update to location counter means update to section size. 457d3190795SRafael Espindola Dot = AssignCmd->Expression(Dot); 45804a2e348SRafael Espindola CurOutSec->Size = Dot - CurOutSec->Addr; 459d3190795SRafael Espindola return; 46097403d15SEugene Leviant } 461afaa9343SEugene Leviant assignSectionSymbol<ELFT>(AssignCmd, Dot); 462d3190795SRafael Espindola return; 46397403d15SEugene Leviant } 464e38cbab5SGeorge Rimar 465e38cbab5SGeorge Rimar // Handle BYTE(), SHORT(), LONG(), or QUAD(). 466e38cbab5SGeorge Rimar if (auto *DataCmd = dyn_cast<BytesDataCommand>(&Base)) { 46704a2e348SRafael Espindola DataCmd->Offset = Dot - CurOutSec->Addr; 468e38cbab5SGeorge Rimar Dot += DataCmd->Size; 46904a2e348SRafael Espindola CurOutSec->Size = Dot - CurOutSec->Addr; 470e38cbab5SGeorge Rimar return; 471e38cbab5SGeorge Rimar } 472e38cbab5SGeorge Rimar 473e38cbab5SGeorge Rimar // It handles single input section description command, 474e38cbab5SGeorge Rimar // calculates and assigns the offsets for each section and also 475e38cbab5SGeorge Rimar // updates the output section size. 476d3190795SRafael Espindola auto &ICmd = cast<InputSectionDescription>(Base); 477d3190795SRafael Espindola for (InputSectionData *ID : ICmd.Sections) { 478d3190795SRafael Espindola auto *IB = static_cast<InputSectionBase<ELFT> *>(ID); 479d3190795SRafael Espindola switchTo(IB->OutSec); 480d3190795SRafael Espindola if (auto *I = dyn_cast<InputSection<ELFT>>(IB)) 481d3190795SRafael Espindola output(I); 48265499b90SRafael Espindola else 48365499b90SRafael Espindola flush(); 484ceabe80eSEugene Leviant } 485ceabe80eSEugene Leviant } 486ceabe80eSEugene Leviant 4878f66df92SGeorge Rimar template <class ELFT> 488e08e78dfSRafael Espindola static std::vector<OutputSectionBase *> 489e08e78dfSRafael Espindola findSections(StringRef Name, const std::vector<OutputSectionBase *> &Sections) { 490e08e78dfSRafael Espindola std::vector<OutputSectionBase *> Ret; 491e08e78dfSRafael Espindola for (OutputSectionBase *Sec : Sections) 4929257764dSEugene Leviant if (Sec->getName() == Name) 493a14b13d8SGeorge Rimar Ret.push_back(Sec); 494a14b13d8SGeorge Rimar return Ret; 4958f66df92SGeorge Rimar } 4968f66df92SGeorge Rimar 4970b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section 4980b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }"). 499d3190795SRafael Espindola template <class ELFT> 500d3190795SRafael Espindola void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) { 501b71d6f7aSEugene Leviant if (Cmd->LMAExpr) 502b71d6f7aSEugene Leviant LMAOffset = Cmd->LMAExpr(Dot) - Dot; 503e08e78dfSRafael Espindola std::vector<OutputSectionBase *> Sections = 504e08e78dfSRafael Espindola findSections<ELFT>(Cmd->Name, *OutputSections); 505d3190795SRafael Espindola if (Sections.empty()) 506d3190795SRafael Espindola return; 507d3190795SRafael Espindola switchTo(Sections[0]); 5080b1b695aSRui Ueyama 509d3190795SRafael Espindola // Find the last section output location. We will output orphan sections 510d3190795SRafael Espindola // there so that end symbols point to the correct location. 511d3190795SRafael Espindola auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(), 512d3190795SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 513d3190795SRafael Espindola return !isa<SymbolAssignment>(*Cmd); 514d3190795SRafael Espindola }) 515d3190795SRafael Espindola .base(); 516d3190795SRafael Espindola for (auto I = Cmd->Commands.begin(); I != E; ++I) 517d3190795SRafael Espindola process(**I); 518e08e78dfSRafael Espindola for (OutputSectionBase *Base : Sections) 519d3190795SRafael Espindola switchTo(Base); 5202506cb4dSEugene Leviant flush(); 521b31dd370SGeorge Rimar std::for_each(E, Cmd->Commands.end(), 522b31dd370SGeorge Rimar [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); }); 523d3190795SRafael Espindola } 524d3190795SRafael Espindola 52507fe6129SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::removeEmptyCommands() { 5266d38e4dbSRafael Espindola // It is common practice to use very generic linker scripts. So for any 5276d38e4dbSRafael Espindola // given run some of the output sections in the script will be empty. 5286d38e4dbSRafael Espindola // We could create corresponding empty output sections, but that would 5296d38e4dbSRafael Espindola // clutter the output. 5306d38e4dbSRafael Espindola // We instead remove trivially empty sections. The bfd linker seems even 5316d38e4dbSRafael Espindola // more aggressive at removing them. 5326d38e4dbSRafael Espindola auto Pos = std::remove_if( 5336d38e4dbSRafael Espindola Opt.Commands.begin(), Opt.Commands.end(), 5346d38e4dbSRafael Espindola [&](const std::unique_ptr<BaseCommand> &Base) { 5350b1b695aSRui Ueyama if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 5366a53737cSRafael Espindola return findSections<ELFT>(Cmd->Name, *OutputSections).empty(); 5370b1b695aSRui Ueyama return false; 5386d38e4dbSRafael Espindola }); 5396d38e4dbSRafael Espindola Opt.Commands.erase(Pos, Opt.Commands.end()); 54007fe6129SRafael Espindola } 54107fe6129SRafael Espindola 5426a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) { 5436a53737cSRafael Espindola for (const std::unique_ptr<BaseCommand> &I : Cmd.Commands) 5446a53737cSRafael Espindola if (!isa<InputSectionDescription>(*I)) 5456a53737cSRafael Espindola return false; 5466a53737cSRafael Espindola return true; 5476a53737cSRafael Espindola } 5486d38e4dbSRafael Espindola 5496a53737cSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() { 5509546fffbSRafael Espindola // If the output section contains only symbol assignments, create a 5519546fffbSRafael Espindola // corresponding output section. The bfd linker seems to only create them if 5529546fffbSRafael Espindola // '.' is assigned to, but creating these section should not have any bad 5539546fffbSRafael Espindola // consequeces and gives us a section to put the symbol in. 5549546fffbSRafael Espindola uintX_t Flags = SHF_ALLOC; 5559546fffbSRafael Espindola uint32_t Type = 0; 5569546fffbSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 5579546fffbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 5589546fffbSRafael Espindola if (!Cmd) 5599546fffbSRafael Espindola continue; 560e08e78dfSRafael Espindola std::vector<OutputSectionBase *> Secs = 561e08e78dfSRafael Espindola findSections<ELFT>(Cmd->Name, *OutputSections); 5629546fffbSRafael Espindola if (!Secs.empty()) { 56304a2e348SRafael Espindola Flags = Secs[0]->Flags; 56404a2e348SRafael Espindola Type = Secs[0]->Type; 5659546fffbSRafael Espindola continue; 5669546fffbSRafael Espindola } 5679546fffbSRafael Espindola 5686a53737cSRafael Espindola if (isAllSectionDescription(*Cmd)) 5696a53737cSRafael Espindola continue; 5706a53737cSRafael Espindola 57195642b95SRui Ueyama auto *OutSec = make<OutputSection<ELFT>>(Cmd->Name, Type, Flags); 5729546fffbSRafael Espindola OutputSections->push_back(OutSec); 5739546fffbSRafael Espindola } 574f7a17448SRafael Espindola } 575f7a17448SRafael Espindola 576f7a17448SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsAfterSorting() { 577f7a17448SRafael Espindola placeOrphanSections(); 578f7a17448SRafael Espindola 579f7a17448SRafael Espindola // If output section command doesn't specify any segments, 580f7a17448SRafael Espindola // and we haven't previously assigned any section to segment, 581f7a17448SRafael Espindola // then we simply assign section to the very first load segment. 582f7a17448SRafael Espindola // Below is an example of such linker script: 583f7a17448SRafael Espindola // PHDRS { seg PT_LOAD; } 584f7a17448SRafael Espindola // SECTIONS { .aaa : { *(.aaa) } } 585f7a17448SRafael Espindola std::vector<StringRef> DefPhdrs; 586f7a17448SRafael Espindola auto FirstPtLoad = 587f7a17448SRafael Espindola std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(), 588f7a17448SRafael Espindola [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; }); 589f7a17448SRafael Espindola if (FirstPtLoad != Opt.PhdrsCommands.end()) 590f7a17448SRafael Espindola DefPhdrs.push_back(FirstPtLoad->Name); 591f7a17448SRafael Espindola 592f7a17448SRafael Espindola // Walk the commands and propagate the program headers to commands that don't 593f7a17448SRafael Espindola // explicitly specify them. 594f7a17448SRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 595f7a17448SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 596f7a17448SRafael Espindola if (!Cmd) 597f7a17448SRafael Espindola continue; 598f7a17448SRafael Espindola if (Cmd->Phdrs.empty()) 599f7a17448SRafael Espindola Cmd->Phdrs = DefPhdrs; 600f7a17448SRafael Espindola else 601f7a17448SRafael Espindola DefPhdrs = Cmd->Phdrs; 602f7a17448SRafael Espindola } 6036a53737cSRafael Espindola 6046a53737cSRafael Espindola removeEmptyCommands(); 6059546fffbSRafael Espindola } 6069546fffbSRafael Espindola 60715c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments 60815c57951SRafael Espindola // so that an orphan after 60915c57951SRafael Espindola // begin_foo = .; 61015c57951SRafael Espindola // foo : { *(foo) } 61115c57951SRafael Espindola // end_foo = .; 61215c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols. 61315c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the 61415c57951SRafael Espindola // one in charge of deciding the order of the sections. 61515c57951SRafael Espindola // We don't want to go over alignments, since doing so in 61615c57951SRafael Espindola // rx_sec : { *(rx_sec) } 61715c57951SRafael Espindola // . = ALIGN(0x1000); 61815c57951SRafael Espindola // /* The RW PT_LOAD starts here*/ 61915c57951SRafael Espindola // rw_sec : { *(rw_sec) } 62015c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned. 62115c57951SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) { 62215c57951SRafael Espindola if (isa<OutputSectionCommand>(Cmd)) 62315c57951SRafael Espindola return false; 62415c57951SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd); 62515c57951SRafael Espindola if (!Assign) 62615c57951SRafael Espindola return true; 62715c57951SRafael Espindola return Assign->Name != "."; 62815c57951SRafael Espindola } 62915c57951SRafael Espindola 630337f903cSRafael Espindola // Orphan sections are sections present in the input files which are not 631337f903cSRafael Espindola // explicitly placed into the output file by the linker script. This just 632337f903cSRafael Espindola // places them in the order already decided in OutputSections. 6336d91fce5SRafael Espindola template <class ELFT> 634337f903cSRafael Espindola void LinkerScript<ELFT>::placeOrphanSections() { 635aab6d5c5SRafael Espindola // The OutputSections are already in the correct order. 636aab6d5c5SRafael Espindola // This loops creates or moves commands as needed so that they are in the 637aab6d5c5SRafael Espindola // correct order. 638aab6d5c5SRafael Espindola int CmdIndex = 0; 639e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) { 640652852c5SGeorge Rimar StringRef Name = Sec->getName(); 641aab6d5c5SRafael Espindola 642aab6d5c5SRafael Espindola // Find the last spot where we can insert a command and still get the 64315c57951SRafael Espindola // correct result. 644aab6d5c5SRafael Espindola auto CmdIter = Opt.Commands.begin() + CmdIndex; 645aab6d5c5SRafael Espindola auto E = Opt.Commands.end(); 64615c57951SRafael Espindola while (CmdIter != E && shouldSkip(**CmdIter)) { 647aab6d5c5SRafael Espindola ++CmdIter; 648aab6d5c5SRafael Espindola ++CmdIndex; 649aab6d5c5SRafael Espindola } 650aab6d5c5SRafael Espindola 651aab6d5c5SRafael Espindola auto Pos = 652aab6d5c5SRafael Espindola std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) { 653aab6d5c5SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 654aab6d5c5SRafael Espindola return Cmd && Cmd->Name == Name; 655aab6d5c5SRafael Espindola }); 656aab6d5c5SRafael Espindola if (Pos == E) { 657aab6d5c5SRafael Espindola Opt.Commands.insert(CmdIter, 658aab6d5c5SRafael Espindola llvm::make_unique<OutputSectionCommand>(Name)); 659aab6d5c5SRafael Espindola ++CmdIndex; 66015c57951SRafael Espindola continue; 66115c57951SRafael Espindola } 66215c57951SRafael Espindola 66315c57951SRafael Espindola // Continue from where we found it. 66415c57951SRafael Espindola CmdIndex = (Pos - Opt.Commands.begin()) + 1; 665652852c5SGeorge Rimar } 666337f903cSRafael Espindola } 667337f903cSRafael Espindola 668337f903cSRafael Espindola template <class ELFT> 669337f903cSRafael Espindola void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs) { 6707c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 671be607334SRafael Espindola Dot = 0; 672652852c5SGeorge Rimar 673076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 674076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 6758d083e6aSRui Ueyama if (Cmd->Name == ".") { 6768d083e6aSRui Ueyama Dot = Cmd->Expression(Dot); 6778d083e6aSRui Ueyama } else if (Cmd->Sym) { 678afaa9343SEugene Leviant assignSectionSymbol<ELFT>(Cmd, Dot); 6798d083e6aSRui Ueyama } 68005ef4cffSRui Ueyama continue; 681652852c5SGeorge Rimar } 682652852c5SGeorge Rimar 683eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 684eefa758eSGeorge Rimar Cmd->Expression(Dot); 685eefa758eSGeorge Rimar continue; 686eefa758eSGeorge Rimar } 687eefa758eSGeorge Rimar 688076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 68958e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 69058e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 691d3190795SRafael Espindola assignOffsets(Cmd); 692a14b13d8SGeorge Rimar } 693467c4d55SEugene Leviant 694aab6d5c5SRafael Espindola uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 695e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) { 69604a2e348SRafael Espindola if (Sec->Flags & SHF_ALLOC) 697e08e78dfSRafael Espindola MinVA = std::min<uint64_t>(MinVA, Sec->Addr); 698aab6d5c5SRafael Espindola else 69904a2e348SRafael Espindola Sec->Addr = 0; 700aab6d5c5SRafael Espindola } 701aab6d5c5SRafael Espindola 7020d4b6d5cSRafael Espindola uintX_t HeaderSize = getHeaderSize(); 7036d91fce5SRafael Espindola auto FirstPTLoad = 7046d91fce5SRafael Espindola std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry<ELFT> &E) { 7056d91fce5SRafael Espindola return E.H.p_type == PT_LOAD; 7066d91fce5SRafael Espindola }); 707d8b81d66SRafael Espindola if (FirstPTLoad == Phdrs.end()) 708d8b81d66SRafael Espindola return; 709db35fdf7SEugene Leviant 7101c57007eSRafael Espindola // If the linker script doesn't have PHDRS, add ElfHeader and ProgramHeaders 7111c57007eSRafael Espindola // now that we know we have space. 7121c57007eSRafael Espindola if (HeaderSize <= MinVA && !hasPhdrsCommands()) { 7131c57007eSRafael Espindola FirstPTLoad->First = Out<ELFT>::ElfHeader; 7141c57007eSRafael Espindola if (!FirstPTLoad->Last) 7151c57007eSRafael Espindola FirstPTLoad->Last = Out<ELFT>::ProgramHeaders; 716db35fdf7SEugene Leviant } 7171c57007eSRafael Espindola 71864c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 719b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 720*28d5f059SRafael Espindola MinVA = alignDown(MinVA - HeaderSize, Config->MaxPageSize); 72104a2e348SRafael Espindola Out<ELFT>::ElfHeader->Addr = MinVA; 72204a2e348SRafael Espindola Out<ELFT>::ProgramHeaders->Addr = Out<ELFT>::ElfHeader->Size + MinVA; 7231c57007eSRafael Espindola 7241c57007eSRafael Espindola if (!FirstPTLoad->First) { 725cd8eaf89SEugene Leviant // Sometimes the very first PT_LOAD segment can be empty. 726cd8eaf89SEugene Leviant // This happens if (all conditions met): 727cd8eaf89SEugene Leviant // - Linker script is used 728cd8eaf89SEugene Leviant // - First section in ELF image is not RO 729cd8eaf89SEugene Leviant // - Not enough space for program headers. 730cd8eaf89SEugene Leviant // The code below removes empty PT_LOAD segment and updates 731cd8eaf89SEugene Leviant // program headers size. 732cd8eaf89SEugene Leviant Phdrs.erase(FirstPTLoad); 73304a2e348SRafael Espindola Out<ELFT>::ProgramHeaders->Size = 73404a2e348SRafael Espindola sizeof(typename ELFT::Phdr) * Phdrs.size(); 7356d91fce5SRafael Espindola } 736fb8978fcSDima Stepanov } 737652852c5SGeorge Rimar 738464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 73907320e40SRui Ueyama template <class ELFT> 740a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { 741edebbdf1SRui Ueyama std::vector<PhdrEntry<ELFT>> Ret; 742bbe38602SEugene Leviant 743464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 744464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 745bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 746edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 747edebbdf1SRui Ueyama PhdrEntry<ELFT> &Phdr = Ret.back(); 748bbe38602SEugene Leviant 749bbe38602SEugene Leviant if (Cmd.HasFilehdr) 750adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 751bbe38602SEugene Leviant if (Cmd.HasPhdrs) 752adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 75356b21c86SEugene Leviant 75456b21c86SEugene Leviant if (Cmd.LMAExpr) { 75556b21c86SEugene Leviant Phdr.H.p_paddr = Cmd.LMAExpr(0); 75656b21c86SEugene Leviant Phdr.HasLMA = true; 75756b21c86SEugene Leviant } 758bbe38602SEugene Leviant } 759bbe38602SEugene Leviant 760464daadcSRui Ueyama // Add output sections to program headers. 761e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) { 76204a2e348SRafael Espindola if (!(Sec->Flags & SHF_ALLOC)) 763bbe38602SEugene Leviant break; 764bbe38602SEugene Leviant 765bbe38602SEugene Leviant // Assign headers specified by linker script 766f7a17448SRafael Espindola for (size_t Id : getPhdrIndices(Sec->getName())) { 767edebbdf1SRui Ueyama Ret[Id].add(Sec); 768865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 7690b113671SRafael Espindola Ret[Id].H.p_flags |= Sec->getPhdrFlags(); 770bbe38602SEugene Leviant } 771bbe38602SEugene Leviant } 772edebbdf1SRui Ueyama return Ret; 773bbe38602SEugene Leviant } 774bbe38602SEugene Leviant 775f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 776f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 777f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 778f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 779f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 780f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 781f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 782f9bc3bd2SEugene Leviant } 783f9bc3bd2SEugene Leviant 784bbe38602SEugene Leviant template <class ELFT> 78516068aebSRui Ueyama uint32_t LinkerScript<ELFT>::getFiller(StringRef Name) { 786f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 787f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 788f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 789f6c3ccefSGeorge Rimar return Cmd->Filler; 79016068aebSRui Ueyama return 0; 791e2ee72b5SGeorge Rimar } 792e2ee72b5SGeorge Rimar 793e38cbab5SGeorge Rimar template <class ELFT> 794e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { 795e38cbab5SGeorge Rimar const endianness E = ELFT::TargetEndianness; 796e38cbab5SGeorge Rimar 797e38cbab5SGeorge Rimar switch (Size) { 798e38cbab5SGeorge Rimar case 1: 799e38cbab5SGeorge Rimar *Buf = (uint8_t)Data; 800e38cbab5SGeorge Rimar break; 801e38cbab5SGeorge Rimar case 2: 802e38cbab5SGeorge Rimar write16<E>(Buf, Data); 803e38cbab5SGeorge Rimar break; 804e38cbab5SGeorge Rimar case 4: 805e38cbab5SGeorge Rimar write32<E>(Buf, Data); 806e38cbab5SGeorge Rimar break; 807e38cbab5SGeorge Rimar case 8: 808e38cbab5SGeorge Rimar write64<E>(Buf, Data); 809e38cbab5SGeorge Rimar break; 810e38cbab5SGeorge Rimar default: 811e38cbab5SGeorge Rimar llvm_unreachable("unsupported Size argument"); 812e38cbab5SGeorge Rimar } 813e38cbab5SGeorge Rimar } 814e38cbab5SGeorge Rimar 815e38cbab5SGeorge Rimar template <class ELFT> 816e38cbab5SGeorge Rimar void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) { 817e38cbab5SGeorge Rimar int I = getSectionIndex(Name); 818e38cbab5SGeorge Rimar if (I == INT_MAX) 819e38cbab5SGeorge Rimar return; 820e38cbab5SGeorge Rimar 8216e68c5e5SRui Ueyama auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()); 8226e68c5e5SRui Ueyama for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 8236e68c5e5SRui Ueyama if (auto *Data = dyn_cast<BytesDataCommand>(Base.get())) 8246e68c5e5SRui Ueyama writeInt<ELFT>(Buf + Data->Offset, Data->Data, Data->Size); 825e38cbab5SGeorge Rimar } 826e38cbab5SGeorge Rimar 827b71d6f7aSEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasLMA(StringRef Name) { 8288ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 8298ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 830b71d6f7aSEugene Leviant if (Cmd->LMAExpr && Cmd->Name == Name) 831b71d6f7aSEugene Leviant return true; 832b71d6f7aSEugene Leviant return false; 8338ceadb38SGeorge Rimar } 8348ceadb38SGeorge Rimar 835c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 836c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 837c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 838c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 839076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 8406e68c5e5SRui Ueyama for (int I = 0, E = Opt.Commands.size(); I != E; ++I) 8416e68c5e5SRui Ueyama if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get())) 842076fe157SGeorge Rimar if (Cmd->Name == Name) 843f510fa6bSRui Ueyama return I; 844f510fa6bSRui Ueyama return INT_MAX; 84571b26e94SGeorge Rimar } 84671b26e94SGeorge Rimar 847bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 848bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 849bbe38602SEugene Leviant } 850bbe38602SEugene Leviant 8519e69450eSGeorge Rimar template <class ELFT> 852afaa9343SEugene Leviant const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(StringRef Name) { 853afaa9343SEugene Leviant static OutputSectionBase FakeSec("", 0, 0); 85496659df0SGeorge Rimar 855e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) 856b71d6f7aSEugene Leviant if (Sec->getName() == Name) 857afaa9343SEugene Leviant return Sec; 858b71d6f7aSEugene Leviant error("undefined section " + Name); 859afaa9343SEugene Leviant return &FakeSec; 86036fac7f0SEugene Leviant } 86136fac7f0SEugene Leviant 862edf75e79SRui Ueyama // This function is essentially the same as getOutputSection(Name)->Size, 863edf75e79SRui Ueyama // but it won't print out an error message if a given section is not found. 864edf75e79SRui Ueyama // 865edf75e79SRui Ueyama // Linker script does not create an output section if its content is empty. 866edf75e79SRui Ueyama // We want to allow SIZEOF(.foo) where .foo is a section which happened to 867edf75e79SRui Ueyama // be empty. That is why this function is different from getOutputSection(). 868edf75e79SRui Ueyama template <class ELFT> 869edf75e79SRui Ueyama uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 870edf75e79SRui Ueyama for (OutputSectionBase *Sec : *OutputSections) 871edf75e79SRui Ueyama if (Sec->getName() == Name) 872edf75e79SRui Ueyama return Sec->Size; 873edf75e79SRui Ueyama return 0; 874edf75e79SRui Ueyama } 875edf75e79SRui Ueyama 876884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() { 8770d4b6d5cSRafael Espindola return elf::getHeaderSize<ELFT>(); 878e32a3598SGeorge Rimar } 879e32a3598SGeorge Rimar 880884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) { 881884e786dSGeorge Rimar if (SymbolBody *B = Symtab<ELFT>::X->find(S)) 882884e786dSGeorge Rimar return B->getVA<ELFT>(); 883884e786dSGeorge Rimar error("symbol not found: " + S); 884884e786dSGeorge Rimar return 0; 885884e786dSGeorge Rimar } 886884e786dSGeorge Rimar 887f34f45fdSGeorge Rimar template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) { 888f34f45fdSGeorge Rimar return Symtab<ELFT>::X->find(S) != nullptr; 889f34f45fdSGeorge Rimar } 890f34f45fdSGeorge Rimar 8912f831dcaSRafael Espindola template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) { 8922f831dcaSRafael Espindola SymbolBody *Sym = Symtab<ELFT>::X->find(S); 8932f831dcaSRafael Espindola auto *DR = dyn_cast_or_null<DefinedRegular<ELFT>>(Sym); 8942f831dcaSRafael Espindola return DR && !DR->Section; 8952f831dcaSRafael Espindola } 8962f831dcaSRafael Espindola 897afaa9343SEugene Leviant // Gets section symbol belongs to. Symbol "." doesn't belong to any 898afaa9343SEugene Leviant // specific section but isn't absolute at the same time, so we try 899afaa9343SEugene Leviant // to find suitable section for it as well. 900afaa9343SEugene Leviant template <class ELFT> 901afaa9343SEugene Leviant const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) { 902afaa9343SEugene Leviant SymbolBody *Sym = Symtab<ELFT>::X->find(S); 903afaa9343SEugene Leviant if (!Sym) { 904afaa9343SEugene Leviant if (OutputSections->empty()) 905afaa9343SEugene Leviant return nullptr; 906afaa9343SEugene Leviant return CurOutSec ? CurOutSec : (*OutputSections)[0]; 907afaa9343SEugene Leviant } 908afaa9343SEugene Leviant 909afaa9343SEugene Leviant if (auto *DR = dyn_cast_or_null<DefinedRegular<ELFT>>(Sym)) 910afaa9343SEugene Leviant return DR->Section ? DR->Section->OutSec : nullptr; 911afaa9343SEugene Leviant if (auto *DS = dyn_cast_or_null<DefinedSynthetic<ELFT>>(Sym)) 912afaa9343SEugene Leviant return DS->Section; 913afaa9343SEugene Leviant 914afaa9343SEugene Leviant return nullptr; 915afaa9343SEugene Leviant } 916afaa9343SEugene Leviant 917bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 918bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 919bbe38602SEugene Leviant // PHDRS {} script block. 920bbe38602SEugene Leviant template <class ELFT> 921edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 922076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 923076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 924edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 92531d842f5SGeorge Rimar continue; 92631d842f5SGeorge Rimar 92729c5a2a9SRui Ueyama std::vector<size_t> Ret; 92829c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 92929c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 93029c5a2a9SRui Ueyama return Ret; 931bbe38602SEugene Leviant } 93231d842f5SGeorge Rimar return {}; 93331d842f5SGeorge Rimar } 934bbe38602SEugene Leviant 93529c5a2a9SRui Ueyama template <class ELFT> 93629c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 93729c5a2a9SRui Ueyama size_t I = 0; 93829c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 93929c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 94029c5a2a9SRui Ueyama return I; 94129c5a2a9SRui Ueyama ++I; 94229c5a2a9SRui Ueyama } 94329c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 94429c5a2a9SRui Ueyama return 0; 94529c5a2a9SRui Ueyama } 94629c5a2a9SRui Ueyama 94703ff0166SEugene Leviant class elf::ScriptParser final : public ScriptParserBase { 948c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 949c3794e58SGeorge Rimar 950f7c5fbb1SRui Ueyama public: 95103ff0166SEugene Leviant ScriptParser(MemoryBufferRef MB, bool B) 95203ff0166SEugene Leviant : ScriptParserBase(MB), IsUnderSysroot(B) {} 953f23b2320SGeorge Rimar 95420b6598cSGeorge Rimar void readLinkerScript(); 95520b6598cSGeorge Rimar void readVersionScript(); 956f7c5fbb1SRui Ueyama 957f7c5fbb1SRui Ueyama private: 95852a1509eSRui Ueyama void addFile(StringRef Path); 95952a1509eSRui Ueyama 960f7c5fbb1SRui Ueyama void readAsNeeded(); 96190c5099eSDenis Protivensky void readEntry(); 96283f406cfSGeorge Rimar void readExtern(); 963f7c5fbb1SRui Ueyama void readGroup(); 96431aa1f83SRui Ueyama void readInclude(); 965ee59282bSRui Ueyama void readOutput(); 9669159ce93SDavide Italiano void readOutputArch(); 967f7c5fbb1SRui Ueyama void readOutputFormat(); 968bbe38602SEugene Leviant void readPhdrs(); 96968a39a65SDavide Italiano void readSearchDir(); 9708e3b38abSDenis Protivensky void readSections(); 97195769b4aSRui Ueyama void readVersion(); 97295769b4aSRui Ueyama void readVersionScriptCommand(); 9738e3b38abSDenis Protivensky 974113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 975e38cbab5SGeorge Rimar BytesDataCommand *readBytesDataCommand(StringRef Tok); 97616068aebSRui Ueyama uint32_t readFill(); 97710416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 97816068aebSRui Ueyama uint32_t readOutputSectionFiller(StringRef Tok); 979bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 980a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 981db688454SEugene Leviant StringMatcher readFilePatterns(); 98207171f21SGeorge Rimar std::vector<SectionPattern> readInputSectionsList(); 983a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 984bbe38602SEugene Leviant unsigned readPhdrType(); 985be394db3SGeorge Rimar SortSectionPolicy readSortKind(); 986a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 987c96da110SRafael Espindola SymbolAssignment *readProvideOrAssignment(StringRef Tok); 98803fc010eSGeorge Rimar void readSort(); 989eefa758eSGeorge Rimar Expr readAssert(); 990708019c4SRui Ueyama 991708019c4SRui Ueyama Expr readExpr(); 992708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 993b71d6f7aSEugene Leviant StringRef readParenLiteral(); 994708019c4SRui Ueyama Expr readPrimary(); 995708019c4SRui Ueyama Expr readTernary(Expr Cond); 9966ad7dfccSRui Ueyama Expr readParenExpr(); 997f7c5fbb1SRui Ueyama 99820b6598cSGeorge Rimar // For parsing version script. 99912450b20SRui Ueyama std::vector<SymbolVersion> readVersionExtern(); 100012450b20SRui Ueyama void readAnonymousDeclaration(); 100195769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 100212450b20SRui Ueyama std::vector<SymbolVersion> readSymbols(); 100320b6598cSGeorge Rimar 100407320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 100516b0cc9eSSimon Atanasyan bool IsUnderSysroot; 100603ff0166SEugene Leviant std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs; 1007f7c5fbb1SRui Ueyama }; 1008f7c5fbb1SRui Ueyama 100920b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 101095769b4aSRui Ueyama readVersionScriptCommand(); 101120b6598cSGeorge Rimar if (!atEOF()) 101295769b4aSRui Ueyama setError("EOF expected, but got " + next()); 101395769b4aSRui Ueyama } 101495769b4aSRui Ueyama 101595769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 101683043f23SRui Ueyama if (consume("{")) { 101712450b20SRui Ueyama readAnonymousDeclaration(); 101820b6598cSGeorge Rimar return; 101920b6598cSGeorge Rimar } 102020b6598cSGeorge Rimar 102195769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 102220b6598cSGeorge Rimar StringRef VerStr = next(); 102320b6598cSGeorge Rimar if (VerStr == "{") { 102495769b4aSRui Ueyama setError("anonymous version definition is used in " 102595769b4aSRui Ueyama "combination with other version definitions"); 102620b6598cSGeorge Rimar return; 102720b6598cSGeorge Rimar } 102820b6598cSGeorge Rimar expect("{"); 102995769b4aSRui Ueyama readVersionDeclaration(VerStr); 103020b6598cSGeorge Rimar } 103120b6598cSGeorge Rimar } 103220b6598cSGeorge Rimar 103395769b4aSRui Ueyama void ScriptParser::readVersion() { 103495769b4aSRui Ueyama expect("{"); 103595769b4aSRui Ueyama readVersionScriptCommand(); 103695769b4aSRui Ueyama expect("}"); 103795769b4aSRui Ueyama } 103895769b4aSRui Ueyama 103920b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 1040f7c5fbb1SRui Ueyama while (!atEOF()) { 1041f7c5fbb1SRui Ueyama StringRef Tok = next(); 1042a27eeccaSRui Ueyama if (Tok == ";") 1043a27eeccaSRui Ueyama continue; 1044a27eeccaSRui Ueyama 104520d03194SEugene Leviant if (Tok == "ASSERT") { 104620d03194SEugene Leviant Opt.Commands.emplace_back(new AssertCommand(readAssert())); 104720d03194SEugene Leviant } else if (Tok == "ENTRY") { 1048a27eeccaSRui Ueyama readEntry(); 1049a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 1050a27eeccaSRui Ueyama readExtern(); 1051a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 1052a27eeccaSRui Ueyama readGroup(); 1053a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 1054a27eeccaSRui Ueyama readInclude(); 1055a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 1056a27eeccaSRui Ueyama readOutput(); 1057a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 1058a27eeccaSRui Ueyama readOutputArch(); 1059a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 1060a27eeccaSRui Ueyama readOutputFormat(); 1061a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 1062a27eeccaSRui Ueyama readPhdrs(); 1063a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 1064a27eeccaSRui Ueyama readSearchDir(); 1065a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 1066a27eeccaSRui Ueyama readSections(); 1067a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 1068a27eeccaSRui Ueyama readVersion(); 1069c96da110SRafael Espindola } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { 10700df80befSPetr Hosek Opt.Commands.emplace_back(Cmd); 1071e5d3ca50SPetr Hosek } else { 10725761042dSGeorge Rimar setError("unknown directive: " + Tok); 1073f7c5fbb1SRui Ueyama } 1074f7c5fbb1SRui Ueyama } 1075e5d3ca50SPetr Hosek } 1076f7c5fbb1SRui Ueyama 1077717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 107816b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 10795af1687fSJustin Bogner SmallString<128> PathData; 10805af1687fSJustin Bogner StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 108116b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 10825af1687fSJustin Bogner Driver->addFile(Saver.save(Path)); 108316b0cc9eSSimon Atanasyan return; 108416b0cc9eSSimon Atanasyan } 108516b0cc9eSSimon Atanasyan } 108616b0cc9eSSimon Atanasyan 1087f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 108852a1509eSRui Ueyama Driver->addFile(S); 108952a1509eSRui Ueyama } else if (S.startswith("=")) { 109052a1509eSRui Ueyama if (Config->Sysroot.empty()) 109152a1509eSRui Ueyama Driver->addFile(S.substr(1)); 109252a1509eSRui Ueyama else 109352a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 109452a1509eSRui Ueyama } else if (S.startswith("-l")) { 109521eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 1096a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 1097a1b8fc3bSSimon Atanasyan Driver->addFile(S); 109852a1509eSRui Ueyama } else { 1099061f9286SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(S)) 1100061f9286SRui Ueyama Driver->addFile(Saver.save(*Path)); 1101025d59b1SRui Ueyama else 1102061f9286SRui Ueyama setError("unable to find " + S); 110352a1509eSRui Ueyama } 110452a1509eSRui Ueyama } 110552a1509eSRui Ueyama 1106717677afSRui Ueyama void ScriptParser::readAsNeeded() { 1107f7c5fbb1SRui Ueyama expect("("); 110835da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 110935da9b6eSRui Ueyama Config->AsNeeded = true; 111083043f23SRui Ueyama while (!Error && !consume(")")) 1111cd574a5eSGeorge Rimar addFile(unquote(next())); 111235da9b6eSRui Ueyama Config->AsNeeded = Orig; 1113f7c5fbb1SRui Ueyama } 1114f7c5fbb1SRui Ueyama 1115717677afSRui Ueyama void ScriptParser::readEntry() { 111690c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 111790c5099eSDenis Protivensky expect("("); 111890c5099eSDenis Protivensky StringRef Tok = next(); 111990c5099eSDenis Protivensky if (Config->Entry.empty()) 112090c5099eSDenis Protivensky Config->Entry = Tok; 112190c5099eSDenis Protivensky expect(")"); 112290c5099eSDenis Protivensky } 112390c5099eSDenis Protivensky 1124717677afSRui Ueyama void ScriptParser::readExtern() { 112583f406cfSGeorge Rimar expect("("); 112683043f23SRui Ueyama while (!Error && !consume(")")) 1127a2acc931SRui Ueyama Config->Undefined.push_back(next()); 112883f406cfSGeorge Rimar } 112983f406cfSGeorge Rimar 1130717677afSRui Ueyama void ScriptParser::readGroup() { 1131f7c5fbb1SRui Ueyama expect("("); 113283043f23SRui Ueyama while (!Error && !consume(")")) { 1133f7c5fbb1SRui Ueyama StringRef Tok = next(); 1134a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 1135f7c5fbb1SRui Ueyama readAsNeeded(); 1136a2acc931SRui Ueyama else 1137cd574a5eSGeorge Rimar addFile(unquote(Tok)); 1138f7c5fbb1SRui Ueyama } 1139f7c5fbb1SRui Ueyama } 1140f7c5fbb1SRui Ueyama 1141717677afSRui Ueyama void ScriptParser::readInclude() { 114231aa1f83SRui Ueyama StringRef Tok = next(); 1143cd574a5eSGeorge Rimar auto MBOrErr = MemoryBuffer::getFile(unquote(Tok)); 1144025d59b1SRui Ueyama if (!MBOrErr) { 11455761042dSGeorge Rimar setError("cannot open " + Tok); 1146025d59b1SRui Ueyama return; 1147025d59b1SRui Ueyama } 114831aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 114903ff0166SEugene Leviant tokenize(MB->getMemBufferRef()); 115003ff0166SEugene Leviant OwningMBs.push_back(std::move(MB)); 115131aa1f83SRui Ueyama } 115231aa1f83SRui Ueyama 1153717677afSRui Ueyama void ScriptParser::readOutput() { 1154ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 1155ee59282bSRui Ueyama expect("("); 1156ee59282bSRui Ueyama StringRef Tok = next(); 1157ee59282bSRui Ueyama if (Config->OutputFile.empty()) 1158cd574a5eSGeorge Rimar Config->OutputFile = unquote(Tok); 1159ee59282bSRui Ueyama expect(")"); 1160ee59282bSRui Ueyama } 1161ee59282bSRui Ueyama 1162717677afSRui Ueyama void ScriptParser::readOutputArch() { 11639159ce93SDavide Italiano // Error checking only for now. 11649159ce93SDavide Italiano expect("("); 11655424e7c7SJustin Bogner skip(); 11669159ce93SDavide Italiano expect(")"); 11679159ce93SDavide Italiano } 11689159ce93SDavide Italiano 1169717677afSRui Ueyama void ScriptParser::readOutputFormat() { 1170f7c5fbb1SRui Ueyama // Error checking only for now. 1171f7c5fbb1SRui Ueyama expect("("); 11725424e7c7SJustin Bogner skip(); 11736836c618SDavide Italiano StringRef Tok = next(); 11746836c618SDavide Italiano if (Tok == ")") 11756836c618SDavide Italiano return; 1176025d59b1SRui Ueyama if (Tok != ",") { 11775761042dSGeorge Rimar setError("unexpected token: " + Tok); 1178025d59b1SRui Ueyama return; 1179025d59b1SRui Ueyama } 11805424e7c7SJustin Bogner skip(); 11816836c618SDavide Italiano expect(","); 11825424e7c7SJustin Bogner skip(); 1183f7c5fbb1SRui Ueyama expect(")"); 1184f7c5fbb1SRui Ueyama } 1185f7c5fbb1SRui Ueyama 1186bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 1187bbe38602SEugene Leviant expect("{"); 118883043f23SRui Ueyama while (!Error && !consume("}")) { 1189bbe38602SEugene Leviant StringRef Tok = next(); 119056b21c86SEugene Leviant Opt.PhdrsCommands.push_back( 119156b21c86SEugene Leviant {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 1192bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 1193bbe38602SEugene Leviant 1194bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 1195bbe38602SEugene Leviant do { 1196bbe38602SEugene Leviant Tok = next(); 1197bbe38602SEugene Leviant if (Tok == ";") 1198bbe38602SEugene Leviant break; 1199bbe38602SEugene Leviant if (Tok == "FILEHDR") 1200bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 1201bbe38602SEugene Leviant else if (Tok == "PHDRS") 1202bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 120356b21c86SEugene Leviant else if (Tok == "AT") 120456b21c86SEugene Leviant PhdrCmd.LMAExpr = readParenExpr(); 1205865bf863SEugene Leviant else if (Tok == "FLAGS") { 1206865bf863SEugene Leviant expect("("); 1207eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 1208eb685cd7SRafael Espindola // we accept expressions like ".|1". 1209eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 1210865bf863SEugene Leviant expect(")"); 1211865bf863SEugene Leviant } else 1212bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 1213bbe38602SEugene Leviant } while (!Error); 1214bbe38602SEugene Leviant } 1215bbe38602SEugene Leviant } 1216bbe38602SEugene Leviant 1217717677afSRui Ueyama void ScriptParser::readSearchDir() { 121868a39a65SDavide Italiano expect("("); 121986c5fb82SRui Ueyama StringRef Tok = next(); 12206c7ad13fSRui Ueyama if (!Config->Nostdlib) 1221cd574a5eSGeorge Rimar Config->SearchPaths.push_back(unquote(Tok)); 122268a39a65SDavide Italiano expect(")"); 122368a39a65SDavide Italiano } 122468a39a65SDavide Italiano 1225717677afSRui Ueyama void ScriptParser::readSections() { 1226e05336ffSEugene Leviant Opt.HasSections = true; 12278e3b38abSDenis Protivensky expect("{"); 122883043f23SRui Ueyama while (!Error && !consume("}")) { 1229113cdec9SRui Ueyama StringRef Tok = next(); 1230c96da110SRafael Espindola BaseCommand *Cmd = readProvideOrAssignment(Tok); 1231ceabe80eSEugene Leviant if (!Cmd) { 1232ceabe80eSEugene Leviant if (Tok == "ASSERT") 1233eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 1234ceabe80eSEugene Leviant else 123510416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 12368e3b38abSDenis Protivensky } 123710416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 1238652852c5SGeorge Rimar } 1239708019c4SRui Ueyama } 12408e3b38abSDenis Protivensky 1241708019c4SRui Ueyama static int precedence(StringRef Op) { 1242708019c4SRui Ueyama return StringSwitch<int>(Op) 12430120e3f2SRui Ueyama .Cases("*", "/", 5) 12440120e3f2SRui Ueyama .Cases("+", "-", 4) 12450120e3f2SRui Ueyama .Cases("<<", ">>", 3) 12469c4ac5f2SRui Ueyama .Cases("<", "<=", ">", ">=", "==", "!=", 2) 12470120e3f2SRui Ueyama .Cases("&", "|", 1) 1248708019c4SRui Ueyama .Default(-1); 1249708019c4SRui Ueyama } 1250708019c4SRui Ueyama 1251db688454SEugene Leviant StringMatcher ScriptParser::readFilePatterns() { 125210416564SRui Ueyama std::vector<StringRef> V; 125383043f23SRui Ueyama while (!Error && !consume(")")) 125410416564SRui Ueyama V.push_back(next()); 1255f91282e1SRui Ueyama return StringMatcher(V); 12560702c4e8SGeorge Rimar } 12570702c4e8SGeorge Rimar 1258be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() { 125983043f23SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 1260be394db3SGeorge Rimar return SortSectionPolicy::Name; 126183043f23SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 1262be394db3SGeorge Rimar return SortSectionPolicy::Alignment; 126383043f23SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 1264be394db3SGeorge Rimar return SortSectionPolicy::Priority; 126583043f23SRui Ueyama if (consume("SORT_NONE")) 1266be394db3SGeorge Rimar return SortSectionPolicy::None; 1267b2a0abdfSRui Ueyama return SortSectionPolicy::Default; 1268be394db3SGeorge Rimar } 1269be394db3SGeorge Rimar 1270395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in 1271395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ 1272395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) 1273af03be19SGeorge Rimar // The semantics of that is next: 1274af03be19SGeorge Rimar // * Include .foo.1 from every file. 1275af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o 1276af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o 127707171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 127807171f21SGeorge Rimar std::vector<SectionPattern> Ret; 1279601e9898SGeorge Rimar while (!Error && peek() != ")") { 1280f91282e1SRui Ueyama StringMatcher ExcludeFilePat; 128183043f23SRui Ueyama if (consume("EXCLUDE_FILE")) { 1282395281cfSGeorge Rimar expect("("); 1283f91282e1SRui Ueyama ExcludeFilePat = readFilePatterns(); 1284395281cfSGeorge Rimar } 1285395281cfSGeorge Rimar 1286601e9898SGeorge Rimar std::vector<StringRef> V; 1287601e9898SGeorge Rimar while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE") 1288395281cfSGeorge Rimar V.push_back(next()); 1289601e9898SGeorge Rimar 1290601e9898SGeorge Rimar if (!V.empty()) 1291f91282e1SRui Ueyama Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); 1292601e9898SGeorge Rimar else 1293601e9898SGeorge Rimar setError("section pattern is expected"); 1294395281cfSGeorge Rimar } 129507171f21SGeorge Rimar return Ret; 1296395281cfSGeorge Rimar } 1297395281cfSGeorge Rimar 1298f8f6f1e7SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a 1299f8f6f1e7SRui Ueyama // list of glob patterns for input sections. The grammar is as follows. 1300f8f6f1e7SRui Ueyama // 1301f8f6f1e7SRui Ueyama // <patterns> ::= <section-list> 1302f8f6f1e7SRui Ueyama // | <sort> "(" <section-list> ")" 1303f8f6f1e7SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")" 1304f8f6f1e7SRui Ueyama // 1305f8f6f1e7SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 1306f8f6f1e7SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 1307f8f6f1e7SRui Ueyama // 1308f8f6f1e7SRui Ueyama // <section-list> is parsed by readInputSectionsList(). 1309a2496cbeSGeorge Rimar InputSectionDescription * 1310a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 1311c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 13120ed42b0cSDavide Italiano expect("("); 131383043f23SRui Ueyama while (!HasError && !consume(")")) { 131407171f21SGeorge Rimar SortSectionPolicy Outer = readSortKind(); 131507171f21SGeorge Rimar SortSectionPolicy Inner = SortSectionPolicy::Default; 131607171f21SGeorge Rimar std::vector<SectionPattern> V; 131707171f21SGeorge Rimar if (Outer != SortSectionPolicy::Default) { 13180702c4e8SGeorge Rimar expect("("); 131907171f21SGeorge Rimar Inner = readSortKind(); 132007171f21SGeorge Rimar if (Inner != SortSectionPolicy::Default) { 1321350ece4eSGeorge Rimar expect("("); 132207171f21SGeorge Rimar V = readInputSectionsList(); 13230702c4e8SGeorge Rimar expect(")"); 1324350ece4eSGeorge Rimar } else { 132507171f21SGeorge Rimar V = readInputSectionsList(); 1326350ece4eSGeorge Rimar } 1327350ece4eSGeorge Rimar expect(")"); 132807171f21SGeorge Rimar } else { 132907171f21SGeorge Rimar V = readInputSectionsList(); 13300659800eSGeorge Rimar } 13310702c4e8SGeorge Rimar 133207171f21SGeorge Rimar for (SectionPattern &Pat : V) { 133307171f21SGeorge Rimar Pat.SortInner = Inner; 133407171f21SGeorge Rimar Pat.SortOuter = Outer; 133507171f21SGeorge Rimar } 133607171f21SGeorge Rimar 133707171f21SGeorge Rimar std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 133807171f21SGeorge Rimar } 133910416564SRui Ueyama return Cmd; 13400659800eSGeorge Rimar } 13410659800eSGeorge Rimar 1342a2496cbeSGeorge Rimar InputSectionDescription * 1343a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 13440659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 13450659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 1346a2496cbeSGeorge Rimar if (Tok == "KEEP") { 1347e7282797SDavide Italiano expect("("); 1348a2496cbeSGeorge Rimar StringRef FilePattern = next(); 1349a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 13500ed42b0cSDavide Italiano expect(")"); 1351cf43f179SEugene Leviant Opt.KeptSections.push_back(Cmd); 135210416564SRui Ueyama return Cmd; 135310416564SRui Ueyama } 1354a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 13550659800eSGeorge Rimar } 13560659800eSGeorge Rimar 135703fc010eSGeorge Rimar void ScriptParser::readSort() { 135803fc010eSGeorge Rimar expect("("); 135903fc010eSGeorge Rimar expect("CONSTRUCTORS"); 136003fc010eSGeorge Rimar expect(")"); 136103fc010eSGeorge Rimar } 136203fc010eSGeorge Rimar 1363eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 1364eefa758eSGeorge Rimar expect("("); 1365eefa758eSGeorge Rimar Expr E = readExpr(); 1366eefa758eSGeorge Rimar expect(","); 1367cd574a5eSGeorge Rimar StringRef Msg = unquote(next()); 1368eefa758eSGeorge Rimar expect(")"); 1369eefa758eSGeorge Rimar return [=](uint64_t Dot) { 1370eefa758eSGeorge Rimar uint64_t V = E(Dot); 1371eefa758eSGeorge Rimar if (!V) 1372eefa758eSGeorge Rimar error(Msg); 1373eefa758eSGeorge Rimar return V; 1374eefa758eSGeorge Rimar }; 1375eefa758eSGeorge Rimar } 1376eefa758eSGeorge Rimar 137725150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 137825150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from 137925150e8bSRui Ueyama // what GNU linkers do. 138025150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 138116068aebSRui Ueyama uint32_t ScriptParser::readFill() { 1382ff1f29e0SGeorge Rimar expect("("); 138316068aebSRui Ueyama uint32_t V = readOutputSectionFiller(next()); 1384ff1f29e0SGeorge Rimar expect(")"); 1385ff1f29e0SGeorge Rimar expect(";"); 1386ff1f29e0SGeorge Rimar return V; 1387ff1f29e0SGeorge Rimar } 1388ff1f29e0SGeorge Rimar 138910416564SRui Ueyama OutputSectionCommand * 139010416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 1391076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 139258e5c4dcSGeorge Rimar 139358e5c4dcSGeorge Rimar // Read an address expression. 139458e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 139558e5c4dcSGeorge Rimar if (peek() != ":") 139658e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 139758e5c4dcSGeorge Rimar 13988e3b38abSDenis Protivensky expect(":"); 1399246f681eSDavide Italiano 140083043f23SRui Ueyama if (consume("AT")) 1401b71d6f7aSEugene Leviant Cmd->LMAExpr = readParenExpr(); 140283043f23SRui Ueyama if (consume("ALIGN")) 14036ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 140483043f23SRui Ueyama if (consume("SUBALIGN")) 1405db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1406630c6179SGeorge Rimar 1407246f681eSDavide Italiano // Parse constraints. 140883043f23SRui Ueyama if (consume("ONLY_IF_RO")) 1409efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 141083043f23SRui Ueyama if (consume("ONLY_IF_RW")) 1411efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 14128e3b38abSDenis Protivensky expect("{"); 14138ec77e64SRui Ueyama 141483043f23SRui Ueyama while (!Error && !consume("}")) { 1415ceabe80eSEugene Leviant StringRef Tok = next(); 1416c96da110SRafael Espindola if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) 1417ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1418e38cbab5SGeorge Rimar else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) 1419e38cbab5SGeorge Rimar Cmd->Commands.emplace_back(Data); 1420ff1f29e0SGeorge Rimar else if (Tok == "FILL") 1421ff1f29e0SGeorge Rimar Cmd->Filler = readFill(); 1422ceabe80eSEugene Leviant else if (Tok == "SORT") 142303fc010eSGeorge Rimar readSort(); 1424a2496cbeSGeorge Rimar else if (peek() == "(") 1425a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1426ceabe80eSEugene Leviant else 1427ceabe80eSEugene Leviant setError("unknown command " + Tok); 14288e3b38abSDenis Protivensky } 1429076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 14304ebc5620SGeorge Rimar 143183043f23SRui Ueyama if (consume("=")) 14324ebc5620SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next()); 14334ebc5620SGeorge Rimar else if (peek().startswith("=")) 1434ff1f29e0SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next().drop_front()); 14354ebc5620SGeorge Rimar 143610416564SRui Ueyama return Cmd; 1437f71caa2bSRui Ueyama } 14388ec77e64SRui Ueyama 14392c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 14402c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 14412c8f1f04SRui Ueyama // 14422c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 14432c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 14442c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 14452c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 144616068aebSRui Ueyama uint32_t ScriptParser::readOutputSectionFiller(StringRef Tok) { 1447965827d6SRui Ueyama uint32_t V; 144816068aebSRui Ueyama if (!Tok.getAsInteger(0, V)) 144916068aebSRui Ueyama return V; 1450965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 145116068aebSRui Ueyama return 0; 14528e3b38abSDenis Protivensky } 14538e3b38abSDenis Protivensky 1454a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1455a31c91b1SEugene Leviant expect("("); 1456174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1457a35e39caSPetr Hosek Cmd->Provide = Provide; 1458174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1459a31c91b1SEugene Leviant expect(")"); 1460a31c91b1SEugene Leviant expect(";"); 146110416564SRui Ueyama return Cmd; 1462eda81a1bSEugene Leviant } 1463eda81a1bSEugene Leviant 1464c96da110SRafael Espindola SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 1465ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1466ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1467ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1468ceabe80eSEugene Leviant expect(";"); 1469ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1470a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1471a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1472a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1473ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1474a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1475ceabe80eSEugene Leviant } 1476ceabe80eSEugene Leviant return Cmd; 1477ceabe80eSEugene Leviant } 1478ceabe80eSEugene Leviant 147930835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { 148030835ea4SGeorge Rimar if (S == ".") 148130835ea4SGeorge Rimar return Dot; 1482884e786dSGeorge Rimar return ScriptBase->getSymbolValue(S); 1483e32a3598SGeorge Rimar } 1484e32a3598SGeorge Rimar 14852f831dcaSRafael Espindola static bool isAbsolute(StringRef S) { 14862f831dcaSRafael Espindola if (S == ".") 14872f831dcaSRafael Espindola return false; 14882f831dcaSRafael Espindola return ScriptBase->isAbsolute(S); 14892f831dcaSRafael Espindola } 14902f831dcaSRafael Espindola 149130835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 149230835ea4SGeorge Rimar StringRef Op = next(); 1493db741e72SEugene Leviant Expr E; 149430835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 149583043f23SRui Ueyama if (consume("ABSOLUTE")) { 14967c1381a0SRui Ueyama // The RHS may be something like "ABSOLUTE(.) & 0xff". 14977c1381a0SRui Ueyama // Call readExpr1 to read the whole expression. 14987c1381a0SRui Ueyama E = readExpr1(readParenExpr(), 0); 1499009d1742SRui Ueyama E.IsAbsolute = [] { return true; }; 1500db741e72SEugene Leviant } else { 1501db741e72SEugene Leviant E = readExpr(); 1502db741e72SEugene Leviant } 150330835ea4SGeorge Rimar if (Op == "+=") 150430835ea4SGeorge Rimar E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; 1505f661393aSRafael Espindola return new SymbolAssignment(Name, E); 150630835ea4SGeorge Rimar } 150730835ea4SGeorge Rimar 150830835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 150930835ea4SGeorge Rimar // script expression. 151030835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 151130835ea4SGeorge Rimar 151236c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 151336c1cd23SRui Ueyama if (Op == "*") 151436c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 151536c1cd23SRui Ueyama if (Op == "/") { 151636c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 151736c1cd23SRui Ueyama uint64_t RHS = R(Dot); 151836c1cd23SRui Ueyama if (RHS == 0) { 151936c1cd23SRui Ueyama error("division by zero"); 152036c1cd23SRui Ueyama return 0; 152136c1cd23SRui Ueyama } 152236c1cd23SRui Ueyama return L(Dot) / RHS; 152336c1cd23SRui Ueyama }; 152436c1cd23SRui Ueyama } 152536c1cd23SRui Ueyama if (Op == "+") 15262f831dcaSRafael Espindola return {[=](uint64_t Dot) { return L(Dot) + R(Dot); }, 1527009d1742SRui Ueyama [=] { return L.IsAbsolute() && R.IsAbsolute(); }, 1528009d1742SRui Ueyama [=] { 1529afaa9343SEugene Leviant const OutputSectionBase *S = L.Section(); 1530afaa9343SEugene Leviant return S ? S : R.Section(); 1531afaa9343SEugene Leviant }}; 153236c1cd23SRui Ueyama if (Op == "-") 153336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 1534c8ccd1f1SGeorge Rimar if (Op == "<<") 1535c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) << R(Dot); }; 1536c8ccd1f1SGeorge Rimar if (Op == ">>") 1537c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) >> R(Dot); }; 153836c1cd23SRui Ueyama if (Op == "<") 153936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 154036c1cd23SRui Ueyama if (Op == ">") 154136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 154236c1cd23SRui Ueyama if (Op == ">=") 154336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 154436c1cd23SRui Ueyama if (Op == "<=") 154536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 154636c1cd23SRui Ueyama if (Op == "==") 154736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 154836c1cd23SRui Ueyama if (Op == "!=") 154936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 155036c1cd23SRui Ueyama if (Op == "&") 155136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 1552cc3dd629SRafael Espindola if (Op == "|") 1553cc3dd629SRafael Espindola return [=](uint64_t Dot) { return L(Dot) | R(Dot); }; 155436c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 155536c1cd23SRui Ueyama } 155636c1cd23SRui Ueyama 1557708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1558708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1559708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1560708019c4SRui Ueyama while (!atEOF() && !Error) { 1561708019c4SRui Ueyama // Read an operator and an expression. 156246247b85SRui Ueyama if (consume("?")) 1563708019c4SRui Ueyama return readTernary(Lhs); 156446247b85SRui Ueyama StringRef Op1 = peek(); 1565708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1566a31c91b1SEugene Leviant break; 15675424e7c7SJustin Bogner skip(); 1568708019c4SRui Ueyama Expr Rhs = readPrimary(); 1569708019c4SRui Ueyama 1570708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1571708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1572708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1573708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1574708019c4SRui Ueyama while (!atEOF()) { 1575708019c4SRui Ueyama StringRef Op2 = peek(); 1576708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1577eda81a1bSEugene Leviant break; 1578708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1579eda81a1bSEugene Leviant } 1580708019c4SRui Ueyama 1581708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1582708019c4SRui Ueyama } 1583708019c4SRui Ueyama return Lhs; 1584708019c4SRui Ueyama } 1585708019c4SRui Ueyama 1586708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1587e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1588708019c4SRui Ueyama return Target->PageSize; 1589e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1590997f8838SPetr Hosek return Config->MaxPageSize; 1591708019c4SRui Ueyama error("unknown constant: " + S); 1592708019c4SRui Ueyama return 0; 1593708019c4SRui Ueyama } 1594708019c4SRui Ueyama 1595626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1596626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1597626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1598626e0b08SRui Ueyama // "M" (mega) prefixes. 15999f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 160046247b85SRui Ueyama // Negative number 1601eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1602eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1603eaeafb2bSSimon Atanasyan return false; 1604eaeafb2bSSimon Atanasyan Result = -Result; 1605eaeafb2bSSimon Atanasyan return true; 1606eaeafb2bSSimon Atanasyan } 160746247b85SRui Ueyama 160846247b85SRui Ueyama // Hexadecimal 16099f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 16109f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 16119f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 16129f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 16139f2f7ad9SGeorge Rimar 161446247b85SRui Ueyama // Decimal 16159f2f7ad9SGeorge Rimar int Suffix = 1; 16169f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 16179f2f7ad9SGeorge Rimar Suffix = 1024; 16189f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 16199f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 16209f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 16219f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 16229f2f7ad9SGeorge Rimar } 16239f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 16249f2f7ad9SGeorge Rimar return false; 16259f2f7ad9SGeorge Rimar Result *= Suffix; 16269f2f7ad9SGeorge Rimar return true; 16279f2f7ad9SGeorge Rimar } 16289f2f7ad9SGeorge Rimar 1629e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { 1630e38cbab5SGeorge Rimar int Size = StringSwitch<unsigned>(Tok) 1631e38cbab5SGeorge Rimar .Case("BYTE", 1) 1632e38cbab5SGeorge Rimar .Case("SHORT", 2) 1633e38cbab5SGeorge Rimar .Case("LONG", 4) 1634e38cbab5SGeorge Rimar .Case("QUAD", 8) 1635e38cbab5SGeorge Rimar .Default(-1); 1636e38cbab5SGeorge Rimar if (Size == -1) 1637e38cbab5SGeorge Rimar return nullptr; 1638e38cbab5SGeorge Rimar 1639e38cbab5SGeorge Rimar expect("("); 1640e38cbab5SGeorge Rimar uint64_t Val = 0; 1641e38cbab5SGeorge Rimar StringRef S = next(); 1642e38cbab5SGeorge Rimar if (!readInteger(S, Val)) 1643e38cbab5SGeorge Rimar setError("unexpected value: " + S); 1644e38cbab5SGeorge Rimar expect(")"); 1645e38cbab5SGeorge Rimar return new BytesDataCommand(Val, Size); 1646e38cbab5SGeorge Rimar } 1647e38cbab5SGeorge Rimar 1648b71d6f7aSEugene Leviant StringRef ScriptParser::readParenLiteral() { 1649b71d6f7aSEugene Leviant expect("("); 1650b71d6f7aSEugene Leviant StringRef Tok = next(); 1651b71d6f7aSEugene Leviant expect(")"); 1652b71d6f7aSEugene Leviant return Tok; 1653b71d6f7aSEugene Leviant } 1654b71d6f7aSEugene Leviant 1655708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 16566ad7dfccSRui Ueyama if (peek() == "(") 16576ad7dfccSRui Ueyama return readParenExpr(); 1658708019c4SRui Ueyama 16596ad7dfccSRui Ueyama StringRef Tok = next(); 1660708019c4SRui Ueyama 1661eaeafb2bSSimon Atanasyan if (Tok == "~") { 1662eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1663eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return ~E(Dot); }; 1664eaeafb2bSSimon Atanasyan } 1665eaeafb2bSSimon Atanasyan if (Tok == "-") { 1666eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1667eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return -E(Dot); }; 1668eaeafb2bSSimon Atanasyan } 1669eaeafb2bSSimon Atanasyan 1670708019c4SRui Ueyama // Built-in functions are parsed here. 1671708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 167296659df0SGeorge Rimar if (Tok == "ADDR") { 1673b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1674afaa9343SEugene Leviant return { 1675afaa9343SEugene Leviant [=](uint64_t Dot) { return ScriptBase->getOutputSection(Name)->Addr; }, 1676009d1742SRui Ueyama [=] { return false; }, 1677009d1742SRui Ueyama [=] { return ScriptBase->getOutputSection(Name); }}; 167896659df0SGeorge Rimar } 1679b71d6f7aSEugene Leviant if (Tok == "LOADADDR") { 1680b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1681afaa9343SEugene Leviant return [=](uint64_t Dot) { 1682afaa9343SEugene Leviant return ScriptBase->getOutputSection(Name)->getLMA(); 1683afaa9343SEugene Leviant }; 1684b71d6f7aSEugene Leviant } 1685eefa758eSGeorge Rimar if (Tok == "ASSERT") 1686eefa758eSGeorge Rimar return readAssert(); 1687708019c4SRui Ueyama if (Tok == "ALIGN") { 16886ad7dfccSRui Ueyama Expr E = readParenExpr(); 1689708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1690708019c4SRui Ueyama } 1691708019c4SRui Ueyama if (Tok == "CONSTANT") { 1692b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1693b0de56b5SRafael Espindola return [=](uint64_t Dot) { return getConstant(Name); }; 1694708019c4SRui Ueyama } 1695f34f45fdSGeorge Rimar if (Tok == "DEFINED") { 16960ee25a69SRui Ueyama StringRef Name = readParenLiteral(); 16970ee25a69SRui Ueyama return [=](uint64_t Dot) { return ScriptBase->isDefined(Name) ? 1 : 0; }; 1698f34f45fdSGeorge Rimar } 169954c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 170054c145ceSRafael Espindola expect("("); 17015424e7c7SJustin Bogner skip(); 170254c145ceSRafael Espindola expect(","); 17038c658bf8SGeorge Rimar Expr E = readExpr(); 170454c145ceSRafael Espindola expect(")"); 17058c658bf8SGeorge Rimar return [=](uint64_t Dot) { return E(Dot); }; 170654c145ceSRafael Espindola } 1707708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1708708019c4SRui Ueyama expect("("); 1709708019c4SRui Ueyama Expr E = readExpr(); 1710708019c4SRui Ueyama expect(","); 1711708019c4SRui Ueyama readExpr(); 1712708019c4SRui Ueyama expect(")"); 1713f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1714708019c4SRui Ueyama } 1715708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1716708019c4SRui Ueyama expect("("); 1717708019c4SRui Ueyama expect("."); 1718708019c4SRui Ueyama expect(")"); 1719708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1720708019c4SRui Ueyama } 1721276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1722276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1723276b4e64SGeorge Rimar // the next page boundary for simplicity. 1724276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1725276b4e64SGeorge Rimar expect("("); 172697bdc722SRafael Espindola readExpr(); 1727276b4e64SGeorge Rimar expect(","); 1728276b4e64SGeorge Rimar readExpr(); 1729276b4e64SGeorge Rimar expect(")"); 1730276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1731276b4e64SGeorge Rimar } 17329e69450eSGeorge Rimar if (Tok == "SIZEOF") { 1733b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1734edf75e79SRui Ueyama return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; 17359e69450eSGeorge Rimar } 173636fac7f0SEugene Leviant if (Tok == "ALIGNOF") { 1737b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1738afaa9343SEugene Leviant return [=](uint64_t Dot) { 1739afaa9343SEugene Leviant return ScriptBase->getOutputSection(Name)->Addralign; 1740afaa9343SEugene Leviant }; 174136fac7f0SEugene Leviant } 1742e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 1743b0de56b5SRafael Espindola return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; 1744708019c4SRui Ueyama 17459f2f7ad9SGeorge Rimar // Tok is a literal number. 17469f2f7ad9SGeorge Rimar uint64_t V; 17479f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 1748b0de56b5SRafael Espindola return [=](uint64_t Dot) { return V; }; 17499f2f7ad9SGeorge Rimar 17509f2f7ad9SGeorge Rimar // Tok is a symbol name. 175130835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1752708019c4SRui Ueyama setError("malformed number: " + Tok); 17532f831dcaSRafael Espindola return {[=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }, 1754009d1742SRui Ueyama [=] { return isAbsolute(Tok); }, 1755009d1742SRui Ueyama [=] { return ScriptBase->getSymbolSection(Tok); }}; 1756a9c5a528SGeorge Rimar } 1757708019c4SRui Ueyama 1758708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1759708019c4SRui Ueyama Expr L = readExpr(); 1760708019c4SRui Ueyama expect(":"); 1761708019c4SRui Ueyama Expr R = readExpr(); 1762708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1763708019c4SRui Ueyama } 1764708019c4SRui Ueyama 17656ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 17666ad7dfccSRui Ueyama expect("("); 17676ad7dfccSRui Ueyama Expr E = readExpr(); 17686ad7dfccSRui Ueyama expect(")"); 17696ad7dfccSRui Ueyama return E; 17706ad7dfccSRui Ueyama } 17716ad7dfccSRui Ueyama 1772bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1773bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1774bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1775bbe38602SEugene Leviant StringRef Tok = next(); 1776da841c16SGeorge Rimar Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); 1777bbe38602SEugene Leviant } 1778bbe38602SEugene Leviant return Phdrs; 1779bbe38602SEugene Leviant } 1780bbe38602SEugene Leviant 178195dd718cSGeorge Rimar // Read a program header type name. The next token must be a 178295dd718cSGeorge Rimar // name of a program header type or a constant (e.g. "0x3"). 1783bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1784bbe38602SEugene Leviant StringRef Tok = next(); 178595dd718cSGeorge Rimar uint64_t Val; 178695dd718cSGeorge Rimar if (readInteger(Tok, Val)) 178795dd718cSGeorge Rimar return Val; 178895dd718cSGeorge Rimar 1789b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1790b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1791b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1792b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1793b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1794b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1795b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1796b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1797b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1798b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1799b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1800b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1801270173f2SGeorge Rimar .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 1802cc6e567cSGeorge Rimar .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 1803b0f6c590SRui Ueyama .Default(-1); 1804bbe38602SEugene Leviant 1805b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1806b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1807b0f6c590SRui Ueyama return PT_NULL; 1808b0f6c590SRui Ueyama } 1809b0f6c590SRui Ueyama return Ret; 1810bbe38602SEugene Leviant } 1811bbe38602SEugene Leviant 181212450b20SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 181312450b20SRui Ueyama void ScriptParser::readAnonymousDeclaration() { 181412450b20SRui Ueyama // Read global symbols first. "global:" is default, so if there's 181512450b20SRui Ueyama // no label, we assume global symbols. 181612450b20SRui Ueyama if (consume("global:") || peek() != "local:") 181712450b20SRui Ueyama Config->VersionScriptGlobals = readSymbols(); 181812450b20SRui Ueyama 181912450b20SRui Ueyama // Next, read local symbols. 182012450b20SRui Ueyama if (consume("local:")) { 182112450b20SRui Ueyama if (consume("*")) { 182212450b20SRui Ueyama Config->DefaultSymbolVersion = VER_NDX_LOCAL; 182312450b20SRui Ueyama expect(";"); 182412450b20SRui Ueyama } else { 182512450b20SRui Ueyama setError("local symbol list for anonymous version is not supported"); 182612450b20SRui Ueyama } 182712450b20SRui Ueyama } 182812450b20SRui Ueyama expect("}"); 182912450b20SRui Ueyama expect(";"); 183012450b20SRui Ueyama } 183112450b20SRui Ueyama 183212450b20SRui Ueyama // Reads a list of symbols, e.g. "VerStr { global: foo; bar; local: *; };". 183395769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 183420b6598cSGeorge Rimar // Identifiers start at 2 because 0 and 1 are reserved 183520b6598cSGeorge Rimar // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. 1836da805c48SRui Ueyama uint16_t VersionId = Config->VersionDefinitions.size() + 2; 183720b6598cSGeorge Rimar Config->VersionDefinitions.push_back({VerStr, VersionId}); 183820b6598cSGeorge Rimar 183912450b20SRui Ueyama // Read global symbols. 184083043f23SRui Ueyama if (consume("global:") || peek() != "local:") 184112450b20SRui Ueyama Config->VersionDefinitions.back().Globals = readSymbols(); 184212450b20SRui Ueyama 184312450b20SRui Ueyama // Read local symbols. 184412450b20SRui Ueyama if (consume("local:")) { 184512450b20SRui Ueyama if (consume("*")) { 184612450b20SRui Ueyama Config->DefaultSymbolVersion = VER_NDX_LOCAL; 184712450b20SRui Ueyama expect(";"); 184812450b20SRui Ueyama } else { 184912450b20SRui Ueyama for (SymbolVersion V : readSymbols()) 185012450b20SRui Ueyama Config->VersionScriptLocals.push_back(V); 185112450b20SRui Ueyama } 185212450b20SRui Ueyama } 185320b6598cSGeorge Rimar expect("}"); 185420b6598cSGeorge Rimar 185512450b20SRui Ueyama // Each version may have a parent version. For example, "Ver2" 185612450b20SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 185712450b20SRui Ueyama // as a parent. This version hierarchy is, probably against your 185812450b20SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it 185912450b20SRui Ueyama // at all. In LLD, we simply ignore it. 186012450b20SRui Ueyama if (peek() != ";") 18615424e7c7SJustin Bogner skip(); 186220b6598cSGeorge Rimar expect(";"); 186320b6598cSGeorge Rimar } 186420b6598cSGeorge Rimar 186512450b20SRui Ueyama // Reads a list of symbols for a versions cript. 186612450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readSymbols() { 186712450b20SRui Ueyama std::vector<SymbolVersion> Ret; 1868e0fc2421SGeorge Rimar for (;;) { 1869e0fc2421SGeorge Rimar if (consume("extern")) 187012450b20SRui Ueyama for (SymbolVersion V : readVersionExtern()) 187112450b20SRui Ueyama Ret.push_back(V); 1872e0fc2421SGeorge Rimar 18730ee25a69SRui Ueyama if (peek() == "}" || peek() == "local:" || Error) 187412450b20SRui Ueyama break; 18750ee25a69SRui Ueyama StringRef Tok = next(); 187612450b20SRui Ueyama Ret.push_back({unquote(Tok), false, hasWildcard(Tok)}); 1877e0fc2421SGeorge Rimar expect(";"); 1878e0fc2421SGeorge Rimar } 187912450b20SRui Ueyama return Ret; 1880e0fc2421SGeorge Rimar } 1881e0fc2421SGeorge Rimar 188212450b20SRui Ueyama // Reads an "extern C++" directive, e.g., 188312450b20SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };" 188412450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 1885cd574a5eSGeorge Rimar expect("\"C++\""); 188620b6598cSGeorge Rimar expect("{"); 188720b6598cSGeorge Rimar 188812450b20SRui Ueyama std::vector<SymbolVersion> Ret; 18890ee25a69SRui Ueyama while (!Error && peek() != "}") { 18900ee25a69SRui Ueyama StringRef Tok = next(); 18910ee25a69SRui Ueyama bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); 189212450b20SRui Ueyama Ret.push_back({unquote(Tok), true, HasWildcard}); 189320b6598cSGeorge Rimar expect(";"); 189420b6598cSGeorge Rimar } 189520b6598cSGeorge Rimar 189620b6598cSGeorge Rimar expect("}"); 189720b6598cSGeorge Rimar expect(";"); 189812450b20SRui Ueyama return Ret; 189920b6598cSGeorge Rimar } 190020b6598cSGeorge Rimar 190116b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 190216b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 190316b0cc9eSSimon Atanasyan return false; 190416b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 190516b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 190616b0cc9eSSimon Atanasyan return true; 190716b0cc9eSSimon Atanasyan return false; 190816b0cc9eSSimon Atanasyan } 190916b0cc9eSSimon Atanasyan 191007320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 191116b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 191203ff0166SEugene Leviant ScriptParser(MB, isUnderSysroot(Path)).readLinkerScript(); 191320b6598cSGeorge Rimar } 191420b6598cSGeorge Rimar 191520b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 191603ff0166SEugene Leviant ScriptParser(MB, false).readVersionScript(); 1917f7c5fbb1SRui Ueyama } 19181ebc8ed7SRui Ueyama 191907320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 192007320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 192107320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 192207320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1923