1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===// 2f7c5fbb1SRui Ueyama // 3f7c5fbb1SRui Ueyama // The LLVM Linker 4f7c5fbb1SRui Ueyama // 5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source 6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details. 7f7c5fbb1SRui Ueyama // 8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 9f7c5fbb1SRui Ueyama // 10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script. 11629e0aa5SRui Ueyama // It parses a linker script and write the result to Config or ScriptConfig 12629e0aa5SRui Ueyama // objects. 13629e0aa5SRui Ueyama // 14629e0aa5SRui Ueyama // If SECTIONS command is used, a ScriptConfig contains an AST 15629e0aa5SRui Ueyama // of the command which will later be consumed by createSections() and 16629e0aa5SRui Ueyama // assignAddresses(). 17f7c5fbb1SRui Ueyama // 18f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 19f7c5fbb1SRui Ueyama 20717677afSRui Ueyama #include "LinkerScript.h" 21f7c5fbb1SRui Ueyama #include "Config.h" 22f7c5fbb1SRui Ueyama #include "Driver.h" 231ebc8ed7SRui Ueyama #include "InputSection.h" 24652852c5SGeorge Rimar #include "OutputSections.h" 25e77b5bf6SAdhemerval Zanella #include "ScriptParser.h" 2693c9af42SRui Ueyama #include "Strings.h" 27eda81a1bSEugene Leviant #include "Symbols.h" 28f7c5fbb1SRui Ueyama #include "SymbolTable.h" 29467c4d55SEugene Leviant #include "Target.h" 30bbe38602SEugene Leviant #include "Writer.h" 31960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 32652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 33f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 34f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h" 35f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 36a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h" 37f7c5fbb1SRui Ueyama 38f7c5fbb1SRui Ueyama using namespace llvm; 39652852c5SGeorge Rimar using namespace llvm::ELF; 401ebc8ed7SRui Ueyama using namespace llvm::object; 41f7c5fbb1SRui Ueyama using namespace lld; 42e0df00b9SRafael Espindola using namespace lld::elf; 43f7c5fbb1SRui Ueyama 44884e786dSGeorge Rimar LinkerScriptBase *elf::ScriptBase; 4507320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 46717677afSRui Ueyama 476c55f0e3SGeorge Rimar template <class ELFT> static void addRegular(SymbolAssignment *Cmd) { 481602421cSRui Ueyama Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, STB_GLOBAL, STV_DEFAULT); 491602421cSRui Ueyama Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; 501602421cSRui Ueyama Cmd->Sym = Sym->body(); 5120d03194SEugene Leviant 5220d03194SEugene Leviant // If we have no SECTIONS then we don't have '.' and don't call 5320d03194SEugene Leviant // assignAddresses(). We calculate symbol value immediately in this case. 5420d03194SEugene Leviant if (!ScriptConfig->HasSections) 5520d03194SEugene Leviant cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0); 56ceabe80eSEugene Leviant } 57ceabe80eSEugene Leviant 580c70d3ccSRui Ueyama template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) { 59e1937bb5SGeorge Rimar Symbol *Sym = Symtab<ELFT>::X->addSynthetic( 60e1937bb5SGeorge Rimar Cmd->Name, nullptr, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT); 611602421cSRui Ueyama Cmd->Sym = Sym->body(); 62ceabe80eSEugene Leviant } 63ceabe80eSEugene Leviant 64db741e72SEugene Leviant template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) { 65db741e72SEugene Leviant if (Cmd->IsAbsolute) 66db741e72SEugene Leviant addRegular<ELFT>(Cmd); 67db741e72SEugene Leviant else 68db741e72SEugene Leviant addSynthetic<ELFT>(Cmd); 69db741e72SEugene Leviant } 701602421cSRui Ueyama // If a symbol was in PROVIDE(), we need to define it only when 711602421cSRui Ueyama // it is an undefined symbol. 721602421cSRui Ueyama template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) { 731602421cSRui Ueyama if (Cmd->Name == ".") 74ceabe80eSEugene Leviant return false; 751602421cSRui Ueyama if (!Cmd->Provide) 76ceabe80eSEugene Leviant return true; 771602421cSRui Ueyama SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 781602421cSRui Ueyama return B && B->isUndefined(); 79ceabe80eSEugene Leviant } 80ceabe80eSEugene Leviant 81076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 82076fe157SGeorge Rimar return C->Kind == AssignmentKind; 83076fe157SGeorge Rimar } 84076fe157SGeorge Rimar 85076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 86076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 87076fe157SGeorge Rimar } 88076fe157SGeorge Rimar 89eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 90eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 91eea3114fSGeorge Rimar } 92eea3114fSGeorge Rimar 93eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 94eefa758eSGeorge Rimar return C->Kind == AssertKind; 95eefa758eSGeorge Rimar } 96eefa758eSGeorge Rimar 9736a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) { 98eea3114fSGeorge Rimar return !S || !S->Live; 99717677afSRui Ueyama } 100717677afSRui Ueyama 101f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::LinkerScript() {} 102f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::~LinkerScript() {} 103f34d0e08SRui Ueyama 10407320e40SRui Ueyama template <class ELFT> 10507320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 106c91930a1SGeorge Rimar for (Regex *Re : Opt.KeptSections) 107042a3f20SRafael Espindola if (Re->match(S->Name)) 108eea3114fSGeorge Rimar return true; 109eea3114fSGeorge Rimar return false; 110eea3114fSGeorge Rimar } 111eea3114fSGeorge Rimar 1123ff27f49SRui Ueyama // We need to use const_cast because match() is not a const function. 1133ff27f49SRui Ueyama // This function encapsulates that ugliness. 1143ff27f49SRui Ueyama static bool match(const Regex &Re, StringRef S) { 1153ff27f49SRui Ueyama return const_cast<Regex &>(Re).match(S); 1160659800eSGeorge Rimar } 1170659800eSGeorge Rimar 118575208caSGeorge Rimar static bool comparePriority(InputSectionData *A, InputSectionData *B) { 119575208caSGeorge Rimar return getPriority(A->Name) < getPriority(B->Name); 120575208caSGeorge Rimar } 121575208caSGeorge Rimar 122c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) { 123042a3f20SRafael Espindola return A->Name < B->Name; 1240702c4e8SGeorge Rimar } 125742c3836SRui Ueyama 126c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) { 127742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 128742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 129742c3836SRui Ueyama // This is compatible with GNU. 130742c3836SRui Ueyama return A->Alignment > B->Alignment; 131742c3836SRui Ueyama } 132742c3836SRui Ueyama 133c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)> 134be394db3SGeorge Rimar getComparator(SortSectionPolicy K) { 135be394db3SGeorge Rimar switch (K) { 136be394db3SGeorge Rimar case SortSectionPolicy::Alignment: 137c0028d3dSRafael Espindola return compareAlignment; 138be394db3SGeorge Rimar case SortSectionPolicy::Name: 139be394db3SGeorge Rimar return compareName; 140be394db3SGeorge Rimar case SortSectionPolicy::Priority: 141be394db3SGeorge Rimar return comparePriority; 142be394db3SGeorge Rimar default: 143be394db3SGeorge Rimar llvm_unreachable("unknown sort policy"); 144be394db3SGeorge Rimar } 145742c3836SRui Ueyama } 1460702c4e8SGeorge Rimar 1478f66df92SGeorge Rimar static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) { 1488f66df92SGeorge Rimar bool RO = (Kind == ConstraintKind::ReadOnly); 1498f66df92SGeorge Rimar bool RW = (Kind == ConstraintKind::ReadWrite); 1508f66df92SGeorge Rimar bool Writable = Flags & SHF_WRITE; 151adcdb664SRui Ueyama return !(RO && Writable) && !(RW && !Writable); 1528f66df92SGeorge Rimar } 1538f66df92SGeorge Rimar 15448c3f1ceSRui Ueyama template <class ELFT> 155e71a3f8aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 15606ae6836SGeorge Rimar ConstraintKind Kind) { 1578f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 1588f66df92SGeorge Rimar return true; 159d3190795SRafael Espindola return llvm::all_of(Sections, [=](InputSectionData *Sec2) { 160d3190795SRafael Espindola auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2); 1618f66df92SGeorge Rimar return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind); 16206ae6836SGeorge Rimar }); 16306ae6836SGeorge Rimar } 16406ae6836SGeorge Rimar 165d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches. 166be94e1b6SRafael Espindola template <class ELFT> 167e71a3f8aSRafael Espindola void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) { 168*4dc07becSRui Ueyama // Collects all sections that satisfy constraints of I 169*4dc07becSRui Ueyama // and attach them to I. 170*4dc07becSRui Ueyama for (SectionPattern &Pat : I->SectionPatterns) { 171395281cfSGeorge Rimar for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) { 1723ff27f49SRui Ueyama StringRef Filename = sys::path::filename(F->getName()); 173*4dc07becSRui Ueyama if (!match(I->FileRe, Filename) || match(Pat.ExcludedFileRe, Filename)) 1743ff27f49SRui Ueyama continue; 175*4dc07becSRui Ueyama 176be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : F->getSections()) 177*4dc07becSRui Ueyama if (!isDiscarded(S) && !S->OutSec && match(Pat.SectionRe, S->Name)) 178d3190795SRafael Espindola I->Sections.push_back(S); 179*4dc07becSRui Ueyama if (match(Pat.SectionRe, "COMMON")) 180d3190795SRafael Espindola I->Sections.push_back(CommonInputSection<ELFT>::X); 181395281cfSGeorge Rimar } 182395281cfSGeorge Rimar } 183d3190795SRafael Espindola 184*4dc07becSRui Ueyama // Sort for SORT() commands. 185b2a0abdfSRui Ueyama if (I->SortInner != SortSectionPolicy::Default) 186d3190795SRafael Espindola std::stable_sort(I->Sections.begin(), I->Sections.end(), 187d3190795SRafael Espindola getComparator(I->SortInner)); 188b2a0abdfSRui Ueyama if (I->SortOuter != SortSectionPolicy::Default) 189d3190795SRafael Espindola std::stable_sort(I->Sections.begin(), I->Sections.end(), 190d3190795SRafael Espindola getComparator(I->SortOuter)); 191d3190795SRafael Espindola 192d3190795SRafael Espindola // We do not add duplicate input sections, so mark them with a dummy output 193d3190795SRafael Espindola // section for now. 194d3190795SRafael Espindola for (InputSectionData *S : I->Sections) { 195d3190795SRafael Espindola auto *S2 = static_cast<InputSectionBase<ELFT> *>(S); 196d3190795SRafael Espindola S2->OutSec = (OutputSectionBase<ELFT> *)-1; 197d3190795SRafael Espindola } 198be94e1b6SRafael Espindola } 199be94e1b6SRafael Espindola 200be94e1b6SRafael Espindola template <class ELFT> 201be94e1b6SRafael Espindola void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) { 202be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : V) { 203be94e1b6SRafael Espindola S->Live = false; 204be94e1b6SRafael Espindola reportDiscarded(S); 205be94e1b6SRafael Espindola } 206be94e1b6SRafael Espindola } 207be94e1b6SRafael Espindola 20806ae6836SGeorge Rimar template <class ELFT> 2090b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 21006ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 2110b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 212e7f912cdSRui Ueyama 21306ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 2147c3ff2ebSRafael Espindola auto *Cmd = dyn_cast<InputSectionDescription>(Base.get()); 2157c3ff2ebSRafael Espindola if (!Cmd) 2160b9ce6a4SRui Ueyama continue; 217e71a3f8aSRafael Espindola computeInputSections(Cmd); 218d3190795SRafael Espindola for (InputSectionData *S : Cmd->Sections) 219d3190795SRafael Espindola Ret.push_back(static_cast<InputSectionBase<ELFT> *>(S)); 2200b9ce6a4SRui Ueyama } 221e71a3f8aSRafael Espindola 2220b9ce6a4SRui Ueyama return Ret; 2230b9ce6a4SRui Ueyama } 2240b9ce6a4SRui Ueyama 225e5d3ca50SPetr Hosek template <class ELFT> 22610897f18SRafael Espindola static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C, 22710897f18SRafael Espindola StringRef OutsecName) { 22810897f18SRafael Espindola // When using linker script the merge rules are different. 22910897f18SRafael Espindola // Unfortunately, linker scripts are name based. This means that expressions 23010897f18SRafael Espindola // like *(.foo*) can refer to multiple input sections that would normally be 23110897f18SRafael Espindola // placed in different output sections. We cannot put them in different 23210897f18SRafael Espindola // output sections or we would produce wrong results for 23310897f18SRafael Espindola // start = .; *(.foo.*) end = .; *(.bar) 23410897f18SRafael Espindola // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to 23510897f18SRafael Espindola // another. The problem is that there is no way to layout those output 23610897f18SRafael Espindola // sections such that the .foo sections are the only thing between the 23710897f18SRafael Espindola // start and end symbols. 23810897f18SRafael Espindola 23910897f18SRafael Espindola // An extra annoyance is that we cannot simply disable merging of the contents 24010897f18SRafael Espindola // of SHF_MERGE sections, but our implementation requires one output section 24110897f18SRafael Espindola // per "kind" (string or not, which size/aligment). 24210897f18SRafael Espindola // Fortunately, creating symbols in the middle of a merge section is not 24310897f18SRafael Espindola // supported by bfd or gold, so we can just create multiple section in that 24410897f18SRafael Espindola // case. 24510897f18SRafael Espindola const typename ELFT::Shdr *H = C->getSectionHdr(); 24610897f18SRafael Espindola typedef typename ELFT::uint uintX_t; 24710897f18SRafael Espindola uintX_t Flags = H->sh_flags & (SHF_MERGE | SHF_STRINGS); 24810897f18SRafael Espindola 24910897f18SRafael Espindola uintX_t Alignment = 0; 25010897f18SRafael Espindola if (isa<MergeInputSection<ELFT>>(C)) 25110897f18SRafael Espindola Alignment = std::max(H->sh_addralign, H->sh_entsize); 25210897f18SRafael Espindola 25310897f18SRafael Espindola return SectionKey<ELFT::Is64Bits>{OutsecName, /*Type*/ 0, Flags, Alignment}; 25410897f18SRafael Espindola } 25510897f18SRafael Espindola 25610897f18SRafael Espindola template <class ELFT> 25720d03194SEugene Leviant void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory, 25820d03194SEugene Leviant InputSectionBase<ELFT> *Sec, 25920d03194SEugene Leviant StringRef Name) { 26028c1597aSRafael Espindola OutputSectionBase<ELFT> *OutSec; 26128c1597aSRafael Espindola bool IsNew; 26210897f18SRafael Espindola std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec); 26328c1597aSRafael Espindola if (IsNew) 26428c1597aSRafael Espindola OutputSections->push_back(OutSec); 26520d03194SEugene Leviant OutSec->addSection(Sec); 26620d03194SEugene Leviant } 26720d03194SEugene Leviant 26820d03194SEugene Leviant template <class ELFT> 26920d03194SEugene Leviant void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { 27028c1597aSRafael Espindola 2717c3ff2ebSRafael Espindola for (unsigned I = 0; I < Opt.Commands.size(); ++I) { 2727c3ff2ebSRafael Espindola auto Iter = Opt.Commands.begin() + I; 2737c3ff2ebSRafael Espindola const std::unique_ptr<BaseCommand> &Base1 = *Iter; 2742ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 2752ab5f73dSRui Ueyama if (shouldDefine<ELFT>(Cmd)) 2762ab5f73dSRui Ueyama addRegular<ELFT>(Cmd); 2772ab5f73dSRui Ueyama continue; 2782ab5f73dSRui Ueyama } 27920d03194SEugene Leviant if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) { 28020d03194SEugene Leviant // If we don't have SECTIONS then output sections have already been 28120d03194SEugene Leviant // created by Writer<EFLT>. The LinkerScript<ELFT>::assignAddresses 28220d03194SEugene Leviant // will not be called, so ASSERT should be evaluated now. 28320d03194SEugene Leviant if (!Opt.HasSections) 28420d03194SEugene Leviant Cmd->Expression(0); 28520d03194SEugene Leviant continue; 28620d03194SEugene Leviant } 2872ab5f73dSRui Ueyama 288ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 2897bd37870SRafael Espindola std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 2907bd37870SRafael Espindola 29148c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 2927bd37870SRafael Espindola discard(V); 29348c3f1ceSRui Ueyama continue; 29448c3f1ceSRui Ueyama } 2950b9ce6a4SRui Ueyama 2967c3ff2ebSRafael Espindola if (!matchConstraints<ELFT>(V, Cmd->Constraint)) { 2977c3ff2ebSRafael Espindola for (InputSectionBase<ELFT> *S : V) 2987c3ff2ebSRafael Espindola S->OutSec = nullptr; 2997c3ff2ebSRafael Espindola Opt.Commands.erase(Iter); 3007c3ff2ebSRafael Espindola continue; 3017c3ff2ebSRafael Espindola } 3027c3ff2ebSRafael Espindola 3037c3ff2ebSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 3047c3ff2ebSRafael Espindola if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) 3057c3ff2ebSRafael Espindola if (shouldDefine<ELFT>(OutCmd)) 3067c3ff2ebSRafael Espindola addSymbol<ELFT>(OutCmd); 3077c3ff2ebSRafael Espindola 30897403d15SEugene Leviant if (V.empty()) 3090b9ce6a4SRui Ueyama continue; 3100b9ce6a4SRui Ueyama 311a14b13d8SGeorge Rimar for (InputSectionBase<ELFT> *Sec : V) { 31220d03194SEugene Leviant addSection(Factory, Sec, Cmd->Name); 31320d03194SEugene Leviant if (uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0) 314db24d9c3SGeorge Rimar Sec->Alignment = Subalign; 31520d03194SEugene Leviant } 316eea3114fSGeorge Rimar } 31748c3f1ceSRui Ueyama } 318db24d9c3SGeorge Rimar } 319e63d81bdSEugene Leviant 32020d03194SEugene Leviant template <class ELFT> 32120d03194SEugene Leviant void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 32220d03194SEugene Leviant processCommands(Factory); 3230b9ce6a4SRui Ueyama // Add orphan sections. 32420d03194SEugene Leviant for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) 32520d03194SEugene Leviant for (InputSectionBase<ELFT> *S : F->getSections()) 32620d03194SEugene Leviant if (!isDiscarded(S) && !S->OutSec) 32720d03194SEugene Leviant addSection(Factory, S, getOutputSectionName(S)); 328e63d81bdSEugene Leviant } 329e63d81bdSEugene Leviant 330db741e72SEugene Leviant // Sets value of a section-defined symbol. Two kinds of 331db741e72SEugene Leviant // symbols are processed: synthetic symbols, whose value 332db741e72SEugene Leviant // is an offset from beginning of section and regular 333db741e72SEugene Leviant // symbols whose value is absolute. 334db741e72SEugene Leviant template <class ELFT> 335db741e72SEugene Leviant static void assignSectionSymbol(SymbolAssignment *Cmd, 336db741e72SEugene Leviant OutputSectionBase<ELFT> *Sec, 337db741e72SEugene Leviant typename ELFT::uint Off) { 338db741e72SEugene Leviant if (!Cmd->Sym) 339db741e72SEugene Leviant return; 340db741e72SEugene Leviant 341db741e72SEugene Leviant if (auto *Body = dyn_cast<DefinedSynthetic<ELFT>>(Cmd->Sym)) { 342db741e72SEugene Leviant Body->Section = Sec; 343db741e72SEugene Leviant Body->Value = Cmd->Expression(Sec->getVA() + Off) - Sec->getVA(); 344db741e72SEugene Leviant return; 345db741e72SEugene Leviant } 346db741e72SEugene Leviant auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym); 347db741e72SEugene Leviant Body->Value = Cmd->Expression(Sec->getVA() + Off); 348db741e72SEugene Leviant } 349db741e72SEugene Leviant 350d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) { 351d3190795SRafael Espindola if (!AlreadyOutputIS.insert(S).second) 352ceabe80eSEugene Leviant return; 353d3190795SRafael Espindola bool IsTbss = 354d3190795SRafael Espindola (CurOutSec->getFlags() & SHF_TLS) && CurOutSec->getType() == SHT_NOBITS; 355d3190795SRafael Espindola 356d3190795SRafael Espindola uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; 357d3190795SRafael Espindola Pos = alignTo(Pos, S->Alignment); 358d3190795SRafael Espindola S->OutSecOff = Pos - CurOutSec->getVA(); 359d3190795SRafael Espindola Pos += S->getSize(); 360d3190795SRafael Espindola 361d3190795SRafael Espindola // Update output section size after adding each section. This is so that 362d3190795SRafael Espindola // SIZEOF works correctly in the case below: 363d3190795SRafael Espindola // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 364d3190795SRafael Espindola CurOutSec->setSize(Pos - CurOutSec->getVA()); 365d3190795SRafael Espindola 366d3190795SRafael Espindola if (!IsTbss) 367d3190795SRafael Espindola Dot = Pos; 3682de509c3SRui Ueyama } 369ceabe80eSEugene Leviant 370d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::flush() { 371d3190795SRafael Espindola if (auto *OutSec = dyn_cast_or_null<OutputSection<ELFT>>(CurOutSec)) { 372d3190795SRafael Espindola for (InputSection<ELFT> *I : OutSec->Sections) 373d3190795SRafael Espindola output(I); 374d3190795SRafael Espindola AlreadyOutputOS.insert(CurOutSec); 375d3190795SRafael Espindola } 376d3190795SRafael Espindola } 37797403d15SEugene Leviant 378d3190795SRafael Espindola template <class ELFT> 379d3190795SRafael Espindola void LinkerScript<ELFT>::switchTo(OutputSectionBase<ELFT> *Sec) { 380d3190795SRafael Espindola if (CurOutSec == Sec) 381d3190795SRafael Espindola return; 382d3190795SRafael Espindola if (AlreadyOutputOS.count(Sec)) 383d3190795SRafael Espindola return; 384d3190795SRafael Espindola 385d3190795SRafael Espindola flush(); 386d3190795SRafael Espindola CurOutSec = Sec; 387d3190795SRafael Espindola 388d3190795SRafael Espindola Dot = alignTo(Dot, CurOutSec->getAlignment()); 389d3190795SRafael Espindola CurOutSec->setVA(Dot); 390d3190795SRafael Espindola } 391d3190795SRafael Espindola 392d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) { 393d3190795SRafael Espindola if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) { 39497403d15SEugene Leviant if (AssignCmd->Name == ".") { 39597403d15SEugene Leviant // Update to location counter means update to section size. 396d3190795SRafael Espindola Dot = AssignCmd->Expression(Dot); 397d3190795SRafael Espindola CurOutSec->setSize(Dot - CurOutSec->getVA()); 398d3190795SRafael Espindola return; 39997403d15SEugene Leviant } 400d3190795SRafael Espindola assignSectionSymbol<ELFT>(AssignCmd, CurOutSec, Dot - CurOutSec->getVA()); 401d3190795SRafael Espindola return; 40297403d15SEugene Leviant } 403d3190795SRafael Espindola auto &ICmd = cast<InputSectionDescription>(Base); 404d3190795SRafael Espindola for (InputSectionData *ID : ICmd.Sections) { 405d3190795SRafael Espindola auto *IB = static_cast<InputSectionBase<ELFT> *>(ID); 406d3190795SRafael Espindola switchTo(IB->OutSec); 407d3190795SRafael Espindola if (auto *I = dyn_cast<InputSection<ELFT>>(IB)) 408d3190795SRafael Espindola output(I); 409d3190795SRafael Espindola else if (AlreadyOutputOS.insert(CurOutSec).second) 410d3190795SRafael Espindola Dot += CurOutSec->getSize(); 411ceabe80eSEugene Leviant } 412ceabe80eSEugene Leviant } 413ceabe80eSEugene Leviant 4148f66df92SGeorge Rimar template <class ELFT> 415a14b13d8SGeorge Rimar static std::vector<OutputSectionBase<ELFT> *> 416a14b13d8SGeorge Rimar findSections(OutputSectionCommand &Cmd, 417d3190795SRafael Espindola const std::vector<OutputSectionBase<ELFT> *> &Sections) { 418a14b13d8SGeorge Rimar std::vector<OutputSectionBase<ELFT> *> Ret; 419a14b13d8SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : Sections) 4207c3ff2ebSRafael Espindola if (Sec->getName() == Cmd.Name) 421a14b13d8SGeorge Rimar Ret.push_back(Sec); 422a14b13d8SGeorge Rimar return Ret; 4238f66df92SGeorge Rimar } 4248f66df92SGeorge Rimar 425d3190795SRafael Espindola template <class ELFT> 426d3190795SRafael Espindola void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) { 427d3190795SRafael Espindola std::vector<OutputSectionBase<ELFT> *> Sections = 428d3190795SRafael Espindola findSections(*Cmd, *OutputSections); 429d3190795SRafael Espindola if (Sections.empty()) 430d3190795SRafael Espindola return; 431d3190795SRafael Espindola switchTo(Sections[0]); 432d3190795SRafael Espindola 433d3190795SRafael Espindola // Find the last section output location. We will output orphan sections 434d3190795SRafael Espindola // there so that end symbols point to the correct location. 435d3190795SRafael Espindola auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(), 436d3190795SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 437d3190795SRafael Espindola return !isa<SymbolAssignment>(*Cmd); 438d3190795SRafael Espindola }) 439d3190795SRafael Espindola .base(); 440d3190795SRafael Espindola for (auto I = Cmd->Commands.begin(); I != E; ++I) 441d3190795SRafael Espindola process(**I); 442d3190795SRafael Espindola flush(); 443d3190795SRafael Espindola for (OutputSectionBase<ELFT> *Base : Sections) { 444d3190795SRafael Espindola if (!AlreadyOutputOS.insert(Base).second) 445d3190795SRafael Espindola continue; 446d3190795SRafael Espindola switchTo(Base); 447d3190795SRafael Espindola Dot += CurOutSec->getSize(); 448d3190795SRafael Espindola } 449d3190795SRafael Espindola for (auto I = E, E = Cmd->Commands.end(); I != E; ++I) 450d3190795SRafael Espindola process(**I); 451d3190795SRafael Espindola } 452d3190795SRafael Espindola 453a4b41dcaSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::assignAddresses() { 454652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 4557c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 4567c18c28cSRui Ueyama // We place orphan sections at end of file. 4577c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 458652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 459aab6d5c5SRafael Espindola 460aab6d5c5SRafael Espindola // The OutputSections are already in the correct order. 461aab6d5c5SRafael Espindola // This loops creates or moves commands as needed so that they are in the 462aab6d5c5SRafael Espindola // correct order. 463aab6d5c5SRafael Espindola int CmdIndex = 0; 464e5cc668eSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 465652852c5SGeorge Rimar StringRef Name = Sec->getName(); 466aab6d5c5SRafael Espindola 467aab6d5c5SRafael Espindola // Find the last spot where we can insert a command and still get the 468aab6d5c5SRafael Espindola // correct order. 469aab6d5c5SRafael Espindola auto CmdIter = Opt.Commands.begin() + CmdIndex; 470aab6d5c5SRafael Espindola auto E = Opt.Commands.end(); 471aab6d5c5SRafael Espindola while (CmdIter != E && !isa<OutputSectionCommand>(**CmdIter)) { 472aab6d5c5SRafael Espindola ++CmdIter; 473aab6d5c5SRafael Espindola ++CmdIndex; 474aab6d5c5SRafael Espindola } 475aab6d5c5SRafael Espindola 476aab6d5c5SRafael Espindola auto Pos = 477aab6d5c5SRafael Espindola std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) { 478aab6d5c5SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 479aab6d5c5SRafael Espindola return Cmd && Cmd->Name == Name; 480aab6d5c5SRafael Espindola }); 481aab6d5c5SRafael Espindola if (Pos == E) { 482aab6d5c5SRafael Espindola Opt.Commands.insert(CmdIter, 483aab6d5c5SRafael Espindola llvm::make_unique<OutputSectionCommand>(Name)); 484aab6d5c5SRafael Espindola } else { 485aab6d5c5SRafael Espindola // If linker script lists alloc/non-alloc sections is the wrong order, 486aab6d5c5SRafael Espindola // this does a right rotate to bring the desired command in place. 487373343bdSRafael Espindola auto RPos = llvm::make_reverse_iterator(Pos + 1); 488373343bdSRafael Espindola std::rotate(RPos, RPos + 1, llvm::make_reverse_iterator(CmdIter)); 489aab6d5c5SRafael Espindola } 490aab6d5c5SRafael Espindola ++CmdIndex; 491652852c5SGeorge Rimar } 492652852c5SGeorge Rimar 4937c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 4944f7500bfSRui Ueyama Dot = getHeaderSize(); 495652852c5SGeorge Rimar 496076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 497076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 4988d083e6aSRui Ueyama if (Cmd->Name == ".") { 4998d083e6aSRui Ueyama Dot = Cmd->Expression(Dot); 5008d083e6aSRui Ueyama } else if (Cmd->Sym) { 5018d083e6aSRui Ueyama cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot); 5028d083e6aSRui Ueyama } 50305ef4cffSRui Ueyama continue; 504652852c5SGeorge Rimar } 505652852c5SGeorge Rimar 506eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 507eefa758eSGeorge Rimar Cmd->Expression(Dot); 508eefa758eSGeorge Rimar continue; 509eefa758eSGeorge Rimar } 510eefa758eSGeorge Rimar 511076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 512652852c5SGeorge Rimar 51358e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 51458e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 51558e5c4dcSGeorge Rimar 516d3190795SRafael Espindola assignOffsets(Cmd); 517a14b13d8SGeorge Rimar } 518467c4d55SEugene Leviant 519aab6d5c5SRafael Espindola uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 520aab6d5c5SRafael Espindola for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 521aab6d5c5SRafael Espindola if (Sec->getFlags() & SHF_ALLOC) 522aab6d5c5SRafael Espindola MinVA = std::min(MinVA, Sec->getVA()); 523aab6d5c5SRafael Espindola else 524d3190795SRafael Espindola Sec->setVA(0); 525aab6d5c5SRafael Espindola } 526aab6d5c5SRafael Espindola 5274ec013acSRafael Espindola uintX_t HeaderSize = 5284ec013acSRafael Espindola Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 5294ec013acSRafael Espindola if (HeaderSize > MinVA) 5304ec013acSRafael Espindola fatal("Not enough space for ELF and program headers"); 5314ec013acSRafael Espindola 53264c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 533b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 5344ec013acSRafael Espindola MinVA = alignDown(MinVA - HeaderSize, Target->PageSize); 535467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 536467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 537fb8978fcSDima Stepanov } 538652852c5SGeorge Rimar 539464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 54007320e40SRui Ueyama template <class ELFT> 541a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { 542edebbdf1SRui Ueyama std::vector<PhdrEntry<ELFT>> Ret; 543bbe38602SEugene Leviant 544464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 545464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 546bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 547edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 548edebbdf1SRui Ueyama PhdrEntry<ELFT> &Phdr = Ret.back(); 549bbe38602SEugene Leviant 550bbe38602SEugene Leviant if (Cmd.HasFilehdr) 551adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 552bbe38602SEugene Leviant if (Cmd.HasPhdrs) 553adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 55456b21c86SEugene Leviant 55556b21c86SEugene Leviant if (Cmd.LMAExpr) { 55656b21c86SEugene Leviant Phdr.H.p_paddr = Cmd.LMAExpr(0); 55756b21c86SEugene Leviant Phdr.HasLMA = true; 55856b21c86SEugene Leviant } 559bbe38602SEugene Leviant } 560bbe38602SEugene Leviant 561464daadcSRui Ueyama // Add output sections to program headers. 562edebbdf1SRui Ueyama PhdrEntry<ELFT> *Load = nullptr; 563edebbdf1SRui Ueyama uintX_t Flags = PF_R; 564464daadcSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 565bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 566bbe38602SEugene Leviant break; 567bbe38602SEugene Leviant 568edebbdf1SRui Ueyama std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName()); 569bbe38602SEugene Leviant if (!PhdrIds.empty()) { 570bbe38602SEugene Leviant // Assign headers specified by linker script 571bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 572edebbdf1SRui Ueyama Ret[Id].add(Sec); 573865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 5740b113671SRafael Espindola Ret[Id].H.p_flags |= Sec->getPhdrFlags(); 575bbe38602SEugene Leviant } 576bbe38602SEugene Leviant } else { 577bbe38602SEugene Leviant // If we have no load segment or flags've changed then we want new load 578bbe38602SEugene Leviant // segment. 5790b113671SRafael Espindola uintX_t NewFlags = Sec->getPhdrFlags(); 580bbe38602SEugene Leviant if (Load == nullptr || Flags != NewFlags) { 581edebbdf1SRui Ueyama Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags); 582bbe38602SEugene Leviant Flags = NewFlags; 583bbe38602SEugene Leviant } 58418f084ffSRui Ueyama Load->add(Sec); 585bbe38602SEugene Leviant } 586bbe38602SEugene Leviant } 587edebbdf1SRui Ueyama return Ret; 588bbe38602SEugene Leviant } 589bbe38602SEugene Leviant 590f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 591f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 592f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 593f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 594f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 595f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 596f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 597f9bc3bd2SEugene Leviant } 598f9bc3bd2SEugene Leviant 599bbe38602SEugene Leviant template <class ELFT> 60007320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 601f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 602f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 603f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 604f6c3ccefSGeorge Rimar return Cmd->Filler; 605e2ee72b5SGeorge Rimar return {}; 606e2ee72b5SGeorge Rimar } 607e2ee72b5SGeorge Rimar 608206fffa1SGeorge Rimar template <class ELFT> Expr LinkerScript<ELFT>::getLma(StringRef Name) { 6098ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 6108ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 6118ceadb38SGeorge Rimar if (Cmd->LmaExpr && Cmd->Name == Name) 6128ceadb38SGeorge Rimar return Cmd->LmaExpr; 6138ceadb38SGeorge Rimar return {}; 6148ceadb38SGeorge Rimar } 6158ceadb38SGeorge Rimar 616c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 617c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 618c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 619c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 620076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 621f510fa6bSRui Ueyama int I = 0; 622f510fa6bSRui Ueyama for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 623076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 624076fe157SGeorge Rimar if (Cmd->Name == Name) 625f510fa6bSRui Ueyama return I; 626f510fa6bSRui Ueyama ++I; 627f510fa6bSRui Ueyama } 628f510fa6bSRui Ueyama return INT_MAX; 62971b26e94SGeorge Rimar } 63071b26e94SGeorge Rimar 63171b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if 63271b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0. 63307320e40SRui Ueyama template <class ELFT> 63407320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 635c3e2a4b0SRui Ueyama int I = getSectionIndex(A); 636c3e2a4b0SRui Ueyama int J = getSectionIndex(B); 637c3e2a4b0SRui Ueyama if (I == INT_MAX && J == INT_MAX) 638717677afSRui Ueyama return 0; 639717677afSRui Ueyama return I < J ? -1 : 1; 640717677afSRui Ueyama } 641717677afSRui Ueyama 642bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 643bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 644bbe38602SEugene Leviant } 645bbe38602SEugene Leviant 6469e69450eSGeorge Rimar template <class ELFT> 647884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) { 64896659df0SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 64996659df0SGeorge Rimar if (Sec->getName() == Name) 65096659df0SGeorge Rimar return Sec->getVA(); 65196659df0SGeorge Rimar error("undefined section " + Name); 65296659df0SGeorge Rimar return 0; 65396659df0SGeorge Rimar } 65496659df0SGeorge Rimar 65596659df0SGeorge Rimar template <class ELFT> 656884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 6579e69450eSGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 6589e69450eSGeorge Rimar if (Sec->getName() == Name) 6599e69450eSGeorge Rimar return Sec->getSize(); 6609e69450eSGeorge Rimar error("undefined section " + Name); 6619e69450eSGeorge Rimar return 0; 6629e69450eSGeorge Rimar } 6639e69450eSGeorge Rimar 66436fac7f0SEugene Leviant template <class ELFT> 66536fac7f0SEugene Leviant uint64_t LinkerScript<ELFT>::getOutputSectionAlign(StringRef Name) { 66636fac7f0SEugene Leviant for (OutputSectionBase<ELFT> *Sec : *OutputSections) 66736fac7f0SEugene Leviant if (Sec->getName() == Name) 66836fac7f0SEugene Leviant return Sec->getAlignment(); 66936fac7f0SEugene Leviant error("undefined section " + Name); 67036fac7f0SEugene Leviant return 0; 67136fac7f0SEugene Leviant } 67236fac7f0SEugene Leviant 673884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() { 674e32a3598SGeorge Rimar return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 675e32a3598SGeorge Rimar } 676e32a3598SGeorge Rimar 677884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) { 678884e786dSGeorge Rimar if (SymbolBody *B = Symtab<ELFT>::X->find(S)) 679884e786dSGeorge Rimar return B->getVA<ELFT>(); 680884e786dSGeorge Rimar error("symbol not found: " + S); 681884e786dSGeorge Rimar return 0; 682884e786dSGeorge Rimar } 683884e786dSGeorge Rimar 684bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 685bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 686bbe38602SEugene Leviant // PHDRS {} script block. 687bbe38602SEugene Leviant template <class ELFT> 688edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 689076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 690076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 691edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 69231d842f5SGeorge Rimar continue; 69331d842f5SGeorge Rimar 69429c5a2a9SRui Ueyama std::vector<size_t> Ret; 69529c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 69629c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 69729c5a2a9SRui Ueyama return Ret; 698bbe38602SEugene Leviant } 69931d842f5SGeorge Rimar return {}; 70031d842f5SGeorge Rimar } 701bbe38602SEugene Leviant 70229c5a2a9SRui Ueyama template <class ELFT> 70329c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 70429c5a2a9SRui Ueyama size_t I = 0; 70529c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 70629c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 70729c5a2a9SRui Ueyama return I; 70829c5a2a9SRui Ueyama ++I; 70929c5a2a9SRui Ueyama } 71029c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 71129c5a2a9SRui Ueyama return 0; 71229c5a2a9SRui Ueyama } 71329c5a2a9SRui Ueyama 71407320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 715c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 716c3794e58SGeorge Rimar 717f7c5fbb1SRui Ueyama public: 71807320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 719f23b2320SGeorge Rimar 72020b6598cSGeorge Rimar void readLinkerScript(); 72120b6598cSGeorge Rimar void readVersionScript(); 722f7c5fbb1SRui Ueyama 723f7c5fbb1SRui Ueyama private: 72452a1509eSRui Ueyama void addFile(StringRef Path); 72552a1509eSRui Ueyama 726f7c5fbb1SRui Ueyama void readAsNeeded(); 72790c5099eSDenis Protivensky void readEntry(); 72883f406cfSGeorge Rimar void readExtern(); 729f7c5fbb1SRui Ueyama void readGroup(); 73031aa1f83SRui Ueyama void readInclude(); 731ee59282bSRui Ueyama void readOutput(); 7329159ce93SDavide Italiano void readOutputArch(); 733f7c5fbb1SRui Ueyama void readOutputFormat(); 734bbe38602SEugene Leviant void readPhdrs(); 73568a39a65SDavide Italiano void readSearchDir(); 7368e3b38abSDenis Protivensky void readSections(); 73795769b4aSRui Ueyama void readVersion(); 73895769b4aSRui Ueyama void readVersionScriptCommand(); 7398e3b38abSDenis Protivensky 740113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 741ff1f29e0SGeorge Rimar std::vector<uint8_t> readFill(); 74210416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 743ff1f29e0SGeorge Rimar std::vector<uint8_t> readOutputSectionFiller(StringRef Tok); 744bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 745a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 746c91930a1SGeorge Rimar Regex readFilePatterns(); 747395281cfSGeorge Rimar void readSectionExcludes(InputSectionDescription *Cmd); 748a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 749bbe38602SEugene Leviant unsigned readPhdrType(); 750be394db3SGeorge Rimar SortSectionPolicy readSortKind(); 751a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 752db741e72SEugene Leviant SymbolAssignment *readProvideOrAssignment(StringRef Tok, bool MakeAbsolute); 75303fc010eSGeorge Rimar void readSort(); 754eefa758eSGeorge Rimar Expr readAssert(); 755708019c4SRui Ueyama 756708019c4SRui Ueyama Expr readExpr(); 757708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 758708019c4SRui Ueyama Expr readPrimary(); 759708019c4SRui Ueyama Expr readTernary(Expr Cond); 7606ad7dfccSRui Ueyama Expr readParenExpr(); 761f7c5fbb1SRui Ueyama 76220b6598cSGeorge Rimar // For parsing version script. 76320b6598cSGeorge Rimar void readExtern(std::vector<SymbolVersion> *Globals); 76495769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 76520b6598cSGeorge Rimar void readGlobal(StringRef VerStr); 76620b6598cSGeorge Rimar void readLocal(); 76720b6598cSGeorge Rimar 76807320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 76907320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 77016b0cc9eSSimon Atanasyan bool IsUnderSysroot; 771f7c5fbb1SRui Ueyama }; 772f7c5fbb1SRui Ueyama 77320b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 77495769b4aSRui Ueyama readVersionScriptCommand(); 77520b6598cSGeorge Rimar if (!atEOF()) 77695769b4aSRui Ueyama setError("EOF expected, but got " + next()); 77795769b4aSRui Ueyama } 77895769b4aSRui Ueyama 77995769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 78095769b4aSRui Ueyama if (skip("{")) { 78195769b4aSRui Ueyama readVersionDeclaration(""); 78220b6598cSGeorge Rimar return; 78320b6598cSGeorge Rimar } 78420b6598cSGeorge Rimar 78595769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 78620b6598cSGeorge Rimar StringRef VerStr = next(); 78720b6598cSGeorge Rimar if (VerStr == "{") { 78895769b4aSRui Ueyama setError("anonymous version definition is used in " 78995769b4aSRui Ueyama "combination with other version definitions"); 79020b6598cSGeorge Rimar return; 79120b6598cSGeorge Rimar } 79220b6598cSGeorge Rimar expect("{"); 79395769b4aSRui Ueyama readVersionDeclaration(VerStr); 79420b6598cSGeorge Rimar } 79520b6598cSGeorge Rimar } 79620b6598cSGeorge Rimar 79795769b4aSRui Ueyama void ScriptParser::readVersion() { 79895769b4aSRui Ueyama expect("{"); 79995769b4aSRui Ueyama readVersionScriptCommand(); 80095769b4aSRui Ueyama expect("}"); 80195769b4aSRui Ueyama } 80295769b4aSRui Ueyama 80320b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 804f7c5fbb1SRui Ueyama while (!atEOF()) { 805f7c5fbb1SRui Ueyama StringRef Tok = next(); 806a27eeccaSRui Ueyama if (Tok == ";") 807a27eeccaSRui Ueyama continue; 808a27eeccaSRui Ueyama 80920d03194SEugene Leviant if (Tok == "ASSERT") { 81020d03194SEugene Leviant Opt.Commands.emplace_back(new AssertCommand(readAssert())); 81120d03194SEugene Leviant } else if (Tok == "ENTRY") { 812a27eeccaSRui Ueyama readEntry(); 813a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 814a27eeccaSRui Ueyama readExtern(); 815a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 816a27eeccaSRui Ueyama readGroup(); 817a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 818a27eeccaSRui Ueyama readInclude(); 819a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 820a27eeccaSRui Ueyama readOutput(); 821a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 822a27eeccaSRui Ueyama readOutputArch(); 823a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 824a27eeccaSRui Ueyama readOutputFormat(); 825a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 826a27eeccaSRui Ueyama readPhdrs(); 827a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 828a27eeccaSRui Ueyama readSearchDir(); 829a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 830a27eeccaSRui Ueyama readSections(); 831a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 832a27eeccaSRui Ueyama readVersion(); 833db741e72SEugene Leviant } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok, true)) { 8340df80befSPetr Hosek Opt.Commands.emplace_back(Cmd); 835e5d3ca50SPetr Hosek } else { 8365761042dSGeorge Rimar setError("unknown directive: " + Tok); 837f7c5fbb1SRui Ueyama } 838f7c5fbb1SRui Ueyama } 839e5d3ca50SPetr Hosek } 840f7c5fbb1SRui Ueyama 841717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 84216b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 84316b0cc9eSSimon Atanasyan SmallString<128> Path; 84416b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 84516b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 84616b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 84716b0cc9eSSimon Atanasyan return; 84816b0cc9eSSimon Atanasyan } 84916b0cc9eSSimon Atanasyan } 85016b0cc9eSSimon Atanasyan 851f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 85252a1509eSRui Ueyama Driver->addFile(S); 85352a1509eSRui Ueyama } else if (S.startswith("=")) { 85452a1509eSRui Ueyama if (Config->Sysroot.empty()) 85552a1509eSRui Ueyama Driver->addFile(S.substr(1)); 85652a1509eSRui Ueyama else 85752a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 85852a1509eSRui Ueyama } else if (S.startswith("-l")) { 85921eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 860a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 861a1b8fc3bSSimon Atanasyan Driver->addFile(S); 86252a1509eSRui Ueyama } else { 86352a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 86452a1509eSRui Ueyama if (Path.empty()) 865777f9630SGeorge Rimar setError("unable to find " + S); 866025d59b1SRui Ueyama else 86752a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 86852a1509eSRui Ueyama } 86952a1509eSRui Ueyama } 87052a1509eSRui Ueyama 871717677afSRui Ueyama void ScriptParser::readAsNeeded() { 872f7c5fbb1SRui Ueyama expect("("); 87335da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 87435da9b6eSRui Ueyama Config->AsNeeded = true; 875a2acc931SRui Ueyama while (!Error && !skip(")")) 876cd574a5eSGeorge Rimar addFile(unquote(next())); 87735da9b6eSRui Ueyama Config->AsNeeded = Orig; 878f7c5fbb1SRui Ueyama } 879f7c5fbb1SRui Ueyama 880717677afSRui Ueyama void ScriptParser::readEntry() { 88190c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 88290c5099eSDenis Protivensky expect("("); 88390c5099eSDenis Protivensky StringRef Tok = next(); 88490c5099eSDenis Protivensky if (Config->Entry.empty()) 88590c5099eSDenis Protivensky Config->Entry = Tok; 88690c5099eSDenis Protivensky expect(")"); 88790c5099eSDenis Protivensky } 88890c5099eSDenis Protivensky 889717677afSRui Ueyama void ScriptParser::readExtern() { 89083f406cfSGeorge Rimar expect("("); 891a2acc931SRui Ueyama while (!Error && !skip(")")) 892a2acc931SRui Ueyama Config->Undefined.push_back(next()); 89383f406cfSGeorge Rimar } 89483f406cfSGeorge Rimar 895717677afSRui Ueyama void ScriptParser::readGroup() { 896f7c5fbb1SRui Ueyama expect("("); 897a2acc931SRui Ueyama while (!Error && !skip(")")) { 898f7c5fbb1SRui Ueyama StringRef Tok = next(); 899a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 900f7c5fbb1SRui Ueyama readAsNeeded(); 901a2acc931SRui Ueyama else 902cd574a5eSGeorge Rimar addFile(unquote(Tok)); 903f7c5fbb1SRui Ueyama } 904f7c5fbb1SRui Ueyama } 905f7c5fbb1SRui Ueyama 906717677afSRui Ueyama void ScriptParser::readInclude() { 90731aa1f83SRui Ueyama StringRef Tok = next(); 908cd574a5eSGeorge Rimar auto MBOrErr = MemoryBuffer::getFile(unquote(Tok)); 909025d59b1SRui Ueyama if (!MBOrErr) { 9105761042dSGeorge Rimar setError("cannot open " + Tok); 911025d59b1SRui Ueyama return; 912025d59b1SRui Ueyama } 91331aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 914a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 915a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 91631aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 91731aa1f83SRui Ueyama } 91831aa1f83SRui Ueyama 919717677afSRui Ueyama void ScriptParser::readOutput() { 920ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 921ee59282bSRui Ueyama expect("("); 922ee59282bSRui Ueyama StringRef Tok = next(); 923ee59282bSRui Ueyama if (Config->OutputFile.empty()) 924cd574a5eSGeorge Rimar Config->OutputFile = unquote(Tok); 925ee59282bSRui Ueyama expect(")"); 926ee59282bSRui Ueyama } 927ee59282bSRui Ueyama 928717677afSRui Ueyama void ScriptParser::readOutputArch() { 9299159ce93SDavide Italiano // Error checking only for now. 9309159ce93SDavide Italiano expect("("); 9319159ce93SDavide Italiano next(); 9329159ce93SDavide Italiano expect(")"); 9339159ce93SDavide Italiano } 9349159ce93SDavide Italiano 935717677afSRui Ueyama void ScriptParser::readOutputFormat() { 936f7c5fbb1SRui Ueyama // Error checking only for now. 937f7c5fbb1SRui Ueyama expect("("); 938f7c5fbb1SRui Ueyama next(); 9396836c618SDavide Italiano StringRef Tok = next(); 9406836c618SDavide Italiano if (Tok == ")") 9416836c618SDavide Italiano return; 942025d59b1SRui Ueyama if (Tok != ",") { 9435761042dSGeorge Rimar setError("unexpected token: " + Tok); 944025d59b1SRui Ueyama return; 945025d59b1SRui Ueyama } 9466836c618SDavide Italiano next(); 9476836c618SDavide Italiano expect(","); 9486836c618SDavide Italiano next(); 949f7c5fbb1SRui Ueyama expect(")"); 950f7c5fbb1SRui Ueyama } 951f7c5fbb1SRui Ueyama 952bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 953bbe38602SEugene Leviant expect("{"); 954bbe38602SEugene Leviant while (!Error && !skip("}")) { 955bbe38602SEugene Leviant StringRef Tok = next(); 95656b21c86SEugene Leviant Opt.PhdrsCommands.push_back( 95756b21c86SEugene Leviant {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 958bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 959bbe38602SEugene Leviant 960bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 961bbe38602SEugene Leviant do { 962bbe38602SEugene Leviant Tok = next(); 963bbe38602SEugene Leviant if (Tok == ";") 964bbe38602SEugene Leviant break; 965bbe38602SEugene Leviant if (Tok == "FILEHDR") 966bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 967bbe38602SEugene Leviant else if (Tok == "PHDRS") 968bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 96956b21c86SEugene Leviant else if (Tok == "AT") 97056b21c86SEugene Leviant PhdrCmd.LMAExpr = readParenExpr(); 971865bf863SEugene Leviant else if (Tok == "FLAGS") { 972865bf863SEugene Leviant expect("("); 973eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 974eb685cd7SRafael Espindola // we accept expressions like ".|1". 975eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 976865bf863SEugene Leviant expect(")"); 977865bf863SEugene Leviant } else 978bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 979bbe38602SEugene Leviant } while (!Error); 980bbe38602SEugene Leviant } 981bbe38602SEugene Leviant } 982bbe38602SEugene Leviant 983717677afSRui Ueyama void ScriptParser::readSearchDir() { 98468a39a65SDavide Italiano expect("("); 98586c5fb82SRui Ueyama StringRef Tok = next(); 9866c7ad13fSRui Ueyama if (!Config->Nostdlib) 987cd574a5eSGeorge Rimar Config->SearchPaths.push_back(unquote(Tok)); 98868a39a65SDavide Italiano expect(")"); 98968a39a65SDavide Italiano } 99068a39a65SDavide Italiano 991717677afSRui Ueyama void ScriptParser::readSections() { 992e05336ffSEugene Leviant Opt.HasSections = true; 9938e3b38abSDenis Protivensky expect("{"); 994652852c5SGeorge Rimar while (!Error && !skip("}")) { 995113cdec9SRui Ueyama StringRef Tok = next(); 996db741e72SEugene Leviant BaseCommand *Cmd = readProvideOrAssignment(Tok, true); 997ceabe80eSEugene Leviant if (!Cmd) { 998ceabe80eSEugene Leviant if (Tok == "ASSERT") 999eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 1000ceabe80eSEugene Leviant else 100110416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 10028e3b38abSDenis Protivensky } 100310416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 1004652852c5SGeorge Rimar } 1005708019c4SRui Ueyama } 10068e3b38abSDenis Protivensky 1007708019c4SRui Ueyama static int precedence(StringRef Op) { 1008708019c4SRui Ueyama return StringSwitch<int>(Op) 1009708019c4SRui Ueyama .Case("*", 4) 1010708019c4SRui Ueyama .Case("/", 4) 1011708019c4SRui Ueyama .Case("+", 3) 1012708019c4SRui Ueyama .Case("-", 3) 1013708019c4SRui Ueyama .Case("<", 2) 1014708019c4SRui Ueyama .Case(">", 2) 1015708019c4SRui Ueyama .Case(">=", 2) 1016708019c4SRui Ueyama .Case("<=", 2) 1017708019c4SRui Ueyama .Case("==", 2) 1018708019c4SRui Ueyama .Case("!=", 2) 1019708019c4SRui Ueyama .Case("&", 1) 1020cc3dd629SRafael Espindola .Case("|", 1) 1021708019c4SRui Ueyama .Default(-1); 1022708019c4SRui Ueyama } 1023708019c4SRui Ueyama 1024c91930a1SGeorge Rimar Regex ScriptParser::readFilePatterns() { 102510416564SRui Ueyama std::vector<StringRef> V; 102610416564SRui Ueyama while (!Error && !skip(")")) 102710416564SRui Ueyama V.push_back(next()); 1028c91930a1SGeorge Rimar return compileGlobPatterns(V); 10290702c4e8SGeorge Rimar } 10300702c4e8SGeorge Rimar 1031be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() { 1032742c3836SRui Ueyama if (skip("SORT") || skip("SORT_BY_NAME")) 1033be394db3SGeorge Rimar return SortSectionPolicy::Name; 1034742c3836SRui Ueyama if (skip("SORT_BY_ALIGNMENT")) 1035be394db3SGeorge Rimar return SortSectionPolicy::Alignment; 1036575208caSGeorge Rimar if (skip("SORT_BY_INIT_PRIORITY")) 1037be394db3SGeorge Rimar return SortSectionPolicy::Priority; 1038be394db3SGeorge Rimar if (skip("SORT_NONE")) 1039be394db3SGeorge Rimar return SortSectionPolicy::None; 1040b2a0abdfSRui Ueyama return SortSectionPolicy::Default; 1041be394db3SGeorge Rimar } 1042be394db3SGeorge Rimar 1043be394db3SGeorge Rimar static void selectSortKind(InputSectionDescription *Cmd) { 1044b2a0abdfSRui Ueyama if (Cmd->SortOuter == SortSectionPolicy::None) { 1045b2a0abdfSRui Ueyama Cmd->SortOuter = SortSectionPolicy::Default; 1046be394db3SGeorge Rimar return; 1047be394db3SGeorge Rimar } 1048be394db3SGeorge Rimar 1049b2a0abdfSRui Ueyama if (Cmd->SortOuter != SortSectionPolicy::Default) { 1050be394db3SGeorge Rimar // If the section sorting command in linker script is nested, the command 1051be394db3SGeorge Rimar // line option will be ignored. 1052b2a0abdfSRui Ueyama if (Cmd->SortInner != SortSectionPolicy::Default) 1053be394db3SGeorge Rimar return; 1054be394db3SGeorge Rimar // If the section sorting command in linker script isn't nested, the 1055be394db3SGeorge Rimar // command line option will make the section sorting command to be treated 1056be394db3SGeorge Rimar // as nested sorting command. 1057be394db3SGeorge Rimar Cmd->SortInner = Config->SortSection; 1058be394db3SGeorge Rimar return; 1059be394db3SGeorge Rimar } 1060be394db3SGeorge Rimar // If sorting rule not specified, use command line option. 1061be394db3SGeorge Rimar Cmd->SortOuter = Config->SortSection; 1062742c3836SRui Ueyama } 1063742c3836SRui Ueyama 1064395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in 1065395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ 1066395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) 1067395281cfSGeorge Rimar void ScriptParser::readSectionExcludes(InputSectionDescription *Cmd) { 1068027a9e87SRui Ueyama Regex ExcludeFileRe; 1069395281cfSGeorge Rimar std::vector<StringRef> V; 1070395281cfSGeorge Rimar 1071395281cfSGeorge Rimar while (!Error) { 1072395281cfSGeorge Rimar if (skip(")")) { 1073*4dc07becSRui Ueyama Cmd->SectionPatterns.push_back( 1074395281cfSGeorge Rimar {std::move(ExcludeFileRe), compileGlobPatterns(V)}); 1075395281cfSGeorge Rimar return; 1076395281cfSGeorge Rimar } 1077395281cfSGeorge Rimar 1078395281cfSGeorge Rimar if (skip("EXCLUDE_FILE")) { 1079395281cfSGeorge Rimar if (!V.empty()) { 1080*4dc07becSRui Ueyama Cmd->SectionPatterns.push_back( 1081395281cfSGeorge Rimar {std::move(ExcludeFileRe), compileGlobPatterns(V)}); 1082395281cfSGeorge Rimar V.clear(); 1083395281cfSGeorge Rimar } 1084395281cfSGeorge Rimar 1085395281cfSGeorge Rimar expect("("); 1086395281cfSGeorge Rimar ExcludeFileRe = readFilePatterns(); 1087395281cfSGeorge Rimar continue; 1088395281cfSGeorge Rimar } 1089395281cfSGeorge Rimar 1090395281cfSGeorge Rimar V.push_back(next()); 1091395281cfSGeorge Rimar } 1092395281cfSGeorge Rimar } 1093395281cfSGeorge Rimar 1094a2496cbeSGeorge Rimar InputSectionDescription * 1095a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 1096c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 10970ed42b0cSDavide Italiano expect("("); 1098e7282797SDavide Italiano 1099742c3836SRui Ueyama // Read SORT(). 1100be394db3SGeorge Rimar SortSectionPolicy K1 = readSortKind(); 1101b2a0abdfSRui Ueyama if (K1 != SortSectionPolicy::Default) { 1102742c3836SRui Ueyama Cmd->SortOuter = K1; 11030702c4e8SGeorge Rimar expect("("); 1104be394db3SGeorge Rimar SortSectionPolicy K2 = readSortKind(); 1105b2a0abdfSRui Ueyama if (K2 != SortSectionPolicy::Default) { 1106742c3836SRui Ueyama Cmd->SortInner = K2; 1107350ece4eSGeorge Rimar expect("("); 1108*4dc07becSRui Ueyama Cmd->SectionPatterns.push_back({Regex(), readFilePatterns()}); 11090702c4e8SGeorge Rimar expect(")"); 1110350ece4eSGeorge Rimar } else { 1111*4dc07becSRui Ueyama Cmd->SectionPatterns.push_back({Regex(), readFilePatterns()}); 1112350ece4eSGeorge Rimar } 1113350ece4eSGeorge Rimar expect(")"); 1114be394db3SGeorge Rimar selectSortKind(Cmd); 111510416564SRui Ueyama return Cmd; 11160659800eSGeorge Rimar } 11170702c4e8SGeorge Rimar 1118be394db3SGeorge Rimar selectSortKind(Cmd); 1119395281cfSGeorge Rimar readSectionExcludes(Cmd); 112010416564SRui Ueyama return Cmd; 11210659800eSGeorge Rimar } 11220659800eSGeorge Rimar 1123a2496cbeSGeorge Rimar InputSectionDescription * 1124a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 11250659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 11260659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 1127a2496cbeSGeorge Rimar if (Tok == "KEEP") { 1128e7282797SDavide Italiano expect("("); 1129a2496cbeSGeorge Rimar StringRef FilePattern = next(); 1130a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 11310ed42b0cSDavide Italiano expect(")"); 1132*4dc07becSRui Ueyama for (SectionPattern &Pat : Cmd->SectionPatterns) 1133*4dc07becSRui Ueyama Opt.KeptSections.push_back(&Pat.SectionRe); 113410416564SRui Ueyama return Cmd; 113510416564SRui Ueyama } 1136a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 11370659800eSGeorge Rimar } 11380659800eSGeorge Rimar 113903fc010eSGeorge Rimar void ScriptParser::readSort() { 114003fc010eSGeorge Rimar expect("("); 114103fc010eSGeorge Rimar expect("CONSTRUCTORS"); 114203fc010eSGeorge Rimar expect(")"); 114303fc010eSGeorge Rimar } 114403fc010eSGeorge Rimar 1145eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 1146eefa758eSGeorge Rimar expect("("); 1147eefa758eSGeorge Rimar Expr E = readExpr(); 1148eefa758eSGeorge Rimar expect(","); 1149cd574a5eSGeorge Rimar StringRef Msg = unquote(next()); 1150eefa758eSGeorge Rimar expect(")"); 1151eefa758eSGeorge Rimar return [=](uint64_t Dot) { 1152eefa758eSGeorge Rimar uint64_t V = E(Dot); 1153eefa758eSGeorge Rimar if (!V) 1154eefa758eSGeorge Rimar error(Msg); 1155eefa758eSGeorge Rimar return V; 1156eefa758eSGeorge Rimar }; 1157eefa758eSGeorge Rimar } 1158eefa758eSGeorge Rimar 115925150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 116025150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from 116125150e8bSRui Ueyama // what GNU linkers do. 116225150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 1163ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readFill() { 1164ff1f29e0SGeorge Rimar expect("("); 1165ff1f29e0SGeorge Rimar std::vector<uint8_t> V = readOutputSectionFiller(next()); 1166ff1f29e0SGeorge Rimar expect(")"); 1167ff1f29e0SGeorge Rimar expect(";"); 1168ff1f29e0SGeorge Rimar return V; 1169ff1f29e0SGeorge Rimar } 1170ff1f29e0SGeorge Rimar 117110416564SRui Ueyama OutputSectionCommand * 117210416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 1173076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 117458e5c4dcSGeorge Rimar 117558e5c4dcSGeorge Rimar // Read an address expression. 117658e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 117758e5c4dcSGeorge Rimar if (peek() != ":") 117858e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 117958e5c4dcSGeorge Rimar 11808e3b38abSDenis Protivensky expect(":"); 1181246f681eSDavide Italiano 11828ceadb38SGeorge Rimar if (skip("AT")) 11836ad7dfccSRui Ueyama Cmd->LmaExpr = readParenExpr(); 1184630c6179SGeorge Rimar if (skip("ALIGN")) 11856ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 1186db24d9c3SGeorge Rimar if (skip("SUBALIGN")) 1187db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1188630c6179SGeorge Rimar 1189246f681eSDavide Italiano // Parse constraints. 1190246f681eSDavide Italiano if (skip("ONLY_IF_RO")) 1191efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 1192246f681eSDavide Italiano if (skip("ONLY_IF_RW")) 1193efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 11948e3b38abSDenis Protivensky expect("{"); 11958ec77e64SRui Ueyama 1196025d59b1SRui Ueyama while (!Error && !skip("}")) { 1197ceabe80eSEugene Leviant StringRef Tok = next(); 1198db741e72SEugene Leviant if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok, false)) 1199ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1200ff1f29e0SGeorge Rimar else if (Tok == "FILL") 1201ff1f29e0SGeorge Rimar Cmd->Filler = readFill(); 1202ceabe80eSEugene Leviant else if (Tok == "SORT") 120303fc010eSGeorge Rimar readSort(); 1204a2496cbeSGeorge Rimar else if (peek() == "(") 1205a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1206ceabe80eSEugene Leviant else 1207ceabe80eSEugene Leviant setError("unknown command " + Tok); 12088e3b38abSDenis Protivensky } 1209076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 1210ff1f29e0SGeorge Rimar if (peek().startswith("=")) 1211ff1f29e0SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next().drop_front()); 121210416564SRui Ueyama return Cmd; 1213f71caa2bSRui Ueyama } 12148ec77e64SRui Ueyama 12152c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 12162c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 12172c8f1f04SRui Ueyama // 12182c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 12192c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 12202c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 12212c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 1222ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readOutputSectionFiller(StringRef Tok) { 1223965827d6SRui Ueyama uint32_t V; 1224ff1f29e0SGeorge Rimar if (Tok.getAsInteger(0, V)) { 1225965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 1226f71caa2bSRui Ueyama return {}; 1227e2ee72b5SGeorge Rimar } 1228965827d6SRui Ueyama return {uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V)}; 12298e3b38abSDenis Protivensky } 12308e3b38abSDenis Protivensky 1231a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1232a31c91b1SEugene Leviant expect("("); 1233174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1234a35e39caSPetr Hosek Cmd->Provide = Provide; 1235174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1236a31c91b1SEugene Leviant expect(")"); 1237a31c91b1SEugene Leviant expect(";"); 123810416564SRui Ueyama return Cmd; 1239eda81a1bSEugene Leviant } 1240eda81a1bSEugene Leviant 1241db741e72SEugene Leviant SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok, 1242db741e72SEugene Leviant bool MakeAbsolute) { 1243ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1244ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1245ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1246ceabe80eSEugene Leviant expect(";"); 1247ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1248a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1249a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1250a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1251ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1252a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1253ceabe80eSEugene Leviant } 1254db741e72SEugene Leviant if (Cmd && MakeAbsolute) 1255db741e72SEugene Leviant Cmd->IsAbsolute = true; 1256ceabe80eSEugene Leviant return Cmd; 1257ceabe80eSEugene Leviant } 1258ceabe80eSEugene Leviant 125930835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { 126030835ea4SGeorge Rimar if (S == ".") 126130835ea4SGeorge Rimar return Dot; 1262884e786dSGeorge Rimar return ScriptBase->getSymbolValue(S); 1263e32a3598SGeorge Rimar } 1264e32a3598SGeorge Rimar 126530835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 126630835ea4SGeorge Rimar StringRef Op = next(); 1267db741e72SEugene Leviant bool IsAbsolute = false; 1268db741e72SEugene Leviant Expr E; 126930835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 1270db741e72SEugene Leviant if (skip("ABSOLUTE")) { 1271db741e72SEugene Leviant E = readParenExpr(); 1272db741e72SEugene Leviant IsAbsolute = true; 1273db741e72SEugene Leviant } else { 1274db741e72SEugene Leviant E = readExpr(); 1275db741e72SEugene Leviant } 127630835ea4SGeorge Rimar if (Op == "+=") 127730835ea4SGeorge Rimar E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; 1278db741e72SEugene Leviant return new SymbolAssignment(Name, E, IsAbsolute); 127930835ea4SGeorge Rimar } 128030835ea4SGeorge Rimar 128130835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 128230835ea4SGeorge Rimar // script expression. 128330835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 128430835ea4SGeorge Rimar 128536c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 128636c1cd23SRui Ueyama if (Op == "*") 128736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 128836c1cd23SRui Ueyama if (Op == "/") { 128936c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 129036c1cd23SRui Ueyama uint64_t RHS = R(Dot); 129136c1cd23SRui Ueyama if (RHS == 0) { 129236c1cd23SRui Ueyama error("division by zero"); 129336c1cd23SRui Ueyama return 0; 129436c1cd23SRui Ueyama } 129536c1cd23SRui Ueyama return L(Dot) / RHS; 129636c1cd23SRui Ueyama }; 129736c1cd23SRui Ueyama } 129836c1cd23SRui Ueyama if (Op == "+") 129936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) + R(Dot); }; 130036c1cd23SRui Ueyama if (Op == "-") 130136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 130236c1cd23SRui Ueyama if (Op == "<") 130336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 130436c1cd23SRui Ueyama if (Op == ">") 130536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 130636c1cd23SRui Ueyama if (Op == ">=") 130736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 130836c1cd23SRui Ueyama if (Op == "<=") 130936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 131036c1cd23SRui Ueyama if (Op == "==") 131136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 131236c1cd23SRui Ueyama if (Op == "!=") 131336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 131436c1cd23SRui Ueyama if (Op == "&") 131536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 1316cc3dd629SRafael Espindola if (Op == "|") 1317cc3dd629SRafael Espindola return [=](uint64_t Dot) { return L(Dot) | R(Dot); }; 131836c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 131936c1cd23SRui Ueyama } 132036c1cd23SRui Ueyama 1321708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1322708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1323708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1324708019c4SRui Ueyama while (!atEOF() && !Error) { 1325708019c4SRui Ueyama // Read an operator and an expression. 1326708019c4SRui Ueyama StringRef Op1 = peek(); 1327708019c4SRui Ueyama if (Op1 == "?") 1328708019c4SRui Ueyama return readTernary(Lhs); 1329708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1330a31c91b1SEugene Leviant break; 1331a31c91b1SEugene Leviant next(); 1332708019c4SRui Ueyama Expr Rhs = readPrimary(); 1333708019c4SRui Ueyama 1334708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1335708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1336708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1337708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1338708019c4SRui Ueyama while (!atEOF()) { 1339708019c4SRui Ueyama StringRef Op2 = peek(); 1340708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1341eda81a1bSEugene Leviant break; 1342708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1343eda81a1bSEugene Leviant } 1344708019c4SRui Ueyama 1345708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1346708019c4SRui Ueyama } 1347708019c4SRui Ueyama return Lhs; 1348708019c4SRui Ueyama } 1349708019c4SRui Ueyama 1350708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1351e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1352708019c4SRui Ueyama return Target->PageSize; 1353e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1354e2cc07bcSMichael J. Spencer return Target->MaxPageSize; 1355708019c4SRui Ueyama error("unknown constant: " + S); 1356708019c4SRui Ueyama return 0; 1357708019c4SRui Ueyama } 1358708019c4SRui Ueyama 1359626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1360626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1361626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1362626e0b08SRui Ueyama // "M" (mega) prefixes. 13639f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 1364eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1365eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1366eaeafb2bSSimon Atanasyan return false; 1367eaeafb2bSSimon Atanasyan Result = -Result; 1368eaeafb2bSSimon Atanasyan return true; 1369eaeafb2bSSimon Atanasyan } 13709f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 13719f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 13729f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 13739f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 13749f2f7ad9SGeorge Rimar 13759f2f7ad9SGeorge Rimar int Suffix = 1; 13769f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 13779f2f7ad9SGeorge Rimar Suffix = 1024; 13789f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 13799f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 13809f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 13819f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 13829f2f7ad9SGeorge Rimar } 13839f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 13849f2f7ad9SGeorge Rimar return false; 13859f2f7ad9SGeorge Rimar Result *= Suffix; 13869f2f7ad9SGeorge Rimar return true; 13879f2f7ad9SGeorge Rimar } 13889f2f7ad9SGeorge Rimar 1389708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 13906ad7dfccSRui Ueyama if (peek() == "(") 13916ad7dfccSRui Ueyama return readParenExpr(); 1392708019c4SRui Ueyama 13936ad7dfccSRui Ueyama StringRef Tok = next(); 1394708019c4SRui Ueyama 1395eaeafb2bSSimon Atanasyan if (Tok == "~") { 1396eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1397eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return ~E(Dot); }; 1398eaeafb2bSSimon Atanasyan } 1399eaeafb2bSSimon Atanasyan if (Tok == "-") { 1400eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1401eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return -E(Dot); }; 1402eaeafb2bSSimon Atanasyan } 1403eaeafb2bSSimon Atanasyan 1404708019c4SRui Ueyama // Built-in functions are parsed here. 1405708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 140696659df0SGeorge Rimar if (Tok == "ADDR") { 140796659df0SGeorge Rimar expect("("); 140896659df0SGeorge Rimar StringRef Name = next(); 140996659df0SGeorge Rimar expect(")"); 1410884e786dSGeorge Rimar return 1411884e786dSGeorge Rimar [=](uint64_t Dot) { return ScriptBase->getOutputSectionAddress(Name); }; 141296659df0SGeorge Rimar } 1413eefa758eSGeorge Rimar if (Tok == "ASSERT") 1414eefa758eSGeorge Rimar return readAssert(); 1415708019c4SRui Ueyama if (Tok == "ALIGN") { 14166ad7dfccSRui Ueyama Expr E = readParenExpr(); 1417708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1418708019c4SRui Ueyama } 1419708019c4SRui Ueyama if (Tok == "CONSTANT") { 1420708019c4SRui Ueyama expect("("); 1421708019c4SRui Ueyama StringRef Tok = next(); 1422708019c4SRui Ueyama expect(")"); 1423708019c4SRui Ueyama return [=](uint64_t Dot) { return getConstant(Tok); }; 1424708019c4SRui Ueyama } 142554c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 142654c145ceSRafael Espindola expect("("); 142754c145ceSRafael Espindola next(); 142854c145ceSRafael Espindola expect(","); 142954c145ceSRafael Espindola uint64_t Val; 14303adbbc38SRafael Espindola if (next().getAsInteger(0, Val)) 14313adbbc38SRafael Espindola setError("integer expected"); 143254c145ceSRafael Espindola expect(")"); 143354c145ceSRafael Espindola return [=](uint64_t Dot) { return Val; }; 143454c145ceSRafael Espindola } 1435708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1436708019c4SRui Ueyama expect("("); 1437708019c4SRui Ueyama Expr E = readExpr(); 1438708019c4SRui Ueyama expect(","); 1439708019c4SRui Ueyama readExpr(); 1440708019c4SRui Ueyama expect(")"); 1441f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1442708019c4SRui Ueyama } 1443708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1444708019c4SRui Ueyama expect("("); 1445708019c4SRui Ueyama expect("."); 1446708019c4SRui Ueyama expect(")"); 1447708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1448708019c4SRui Ueyama } 1449276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1450276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1451276b4e64SGeorge Rimar // the next page boundary for simplicity. 1452276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1453276b4e64SGeorge Rimar expect("("); 145497bdc722SRafael Espindola readExpr(); 1455276b4e64SGeorge Rimar expect(","); 1456276b4e64SGeorge Rimar readExpr(); 1457276b4e64SGeorge Rimar expect(")"); 1458276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1459276b4e64SGeorge Rimar } 14609e69450eSGeorge Rimar if (Tok == "SIZEOF") { 14619e69450eSGeorge Rimar expect("("); 14629e69450eSGeorge Rimar StringRef Name = next(); 14639e69450eSGeorge Rimar expect(")"); 1464884e786dSGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; 14659e69450eSGeorge Rimar } 146636fac7f0SEugene Leviant if (Tok == "ALIGNOF") { 146736fac7f0SEugene Leviant expect("("); 146836fac7f0SEugene Leviant StringRef Name = next(); 146936fac7f0SEugene Leviant expect(")"); 147036fac7f0SEugene Leviant return 147136fac7f0SEugene Leviant [=](uint64_t Dot) { return ScriptBase->getOutputSectionAlign(Name); }; 147236fac7f0SEugene Leviant } 1473e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 1474884e786dSGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; 1475708019c4SRui Ueyama 14769f2f7ad9SGeorge Rimar // Tok is a literal number. 14779f2f7ad9SGeorge Rimar uint64_t V; 14789f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 14799f2f7ad9SGeorge Rimar return [=](uint64_t Dot) { return V; }; 14809f2f7ad9SGeorge Rimar 14819f2f7ad9SGeorge Rimar // Tok is a symbol name. 148230835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1483708019c4SRui Ueyama setError("malformed number: " + Tok); 148430835ea4SGeorge Rimar return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }; 1485a9c5a528SGeorge Rimar } 1486708019c4SRui Ueyama 1487708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1488708019c4SRui Ueyama next(); 1489708019c4SRui Ueyama Expr L = readExpr(); 1490708019c4SRui Ueyama expect(":"); 1491708019c4SRui Ueyama Expr R = readExpr(); 1492708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1493708019c4SRui Ueyama } 1494708019c4SRui Ueyama 14956ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 14966ad7dfccSRui Ueyama expect("("); 14976ad7dfccSRui Ueyama Expr E = readExpr(); 14986ad7dfccSRui Ueyama expect(")"); 14996ad7dfccSRui Ueyama return E; 15006ad7dfccSRui Ueyama } 15016ad7dfccSRui Ueyama 1502bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1503bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1504bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1505bbe38602SEugene Leviant StringRef Tok = next(); 1506bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 1507bbe38602SEugene Leviant if (Tok.empty()) { 1508bbe38602SEugene Leviant setError("section header name is empty"); 1509bbe38602SEugene Leviant break; 1510bbe38602SEugene Leviant } 1511bbe38602SEugene Leviant Phdrs.push_back(Tok); 1512bbe38602SEugene Leviant } 1513bbe38602SEugene Leviant return Phdrs; 1514bbe38602SEugene Leviant } 1515bbe38602SEugene Leviant 1516bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1517bbe38602SEugene Leviant StringRef Tok = next(); 1518b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1519b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1520b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1521b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1522b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1523b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1524b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1525b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1526b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1527b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1528b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1529b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1530b0f6c590SRui Ueyama .Default(-1); 1531bbe38602SEugene Leviant 1532b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1533b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1534b0f6c590SRui Ueyama return PT_NULL; 1535b0f6c590SRui Ueyama } 1536b0f6c590SRui Ueyama return Ret; 1537bbe38602SEugene Leviant } 1538bbe38602SEugene Leviant 153995769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 154020b6598cSGeorge Rimar // Identifiers start at 2 because 0 and 1 are reserved 154120b6598cSGeorge Rimar // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. 154220b6598cSGeorge Rimar size_t VersionId = Config->VersionDefinitions.size() + 2; 154320b6598cSGeorge Rimar Config->VersionDefinitions.push_back({VerStr, VersionId}); 154420b6598cSGeorge Rimar 154520b6598cSGeorge Rimar if (skip("global:") || peek() != "local:") 154620b6598cSGeorge Rimar readGlobal(VerStr); 154720b6598cSGeorge Rimar if (skip("local:")) 154820b6598cSGeorge Rimar readLocal(); 154920b6598cSGeorge Rimar expect("}"); 155020b6598cSGeorge Rimar 155120b6598cSGeorge Rimar // Each version may have a parent version. For example, "Ver2" defined as 155220b6598cSGeorge Rimar // "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This 155320b6598cSGeorge Rimar // version hierarchy is, probably against your instinct, purely for human; the 155420b6598cSGeorge Rimar // runtime doesn't care about them at all. In LLD, we simply skip the token. 155520b6598cSGeorge Rimar if (!VerStr.empty() && peek() != ";") 155620b6598cSGeorge Rimar next(); 155720b6598cSGeorge Rimar expect(";"); 155820b6598cSGeorge Rimar } 155920b6598cSGeorge Rimar 156020b6598cSGeorge Rimar void ScriptParser::readLocal() { 156120b6598cSGeorge Rimar Config->DefaultSymbolVersion = VER_NDX_LOCAL; 156220b6598cSGeorge Rimar expect("*"); 156320b6598cSGeorge Rimar expect(";"); 156420b6598cSGeorge Rimar } 156520b6598cSGeorge Rimar 156620b6598cSGeorge Rimar void ScriptParser::readExtern(std::vector<SymbolVersion> *Globals) { 1567cd574a5eSGeorge Rimar expect("\"C++\""); 156820b6598cSGeorge Rimar expect("{"); 156920b6598cSGeorge Rimar 157020b6598cSGeorge Rimar for (;;) { 157120b6598cSGeorge Rimar if (peek() == "}" || Error) 157220b6598cSGeorge Rimar break; 1573cd574a5eSGeorge Rimar bool HasWildcard = !peek().startswith("\"") && hasWildcard(peek()); 1574cd574a5eSGeorge Rimar Globals->push_back({unquote(next()), true, HasWildcard}); 157520b6598cSGeorge Rimar expect(";"); 157620b6598cSGeorge Rimar } 157720b6598cSGeorge Rimar 157820b6598cSGeorge Rimar expect("}"); 157920b6598cSGeorge Rimar expect(";"); 158020b6598cSGeorge Rimar } 158120b6598cSGeorge Rimar 158220b6598cSGeorge Rimar void ScriptParser::readGlobal(StringRef VerStr) { 158320b6598cSGeorge Rimar std::vector<SymbolVersion> *Globals; 158420b6598cSGeorge Rimar if (VerStr.empty()) 158520b6598cSGeorge Rimar Globals = &Config->VersionScriptGlobals; 158620b6598cSGeorge Rimar else 158720b6598cSGeorge Rimar Globals = &Config->VersionDefinitions.back().Globals; 158820b6598cSGeorge Rimar 158920b6598cSGeorge Rimar for (;;) { 159020b6598cSGeorge Rimar if (skip("extern")) 159120b6598cSGeorge Rimar readExtern(Globals); 159220b6598cSGeorge Rimar 159320b6598cSGeorge Rimar StringRef Cur = peek(); 159420b6598cSGeorge Rimar if (Cur == "}" || Cur == "local:" || Error) 159520b6598cSGeorge Rimar return; 159620b6598cSGeorge Rimar next(); 1597cd574a5eSGeorge Rimar Globals->push_back({unquote(Cur), false, hasWildcard(Cur)}); 159820b6598cSGeorge Rimar expect(";"); 159920b6598cSGeorge Rimar } 160020b6598cSGeorge Rimar } 160120b6598cSGeorge Rimar 160216b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 160316b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 160416b0cc9eSSimon Atanasyan return false; 160516b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 160616b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 160716b0cc9eSSimon Atanasyan return true; 160816b0cc9eSSimon Atanasyan return false; 160916b0cc9eSSimon Atanasyan } 161016b0cc9eSSimon Atanasyan 161107320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 161216b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 161320b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).readLinkerScript(); 161420b6598cSGeorge Rimar } 161520b6598cSGeorge Rimar 161620b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 161720b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), false).readVersionScript(); 1618f7c5fbb1SRui Ueyama } 16191ebc8ed7SRui Ueyama 162007320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 162107320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 162207320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 162307320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1624