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" 189381eb10SRui Ueyama #include "Memory.h" 19652852c5SGeorge Rimar #include "OutputSections.h" 20794366a2SRui Ueyama #include "ScriptLexer.h" 2193c9af42SRui Ueyama #include "Strings.h" 22f7c5fbb1SRui Ueyama #include "SymbolTable.h" 2355518e7dSRui Ueyama #include "Symbols.h" 243fb5a6dcSGeorge Rimar #include "SyntheticSections.h" 25467c4d55SEugene Leviant #include "Target.h" 26bbe38602SEugene Leviant #include "Writer.h" 2722886a28SEugene Zelenko #include "llvm/ADT/STLExtras.h" 288c6a5aafSRui Ueyama #include "llvm/ADT/SmallString.h" 2922886a28SEugene Zelenko #include "llvm/ADT/StringRef.h" 30960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 3122886a28SEugene Zelenko #include "llvm/Support/Casting.h" 32652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 3322886a28SEugene Zelenko #include "llvm/Support/Endian.h" 3422886a28SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 35f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 3622886a28SEugene Zelenko #include "llvm/Support/MathExtras.h" 37f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 3822886a28SEugene Zelenko #include <algorithm> 3922886a28SEugene Zelenko #include <cassert> 4022886a28SEugene Zelenko #include <cstddef> 4122886a28SEugene Zelenko #include <cstdint> 4222886a28SEugene Zelenko #include <iterator> 4322886a28SEugene Zelenko #include <limits> 4422886a28SEugene Zelenko #include <memory> 4522886a28SEugene Zelenko #include <string> 4622886a28SEugene Zelenko #include <tuple> 4722886a28SEugene Zelenko #include <vector> 48f7c5fbb1SRui Ueyama 49f7c5fbb1SRui Ueyama using namespace llvm; 50652852c5SGeorge Rimar using namespace llvm::ELF; 511ebc8ed7SRui Ueyama using namespace llvm::object; 52e38cbab5SGeorge Rimar using namespace llvm::support::endian; 53f7c5fbb1SRui Ueyama using namespace lld; 54e0df00b9SRafael Espindola using namespace lld::elf; 55f7c5fbb1SRui Ueyama 56884e786dSGeorge Rimar LinkerScriptBase *elf::ScriptBase; 5707320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 58717677afSRui Ueyama 598f1f3c40SMeador Inge template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) { 603dabfc6bSRafael Espindola uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; 618f1f3c40SMeador Inge Symbol *Sym = Symtab<ELFT>::X->addUndefined( 628f1f3c40SMeador Inge Cmd->Name, /*IsLocal=*/false, STB_GLOBAL, Visibility, 638f1f3c40SMeador Inge /*Type*/ 0, 648f1f3c40SMeador Inge /*CanOmitFromDynSym*/ false, /*File*/ nullptr); 6520d03194SEugene Leviant 668f1f3c40SMeador Inge replaceBody<DefinedRegular<ELFT>>(Sym, Cmd->Name, /*IsLocal=*/false, 678f1f3c40SMeador Inge Visibility, STT_NOTYPE, 0, 0, nullptr, 688f1f3c40SMeador Inge nullptr); 698f1f3c40SMeador Inge return Sym->body(); 70ceabe80eSEugene Leviant } 71ceabe80eSEugene Leviant 728f1f3c40SMeador Inge template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment *Cmd) { 738f1f3c40SMeador Inge uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; 74afaa9343SEugene Leviant const OutputSectionBase *Sec = 75afaa9343SEugene Leviant ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section(); 768f1f3c40SMeador Inge Symbol *Sym = Symtab<ELFT>::X->addUndefined( 778f1f3c40SMeador Inge Cmd->Name, /*IsLocal=*/false, STB_GLOBAL, Visibility, 788f1f3c40SMeador Inge /*Type*/ 0, 798f1f3c40SMeador Inge /*CanOmitFromDynSym*/ false, /*File*/ nullptr); 80afaa9343SEugene Leviant 818f1f3c40SMeador Inge replaceBody<DefinedSynthetic>(Sym, Cmd->Name, 0, Sec); 828f1f3c40SMeador Inge return Sym->body(); 83ceabe80eSEugene Leviant } 84ceabe80eSEugene Leviant 8522375f24SRui Ueyama static bool isUnderSysroot(StringRef Path) { 8622375f24SRui Ueyama if (Config->Sysroot == "") 8722375f24SRui Ueyama return false; 8822375f24SRui Ueyama for (; !Path.empty(); Path = sys::path::parent_path(Path)) 8922375f24SRui Ueyama if (sys::fs::equivalent(Config->Sysroot, Path)) 9022375f24SRui Ueyama return true; 9122375f24SRui Ueyama return false; 9222375f24SRui Ueyama } 9322375f24SRui Ueyama 94679828ffSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::setDot(Expr E, bool InSec) { 95679828ffSRafael Espindola uintX_t Val = E(Dot); 964cd7352cSRafael Espindola if (Val < Dot) { 974cd7352cSRafael Espindola if (InSec) 98679828ffSRafael Espindola error("unable to move location counter backward for: " + CurOutSec->Name); 994cd7352cSRafael Espindola else 1004cd7352cSRafael Espindola error("unable to move location counter backward"); 1014cd7352cSRafael Espindola } 1024cd7352cSRafael Espindola Dot = Val; 1034cd7352cSRafael Espindola // Update to location counter means update to section size. 1044cd7352cSRafael Espindola if (InSec) 1054cd7352cSRafael Espindola CurOutSec->Size = Dot - CurOutSec->Addr; 106679828ffSRafael Espindola } 107679828ffSRafael Espindola 108679828ffSRafael Espindola // Sets value of a symbol. Two kinds of symbols are processed: synthetic 109679828ffSRafael Espindola // symbols, whose value is an offset from beginning of section and regular 110679828ffSRafael Espindola // symbols whose value is absolute. 111679828ffSRafael Espindola template <class ELFT> 112679828ffSRafael Espindola void LinkerScript<ELFT>::assignSymbol(SymbolAssignment *Cmd, bool InSec) { 113679828ffSRafael Espindola if (Cmd->Name == ".") { 114679828ffSRafael Espindola setDot(Cmd->Expression, InSec); 1154cd7352cSRafael Espindola return; 1164cd7352cSRafael Espindola } 1174cd7352cSRafael Espindola 118b2b70975SGeorge Rimar if (!Cmd->Sym) 1198f1f3c40SMeador Inge return; 1208f1f3c40SMeador Inge 121b2b70975SGeorge Rimar if (auto *Body = dyn_cast<DefinedSynthetic>(Cmd->Sym)) { 122b2b70975SGeorge Rimar Body->Section = Cmd->Expression.Section(); 123ea590d91SRafael Espindola if (Body->Section) { 124ea590d91SRafael Espindola uint64_t VA = 0; 125ea590d91SRafael Espindola if (Body->Section->Flags & SHF_ALLOC) 126ea590d91SRafael Espindola VA = Body->Section->Addr; 127ea590d91SRafael Espindola Body->Value = Cmd->Expression(Dot) - VA; 128ea590d91SRafael Espindola } 129b2b70975SGeorge Rimar return; 130db741e72SEugene Leviant } 131b2b70975SGeorge Rimar 132b2b70975SGeorge Rimar cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot); 1338f1f3c40SMeador Inge } 1348f1f3c40SMeador Inge 1354cd7352cSRafael Espindola template <class ELFT> 1364cd7352cSRafael Espindola void LinkerScript<ELFT>::addSymbol(SymbolAssignment *Cmd) { 1371602421cSRui Ueyama if (Cmd->Name == ".") 1388f1f3c40SMeador Inge return; 1398f1f3c40SMeador Inge 1408f1f3c40SMeador Inge // If a symbol was in PROVIDE(), we need to define it only when 1418f1f3c40SMeador Inge // it is a referenced undefined symbol. 1421602421cSRui Ueyama SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 1438f1f3c40SMeador Inge if (Cmd->Provide && (!B || B->isDefined())) 1448f1f3c40SMeador Inge return; 1458f1f3c40SMeador Inge 1468f1f3c40SMeador Inge // Otherwise, create a new symbol if one does not exist or an 1478f1f3c40SMeador Inge // undefined one does exist. 1488f1f3c40SMeador Inge if (Cmd->Expression.IsAbsolute()) 1498f1f3c40SMeador Inge Cmd->Sym = addRegular<ELFT>(Cmd); 1508f1f3c40SMeador Inge else 1518f1f3c40SMeador Inge Cmd->Sym = addSynthetic<ELFT>(Cmd); 152b2b70975SGeorge Rimar 153b2b70975SGeorge Rimar // If there are sections, then let the value be assigned later in 154b2b70975SGeorge Rimar // `assignAddresses`. 155b2b70975SGeorge Rimar if (!ScriptConfig->HasSections) 1564cd7352cSRafael Espindola assignSymbol(Cmd); 157ceabe80eSEugene Leviant } 158ceabe80eSEugene Leviant 159076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 160076fe157SGeorge Rimar return C->Kind == AssignmentKind; 161076fe157SGeorge Rimar } 162076fe157SGeorge Rimar 163076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 164076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 165076fe157SGeorge Rimar } 166076fe157SGeorge Rimar 167eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 168eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 169eea3114fSGeorge Rimar } 170eea3114fSGeorge Rimar 171eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 172eefa758eSGeorge Rimar return C->Kind == AssertKind; 173eefa758eSGeorge Rimar } 174eefa758eSGeorge Rimar 175e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) { 176e38cbab5SGeorge Rimar return C->Kind == BytesDataKind; 177e38cbab5SGeorge Rimar } 178e38cbab5SGeorge Rimar 17922886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::LinkerScript() = default; 18022886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::~LinkerScript() = default; 181f34d0e08SRui Ueyama 182e0be2901SRui Ueyama template <class ELFT> static StringRef basename(InputSectionBase<ELFT> *S) { 183e0be2901SRui Ueyama if (S->getFile()) 184e0be2901SRui Ueyama return sys::path::filename(S->getFile()->getName()); 185e0be2901SRui Ueyama return ""; 186e0be2901SRui Ueyama } 187e0be2901SRui Ueyama 18807320e40SRui Ueyama template <class ELFT> 18907320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 190e0be2901SRui Ueyama for (InputSectionDescription *ID : Opt.KeptSections) 191e0be2901SRui Ueyama if (ID->FilePat.match(basename(S))) 192cf43f179SEugene Leviant for (SectionPattern &P : ID->SectionPatterns) 193f91282e1SRui Ueyama if (P.SectionPat.match(S->Name)) 194eea3114fSGeorge Rimar return true; 195eea3114fSGeorge Rimar return false; 196eea3114fSGeorge Rimar } 197eea3114fSGeorge Rimar 198575208caSGeorge Rimar static bool comparePriority(InputSectionData *A, InputSectionData *B) { 199575208caSGeorge Rimar return getPriority(A->Name) < getPriority(B->Name); 200575208caSGeorge Rimar } 201575208caSGeorge Rimar 202c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) { 203042a3f20SRafael Espindola return A->Name < B->Name; 2040702c4e8SGeorge Rimar } 205742c3836SRui Ueyama 206c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) { 207742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 208742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 209742c3836SRui Ueyama // This is compatible with GNU. 210742c3836SRui Ueyama return A->Alignment > B->Alignment; 211742c3836SRui Ueyama } 212742c3836SRui Ueyama 213c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)> 214be394db3SGeorge Rimar getComparator(SortSectionPolicy K) { 215be394db3SGeorge Rimar switch (K) { 216be394db3SGeorge Rimar case SortSectionPolicy::Alignment: 217c0028d3dSRafael Espindola return compareAlignment; 218be394db3SGeorge Rimar case SortSectionPolicy::Name: 219be394db3SGeorge Rimar return compareName; 220be394db3SGeorge Rimar case SortSectionPolicy::Priority: 221be394db3SGeorge Rimar return comparePriority; 222be394db3SGeorge Rimar default: 223be394db3SGeorge Rimar llvm_unreachable("unknown sort policy"); 224be394db3SGeorge Rimar } 225742c3836SRui Ueyama } 2260702c4e8SGeorge Rimar 22748c3f1ceSRui Ueyama template <class ELFT> 228e71a3f8aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 22906ae6836SGeorge Rimar ConstraintKind Kind) { 2308f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 2318f66df92SGeorge Rimar return true; 232e746e52cSRafael Espindola bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) { 233d3190795SRafael Espindola auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2); 2341854a8ebSRafael Espindola return Sec->Flags & SHF_WRITE; 23506ae6836SGeorge Rimar }); 236e746e52cSRafael Espindola return (IsRW && Kind == ConstraintKind::ReadWrite) || 237e746e52cSRafael Espindola (!IsRW && Kind == ConstraintKind::ReadOnly); 23806ae6836SGeorge Rimar } 23906ae6836SGeorge Rimar 24007171f21SGeorge Rimar static void sortSections(InputSectionData **Begin, InputSectionData **End, 241ee924709SRui Ueyama SortSectionPolicy K) { 242ee924709SRui Ueyama if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None) 24307171f21SGeorge Rimar std::stable_sort(Begin, End, getComparator(K)); 244ee924709SRui Ueyama } 245ee924709SRui Ueyama 246d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches. 247be94e1b6SRafael Espindola template <class ELFT> 248e71a3f8aSRafael Espindola void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) { 2494dc07becSRui Ueyama // Collects all sections that satisfy constraints of I 2504dc07becSRui Ueyama // and attach them to I. 2514dc07becSRui Ueyama for (SectionPattern &Pat : I->SectionPatterns) { 25207171f21SGeorge Rimar size_t SizeBefore = I->Sections.size(); 2538c6a5aafSRui Ueyama 2548c6a5aafSRui Ueyama for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) { 255f94efdddSRui Ueyama if (!S->Live || S->Assigned) 2568c6a5aafSRui Ueyama continue; 257908a3d34SRafael Espindola // For -emit-relocs we have to ignore entries like 258908a3d34SRafael Espindola // .rela.dyn : { *(.rela.data) } 259908a3d34SRafael Espindola // which are common because they are in the default bfd script. 260908a3d34SRafael Espindola if (S->Type == SHT_REL || S->Type == SHT_RELA) 261908a3d34SRafael Espindola continue; 2628c6a5aafSRui Ueyama 263e0be2901SRui Ueyama StringRef Filename = basename(S); 264e0be2901SRui Ueyama if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename)) 265e0be2901SRui Ueyama continue; 266e0be2901SRui Ueyama if (!Pat.SectionPat.match(S->Name)) 267e0be2901SRui Ueyama continue; 268d3190795SRafael Espindola I->Sections.push_back(S); 269f94efdddSRui Ueyama S->Assigned = true; 270f94efdddSRui Ueyama } 271d3190795SRafael Espindola 272ee924709SRui Ueyama // Sort sections as instructed by SORT-family commands and --sort-section 273ee924709SRui Ueyama // option. Because SORT-family commands can be nested at most two depth 274ee924709SRui Ueyama // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command 275ee924709SRui Ueyama // line option is respected even if a SORT command is given, the exact 276ee924709SRui Ueyama // behavior we have here is a bit complicated. Here are the rules. 277ee924709SRui Ueyama // 278ee924709SRui Ueyama // 1. If two SORT commands are given, --sort-section is ignored. 279ee924709SRui Ueyama // 2. If one SORT command is given, and if it is not SORT_NONE, 280ee924709SRui Ueyama // --sort-section is handled as an inner SORT command. 281ee924709SRui Ueyama // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. 282ee924709SRui Ueyama // 4. If no SORT command is given, sort according to --sort-section. 28307171f21SGeorge Rimar InputSectionData **Begin = I->Sections.data() + SizeBefore; 28407171f21SGeorge Rimar InputSectionData **End = I->Sections.data() + I->Sections.size(); 28507171f21SGeorge Rimar if (Pat.SortOuter != SortSectionPolicy::None) { 28607171f21SGeorge Rimar if (Pat.SortInner == SortSectionPolicy::Default) 28707171f21SGeorge Rimar sortSections(Begin, End, Config->SortSection); 288ee924709SRui Ueyama else 28907171f21SGeorge Rimar sortSections(Begin, End, Pat.SortInner); 29007171f21SGeorge Rimar sortSections(Begin, End, Pat.SortOuter); 29107171f21SGeorge Rimar } 292ee924709SRui Ueyama } 293be94e1b6SRafael Espindola } 294be94e1b6SRafael Espindola 295be94e1b6SRafael Espindola template <class ELFT> 296be94e1b6SRafael Espindola void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) { 297be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : V) { 298be94e1b6SRafael Espindola S->Live = false; 299*ecbfd871SRafael Espindola if (S == In<ELFT>::ShStrTab) 300*ecbfd871SRafael Espindola error("discarding .shstrtab section is not allowed"); 301505ac8dcSGeorge Rimar 302505ac8dcSGeorge Rimar InputSection<ELFT> *IS = dyn_cast<InputSection<ELFT>>(S); 303505ac8dcSGeorge Rimar if (!IS || IS->DependentSections.empty()) 304505ac8dcSGeorge Rimar continue; 305505ac8dcSGeorge Rimar discard(IS->DependentSections); 306be94e1b6SRafael Espindola } 307be94e1b6SRafael Espindola } 308be94e1b6SRafael Espindola 30906ae6836SGeorge Rimar template <class ELFT> 3100b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 31106ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 3120b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 313e7f912cdSRui Ueyama 31406ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 3157c3ff2ebSRafael Espindola auto *Cmd = dyn_cast<InputSectionDescription>(Base.get()); 3167c3ff2ebSRafael Espindola if (!Cmd) 3170b9ce6a4SRui Ueyama continue; 318e71a3f8aSRafael Espindola computeInputSections(Cmd); 319d3190795SRafael Espindola for (InputSectionData *S : Cmd->Sections) 320d3190795SRafael Espindola Ret.push_back(static_cast<InputSectionBase<ELFT> *>(S)); 3210b9ce6a4SRui Ueyama } 322e71a3f8aSRafael Espindola 3230b9ce6a4SRui Ueyama return Ret; 3240b9ce6a4SRui Ueyama } 3250b9ce6a4SRui Ueyama 326e5d3ca50SPetr Hosek template <class ELFT> 32720d03194SEugene Leviant void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { 3287c3ff2ebSRafael Espindola for (unsigned I = 0; I < Opt.Commands.size(); ++I) { 3297c3ff2ebSRafael Espindola auto Iter = Opt.Commands.begin() + I; 3307c3ff2ebSRafael Espindola const std::unique_ptr<BaseCommand> &Base1 = *Iter; 3310b1b695aSRui Ueyama 3320b1b695aSRui Ueyama // Handle symbol assignments outside of any output section. 3332ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 3344cd7352cSRafael Espindola addSymbol(Cmd); 3352ab5f73dSRui Ueyama continue; 3362ab5f73dSRui Ueyama } 3370b1b695aSRui Ueyama 33820d03194SEugene Leviant if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) { 33920d03194SEugene Leviant // If we don't have SECTIONS then output sections have already been 340194470cdSGeorge Rimar // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses 34120d03194SEugene Leviant // will not be called, so ASSERT should be evaluated now. 34220d03194SEugene Leviant if (!Opt.HasSections) 34320d03194SEugene Leviant Cmd->Expression(0); 34420d03194SEugene Leviant continue; 34520d03194SEugene Leviant } 3462ab5f73dSRui Ueyama 347ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 3487bd37870SRafael Espindola std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 3497bd37870SRafael Espindola 3500b1b695aSRui Ueyama // The output section name `/DISCARD/' is special. 3510b1b695aSRui Ueyama // Any input section assigned to it is discarded. 35248c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 3537bd37870SRafael Espindola discard(V); 35448c3f1ceSRui Ueyama continue; 35548c3f1ceSRui Ueyama } 3560b9ce6a4SRui Ueyama 3570b1b695aSRui Ueyama // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive 3580b1b695aSRui Ueyama // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input 3590b1b695aSRui Ueyama // sections satisfy a given constraint. If not, a directive is handled 3600b1b695aSRui Ueyama // as if it wasn't present from the beginning. 3610b1b695aSRui Ueyama // 3620b1b695aSRui Ueyama // Because we'll iterate over Commands many more times, the easiest 3630b1b695aSRui Ueyama // way to "make it as if it wasn't present" is to just remove it. 3647c3ff2ebSRafael Espindola if (!matchConstraints<ELFT>(V, Cmd->Constraint)) { 3657c3ff2ebSRafael Espindola for (InputSectionBase<ELFT> *S : V) 366f94efdddSRui Ueyama S->Assigned = false; 3677c3ff2ebSRafael Espindola Opt.Commands.erase(Iter); 368dfbbbc86SGeorge Rimar --I; 3697c3ff2ebSRafael Espindola continue; 3707c3ff2ebSRafael Espindola } 3717c3ff2ebSRafael Espindola 3720b1b695aSRui Ueyama // A directive may contain symbol definitions like this: 3730b1b695aSRui Ueyama // ".foo : { ...; bar = .; }". Handle them. 3747c3ff2ebSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 3757c3ff2ebSRafael Espindola if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) 3764cd7352cSRafael Espindola addSymbol(OutCmd); 3777c3ff2ebSRafael Espindola 3780b1b695aSRui Ueyama // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign 3790b1b695aSRui Ueyama // is given, input sections are aligned to that value, whether the 3800b1b695aSRui Ueyama // given value is larger or smaller than the original section alignment. 3810b1b695aSRui Ueyama if (Cmd->SubalignExpr) { 3820b1b695aSRui Ueyama uint32_t Subalign = Cmd->SubalignExpr(0); 3830b1b695aSRui Ueyama for (InputSectionBase<ELFT> *S : V) 3840b1b695aSRui Ueyama S->Alignment = Subalign; 38520d03194SEugene Leviant } 3860b1b695aSRui Ueyama 3870b1b695aSRui Ueyama // Add input sections to an output section. 3880b1b695aSRui Ueyama for (InputSectionBase<ELFT> *S : V) 3898290274cSRafael Espindola Factory.addInputSec(S, Cmd->Name); 390eea3114fSGeorge Rimar } 39148c3f1ceSRui Ueyama } 392db24d9c3SGeorge Rimar } 393e63d81bdSEugene Leviant 3940b1b695aSRui Ueyama // Add sections that didn't match any sections command. 39520d03194SEugene Leviant template <class ELFT> 39693c64025SGeorge Rimar void LinkerScript<ELFT>::addOrphanSections( 39793c64025SGeorge Rimar OutputSectionFactory<ELFT> &Factory) { 3988c6a5aafSRui Ueyama for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) 3998f9026baSRafael Espindola if (S->Live && !S->OutSec) 4008290274cSRafael Espindola Factory.addInputSec(S, getOutputSectionName(S->Name)); 401e63d81bdSEugene Leviant } 402e63d81bdSEugene Leviant 403e08e78dfSRafael Espindola template <class ELFT> static bool isTbss(OutputSectionBase *Sec) { 40404a2e348SRafael Espindola return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS; 405a940e539SRafael Espindola } 406a940e539SRafael Espindola 407d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) { 408d3190795SRafael Espindola if (!AlreadyOutputIS.insert(S).second) 409ceabe80eSEugene Leviant return; 410e08e78dfSRafael Espindola bool IsTbss = isTbss<ELFT>(CurOutSec); 411d3190795SRafael Espindola 412d3190795SRafael Espindola uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; 413d3190795SRafael Espindola Pos = alignTo(Pos, S->Alignment); 41404a2e348SRafael Espindola S->OutSecOff = Pos - CurOutSec->Addr; 415d3190795SRafael Espindola Pos += S->getSize(); 416d3190795SRafael Espindola 417d3190795SRafael Espindola // Update output section size after adding each section. This is so that 418d3190795SRafael Espindola // SIZEOF works correctly in the case below: 419d3190795SRafael Espindola // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 42004a2e348SRafael Espindola CurOutSec->Size = Pos - CurOutSec->Addr; 421d3190795SRafael Espindola 422b889744eSMeador Inge // If there is a memory region associated with this input section, then 423b889744eSMeador Inge // place the section in that region and update the region index. 424b889744eSMeador Inge if (CurMemRegion) { 425b889744eSMeador Inge CurMemRegion->Offset += CurOutSec->Size; 426b889744eSMeador Inge uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin; 427b889744eSMeador Inge if (CurSize > CurMemRegion->Length) { 428b889744eSMeador Inge uint64_t OverflowAmt = CurSize - CurMemRegion->Length; 429b889744eSMeador Inge error("section '" + CurOutSec->Name + "' will not fit in region '" + 430b889744eSMeador Inge CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) + 431b889744eSMeador Inge " bytes"); 432b889744eSMeador Inge } 433b889744eSMeador Inge } 434b889744eSMeador Inge 4357252ae52SRafael Espindola if (IsTbss) 4367252ae52SRafael Espindola ThreadBssOffset = Pos - Dot; 4377252ae52SRafael Espindola else 438d3190795SRafael Espindola Dot = Pos; 4392de509c3SRui Ueyama } 440ceabe80eSEugene Leviant 441d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::flush() { 44265499b90SRafael Espindola if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second) 44365499b90SRafael Espindola return; 44465499b90SRafael Espindola if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) { 445d3190795SRafael Espindola for (InputSection<ELFT> *I : OutSec->Sections) 446d3190795SRafael Espindola output(I); 44765499b90SRafael Espindola } else { 44804a2e348SRafael Espindola Dot += CurOutSec->Size; 449d3190795SRafael Espindola } 450d3190795SRafael Espindola } 45197403d15SEugene Leviant 452d3190795SRafael Espindola template <class ELFT> 453e08e78dfSRafael Espindola void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) { 454d3190795SRafael Espindola if (CurOutSec == Sec) 455d3190795SRafael Espindola return; 456d3190795SRafael Espindola if (AlreadyOutputOS.count(Sec)) 457d3190795SRafael Espindola return; 458d3190795SRafael Espindola 459d3190795SRafael Espindola flush(); 460d3190795SRafael Espindola CurOutSec = Sec; 461d3190795SRafael Espindola 46204a2e348SRafael Espindola Dot = alignTo(Dot, CurOutSec->Addralign); 463e08e78dfSRafael Espindola CurOutSec->Addr = isTbss<ELFT>(CurOutSec) ? Dot + ThreadBssOffset : Dot; 464b71d6f7aSEugene Leviant 465b71d6f7aSEugene Leviant // If neither AT nor AT> is specified for an allocatable section, the linker 466b71d6f7aSEugene Leviant // will set the LMA such that the difference between VMA and LMA for the 467b71d6f7aSEugene Leviant // section is the same as the preceding output section in the same region 468b71d6f7aSEugene Leviant // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html 469b71d6f7aSEugene Leviant CurOutSec->setLMAOffset(LMAOffset); 470d3190795SRafael Espindola } 471d3190795SRafael Espindola 472d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) { 473e38cbab5SGeorge Rimar // This handles the assignments to symbol or to a location counter (.) 474d3190795SRafael Espindola if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) { 4754cd7352cSRafael Espindola assignSymbol(AssignCmd, true); 476d3190795SRafael Espindola return; 47797403d15SEugene Leviant } 478e38cbab5SGeorge Rimar 479e38cbab5SGeorge Rimar // Handle BYTE(), SHORT(), LONG(), or QUAD(). 480e38cbab5SGeorge Rimar if (auto *DataCmd = dyn_cast<BytesDataCommand>(&Base)) { 48104a2e348SRafael Espindola DataCmd->Offset = Dot - CurOutSec->Addr; 482e38cbab5SGeorge Rimar Dot += DataCmd->Size; 48304a2e348SRafael Espindola CurOutSec->Size = Dot - CurOutSec->Addr; 484e38cbab5SGeorge Rimar return; 485e38cbab5SGeorge Rimar } 486e38cbab5SGeorge Rimar 487b2d99d6aSMeador Inge if (auto *AssertCmd = dyn_cast<AssertCommand>(&Base)) { 488b2d99d6aSMeador Inge AssertCmd->Expression(Dot); 489b2d99d6aSMeador Inge return; 490b2d99d6aSMeador Inge } 491b2d99d6aSMeador Inge 492e38cbab5SGeorge Rimar // It handles single input section description command, 493e38cbab5SGeorge Rimar // calculates and assigns the offsets for each section and also 494e38cbab5SGeorge Rimar // updates the output section size. 495d3190795SRafael Espindola auto &ICmd = cast<InputSectionDescription>(Base); 496d3190795SRafael Espindola for (InputSectionData *ID : ICmd.Sections) { 4973fb5a6dcSGeorge Rimar // We tentatively added all synthetic sections at the beginning and removed 4983fb5a6dcSGeorge Rimar // empty ones afterwards (because there is no way to know whether they were 4993fb5a6dcSGeorge Rimar // going be empty or not other than actually running linker scripts.) 5003fb5a6dcSGeorge Rimar // We need to ignore remains of empty sections. 5013fb5a6dcSGeorge Rimar if (auto *Sec = dyn_cast<SyntheticSection<ELFT>>(ID)) 5023fb5a6dcSGeorge Rimar if (Sec->empty()) 5033fb5a6dcSGeorge Rimar continue; 5043fb5a6dcSGeorge Rimar 505d3190795SRafael Espindola auto *IB = static_cast<InputSectionBase<ELFT> *>(ID); 506d3190795SRafael Espindola switchTo(IB->OutSec); 507d3190795SRafael Espindola if (auto *I = dyn_cast<InputSection<ELFT>>(IB)) 508d3190795SRafael Espindola output(I); 50965499b90SRafael Espindola else 51065499b90SRafael Espindola flush(); 511ceabe80eSEugene Leviant } 512ceabe80eSEugene Leviant } 513ceabe80eSEugene Leviant 5148f66df92SGeorge Rimar template <class ELFT> 5152b074553SRafael Espindola static OutputSectionBase * 5162b074553SRafael Espindola findSection(StringRef Name, const std::vector<OutputSectionBase *> &Sections) { 5172b074553SRafael Espindola auto End = Sections.end(); 5182b074553SRafael Espindola auto HasName = [=](OutputSectionBase *Sec) { return Sec->getName() == Name; }; 5192b074553SRafael Espindola auto I = std::find_if(Sections.begin(), End, HasName); 520e08e78dfSRafael Espindola std::vector<OutputSectionBase *> Ret; 5212b074553SRafael Espindola if (I == End) 5222b074553SRafael Espindola return nullptr; 5232b074553SRafael Espindola assert(std::find_if(I + 1, End, HasName) == End); 5242b074553SRafael Espindola return *I; 5258f66df92SGeorge Rimar } 5268f66df92SGeorge Rimar 527b889744eSMeador Inge // This function searches for a memory region to place the given output 528b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is 529b889744eSMeador Inge // returned. Otherwise, a nullptr is returned. 530b889744eSMeador Inge template <class ELFT> 531b889744eSMeador Inge MemoryRegion *LinkerScript<ELFT>::findMemoryRegion(OutputSectionCommand *Cmd, 532b889744eSMeador Inge OutputSectionBase *Sec) { 533b889744eSMeador Inge // If a memory region name was specified in the output section command, 534b889744eSMeador Inge // then try to find that region first. 535b889744eSMeador Inge if (!Cmd->MemoryRegionName.empty()) { 536b889744eSMeador Inge auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName); 537b889744eSMeador Inge if (It != Opt.MemoryRegions.end()) 538b889744eSMeador Inge return &It->second; 539b889744eSMeador Inge error("memory region '" + Cmd->MemoryRegionName + "' not declared"); 540b889744eSMeador Inge return nullptr; 541b889744eSMeador Inge } 542b889744eSMeador Inge 543b889744eSMeador Inge // The memory region name is empty, thus a suitable region must be 544b889744eSMeador Inge // searched for in the region map. If the region map is empty, just 545b889744eSMeador Inge // return. Note that this check doesn't happen at the very beginning 546b889744eSMeador Inge // so that uses of undeclared regions can be caught. 547b889744eSMeador Inge if (!Opt.MemoryRegions.size()) 548b889744eSMeador Inge return nullptr; 549b889744eSMeador Inge 550b889744eSMeador Inge // See if a region can be found by matching section flags. 551b889744eSMeador Inge for (auto &MRI : Opt.MemoryRegions) { 552b889744eSMeador Inge MemoryRegion &MR = MRI.second; 5538a8a953eSRui Ueyama if ((MR.Flags & Sec->Flags) != 0 && (MR.NegFlags & Sec->Flags) == 0) 554b889744eSMeador Inge return &MR; 555b889744eSMeador Inge } 556b889744eSMeador Inge 557b889744eSMeador Inge // Otherwise, no suitable region was found. 558b889744eSMeador Inge if (Sec->Flags & SHF_ALLOC) 559b889744eSMeador Inge error("no memory region specified for section '" + Sec->Name + "'"); 560b889744eSMeador Inge return nullptr; 561b889744eSMeador Inge } 562b889744eSMeador Inge 5630b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section 5640b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }"). 565d3190795SRafael Espindola template <class ELFT> 566d3190795SRafael Espindola void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) { 567b71d6f7aSEugene Leviant if (Cmd->LMAExpr) 568b71d6f7aSEugene Leviant LMAOffset = Cmd->LMAExpr(Dot) - Dot; 5692b074553SRafael Espindola OutputSectionBase *Sec = findSection<ELFT>(Cmd->Name, *OutputSections); 5702b074553SRafael Espindola if (!Sec) 571d3190795SRafael Espindola return; 572b889744eSMeador Inge 573679828ffSRafael Espindola if (Cmd->AddrExpr && Sec->Flags & SHF_ALLOC) 574679828ffSRafael Espindola setDot(Cmd->AddrExpr); 575679828ffSRafael Espindola 576165088aaSPetr Hosek // Handle align (e.g. ".foo : ALIGN(16) { ... }"). 577165088aaSPetr Hosek if (Cmd->AlignExpr) 578165088aaSPetr Hosek Sec->updateAlignment(Cmd->AlignExpr(0)); 579165088aaSPetr Hosek 580b889744eSMeador Inge // Try and find an appropriate memory region to assign offsets in. 581b889744eSMeador Inge CurMemRegion = findMemoryRegion(Cmd, Sec); 582b889744eSMeador Inge if (CurMemRegion) 583b889744eSMeador Inge Dot = CurMemRegion->Offset; 584b889744eSMeador Inge switchTo(Sec); 5850b1b695aSRui Ueyama 586d3190795SRafael Espindola // Find the last section output location. We will output orphan sections 587d3190795SRafael Espindola // there so that end symbols point to the correct location. 588d3190795SRafael Espindola auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(), 589d3190795SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 590d3190795SRafael Espindola return !isa<SymbolAssignment>(*Cmd); 591d3190795SRafael Espindola }) 592d3190795SRafael Espindola .base(); 593d3190795SRafael Espindola for (auto I = Cmd->Commands.begin(); I != E; ++I) 594d3190795SRafael Espindola process(**I); 5952506cb4dSEugene Leviant flush(); 596b31dd370SGeorge Rimar std::for_each(E, Cmd->Commands.end(), 597b31dd370SGeorge Rimar [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); }); 598d3190795SRafael Espindola } 599d3190795SRafael Espindola 60007fe6129SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::removeEmptyCommands() { 6016d38e4dbSRafael Espindola // It is common practice to use very generic linker scripts. So for any 6026d38e4dbSRafael Espindola // given run some of the output sections in the script will be empty. 6036d38e4dbSRafael Espindola // We could create corresponding empty output sections, but that would 6046d38e4dbSRafael Espindola // clutter the output. 6056d38e4dbSRafael Espindola // We instead remove trivially empty sections. The bfd linker seems even 6066d38e4dbSRafael Espindola // more aggressive at removing them. 6076d38e4dbSRafael Espindola auto Pos = std::remove_if( 6086d38e4dbSRafael Espindola Opt.Commands.begin(), Opt.Commands.end(), 6096d38e4dbSRafael Espindola [&](const std::unique_ptr<BaseCommand> &Base) { 6100b1b695aSRui Ueyama if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 6112b074553SRafael Espindola return !findSection<ELFT>(Cmd->Name, *OutputSections); 6120b1b695aSRui Ueyama return false; 6136d38e4dbSRafael Espindola }); 6146d38e4dbSRafael Espindola Opt.Commands.erase(Pos, Opt.Commands.end()); 61507fe6129SRafael Espindola } 61607fe6129SRafael Espindola 6176a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) { 6186a53737cSRafael Espindola for (const std::unique_ptr<BaseCommand> &I : Cmd.Commands) 6196a53737cSRafael Espindola if (!isa<InputSectionDescription>(*I)) 6206a53737cSRafael Espindola return false; 6216a53737cSRafael Espindola return true; 6226a53737cSRafael Espindola } 6236d38e4dbSRafael Espindola 6246a53737cSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() { 6259546fffbSRafael Espindola // If the output section contains only symbol assignments, create a 6269546fffbSRafael Espindola // corresponding output section. The bfd linker seems to only create them if 6279546fffbSRafael Espindola // '.' is assigned to, but creating these section should not have any bad 6289546fffbSRafael Espindola // consequeces and gives us a section to put the symbol in. 6299546fffbSRafael Espindola uintX_t Flags = SHF_ALLOC; 630f93b8c29SRafael Espindola uint32_t Type = SHT_NOBITS; 6319546fffbSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 6329546fffbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 6339546fffbSRafael Espindola if (!Cmd) 6349546fffbSRafael Espindola continue; 6352b074553SRafael Espindola if (OutputSectionBase *Sec = 6362b074553SRafael Espindola findSection<ELFT>(Cmd->Name, *OutputSections)) { 6372b074553SRafael Espindola Flags = Sec->Flags; 6382b074553SRafael Espindola Type = Sec->Type; 6399546fffbSRafael Espindola continue; 6409546fffbSRafael Espindola } 6419546fffbSRafael Espindola 6426a53737cSRafael Espindola if (isAllSectionDescription(*Cmd)) 6436a53737cSRafael Espindola continue; 6446a53737cSRafael Espindola 64595642b95SRui Ueyama auto *OutSec = make<OutputSection<ELFT>>(Cmd->Name, Type, Flags); 6469546fffbSRafael Espindola OutputSections->push_back(OutSec); 6479546fffbSRafael Espindola } 648f7a17448SRafael Espindola } 649f7a17448SRafael Espindola 650f7a17448SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsAfterSorting() { 651f7a17448SRafael Espindola placeOrphanSections(); 652f7a17448SRafael Espindola 653f7a17448SRafael Espindola // If output section command doesn't specify any segments, 654f7a17448SRafael Espindola // and we haven't previously assigned any section to segment, 655f7a17448SRafael Espindola // then we simply assign section to the very first load segment. 656f7a17448SRafael Espindola // Below is an example of such linker script: 657f7a17448SRafael Espindola // PHDRS { seg PT_LOAD; } 658f7a17448SRafael Espindola // SECTIONS { .aaa : { *(.aaa) } } 659f7a17448SRafael Espindola std::vector<StringRef> DefPhdrs; 660f7a17448SRafael Espindola auto FirstPtLoad = 661f7a17448SRafael Espindola std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(), 662f7a17448SRafael Espindola [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; }); 663f7a17448SRafael Espindola if (FirstPtLoad != Opt.PhdrsCommands.end()) 664f7a17448SRafael Espindola DefPhdrs.push_back(FirstPtLoad->Name); 665f7a17448SRafael Espindola 666f7a17448SRafael Espindola // Walk the commands and propagate the program headers to commands that don't 667f7a17448SRafael Espindola // explicitly specify them. 668f7a17448SRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 669f7a17448SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 670f7a17448SRafael Espindola if (!Cmd) 671f7a17448SRafael Espindola continue; 672f7a17448SRafael Espindola if (Cmd->Phdrs.empty()) 673f7a17448SRafael Espindola Cmd->Phdrs = DefPhdrs; 674f7a17448SRafael Espindola else 675f7a17448SRafael Espindola DefPhdrs = Cmd->Phdrs; 676f7a17448SRafael Espindola } 6776a53737cSRafael Espindola 6786a53737cSRafael Espindola removeEmptyCommands(); 6799546fffbSRafael Espindola } 6809546fffbSRafael Espindola 68115c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments 68215c57951SRafael Espindola // so that an orphan after 68315c57951SRafael Espindola // begin_foo = .; 68415c57951SRafael Espindola // foo : { *(foo) } 68515c57951SRafael Espindola // end_foo = .; 68615c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols. 68715c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the 68815c57951SRafael Espindola // one in charge of deciding the order of the sections. 68915c57951SRafael Espindola // We don't want to go over alignments, since doing so in 69015c57951SRafael Espindola // rx_sec : { *(rx_sec) } 69115c57951SRafael Espindola // . = ALIGN(0x1000); 69215c57951SRafael Espindola // /* The RW PT_LOAD starts here*/ 69315c57951SRafael Espindola // rw_sec : { *(rw_sec) } 69415c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned. 6955fcc99c2SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) { 69615c57951SRafael Espindola if (isa<OutputSectionCommand>(Cmd)) 69715c57951SRafael Espindola return false; 69815c57951SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd); 69915c57951SRafael Espindola if (!Assign) 70015c57951SRafael Espindola return true; 7015fcc99c2SRafael Espindola return Assign->Name != "."; 70215c57951SRafael Espindola } 70315c57951SRafael Espindola 7046697ec29SRui Ueyama // Orphan sections are sections present in the input files which are 7056697ec29SRui Ueyama // not explicitly placed into the output file by the linker script. 7066697ec29SRui Ueyama // 7076697ec29SRui Ueyama // When the control reaches this function, Opt.Commands contains 7086697ec29SRui Ueyama // output section commands for non-orphan sections only. This function 7096697ec29SRui Ueyama // adds new elements for orphan sections to Opt.Commands so that all 7106697ec29SRui Ueyama // sections are explicitly handled by Opt.Commands. 7116697ec29SRui Ueyama // 7126697ec29SRui Ueyama // Writer<ELFT>::sortSections has already sorted output sections. 7136697ec29SRui Ueyama // What we need to do is to scan OutputSections vector and 7146697ec29SRui Ueyama // Opt.Commands in parallel to find orphan sections. If there is an 7156697ec29SRui Ueyama // output section that doesn't have a corresponding entry in 7166697ec29SRui Ueyama // Opt.Commands, we will insert a new entry to Opt.Commands. 7176697ec29SRui Ueyama // 7186697ec29SRui Ueyama // There is some ambiguity as to where exactly a new entry should be 7196697ec29SRui Ueyama // inserted, because Opt.Commands contains not only output section 7206697ec29SRui Ueyama // commands but other types of commands such as symbol assignment 7216697ec29SRui Ueyama // expressions. There's no correct answer here due to the lack of the 7226697ec29SRui Ueyama // formal specification of the linker script. We use heuristics to 7236697ec29SRui Ueyama // determine whether a new output command should be added before or 7246697ec29SRui Ueyama // after another commands. For the details, look at shouldSkip 7256697ec29SRui Ueyama // function. 72693c64025SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::placeOrphanSections() { 727aab6d5c5SRafael Espindola // The OutputSections are already in the correct order. 728aab6d5c5SRafael Espindola // This loops creates or moves commands as needed so that they are in the 729aab6d5c5SRafael Espindola // correct order. 730aab6d5c5SRafael Espindola int CmdIndex = 0; 7315fcc99c2SRafael Espindola 7325fcc99c2SRafael Espindola // As a horrible special case, skip the first . assignment if it is before any 7335fcc99c2SRafael Espindola // section. We do this because it is common to set a load address by starting 7345fcc99c2SRafael Espindola // the script with ". = 0xabcd" and the expectation is that every section is 7355fcc99c2SRafael Espindola // after that. 7365fcc99c2SRafael Espindola auto FirstSectionOrDotAssignment = 7375fcc99c2SRafael Espindola std::find_if(Opt.Commands.begin(), Opt.Commands.end(), 7385fcc99c2SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 7395fcc99c2SRafael Espindola if (isa<OutputSectionCommand>(*Cmd)) 7405fcc99c2SRafael Espindola return true; 7415fcc99c2SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(Cmd.get()); 7425fcc99c2SRafael Espindola if (!Assign) 7435fcc99c2SRafael Espindola return false; 7445fcc99c2SRafael Espindola return Assign->Name == "."; 7455fcc99c2SRafael Espindola }); 7465fcc99c2SRafael Espindola if (FirstSectionOrDotAssignment != Opt.Commands.end()) { 7475fcc99c2SRafael Espindola CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin(); 7485fcc99c2SRafael Espindola if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment)) 7495fcc99c2SRafael Espindola ++CmdIndex; 7505fcc99c2SRafael Espindola } 7515fcc99c2SRafael Espindola 752e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) { 753652852c5SGeorge Rimar StringRef Name = Sec->getName(); 754aab6d5c5SRafael Espindola 755aab6d5c5SRafael Espindola // Find the last spot where we can insert a command and still get the 75615c57951SRafael Espindola // correct result. 757aab6d5c5SRafael Espindola auto CmdIter = Opt.Commands.begin() + CmdIndex; 758aab6d5c5SRafael Espindola auto E = Opt.Commands.end(); 7595fcc99c2SRafael Espindola while (CmdIter != E && shouldSkip(**CmdIter)) { 760aab6d5c5SRafael Espindola ++CmdIter; 761aab6d5c5SRafael Espindola ++CmdIndex; 762aab6d5c5SRafael Espindola } 763aab6d5c5SRafael Espindola 764aab6d5c5SRafael Espindola auto Pos = 765aab6d5c5SRafael Espindola std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) { 766aab6d5c5SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 767aab6d5c5SRafael Espindola return Cmd && Cmd->Name == Name; 768aab6d5c5SRafael Espindola }); 769aab6d5c5SRafael Espindola if (Pos == E) { 770aab6d5c5SRafael Espindola Opt.Commands.insert(CmdIter, 771aab6d5c5SRafael Espindola llvm::make_unique<OutputSectionCommand>(Name)); 772aab6d5c5SRafael Espindola ++CmdIndex; 77315c57951SRafael Espindola continue; 77415c57951SRafael Espindola } 77515c57951SRafael Espindola 77615c57951SRafael Espindola // Continue from where we found it. 77715c57951SRafael Espindola CmdIndex = (Pos - Opt.Commands.begin()) + 1; 778652852c5SGeorge Rimar } 779337f903cSRafael Espindola } 780337f903cSRafael Espindola 781337f903cSRafael Espindola template <class ELFT> 78217cb7c0aSRafael Espindola void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) { 7837c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 784be607334SRafael Espindola Dot = 0; 785652852c5SGeorge Rimar 78606f4743aSRafael Espindola // A symbol can be assigned before any section is mentioned in the linker 78706f4743aSRafael Espindola // script. In an DSO, the symbol values are addresses, so the only important 78806f4743aSRafael Espindola // section values are: 78906f4743aSRafael Espindola // * SHN_UNDEF 79006f4743aSRafael Espindola // * SHN_ABS 79106f4743aSRafael Espindola // * Any value meaning a regular section. 79206f4743aSRafael Espindola // To handle that, create a dummy aether section that fills the void before 79306f4743aSRafael Espindola // the linker scripts switches to another section. It has an index of one 79406f4743aSRafael Espindola // which will map to whatever the first actual section is. 79506f4743aSRafael Espindola auto *Aether = make<OutputSectionBase>("", 0, SHF_ALLOC); 79606f4743aSRafael Espindola Aether->SectionIndex = 1; 79706f4743aSRafael Espindola switchTo(Aether); 79806f4743aSRafael Espindola 799076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 800076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 8014cd7352cSRafael Espindola assignSymbol(Cmd); 80205ef4cffSRui Ueyama continue; 803652852c5SGeorge Rimar } 804652852c5SGeorge Rimar 805eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 806eefa758eSGeorge Rimar Cmd->Expression(Dot); 807eefa758eSGeorge Rimar continue; 808eefa758eSGeorge Rimar } 809eefa758eSGeorge Rimar 810076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 811d3190795SRafael Espindola assignOffsets(Cmd); 812a14b13d8SGeorge Rimar } 813467c4d55SEugene Leviant 814aab6d5c5SRafael Espindola uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 815ea590d91SRafael Espindola for (OutputSectionBase *Sec : *OutputSections) { 81604a2e348SRafael Espindola if (Sec->Flags & SHF_ALLOC) 817e08e78dfSRafael Espindola MinVA = std::min<uint64_t>(MinVA, Sec->Addr); 818ea590d91SRafael Espindola else 819ea590d91SRafael Espindola Sec->Addr = 0; 820ea590d91SRafael Espindola } 821aab6d5c5SRafael Espindola 8228c495e20SRafael Espindola allocateHeaders<ELFT>(Phdrs, *OutputSections, MinVA); 823fb8978fcSDima Stepanov } 824652852c5SGeorge Rimar 825464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 82617cb7c0aSRafael Espindola template <class ELFT> std::vector<PhdrEntry> LinkerScript<ELFT>::createPhdrs() { 82717cb7c0aSRafael Espindola std::vector<PhdrEntry> Ret; 828bbe38602SEugene Leviant 829464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 830464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 831bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 832edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 83317cb7c0aSRafael Espindola PhdrEntry &Phdr = Ret.back(); 834bbe38602SEugene Leviant 835bbe38602SEugene Leviant if (Cmd.HasFilehdr) 836adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 837bbe38602SEugene Leviant if (Cmd.HasPhdrs) 838adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 83956b21c86SEugene Leviant 84056b21c86SEugene Leviant if (Cmd.LMAExpr) { 84117cb7c0aSRafael Espindola Phdr.p_paddr = Cmd.LMAExpr(0); 84256b21c86SEugene Leviant Phdr.HasLMA = true; 84356b21c86SEugene Leviant } 844bbe38602SEugene Leviant } 845bbe38602SEugene Leviant 846464daadcSRui Ueyama // Add output sections to program headers. 847e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) { 84804a2e348SRafael Espindola if (!(Sec->Flags & SHF_ALLOC)) 849bbe38602SEugene Leviant break; 850bbe38602SEugene Leviant 851bbe38602SEugene Leviant // Assign headers specified by linker script 852f7a17448SRafael Espindola for (size_t Id : getPhdrIndices(Sec->getName())) { 853edebbdf1SRui Ueyama Ret[Id].add(Sec); 854865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 85517cb7c0aSRafael Espindola Ret[Id].p_flags |= Sec->getPhdrFlags(); 856bbe38602SEugene Leviant } 857bbe38602SEugene Leviant } 858edebbdf1SRui Ueyama return Ret; 859bbe38602SEugene Leviant } 860bbe38602SEugene Leviant 861f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 862f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 863f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 864f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 865f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 866f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 867f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 868f9bc3bd2SEugene Leviant } 869f9bc3bd2SEugene Leviant 87093c64025SGeorge Rimar template <class ELFT> uint32_t LinkerScript<ELFT>::getFiller(StringRef Name) { 871f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 872f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 873f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 874f6c3ccefSGeorge Rimar return Cmd->Filler; 87516068aebSRui Ueyama return 0; 876e2ee72b5SGeorge Rimar } 877e2ee72b5SGeorge Rimar 878e38cbab5SGeorge Rimar template <class ELFT> 879e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { 880e38cbab5SGeorge Rimar const endianness E = ELFT::TargetEndianness; 881e38cbab5SGeorge Rimar 882e38cbab5SGeorge Rimar switch (Size) { 883e38cbab5SGeorge Rimar case 1: 884e38cbab5SGeorge Rimar *Buf = (uint8_t)Data; 885e38cbab5SGeorge Rimar break; 886e38cbab5SGeorge Rimar case 2: 887e38cbab5SGeorge Rimar write16<E>(Buf, Data); 888e38cbab5SGeorge Rimar break; 889e38cbab5SGeorge Rimar case 4: 890e38cbab5SGeorge Rimar write32<E>(Buf, Data); 891e38cbab5SGeorge Rimar break; 892e38cbab5SGeorge Rimar case 8: 893e38cbab5SGeorge Rimar write64<E>(Buf, Data); 894e38cbab5SGeorge Rimar break; 895e38cbab5SGeorge Rimar default: 896e38cbab5SGeorge Rimar llvm_unreachable("unsupported Size argument"); 897e38cbab5SGeorge Rimar } 898e38cbab5SGeorge Rimar } 899e38cbab5SGeorge Rimar 900e38cbab5SGeorge Rimar template <class ELFT> 901e38cbab5SGeorge Rimar void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) { 902e38cbab5SGeorge Rimar int I = getSectionIndex(Name); 903e38cbab5SGeorge Rimar if (I == INT_MAX) 904e38cbab5SGeorge Rimar return; 905e38cbab5SGeorge Rimar 9066e68c5e5SRui Ueyama auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()); 9076e68c5e5SRui Ueyama for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 9086e68c5e5SRui Ueyama if (auto *Data = dyn_cast<BytesDataCommand>(Base.get())) 90995c7d8d2SMeador Inge writeInt<ELFT>(Buf + Data->Offset, Data->Expression(0), Data->Size); 910e38cbab5SGeorge Rimar } 911e38cbab5SGeorge Rimar 912b71d6f7aSEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasLMA(StringRef Name) { 9138ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 9148ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 915b71d6f7aSEugene Leviant if (Cmd->LMAExpr && Cmd->Name == Name) 916b71d6f7aSEugene Leviant return true; 917b71d6f7aSEugene Leviant return false; 9188ceadb38SGeorge Rimar } 9198ceadb38SGeorge Rimar 920c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 921c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 922c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 923c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 924076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 9256e68c5e5SRui Ueyama for (int I = 0, E = Opt.Commands.size(); I != E; ++I) 9266e68c5e5SRui Ueyama if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get())) 927076fe157SGeorge Rimar if (Cmd->Name == Name) 928f510fa6bSRui Ueyama return I; 929f510fa6bSRui Ueyama return INT_MAX; 93071b26e94SGeorge Rimar } 93171b26e94SGeorge Rimar 932bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 933bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 934bbe38602SEugene Leviant } 935bbe38602SEugene Leviant 9369e69450eSGeorge Rimar template <class ELFT> 937ed30ce7aSEugene Leviant const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(const Twine &Loc, 938ed30ce7aSEugene Leviant StringRef Name) { 939afaa9343SEugene Leviant static OutputSectionBase FakeSec("", 0, 0); 94096659df0SGeorge Rimar 941e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) 942b71d6f7aSEugene Leviant if (Sec->getName() == Name) 943afaa9343SEugene Leviant return Sec; 944ed30ce7aSEugene Leviant 945ed30ce7aSEugene Leviant error(Loc + ": undefined section " + Name); 946afaa9343SEugene Leviant return &FakeSec; 94736fac7f0SEugene Leviant } 94836fac7f0SEugene Leviant 949edf75e79SRui Ueyama // This function is essentially the same as getOutputSection(Name)->Size, 950edf75e79SRui Ueyama // but it won't print out an error message if a given section is not found. 951edf75e79SRui Ueyama // 952edf75e79SRui Ueyama // Linker script does not create an output section if its content is empty. 953edf75e79SRui Ueyama // We want to allow SIZEOF(.foo) where .foo is a section which happened to 954edf75e79SRui Ueyama // be empty. That is why this function is different from getOutputSection(). 955edf75e79SRui Ueyama template <class ELFT> 956edf75e79SRui Ueyama uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 957edf75e79SRui Ueyama for (OutputSectionBase *Sec : *OutputSections) 958edf75e79SRui Ueyama if (Sec->getName() == Name) 959edf75e79SRui Ueyama return Sec->Size; 960edf75e79SRui Ueyama return 0; 961edf75e79SRui Ueyama } 962edf75e79SRui Ueyama 963884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() { 9640d4b6d5cSRafael Espindola return elf::getHeaderSize<ELFT>(); 965e32a3598SGeorge Rimar } 966e32a3598SGeorge Rimar 967f6aeed36SEugene Leviant template <class ELFT> 968f6aeed36SEugene Leviant uint64_t LinkerScript<ELFT>::getSymbolValue(const Twine &Loc, StringRef S) { 969884e786dSGeorge Rimar if (SymbolBody *B = Symtab<ELFT>::X->find(S)) 970884e786dSGeorge Rimar return B->getVA<ELFT>(); 971f6aeed36SEugene Leviant error(Loc + ": symbol not found: " + S); 972884e786dSGeorge Rimar return 0; 973884e786dSGeorge Rimar } 974884e786dSGeorge Rimar 975f34f45fdSGeorge Rimar template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) { 976f34f45fdSGeorge Rimar return Symtab<ELFT>::X->find(S) != nullptr; 977f34f45fdSGeorge Rimar } 978f34f45fdSGeorge Rimar 9792f831dcaSRafael Espindola template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) { 9802f831dcaSRafael Espindola SymbolBody *Sym = Symtab<ELFT>::X->find(S); 9812f831dcaSRafael Espindola auto *DR = dyn_cast_or_null<DefinedRegular<ELFT>>(Sym); 9822f831dcaSRafael Espindola return DR && !DR->Section; 9832f831dcaSRafael Espindola } 9842f831dcaSRafael Espindola 985afaa9343SEugene Leviant // Gets section symbol belongs to. Symbol "." doesn't belong to any 986afaa9343SEugene Leviant // specific section but isn't absolute at the same time, so we try 987afaa9343SEugene Leviant // to find suitable section for it as well. 988afaa9343SEugene Leviant template <class ELFT> 989afaa9343SEugene Leviant const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) { 99006f4743aSRafael Espindola if (SymbolBody *Sym = Symtab<ELFT>::X->find(S)) 99160aed443SGeorge Rimar return SymbolTableSection<ELFT>::getOutputSection(Sym); 99206f4743aSRafael Espindola return CurOutSec; 993afaa9343SEugene Leviant } 994afaa9343SEugene Leviant 995bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 996bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 997bbe38602SEugene Leviant // PHDRS {} script block. 998bbe38602SEugene Leviant template <class ELFT> 999edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 1000076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 1001076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 1002edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 100331d842f5SGeorge Rimar continue; 100431d842f5SGeorge Rimar 100529c5a2a9SRui Ueyama std::vector<size_t> Ret; 100629c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 10072a942c4bSEugene Leviant Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName)); 100829c5a2a9SRui Ueyama return Ret; 1009bbe38602SEugene Leviant } 101031d842f5SGeorge Rimar return {}; 101131d842f5SGeorge Rimar } 1012bbe38602SEugene Leviant 101329c5a2a9SRui Ueyama template <class ELFT> 10142a942c4bSEugene Leviant size_t LinkerScript<ELFT>::getPhdrIndex(const Twine &Loc, StringRef PhdrName) { 101529c5a2a9SRui Ueyama size_t I = 0; 101629c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 101729c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 101829c5a2a9SRui Ueyama return I; 101929c5a2a9SRui Ueyama ++I; 102029c5a2a9SRui Ueyama } 10212a942c4bSEugene Leviant error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS"); 102229c5a2a9SRui Ueyama return 0; 102329c5a2a9SRui Ueyama } 102429c5a2a9SRui Ueyama 1025794366a2SRui Ueyama class elf::ScriptParser final : public ScriptLexer { 1026c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 1027c3794e58SGeorge Rimar 1028f7c5fbb1SRui Ueyama public: 102922375f24SRui Ueyama ScriptParser(MemoryBufferRef MB) 1030794366a2SRui Ueyama : ScriptLexer(MB), 103122375f24SRui Ueyama IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {} 1032f23b2320SGeorge Rimar 103320b6598cSGeorge Rimar void readLinkerScript(); 103420b6598cSGeorge Rimar void readVersionScript(); 1035d0ebd84cSRafael Espindola void readDynamicList(); 1036f7c5fbb1SRui Ueyama 1037f7c5fbb1SRui Ueyama private: 103852a1509eSRui Ueyama void addFile(StringRef Path); 103952a1509eSRui Ueyama 1040f7c5fbb1SRui Ueyama void readAsNeeded(); 104190c5099eSDenis Protivensky void readEntry(); 104283f406cfSGeorge Rimar void readExtern(); 1043f7c5fbb1SRui Ueyama void readGroup(); 104431aa1f83SRui Ueyama void readInclude(); 1045b889744eSMeador Inge void readMemory(); 1046ee59282bSRui Ueyama void readOutput(); 10479159ce93SDavide Italiano void readOutputArch(); 1048f7c5fbb1SRui Ueyama void readOutputFormat(); 1049bbe38602SEugene Leviant void readPhdrs(); 105068a39a65SDavide Italiano void readSearchDir(); 10518e3b38abSDenis Protivensky void readSections(); 105295769b4aSRui Ueyama void readVersion(); 105395769b4aSRui Ueyama void readVersionScriptCommand(); 10548e3b38abSDenis Protivensky 1055113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 1056e38cbab5SGeorge Rimar BytesDataCommand *readBytesDataCommand(StringRef Tok); 105716068aebSRui Ueyama uint32_t readFill(); 105810416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 105916068aebSRui Ueyama uint32_t readOutputSectionFiller(StringRef Tok); 1060bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 1061a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 1062db688454SEugene Leviant StringMatcher readFilePatterns(); 106307171f21SGeorge Rimar std::vector<SectionPattern> readInputSectionsList(); 1064a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 1065bbe38602SEugene Leviant unsigned readPhdrType(); 1066be394db3SGeorge Rimar SortSectionPolicy readSortKind(); 1067a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 1068c96da110SRafael Espindola SymbolAssignment *readProvideOrAssignment(StringRef Tok); 106903fc010eSGeorge Rimar void readSort(); 1070eefa758eSGeorge Rimar Expr readAssert(); 1071708019c4SRui Ueyama 107224e626ccSRui Ueyama uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); 107324e626ccSRui Ueyama std::pair<uint32_t, uint32_t> readMemoryAttributes(); 107424e626ccSRui Ueyama 1075708019c4SRui Ueyama Expr readExpr(); 1076708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 1077b71d6f7aSEugene Leviant StringRef readParenLiteral(); 1078708019c4SRui Ueyama Expr readPrimary(); 1079708019c4SRui Ueyama Expr readTernary(Expr Cond); 10806ad7dfccSRui Ueyama Expr readParenExpr(); 1081f7c5fbb1SRui Ueyama 108220b6598cSGeorge Rimar // For parsing version script. 108312450b20SRui Ueyama std::vector<SymbolVersion> readVersionExtern(); 108412450b20SRui Ueyama void readAnonymousDeclaration(); 108595769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 108612450b20SRui Ueyama std::vector<SymbolVersion> readSymbols(); 1087e999ddb8SRafael Espindola void readLocals(); 108820b6598cSGeorge Rimar 108907320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 109016b0cc9eSSimon Atanasyan bool IsUnderSysroot; 1091f7c5fbb1SRui Ueyama }; 1092f7c5fbb1SRui Ueyama 1093d0ebd84cSRafael Espindola void ScriptParser::readDynamicList() { 1094d0ebd84cSRafael Espindola expect("{"); 1095d0ebd84cSRafael Espindola readAnonymousDeclaration(); 1096d0ebd84cSRafael Espindola if (!atEOF()) 1097d0ebd84cSRafael Espindola setError("EOF expected, but got " + next()); 1098d0ebd84cSRafael Espindola } 1099d0ebd84cSRafael Espindola 110020b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 110195769b4aSRui Ueyama readVersionScriptCommand(); 110220b6598cSGeorge Rimar if (!atEOF()) 110395769b4aSRui Ueyama setError("EOF expected, but got " + next()); 110495769b4aSRui Ueyama } 110595769b4aSRui Ueyama 110695769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 110783043f23SRui Ueyama if (consume("{")) { 110812450b20SRui Ueyama readAnonymousDeclaration(); 110920b6598cSGeorge Rimar return; 111020b6598cSGeorge Rimar } 111120b6598cSGeorge Rimar 111295769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 111320b6598cSGeorge Rimar StringRef VerStr = next(); 111420b6598cSGeorge Rimar if (VerStr == "{") { 111595769b4aSRui Ueyama setError("anonymous version definition is used in " 111695769b4aSRui Ueyama "combination with other version definitions"); 111720b6598cSGeorge Rimar return; 111820b6598cSGeorge Rimar } 111920b6598cSGeorge Rimar expect("{"); 112095769b4aSRui Ueyama readVersionDeclaration(VerStr); 112120b6598cSGeorge Rimar } 112220b6598cSGeorge Rimar } 112320b6598cSGeorge Rimar 112495769b4aSRui Ueyama void ScriptParser::readVersion() { 112595769b4aSRui Ueyama expect("{"); 112695769b4aSRui Ueyama readVersionScriptCommand(); 112795769b4aSRui Ueyama expect("}"); 112895769b4aSRui Ueyama } 112995769b4aSRui Ueyama 113020b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 1131f7c5fbb1SRui Ueyama while (!atEOF()) { 1132f7c5fbb1SRui Ueyama StringRef Tok = next(); 1133a27eeccaSRui Ueyama if (Tok == ";") 1134a27eeccaSRui Ueyama continue; 1135a27eeccaSRui Ueyama 113620d03194SEugene Leviant if (Tok == "ASSERT") { 113720d03194SEugene Leviant Opt.Commands.emplace_back(new AssertCommand(readAssert())); 113820d03194SEugene Leviant } else if (Tok == "ENTRY") { 1139a27eeccaSRui Ueyama readEntry(); 1140a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 1141a27eeccaSRui Ueyama readExtern(); 1142a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 1143a27eeccaSRui Ueyama readGroup(); 1144a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 1145a27eeccaSRui Ueyama readInclude(); 1146b889744eSMeador Inge } else if (Tok == "MEMORY") { 1147b889744eSMeador Inge readMemory(); 1148a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 1149a27eeccaSRui Ueyama readOutput(); 1150a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 1151a27eeccaSRui Ueyama readOutputArch(); 1152a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 1153a27eeccaSRui Ueyama readOutputFormat(); 1154a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 1155a27eeccaSRui Ueyama readPhdrs(); 1156a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 1157a27eeccaSRui Ueyama readSearchDir(); 1158a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 1159a27eeccaSRui Ueyama readSections(); 1160a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 1161a27eeccaSRui Ueyama readVersion(); 1162c96da110SRafael Espindola } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { 11630df80befSPetr Hosek Opt.Commands.emplace_back(Cmd); 1164e5d3ca50SPetr Hosek } else { 11655761042dSGeorge Rimar setError("unknown directive: " + Tok); 1166f7c5fbb1SRui Ueyama } 1167f7c5fbb1SRui Ueyama } 1168e5d3ca50SPetr Hosek } 1169f7c5fbb1SRui Ueyama 1170717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 117116b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 11725af1687fSJustin Bogner SmallString<128> PathData; 11735af1687fSJustin Bogner StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 117416b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 11755af1687fSJustin Bogner Driver->addFile(Saver.save(Path)); 117616b0cc9eSSimon Atanasyan return; 117716b0cc9eSSimon Atanasyan } 117816b0cc9eSSimon Atanasyan } 117916b0cc9eSSimon Atanasyan 1180f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 118152a1509eSRui Ueyama Driver->addFile(S); 118252a1509eSRui Ueyama } else if (S.startswith("=")) { 118352a1509eSRui Ueyama if (Config->Sysroot.empty()) 118452a1509eSRui Ueyama Driver->addFile(S.substr(1)); 118552a1509eSRui Ueyama else 118652a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 118752a1509eSRui Ueyama } else if (S.startswith("-l")) { 118821eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 1189a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 1190a1b8fc3bSSimon Atanasyan Driver->addFile(S); 119152a1509eSRui Ueyama } else { 1192061f9286SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(S)) 1193061f9286SRui Ueyama Driver->addFile(Saver.save(*Path)); 1194025d59b1SRui Ueyama else 1195061f9286SRui Ueyama setError("unable to find " + S); 119652a1509eSRui Ueyama } 119752a1509eSRui Ueyama } 119852a1509eSRui Ueyama 1199717677afSRui Ueyama void ScriptParser::readAsNeeded() { 1200f7c5fbb1SRui Ueyama expect("("); 120135da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 120235da9b6eSRui Ueyama Config->AsNeeded = true; 120383043f23SRui Ueyama while (!Error && !consume(")")) 1204cd574a5eSGeorge Rimar addFile(unquote(next())); 120535da9b6eSRui Ueyama Config->AsNeeded = Orig; 1206f7c5fbb1SRui Ueyama } 1207f7c5fbb1SRui Ueyama 1208717677afSRui Ueyama void ScriptParser::readEntry() { 120990c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 121090c5099eSDenis Protivensky expect("("); 121190c5099eSDenis Protivensky StringRef Tok = next(); 121290c5099eSDenis Protivensky if (Config->Entry.empty()) 121390c5099eSDenis Protivensky Config->Entry = Tok; 121490c5099eSDenis Protivensky expect(")"); 121590c5099eSDenis Protivensky } 121690c5099eSDenis Protivensky 1217717677afSRui Ueyama void ScriptParser::readExtern() { 121883f406cfSGeorge Rimar expect("("); 121983043f23SRui Ueyama while (!Error && !consume(")")) 1220a2acc931SRui Ueyama Config->Undefined.push_back(next()); 122183f406cfSGeorge Rimar } 122283f406cfSGeorge Rimar 1223717677afSRui Ueyama void ScriptParser::readGroup() { 1224f7c5fbb1SRui Ueyama expect("("); 122583043f23SRui Ueyama while (!Error && !consume(")")) { 1226f7c5fbb1SRui Ueyama StringRef Tok = next(); 1227a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 1228f7c5fbb1SRui Ueyama readAsNeeded(); 1229a2acc931SRui Ueyama else 1230cd574a5eSGeorge Rimar addFile(unquote(Tok)); 1231f7c5fbb1SRui Ueyama } 1232f7c5fbb1SRui Ueyama } 1233f7c5fbb1SRui Ueyama 1234717677afSRui Ueyama void ScriptParser::readInclude() { 1235d4500653SGeorge Rimar StringRef Tok = unquote(next()); 1236ec1c75e0SRui Ueyama 1237d4500653SGeorge Rimar // https://sourceware.org/binutils/docs/ld/File-Commands.html: 1238d4500653SGeorge Rimar // The file will be searched for in the current directory, and in any 1239d4500653SGeorge Rimar // directory specified with the -L option. 1240ec1c75e0SRui Ueyama if (sys::fs::exists(Tok)) { 1241ec1c75e0SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(Tok)) 1242ec1c75e0SRui Ueyama tokenize(*MB); 1243025d59b1SRui Ueyama return; 1244025d59b1SRui Ueyama } 1245ec1c75e0SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(Tok)) { 1246ec1c75e0SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(*Path)) 1247ec1c75e0SRui Ueyama tokenize(*MB); 1248ec1c75e0SRui Ueyama return; 1249ec1c75e0SRui Ueyama } 1250ec1c75e0SRui Ueyama setError("cannot open " + Tok); 125131aa1f83SRui Ueyama } 125231aa1f83SRui Ueyama 1253717677afSRui Ueyama void ScriptParser::readOutput() { 1254ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 1255ee59282bSRui Ueyama expect("("); 1256ee59282bSRui Ueyama StringRef Tok = next(); 1257ee59282bSRui Ueyama if (Config->OutputFile.empty()) 1258cd574a5eSGeorge Rimar Config->OutputFile = unquote(Tok); 1259ee59282bSRui Ueyama expect(")"); 1260ee59282bSRui Ueyama } 1261ee59282bSRui Ueyama 1262717677afSRui Ueyama void ScriptParser::readOutputArch() { 12634e01c3e8SGeorge Rimar // OUTPUT_ARCH is ignored for now. 12649159ce93SDavide Italiano expect("("); 12654e01c3e8SGeorge Rimar while (!Error && !consume(")")) 12665424e7c7SJustin Bogner skip(); 12679159ce93SDavide Italiano } 12689159ce93SDavide Italiano 1269717677afSRui Ueyama void ScriptParser::readOutputFormat() { 1270f7c5fbb1SRui Ueyama // Error checking only for now. 1271f7c5fbb1SRui Ueyama expect("("); 12725424e7c7SJustin Bogner skip(); 12736836c618SDavide Italiano StringRef Tok = next(); 12746836c618SDavide Italiano if (Tok == ")") 12756836c618SDavide Italiano return; 1276025d59b1SRui Ueyama if (Tok != ",") { 12775761042dSGeorge Rimar setError("unexpected token: " + Tok); 1278025d59b1SRui Ueyama return; 1279025d59b1SRui Ueyama } 12805424e7c7SJustin Bogner skip(); 12816836c618SDavide Italiano expect(","); 12825424e7c7SJustin Bogner skip(); 1283f7c5fbb1SRui Ueyama expect(")"); 1284f7c5fbb1SRui Ueyama } 1285f7c5fbb1SRui Ueyama 1286bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 1287bbe38602SEugene Leviant expect("{"); 128883043f23SRui Ueyama while (!Error && !consume("}")) { 1289bbe38602SEugene Leviant StringRef Tok = next(); 129056b21c86SEugene Leviant Opt.PhdrsCommands.push_back( 129156b21c86SEugene Leviant {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 1292bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 1293bbe38602SEugene Leviant 1294bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 1295bbe38602SEugene Leviant do { 1296bbe38602SEugene Leviant Tok = next(); 1297bbe38602SEugene Leviant if (Tok == ";") 1298bbe38602SEugene Leviant break; 1299bbe38602SEugene Leviant if (Tok == "FILEHDR") 1300bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 1301bbe38602SEugene Leviant else if (Tok == "PHDRS") 1302bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 130356b21c86SEugene Leviant else if (Tok == "AT") 130456b21c86SEugene Leviant PhdrCmd.LMAExpr = readParenExpr(); 1305865bf863SEugene Leviant else if (Tok == "FLAGS") { 1306865bf863SEugene Leviant expect("("); 1307eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 1308eb685cd7SRafael Espindola // we accept expressions like ".|1". 1309eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 1310865bf863SEugene Leviant expect(")"); 1311865bf863SEugene Leviant } else 1312bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 1313bbe38602SEugene Leviant } while (!Error); 1314bbe38602SEugene Leviant } 1315bbe38602SEugene Leviant } 1316bbe38602SEugene Leviant 1317717677afSRui Ueyama void ScriptParser::readSearchDir() { 131868a39a65SDavide Italiano expect("("); 131986c5fb82SRui Ueyama StringRef Tok = next(); 13206c7ad13fSRui Ueyama if (!Config->Nostdlib) 1321cd574a5eSGeorge Rimar Config->SearchPaths.push_back(unquote(Tok)); 132268a39a65SDavide Italiano expect(")"); 132368a39a65SDavide Italiano } 132468a39a65SDavide Italiano 1325717677afSRui Ueyama void ScriptParser::readSections() { 1326e05336ffSEugene Leviant Opt.HasSections = true; 132718a30962SGeorge Rimar // -no-rosegment is used to avoid placing read only non-executable sections in 132818a30962SGeorge Rimar // their own segment. We do the same if SECTIONS command is present in linker 132918a30962SGeorge Rimar // script. See comment for computeFlags(). 133018a30962SGeorge Rimar Config->SingleRoRx = true; 133118a30962SGeorge Rimar 13328e3b38abSDenis Protivensky expect("{"); 133383043f23SRui Ueyama while (!Error && !consume("}")) { 1334113cdec9SRui Ueyama StringRef Tok = next(); 1335c96da110SRafael Espindola BaseCommand *Cmd = readProvideOrAssignment(Tok); 1336ceabe80eSEugene Leviant if (!Cmd) { 1337ceabe80eSEugene Leviant if (Tok == "ASSERT") 1338eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 1339ceabe80eSEugene Leviant else 134010416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 13418e3b38abSDenis Protivensky } 134210416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 1343652852c5SGeorge Rimar } 1344708019c4SRui Ueyama } 13458e3b38abSDenis Protivensky 1346708019c4SRui Ueyama static int precedence(StringRef Op) { 1347708019c4SRui Ueyama return StringSwitch<int>(Op) 13480120e3f2SRui Ueyama .Cases("*", "/", 5) 13490120e3f2SRui Ueyama .Cases("+", "-", 4) 13500120e3f2SRui Ueyama .Cases("<<", ">>", 3) 13519c4ac5f2SRui Ueyama .Cases("<", "<=", ">", ">=", "==", "!=", 2) 13520120e3f2SRui Ueyama .Cases("&", "|", 1) 1353708019c4SRui Ueyama .Default(-1); 1354708019c4SRui Ueyama } 1355708019c4SRui Ueyama 1356db688454SEugene Leviant StringMatcher ScriptParser::readFilePatterns() { 135710416564SRui Ueyama std::vector<StringRef> V; 135883043f23SRui Ueyama while (!Error && !consume(")")) 135910416564SRui Ueyama V.push_back(next()); 1360f91282e1SRui Ueyama return StringMatcher(V); 13610702c4e8SGeorge Rimar } 13620702c4e8SGeorge Rimar 1363be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() { 136483043f23SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 1365be394db3SGeorge Rimar return SortSectionPolicy::Name; 136683043f23SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 1367be394db3SGeorge Rimar return SortSectionPolicy::Alignment; 136883043f23SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 1369be394db3SGeorge Rimar return SortSectionPolicy::Priority; 137083043f23SRui Ueyama if (consume("SORT_NONE")) 1371be394db3SGeorge Rimar return SortSectionPolicy::None; 1372b2a0abdfSRui Ueyama return SortSectionPolicy::Default; 1373be394db3SGeorge Rimar } 1374be394db3SGeorge Rimar 1375395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in 1376395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ 1377395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) 1378af03be19SGeorge Rimar // The semantics of that is next: 1379af03be19SGeorge Rimar // * Include .foo.1 from every file. 1380af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o 1381af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o 138207171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 138307171f21SGeorge Rimar std::vector<SectionPattern> Ret; 1384601e9898SGeorge Rimar while (!Error && peek() != ")") { 1385f91282e1SRui Ueyama StringMatcher ExcludeFilePat; 138683043f23SRui Ueyama if (consume("EXCLUDE_FILE")) { 1387395281cfSGeorge Rimar expect("("); 1388f91282e1SRui Ueyama ExcludeFilePat = readFilePatterns(); 1389395281cfSGeorge Rimar } 1390395281cfSGeorge Rimar 1391601e9898SGeorge Rimar std::vector<StringRef> V; 1392601e9898SGeorge Rimar while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE") 1393395281cfSGeorge Rimar V.push_back(next()); 1394601e9898SGeorge Rimar 1395601e9898SGeorge Rimar if (!V.empty()) 1396f91282e1SRui Ueyama Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); 1397601e9898SGeorge Rimar else 1398601e9898SGeorge Rimar setError("section pattern is expected"); 1399395281cfSGeorge Rimar } 140007171f21SGeorge Rimar return Ret; 1401395281cfSGeorge Rimar } 1402395281cfSGeorge Rimar 1403f8f6f1e7SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a 1404f8f6f1e7SRui Ueyama // list of glob patterns for input sections. The grammar is as follows. 1405f8f6f1e7SRui Ueyama // 1406f8f6f1e7SRui Ueyama // <patterns> ::= <section-list> 1407f8f6f1e7SRui Ueyama // | <sort> "(" <section-list> ")" 1408f8f6f1e7SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")" 1409f8f6f1e7SRui Ueyama // 1410f8f6f1e7SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 1411f8f6f1e7SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 1412f8f6f1e7SRui Ueyama // 1413f8f6f1e7SRui Ueyama // <section-list> is parsed by readInputSectionsList(). 1414a2496cbeSGeorge Rimar InputSectionDescription * 1415a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 1416c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 14170ed42b0cSDavide Italiano expect("("); 1418f373dd76SRui Ueyama while (!Error && !consume(")")) { 141907171f21SGeorge Rimar SortSectionPolicy Outer = readSortKind(); 142007171f21SGeorge Rimar SortSectionPolicy Inner = SortSectionPolicy::Default; 142107171f21SGeorge Rimar std::vector<SectionPattern> V; 142207171f21SGeorge Rimar if (Outer != SortSectionPolicy::Default) { 14230702c4e8SGeorge Rimar expect("("); 142407171f21SGeorge Rimar Inner = readSortKind(); 142507171f21SGeorge Rimar if (Inner != SortSectionPolicy::Default) { 1426350ece4eSGeorge Rimar expect("("); 142707171f21SGeorge Rimar V = readInputSectionsList(); 14280702c4e8SGeorge Rimar expect(")"); 1429350ece4eSGeorge Rimar } else { 143007171f21SGeorge Rimar V = readInputSectionsList(); 1431350ece4eSGeorge Rimar } 1432350ece4eSGeorge Rimar expect(")"); 143307171f21SGeorge Rimar } else { 143407171f21SGeorge Rimar V = readInputSectionsList(); 14350659800eSGeorge Rimar } 14360702c4e8SGeorge Rimar 143707171f21SGeorge Rimar for (SectionPattern &Pat : V) { 143807171f21SGeorge Rimar Pat.SortInner = Inner; 143907171f21SGeorge Rimar Pat.SortOuter = Outer; 144007171f21SGeorge Rimar } 144107171f21SGeorge Rimar 144207171f21SGeorge Rimar std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 144307171f21SGeorge Rimar } 144410416564SRui Ueyama return Cmd; 14450659800eSGeorge Rimar } 14460659800eSGeorge Rimar 1447a2496cbeSGeorge Rimar InputSectionDescription * 1448a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 14490659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 14500659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 1451a2496cbeSGeorge Rimar if (Tok == "KEEP") { 1452e7282797SDavide Italiano expect("("); 1453a2496cbeSGeorge Rimar StringRef FilePattern = next(); 1454a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 14550ed42b0cSDavide Italiano expect(")"); 1456cf43f179SEugene Leviant Opt.KeptSections.push_back(Cmd); 145710416564SRui Ueyama return Cmd; 145810416564SRui Ueyama } 1459a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 14600659800eSGeorge Rimar } 14610659800eSGeorge Rimar 146203fc010eSGeorge Rimar void ScriptParser::readSort() { 146303fc010eSGeorge Rimar expect("("); 146403fc010eSGeorge Rimar expect("CONSTRUCTORS"); 146503fc010eSGeorge Rimar expect(")"); 146603fc010eSGeorge Rimar } 146703fc010eSGeorge Rimar 1468eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 1469eefa758eSGeorge Rimar expect("("); 1470eefa758eSGeorge Rimar Expr E = readExpr(); 1471eefa758eSGeorge Rimar expect(","); 1472cd574a5eSGeorge Rimar StringRef Msg = unquote(next()); 1473eefa758eSGeorge Rimar expect(")"); 1474eefa758eSGeorge Rimar return [=](uint64_t Dot) { 1475eefa758eSGeorge Rimar uint64_t V = E(Dot); 1476eefa758eSGeorge Rimar if (!V) 1477eefa758eSGeorge Rimar error(Msg); 1478eefa758eSGeorge Rimar return V; 1479eefa758eSGeorge Rimar }; 1480eefa758eSGeorge Rimar } 1481eefa758eSGeorge Rimar 148225150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 148325150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from 148425150e8bSRui Ueyama // what GNU linkers do. 148525150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 148616068aebSRui Ueyama uint32_t ScriptParser::readFill() { 1487ff1f29e0SGeorge Rimar expect("("); 148816068aebSRui Ueyama uint32_t V = readOutputSectionFiller(next()); 1489ff1f29e0SGeorge Rimar expect(")"); 1490ff1f29e0SGeorge Rimar expect(";"); 1491ff1f29e0SGeorge Rimar return V; 1492ff1f29e0SGeorge Rimar } 1493ff1f29e0SGeorge Rimar 149410416564SRui Ueyama OutputSectionCommand * 149510416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 1496076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 14972a942c4bSEugene Leviant Cmd->Location = getCurrentLocation(); 149858e5c4dcSGeorge Rimar 149958e5c4dcSGeorge Rimar // Read an address expression. 150058e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 150158e5c4dcSGeorge Rimar if (peek() != ":") 150258e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 150358e5c4dcSGeorge Rimar 15048e3b38abSDenis Protivensky expect(":"); 1505246f681eSDavide Italiano 150683043f23SRui Ueyama if (consume("AT")) 1507b71d6f7aSEugene Leviant Cmd->LMAExpr = readParenExpr(); 150883043f23SRui Ueyama if (consume("ALIGN")) 15096ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 151083043f23SRui Ueyama if (consume("SUBALIGN")) 1511db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1512630c6179SGeorge Rimar 1513246f681eSDavide Italiano // Parse constraints. 151483043f23SRui Ueyama if (consume("ONLY_IF_RO")) 1515efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 151683043f23SRui Ueyama if (consume("ONLY_IF_RW")) 1517efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 15188e3b38abSDenis Protivensky expect("{"); 15198ec77e64SRui Ueyama 152083043f23SRui Ueyama while (!Error && !consume("}")) { 1521ceabe80eSEugene Leviant StringRef Tok = next(); 15222fe07923SGeorge Rimar if (Tok == ";") { 152369750755SGeorge Rimar // Empty commands are allowed. Do nothing here. 15242fe07923SGeorge Rimar } else if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) { 1525ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1526b2d99d6aSMeador Inge } else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) { 1527e38cbab5SGeorge Rimar Cmd->Commands.emplace_back(Data); 1528b2d99d6aSMeador Inge } else if (Tok == "ASSERT") { 1529b2d99d6aSMeador Inge Cmd->Commands.emplace_back(new AssertCommand(readAssert())); 1530b2d99d6aSMeador Inge expect(";"); 15318e2eca22SGeorge Rimar } else if (Tok == "CONSTRUCTORS") { 15328e2eca22SGeorge Rimar // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors 15338e2eca22SGeorge Rimar // by name. This is for very old file formats such as ECOFF/XCOFF. 15348e2eca22SGeorge Rimar // For ELF, we should ignore. 1535b2d99d6aSMeador Inge } else if (Tok == "FILL") { 1536ff1f29e0SGeorge Rimar Cmd->Filler = readFill(); 1537b2d99d6aSMeador Inge } else if (Tok == "SORT") { 153803fc010eSGeorge Rimar readSort(); 1539b2d99d6aSMeador Inge } else if (peek() == "(") { 1540a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1541b2d99d6aSMeador Inge } else { 1542ceabe80eSEugene Leviant setError("unknown command " + Tok); 15438e3b38abSDenis Protivensky } 1544b2d99d6aSMeador Inge } 1545b889744eSMeador Inge 1546b889744eSMeador Inge if (consume(">")) 1547b889744eSMeador Inge Cmd->MemoryRegionName = next(); 1548b889744eSMeador Inge 1549076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 15504ebc5620SGeorge Rimar 155183043f23SRui Ueyama if (consume("=")) 15524ebc5620SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next()); 15534ebc5620SGeorge Rimar else if (peek().startswith("=")) 1554ff1f29e0SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next().drop_front()); 15554ebc5620SGeorge Rimar 15567185a1acSGeorge Rimar // Consume optional comma following output section command. 15577185a1acSGeorge Rimar consume(","); 15587185a1acSGeorge Rimar 155910416564SRui Ueyama return Cmd; 1560f71caa2bSRui Ueyama } 15618ec77e64SRui Ueyama 15622c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 15632c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 15642c8f1f04SRui Ueyama // 15652c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 15662c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 15672c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 15682c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 156916068aebSRui Ueyama uint32_t ScriptParser::readOutputSectionFiller(StringRef Tok) { 1570965827d6SRui Ueyama uint32_t V; 157116068aebSRui Ueyama if (!Tok.getAsInteger(0, V)) 157216068aebSRui Ueyama return V; 1573965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 157416068aebSRui Ueyama return 0; 15758e3b38abSDenis Protivensky } 15768e3b38abSDenis Protivensky 1577a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1578a31c91b1SEugene Leviant expect("("); 1579174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1580a35e39caSPetr Hosek Cmd->Provide = Provide; 1581174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1582a31c91b1SEugene Leviant expect(")"); 1583a31c91b1SEugene Leviant expect(";"); 158410416564SRui Ueyama return Cmd; 1585eda81a1bSEugene Leviant } 1586eda81a1bSEugene Leviant 1587c96da110SRafael Espindola SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 1588ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1589ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1590ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1591ceabe80eSEugene Leviant expect(";"); 1592ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1593a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1594a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1595a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1596ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1597a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1598ceabe80eSEugene Leviant } 1599ceabe80eSEugene Leviant return Cmd; 1600ceabe80eSEugene Leviant } 1601ceabe80eSEugene Leviant 1602f6aeed36SEugene Leviant static uint64_t getSymbolValue(const Twine &Loc, StringRef S, uint64_t Dot) { 160330835ea4SGeorge Rimar if (S == ".") 160430835ea4SGeorge Rimar return Dot; 1605f6aeed36SEugene Leviant return ScriptBase->getSymbolValue(Loc, S); 1606e32a3598SGeorge Rimar } 1607e32a3598SGeorge Rimar 16082f831dcaSRafael Espindola static bool isAbsolute(StringRef S) { 16092f831dcaSRafael Espindola if (S == ".") 16102f831dcaSRafael Espindola return false; 16112f831dcaSRafael Espindola return ScriptBase->isAbsolute(S); 16122f831dcaSRafael Espindola } 16132f831dcaSRafael Espindola 161430835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 161530835ea4SGeorge Rimar StringRef Op = next(); 1616db741e72SEugene Leviant Expr E; 161730835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 161883043f23SRui Ueyama if (consume("ABSOLUTE")) { 1619731a66aeSRui Ueyama E = readExpr(); 1620009d1742SRui Ueyama E.IsAbsolute = [] { return true; }; 1621db741e72SEugene Leviant } else { 1622db741e72SEugene Leviant E = readExpr(); 1623db741e72SEugene Leviant } 1624f6aeed36SEugene Leviant if (Op == "+=") { 1625f6aeed36SEugene Leviant std::string Loc = getCurrentLocation(); 1626f6aeed36SEugene Leviant E = [=](uint64_t Dot) { 1627f6aeed36SEugene Leviant return getSymbolValue(Loc, Name, Dot) + E(Dot); 1628f6aeed36SEugene Leviant }; 1629f6aeed36SEugene Leviant } 1630f661393aSRafael Espindola return new SymbolAssignment(Name, E); 163130835ea4SGeorge Rimar } 163230835ea4SGeorge Rimar 163330835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 163430835ea4SGeorge Rimar // script expression. 1635731a66aeSRui Ueyama Expr ScriptParser::readExpr() { 1636731a66aeSRui Ueyama // Our lexer is context-aware. Set the in-expression bit so that 1637731a66aeSRui Ueyama // they apply different tokenization rules. 1638731a66aeSRui Ueyama bool Orig = InExpr; 1639731a66aeSRui Ueyama InExpr = true; 1640731a66aeSRui Ueyama Expr E = readExpr1(readPrimary(), 0); 1641731a66aeSRui Ueyama InExpr = Orig; 1642731a66aeSRui Ueyama return E; 1643731a66aeSRui Ueyama } 164430835ea4SGeorge Rimar 164536c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 1646cc4d3e57SGeorge Rimar auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); }; 1647cc4d3e57SGeorge Rimar auto GetOutSec = [=] { 1648cc4d3e57SGeorge Rimar const OutputSectionBase *S = L.Section(); 1649cc4d3e57SGeorge Rimar return S ? S : R.Section(); 1650cc4d3e57SGeorge Rimar }; 1651cc4d3e57SGeorge Rimar 165236c1cd23SRui Ueyama if (Op == "*") 165336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 165436c1cd23SRui Ueyama if (Op == "/") { 165536c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 165636c1cd23SRui Ueyama uint64_t RHS = R(Dot); 165736c1cd23SRui Ueyama if (RHS == 0) { 165836c1cd23SRui Ueyama error("division by zero"); 165936c1cd23SRui Ueyama return 0; 166036c1cd23SRui Ueyama } 166136c1cd23SRui Ueyama return L(Dot) / RHS; 166236c1cd23SRui Ueyama }; 166336c1cd23SRui Ueyama } 166436c1cd23SRui Ueyama if (Op == "+") 1665cc4d3e57SGeorge Rimar return {[=](uint64_t Dot) { return L(Dot) + R(Dot); }, IsAbs, GetOutSec}; 166636c1cd23SRui Ueyama if (Op == "-") 1667cc4d3e57SGeorge Rimar return {[=](uint64_t Dot) { return L(Dot) - R(Dot); }, IsAbs, GetOutSec}; 1668c8ccd1f1SGeorge Rimar if (Op == "<<") 1669c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) << R(Dot); }; 1670c8ccd1f1SGeorge Rimar if (Op == ">>") 1671c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) >> R(Dot); }; 167236c1cd23SRui Ueyama if (Op == "<") 167336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 167436c1cd23SRui Ueyama if (Op == ">") 167536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 167636c1cd23SRui Ueyama if (Op == ">=") 167736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 167836c1cd23SRui Ueyama if (Op == "<=") 167936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 168036c1cd23SRui Ueyama if (Op == "==") 168136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 168236c1cd23SRui Ueyama if (Op == "!=") 168336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 168436c1cd23SRui Ueyama if (Op == "&") 168536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 1686cc3dd629SRafael Espindola if (Op == "|") 1687cc3dd629SRafael Espindola return [=](uint64_t Dot) { return L(Dot) | R(Dot); }; 168836c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 168936c1cd23SRui Ueyama } 169036c1cd23SRui Ueyama 1691708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1692708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1693708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1694708019c4SRui Ueyama while (!atEOF() && !Error) { 1695708019c4SRui Ueyama // Read an operator and an expression. 169646247b85SRui Ueyama if (consume("?")) 1697708019c4SRui Ueyama return readTernary(Lhs); 169846247b85SRui Ueyama StringRef Op1 = peek(); 1699708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1700a31c91b1SEugene Leviant break; 17015424e7c7SJustin Bogner skip(); 1702708019c4SRui Ueyama Expr Rhs = readPrimary(); 1703708019c4SRui Ueyama 1704708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1705708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1706708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1707708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1708708019c4SRui Ueyama while (!atEOF()) { 1709708019c4SRui Ueyama StringRef Op2 = peek(); 1710708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1711eda81a1bSEugene Leviant break; 1712708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1713eda81a1bSEugene Leviant } 1714708019c4SRui Ueyama 1715708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1716708019c4SRui Ueyama } 1717708019c4SRui Ueyama return Lhs; 1718708019c4SRui Ueyama } 1719708019c4SRui Ueyama 1720708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1721e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1722708019c4SRui Ueyama return Target->PageSize; 1723e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1724997f8838SPetr Hosek return Config->MaxPageSize; 1725708019c4SRui Ueyama error("unknown constant: " + S); 1726708019c4SRui Ueyama return 0; 1727708019c4SRui Ueyama } 1728708019c4SRui Ueyama 1729626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1730626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1731626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1732626e0b08SRui Ueyama // "M" (mega) prefixes. 17339f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 173446247b85SRui Ueyama // Negative number 1735eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1736eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1737eaeafb2bSSimon Atanasyan return false; 1738eaeafb2bSSimon Atanasyan Result = -Result; 1739eaeafb2bSSimon Atanasyan return true; 1740eaeafb2bSSimon Atanasyan } 174146247b85SRui Ueyama 174246247b85SRui Ueyama // Hexadecimal 17439f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 17449f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 17459f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 17469f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 17479f2f7ad9SGeorge Rimar 174846247b85SRui Ueyama // Decimal 17499f2f7ad9SGeorge Rimar int Suffix = 1; 17509f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 17519f2f7ad9SGeorge Rimar Suffix = 1024; 17529f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 17539f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 17549f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 17559f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 17569f2f7ad9SGeorge Rimar } 17579f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 17589f2f7ad9SGeorge Rimar return false; 17599f2f7ad9SGeorge Rimar Result *= Suffix; 17609f2f7ad9SGeorge Rimar return true; 17619f2f7ad9SGeorge Rimar } 17629f2f7ad9SGeorge Rimar 1763e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { 1764e38cbab5SGeorge Rimar int Size = StringSwitch<unsigned>(Tok) 1765e38cbab5SGeorge Rimar .Case("BYTE", 1) 1766e38cbab5SGeorge Rimar .Case("SHORT", 2) 1767e38cbab5SGeorge Rimar .Case("LONG", 4) 1768e38cbab5SGeorge Rimar .Case("QUAD", 8) 1769e38cbab5SGeorge Rimar .Default(-1); 1770e38cbab5SGeorge Rimar if (Size == -1) 1771e38cbab5SGeorge Rimar return nullptr; 1772e38cbab5SGeorge Rimar 177395c7d8d2SMeador Inge return new BytesDataCommand(readParenExpr(), Size); 1774e38cbab5SGeorge Rimar } 1775e38cbab5SGeorge Rimar 1776b71d6f7aSEugene Leviant StringRef ScriptParser::readParenLiteral() { 1777b71d6f7aSEugene Leviant expect("("); 1778b71d6f7aSEugene Leviant StringRef Tok = next(); 1779b71d6f7aSEugene Leviant expect(")"); 1780b71d6f7aSEugene Leviant return Tok; 1781b71d6f7aSEugene Leviant } 1782b71d6f7aSEugene Leviant 1783708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 17846ad7dfccSRui Ueyama if (peek() == "(") 17856ad7dfccSRui Ueyama return readParenExpr(); 1786708019c4SRui Ueyama 17876ad7dfccSRui Ueyama StringRef Tok = next(); 1788b5f1c3ecSRui Ueyama std::string Location = getCurrentLocation(); 1789708019c4SRui Ueyama 1790eaeafb2bSSimon Atanasyan if (Tok == "~") { 1791eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1792eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return ~E(Dot); }; 1793eaeafb2bSSimon Atanasyan } 1794eaeafb2bSSimon Atanasyan if (Tok == "-") { 1795eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1796eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return -E(Dot); }; 1797eaeafb2bSSimon Atanasyan } 1798eaeafb2bSSimon Atanasyan 1799708019c4SRui Ueyama // Built-in functions are parsed here. 1800708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 180196659df0SGeorge Rimar if (Tok == "ADDR") { 1802b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1803ed30ce7aSEugene Leviant return {[=](uint64_t Dot) { 1804ed30ce7aSEugene Leviant return ScriptBase->getOutputSection(Location, Name)->Addr; 1805ed30ce7aSEugene Leviant }, 1806009d1742SRui Ueyama [=] { return false; }, 1807ed30ce7aSEugene Leviant [=] { return ScriptBase->getOutputSection(Location, Name); }}; 180896659df0SGeorge Rimar } 1809b71d6f7aSEugene Leviant if (Tok == "LOADADDR") { 1810b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1811afaa9343SEugene Leviant return [=](uint64_t Dot) { 1812ed30ce7aSEugene Leviant return ScriptBase->getOutputSection(Location, Name)->getLMA(); 1813afaa9343SEugene Leviant }; 1814b71d6f7aSEugene Leviant } 1815eefa758eSGeorge Rimar if (Tok == "ASSERT") 1816eefa758eSGeorge Rimar return readAssert(); 1817708019c4SRui Ueyama if (Tok == "ALIGN") { 18185d804dc8SRui Ueyama expect("("); 18195d804dc8SRui Ueyama Expr E = readExpr(); 18205d804dc8SRui Ueyama if (consume(",")) { 18215d804dc8SRui Ueyama Expr E2 = readExpr(); 18225d804dc8SRui Ueyama expect(")"); 18235d804dc8SRui Ueyama return [=](uint64_t Dot) { return alignTo(E(Dot), E2(Dot)); }; 18245d804dc8SRui Ueyama } 18255d804dc8SRui Ueyama expect(")"); 1826708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1827708019c4SRui Ueyama } 1828708019c4SRui Ueyama if (Tok == "CONSTANT") { 1829b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1830b0de56b5SRafael Espindola return [=](uint64_t Dot) { return getConstant(Name); }; 1831708019c4SRui Ueyama } 1832f34f45fdSGeorge Rimar if (Tok == "DEFINED") { 18330ee25a69SRui Ueyama StringRef Name = readParenLiteral(); 18340ee25a69SRui Ueyama return [=](uint64_t Dot) { return ScriptBase->isDefined(Name) ? 1 : 0; }; 1835f34f45fdSGeorge Rimar } 183654c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 183754c145ceSRafael Espindola expect("("); 18385424e7c7SJustin Bogner skip(); 183954c145ceSRafael Espindola expect(","); 18408c658bf8SGeorge Rimar Expr E = readExpr(); 184154c145ceSRafael Espindola expect(")"); 18428c658bf8SGeorge Rimar return [=](uint64_t Dot) { return E(Dot); }; 184354c145ceSRafael Espindola } 1844708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1845708019c4SRui Ueyama expect("("); 1846708019c4SRui Ueyama Expr E = readExpr(); 1847708019c4SRui Ueyama expect(","); 1848708019c4SRui Ueyama readExpr(); 1849708019c4SRui Ueyama expect(")"); 1850f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1851708019c4SRui Ueyama } 1852708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1853708019c4SRui Ueyama expect("("); 1854708019c4SRui Ueyama expect("."); 1855708019c4SRui Ueyama expect(")"); 1856708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1857708019c4SRui Ueyama } 1858276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1859276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1860276b4e64SGeorge Rimar // the next page boundary for simplicity. 1861276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1862276b4e64SGeorge Rimar expect("("); 186397bdc722SRafael Espindola readExpr(); 1864276b4e64SGeorge Rimar expect(","); 1865276b4e64SGeorge Rimar readExpr(); 1866276b4e64SGeorge Rimar expect(")"); 1867276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1868276b4e64SGeorge Rimar } 18699e69450eSGeorge Rimar if (Tok == "SIZEOF") { 1870b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1871edf75e79SRui Ueyama return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; 18729e69450eSGeorge Rimar } 187336fac7f0SEugene Leviant if (Tok == "ALIGNOF") { 1874b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1875afaa9343SEugene Leviant return [=](uint64_t Dot) { 1876ed30ce7aSEugene Leviant return ScriptBase->getOutputSection(Location, Name)->Addralign; 1877afaa9343SEugene Leviant }; 187836fac7f0SEugene Leviant } 1879e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 1880b0de56b5SRafael Espindola return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; 1881708019c4SRui Ueyama 18829f2f7ad9SGeorge Rimar // Tok is a literal number. 18839f2f7ad9SGeorge Rimar uint64_t V; 18849f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 1885b0de56b5SRafael Espindola return [=](uint64_t Dot) { return V; }; 18869f2f7ad9SGeorge Rimar 18879f2f7ad9SGeorge Rimar // Tok is a symbol name. 188830835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1889708019c4SRui Ueyama setError("malformed number: " + Tok); 1890f6aeed36SEugene Leviant return {[=](uint64_t Dot) { return getSymbolValue(Location, Tok, Dot); }, 1891009d1742SRui Ueyama [=] { return isAbsolute(Tok); }, 1892009d1742SRui Ueyama [=] { return ScriptBase->getSymbolSection(Tok); }}; 1893a9c5a528SGeorge Rimar } 1894708019c4SRui Ueyama 1895708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1896708019c4SRui Ueyama Expr L = readExpr(); 1897708019c4SRui Ueyama expect(":"); 1898708019c4SRui Ueyama Expr R = readExpr(); 1899708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1900708019c4SRui Ueyama } 1901708019c4SRui Ueyama 19026ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 19036ad7dfccSRui Ueyama expect("("); 19046ad7dfccSRui Ueyama Expr E = readExpr(); 19056ad7dfccSRui Ueyama expect(")"); 19066ad7dfccSRui Ueyama return E; 19076ad7dfccSRui Ueyama } 19086ad7dfccSRui Ueyama 1909bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1910bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1911bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1912bbe38602SEugene Leviant StringRef Tok = next(); 1913da841c16SGeorge Rimar Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); 1914bbe38602SEugene Leviant } 1915bbe38602SEugene Leviant return Phdrs; 1916bbe38602SEugene Leviant } 1917bbe38602SEugene Leviant 191895dd718cSGeorge Rimar // Read a program header type name. The next token must be a 191995dd718cSGeorge Rimar // name of a program header type or a constant (e.g. "0x3"). 1920bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1921bbe38602SEugene Leviant StringRef Tok = next(); 192295dd718cSGeorge Rimar uint64_t Val; 192395dd718cSGeorge Rimar if (readInteger(Tok, Val)) 192495dd718cSGeorge Rimar return Val; 192595dd718cSGeorge Rimar 1926b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1927b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1928b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1929b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1930b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1931b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1932b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1933b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1934b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1935b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1936b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1937b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1938270173f2SGeorge Rimar .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 1939cc6e567cSGeorge Rimar .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 1940a2a32c2cSGeorge Rimar .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) 1941b0f6c590SRui Ueyama .Default(-1); 1942bbe38602SEugene Leviant 1943b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1944b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1945b0f6c590SRui Ueyama return PT_NULL; 1946b0f6c590SRui Ueyama } 1947b0f6c590SRui Ueyama return Ret; 1948bbe38602SEugene Leviant } 1949bbe38602SEugene Leviant 195012450b20SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 195112450b20SRui Ueyama void ScriptParser::readAnonymousDeclaration() { 195212450b20SRui Ueyama // Read global symbols first. "global:" is default, so if there's 195312450b20SRui Ueyama // no label, we assume global symbols. 19544524268cSRafael Espindola if (peek() != "local") { 19554524268cSRafael Espindola if (consume("global")) 19564524268cSRafael Espindola expect(":"); 1957904c5ed5SPeter Collingbourne for (SymbolVersion V : readSymbols()) 1958904c5ed5SPeter Collingbourne Config->VersionScriptGlobals.push_back(V); 19594524268cSRafael Espindola } 1960e999ddb8SRafael Espindola readLocals(); 196112450b20SRui Ueyama expect("}"); 196212450b20SRui Ueyama expect(";"); 196312450b20SRui Ueyama } 196412450b20SRui Ueyama 1965e999ddb8SRafael Espindola void ScriptParser::readLocals() { 19664524268cSRafael Espindola if (!consume("local")) 1967e999ddb8SRafael Espindola return; 19684524268cSRafael Espindola expect(":"); 1969e999ddb8SRafael Espindola std::vector<SymbolVersion> Locals = readSymbols(); 1970e999ddb8SRafael Espindola for (SymbolVersion V : Locals) { 1971e999ddb8SRafael Espindola if (V.Name == "*") { 1972e999ddb8SRafael Espindola Config->DefaultSymbolVersion = VER_NDX_LOCAL; 1973e999ddb8SRafael Espindola continue; 1974e999ddb8SRafael Espindola } 1975e999ddb8SRafael Espindola Config->VersionScriptLocals.push_back(V); 1976e999ddb8SRafael Espindola } 1977e999ddb8SRafael Espindola } 1978e999ddb8SRafael Espindola 197912450b20SRui Ueyama // Reads a list of symbols, e.g. "VerStr { global: foo; bar; local: *; };". 198095769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 198120b6598cSGeorge Rimar // Identifiers start at 2 because 0 and 1 are reserved 198220b6598cSGeorge Rimar // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. 1983da805c48SRui Ueyama uint16_t VersionId = Config->VersionDefinitions.size() + 2; 198420b6598cSGeorge Rimar Config->VersionDefinitions.push_back({VerStr, VersionId}); 198520b6598cSGeorge Rimar 198612450b20SRui Ueyama // Read global symbols. 19874524268cSRafael Espindola if (peek() != "local") { 19884524268cSRafael Espindola if (consume("global")) 19894524268cSRafael Espindola expect(":"); 199012450b20SRui Ueyama Config->VersionDefinitions.back().Globals = readSymbols(); 19914524268cSRafael Espindola } 1992e999ddb8SRafael Espindola readLocals(); 199320b6598cSGeorge Rimar expect("}"); 199420b6598cSGeorge Rimar 199512450b20SRui Ueyama // Each version may have a parent version. For example, "Ver2" 199612450b20SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 199712450b20SRui Ueyama // as a parent. This version hierarchy is, probably against your 199812450b20SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it 199912450b20SRui Ueyama // at all. In LLD, we simply ignore it. 200012450b20SRui Ueyama if (peek() != ";") 20015424e7c7SJustin Bogner skip(); 200220b6598cSGeorge Rimar expect(";"); 200320b6598cSGeorge Rimar } 200420b6598cSGeorge Rimar 200512450b20SRui Ueyama // Reads a list of symbols for a versions cript. 200612450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readSymbols() { 200712450b20SRui Ueyama std::vector<SymbolVersion> Ret; 2008e0fc2421SGeorge Rimar for (;;) { 20091ef90d2fSRafael Espindola if (consume("extern")) { 201012450b20SRui Ueyama for (SymbolVersion V : readVersionExtern()) 201112450b20SRui Ueyama Ret.push_back(V); 20121ef90d2fSRafael Espindola continue; 20131ef90d2fSRafael Espindola } 2014e0fc2421SGeorge Rimar 2015f3965c02SDmitry Mikulin if (peek() == "}" || (peek() == "local" && peek(1) == ":") || Error) 201612450b20SRui Ueyama break; 20170ee25a69SRui Ueyama StringRef Tok = next(); 201812450b20SRui Ueyama Ret.push_back({unquote(Tok), false, hasWildcard(Tok)}); 2019e0fc2421SGeorge Rimar expect(";"); 2020e0fc2421SGeorge Rimar } 202112450b20SRui Ueyama return Ret; 2022e0fc2421SGeorge Rimar } 2023e0fc2421SGeorge Rimar 202412450b20SRui Ueyama // Reads an "extern C++" directive, e.g., 202512450b20SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };" 202612450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 20277e71415cSRafael Espindola StringRef Tok = next(); 20287e71415cSRafael Espindola bool IsCXX = Tok == "\"C++\""; 20297e71415cSRafael Espindola if (!IsCXX && Tok != "\"C\"") 2030d0ebd84cSRafael Espindola setError("Unknown language"); 203120b6598cSGeorge Rimar expect("{"); 203220b6598cSGeorge Rimar 203312450b20SRui Ueyama std::vector<SymbolVersion> Ret; 20340ee25a69SRui Ueyama while (!Error && peek() != "}") { 20350ee25a69SRui Ueyama StringRef Tok = next(); 20360ee25a69SRui Ueyama bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); 20377e71415cSRafael Espindola Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); 203820b6598cSGeorge Rimar expect(";"); 203920b6598cSGeorge Rimar } 204020b6598cSGeorge Rimar 204120b6598cSGeorge Rimar expect("}"); 204220b6598cSGeorge Rimar expect(";"); 204312450b20SRui Ueyama return Ret; 204420b6598cSGeorge Rimar } 204520b6598cSGeorge Rimar 204624e626ccSRui Ueyama uint64_t ScriptParser::readMemoryAssignment( 204724e626ccSRui Ueyama StringRef S1, StringRef S2, StringRef S3) { 204824e626ccSRui Ueyama if (!(consume(S1) || consume(S2) || consume(S3))) { 204924e626ccSRui Ueyama setError("expected one of: " + S1 + ", " + S2 + ", or " + S3); 205024e626ccSRui Ueyama return 0; 205124e626ccSRui Ueyama } 205224e626ccSRui Ueyama expect("="); 205324e626ccSRui Ueyama 205424e626ccSRui Ueyama // TODO: Fully support constant expressions. 205524e626ccSRui Ueyama uint64_t Val; 205624e626ccSRui Ueyama if (!readInteger(next(), Val)) 205724e626ccSRui Ueyama setError("nonconstant expression for "+ S1); 205824e626ccSRui Ueyama return Val; 205924e626ccSRui Ueyama } 206024e626ccSRui Ueyama 206124e626ccSRui Ueyama // Parse the MEMORY command as specified in: 206224e626ccSRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html 206324e626ccSRui Ueyama // 206424e626ccSRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } 2065b889744eSMeador Inge void ScriptParser::readMemory() { 2066b889744eSMeador Inge expect("{"); 2067b889744eSMeador Inge while (!Error && !consume("}")) { 2068b889744eSMeador Inge StringRef Name = next(); 206924e626ccSRui Ueyama 2070b889744eSMeador Inge uint32_t Flags = 0; 20718a8a953eSRui Ueyama uint32_t NegFlags = 0; 2072b889744eSMeador Inge if (consume("(")) { 20738a8a953eSRui Ueyama std::tie(Flags, NegFlags) = readMemoryAttributes(); 2074b889744eSMeador Inge expect(")"); 2075b889744eSMeador Inge } 2076b889744eSMeador Inge expect(":"); 2077b889744eSMeador Inge 207824e626ccSRui Ueyama uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o"); 2079b889744eSMeador Inge expect(","); 208024e626ccSRui Ueyama uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); 2081b889744eSMeador Inge 2082b889744eSMeador Inge // Add the memory region to the region map (if it doesn't already exist). 2083b889744eSMeador Inge auto It = Opt.MemoryRegions.find(Name); 2084b889744eSMeador Inge if (It != Opt.MemoryRegions.end()) 2085b889744eSMeador Inge setError("region '" + Name + "' already defined"); 2086b889744eSMeador Inge else 20878a8a953eSRui Ueyama Opt.MemoryRegions[Name] = {Name, Origin, Length, Origin, Flags, NegFlags}; 2088b889744eSMeador Inge } 2089b889744eSMeador Inge } 2090b889744eSMeador Inge 2091b889744eSMeador Inge // This function parses the attributes used to match against section 2092b889744eSMeador Inge // flags when placing output sections in a memory region. These flags 2093b889744eSMeador Inge // are only used when an explicit memory region name is not used. 2094b889744eSMeador Inge std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { 2095b889744eSMeador Inge uint32_t Flags = 0; 20968a8a953eSRui Ueyama uint32_t NegFlags = 0; 2097b889744eSMeador Inge bool Invert = false; 2098481ac996SRui Ueyama 2099481ac996SRui Ueyama for (char C : next().lower()) { 2100b889744eSMeador Inge uint32_t Flag = 0; 2101b889744eSMeador Inge if (C == '!') 2102b889744eSMeador Inge Invert = !Invert; 2103481ac996SRui Ueyama else if (C == 'w') 2104b889744eSMeador Inge Flag = SHF_WRITE; 2105481ac996SRui Ueyama else if (C == 'x') 2106b889744eSMeador Inge Flag = SHF_EXECINSTR; 2107481ac996SRui Ueyama else if (C == 'a') 2108b889744eSMeador Inge Flag = SHF_ALLOC; 2109481ac996SRui Ueyama else if (C != 'r') 2110b889744eSMeador Inge setError("invalid memory region attribute"); 2111481ac996SRui Ueyama 2112b889744eSMeador Inge if (Invert) 21138a8a953eSRui Ueyama NegFlags |= Flag; 2114b889744eSMeador Inge else 2115b889744eSMeador Inge Flags |= Flag; 2116b889744eSMeador Inge } 21178a8a953eSRui Ueyama return {Flags, NegFlags}; 2118b889744eSMeador Inge } 2119b889744eSMeador Inge 212007320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 212122375f24SRui Ueyama ScriptParser(MB).readLinkerScript(); 212220b6598cSGeorge Rimar } 212320b6598cSGeorge Rimar 212420b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 212522375f24SRui Ueyama ScriptParser(MB).readVersionScript(); 2126f7c5fbb1SRui Ueyama } 21271ebc8ed7SRui Ueyama 2128d0ebd84cSRafael Espindola void elf::readDynamicList(MemoryBufferRef MB) { 2129d0ebd84cSRafael Espindola ScriptParser(MB).readDynamicList(); 2130d0ebd84cSRafael Espindola } 2131d0ebd84cSRafael Espindola 213207320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 213307320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 213407320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 213507320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 2136