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" 20e77b5bf6SAdhemerval Zanella #include "ScriptParser.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 948f1f3c40SMeador Inge template <class ELFT> static void assignSymbol(SymbolAssignment *Cmd) { 958f1f3c40SMeador Inge // If there are sections, then let the value be assigned later in 968f1f3c40SMeador Inge // `assignAddresses`. 978f1f3c40SMeador Inge if (ScriptConfig->HasSections) 988f1f3c40SMeador Inge return; 998f1f3c40SMeador Inge 1008f1f3c40SMeador Inge uint64_t Value = Cmd->Expression(0); 1018f1f3c40SMeador Inge if (Cmd->Expression.IsAbsolute()) { 1028f1f3c40SMeador Inge cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Value; 1038f1f3c40SMeador Inge } else { 1048f1f3c40SMeador Inge const OutputSectionBase *Sec = Cmd->Expression.Section(); 1058f1f3c40SMeador Inge if (Sec) 1068f1f3c40SMeador Inge cast<DefinedSynthetic>(Cmd->Sym)->Value = Value - Sec->Addr; 107db741e72SEugene Leviant } 1088f1f3c40SMeador Inge } 1098f1f3c40SMeador Inge 1108f1f3c40SMeador Inge template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) { 1111602421cSRui Ueyama if (Cmd->Name == ".") 1128f1f3c40SMeador Inge return; 1138f1f3c40SMeador Inge 1148f1f3c40SMeador Inge // If a symbol was in PROVIDE(), we need to define it only when 1158f1f3c40SMeador Inge // it is a referenced undefined symbol. 1161602421cSRui Ueyama SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 1178f1f3c40SMeador Inge if (Cmd->Provide && (!B || B->isDefined())) 1188f1f3c40SMeador Inge return; 1198f1f3c40SMeador Inge 1208f1f3c40SMeador Inge // Otherwise, create a new symbol if one does not exist or an 1218f1f3c40SMeador Inge // undefined one does exist. 1228f1f3c40SMeador Inge if (Cmd->Expression.IsAbsolute()) 1238f1f3c40SMeador Inge Cmd->Sym = addRegular<ELFT>(Cmd); 1248f1f3c40SMeador Inge else 1258f1f3c40SMeador Inge Cmd->Sym = addSynthetic<ELFT>(Cmd); 1268f1f3c40SMeador Inge assignSymbol<ELFT>(Cmd); 127ceabe80eSEugene Leviant } 128ceabe80eSEugene Leviant 129076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 130076fe157SGeorge Rimar return C->Kind == AssignmentKind; 131076fe157SGeorge Rimar } 132076fe157SGeorge Rimar 133076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 134076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 135076fe157SGeorge Rimar } 136076fe157SGeorge Rimar 137eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 138eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 139eea3114fSGeorge Rimar } 140eea3114fSGeorge Rimar 141eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 142eefa758eSGeorge Rimar return C->Kind == AssertKind; 143eefa758eSGeorge Rimar } 144eefa758eSGeorge Rimar 145e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) { 146e38cbab5SGeorge Rimar return C->Kind == BytesDataKind; 147e38cbab5SGeorge Rimar } 148e38cbab5SGeorge Rimar 14922886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::LinkerScript() = default; 15022886a28SEugene Zelenko template <class ELFT> LinkerScript<ELFT>::~LinkerScript() = default; 151f34d0e08SRui Ueyama 152e0be2901SRui Ueyama template <class ELFT> static StringRef basename(InputSectionBase<ELFT> *S) { 153e0be2901SRui Ueyama if (S->getFile()) 154e0be2901SRui Ueyama return sys::path::filename(S->getFile()->getName()); 155e0be2901SRui Ueyama return ""; 156e0be2901SRui Ueyama } 157e0be2901SRui Ueyama 15807320e40SRui Ueyama template <class ELFT> 15907320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 160e0be2901SRui Ueyama for (InputSectionDescription *ID : Opt.KeptSections) 161e0be2901SRui Ueyama if (ID->FilePat.match(basename(S))) 162cf43f179SEugene Leviant for (SectionPattern &P : ID->SectionPatterns) 163f91282e1SRui Ueyama if (P.SectionPat.match(S->Name)) 164eea3114fSGeorge Rimar return true; 165eea3114fSGeorge Rimar return false; 166eea3114fSGeorge Rimar } 167eea3114fSGeorge Rimar 168575208caSGeorge Rimar static bool comparePriority(InputSectionData *A, InputSectionData *B) { 169575208caSGeorge Rimar return getPriority(A->Name) < getPriority(B->Name); 170575208caSGeorge Rimar } 171575208caSGeorge Rimar 172c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) { 173042a3f20SRafael Espindola return A->Name < B->Name; 1740702c4e8SGeorge Rimar } 175742c3836SRui Ueyama 176c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) { 177742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 178742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 179742c3836SRui Ueyama // This is compatible with GNU. 180742c3836SRui Ueyama return A->Alignment > B->Alignment; 181742c3836SRui Ueyama } 182742c3836SRui Ueyama 183c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)> 184be394db3SGeorge Rimar getComparator(SortSectionPolicy K) { 185be394db3SGeorge Rimar switch (K) { 186be394db3SGeorge Rimar case SortSectionPolicy::Alignment: 187c0028d3dSRafael Espindola return compareAlignment; 188be394db3SGeorge Rimar case SortSectionPolicy::Name: 189be394db3SGeorge Rimar return compareName; 190be394db3SGeorge Rimar case SortSectionPolicy::Priority: 191be394db3SGeorge Rimar return comparePriority; 192be394db3SGeorge Rimar default: 193be394db3SGeorge Rimar llvm_unreachable("unknown sort policy"); 194be394db3SGeorge Rimar } 195742c3836SRui Ueyama } 1960702c4e8SGeorge Rimar 19748c3f1ceSRui Ueyama template <class ELFT> 198e71a3f8aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 19906ae6836SGeorge Rimar ConstraintKind Kind) { 2008f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 2018f66df92SGeorge Rimar return true; 202e746e52cSRafael Espindola bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) { 203d3190795SRafael Espindola auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2); 2041854a8ebSRafael Espindola return Sec->Flags & SHF_WRITE; 20506ae6836SGeorge Rimar }); 206e746e52cSRafael Espindola return (IsRW && Kind == ConstraintKind::ReadWrite) || 207e746e52cSRafael Espindola (!IsRW && Kind == ConstraintKind::ReadOnly); 20806ae6836SGeorge Rimar } 20906ae6836SGeorge Rimar 21007171f21SGeorge Rimar static void sortSections(InputSectionData **Begin, InputSectionData **End, 211ee924709SRui Ueyama SortSectionPolicy K) { 212ee924709SRui Ueyama if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None) 21307171f21SGeorge Rimar std::stable_sort(Begin, End, getComparator(K)); 214ee924709SRui Ueyama } 215ee924709SRui Ueyama 216d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches. 217be94e1b6SRafael Espindola template <class ELFT> 218e71a3f8aSRafael Espindola void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) { 2194dc07becSRui Ueyama // Collects all sections that satisfy constraints of I 2204dc07becSRui Ueyama // and attach them to I. 2214dc07becSRui Ueyama for (SectionPattern &Pat : I->SectionPatterns) { 22207171f21SGeorge Rimar size_t SizeBefore = I->Sections.size(); 2238c6a5aafSRui Ueyama 2248c6a5aafSRui Ueyama for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) { 225f94efdddSRui Ueyama if (!S->Live || S->Assigned) 2268c6a5aafSRui Ueyama continue; 2278c6a5aafSRui Ueyama 228e0be2901SRui Ueyama StringRef Filename = basename(S); 229e0be2901SRui Ueyama if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename)) 230e0be2901SRui Ueyama continue; 231e0be2901SRui Ueyama if (!Pat.SectionPat.match(S->Name)) 232e0be2901SRui Ueyama continue; 233d3190795SRafael Espindola I->Sections.push_back(S); 234f94efdddSRui Ueyama S->Assigned = true; 235f94efdddSRui Ueyama } 236d3190795SRafael Espindola 237ee924709SRui Ueyama // Sort sections as instructed by SORT-family commands and --sort-section 238ee924709SRui Ueyama // option. Because SORT-family commands can be nested at most two depth 239ee924709SRui Ueyama // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command 240ee924709SRui Ueyama // line option is respected even if a SORT command is given, the exact 241ee924709SRui Ueyama // behavior we have here is a bit complicated. Here are the rules. 242ee924709SRui Ueyama // 243ee924709SRui Ueyama // 1. If two SORT commands are given, --sort-section is ignored. 244ee924709SRui Ueyama // 2. If one SORT command is given, and if it is not SORT_NONE, 245ee924709SRui Ueyama // --sort-section is handled as an inner SORT command. 246ee924709SRui Ueyama // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. 247ee924709SRui Ueyama // 4. If no SORT command is given, sort according to --sort-section. 24807171f21SGeorge Rimar InputSectionData **Begin = I->Sections.data() + SizeBefore; 24907171f21SGeorge Rimar InputSectionData **End = I->Sections.data() + I->Sections.size(); 25007171f21SGeorge Rimar if (Pat.SortOuter != SortSectionPolicy::None) { 25107171f21SGeorge Rimar if (Pat.SortInner == SortSectionPolicy::Default) 25207171f21SGeorge Rimar sortSections(Begin, End, Config->SortSection); 253ee924709SRui Ueyama else 25407171f21SGeorge Rimar sortSections(Begin, End, Pat.SortInner); 25507171f21SGeorge Rimar sortSections(Begin, End, Pat.SortOuter); 25607171f21SGeorge Rimar } 257ee924709SRui Ueyama } 258be94e1b6SRafael Espindola } 259be94e1b6SRafael Espindola 260be94e1b6SRafael Espindola template <class ELFT> 261be94e1b6SRafael Espindola void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) { 262be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : V) { 263be94e1b6SRafael Espindola S->Live = false; 264be94e1b6SRafael Espindola reportDiscarded(S); 265be94e1b6SRafael Espindola } 266be94e1b6SRafael Espindola } 267be94e1b6SRafael Espindola 26806ae6836SGeorge Rimar template <class ELFT> 2690b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 27006ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 2710b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 272e7f912cdSRui Ueyama 27306ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 2747c3ff2ebSRafael Espindola auto *Cmd = dyn_cast<InputSectionDescription>(Base.get()); 2757c3ff2ebSRafael Espindola if (!Cmd) 2760b9ce6a4SRui Ueyama continue; 277e71a3f8aSRafael Espindola computeInputSections(Cmd); 278d3190795SRafael Espindola for (InputSectionData *S : Cmd->Sections) 279d3190795SRafael Espindola Ret.push_back(static_cast<InputSectionBase<ELFT> *>(S)); 2800b9ce6a4SRui Ueyama } 281e71a3f8aSRafael Espindola 2820b9ce6a4SRui Ueyama return Ret; 2830b9ce6a4SRui Ueyama } 2840b9ce6a4SRui Ueyama 285e5d3ca50SPetr Hosek template <class ELFT> 28620d03194SEugene Leviant void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory, 28720d03194SEugene Leviant InputSectionBase<ELFT> *Sec, 28820d03194SEugene Leviant StringRef Name) { 289e08e78dfSRafael Espindola OutputSectionBase *OutSec; 29028c1597aSRafael Espindola bool IsNew; 29133713983SRafael Espindola std::tie(OutSec, IsNew) = Factory.create(Sec, Name); 29228c1597aSRafael Espindola if (IsNew) 29328c1597aSRafael Espindola OutputSections->push_back(OutSec); 29420d03194SEugene Leviant OutSec->addSection(Sec); 29520d03194SEugene Leviant } 29620d03194SEugene Leviant 29720d03194SEugene Leviant template <class ELFT> 29820d03194SEugene Leviant void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { 2997c3ff2ebSRafael Espindola for (unsigned I = 0; I < Opt.Commands.size(); ++I) { 3007c3ff2ebSRafael Espindola auto Iter = Opt.Commands.begin() + I; 3017c3ff2ebSRafael Espindola const std::unique_ptr<BaseCommand> &Base1 = *Iter; 3020b1b695aSRui Ueyama 3030b1b695aSRui Ueyama // Handle symbol assignments outside of any output section. 3042ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 305b0de56b5SRafael Espindola addSymbol<ELFT>(Cmd); 3062ab5f73dSRui Ueyama continue; 3072ab5f73dSRui Ueyama } 3080b1b695aSRui Ueyama 30920d03194SEugene Leviant if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) { 31020d03194SEugene Leviant // If we don't have SECTIONS then output sections have already been 311194470cdSGeorge Rimar // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses 31220d03194SEugene Leviant // will not be called, so ASSERT should be evaluated now. 31320d03194SEugene Leviant if (!Opt.HasSections) 31420d03194SEugene Leviant Cmd->Expression(0); 31520d03194SEugene Leviant continue; 31620d03194SEugene Leviant } 3172ab5f73dSRui Ueyama 318ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 3197bd37870SRafael Espindola std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 3207bd37870SRafael Espindola 3210b1b695aSRui Ueyama // The output section name `/DISCARD/' is special. 3220b1b695aSRui Ueyama // Any input section assigned to it is discarded. 32348c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 3247bd37870SRafael Espindola discard(V); 32548c3f1ceSRui Ueyama continue; 32648c3f1ceSRui Ueyama } 3270b9ce6a4SRui Ueyama 3280b1b695aSRui Ueyama // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive 3290b1b695aSRui Ueyama // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input 3300b1b695aSRui Ueyama // sections satisfy a given constraint. If not, a directive is handled 3310b1b695aSRui Ueyama // as if it wasn't present from the beginning. 3320b1b695aSRui Ueyama // 3330b1b695aSRui Ueyama // Because we'll iterate over Commands many more times, the easiest 3340b1b695aSRui Ueyama // way to "make it as if it wasn't present" is to just remove it. 3357c3ff2ebSRafael Espindola if (!matchConstraints<ELFT>(V, Cmd->Constraint)) { 3367c3ff2ebSRafael Espindola for (InputSectionBase<ELFT> *S : V) 337f94efdddSRui Ueyama S->Assigned = false; 3387c3ff2ebSRafael Espindola Opt.Commands.erase(Iter); 339dfbbbc86SGeorge Rimar --I; 3407c3ff2ebSRafael Espindola continue; 3417c3ff2ebSRafael Espindola } 3427c3ff2ebSRafael Espindola 3430b1b695aSRui Ueyama // A directive may contain symbol definitions like this: 3440b1b695aSRui Ueyama // ".foo : { ...; bar = .; }". Handle them. 3457c3ff2ebSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 3467c3ff2ebSRafael Espindola if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) 3477c3ff2ebSRafael Espindola addSymbol<ELFT>(OutCmd); 3487c3ff2ebSRafael Espindola 3490b1b695aSRui Ueyama // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign 3500b1b695aSRui Ueyama // is given, input sections are aligned to that value, whether the 3510b1b695aSRui Ueyama // given value is larger or smaller than the original section alignment. 3520b1b695aSRui Ueyama if (Cmd->SubalignExpr) { 3530b1b695aSRui Ueyama uint32_t Subalign = Cmd->SubalignExpr(0); 3540b1b695aSRui Ueyama for (InputSectionBase<ELFT> *S : V) 3550b1b695aSRui Ueyama S->Alignment = Subalign; 35620d03194SEugene Leviant } 3570b1b695aSRui Ueyama 3580b1b695aSRui Ueyama // Add input sections to an output section. 3590b1b695aSRui Ueyama for (InputSectionBase<ELFT> *S : V) 3600b1b695aSRui Ueyama addSection(Factory, S, Cmd->Name); 361eea3114fSGeorge Rimar } 36248c3f1ceSRui Ueyama } 363db24d9c3SGeorge Rimar } 364e63d81bdSEugene Leviant 3650b1b695aSRui Ueyama // Add sections that didn't match any sections command. 36620d03194SEugene Leviant template <class ELFT> 36793c64025SGeorge Rimar void LinkerScript<ELFT>::addOrphanSections( 36893c64025SGeorge Rimar OutputSectionFactory<ELFT> &Factory) { 3698c6a5aafSRui Ueyama for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) 3708f9026baSRafael Espindola if (S->Live && !S->OutSec) 37155518e7dSRui Ueyama addSection(Factory, S, getOutputSectionName(S->Name)); 372e63d81bdSEugene Leviant } 373e63d81bdSEugene Leviant 374db741e72SEugene Leviant // Sets value of a section-defined symbol. Two kinds of 375db741e72SEugene Leviant // symbols are processed: synthetic symbols, whose value 376db741e72SEugene Leviant // is an offset from beginning of section and regular 377db741e72SEugene Leviant // symbols whose value is absolute. 378db741e72SEugene Leviant template <class ELFT> 379afaa9343SEugene Leviant static void assignSectionSymbol(SymbolAssignment *Cmd, 380498ed714SRafael Espindola typename ELFT::uint Value) { 381db741e72SEugene Leviant if (!Cmd->Sym) 382db741e72SEugene Leviant return; 383db741e72SEugene Leviant 3844f2f50dcSRui Ueyama if (auto *Body = dyn_cast<DefinedSynthetic>(Cmd->Sym)) { 385afaa9343SEugene Leviant Body->Section = Cmd->Expression.Section(); 386afaa9343SEugene Leviant Body->Value = Cmd->Expression(Value) - Body->Section->Addr; 387db741e72SEugene Leviant return; 388db741e72SEugene Leviant } 389db741e72SEugene Leviant auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym); 390498ed714SRafael Espindola Body->Value = Cmd->Expression(Value); 391db741e72SEugene Leviant } 392db741e72SEugene Leviant 393e08e78dfSRafael Espindola template <class ELFT> static bool isTbss(OutputSectionBase *Sec) { 39404a2e348SRafael Espindola return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS; 395a940e539SRafael Espindola } 396a940e539SRafael Espindola 397d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) { 398d3190795SRafael Espindola if (!AlreadyOutputIS.insert(S).second) 399ceabe80eSEugene Leviant return; 400e08e78dfSRafael Espindola bool IsTbss = isTbss<ELFT>(CurOutSec); 401d3190795SRafael Espindola 402d3190795SRafael Espindola uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; 403d3190795SRafael Espindola Pos = alignTo(Pos, S->Alignment); 40404a2e348SRafael Espindola S->OutSecOff = Pos - CurOutSec->Addr; 405d3190795SRafael Espindola Pos += S->getSize(); 406d3190795SRafael Espindola 407d3190795SRafael Espindola // Update output section size after adding each section. This is so that 408d3190795SRafael Espindola // SIZEOF works correctly in the case below: 409d3190795SRafael Espindola // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 41004a2e348SRafael Espindola CurOutSec->Size = Pos - CurOutSec->Addr; 411d3190795SRafael Espindola 412b889744eSMeador Inge // If there is a memory region associated with this input section, then 413b889744eSMeador Inge // place the section in that region and update the region index. 414b889744eSMeador Inge if (CurMemRegion) { 415b889744eSMeador Inge CurMemRegion->Offset += CurOutSec->Size; 416b889744eSMeador Inge uint64_t CurSize = CurMemRegion->Offset - CurMemRegion->Origin; 417b889744eSMeador Inge if (CurSize > CurMemRegion->Length) { 418b889744eSMeador Inge uint64_t OverflowAmt = CurSize - CurMemRegion->Length; 419b889744eSMeador Inge error("section '" + CurOutSec->Name + "' will not fit in region '" + 420b889744eSMeador Inge CurMemRegion->Name + "': overflowed by " + Twine(OverflowAmt) + 421b889744eSMeador Inge " bytes"); 422b889744eSMeador Inge } 423b889744eSMeador Inge } 424b889744eSMeador Inge 4257252ae52SRafael Espindola if (IsTbss) 4267252ae52SRafael Espindola ThreadBssOffset = Pos - Dot; 4277252ae52SRafael Espindola else 428d3190795SRafael Espindola Dot = Pos; 4292de509c3SRui Ueyama } 430ceabe80eSEugene Leviant 431d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::flush() { 43265499b90SRafael Espindola if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second) 43365499b90SRafael Espindola return; 43465499b90SRafael Espindola if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) { 435d3190795SRafael Espindola for (InputSection<ELFT> *I : OutSec->Sections) 436d3190795SRafael Espindola output(I); 43765499b90SRafael Espindola } else { 43804a2e348SRafael Espindola Dot += CurOutSec->Size; 439d3190795SRafael Espindola } 440d3190795SRafael Espindola } 44197403d15SEugene Leviant 442d3190795SRafael Espindola template <class ELFT> 443e08e78dfSRafael Espindola void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) { 444d3190795SRafael Espindola if (CurOutSec == Sec) 445d3190795SRafael Espindola return; 446d3190795SRafael Espindola if (AlreadyOutputOS.count(Sec)) 447d3190795SRafael Espindola return; 448d3190795SRafael Espindola 449d3190795SRafael Espindola flush(); 450d3190795SRafael Espindola CurOutSec = Sec; 451d3190795SRafael Espindola 45204a2e348SRafael Espindola Dot = alignTo(Dot, CurOutSec->Addralign); 453e08e78dfSRafael Espindola CurOutSec->Addr = isTbss<ELFT>(CurOutSec) ? Dot + ThreadBssOffset : Dot; 454b71d6f7aSEugene Leviant 455b71d6f7aSEugene Leviant // If neither AT nor AT> is specified for an allocatable section, the linker 456b71d6f7aSEugene Leviant // will set the LMA such that the difference between VMA and LMA for the 457b71d6f7aSEugene Leviant // section is the same as the preceding output section in the same region 458b71d6f7aSEugene Leviant // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html 459b71d6f7aSEugene Leviant CurOutSec->setLMAOffset(LMAOffset); 460d3190795SRafael Espindola } 461d3190795SRafael Espindola 462d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) { 463e38cbab5SGeorge Rimar // This handles the assignments to symbol or to a location counter (.) 464d3190795SRafael Espindola if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) { 46597403d15SEugene Leviant if (AssignCmd->Name == ".") { 46697403d15SEugene Leviant // Update to location counter means update to section size. 46714460e02SGeorge Rimar uintX_t Val = AssignCmd->Expression(Dot); 46814460e02SGeorge Rimar if (Val < Dot) 46914460e02SGeorge Rimar error("unable to move location counter backward for: " + 47014460e02SGeorge Rimar CurOutSec->Name); 47114460e02SGeorge Rimar Dot = Val; 47204a2e348SRafael Espindola CurOutSec->Size = Dot - CurOutSec->Addr; 473d3190795SRafael Espindola return; 47497403d15SEugene Leviant } 475afaa9343SEugene Leviant assignSectionSymbol<ELFT>(AssignCmd, Dot); 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> 515e08e78dfSRafael Espindola static std::vector<OutputSectionBase *> 516e08e78dfSRafael Espindola findSections(StringRef Name, const std::vector<OutputSectionBase *> &Sections) { 517e08e78dfSRafael Espindola std::vector<OutputSectionBase *> Ret; 518e08e78dfSRafael Espindola for (OutputSectionBase *Sec : Sections) 5199257764dSEugene Leviant if (Sec->getName() == Name) 520a14b13d8SGeorge Rimar Ret.push_back(Sec); 521a14b13d8SGeorge Rimar return Ret; 5228f66df92SGeorge Rimar } 5238f66df92SGeorge Rimar 524b889744eSMeador Inge // This function searches for a memory region to place the given output 525b889744eSMeador Inge // section in. If found, a pointer to the appropriate memory region is 526b889744eSMeador Inge // returned. Otherwise, a nullptr is returned. 527b889744eSMeador Inge template <class ELFT> 528b889744eSMeador Inge MemoryRegion *LinkerScript<ELFT>::findMemoryRegion(OutputSectionCommand *Cmd, 529b889744eSMeador Inge OutputSectionBase *Sec) { 530b889744eSMeador Inge // If a memory region name was specified in the output section command, 531b889744eSMeador Inge // then try to find that region first. 532b889744eSMeador Inge if (!Cmd->MemoryRegionName.empty()) { 533b889744eSMeador Inge auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName); 534b889744eSMeador Inge if (It != Opt.MemoryRegions.end()) 535b889744eSMeador Inge return &It->second; 536b889744eSMeador Inge error("memory region '" + Cmd->MemoryRegionName + "' not declared"); 537b889744eSMeador Inge return nullptr; 538b889744eSMeador Inge } 539b889744eSMeador Inge 540b889744eSMeador Inge // The memory region name is empty, thus a suitable region must be 541b889744eSMeador Inge // searched for in the region map. If the region map is empty, just 542b889744eSMeador Inge // return. Note that this check doesn't happen at the very beginning 543b889744eSMeador Inge // so that uses of undeclared regions can be caught. 544b889744eSMeador Inge if (!Opt.MemoryRegions.size()) 545b889744eSMeador Inge return nullptr; 546b889744eSMeador Inge 547b889744eSMeador Inge // See if a region can be found by matching section flags. 548b889744eSMeador Inge for (auto &MRI : Opt.MemoryRegions) { 549b889744eSMeador Inge MemoryRegion &MR = MRI.second; 550*8a8a953eSRui Ueyama if ((MR.Flags & Sec->Flags) != 0 && (MR.NegFlags & Sec->Flags) == 0) 551b889744eSMeador Inge return &MR; 552b889744eSMeador Inge } 553b889744eSMeador Inge 554b889744eSMeador Inge // Otherwise, no suitable region was found. 555b889744eSMeador Inge if (Sec->Flags & SHF_ALLOC) 556b889744eSMeador Inge error("no memory region specified for section '" + Sec->Name + "'"); 557b889744eSMeador Inge return nullptr; 558b889744eSMeador Inge } 559b889744eSMeador Inge 5600b1b695aSRui Ueyama // This function assigns offsets to input sections and an output section 5610b1b695aSRui Ueyama // for a single sections command (e.g. ".text { *(.text); }"). 562d3190795SRafael Espindola template <class ELFT> 563d3190795SRafael Espindola void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) { 564b71d6f7aSEugene Leviant if (Cmd->LMAExpr) 565b71d6f7aSEugene Leviant LMAOffset = Cmd->LMAExpr(Dot) - Dot; 566e08e78dfSRafael Espindola std::vector<OutputSectionBase *> Sections = 567e08e78dfSRafael Espindola findSections<ELFT>(Cmd->Name, *OutputSections); 568d3190795SRafael Espindola if (Sections.empty()) 569d3190795SRafael Espindola return; 570b889744eSMeador Inge 571b889744eSMeador Inge OutputSectionBase *Sec = Sections[0]; 572b889744eSMeador Inge // Try and find an appropriate memory region to assign offsets in. 573b889744eSMeador Inge CurMemRegion = findMemoryRegion(Cmd, Sec); 574b889744eSMeador Inge if (CurMemRegion) 575b889744eSMeador Inge Dot = CurMemRegion->Offset; 576b889744eSMeador Inge switchTo(Sec); 5770b1b695aSRui Ueyama 578d3190795SRafael Espindola // Find the last section output location. We will output orphan sections 579d3190795SRafael Espindola // there so that end symbols point to the correct location. 580d3190795SRafael Espindola auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(), 581d3190795SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 582d3190795SRafael Espindola return !isa<SymbolAssignment>(*Cmd); 583d3190795SRafael Espindola }) 584d3190795SRafael Espindola .base(); 585d3190795SRafael Espindola for (auto I = Cmd->Commands.begin(); I != E; ++I) 586d3190795SRafael Espindola process(**I); 587e08e78dfSRafael Espindola for (OutputSectionBase *Base : Sections) 588d3190795SRafael Espindola switchTo(Base); 5892506cb4dSEugene Leviant flush(); 590b31dd370SGeorge Rimar std::for_each(E, Cmd->Commands.end(), 591b31dd370SGeorge Rimar [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); }); 592d3190795SRafael Espindola } 593d3190795SRafael Espindola 59407fe6129SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::removeEmptyCommands() { 5956d38e4dbSRafael Espindola // It is common practice to use very generic linker scripts. So for any 5966d38e4dbSRafael Espindola // given run some of the output sections in the script will be empty. 5976d38e4dbSRafael Espindola // We could create corresponding empty output sections, but that would 5986d38e4dbSRafael Espindola // clutter the output. 5996d38e4dbSRafael Espindola // We instead remove trivially empty sections. The bfd linker seems even 6006d38e4dbSRafael Espindola // more aggressive at removing them. 6016d38e4dbSRafael Espindola auto Pos = std::remove_if( 6026d38e4dbSRafael Espindola Opt.Commands.begin(), Opt.Commands.end(), 6036d38e4dbSRafael Espindola [&](const std::unique_ptr<BaseCommand> &Base) { 6040b1b695aSRui Ueyama if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 6056a53737cSRafael Espindola return findSections<ELFT>(Cmd->Name, *OutputSections).empty(); 6060b1b695aSRui Ueyama return false; 6076d38e4dbSRafael Espindola }); 6086d38e4dbSRafael Espindola Opt.Commands.erase(Pos, Opt.Commands.end()); 60907fe6129SRafael Espindola } 61007fe6129SRafael Espindola 6116a53737cSRafael Espindola static bool isAllSectionDescription(const OutputSectionCommand &Cmd) { 6126a53737cSRafael Espindola for (const std::unique_ptr<BaseCommand> &I : Cmd.Commands) 6136a53737cSRafael Espindola if (!isa<InputSectionDescription>(*I)) 6146a53737cSRafael Espindola return false; 6156a53737cSRafael Espindola return true; 6166a53737cSRafael Espindola } 6176d38e4dbSRafael Espindola 6186a53737cSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() { 6199546fffbSRafael Espindola // If the output section contains only symbol assignments, create a 6209546fffbSRafael Espindola // corresponding output section. The bfd linker seems to only create them if 6219546fffbSRafael Espindola // '.' is assigned to, but creating these section should not have any bad 6229546fffbSRafael Espindola // consequeces and gives us a section to put the symbol in. 6239546fffbSRafael Espindola uintX_t Flags = SHF_ALLOC; 624f93b8c29SRafael Espindola uint32_t Type = SHT_NOBITS; 6259546fffbSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 6269546fffbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 6279546fffbSRafael Espindola if (!Cmd) 6289546fffbSRafael Espindola continue; 629e08e78dfSRafael Espindola std::vector<OutputSectionBase *> Secs = 630e08e78dfSRafael Espindola findSections<ELFT>(Cmd->Name, *OutputSections); 6319546fffbSRafael Espindola if (!Secs.empty()) { 63204a2e348SRafael Espindola Flags = Secs[0]->Flags; 63304a2e348SRafael Espindola Type = Secs[0]->Type; 6349546fffbSRafael Espindola continue; 6359546fffbSRafael Espindola } 6369546fffbSRafael Espindola 6376a53737cSRafael Espindola if (isAllSectionDescription(*Cmd)) 6386a53737cSRafael Espindola continue; 6396a53737cSRafael Espindola 64095642b95SRui Ueyama auto *OutSec = make<OutputSection<ELFT>>(Cmd->Name, Type, Flags); 6419546fffbSRafael Espindola OutputSections->push_back(OutSec); 6429546fffbSRafael Espindola } 643f7a17448SRafael Espindola } 644f7a17448SRafael Espindola 645f7a17448SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsAfterSorting() { 646f7a17448SRafael Espindola placeOrphanSections(); 647f7a17448SRafael Espindola 648f7a17448SRafael Espindola // If output section command doesn't specify any segments, 649f7a17448SRafael Espindola // and we haven't previously assigned any section to segment, 650f7a17448SRafael Espindola // then we simply assign section to the very first load segment. 651f7a17448SRafael Espindola // Below is an example of such linker script: 652f7a17448SRafael Espindola // PHDRS { seg PT_LOAD; } 653f7a17448SRafael Espindola // SECTIONS { .aaa : { *(.aaa) } } 654f7a17448SRafael Espindola std::vector<StringRef> DefPhdrs; 655f7a17448SRafael Espindola auto FirstPtLoad = 656f7a17448SRafael Espindola std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(), 657f7a17448SRafael Espindola [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; }); 658f7a17448SRafael Espindola if (FirstPtLoad != Opt.PhdrsCommands.end()) 659f7a17448SRafael Espindola DefPhdrs.push_back(FirstPtLoad->Name); 660f7a17448SRafael Espindola 661f7a17448SRafael Espindola // Walk the commands and propagate the program headers to commands that don't 662f7a17448SRafael Espindola // explicitly specify them. 663f7a17448SRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 664f7a17448SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 665f7a17448SRafael Espindola if (!Cmd) 666f7a17448SRafael Espindola continue; 667f7a17448SRafael Espindola if (Cmd->Phdrs.empty()) 668f7a17448SRafael Espindola Cmd->Phdrs = DefPhdrs; 669f7a17448SRafael Espindola else 670f7a17448SRafael Espindola DefPhdrs = Cmd->Phdrs; 671f7a17448SRafael Espindola } 6726a53737cSRafael Espindola 6736a53737cSRafael Espindola removeEmptyCommands(); 6749546fffbSRafael Espindola } 6759546fffbSRafael Espindola 67615c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments 67715c57951SRafael Espindola // so that an orphan after 67815c57951SRafael Espindola // begin_foo = .; 67915c57951SRafael Espindola // foo : { *(foo) } 68015c57951SRafael Espindola // end_foo = .; 68115c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols. 68215c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the 68315c57951SRafael Espindola // one in charge of deciding the order of the sections. 68415c57951SRafael Espindola // We don't want to go over alignments, since doing so in 68515c57951SRafael Espindola // rx_sec : { *(rx_sec) } 68615c57951SRafael Espindola // . = ALIGN(0x1000); 68715c57951SRafael Espindola // /* The RW PT_LOAD starts here*/ 68815c57951SRafael Espindola // rw_sec : { *(rw_sec) } 68915c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned. 6905fcc99c2SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) { 69115c57951SRafael Espindola if (isa<OutputSectionCommand>(Cmd)) 69215c57951SRafael Espindola return false; 69315c57951SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd); 69415c57951SRafael Espindola if (!Assign) 69515c57951SRafael Espindola return true; 6965fcc99c2SRafael Espindola return Assign->Name != "."; 69715c57951SRafael Espindola } 69815c57951SRafael Espindola 699337f903cSRafael Espindola // Orphan sections are sections present in the input files which are not 700337f903cSRafael Espindola // explicitly placed into the output file by the linker script. This just 701337f903cSRafael Espindola // places them in the order already decided in OutputSections. 70293c64025SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::placeOrphanSections() { 703aab6d5c5SRafael Espindola // The OutputSections are already in the correct order. 704aab6d5c5SRafael Espindola // This loops creates or moves commands as needed so that they are in the 705aab6d5c5SRafael Espindola // correct order. 706aab6d5c5SRafael Espindola int CmdIndex = 0; 7075fcc99c2SRafael Espindola 7085fcc99c2SRafael Espindola // As a horrible special case, skip the first . assignment if it is before any 7095fcc99c2SRafael Espindola // section. We do this because it is common to set a load address by starting 7105fcc99c2SRafael Espindola // the script with ". = 0xabcd" and the expectation is that every section is 7115fcc99c2SRafael Espindola // after that. 7125fcc99c2SRafael Espindola auto FirstSectionOrDotAssignment = 7135fcc99c2SRafael Espindola std::find_if(Opt.Commands.begin(), Opt.Commands.end(), 7145fcc99c2SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 7155fcc99c2SRafael Espindola if (isa<OutputSectionCommand>(*Cmd)) 7165fcc99c2SRafael Espindola return true; 7175fcc99c2SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(Cmd.get()); 7185fcc99c2SRafael Espindola if (!Assign) 7195fcc99c2SRafael Espindola return false; 7205fcc99c2SRafael Espindola return Assign->Name == "."; 7215fcc99c2SRafael Espindola }); 7225fcc99c2SRafael Espindola if (FirstSectionOrDotAssignment != Opt.Commands.end()) { 7235fcc99c2SRafael Espindola CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin(); 7245fcc99c2SRafael Espindola if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment)) 7255fcc99c2SRafael Espindola ++CmdIndex; 7265fcc99c2SRafael Espindola } 7275fcc99c2SRafael Espindola 728e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) { 729652852c5SGeorge Rimar StringRef Name = Sec->getName(); 730aab6d5c5SRafael Espindola 731aab6d5c5SRafael Espindola // Find the last spot where we can insert a command and still get the 73215c57951SRafael Espindola // correct result. 733aab6d5c5SRafael Espindola auto CmdIter = Opt.Commands.begin() + CmdIndex; 734aab6d5c5SRafael Espindola auto E = Opt.Commands.end(); 7355fcc99c2SRafael Espindola while (CmdIter != E && shouldSkip(**CmdIter)) { 736aab6d5c5SRafael Espindola ++CmdIter; 737aab6d5c5SRafael Espindola ++CmdIndex; 738aab6d5c5SRafael Espindola } 739aab6d5c5SRafael Espindola 740aab6d5c5SRafael Espindola auto Pos = 741aab6d5c5SRafael Espindola std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) { 742aab6d5c5SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 743aab6d5c5SRafael Espindola return Cmd && Cmd->Name == Name; 744aab6d5c5SRafael Espindola }); 745aab6d5c5SRafael Espindola if (Pos == E) { 746aab6d5c5SRafael Espindola Opt.Commands.insert(CmdIter, 747aab6d5c5SRafael Espindola llvm::make_unique<OutputSectionCommand>(Name)); 748aab6d5c5SRafael Espindola ++CmdIndex; 74915c57951SRafael Espindola continue; 75015c57951SRafael Espindola } 75115c57951SRafael Espindola 75215c57951SRafael Espindola // Continue from where we found it. 75315c57951SRafael Espindola CmdIndex = (Pos - Opt.Commands.begin()) + 1; 754652852c5SGeorge Rimar } 755337f903cSRafael Espindola } 756337f903cSRafael Espindola 757337f903cSRafael Espindola template <class ELFT> 75817cb7c0aSRafael Espindola void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) { 7597c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 760be607334SRafael Espindola Dot = 0; 761652852c5SGeorge Rimar 762076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 763076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 7648d083e6aSRui Ueyama if (Cmd->Name == ".") { 7658d083e6aSRui Ueyama Dot = Cmd->Expression(Dot); 7668d083e6aSRui Ueyama } else if (Cmd->Sym) { 767afaa9343SEugene Leviant assignSectionSymbol<ELFT>(Cmd, Dot); 7688d083e6aSRui Ueyama } 76905ef4cffSRui Ueyama continue; 770652852c5SGeorge Rimar } 771652852c5SGeorge Rimar 772eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 773eefa758eSGeorge Rimar Cmd->Expression(Dot); 774eefa758eSGeorge Rimar continue; 775eefa758eSGeorge Rimar } 776eefa758eSGeorge Rimar 777076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 77858e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 77958e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 780d3190795SRafael Espindola assignOffsets(Cmd); 781a14b13d8SGeorge Rimar } 782467c4d55SEugene Leviant 783aab6d5c5SRafael Espindola uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 784e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) { 78504a2e348SRafael Espindola if (Sec->Flags & SHF_ALLOC) 786e08e78dfSRafael Espindola MinVA = std::min<uint64_t>(MinVA, Sec->Addr); 787aab6d5c5SRafael Espindola else 78804a2e348SRafael Espindola Sec->Addr = 0; 789aab6d5c5SRafael Espindola } 790aab6d5c5SRafael Espindola 7918c495e20SRafael Espindola allocateHeaders<ELFT>(Phdrs, *OutputSections, MinVA); 792fb8978fcSDima Stepanov } 793652852c5SGeorge Rimar 794464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 79517cb7c0aSRafael Espindola template <class ELFT> std::vector<PhdrEntry> LinkerScript<ELFT>::createPhdrs() { 79617cb7c0aSRafael Espindola std::vector<PhdrEntry> Ret; 797bbe38602SEugene Leviant 798464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 799464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 800bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 801edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 80217cb7c0aSRafael Espindola PhdrEntry &Phdr = Ret.back(); 803bbe38602SEugene Leviant 804bbe38602SEugene Leviant if (Cmd.HasFilehdr) 805adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 806bbe38602SEugene Leviant if (Cmd.HasPhdrs) 807adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 80856b21c86SEugene Leviant 80956b21c86SEugene Leviant if (Cmd.LMAExpr) { 81017cb7c0aSRafael Espindola Phdr.p_paddr = Cmd.LMAExpr(0); 81156b21c86SEugene Leviant Phdr.HasLMA = true; 81256b21c86SEugene Leviant } 813bbe38602SEugene Leviant } 814bbe38602SEugene Leviant 815464daadcSRui Ueyama // Add output sections to program headers. 816e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) { 81704a2e348SRafael Espindola if (!(Sec->Flags & SHF_ALLOC)) 818bbe38602SEugene Leviant break; 819bbe38602SEugene Leviant 820bbe38602SEugene Leviant // Assign headers specified by linker script 821f7a17448SRafael Espindola for (size_t Id : getPhdrIndices(Sec->getName())) { 822edebbdf1SRui Ueyama Ret[Id].add(Sec); 823865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 82417cb7c0aSRafael Espindola Ret[Id].p_flags |= Sec->getPhdrFlags(); 825bbe38602SEugene Leviant } 826bbe38602SEugene Leviant } 827edebbdf1SRui Ueyama return Ret; 828bbe38602SEugene Leviant } 829bbe38602SEugene Leviant 830f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 831f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 832f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 833f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 834f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 835f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 836f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 837f9bc3bd2SEugene Leviant } 838f9bc3bd2SEugene Leviant 83993c64025SGeorge Rimar template <class ELFT> uint32_t LinkerScript<ELFT>::getFiller(StringRef Name) { 840f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 841f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 842f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 843f6c3ccefSGeorge Rimar return Cmd->Filler; 84416068aebSRui Ueyama return 0; 845e2ee72b5SGeorge Rimar } 846e2ee72b5SGeorge Rimar 847e38cbab5SGeorge Rimar template <class ELFT> 848e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { 849e38cbab5SGeorge Rimar const endianness E = ELFT::TargetEndianness; 850e38cbab5SGeorge Rimar 851e38cbab5SGeorge Rimar switch (Size) { 852e38cbab5SGeorge Rimar case 1: 853e38cbab5SGeorge Rimar *Buf = (uint8_t)Data; 854e38cbab5SGeorge Rimar break; 855e38cbab5SGeorge Rimar case 2: 856e38cbab5SGeorge Rimar write16<E>(Buf, Data); 857e38cbab5SGeorge Rimar break; 858e38cbab5SGeorge Rimar case 4: 859e38cbab5SGeorge Rimar write32<E>(Buf, Data); 860e38cbab5SGeorge Rimar break; 861e38cbab5SGeorge Rimar case 8: 862e38cbab5SGeorge Rimar write64<E>(Buf, Data); 863e38cbab5SGeorge Rimar break; 864e38cbab5SGeorge Rimar default: 865e38cbab5SGeorge Rimar llvm_unreachable("unsupported Size argument"); 866e38cbab5SGeorge Rimar } 867e38cbab5SGeorge Rimar } 868e38cbab5SGeorge Rimar 869e38cbab5SGeorge Rimar template <class ELFT> 870e38cbab5SGeorge Rimar void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) { 871e38cbab5SGeorge Rimar int I = getSectionIndex(Name); 872e38cbab5SGeorge Rimar if (I == INT_MAX) 873e38cbab5SGeorge Rimar return; 874e38cbab5SGeorge Rimar 8756e68c5e5SRui Ueyama auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()); 8766e68c5e5SRui Ueyama for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 8776e68c5e5SRui Ueyama if (auto *Data = dyn_cast<BytesDataCommand>(Base.get())) 87895c7d8d2SMeador Inge writeInt<ELFT>(Buf + Data->Offset, Data->Expression(0), Data->Size); 879e38cbab5SGeorge Rimar } 880e38cbab5SGeorge Rimar 881b71d6f7aSEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasLMA(StringRef Name) { 8828ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 8838ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 884b71d6f7aSEugene Leviant if (Cmd->LMAExpr && Cmd->Name == Name) 885b71d6f7aSEugene Leviant return true; 886b71d6f7aSEugene Leviant return false; 8878ceadb38SGeorge Rimar } 8888ceadb38SGeorge Rimar 889c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 890c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 891c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 892c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 893076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 8946e68c5e5SRui Ueyama for (int I = 0, E = Opt.Commands.size(); I != E; ++I) 8956e68c5e5SRui Ueyama if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I].get())) 896076fe157SGeorge Rimar if (Cmd->Name == Name) 897f510fa6bSRui Ueyama return I; 898f510fa6bSRui Ueyama return INT_MAX; 89971b26e94SGeorge Rimar } 90071b26e94SGeorge Rimar 901bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 902bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 903bbe38602SEugene Leviant } 904bbe38602SEugene Leviant 9059e69450eSGeorge Rimar template <class ELFT> 906ed30ce7aSEugene Leviant const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(const Twine &Loc, 907ed30ce7aSEugene Leviant StringRef Name) { 908afaa9343SEugene Leviant static OutputSectionBase FakeSec("", 0, 0); 90996659df0SGeorge Rimar 910e08e78dfSRafael Espindola for (OutputSectionBase *Sec : *OutputSections) 911b71d6f7aSEugene Leviant if (Sec->getName() == Name) 912afaa9343SEugene Leviant return Sec; 913ed30ce7aSEugene Leviant 914ed30ce7aSEugene Leviant error(Loc + ": undefined section " + Name); 915afaa9343SEugene Leviant return &FakeSec; 91636fac7f0SEugene Leviant } 91736fac7f0SEugene Leviant 918edf75e79SRui Ueyama // This function is essentially the same as getOutputSection(Name)->Size, 919edf75e79SRui Ueyama // but it won't print out an error message if a given section is not found. 920edf75e79SRui Ueyama // 921edf75e79SRui Ueyama // Linker script does not create an output section if its content is empty. 922edf75e79SRui Ueyama // We want to allow SIZEOF(.foo) where .foo is a section which happened to 923edf75e79SRui Ueyama // be empty. That is why this function is different from getOutputSection(). 924edf75e79SRui Ueyama template <class ELFT> 925edf75e79SRui Ueyama uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 926edf75e79SRui Ueyama for (OutputSectionBase *Sec : *OutputSections) 927edf75e79SRui Ueyama if (Sec->getName() == Name) 928edf75e79SRui Ueyama return Sec->Size; 929edf75e79SRui Ueyama return 0; 930edf75e79SRui Ueyama } 931edf75e79SRui Ueyama 932884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() { 9330d4b6d5cSRafael Espindola return elf::getHeaderSize<ELFT>(); 934e32a3598SGeorge Rimar } 935e32a3598SGeorge Rimar 936f6aeed36SEugene Leviant template <class ELFT> 937f6aeed36SEugene Leviant uint64_t LinkerScript<ELFT>::getSymbolValue(const Twine &Loc, StringRef S) { 938884e786dSGeorge Rimar if (SymbolBody *B = Symtab<ELFT>::X->find(S)) 939884e786dSGeorge Rimar return B->getVA<ELFT>(); 940f6aeed36SEugene Leviant error(Loc + ": symbol not found: " + S); 941884e786dSGeorge Rimar return 0; 942884e786dSGeorge Rimar } 943884e786dSGeorge Rimar 944f34f45fdSGeorge Rimar template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) { 945f34f45fdSGeorge Rimar return Symtab<ELFT>::X->find(S) != nullptr; 946f34f45fdSGeorge Rimar } 947f34f45fdSGeorge Rimar 9482f831dcaSRafael Espindola template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) { 9492f831dcaSRafael Espindola SymbolBody *Sym = Symtab<ELFT>::X->find(S); 9502f831dcaSRafael Espindola auto *DR = dyn_cast_or_null<DefinedRegular<ELFT>>(Sym); 9512f831dcaSRafael Espindola return DR && !DR->Section; 9522f831dcaSRafael Espindola } 9532f831dcaSRafael Espindola 954afaa9343SEugene Leviant // Gets section symbol belongs to. Symbol "." doesn't belong to any 955afaa9343SEugene Leviant // specific section but isn't absolute at the same time, so we try 956afaa9343SEugene Leviant // to find suitable section for it as well. 957afaa9343SEugene Leviant template <class ELFT> 958afaa9343SEugene Leviant const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) { 959afaa9343SEugene Leviant SymbolBody *Sym = Symtab<ELFT>::X->find(S); 960afaa9343SEugene Leviant if (!Sym) { 961afaa9343SEugene Leviant if (OutputSections->empty()) 962afaa9343SEugene Leviant return nullptr; 963afaa9343SEugene Leviant return CurOutSec ? CurOutSec : (*OutputSections)[0]; 964afaa9343SEugene Leviant } 965afaa9343SEugene Leviant 96660aed443SGeorge Rimar return SymbolTableSection<ELFT>::getOutputSection(Sym); 967afaa9343SEugene Leviant } 968afaa9343SEugene Leviant 969bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 970bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 971bbe38602SEugene Leviant // PHDRS {} script block. 972bbe38602SEugene Leviant template <class ELFT> 973edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 974076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 975076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 976edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 97731d842f5SGeorge Rimar continue; 97831d842f5SGeorge Rimar 97929c5a2a9SRui Ueyama std::vector<size_t> Ret; 98029c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 9812a942c4bSEugene Leviant Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName)); 98229c5a2a9SRui Ueyama return Ret; 983bbe38602SEugene Leviant } 98431d842f5SGeorge Rimar return {}; 98531d842f5SGeorge Rimar } 986bbe38602SEugene Leviant 98729c5a2a9SRui Ueyama template <class ELFT> 9882a942c4bSEugene Leviant size_t LinkerScript<ELFT>::getPhdrIndex(const Twine &Loc, StringRef PhdrName) { 98929c5a2a9SRui Ueyama size_t I = 0; 99029c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 99129c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 99229c5a2a9SRui Ueyama return I; 99329c5a2a9SRui Ueyama ++I; 99429c5a2a9SRui Ueyama } 9952a942c4bSEugene Leviant error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS"); 99629c5a2a9SRui Ueyama return 0; 99729c5a2a9SRui Ueyama } 99829c5a2a9SRui Ueyama 99903ff0166SEugene Leviant class elf::ScriptParser final : public ScriptParserBase { 1000c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 1001c3794e58SGeorge Rimar 1002f7c5fbb1SRui Ueyama public: 100322375f24SRui Ueyama ScriptParser(MemoryBufferRef MB) 100422375f24SRui Ueyama : ScriptParserBase(MB), 100522375f24SRui Ueyama IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {} 1006f23b2320SGeorge Rimar 100720b6598cSGeorge Rimar void readLinkerScript(); 100820b6598cSGeorge Rimar void readVersionScript(); 1009d0ebd84cSRafael Espindola void readDynamicList(); 1010f7c5fbb1SRui Ueyama 1011f7c5fbb1SRui Ueyama private: 101252a1509eSRui Ueyama void addFile(StringRef Path); 101352a1509eSRui Ueyama 1014f7c5fbb1SRui Ueyama void readAsNeeded(); 101590c5099eSDenis Protivensky void readEntry(); 101683f406cfSGeorge Rimar void readExtern(); 1017f7c5fbb1SRui Ueyama void readGroup(); 101831aa1f83SRui Ueyama void readInclude(); 1019b889744eSMeador Inge void readMemory(); 1020ee59282bSRui Ueyama void readOutput(); 10219159ce93SDavide Italiano void readOutputArch(); 1022f7c5fbb1SRui Ueyama void readOutputFormat(); 1023bbe38602SEugene Leviant void readPhdrs(); 102468a39a65SDavide Italiano void readSearchDir(); 10258e3b38abSDenis Protivensky void readSections(); 102695769b4aSRui Ueyama void readVersion(); 102795769b4aSRui Ueyama void readVersionScriptCommand(); 10288e3b38abSDenis Protivensky 1029113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 1030e38cbab5SGeorge Rimar BytesDataCommand *readBytesDataCommand(StringRef Tok); 103116068aebSRui Ueyama uint32_t readFill(); 103210416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 103316068aebSRui Ueyama uint32_t readOutputSectionFiller(StringRef Tok); 1034bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 1035a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 1036db688454SEugene Leviant StringMatcher readFilePatterns(); 103707171f21SGeorge Rimar std::vector<SectionPattern> readInputSectionsList(); 1038a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 1039bbe38602SEugene Leviant unsigned readPhdrType(); 1040be394db3SGeorge Rimar SortSectionPolicy readSortKind(); 1041a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 1042c96da110SRafael Espindola SymbolAssignment *readProvideOrAssignment(StringRef Tok); 104303fc010eSGeorge Rimar void readSort(); 1044eefa758eSGeorge Rimar Expr readAssert(); 1045708019c4SRui Ueyama 104624e626ccSRui Ueyama uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); 104724e626ccSRui Ueyama std::pair<uint32_t, uint32_t> readMemoryAttributes(); 104824e626ccSRui Ueyama 1049708019c4SRui Ueyama Expr readExpr(); 1050708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 1051b71d6f7aSEugene Leviant StringRef readParenLiteral(); 1052708019c4SRui Ueyama Expr readPrimary(); 1053708019c4SRui Ueyama Expr readTernary(Expr Cond); 10546ad7dfccSRui Ueyama Expr readParenExpr(); 1055f7c5fbb1SRui Ueyama 105620b6598cSGeorge Rimar // For parsing version script. 105712450b20SRui Ueyama std::vector<SymbolVersion> readVersionExtern(); 105812450b20SRui Ueyama void readAnonymousDeclaration(); 105995769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 106012450b20SRui Ueyama std::vector<SymbolVersion> readSymbols(); 1061e999ddb8SRafael Espindola void readLocals(); 106220b6598cSGeorge Rimar 106307320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 106416b0cc9eSSimon Atanasyan bool IsUnderSysroot; 1065f7c5fbb1SRui Ueyama }; 1066f7c5fbb1SRui Ueyama 1067d0ebd84cSRafael Espindola void ScriptParser::readDynamicList() { 1068d0ebd84cSRafael Espindola expect("{"); 1069d0ebd84cSRafael Espindola readAnonymousDeclaration(); 1070d0ebd84cSRafael Espindola if (!atEOF()) 1071d0ebd84cSRafael Espindola setError("EOF expected, but got " + next()); 1072d0ebd84cSRafael Espindola } 1073d0ebd84cSRafael Espindola 107420b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 107595769b4aSRui Ueyama readVersionScriptCommand(); 107620b6598cSGeorge Rimar if (!atEOF()) 107795769b4aSRui Ueyama setError("EOF expected, but got " + next()); 107895769b4aSRui Ueyama } 107995769b4aSRui Ueyama 108095769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 108183043f23SRui Ueyama if (consume("{")) { 108212450b20SRui Ueyama readAnonymousDeclaration(); 108320b6598cSGeorge Rimar return; 108420b6598cSGeorge Rimar } 108520b6598cSGeorge Rimar 108695769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 108720b6598cSGeorge Rimar StringRef VerStr = next(); 108820b6598cSGeorge Rimar if (VerStr == "{") { 108995769b4aSRui Ueyama setError("anonymous version definition is used in " 109095769b4aSRui Ueyama "combination with other version definitions"); 109120b6598cSGeorge Rimar return; 109220b6598cSGeorge Rimar } 109320b6598cSGeorge Rimar expect("{"); 109495769b4aSRui Ueyama readVersionDeclaration(VerStr); 109520b6598cSGeorge Rimar } 109620b6598cSGeorge Rimar } 109720b6598cSGeorge Rimar 109895769b4aSRui Ueyama void ScriptParser::readVersion() { 109995769b4aSRui Ueyama expect("{"); 110095769b4aSRui Ueyama readVersionScriptCommand(); 110195769b4aSRui Ueyama expect("}"); 110295769b4aSRui Ueyama } 110395769b4aSRui Ueyama 110420b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 1105f7c5fbb1SRui Ueyama while (!atEOF()) { 1106f7c5fbb1SRui Ueyama StringRef Tok = next(); 1107a27eeccaSRui Ueyama if (Tok == ";") 1108a27eeccaSRui Ueyama continue; 1109a27eeccaSRui Ueyama 111020d03194SEugene Leviant if (Tok == "ASSERT") { 111120d03194SEugene Leviant Opt.Commands.emplace_back(new AssertCommand(readAssert())); 111220d03194SEugene Leviant } else if (Tok == "ENTRY") { 1113a27eeccaSRui Ueyama readEntry(); 1114a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 1115a27eeccaSRui Ueyama readExtern(); 1116a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 1117a27eeccaSRui Ueyama readGroup(); 1118a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 1119a27eeccaSRui Ueyama readInclude(); 1120b889744eSMeador Inge } else if (Tok == "MEMORY") { 1121b889744eSMeador Inge readMemory(); 1122a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 1123a27eeccaSRui Ueyama readOutput(); 1124a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 1125a27eeccaSRui Ueyama readOutputArch(); 1126a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 1127a27eeccaSRui Ueyama readOutputFormat(); 1128a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 1129a27eeccaSRui Ueyama readPhdrs(); 1130a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 1131a27eeccaSRui Ueyama readSearchDir(); 1132a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 1133a27eeccaSRui Ueyama readSections(); 1134a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 1135a27eeccaSRui Ueyama readVersion(); 1136c96da110SRafael Espindola } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { 11370df80befSPetr Hosek Opt.Commands.emplace_back(Cmd); 1138e5d3ca50SPetr Hosek } else { 11395761042dSGeorge Rimar setError("unknown directive: " + Tok); 1140f7c5fbb1SRui Ueyama } 1141f7c5fbb1SRui Ueyama } 1142e5d3ca50SPetr Hosek } 1143f7c5fbb1SRui Ueyama 1144717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 114516b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 11465af1687fSJustin Bogner SmallString<128> PathData; 11475af1687fSJustin Bogner StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 114816b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 11495af1687fSJustin Bogner Driver->addFile(Saver.save(Path)); 115016b0cc9eSSimon Atanasyan return; 115116b0cc9eSSimon Atanasyan } 115216b0cc9eSSimon Atanasyan } 115316b0cc9eSSimon Atanasyan 1154f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 115552a1509eSRui Ueyama Driver->addFile(S); 115652a1509eSRui Ueyama } else if (S.startswith("=")) { 115752a1509eSRui Ueyama if (Config->Sysroot.empty()) 115852a1509eSRui Ueyama Driver->addFile(S.substr(1)); 115952a1509eSRui Ueyama else 116052a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 116152a1509eSRui Ueyama } else if (S.startswith("-l")) { 116221eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 1163a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 1164a1b8fc3bSSimon Atanasyan Driver->addFile(S); 116552a1509eSRui Ueyama } else { 1166061f9286SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(S)) 1167061f9286SRui Ueyama Driver->addFile(Saver.save(*Path)); 1168025d59b1SRui Ueyama else 1169061f9286SRui Ueyama setError("unable to find " + S); 117052a1509eSRui Ueyama } 117152a1509eSRui Ueyama } 117252a1509eSRui Ueyama 1173717677afSRui Ueyama void ScriptParser::readAsNeeded() { 1174f7c5fbb1SRui Ueyama expect("("); 117535da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 117635da9b6eSRui Ueyama Config->AsNeeded = true; 117783043f23SRui Ueyama while (!Error && !consume(")")) 1178cd574a5eSGeorge Rimar addFile(unquote(next())); 117935da9b6eSRui Ueyama Config->AsNeeded = Orig; 1180f7c5fbb1SRui Ueyama } 1181f7c5fbb1SRui Ueyama 1182717677afSRui Ueyama void ScriptParser::readEntry() { 118390c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 118490c5099eSDenis Protivensky expect("("); 118590c5099eSDenis Protivensky StringRef Tok = next(); 118690c5099eSDenis Protivensky if (Config->Entry.empty()) 118790c5099eSDenis Protivensky Config->Entry = Tok; 118890c5099eSDenis Protivensky expect(")"); 118990c5099eSDenis Protivensky } 119090c5099eSDenis Protivensky 1191717677afSRui Ueyama void ScriptParser::readExtern() { 119283f406cfSGeorge Rimar expect("("); 119383043f23SRui Ueyama while (!Error && !consume(")")) 1194a2acc931SRui Ueyama Config->Undefined.push_back(next()); 119583f406cfSGeorge Rimar } 119683f406cfSGeorge Rimar 1197717677afSRui Ueyama void ScriptParser::readGroup() { 1198f7c5fbb1SRui Ueyama expect("("); 119983043f23SRui Ueyama while (!Error && !consume(")")) { 1200f7c5fbb1SRui Ueyama StringRef Tok = next(); 1201a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 1202f7c5fbb1SRui Ueyama readAsNeeded(); 1203a2acc931SRui Ueyama else 1204cd574a5eSGeorge Rimar addFile(unquote(Tok)); 1205f7c5fbb1SRui Ueyama } 1206f7c5fbb1SRui Ueyama } 1207f7c5fbb1SRui Ueyama 1208717677afSRui Ueyama void ScriptParser::readInclude() { 1209d4500653SGeorge Rimar StringRef Tok = unquote(next()); 1210ec1c75e0SRui Ueyama 1211d4500653SGeorge Rimar // https://sourceware.org/binutils/docs/ld/File-Commands.html: 1212d4500653SGeorge Rimar // The file will be searched for in the current directory, and in any 1213d4500653SGeorge Rimar // directory specified with the -L option. 1214ec1c75e0SRui Ueyama if (sys::fs::exists(Tok)) { 1215ec1c75e0SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(Tok)) 1216ec1c75e0SRui Ueyama tokenize(*MB); 1217025d59b1SRui Ueyama return; 1218025d59b1SRui Ueyama } 1219ec1c75e0SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(Tok)) { 1220ec1c75e0SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(*Path)) 1221ec1c75e0SRui Ueyama tokenize(*MB); 1222ec1c75e0SRui Ueyama return; 1223ec1c75e0SRui Ueyama } 1224ec1c75e0SRui Ueyama setError("cannot open " + Tok); 122531aa1f83SRui Ueyama } 122631aa1f83SRui Ueyama 1227717677afSRui Ueyama void ScriptParser::readOutput() { 1228ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 1229ee59282bSRui Ueyama expect("("); 1230ee59282bSRui Ueyama StringRef Tok = next(); 1231ee59282bSRui Ueyama if (Config->OutputFile.empty()) 1232cd574a5eSGeorge Rimar Config->OutputFile = unquote(Tok); 1233ee59282bSRui Ueyama expect(")"); 1234ee59282bSRui Ueyama } 1235ee59282bSRui Ueyama 1236717677afSRui Ueyama void ScriptParser::readOutputArch() { 12379159ce93SDavide Italiano // Error checking only for now. 12389159ce93SDavide Italiano expect("("); 12395424e7c7SJustin Bogner skip(); 12409159ce93SDavide Italiano expect(")"); 12419159ce93SDavide Italiano } 12429159ce93SDavide Italiano 1243717677afSRui Ueyama void ScriptParser::readOutputFormat() { 1244f7c5fbb1SRui Ueyama // Error checking only for now. 1245f7c5fbb1SRui Ueyama expect("("); 12465424e7c7SJustin Bogner skip(); 12476836c618SDavide Italiano StringRef Tok = next(); 12486836c618SDavide Italiano if (Tok == ")") 12496836c618SDavide Italiano return; 1250025d59b1SRui Ueyama if (Tok != ",") { 12515761042dSGeorge Rimar setError("unexpected token: " + Tok); 1252025d59b1SRui Ueyama return; 1253025d59b1SRui Ueyama } 12545424e7c7SJustin Bogner skip(); 12556836c618SDavide Italiano expect(","); 12565424e7c7SJustin Bogner skip(); 1257f7c5fbb1SRui Ueyama expect(")"); 1258f7c5fbb1SRui Ueyama } 1259f7c5fbb1SRui Ueyama 1260bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 1261bbe38602SEugene Leviant expect("{"); 126283043f23SRui Ueyama while (!Error && !consume("}")) { 1263bbe38602SEugene Leviant StringRef Tok = next(); 126456b21c86SEugene Leviant Opt.PhdrsCommands.push_back( 126556b21c86SEugene Leviant {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 1266bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 1267bbe38602SEugene Leviant 1268bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 1269bbe38602SEugene Leviant do { 1270bbe38602SEugene Leviant Tok = next(); 1271bbe38602SEugene Leviant if (Tok == ";") 1272bbe38602SEugene Leviant break; 1273bbe38602SEugene Leviant if (Tok == "FILEHDR") 1274bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 1275bbe38602SEugene Leviant else if (Tok == "PHDRS") 1276bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 127756b21c86SEugene Leviant else if (Tok == "AT") 127856b21c86SEugene Leviant PhdrCmd.LMAExpr = readParenExpr(); 1279865bf863SEugene Leviant else if (Tok == "FLAGS") { 1280865bf863SEugene Leviant expect("("); 1281eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 1282eb685cd7SRafael Espindola // we accept expressions like ".|1". 1283eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 1284865bf863SEugene Leviant expect(")"); 1285865bf863SEugene Leviant } else 1286bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 1287bbe38602SEugene Leviant } while (!Error); 1288bbe38602SEugene Leviant } 1289bbe38602SEugene Leviant } 1290bbe38602SEugene Leviant 1291717677afSRui Ueyama void ScriptParser::readSearchDir() { 129268a39a65SDavide Italiano expect("("); 129386c5fb82SRui Ueyama StringRef Tok = next(); 12946c7ad13fSRui Ueyama if (!Config->Nostdlib) 1295cd574a5eSGeorge Rimar Config->SearchPaths.push_back(unquote(Tok)); 129668a39a65SDavide Italiano expect(")"); 129768a39a65SDavide Italiano } 129868a39a65SDavide Italiano 1299717677afSRui Ueyama void ScriptParser::readSections() { 1300e05336ffSEugene Leviant Opt.HasSections = true; 130118a30962SGeorge Rimar // -no-rosegment is used to avoid placing read only non-executable sections in 130218a30962SGeorge Rimar // their own segment. We do the same if SECTIONS command is present in linker 130318a30962SGeorge Rimar // script. See comment for computeFlags(). 130418a30962SGeorge Rimar Config->SingleRoRx = true; 130518a30962SGeorge Rimar 13068e3b38abSDenis Protivensky expect("{"); 130783043f23SRui Ueyama while (!Error && !consume("}")) { 1308113cdec9SRui Ueyama StringRef Tok = next(); 1309c96da110SRafael Espindola BaseCommand *Cmd = readProvideOrAssignment(Tok); 1310ceabe80eSEugene Leviant if (!Cmd) { 1311ceabe80eSEugene Leviant if (Tok == "ASSERT") 1312eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 1313ceabe80eSEugene Leviant else 131410416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 13158e3b38abSDenis Protivensky } 131610416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 1317652852c5SGeorge Rimar } 1318708019c4SRui Ueyama } 13198e3b38abSDenis Protivensky 1320708019c4SRui Ueyama static int precedence(StringRef Op) { 1321708019c4SRui Ueyama return StringSwitch<int>(Op) 13220120e3f2SRui Ueyama .Cases("*", "/", 5) 13230120e3f2SRui Ueyama .Cases("+", "-", 4) 13240120e3f2SRui Ueyama .Cases("<<", ">>", 3) 13259c4ac5f2SRui Ueyama .Cases("<", "<=", ">", ">=", "==", "!=", 2) 13260120e3f2SRui Ueyama .Cases("&", "|", 1) 1327708019c4SRui Ueyama .Default(-1); 1328708019c4SRui Ueyama } 1329708019c4SRui Ueyama 1330db688454SEugene Leviant StringMatcher ScriptParser::readFilePatterns() { 133110416564SRui Ueyama std::vector<StringRef> V; 133283043f23SRui Ueyama while (!Error && !consume(")")) 133310416564SRui Ueyama V.push_back(next()); 1334f91282e1SRui Ueyama return StringMatcher(V); 13350702c4e8SGeorge Rimar } 13360702c4e8SGeorge Rimar 1337be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() { 133883043f23SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 1339be394db3SGeorge Rimar return SortSectionPolicy::Name; 134083043f23SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 1341be394db3SGeorge Rimar return SortSectionPolicy::Alignment; 134283043f23SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 1343be394db3SGeorge Rimar return SortSectionPolicy::Priority; 134483043f23SRui Ueyama if (consume("SORT_NONE")) 1345be394db3SGeorge Rimar return SortSectionPolicy::None; 1346b2a0abdfSRui Ueyama return SortSectionPolicy::Default; 1347be394db3SGeorge Rimar } 1348be394db3SGeorge Rimar 1349395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in 1350395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ 1351395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) 1352af03be19SGeorge Rimar // The semantics of that is next: 1353af03be19SGeorge Rimar // * Include .foo.1 from every file. 1354af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o 1355af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o 135607171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 135707171f21SGeorge Rimar std::vector<SectionPattern> Ret; 1358601e9898SGeorge Rimar while (!Error && peek() != ")") { 1359f91282e1SRui Ueyama StringMatcher ExcludeFilePat; 136083043f23SRui Ueyama if (consume("EXCLUDE_FILE")) { 1361395281cfSGeorge Rimar expect("("); 1362f91282e1SRui Ueyama ExcludeFilePat = readFilePatterns(); 1363395281cfSGeorge Rimar } 1364395281cfSGeorge Rimar 1365601e9898SGeorge Rimar std::vector<StringRef> V; 1366601e9898SGeorge Rimar while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE") 1367395281cfSGeorge Rimar V.push_back(next()); 1368601e9898SGeorge Rimar 1369601e9898SGeorge Rimar if (!V.empty()) 1370f91282e1SRui Ueyama Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); 1371601e9898SGeorge Rimar else 1372601e9898SGeorge Rimar setError("section pattern is expected"); 1373395281cfSGeorge Rimar } 137407171f21SGeorge Rimar return Ret; 1375395281cfSGeorge Rimar } 1376395281cfSGeorge Rimar 1377f8f6f1e7SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a 1378f8f6f1e7SRui Ueyama // list of glob patterns for input sections. The grammar is as follows. 1379f8f6f1e7SRui Ueyama // 1380f8f6f1e7SRui Ueyama // <patterns> ::= <section-list> 1381f8f6f1e7SRui Ueyama // | <sort> "(" <section-list> ")" 1382f8f6f1e7SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")" 1383f8f6f1e7SRui Ueyama // 1384f8f6f1e7SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 1385f8f6f1e7SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 1386f8f6f1e7SRui Ueyama // 1387f8f6f1e7SRui Ueyama // <section-list> is parsed by readInputSectionsList(). 1388a2496cbeSGeorge Rimar InputSectionDescription * 1389a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 1390c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 13910ed42b0cSDavide Italiano expect("("); 1392f373dd76SRui Ueyama while (!Error && !consume(")")) { 139307171f21SGeorge Rimar SortSectionPolicy Outer = readSortKind(); 139407171f21SGeorge Rimar SortSectionPolicy Inner = SortSectionPolicy::Default; 139507171f21SGeorge Rimar std::vector<SectionPattern> V; 139607171f21SGeorge Rimar if (Outer != SortSectionPolicy::Default) { 13970702c4e8SGeorge Rimar expect("("); 139807171f21SGeorge Rimar Inner = readSortKind(); 139907171f21SGeorge Rimar if (Inner != SortSectionPolicy::Default) { 1400350ece4eSGeorge Rimar expect("("); 140107171f21SGeorge Rimar V = readInputSectionsList(); 14020702c4e8SGeorge Rimar expect(")"); 1403350ece4eSGeorge Rimar } else { 140407171f21SGeorge Rimar V = readInputSectionsList(); 1405350ece4eSGeorge Rimar } 1406350ece4eSGeorge Rimar expect(")"); 140707171f21SGeorge Rimar } else { 140807171f21SGeorge Rimar V = readInputSectionsList(); 14090659800eSGeorge Rimar } 14100702c4e8SGeorge Rimar 141107171f21SGeorge Rimar for (SectionPattern &Pat : V) { 141207171f21SGeorge Rimar Pat.SortInner = Inner; 141307171f21SGeorge Rimar Pat.SortOuter = Outer; 141407171f21SGeorge Rimar } 141507171f21SGeorge Rimar 141607171f21SGeorge Rimar std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 141707171f21SGeorge Rimar } 141810416564SRui Ueyama return Cmd; 14190659800eSGeorge Rimar } 14200659800eSGeorge Rimar 1421a2496cbeSGeorge Rimar InputSectionDescription * 1422a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 14230659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 14240659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 1425a2496cbeSGeorge Rimar if (Tok == "KEEP") { 1426e7282797SDavide Italiano expect("("); 1427a2496cbeSGeorge Rimar StringRef FilePattern = next(); 1428a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 14290ed42b0cSDavide Italiano expect(")"); 1430cf43f179SEugene Leviant Opt.KeptSections.push_back(Cmd); 143110416564SRui Ueyama return Cmd; 143210416564SRui Ueyama } 1433a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 14340659800eSGeorge Rimar } 14350659800eSGeorge Rimar 143603fc010eSGeorge Rimar void ScriptParser::readSort() { 143703fc010eSGeorge Rimar expect("("); 143803fc010eSGeorge Rimar expect("CONSTRUCTORS"); 143903fc010eSGeorge Rimar expect(")"); 144003fc010eSGeorge Rimar } 144103fc010eSGeorge Rimar 1442eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 1443eefa758eSGeorge Rimar expect("("); 1444eefa758eSGeorge Rimar Expr E = readExpr(); 1445eefa758eSGeorge Rimar expect(","); 1446cd574a5eSGeorge Rimar StringRef Msg = unquote(next()); 1447eefa758eSGeorge Rimar expect(")"); 1448eefa758eSGeorge Rimar return [=](uint64_t Dot) { 1449eefa758eSGeorge Rimar uint64_t V = E(Dot); 1450eefa758eSGeorge Rimar if (!V) 1451eefa758eSGeorge Rimar error(Msg); 1452eefa758eSGeorge Rimar return V; 1453eefa758eSGeorge Rimar }; 1454eefa758eSGeorge Rimar } 1455eefa758eSGeorge Rimar 145625150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 145725150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from 145825150e8bSRui Ueyama // what GNU linkers do. 145925150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 146016068aebSRui Ueyama uint32_t ScriptParser::readFill() { 1461ff1f29e0SGeorge Rimar expect("("); 146216068aebSRui Ueyama uint32_t V = readOutputSectionFiller(next()); 1463ff1f29e0SGeorge Rimar expect(")"); 1464ff1f29e0SGeorge Rimar expect(";"); 1465ff1f29e0SGeorge Rimar return V; 1466ff1f29e0SGeorge Rimar } 1467ff1f29e0SGeorge Rimar 146810416564SRui Ueyama OutputSectionCommand * 146910416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 1470076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 14712a942c4bSEugene Leviant Cmd->Location = getCurrentLocation(); 147258e5c4dcSGeorge Rimar 147358e5c4dcSGeorge Rimar // Read an address expression. 147458e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 147558e5c4dcSGeorge Rimar if (peek() != ":") 147658e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 147758e5c4dcSGeorge Rimar 14788e3b38abSDenis Protivensky expect(":"); 1479246f681eSDavide Italiano 148083043f23SRui Ueyama if (consume("AT")) 1481b71d6f7aSEugene Leviant Cmd->LMAExpr = readParenExpr(); 148283043f23SRui Ueyama if (consume("ALIGN")) 14836ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 148483043f23SRui Ueyama if (consume("SUBALIGN")) 1485db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1486630c6179SGeorge Rimar 1487246f681eSDavide Italiano // Parse constraints. 148883043f23SRui Ueyama if (consume("ONLY_IF_RO")) 1489efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 149083043f23SRui Ueyama if (consume("ONLY_IF_RW")) 1491efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 14928e3b38abSDenis Protivensky expect("{"); 14938ec77e64SRui Ueyama 149483043f23SRui Ueyama while (!Error && !consume("}")) { 1495ceabe80eSEugene Leviant StringRef Tok = next(); 1496b2d99d6aSMeador Inge if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) { 1497ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1498b2d99d6aSMeador Inge } else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) { 1499e38cbab5SGeorge Rimar Cmd->Commands.emplace_back(Data); 1500b2d99d6aSMeador Inge } else if (Tok == "ASSERT") { 1501b2d99d6aSMeador Inge Cmd->Commands.emplace_back(new AssertCommand(readAssert())); 1502b2d99d6aSMeador Inge expect(";"); 15038e2eca22SGeorge Rimar } else if (Tok == "CONSTRUCTORS") { 15048e2eca22SGeorge Rimar // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors 15058e2eca22SGeorge Rimar // by name. This is for very old file formats such as ECOFF/XCOFF. 15068e2eca22SGeorge Rimar // For ELF, we should ignore. 1507b2d99d6aSMeador Inge } else if (Tok == "FILL") { 1508ff1f29e0SGeorge Rimar Cmd->Filler = readFill(); 1509b2d99d6aSMeador Inge } else if (Tok == "SORT") { 151003fc010eSGeorge Rimar readSort(); 1511b2d99d6aSMeador Inge } else if (peek() == "(") { 1512a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1513b2d99d6aSMeador Inge } else { 1514ceabe80eSEugene Leviant setError("unknown command " + Tok); 15158e3b38abSDenis Protivensky } 1516b2d99d6aSMeador Inge } 1517b889744eSMeador Inge 1518b889744eSMeador Inge if (consume(">")) 1519b889744eSMeador Inge Cmd->MemoryRegionName = next(); 1520b889744eSMeador Inge 1521076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 15224ebc5620SGeorge Rimar 152383043f23SRui Ueyama if (consume("=")) 15244ebc5620SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next()); 15254ebc5620SGeorge Rimar else if (peek().startswith("=")) 1526ff1f29e0SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next().drop_front()); 15274ebc5620SGeorge Rimar 15287185a1acSGeorge Rimar // Consume optional comma following output section command. 15297185a1acSGeorge Rimar consume(","); 15307185a1acSGeorge Rimar 153110416564SRui Ueyama return Cmd; 1532f71caa2bSRui Ueyama } 15338ec77e64SRui Ueyama 15342c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 15352c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 15362c8f1f04SRui Ueyama // 15372c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 15382c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 15392c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 15402c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 154116068aebSRui Ueyama uint32_t ScriptParser::readOutputSectionFiller(StringRef Tok) { 1542965827d6SRui Ueyama uint32_t V; 154316068aebSRui Ueyama if (!Tok.getAsInteger(0, V)) 154416068aebSRui Ueyama return V; 1545965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 154616068aebSRui Ueyama return 0; 15478e3b38abSDenis Protivensky } 15488e3b38abSDenis Protivensky 1549a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1550a31c91b1SEugene Leviant expect("("); 1551174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1552a35e39caSPetr Hosek Cmd->Provide = Provide; 1553174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1554a31c91b1SEugene Leviant expect(")"); 1555a31c91b1SEugene Leviant expect(";"); 155610416564SRui Ueyama return Cmd; 1557eda81a1bSEugene Leviant } 1558eda81a1bSEugene Leviant 1559c96da110SRafael Espindola SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 1560ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1561ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1562ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1563ceabe80eSEugene Leviant expect(";"); 1564ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1565a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1566a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1567a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1568ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1569a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1570ceabe80eSEugene Leviant } 1571ceabe80eSEugene Leviant return Cmd; 1572ceabe80eSEugene Leviant } 1573ceabe80eSEugene Leviant 1574f6aeed36SEugene Leviant static uint64_t getSymbolValue(const Twine &Loc, StringRef S, uint64_t Dot) { 157530835ea4SGeorge Rimar if (S == ".") 157630835ea4SGeorge Rimar return Dot; 1577f6aeed36SEugene Leviant return ScriptBase->getSymbolValue(Loc, S); 1578e32a3598SGeorge Rimar } 1579e32a3598SGeorge Rimar 15802f831dcaSRafael Espindola static bool isAbsolute(StringRef S) { 15812f831dcaSRafael Espindola if (S == ".") 15822f831dcaSRafael Espindola return false; 15832f831dcaSRafael Espindola return ScriptBase->isAbsolute(S); 15842f831dcaSRafael Espindola } 15852f831dcaSRafael Espindola 158630835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 158730835ea4SGeorge Rimar StringRef Op = next(); 1588db741e72SEugene Leviant Expr E; 158930835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 159083043f23SRui Ueyama if (consume("ABSOLUTE")) { 15917c1381a0SRui Ueyama // The RHS may be something like "ABSOLUTE(.) & 0xff". 15927c1381a0SRui Ueyama // Call readExpr1 to read the whole expression. 15937c1381a0SRui Ueyama E = readExpr1(readParenExpr(), 0); 1594009d1742SRui Ueyama E.IsAbsolute = [] { return true; }; 1595db741e72SEugene Leviant } else { 1596db741e72SEugene Leviant E = readExpr(); 1597db741e72SEugene Leviant } 1598f6aeed36SEugene Leviant if (Op == "+=") { 1599f6aeed36SEugene Leviant std::string Loc = getCurrentLocation(); 1600f6aeed36SEugene Leviant E = [=](uint64_t Dot) { 1601f6aeed36SEugene Leviant return getSymbolValue(Loc, Name, Dot) + E(Dot); 1602f6aeed36SEugene Leviant }; 1603f6aeed36SEugene Leviant } 1604f661393aSRafael Espindola return new SymbolAssignment(Name, E); 160530835ea4SGeorge Rimar } 160630835ea4SGeorge Rimar 160730835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 160830835ea4SGeorge Rimar // script expression. 160930835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 161030835ea4SGeorge Rimar 161136c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 161236c1cd23SRui Ueyama if (Op == "*") 161336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 161436c1cd23SRui Ueyama if (Op == "/") { 161536c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 161636c1cd23SRui Ueyama uint64_t RHS = R(Dot); 161736c1cd23SRui Ueyama if (RHS == 0) { 161836c1cd23SRui Ueyama error("division by zero"); 161936c1cd23SRui Ueyama return 0; 162036c1cd23SRui Ueyama } 162136c1cd23SRui Ueyama return L(Dot) / RHS; 162236c1cd23SRui Ueyama }; 162336c1cd23SRui Ueyama } 162436c1cd23SRui Ueyama if (Op == "+") 16252f831dcaSRafael Espindola return {[=](uint64_t Dot) { return L(Dot) + R(Dot); }, 1626009d1742SRui Ueyama [=] { return L.IsAbsolute() && R.IsAbsolute(); }, 1627009d1742SRui Ueyama [=] { 1628afaa9343SEugene Leviant const OutputSectionBase *S = L.Section(); 1629afaa9343SEugene Leviant return S ? S : R.Section(); 1630afaa9343SEugene Leviant }}; 163136c1cd23SRui Ueyama if (Op == "-") 163236c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 1633c8ccd1f1SGeorge Rimar if (Op == "<<") 1634c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) << R(Dot); }; 1635c8ccd1f1SGeorge Rimar if (Op == ">>") 1636c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) >> R(Dot); }; 163736c1cd23SRui Ueyama if (Op == "<") 163836c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 163936c1cd23SRui Ueyama if (Op == ">") 164036c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 164136c1cd23SRui Ueyama if (Op == ">=") 164236c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 164336c1cd23SRui Ueyama if (Op == "<=") 164436c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 164536c1cd23SRui Ueyama if (Op == "==") 164636c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 164736c1cd23SRui Ueyama if (Op == "!=") 164836c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 164936c1cd23SRui Ueyama if (Op == "&") 165036c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 1651cc3dd629SRafael Espindola if (Op == "|") 1652cc3dd629SRafael Espindola return [=](uint64_t Dot) { return L(Dot) | R(Dot); }; 165336c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 165436c1cd23SRui Ueyama } 165536c1cd23SRui Ueyama 1656708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1657708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1658708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1659708019c4SRui Ueyama while (!atEOF() && !Error) { 1660708019c4SRui Ueyama // Read an operator and an expression. 166146247b85SRui Ueyama if (consume("?")) 1662708019c4SRui Ueyama return readTernary(Lhs); 166346247b85SRui Ueyama StringRef Op1 = peek(); 1664708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1665a31c91b1SEugene Leviant break; 16665424e7c7SJustin Bogner skip(); 1667708019c4SRui Ueyama Expr Rhs = readPrimary(); 1668708019c4SRui Ueyama 1669708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1670708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1671708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1672708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1673708019c4SRui Ueyama while (!atEOF()) { 1674708019c4SRui Ueyama StringRef Op2 = peek(); 1675708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1676eda81a1bSEugene Leviant break; 1677708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1678eda81a1bSEugene Leviant } 1679708019c4SRui Ueyama 1680708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1681708019c4SRui Ueyama } 1682708019c4SRui Ueyama return Lhs; 1683708019c4SRui Ueyama } 1684708019c4SRui Ueyama 1685708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1686e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1687708019c4SRui Ueyama return Target->PageSize; 1688e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1689997f8838SPetr Hosek return Config->MaxPageSize; 1690708019c4SRui Ueyama error("unknown constant: " + S); 1691708019c4SRui Ueyama return 0; 1692708019c4SRui Ueyama } 1693708019c4SRui Ueyama 1694626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1695626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1696626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1697626e0b08SRui Ueyama // "M" (mega) prefixes. 16989f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 169946247b85SRui Ueyama // Negative number 1700eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1701eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1702eaeafb2bSSimon Atanasyan return false; 1703eaeafb2bSSimon Atanasyan Result = -Result; 1704eaeafb2bSSimon Atanasyan return true; 1705eaeafb2bSSimon Atanasyan } 170646247b85SRui Ueyama 170746247b85SRui Ueyama // Hexadecimal 17089f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 17099f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 17109f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 17119f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 17129f2f7ad9SGeorge Rimar 171346247b85SRui Ueyama // Decimal 17149f2f7ad9SGeorge Rimar int Suffix = 1; 17159f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 17169f2f7ad9SGeorge Rimar Suffix = 1024; 17179f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 17189f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 17199f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 17209f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 17219f2f7ad9SGeorge Rimar } 17229f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 17239f2f7ad9SGeorge Rimar return false; 17249f2f7ad9SGeorge Rimar Result *= Suffix; 17259f2f7ad9SGeorge Rimar return true; 17269f2f7ad9SGeorge Rimar } 17279f2f7ad9SGeorge Rimar 1728e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { 1729e38cbab5SGeorge Rimar int Size = StringSwitch<unsigned>(Tok) 1730e38cbab5SGeorge Rimar .Case("BYTE", 1) 1731e38cbab5SGeorge Rimar .Case("SHORT", 2) 1732e38cbab5SGeorge Rimar .Case("LONG", 4) 1733e38cbab5SGeorge Rimar .Case("QUAD", 8) 1734e38cbab5SGeorge Rimar .Default(-1); 1735e38cbab5SGeorge Rimar if (Size == -1) 1736e38cbab5SGeorge Rimar return nullptr; 1737e38cbab5SGeorge Rimar 173895c7d8d2SMeador Inge return new BytesDataCommand(readParenExpr(), Size); 1739e38cbab5SGeorge Rimar } 1740e38cbab5SGeorge Rimar 1741b71d6f7aSEugene Leviant StringRef ScriptParser::readParenLiteral() { 1742b71d6f7aSEugene Leviant expect("("); 1743b71d6f7aSEugene Leviant StringRef Tok = next(); 1744b71d6f7aSEugene Leviant expect(")"); 1745b71d6f7aSEugene Leviant return Tok; 1746b71d6f7aSEugene Leviant } 1747b71d6f7aSEugene Leviant 1748708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 17496ad7dfccSRui Ueyama if (peek() == "(") 17506ad7dfccSRui Ueyama return readParenExpr(); 1751708019c4SRui Ueyama 17526ad7dfccSRui Ueyama StringRef Tok = next(); 1753b5f1c3ecSRui Ueyama std::string Location = getCurrentLocation(); 1754708019c4SRui Ueyama 1755eaeafb2bSSimon Atanasyan if (Tok == "~") { 1756eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1757eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return ~E(Dot); }; 1758eaeafb2bSSimon Atanasyan } 1759eaeafb2bSSimon Atanasyan if (Tok == "-") { 1760eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1761eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return -E(Dot); }; 1762eaeafb2bSSimon Atanasyan } 1763eaeafb2bSSimon Atanasyan 1764708019c4SRui Ueyama // Built-in functions are parsed here. 1765708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 176696659df0SGeorge Rimar if (Tok == "ADDR") { 1767b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1768ed30ce7aSEugene Leviant return {[=](uint64_t Dot) { 1769ed30ce7aSEugene Leviant return ScriptBase->getOutputSection(Location, Name)->Addr; 1770ed30ce7aSEugene Leviant }, 1771009d1742SRui Ueyama [=] { return false; }, 1772ed30ce7aSEugene Leviant [=] { return ScriptBase->getOutputSection(Location, Name); }}; 177396659df0SGeorge Rimar } 1774b71d6f7aSEugene Leviant if (Tok == "LOADADDR") { 1775b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1776afaa9343SEugene Leviant return [=](uint64_t Dot) { 1777ed30ce7aSEugene Leviant return ScriptBase->getOutputSection(Location, Name)->getLMA(); 1778afaa9343SEugene Leviant }; 1779b71d6f7aSEugene Leviant } 1780eefa758eSGeorge Rimar if (Tok == "ASSERT") 1781eefa758eSGeorge Rimar return readAssert(); 1782708019c4SRui Ueyama if (Tok == "ALIGN") { 17835d804dc8SRui Ueyama expect("("); 17845d804dc8SRui Ueyama Expr E = readExpr(); 17855d804dc8SRui Ueyama if (consume(",")) { 17865d804dc8SRui Ueyama Expr E2 = readExpr(); 17875d804dc8SRui Ueyama expect(")"); 17885d804dc8SRui Ueyama return [=](uint64_t Dot) { return alignTo(E(Dot), E2(Dot)); }; 17895d804dc8SRui Ueyama } 17905d804dc8SRui Ueyama expect(")"); 1791708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1792708019c4SRui Ueyama } 1793708019c4SRui Ueyama if (Tok == "CONSTANT") { 1794b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1795b0de56b5SRafael Espindola return [=](uint64_t Dot) { return getConstant(Name); }; 1796708019c4SRui Ueyama } 1797f34f45fdSGeorge Rimar if (Tok == "DEFINED") { 17980ee25a69SRui Ueyama StringRef Name = readParenLiteral(); 17990ee25a69SRui Ueyama return [=](uint64_t Dot) { return ScriptBase->isDefined(Name) ? 1 : 0; }; 1800f34f45fdSGeorge Rimar } 180154c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 180254c145ceSRafael Espindola expect("("); 18035424e7c7SJustin Bogner skip(); 180454c145ceSRafael Espindola expect(","); 18058c658bf8SGeorge Rimar Expr E = readExpr(); 180654c145ceSRafael Espindola expect(")"); 18078c658bf8SGeorge Rimar return [=](uint64_t Dot) { return E(Dot); }; 180854c145ceSRafael Espindola } 1809708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1810708019c4SRui Ueyama expect("("); 1811708019c4SRui Ueyama Expr E = readExpr(); 1812708019c4SRui Ueyama expect(","); 1813708019c4SRui Ueyama readExpr(); 1814708019c4SRui Ueyama expect(")"); 1815f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1816708019c4SRui Ueyama } 1817708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1818708019c4SRui Ueyama expect("("); 1819708019c4SRui Ueyama expect("."); 1820708019c4SRui Ueyama expect(")"); 1821708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1822708019c4SRui Ueyama } 1823276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1824276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1825276b4e64SGeorge Rimar // the next page boundary for simplicity. 1826276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1827276b4e64SGeorge Rimar expect("("); 182897bdc722SRafael Espindola readExpr(); 1829276b4e64SGeorge Rimar expect(","); 1830276b4e64SGeorge Rimar readExpr(); 1831276b4e64SGeorge Rimar expect(")"); 1832276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1833276b4e64SGeorge Rimar } 18349e69450eSGeorge Rimar if (Tok == "SIZEOF") { 1835b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1836edf75e79SRui Ueyama return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; 18379e69450eSGeorge Rimar } 183836fac7f0SEugene Leviant if (Tok == "ALIGNOF") { 1839b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1840afaa9343SEugene Leviant return [=](uint64_t Dot) { 1841ed30ce7aSEugene Leviant return ScriptBase->getOutputSection(Location, Name)->Addralign; 1842afaa9343SEugene Leviant }; 184336fac7f0SEugene Leviant } 1844e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 1845b0de56b5SRafael Espindola return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; 1846708019c4SRui Ueyama 18479f2f7ad9SGeorge Rimar // Tok is a literal number. 18489f2f7ad9SGeorge Rimar uint64_t V; 18499f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 1850b0de56b5SRafael Espindola return [=](uint64_t Dot) { return V; }; 18519f2f7ad9SGeorge Rimar 18529f2f7ad9SGeorge Rimar // Tok is a symbol name. 185330835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1854708019c4SRui Ueyama setError("malformed number: " + Tok); 1855f6aeed36SEugene Leviant return {[=](uint64_t Dot) { return getSymbolValue(Location, Tok, Dot); }, 1856009d1742SRui Ueyama [=] { return isAbsolute(Tok); }, 1857009d1742SRui Ueyama [=] { return ScriptBase->getSymbolSection(Tok); }}; 1858a9c5a528SGeorge Rimar } 1859708019c4SRui Ueyama 1860708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1861708019c4SRui Ueyama Expr L = readExpr(); 1862708019c4SRui Ueyama expect(":"); 1863708019c4SRui Ueyama Expr R = readExpr(); 1864708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1865708019c4SRui Ueyama } 1866708019c4SRui Ueyama 18676ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 18686ad7dfccSRui Ueyama expect("("); 18696ad7dfccSRui Ueyama Expr E = readExpr(); 18706ad7dfccSRui Ueyama expect(")"); 18716ad7dfccSRui Ueyama return E; 18726ad7dfccSRui Ueyama } 18736ad7dfccSRui Ueyama 1874bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1875bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1876bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1877bbe38602SEugene Leviant StringRef Tok = next(); 1878da841c16SGeorge Rimar Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); 1879bbe38602SEugene Leviant } 1880bbe38602SEugene Leviant return Phdrs; 1881bbe38602SEugene Leviant } 1882bbe38602SEugene Leviant 188395dd718cSGeorge Rimar // Read a program header type name. The next token must be a 188495dd718cSGeorge Rimar // name of a program header type or a constant (e.g. "0x3"). 1885bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1886bbe38602SEugene Leviant StringRef Tok = next(); 188795dd718cSGeorge Rimar uint64_t Val; 188895dd718cSGeorge Rimar if (readInteger(Tok, Val)) 188995dd718cSGeorge Rimar return Val; 189095dd718cSGeorge Rimar 1891b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1892b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1893b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1894b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1895b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1896b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1897b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1898b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1899b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1900b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1901b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1902b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1903270173f2SGeorge Rimar .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 1904cc6e567cSGeorge Rimar .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 1905a2a32c2cSGeorge Rimar .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) 1906b0f6c590SRui Ueyama .Default(-1); 1907bbe38602SEugene Leviant 1908b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1909b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1910b0f6c590SRui Ueyama return PT_NULL; 1911b0f6c590SRui Ueyama } 1912b0f6c590SRui Ueyama return Ret; 1913bbe38602SEugene Leviant } 1914bbe38602SEugene Leviant 191512450b20SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 191612450b20SRui Ueyama void ScriptParser::readAnonymousDeclaration() { 191712450b20SRui Ueyama // Read global symbols first. "global:" is default, so if there's 191812450b20SRui Ueyama // no label, we assume global symbols. 191912450b20SRui Ueyama if (consume("global:") || peek() != "local:") 192012450b20SRui Ueyama Config->VersionScriptGlobals = readSymbols(); 192112450b20SRui Ueyama 1922e999ddb8SRafael Espindola readLocals(); 192312450b20SRui Ueyama expect("}"); 192412450b20SRui Ueyama expect(";"); 192512450b20SRui Ueyama } 192612450b20SRui Ueyama 1927e999ddb8SRafael Espindola void ScriptParser::readLocals() { 1928e999ddb8SRafael Espindola if (!consume("local:")) 1929e999ddb8SRafael Espindola return; 1930e999ddb8SRafael Espindola std::vector<SymbolVersion> Locals = readSymbols(); 1931e999ddb8SRafael Espindola for (SymbolVersion V : Locals) { 1932e999ddb8SRafael Espindola if (V.Name == "*") { 1933e999ddb8SRafael Espindola Config->DefaultSymbolVersion = VER_NDX_LOCAL; 1934e999ddb8SRafael Espindola continue; 1935e999ddb8SRafael Espindola } 1936e999ddb8SRafael Espindola Config->VersionScriptLocals.push_back(V); 1937e999ddb8SRafael Espindola } 1938e999ddb8SRafael Espindola } 1939e999ddb8SRafael Espindola 194012450b20SRui Ueyama // Reads a list of symbols, e.g. "VerStr { global: foo; bar; local: *; };". 194195769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 194220b6598cSGeorge Rimar // Identifiers start at 2 because 0 and 1 are reserved 194320b6598cSGeorge Rimar // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. 1944da805c48SRui Ueyama uint16_t VersionId = Config->VersionDefinitions.size() + 2; 194520b6598cSGeorge Rimar Config->VersionDefinitions.push_back({VerStr, VersionId}); 194620b6598cSGeorge Rimar 194712450b20SRui Ueyama // Read global symbols. 194883043f23SRui Ueyama if (consume("global:") || peek() != "local:") 194912450b20SRui Ueyama Config->VersionDefinitions.back().Globals = readSymbols(); 195012450b20SRui Ueyama 1951e999ddb8SRafael Espindola readLocals(); 195220b6598cSGeorge Rimar expect("}"); 195320b6598cSGeorge Rimar 195412450b20SRui Ueyama // Each version may have a parent version. For example, "Ver2" 195512450b20SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 195612450b20SRui Ueyama // as a parent. This version hierarchy is, probably against your 195712450b20SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it 195812450b20SRui Ueyama // at all. In LLD, we simply ignore it. 195912450b20SRui Ueyama if (peek() != ";") 19605424e7c7SJustin Bogner skip(); 196120b6598cSGeorge Rimar expect(";"); 196220b6598cSGeorge Rimar } 196320b6598cSGeorge Rimar 196412450b20SRui Ueyama // Reads a list of symbols for a versions cript. 196512450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readSymbols() { 196612450b20SRui Ueyama std::vector<SymbolVersion> Ret; 1967e0fc2421SGeorge Rimar for (;;) { 19681ef90d2fSRafael Espindola if (consume("extern")) { 196912450b20SRui Ueyama for (SymbolVersion V : readVersionExtern()) 197012450b20SRui Ueyama Ret.push_back(V); 19711ef90d2fSRafael Espindola continue; 19721ef90d2fSRafael Espindola } 1973e0fc2421SGeorge Rimar 19740ee25a69SRui Ueyama if (peek() == "}" || peek() == "local:" || Error) 197512450b20SRui Ueyama break; 19760ee25a69SRui Ueyama StringRef Tok = next(); 197712450b20SRui Ueyama Ret.push_back({unquote(Tok), false, hasWildcard(Tok)}); 1978e0fc2421SGeorge Rimar expect(";"); 1979e0fc2421SGeorge Rimar } 198012450b20SRui Ueyama return Ret; 1981e0fc2421SGeorge Rimar } 1982e0fc2421SGeorge Rimar 198312450b20SRui Ueyama // Reads an "extern C++" directive, e.g., 198412450b20SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };" 198512450b20SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 19867e71415cSRafael Espindola StringRef Tok = next(); 19877e71415cSRafael Espindola bool IsCXX = Tok == "\"C++\""; 19887e71415cSRafael Espindola if (!IsCXX && Tok != "\"C\"") 1989d0ebd84cSRafael Espindola setError("Unknown language"); 199020b6598cSGeorge Rimar expect("{"); 199120b6598cSGeorge Rimar 199212450b20SRui Ueyama std::vector<SymbolVersion> Ret; 19930ee25a69SRui Ueyama while (!Error && peek() != "}") { 19940ee25a69SRui Ueyama StringRef Tok = next(); 19950ee25a69SRui Ueyama bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); 19967e71415cSRafael Espindola Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); 199720b6598cSGeorge Rimar expect(";"); 199820b6598cSGeorge Rimar } 199920b6598cSGeorge Rimar 200020b6598cSGeorge Rimar expect("}"); 200120b6598cSGeorge Rimar expect(";"); 200212450b20SRui Ueyama return Ret; 200320b6598cSGeorge Rimar } 200420b6598cSGeorge Rimar 200524e626ccSRui Ueyama uint64_t ScriptParser::readMemoryAssignment( 200624e626ccSRui Ueyama StringRef S1, StringRef S2, StringRef S3) { 200724e626ccSRui Ueyama if (!(consume(S1) || consume(S2) || consume(S3))) { 200824e626ccSRui Ueyama setError("expected one of: " + S1 + ", " + S2 + ", or " + S3); 200924e626ccSRui Ueyama return 0; 201024e626ccSRui Ueyama } 201124e626ccSRui Ueyama expect("="); 201224e626ccSRui Ueyama 201324e626ccSRui Ueyama // TODO: Fully support constant expressions. 201424e626ccSRui Ueyama uint64_t Val; 201524e626ccSRui Ueyama if (!readInteger(next(), Val)) 201624e626ccSRui Ueyama setError("nonconstant expression for "+ S1); 201724e626ccSRui Ueyama return Val; 201824e626ccSRui Ueyama } 201924e626ccSRui Ueyama 202024e626ccSRui Ueyama // Parse the MEMORY command as specified in: 202124e626ccSRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html 202224e626ccSRui Ueyama // 202324e626ccSRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } 2024b889744eSMeador Inge void ScriptParser::readMemory() { 2025b889744eSMeador Inge expect("{"); 2026b889744eSMeador Inge while (!Error && !consume("}")) { 2027b889744eSMeador Inge StringRef Name = next(); 202824e626ccSRui Ueyama 2029b889744eSMeador Inge uint32_t Flags = 0; 2030*8a8a953eSRui Ueyama uint32_t NegFlags = 0; 2031b889744eSMeador Inge if (consume("(")) { 2032*8a8a953eSRui Ueyama std::tie(Flags, NegFlags) = readMemoryAttributes(); 2033b889744eSMeador Inge expect(")"); 2034b889744eSMeador Inge } 2035b889744eSMeador Inge expect(":"); 2036b889744eSMeador Inge 203724e626ccSRui Ueyama uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o"); 2038b889744eSMeador Inge expect(","); 203924e626ccSRui Ueyama uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); 2040b889744eSMeador Inge 2041b889744eSMeador Inge // Add the memory region to the region map (if it doesn't already exist). 2042b889744eSMeador Inge auto It = Opt.MemoryRegions.find(Name); 2043b889744eSMeador Inge if (It != Opt.MemoryRegions.end()) 2044b889744eSMeador Inge setError("region '" + Name + "' already defined"); 2045b889744eSMeador Inge else 2046*8a8a953eSRui Ueyama Opt.MemoryRegions[Name] = {Name, Origin, Length, Origin, Flags, NegFlags}; 2047b889744eSMeador Inge } 2048b889744eSMeador Inge } 2049b889744eSMeador Inge 2050b889744eSMeador Inge // This function parses the attributes used to match against section 2051b889744eSMeador Inge // flags when placing output sections in a memory region. These flags 2052b889744eSMeador Inge // are only used when an explicit memory region name is not used. 2053b889744eSMeador Inge std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { 2054b889744eSMeador Inge uint32_t Flags = 0; 2055*8a8a953eSRui Ueyama uint32_t NegFlags = 0; 2056b889744eSMeador Inge bool Invert = false; 2057481ac996SRui Ueyama 2058481ac996SRui Ueyama for (char C : next().lower()) { 2059b889744eSMeador Inge uint32_t Flag = 0; 2060b889744eSMeador Inge if (C == '!') 2061b889744eSMeador Inge Invert = !Invert; 2062481ac996SRui Ueyama else if (C == 'w') 2063b889744eSMeador Inge Flag = SHF_WRITE; 2064481ac996SRui Ueyama else if (C == 'x') 2065b889744eSMeador Inge Flag = SHF_EXECINSTR; 2066481ac996SRui Ueyama else if (C == 'a') 2067b889744eSMeador Inge Flag = SHF_ALLOC; 2068481ac996SRui Ueyama else if (C != 'r') 2069b889744eSMeador Inge setError("invalid memory region attribute"); 2070481ac996SRui Ueyama 2071b889744eSMeador Inge if (Invert) 2072*8a8a953eSRui Ueyama NegFlags |= Flag; 2073b889744eSMeador Inge else 2074b889744eSMeador Inge Flags |= Flag; 2075b889744eSMeador Inge } 2076*8a8a953eSRui Ueyama return {Flags, NegFlags}; 2077b889744eSMeador Inge } 2078b889744eSMeador Inge 207907320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 208022375f24SRui Ueyama ScriptParser(MB).readLinkerScript(); 208120b6598cSGeorge Rimar } 208220b6598cSGeorge Rimar 208320b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 208422375f24SRui Ueyama ScriptParser(MB).readVersionScript(); 2085f7c5fbb1SRui Ueyama } 20861ebc8ed7SRui Ueyama 2087d0ebd84cSRafael Espindola void elf::readDynamicList(MemoryBufferRef MB) { 2088d0ebd84cSRafael Espindola ScriptParser(MB).readDynamicList(); 2089d0ebd84cSRafael Espindola } 2090d0ebd84cSRafael Espindola 209107320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 209207320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 209307320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 209407320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 2095