1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===// 2f7c5fbb1SRui Ueyama // 3f7c5fbb1SRui Ueyama // The LLVM Linker 4f7c5fbb1SRui Ueyama // 5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source 6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details. 7f7c5fbb1SRui Ueyama // 8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 9f7c5fbb1SRui Ueyama // 10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script. 11629e0aa5SRui Ueyama // It parses a linker script and write the result to Config or ScriptConfig 12629e0aa5SRui Ueyama // objects. 13629e0aa5SRui Ueyama // 14629e0aa5SRui Ueyama // If SECTIONS command is used, a ScriptConfig contains an AST 15629e0aa5SRui Ueyama // of the command which will later be consumed by createSections() and 16629e0aa5SRui Ueyama // assignAddresses(). 17f7c5fbb1SRui Ueyama // 18f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 19f7c5fbb1SRui Ueyama 20717677afSRui Ueyama #include "LinkerScript.h" 21f7c5fbb1SRui Ueyama #include "Config.h" 22f7c5fbb1SRui Ueyama #include "Driver.h" 231ebc8ed7SRui Ueyama #include "InputSection.h" 24652852c5SGeorge Rimar #include "OutputSections.h" 25e77b5bf6SAdhemerval Zanella #include "ScriptParser.h" 2693c9af42SRui Ueyama #include "Strings.h" 27eda81a1bSEugene Leviant #include "Symbols.h" 28f7c5fbb1SRui Ueyama #include "SymbolTable.h" 29467c4d55SEugene Leviant #include "Target.h" 30bbe38602SEugene Leviant #include "Writer.h" 31960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 32652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 33f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 34f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h" 35f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 36a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h" 37f7c5fbb1SRui Ueyama 38f7c5fbb1SRui Ueyama using namespace llvm; 39652852c5SGeorge Rimar using namespace llvm::ELF; 401ebc8ed7SRui Ueyama using namespace llvm::object; 41e38cbab5SGeorge Rimar using namespace llvm::support::endian; 42f7c5fbb1SRui Ueyama using namespace lld; 43e0df00b9SRafael Espindola using namespace lld::elf; 44f7c5fbb1SRui Ueyama 45884e786dSGeorge Rimar LinkerScriptBase *elf::ScriptBase; 4607320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 47717677afSRui Ueyama 486c55f0e3SGeorge Rimar template <class ELFT> static void addRegular(SymbolAssignment *Cmd) { 491602421cSRui Ueyama Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, STB_GLOBAL, STV_DEFAULT); 501602421cSRui Ueyama Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; 511602421cSRui Ueyama Cmd->Sym = Sym->body(); 5220d03194SEugene Leviant 5320d03194SEugene Leviant // If we have no SECTIONS then we don't have '.' and don't call 5420d03194SEugene Leviant // assignAddresses(). We calculate symbol value immediately in this case. 5520d03194SEugene Leviant if (!ScriptConfig->HasSections) 5620d03194SEugene Leviant cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0); 57ceabe80eSEugene Leviant } 58ceabe80eSEugene Leviant 590c70d3ccSRui Ueyama template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) { 60e1937bb5SGeorge Rimar Symbol *Sym = Symtab<ELFT>::X->addSynthetic( 61e1937bb5SGeorge Rimar Cmd->Name, nullptr, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT); 621602421cSRui Ueyama Cmd->Sym = Sym->body(); 63ceabe80eSEugene Leviant } 64ceabe80eSEugene Leviant 65db741e72SEugene Leviant template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) { 66db741e72SEugene Leviant if (Cmd->IsAbsolute) 67db741e72SEugene Leviant addRegular<ELFT>(Cmd); 68db741e72SEugene Leviant else 69db741e72SEugene Leviant addSynthetic<ELFT>(Cmd); 70db741e72SEugene Leviant } 711602421cSRui Ueyama // If a symbol was in PROVIDE(), we need to define it only when 721602421cSRui Ueyama // it is an undefined symbol. 731602421cSRui Ueyama template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) { 741602421cSRui Ueyama if (Cmd->Name == ".") 75ceabe80eSEugene Leviant return false; 761602421cSRui Ueyama if (!Cmd->Provide) 77ceabe80eSEugene Leviant return true; 781602421cSRui Ueyama SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 791602421cSRui Ueyama return B && B->isUndefined(); 80ceabe80eSEugene Leviant } 81ceabe80eSEugene Leviant 82076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 83076fe157SGeorge Rimar return C->Kind == AssignmentKind; 84076fe157SGeorge Rimar } 85076fe157SGeorge Rimar 86076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 87076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 88076fe157SGeorge Rimar } 89076fe157SGeorge Rimar 90eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 91eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 92eea3114fSGeorge Rimar } 93eea3114fSGeorge Rimar 94eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 95eefa758eSGeorge Rimar return C->Kind == AssertKind; 96eefa758eSGeorge Rimar } 97eefa758eSGeorge Rimar 98e38cbab5SGeorge Rimar bool BytesDataCommand::classof(const BaseCommand *C) { 99e38cbab5SGeorge Rimar return C->Kind == BytesDataKind; 100e38cbab5SGeorge Rimar } 101e38cbab5SGeorge Rimar 10236a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) { 103eea3114fSGeorge Rimar return !S || !S->Live; 104717677afSRui Ueyama } 105717677afSRui Ueyama 106f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::LinkerScript() {} 107f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::~LinkerScript() {} 108f34d0e08SRui Ueyama 10907320e40SRui Ueyama template <class ELFT> 11007320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 111cf43f179SEugene Leviant for (InputSectionDescription *ID : Opt.KeptSections) { 112cf43f179SEugene Leviant StringRef Filename = S->getFile()->getName(); 113cf43f179SEugene Leviant if (!ID->FileRe.match(sys::path::filename(Filename))) 114cf43f179SEugene Leviant continue; 115cf43f179SEugene Leviant 116cf43f179SEugene Leviant for (SectionPattern &P : ID->SectionPatterns) 117cf43f179SEugene Leviant if (P.SectionRe.match(S->Name)) 118eea3114fSGeorge Rimar return true; 119cf43f179SEugene Leviant } 120eea3114fSGeorge Rimar return false; 121eea3114fSGeorge Rimar } 122eea3114fSGeorge Rimar 123575208caSGeorge Rimar static bool comparePriority(InputSectionData *A, InputSectionData *B) { 124575208caSGeorge Rimar return getPriority(A->Name) < getPriority(B->Name); 125575208caSGeorge Rimar } 126575208caSGeorge Rimar 127c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) { 128042a3f20SRafael Espindola return A->Name < B->Name; 1290702c4e8SGeorge Rimar } 130742c3836SRui Ueyama 131c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) { 132742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 133742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 134742c3836SRui Ueyama // This is compatible with GNU. 135742c3836SRui Ueyama return A->Alignment > B->Alignment; 136742c3836SRui Ueyama } 137742c3836SRui Ueyama 138c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)> 139be394db3SGeorge Rimar getComparator(SortSectionPolicy K) { 140be394db3SGeorge Rimar switch (K) { 141be394db3SGeorge Rimar case SortSectionPolicy::Alignment: 142c0028d3dSRafael Espindola return compareAlignment; 143be394db3SGeorge Rimar case SortSectionPolicy::Name: 144be394db3SGeorge Rimar return compareName; 145be394db3SGeorge Rimar case SortSectionPolicy::Priority: 146be394db3SGeorge Rimar return comparePriority; 147be394db3SGeorge Rimar default: 148be394db3SGeorge Rimar llvm_unreachable("unknown sort policy"); 149be394db3SGeorge Rimar } 150742c3836SRui Ueyama } 1510702c4e8SGeorge Rimar 15248c3f1ceSRui Ueyama template <class ELFT> 153e71a3f8aSRafael Espindola static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 15406ae6836SGeorge Rimar ConstraintKind Kind) { 1558f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 1568f66df92SGeorge Rimar return true; 157e746e52cSRafael Espindola bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) { 158d3190795SRafael Espindola auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2); 159*58139d17SRafael Espindola return Sec->getFlags() & SHF_WRITE; 16006ae6836SGeorge Rimar }); 161e746e52cSRafael Espindola return (IsRW && Kind == ConstraintKind::ReadWrite) || 162e746e52cSRafael Espindola (!IsRW && Kind == ConstraintKind::ReadOnly); 16306ae6836SGeorge Rimar } 16406ae6836SGeorge Rimar 16507171f21SGeorge Rimar static void sortSections(InputSectionData **Begin, InputSectionData **End, 166ee924709SRui Ueyama SortSectionPolicy K) { 167ee924709SRui Ueyama if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None) 16807171f21SGeorge Rimar std::stable_sort(Begin, End, getComparator(K)); 169ee924709SRui Ueyama } 170ee924709SRui Ueyama 171d3190795SRafael Espindola // Compute and remember which sections the InputSectionDescription matches. 172be94e1b6SRafael Espindola template <class ELFT> 173e71a3f8aSRafael Espindola void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) { 1744dc07becSRui Ueyama // Collects all sections that satisfy constraints of I 1754dc07becSRui Ueyama // and attach them to I. 1764dc07becSRui Ueyama for (SectionPattern &Pat : I->SectionPatterns) { 17707171f21SGeorge Rimar size_t SizeBefore = I->Sections.size(); 178395281cfSGeorge Rimar for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) { 1793ff27f49SRui Ueyama StringRef Filename = sys::path::filename(F->getName()); 180f135f0ecSRafael Espindola if (!I->FileRe.match(Filename) || Pat.ExcludedFileRe.match(Filename)) 1813ff27f49SRui Ueyama continue; 1824dc07becSRui Ueyama 183be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : F->getSections()) 184f135f0ecSRafael Espindola if (!isDiscarded(S) && !S->OutSec && Pat.SectionRe.match(S->Name)) 185d3190795SRafael Espindola I->Sections.push_back(S); 186f135f0ecSRafael Espindola if (Pat.SectionRe.match("COMMON")) 187d3190795SRafael Espindola I->Sections.push_back(CommonInputSection<ELFT>::X); 188395281cfSGeorge Rimar } 189d3190795SRafael Espindola 190ee924709SRui Ueyama // Sort sections as instructed by SORT-family commands and --sort-section 191ee924709SRui Ueyama // option. Because SORT-family commands can be nested at most two depth 192ee924709SRui Ueyama // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command 193ee924709SRui Ueyama // line option is respected even if a SORT command is given, the exact 194ee924709SRui Ueyama // behavior we have here is a bit complicated. Here are the rules. 195ee924709SRui Ueyama // 196ee924709SRui Ueyama // 1. If two SORT commands are given, --sort-section is ignored. 197ee924709SRui Ueyama // 2. If one SORT command is given, and if it is not SORT_NONE, 198ee924709SRui Ueyama // --sort-section is handled as an inner SORT command. 199ee924709SRui Ueyama // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. 200ee924709SRui Ueyama // 4. If no SORT command is given, sort according to --sort-section. 20107171f21SGeorge Rimar InputSectionData **Begin = I->Sections.data() + SizeBefore; 20207171f21SGeorge Rimar InputSectionData **End = I->Sections.data() + I->Sections.size(); 20307171f21SGeorge Rimar if (Pat.SortOuter != SortSectionPolicy::None) { 20407171f21SGeorge Rimar if (Pat.SortInner == SortSectionPolicy::Default) 20507171f21SGeorge Rimar sortSections(Begin, End, Config->SortSection); 206ee924709SRui Ueyama else 20707171f21SGeorge Rimar sortSections(Begin, End, Pat.SortInner); 20807171f21SGeorge Rimar sortSections(Begin, End, Pat.SortOuter); 20907171f21SGeorge Rimar } 210ee924709SRui Ueyama } 211d3190795SRafael Espindola 212d3190795SRafael Espindola // We do not add duplicate input sections, so mark them with a dummy output 213d3190795SRafael Espindola // section for now. 214d3190795SRafael Espindola for (InputSectionData *S : I->Sections) { 215d3190795SRafael Espindola auto *S2 = static_cast<InputSectionBase<ELFT> *>(S); 216d3190795SRafael Espindola S2->OutSec = (OutputSectionBase<ELFT> *)-1; 217d3190795SRafael Espindola } 218be94e1b6SRafael Espindola } 219be94e1b6SRafael Espindola 220be94e1b6SRafael Espindola template <class ELFT> 221be94e1b6SRafael Espindola void LinkerScript<ELFT>::discard(ArrayRef<InputSectionBase<ELFT> *> V) { 222be94e1b6SRafael Espindola for (InputSectionBase<ELFT> *S : V) { 223be94e1b6SRafael Espindola S->Live = false; 224be94e1b6SRafael Espindola reportDiscarded(S); 225be94e1b6SRafael Espindola } 226be94e1b6SRafael Espindola } 227be94e1b6SRafael Espindola 22806ae6836SGeorge Rimar template <class ELFT> 2290b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 23006ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 2310b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 232e7f912cdSRui Ueyama 23306ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 2347c3ff2ebSRafael Espindola auto *Cmd = dyn_cast<InputSectionDescription>(Base.get()); 2357c3ff2ebSRafael Espindola if (!Cmd) 2360b9ce6a4SRui Ueyama continue; 237e71a3f8aSRafael Espindola computeInputSections(Cmd); 238d3190795SRafael Espindola for (InputSectionData *S : Cmd->Sections) 239d3190795SRafael Espindola Ret.push_back(static_cast<InputSectionBase<ELFT> *>(S)); 2400b9ce6a4SRui Ueyama } 241e71a3f8aSRafael Espindola 242cc1ba8c7SEugene Leviant // After we created final list we should now set OutSec pointer to null, 243cc1ba8c7SEugene Leviant // instead of -1. Otherwise we may get a crash when writing relocs, in 244cc1ba8c7SEugene Leviant // case section is discarded by linker script 245cc1ba8c7SEugene Leviant for (InputSectionBase<ELFT> *S : Ret) 246cc1ba8c7SEugene Leviant S->OutSec = nullptr; 247cc1ba8c7SEugene Leviant 2480b9ce6a4SRui Ueyama return Ret; 2490b9ce6a4SRui Ueyama } 2500b9ce6a4SRui Ueyama 251e5d3ca50SPetr Hosek template <class ELFT> 25210897f18SRafael Espindola static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C, 25310897f18SRafael Espindola StringRef OutsecName) { 25410897f18SRafael Espindola // When using linker script the merge rules are different. 25510897f18SRafael Espindola // Unfortunately, linker scripts are name based. This means that expressions 25610897f18SRafael Espindola // like *(.foo*) can refer to multiple input sections that would normally be 25710897f18SRafael Espindola // placed in different output sections. We cannot put them in different 25810897f18SRafael Espindola // output sections or we would produce wrong results for 25910897f18SRafael Espindola // start = .; *(.foo.*) end = .; *(.bar) 26010897f18SRafael Espindola // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to 26110897f18SRafael Espindola // another. The problem is that there is no way to layout those output 26210897f18SRafael Espindola // sections such that the .foo sections are the only thing between the 26310897f18SRafael Espindola // start and end symbols. 26410897f18SRafael Espindola 26510897f18SRafael Espindola // An extra annoyance is that we cannot simply disable merging of the contents 26610897f18SRafael Espindola // of SHF_MERGE sections, but our implementation requires one output section 26710897f18SRafael Espindola // per "kind" (string or not, which size/aligment). 26810897f18SRafael Espindola // Fortunately, creating symbols in the middle of a merge section is not 26910897f18SRafael Espindola // supported by bfd or gold, so we can just create multiple section in that 27010897f18SRafael Espindola // case. 27110897f18SRafael Espindola typedef typename ELFT::uint uintX_t; 272*58139d17SRafael Espindola uintX_t Flags = C->getFlags() & (SHF_MERGE | SHF_STRINGS); 27310897f18SRafael Espindola 27410897f18SRafael Espindola uintX_t Alignment = 0; 27510897f18SRafael Espindola if (isa<MergeInputSection<ELFT>>(C)) 276*58139d17SRafael Espindola Alignment = std::max<uintX_t>(C->Alignment, C->getEntsize()); 27710897f18SRafael Espindola 27810897f18SRafael Espindola return SectionKey<ELFT::Is64Bits>{OutsecName, /*Type*/ 0, Flags, Alignment}; 27910897f18SRafael Espindola } 28010897f18SRafael Espindola 28110897f18SRafael Espindola template <class ELFT> 28220d03194SEugene Leviant void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory, 28320d03194SEugene Leviant InputSectionBase<ELFT> *Sec, 28420d03194SEugene Leviant StringRef Name) { 28528c1597aSRafael Espindola OutputSectionBase<ELFT> *OutSec; 28628c1597aSRafael Espindola bool IsNew; 28710897f18SRafael Espindola std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec); 28828c1597aSRafael Espindola if (IsNew) 28928c1597aSRafael Espindola OutputSections->push_back(OutSec); 29020d03194SEugene Leviant OutSec->addSection(Sec); 29120d03194SEugene Leviant } 29220d03194SEugene Leviant 29320d03194SEugene Leviant template <class ELFT> 29420d03194SEugene Leviant void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { 29528c1597aSRafael Espindola 2967c3ff2ebSRafael Espindola for (unsigned I = 0; I < Opt.Commands.size(); ++I) { 2977c3ff2ebSRafael Espindola auto Iter = Opt.Commands.begin() + I; 2987c3ff2ebSRafael Espindola const std::unique_ptr<BaseCommand> &Base1 = *Iter; 2992ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 3002ab5f73dSRui Ueyama if (shouldDefine<ELFT>(Cmd)) 3012ab5f73dSRui Ueyama addRegular<ELFT>(Cmd); 3022ab5f73dSRui Ueyama continue; 3032ab5f73dSRui Ueyama } 30420d03194SEugene Leviant if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) { 30520d03194SEugene Leviant // If we don't have SECTIONS then output sections have already been 306194470cdSGeorge Rimar // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses 30720d03194SEugene Leviant // will not be called, so ASSERT should be evaluated now. 30820d03194SEugene Leviant if (!Opt.HasSections) 30920d03194SEugene Leviant Cmd->Expression(0); 31020d03194SEugene Leviant continue; 31120d03194SEugene Leviant } 3122ab5f73dSRui Ueyama 313ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 3147bd37870SRafael Espindola std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 3157bd37870SRafael Espindola 31648c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 3177bd37870SRafael Espindola discard(V); 31848c3f1ceSRui Ueyama continue; 31948c3f1ceSRui Ueyama } 3200b9ce6a4SRui Ueyama 3217c3ff2ebSRafael Espindola if (!matchConstraints<ELFT>(V, Cmd->Constraint)) { 3227c3ff2ebSRafael Espindola for (InputSectionBase<ELFT> *S : V) 3237c3ff2ebSRafael Espindola S->OutSec = nullptr; 3247c3ff2ebSRafael Espindola Opt.Commands.erase(Iter); 325dfbbbc86SGeorge Rimar --I; 3267c3ff2ebSRafael Espindola continue; 3277c3ff2ebSRafael Espindola } 3287c3ff2ebSRafael Espindola 3297c3ff2ebSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands) 3307c3ff2ebSRafael Espindola if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) 3317c3ff2ebSRafael Espindola if (shouldDefine<ELFT>(OutCmd)) 3327c3ff2ebSRafael Espindola addSymbol<ELFT>(OutCmd); 3337c3ff2ebSRafael Espindola 33497403d15SEugene Leviant if (V.empty()) 3350b9ce6a4SRui Ueyama continue; 3360b9ce6a4SRui Ueyama 337a14b13d8SGeorge Rimar for (InputSectionBase<ELFT> *Sec : V) { 33820d03194SEugene Leviant addSection(Factory, Sec, Cmd->Name); 33920d03194SEugene Leviant if (uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0) 340db24d9c3SGeorge Rimar Sec->Alignment = Subalign; 34120d03194SEugene Leviant } 342eea3114fSGeorge Rimar } 34348c3f1ceSRui Ueyama } 344db24d9c3SGeorge Rimar } 345e63d81bdSEugene Leviant 34620d03194SEugene Leviant template <class ELFT> 34720d03194SEugene Leviant void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 34820d03194SEugene Leviant processCommands(Factory); 3490b9ce6a4SRui Ueyama // Add orphan sections. 35020d03194SEugene Leviant for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) 35120d03194SEugene Leviant for (InputSectionBase<ELFT> *S : F->getSections()) 35220d03194SEugene Leviant if (!isDiscarded(S) && !S->OutSec) 35305384080SRui Ueyama addSection(Factory, S, getOutputSectionName(S->Name, Opt.Alloc)); 354e63d81bdSEugene Leviant } 355e63d81bdSEugene Leviant 356db741e72SEugene Leviant // Sets value of a section-defined symbol. Two kinds of 357db741e72SEugene Leviant // symbols are processed: synthetic symbols, whose value 358db741e72SEugene Leviant // is an offset from beginning of section and regular 359db741e72SEugene Leviant // symbols whose value is absolute. 360db741e72SEugene Leviant template <class ELFT> 361db741e72SEugene Leviant static void assignSectionSymbol(SymbolAssignment *Cmd, 362db741e72SEugene Leviant OutputSectionBase<ELFT> *Sec, 363db741e72SEugene Leviant typename ELFT::uint Off) { 364db741e72SEugene Leviant if (!Cmd->Sym) 365db741e72SEugene Leviant return; 366db741e72SEugene Leviant 367db741e72SEugene Leviant if (auto *Body = dyn_cast<DefinedSynthetic<ELFT>>(Cmd->Sym)) { 368db741e72SEugene Leviant Body->Section = Sec; 369db741e72SEugene Leviant Body->Value = Cmd->Expression(Sec->getVA() + Off) - Sec->getVA(); 370db741e72SEugene Leviant return; 371db741e72SEugene Leviant } 372db741e72SEugene Leviant auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym); 373db741e72SEugene Leviant Body->Value = Cmd->Expression(Sec->getVA() + Off); 374db741e72SEugene Leviant } 375db741e72SEugene Leviant 376a940e539SRafael Espindola template <class ELFT> static bool isTbss(OutputSectionBase<ELFT> *Sec) { 377a940e539SRafael Espindola return (Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS; 378a940e539SRafael Espindola } 379a940e539SRafael Espindola 380d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) { 381d3190795SRafael Espindola if (!AlreadyOutputIS.insert(S).second) 382ceabe80eSEugene Leviant return; 383a940e539SRafael Espindola bool IsTbss = isTbss(CurOutSec); 384d3190795SRafael Espindola 385d3190795SRafael Espindola uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot; 386d3190795SRafael Espindola Pos = alignTo(Pos, S->Alignment); 387d3190795SRafael Espindola S->OutSecOff = Pos - CurOutSec->getVA(); 388d3190795SRafael Espindola Pos += S->getSize(); 389d3190795SRafael Espindola 390d3190795SRafael Espindola // Update output section size after adding each section. This is so that 391d3190795SRafael Espindola // SIZEOF works correctly in the case below: 392d3190795SRafael Espindola // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 393d3190795SRafael Espindola CurOutSec->setSize(Pos - CurOutSec->getVA()); 394d3190795SRafael Espindola 3957252ae52SRafael Espindola if (IsTbss) 3967252ae52SRafael Espindola ThreadBssOffset = Pos - Dot; 3977252ae52SRafael Espindola else 398d3190795SRafael Espindola Dot = Pos; 3992de509c3SRui Ueyama } 400ceabe80eSEugene Leviant 401d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::flush() { 40265499b90SRafael Espindola if (!CurOutSec || !AlreadyOutputOS.insert(CurOutSec).second) 40365499b90SRafael Espindola return; 40465499b90SRafael Espindola if (auto *OutSec = dyn_cast<OutputSection<ELFT>>(CurOutSec)) { 405d3190795SRafael Espindola for (InputSection<ELFT> *I : OutSec->Sections) 406d3190795SRafael Espindola output(I); 40765499b90SRafael Espindola } else { 40865499b90SRafael Espindola Dot += CurOutSec->getSize(); 409d3190795SRafael Espindola } 410d3190795SRafael Espindola } 41197403d15SEugene Leviant 412d3190795SRafael Espindola template <class ELFT> 413d3190795SRafael Espindola void LinkerScript<ELFT>::switchTo(OutputSectionBase<ELFT> *Sec) { 414d3190795SRafael Espindola if (CurOutSec == Sec) 415d3190795SRafael Espindola return; 416d3190795SRafael Espindola if (AlreadyOutputOS.count(Sec)) 417d3190795SRafael Espindola return; 418d3190795SRafael Espindola 419d3190795SRafael Espindola flush(); 420d3190795SRafael Espindola CurOutSec = Sec; 421d3190795SRafael Espindola 422d3190795SRafael Espindola Dot = alignTo(Dot, CurOutSec->getAlignment()); 423a940e539SRafael Espindola CurOutSec->setVA(isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot); 424b71d6f7aSEugene Leviant 425b71d6f7aSEugene Leviant // If neither AT nor AT> is specified for an allocatable section, the linker 426b71d6f7aSEugene Leviant // will set the LMA such that the difference between VMA and LMA for the 427b71d6f7aSEugene Leviant // section is the same as the preceding output section in the same region 428b71d6f7aSEugene Leviant // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html 429b71d6f7aSEugene Leviant CurOutSec->setLMAOffset(LMAOffset); 430d3190795SRafael Espindola } 431d3190795SRafael Espindola 432d3190795SRafael Espindola template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) { 433e38cbab5SGeorge Rimar // This handles the assignments to symbol or to a location counter (.) 434d3190795SRafael Espindola if (auto *AssignCmd = dyn_cast<SymbolAssignment>(&Base)) { 43597403d15SEugene Leviant if (AssignCmd->Name == ".") { 43697403d15SEugene Leviant // Update to location counter means update to section size. 437d3190795SRafael Espindola Dot = AssignCmd->Expression(Dot); 438d3190795SRafael Espindola CurOutSec->setSize(Dot - CurOutSec->getVA()); 439d3190795SRafael Espindola return; 44097403d15SEugene Leviant } 441d3190795SRafael Espindola assignSectionSymbol<ELFT>(AssignCmd, CurOutSec, Dot - CurOutSec->getVA()); 442d3190795SRafael Espindola return; 44397403d15SEugene Leviant } 444e38cbab5SGeorge Rimar 445e38cbab5SGeorge Rimar // Handle BYTE(), SHORT(), LONG(), or QUAD(). 446e38cbab5SGeorge Rimar if (auto *DataCmd = dyn_cast<BytesDataCommand>(&Base)) { 447e38cbab5SGeorge Rimar DataCmd->Offset = Dot - CurOutSec->getVA(); 448e38cbab5SGeorge Rimar Dot += DataCmd->Size; 449e38cbab5SGeorge Rimar CurOutSec->setSize(Dot - CurOutSec->getVA()); 450e38cbab5SGeorge Rimar return; 451e38cbab5SGeorge Rimar } 452e38cbab5SGeorge Rimar 453e38cbab5SGeorge Rimar // It handles single input section description command, 454e38cbab5SGeorge Rimar // calculates and assigns the offsets for each section and also 455e38cbab5SGeorge Rimar // updates the output section size. 456d3190795SRafael Espindola auto &ICmd = cast<InputSectionDescription>(Base); 457d3190795SRafael Espindola for (InputSectionData *ID : ICmd.Sections) { 458d3190795SRafael Espindola auto *IB = static_cast<InputSectionBase<ELFT> *>(ID); 459d3190795SRafael Espindola switchTo(IB->OutSec); 460d3190795SRafael Espindola if (auto *I = dyn_cast<InputSection<ELFT>>(IB)) 461d3190795SRafael Espindola output(I); 46265499b90SRafael Espindola else 46365499b90SRafael Espindola flush(); 464ceabe80eSEugene Leviant } 465ceabe80eSEugene Leviant } 466ceabe80eSEugene Leviant 4678f66df92SGeorge Rimar template <class ELFT> 468a14b13d8SGeorge Rimar static std::vector<OutputSectionBase<ELFT> *> 4699257764dSEugene Leviant findSections(StringRef Name, 470d3190795SRafael Espindola const std::vector<OutputSectionBase<ELFT> *> &Sections) { 471a14b13d8SGeorge Rimar std::vector<OutputSectionBase<ELFT> *> Ret; 472a14b13d8SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : Sections) 4739257764dSEugene Leviant if (Sec->getName() == Name) 474a14b13d8SGeorge Rimar Ret.push_back(Sec); 475a14b13d8SGeorge Rimar return Ret; 4768f66df92SGeorge Rimar } 4778f66df92SGeorge Rimar 478d3190795SRafael Espindola template <class ELFT> 479d3190795SRafael Espindola void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) { 480b71d6f7aSEugene Leviant if (Cmd->LMAExpr) 481b71d6f7aSEugene Leviant LMAOffset = Cmd->LMAExpr(Dot) - Dot; 482d3190795SRafael Espindola std::vector<OutputSectionBase<ELFT> *> Sections = 4839257764dSEugene Leviant findSections(Cmd->Name, *OutputSections); 484d3190795SRafael Espindola if (Sections.empty()) 485d3190795SRafael Espindola return; 486d3190795SRafael Espindola switchTo(Sections[0]); 487d3190795SRafael Espindola // Find the last section output location. We will output orphan sections 488d3190795SRafael Espindola // there so that end symbols point to the correct location. 489d3190795SRafael Espindola auto E = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(), 490d3190795SRafael Espindola [](const std::unique_ptr<BaseCommand> &Cmd) { 491d3190795SRafael Espindola return !isa<SymbolAssignment>(*Cmd); 492d3190795SRafael Espindola }) 493d3190795SRafael Espindola .base(); 494d3190795SRafael Espindola for (auto I = Cmd->Commands.begin(); I != E; ++I) 495d3190795SRafael Espindola process(**I); 49665499b90SRafael Espindola for (OutputSectionBase<ELFT> *Base : Sections) 497d3190795SRafael Espindola switchTo(Base); 4982506cb4dSEugene Leviant flush(); 499b31dd370SGeorge Rimar std::for_each(E, Cmd->Commands.end(), 500b31dd370SGeorge Rimar [this](std::unique_ptr<BaseCommand> &B) { process(*B.get()); }); 501d3190795SRafael Espindola } 502d3190795SRafael Espindola 5039546fffbSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() { 5046d38e4dbSRafael Espindola // It is common practice to use very generic linker scripts. So for any 5056d38e4dbSRafael Espindola // given run some of the output sections in the script will be empty. 5066d38e4dbSRafael Espindola // We could create corresponding empty output sections, but that would 5076d38e4dbSRafael Espindola // clutter the output. 5086d38e4dbSRafael Espindola // We instead remove trivially empty sections. The bfd linker seems even 5096d38e4dbSRafael Espindola // more aggressive at removing them. 5106d38e4dbSRafael Espindola auto Pos = std::remove_if( 5116d38e4dbSRafael Espindola Opt.Commands.begin(), Opt.Commands.end(), 5126d38e4dbSRafael Espindola [&](const std::unique_ptr<BaseCommand> &Base) { 5136d38e4dbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 5146d38e4dbSRafael Espindola if (!Cmd) 5156d38e4dbSRafael Espindola return false; 5166d38e4dbSRafael Espindola std::vector<OutputSectionBase<ELFT> *> Secs = 5179257764dSEugene Leviant findSections(Cmd->Name, *OutputSections); 5186d38e4dbSRafael Espindola if (!Secs.empty()) 5196d38e4dbSRafael Espindola return false; 5206d38e4dbSRafael Espindola for (const std::unique_ptr<BaseCommand> &I : Cmd->Commands) 5216d38e4dbSRafael Espindola if (!isa<InputSectionDescription>(I.get())) 5226d38e4dbSRafael Espindola return false; 5236d38e4dbSRafael Espindola return true; 5246d38e4dbSRafael Espindola }); 5256d38e4dbSRafael Espindola Opt.Commands.erase(Pos, Opt.Commands.end()); 5266d38e4dbSRafael Espindola 5279546fffbSRafael Espindola // If the output section contains only symbol assignments, create a 5289546fffbSRafael Espindola // corresponding output section. The bfd linker seems to only create them if 5299546fffbSRafael Espindola // '.' is assigned to, but creating these section should not have any bad 5309546fffbSRafael Espindola // consequeces and gives us a section to put the symbol in. 5319546fffbSRafael Espindola uintX_t Flags = SHF_ALLOC; 5329546fffbSRafael Espindola uint32_t Type = 0; 5339546fffbSRafael Espindola for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 5349546fffbSRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 5359546fffbSRafael Espindola if (!Cmd) 5369546fffbSRafael Espindola continue; 5379546fffbSRafael Espindola std::vector<OutputSectionBase<ELFT> *> Secs = 5389257764dSEugene Leviant findSections(Cmd->Name, *OutputSections); 5399546fffbSRafael Espindola if (!Secs.empty()) { 5409546fffbSRafael Espindola Flags = Secs[0]->getFlags(); 5419546fffbSRafael Espindola Type = Secs[0]->getType(); 5429546fffbSRafael Espindola continue; 5439546fffbSRafael Espindola } 5449546fffbSRafael Espindola 5459546fffbSRafael Espindola auto *OutSec = new OutputSection<ELFT>(Cmd->Name, Type, Flags); 5469546fffbSRafael Espindola Out<ELFT>::Pool.emplace_back(OutSec); 5479546fffbSRafael Espindola OutputSections->push_back(OutSec); 5489546fffbSRafael Espindola } 5499546fffbSRafael Espindola } 5509546fffbSRafael Espindola 55115c57951SRafael Espindola // When placing orphan sections, we want to place them after symbol assignments 55215c57951SRafael Espindola // so that an orphan after 55315c57951SRafael Espindola // begin_foo = .; 55415c57951SRafael Espindola // foo : { *(foo) } 55515c57951SRafael Espindola // end_foo = .; 55615c57951SRafael Espindola // doesn't break the intended meaning of the begin/end symbols. 55715c57951SRafael Espindola // We don't want to go over sections since Writer<ELFT>::sortSections is the 55815c57951SRafael Espindola // one in charge of deciding the order of the sections. 55915c57951SRafael Espindola // We don't want to go over alignments, since doing so in 56015c57951SRafael Espindola // rx_sec : { *(rx_sec) } 56115c57951SRafael Espindola // . = ALIGN(0x1000); 56215c57951SRafael Espindola // /* The RW PT_LOAD starts here*/ 56315c57951SRafael Espindola // rw_sec : { *(rw_sec) } 56415c57951SRafael Espindola // would mean that the RW PT_LOAD would become unaligned. 56515c57951SRafael Espindola static bool shouldSkip(const BaseCommand &Cmd) { 56615c57951SRafael Espindola if (isa<OutputSectionCommand>(Cmd)) 56715c57951SRafael Espindola return false; 56815c57951SRafael Espindola const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd); 56915c57951SRafael Espindola if (!Assign) 57015c57951SRafael Espindola return true; 57115c57951SRafael Espindola return Assign->Name != "."; 57215c57951SRafael Espindola } 57315c57951SRafael Espindola 5746d91fce5SRafael Espindola template <class ELFT> 5756d91fce5SRafael Espindola void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs) { 576652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 5777c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 5787c18c28cSRui Ueyama // We place orphan sections at end of file. 5797c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 580652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 581aab6d5c5SRafael Espindola 582aab6d5c5SRafael Espindola // The OutputSections are already in the correct order. 583aab6d5c5SRafael Espindola // This loops creates or moves commands as needed so that they are in the 584aab6d5c5SRafael Espindola // correct order. 585aab6d5c5SRafael Espindola int CmdIndex = 0; 586e5cc668eSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 587652852c5SGeorge Rimar StringRef Name = Sec->getName(); 588aab6d5c5SRafael Espindola 589aab6d5c5SRafael Espindola // Find the last spot where we can insert a command and still get the 59015c57951SRafael Espindola // correct result. 591aab6d5c5SRafael Espindola auto CmdIter = Opt.Commands.begin() + CmdIndex; 592aab6d5c5SRafael Espindola auto E = Opt.Commands.end(); 59315c57951SRafael Espindola while (CmdIter != E && shouldSkip(**CmdIter)) { 594aab6d5c5SRafael Espindola ++CmdIter; 595aab6d5c5SRafael Espindola ++CmdIndex; 596aab6d5c5SRafael Espindola } 597aab6d5c5SRafael Espindola 598aab6d5c5SRafael Espindola auto Pos = 599aab6d5c5SRafael Espindola std::find_if(CmdIter, E, [&](const std::unique_ptr<BaseCommand> &Base) { 600aab6d5c5SRafael Espindola auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 601aab6d5c5SRafael Espindola return Cmd && Cmd->Name == Name; 602aab6d5c5SRafael Espindola }); 603aab6d5c5SRafael Espindola if (Pos == E) { 604aab6d5c5SRafael Espindola Opt.Commands.insert(CmdIter, 605aab6d5c5SRafael Espindola llvm::make_unique<OutputSectionCommand>(Name)); 606aab6d5c5SRafael Espindola ++CmdIndex; 60715c57951SRafael Espindola continue; 60815c57951SRafael Espindola } 60915c57951SRafael Espindola 61015c57951SRafael Espindola // Continue from where we found it. 61115c57951SRafael Espindola CmdIndex = (Pos - Opt.Commands.begin()) + 1; 61215c57951SRafael Espindola continue; 613652852c5SGeorge Rimar } 614652852c5SGeorge Rimar 6157c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 616be607334SRafael Espindola Dot = 0; 617652852c5SGeorge Rimar 618076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 619076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 6208d083e6aSRui Ueyama if (Cmd->Name == ".") { 6218d083e6aSRui Ueyama Dot = Cmd->Expression(Dot); 6228d083e6aSRui Ueyama } else if (Cmd->Sym) { 6238d083e6aSRui Ueyama cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot); 6248d083e6aSRui Ueyama } 62505ef4cffSRui Ueyama continue; 626652852c5SGeorge Rimar } 627652852c5SGeorge Rimar 628eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 629eefa758eSGeorge Rimar Cmd->Expression(Dot); 630eefa758eSGeorge Rimar continue; 631eefa758eSGeorge Rimar } 632eefa758eSGeorge Rimar 633076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 634652852c5SGeorge Rimar 63558e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 63658e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 63758e5c4dcSGeorge Rimar 638d3190795SRafael Espindola assignOffsets(Cmd); 639a14b13d8SGeorge Rimar } 640467c4d55SEugene Leviant 641aab6d5c5SRafael Espindola uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 642aab6d5c5SRafael Espindola for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 643aab6d5c5SRafael Espindola if (Sec->getFlags() & SHF_ALLOC) 644aab6d5c5SRafael Espindola MinVA = std::min(MinVA, Sec->getVA()); 645aab6d5c5SRafael Espindola else 646d3190795SRafael Espindola Sec->setVA(0); 647aab6d5c5SRafael Espindola } 648aab6d5c5SRafael Espindola 6490d4b6d5cSRafael Espindola uintX_t HeaderSize = getHeaderSize(); 6506d91fce5SRafael Espindola auto FirstPTLoad = 6516d91fce5SRafael Espindola std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry<ELFT> &E) { 6526d91fce5SRafael Espindola return E.H.p_type == PT_LOAD; 6536d91fce5SRafael Espindola }); 654db35fdf7SEugene Leviant 6556d91fce5SRafael Espindola if (HeaderSize <= MinVA && FirstPTLoad != Phdrs.end()) { 656db35fdf7SEugene Leviant // If linker script specifies program headers and first PT_LOAD doesn't 657db35fdf7SEugene Leviant // have both PHDRS and FILEHDR attributes then do nothing 658db35fdf7SEugene Leviant if (!Opt.PhdrsCommands.empty()) { 659db35fdf7SEugene Leviant size_t SegNum = std::distance(Phdrs.begin(), FirstPTLoad); 660db35fdf7SEugene Leviant if (!Opt.PhdrsCommands[SegNum].HasPhdrs || 661db35fdf7SEugene Leviant !Opt.PhdrsCommands[SegNum].HasFilehdr) 662db35fdf7SEugene Leviant return; 663db35fdf7SEugene Leviant } 66464c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 665b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 6664ec013acSRafael Espindola MinVA = alignDown(MinVA - HeaderSize, Target->PageSize); 667467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 668467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 6696d91fce5SRafael Espindola FirstPTLoad->First = Out<ELFT>::ElfHeader; 6706d91fce5SRafael Espindola if (!FirstPTLoad->Last) 6716d91fce5SRafael Espindola FirstPTLoad->Last = Out<ELFT>::ProgramHeaders; 672cd8eaf89SEugene Leviant } else if (!FirstPTLoad->First) { 673cd8eaf89SEugene Leviant // Sometimes the very first PT_LOAD segment can be empty. 674cd8eaf89SEugene Leviant // This happens if (all conditions met): 675cd8eaf89SEugene Leviant // - Linker script is used 676cd8eaf89SEugene Leviant // - First section in ELF image is not RO 677cd8eaf89SEugene Leviant // - Not enough space for program headers. 678cd8eaf89SEugene Leviant // The code below removes empty PT_LOAD segment and updates 679cd8eaf89SEugene Leviant // program headers size. 680cd8eaf89SEugene Leviant Phdrs.erase(FirstPTLoad); 681cd8eaf89SEugene Leviant Out<ELFT>::ProgramHeaders->setSize(sizeof(typename ELFT::Phdr) * 682cd8eaf89SEugene Leviant Phdrs.size()); 6836d91fce5SRafael Espindola } 684fb8978fcSDima Stepanov } 685652852c5SGeorge Rimar 686464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 68707320e40SRui Ueyama template <class ELFT> 688a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { 689edebbdf1SRui Ueyama std::vector<PhdrEntry<ELFT>> Ret; 690bbe38602SEugene Leviant 691464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 692464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 693ce30b1c7SEugene Leviant std::vector<size_t> DefPhdrIds; 694bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 695edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 696edebbdf1SRui Ueyama PhdrEntry<ELFT> &Phdr = Ret.back(); 697bbe38602SEugene Leviant 698bbe38602SEugene Leviant if (Cmd.HasFilehdr) 699adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 700bbe38602SEugene Leviant if (Cmd.HasPhdrs) 701adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 70256b21c86SEugene Leviant 70356b21c86SEugene Leviant if (Cmd.LMAExpr) { 70456b21c86SEugene Leviant Phdr.H.p_paddr = Cmd.LMAExpr(0); 70556b21c86SEugene Leviant Phdr.HasLMA = true; 70656b21c86SEugene Leviant } 707ce30b1c7SEugene Leviant 708ce30b1c7SEugene Leviant // If output section command doesn't specify any segments, 709ce30b1c7SEugene Leviant // and we haven't previously assigned any section to segment, 710ce30b1c7SEugene Leviant // then we simply assign section to the very first load segment. 711ce30b1c7SEugene Leviant // Below is an example of such linker script: 712ce30b1c7SEugene Leviant // PHDRS { seg PT_LOAD; } 713ce30b1c7SEugene Leviant // SECTIONS { .aaa : { *(.aaa) } } 714ce30b1c7SEugene Leviant if (DefPhdrIds.empty() && Phdr.H.p_type == PT_LOAD) 715ce30b1c7SEugene Leviant DefPhdrIds.push_back(Ret.size() - 1); 716bbe38602SEugene Leviant } 717bbe38602SEugene Leviant 718464daadcSRui Ueyama // Add output sections to program headers. 719464daadcSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 720bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 721bbe38602SEugene Leviant break; 722bbe38602SEugene Leviant 723edebbdf1SRui Ueyama std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName()); 724ce30b1c7SEugene Leviant if (PhdrIds.empty()) 725ce30b1c7SEugene Leviant PhdrIds = std::move(DefPhdrIds); 726ce30b1c7SEugene Leviant 727bbe38602SEugene Leviant // Assign headers specified by linker script 728bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 729edebbdf1SRui Ueyama Ret[Id].add(Sec); 730865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 7310b113671SRafael Espindola Ret[Id].H.p_flags |= Sec->getPhdrFlags(); 732bbe38602SEugene Leviant } 733ce30b1c7SEugene Leviant DefPhdrIds = std::move(PhdrIds); 734bbe38602SEugene Leviant } 735edebbdf1SRui Ueyama return Ret; 736bbe38602SEugene Leviant } 737bbe38602SEugene Leviant 738f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 739f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 740f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 741f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 742f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 743f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 744f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 745f9bc3bd2SEugene Leviant } 746f9bc3bd2SEugene Leviant 747bbe38602SEugene Leviant template <class ELFT> 74807320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 749f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 750f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 751f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 752f6c3ccefSGeorge Rimar return Cmd->Filler; 753e2ee72b5SGeorge Rimar return {}; 754e2ee72b5SGeorge Rimar } 755e2ee72b5SGeorge Rimar 756e38cbab5SGeorge Rimar template <class ELFT> 757e38cbab5SGeorge Rimar static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { 758e38cbab5SGeorge Rimar const endianness E = ELFT::TargetEndianness; 759e38cbab5SGeorge Rimar 760e38cbab5SGeorge Rimar switch (Size) { 761e38cbab5SGeorge Rimar case 1: 762e38cbab5SGeorge Rimar *Buf = (uint8_t)Data; 763e38cbab5SGeorge Rimar break; 764e38cbab5SGeorge Rimar case 2: 765e38cbab5SGeorge Rimar write16<E>(Buf, Data); 766e38cbab5SGeorge Rimar break; 767e38cbab5SGeorge Rimar case 4: 768e38cbab5SGeorge Rimar write32<E>(Buf, Data); 769e38cbab5SGeorge Rimar break; 770e38cbab5SGeorge Rimar case 8: 771e38cbab5SGeorge Rimar write64<E>(Buf, Data); 772e38cbab5SGeorge Rimar break; 773e38cbab5SGeorge Rimar default: 774e38cbab5SGeorge Rimar llvm_unreachable("unsupported Size argument"); 775e38cbab5SGeorge Rimar } 776e38cbab5SGeorge Rimar } 777e38cbab5SGeorge Rimar 778e38cbab5SGeorge Rimar template <class ELFT> 779e38cbab5SGeorge Rimar void LinkerScript<ELFT>::writeDataBytes(StringRef Name, uint8_t *Buf) { 780e38cbab5SGeorge Rimar int I = getSectionIndex(Name); 781e38cbab5SGeorge Rimar if (I == INT_MAX) 782e38cbab5SGeorge Rimar return; 783e38cbab5SGeorge Rimar 784e38cbab5SGeorge Rimar OutputSectionCommand *Cmd = 785e38cbab5SGeorge Rimar dyn_cast<OutputSectionCommand>(Opt.Commands[I].get()); 786e38cbab5SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base2 : Cmd->Commands) 787e38cbab5SGeorge Rimar if (auto *DataCmd = dyn_cast<BytesDataCommand>(Base2.get())) 788e38cbab5SGeorge Rimar writeInt<ELFT>(&Buf[DataCmd->Offset], DataCmd->Data, DataCmd->Size); 789e38cbab5SGeorge Rimar } 790e38cbab5SGeorge Rimar 791b71d6f7aSEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasLMA(StringRef Name) { 7928ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 7938ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 794b71d6f7aSEugene Leviant if (Cmd->LMAExpr && Cmd->Name == Name) 795b71d6f7aSEugene Leviant return true; 796b71d6f7aSEugene Leviant return false; 7978ceadb38SGeorge Rimar } 7988ceadb38SGeorge Rimar 799c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 800c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 801c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 802c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 803076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 804f510fa6bSRui Ueyama int I = 0; 805f510fa6bSRui Ueyama for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 806076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 807076fe157SGeorge Rimar if (Cmd->Name == Name) 808f510fa6bSRui Ueyama return I; 809f510fa6bSRui Ueyama ++I; 810f510fa6bSRui Ueyama } 811f510fa6bSRui Ueyama return INT_MAX; 81271b26e94SGeorge Rimar } 81371b26e94SGeorge Rimar 814bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 815bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 816bbe38602SEugene Leviant } 817bbe38602SEugene Leviant 8189e69450eSGeorge Rimar template <class ELFT> 819884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) { 82096659df0SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 82196659df0SGeorge Rimar if (Sec->getName() == Name) 82296659df0SGeorge Rimar return Sec->getVA(); 82396659df0SGeorge Rimar error("undefined section " + Name); 82496659df0SGeorge Rimar return 0; 82596659df0SGeorge Rimar } 82696659df0SGeorge Rimar 82796659df0SGeorge Rimar template <class ELFT> 828b71d6f7aSEugene Leviant uint64_t LinkerScript<ELFT>::getOutputSectionLMA(StringRef Name) { 829b71d6f7aSEugene Leviant for (OutputSectionBase<ELFT> *Sec : *OutputSections) 830b71d6f7aSEugene Leviant if (Sec->getName() == Name) 831b71d6f7aSEugene Leviant return Sec->getLMA(); 832b71d6f7aSEugene Leviant error("undefined section " + Name); 833b71d6f7aSEugene Leviant return 0; 834b71d6f7aSEugene Leviant } 835b71d6f7aSEugene Leviant 836b71d6f7aSEugene Leviant template <class ELFT> 837884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 8389e69450eSGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 8399e69450eSGeorge Rimar if (Sec->getName() == Name) 8409e69450eSGeorge Rimar return Sec->getSize(); 8419e69450eSGeorge Rimar error("undefined section " + Name); 8429e69450eSGeorge Rimar return 0; 8439e69450eSGeorge Rimar } 8449e69450eSGeorge Rimar 84536fac7f0SEugene Leviant template <class ELFT> 84636fac7f0SEugene Leviant uint64_t LinkerScript<ELFT>::getOutputSectionAlign(StringRef Name) { 84736fac7f0SEugene Leviant for (OutputSectionBase<ELFT> *Sec : *OutputSections) 84836fac7f0SEugene Leviant if (Sec->getName() == Name) 84936fac7f0SEugene Leviant return Sec->getAlignment(); 85036fac7f0SEugene Leviant error("undefined section " + Name); 85136fac7f0SEugene Leviant return 0; 85236fac7f0SEugene Leviant } 85336fac7f0SEugene Leviant 854884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() { 8550d4b6d5cSRafael Espindola return elf::getHeaderSize<ELFT>(); 856e32a3598SGeorge Rimar } 857e32a3598SGeorge Rimar 858884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) { 859884e786dSGeorge Rimar if (SymbolBody *B = Symtab<ELFT>::X->find(S)) 860884e786dSGeorge Rimar return B->getVA<ELFT>(); 861884e786dSGeorge Rimar error("symbol not found: " + S); 862884e786dSGeorge Rimar return 0; 863884e786dSGeorge Rimar } 864884e786dSGeorge Rimar 865f34f45fdSGeorge Rimar template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) { 866f34f45fdSGeorge Rimar return Symtab<ELFT>::X->find(S) != nullptr; 867f34f45fdSGeorge Rimar } 868f34f45fdSGeorge Rimar 869bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 870bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 871bbe38602SEugene Leviant // PHDRS {} script block. 872bbe38602SEugene Leviant template <class ELFT> 873edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 874076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 875076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 876edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 87731d842f5SGeorge Rimar continue; 87831d842f5SGeorge Rimar 87929c5a2a9SRui Ueyama std::vector<size_t> Ret; 88029c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 88129c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 88229c5a2a9SRui Ueyama return Ret; 883bbe38602SEugene Leviant } 88431d842f5SGeorge Rimar return {}; 88531d842f5SGeorge Rimar } 886bbe38602SEugene Leviant 88729c5a2a9SRui Ueyama template <class ELFT> 88829c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 88929c5a2a9SRui Ueyama size_t I = 0; 89029c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 89129c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 89229c5a2a9SRui Ueyama return I; 89329c5a2a9SRui Ueyama ++I; 89429c5a2a9SRui Ueyama } 89529c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 89629c5a2a9SRui Ueyama return 0; 89729c5a2a9SRui Ueyama } 89829c5a2a9SRui Ueyama 89907320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 900c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 901c3794e58SGeorge Rimar 902f7c5fbb1SRui Ueyama public: 90307320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 904f23b2320SGeorge Rimar 90520b6598cSGeorge Rimar void readLinkerScript(); 90620b6598cSGeorge Rimar void readVersionScript(); 907f7c5fbb1SRui Ueyama 908f7c5fbb1SRui Ueyama private: 90952a1509eSRui Ueyama void addFile(StringRef Path); 91052a1509eSRui Ueyama 911f7c5fbb1SRui Ueyama void readAsNeeded(); 91290c5099eSDenis Protivensky void readEntry(); 91383f406cfSGeorge Rimar void readExtern(); 914f7c5fbb1SRui Ueyama void readGroup(); 91531aa1f83SRui Ueyama void readInclude(); 916ee59282bSRui Ueyama void readOutput(); 9179159ce93SDavide Italiano void readOutputArch(); 918f7c5fbb1SRui Ueyama void readOutputFormat(); 919bbe38602SEugene Leviant void readPhdrs(); 92068a39a65SDavide Italiano void readSearchDir(); 9218e3b38abSDenis Protivensky void readSections(); 92295769b4aSRui Ueyama void readVersion(); 92395769b4aSRui Ueyama void readVersionScriptCommand(); 9248e3b38abSDenis Protivensky 925113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 926e38cbab5SGeorge Rimar BytesDataCommand *readBytesDataCommand(StringRef Tok); 927ff1f29e0SGeorge Rimar std::vector<uint8_t> readFill(); 92810416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 929ff1f29e0SGeorge Rimar std::vector<uint8_t> readOutputSectionFiller(StringRef Tok); 930bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 931a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 932c91930a1SGeorge Rimar Regex readFilePatterns(); 93307171f21SGeorge Rimar std::vector<SectionPattern> readInputSectionsList(); 934a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 935bbe38602SEugene Leviant unsigned readPhdrType(); 936be394db3SGeorge Rimar SortSectionPolicy readSortKind(); 937a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 938db741e72SEugene Leviant SymbolAssignment *readProvideOrAssignment(StringRef Tok, bool MakeAbsolute); 93903fc010eSGeorge Rimar void readSort(); 940eefa758eSGeorge Rimar Expr readAssert(); 941708019c4SRui Ueyama 942708019c4SRui Ueyama Expr readExpr(); 943708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 944b71d6f7aSEugene Leviant StringRef readParenLiteral(); 945708019c4SRui Ueyama Expr readPrimary(); 946708019c4SRui Ueyama Expr readTernary(Expr Cond); 9476ad7dfccSRui Ueyama Expr readParenExpr(); 948f7c5fbb1SRui Ueyama 94920b6598cSGeorge Rimar // For parsing version script. 95020b6598cSGeorge Rimar void readExtern(std::vector<SymbolVersion> *Globals); 95195769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 95220b6598cSGeorge Rimar void readGlobal(StringRef VerStr); 95320b6598cSGeorge Rimar void readLocal(); 95420b6598cSGeorge Rimar 95507320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 95607320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 95716b0cc9eSSimon Atanasyan bool IsUnderSysroot; 958f7c5fbb1SRui Ueyama }; 959f7c5fbb1SRui Ueyama 96020b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 96195769b4aSRui Ueyama readVersionScriptCommand(); 96220b6598cSGeorge Rimar if (!atEOF()) 96395769b4aSRui Ueyama setError("EOF expected, but got " + next()); 96495769b4aSRui Ueyama } 96595769b4aSRui Ueyama 96695769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 96783043f23SRui Ueyama if (consume("{")) { 96895769b4aSRui Ueyama readVersionDeclaration(""); 96920b6598cSGeorge Rimar return; 97020b6598cSGeorge Rimar } 97120b6598cSGeorge Rimar 97295769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 97320b6598cSGeorge Rimar StringRef VerStr = next(); 97420b6598cSGeorge Rimar if (VerStr == "{") { 97595769b4aSRui Ueyama setError("anonymous version definition is used in " 97695769b4aSRui Ueyama "combination with other version definitions"); 97720b6598cSGeorge Rimar return; 97820b6598cSGeorge Rimar } 97920b6598cSGeorge Rimar expect("{"); 98095769b4aSRui Ueyama readVersionDeclaration(VerStr); 98120b6598cSGeorge Rimar } 98220b6598cSGeorge Rimar } 98320b6598cSGeorge Rimar 98495769b4aSRui Ueyama void ScriptParser::readVersion() { 98595769b4aSRui Ueyama expect("{"); 98695769b4aSRui Ueyama readVersionScriptCommand(); 98795769b4aSRui Ueyama expect("}"); 98895769b4aSRui Ueyama } 98995769b4aSRui Ueyama 99020b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 991f7c5fbb1SRui Ueyama while (!atEOF()) { 992f7c5fbb1SRui Ueyama StringRef Tok = next(); 993a27eeccaSRui Ueyama if (Tok == ";") 994a27eeccaSRui Ueyama continue; 995a27eeccaSRui Ueyama 99620d03194SEugene Leviant if (Tok == "ASSERT") { 99720d03194SEugene Leviant Opt.Commands.emplace_back(new AssertCommand(readAssert())); 99820d03194SEugene Leviant } else if (Tok == "ENTRY") { 999a27eeccaSRui Ueyama readEntry(); 1000a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 1001a27eeccaSRui Ueyama readExtern(); 1002a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 1003a27eeccaSRui Ueyama readGroup(); 1004a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 1005a27eeccaSRui Ueyama readInclude(); 1006a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 1007a27eeccaSRui Ueyama readOutput(); 1008a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 1009a27eeccaSRui Ueyama readOutputArch(); 1010a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 1011a27eeccaSRui Ueyama readOutputFormat(); 1012a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 1013a27eeccaSRui Ueyama readPhdrs(); 1014a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 1015a27eeccaSRui Ueyama readSearchDir(); 1016a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 1017a27eeccaSRui Ueyama readSections(); 1018a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 1019a27eeccaSRui Ueyama readVersion(); 1020db741e72SEugene Leviant } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok, true)) { 10210df80befSPetr Hosek Opt.Commands.emplace_back(Cmd); 1022e5d3ca50SPetr Hosek } else { 10235761042dSGeorge Rimar setError("unknown directive: " + Tok); 1024f7c5fbb1SRui Ueyama } 1025f7c5fbb1SRui Ueyama } 1026e5d3ca50SPetr Hosek } 1027f7c5fbb1SRui Ueyama 1028717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 102916b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 10305af1687fSJustin Bogner SmallString<128> PathData; 10315af1687fSJustin Bogner StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 103216b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 10335af1687fSJustin Bogner Driver->addFile(Saver.save(Path)); 103416b0cc9eSSimon Atanasyan return; 103516b0cc9eSSimon Atanasyan } 103616b0cc9eSSimon Atanasyan } 103716b0cc9eSSimon Atanasyan 1038f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 103952a1509eSRui Ueyama Driver->addFile(S); 104052a1509eSRui Ueyama } else if (S.startswith("=")) { 104152a1509eSRui Ueyama if (Config->Sysroot.empty()) 104252a1509eSRui Ueyama Driver->addFile(S.substr(1)); 104352a1509eSRui Ueyama else 104452a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 104552a1509eSRui Ueyama } else if (S.startswith("-l")) { 104621eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 1047a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 1048a1b8fc3bSSimon Atanasyan Driver->addFile(S); 104952a1509eSRui Ueyama } else { 105052a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 105152a1509eSRui Ueyama if (Path.empty()) 1052777f9630SGeorge Rimar setError("unable to find " + S); 1053025d59b1SRui Ueyama else 105452a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 105552a1509eSRui Ueyama } 105652a1509eSRui Ueyama } 105752a1509eSRui Ueyama 1058717677afSRui Ueyama void ScriptParser::readAsNeeded() { 1059f7c5fbb1SRui Ueyama expect("("); 106035da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 106135da9b6eSRui Ueyama Config->AsNeeded = true; 106283043f23SRui Ueyama while (!Error && !consume(")")) 1063cd574a5eSGeorge Rimar addFile(unquote(next())); 106435da9b6eSRui Ueyama Config->AsNeeded = Orig; 1065f7c5fbb1SRui Ueyama } 1066f7c5fbb1SRui Ueyama 1067717677afSRui Ueyama void ScriptParser::readEntry() { 106890c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 106990c5099eSDenis Protivensky expect("("); 107090c5099eSDenis Protivensky StringRef Tok = next(); 107190c5099eSDenis Protivensky if (Config->Entry.empty()) 107290c5099eSDenis Protivensky Config->Entry = Tok; 107390c5099eSDenis Protivensky expect(")"); 107490c5099eSDenis Protivensky } 107590c5099eSDenis Protivensky 1076717677afSRui Ueyama void ScriptParser::readExtern() { 107783f406cfSGeorge Rimar expect("("); 107883043f23SRui Ueyama while (!Error && !consume(")")) 1079a2acc931SRui Ueyama Config->Undefined.push_back(next()); 108083f406cfSGeorge Rimar } 108183f406cfSGeorge Rimar 1082717677afSRui Ueyama void ScriptParser::readGroup() { 1083f7c5fbb1SRui Ueyama expect("("); 108483043f23SRui Ueyama while (!Error && !consume(")")) { 1085f7c5fbb1SRui Ueyama StringRef Tok = next(); 1086a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 1087f7c5fbb1SRui Ueyama readAsNeeded(); 1088a2acc931SRui Ueyama else 1089cd574a5eSGeorge Rimar addFile(unquote(Tok)); 1090f7c5fbb1SRui Ueyama } 1091f7c5fbb1SRui Ueyama } 1092f7c5fbb1SRui Ueyama 1093717677afSRui Ueyama void ScriptParser::readInclude() { 109431aa1f83SRui Ueyama StringRef Tok = next(); 1095cd574a5eSGeorge Rimar auto MBOrErr = MemoryBuffer::getFile(unquote(Tok)); 1096025d59b1SRui Ueyama if (!MBOrErr) { 10975761042dSGeorge Rimar setError("cannot open " + Tok); 1098025d59b1SRui Ueyama return; 1099025d59b1SRui Ueyama } 110031aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 1101a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 1102a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 110331aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 110431aa1f83SRui Ueyama } 110531aa1f83SRui Ueyama 1106717677afSRui Ueyama void ScriptParser::readOutput() { 1107ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 1108ee59282bSRui Ueyama expect("("); 1109ee59282bSRui Ueyama StringRef Tok = next(); 1110ee59282bSRui Ueyama if (Config->OutputFile.empty()) 1111cd574a5eSGeorge Rimar Config->OutputFile = unquote(Tok); 1112ee59282bSRui Ueyama expect(")"); 1113ee59282bSRui Ueyama } 1114ee59282bSRui Ueyama 1115717677afSRui Ueyama void ScriptParser::readOutputArch() { 11169159ce93SDavide Italiano // Error checking only for now. 11179159ce93SDavide Italiano expect("("); 11185424e7c7SJustin Bogner skip(); 11199159ce93SDavide Italiano expect(")"); 11209159ce93SDavide Italiano } 11219159ce93SDavide Italiano 1122717677afSRui Ueyama void ScriptParser::readOutputFormat() { 1123f7c5fbb1SRui Ueyama // Error checking only for now. 1124f7c5fbb1SRui Ueyama expect("("); 11255424e7c7SJustin Bogner skip(); 11266836c618SDavide Italiano StringRef Tok = next(); 11276836c618SDavide Italiano if (Tok == ")") 11286836c618SDavide Italiano return; 1129025d59b1SRui Ueyama if (Tok != ",") { 11305761042dSGeorge Rimar setError("unexpected token: " + Tok); 1131025d59b1SRui Ueyama return; 1132025d59b1SRui Ueyama } 11335424e7c7SJustin Bogner skip(); 11346836c618SDavide Italiano expect(","); 11355424e7c7SJustin Bogner skip(); 1136f7c5fbb1SRui Ueyama expect(")"); 1137f7c5fbb1SRui Ueyama } 1138f7c5fbb1SRui Ueyama 1139bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 1140bbe38602SEugene Leviant expect("{"); 114183043f23SRui Ueyama while (!Error && !consume("}")) { 1142bbe38602SEugene Leviant StringRef Tok = next(); 114356b21c86SEugene Leviant Opt.PhdrsCommands.push_back( 114456b21c86SEugene Leviant {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 1145bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 1146bbe38602SEugene Leviant 1147bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 1148bbe38602SEugene Leviant do { 1149bbe38602SEugene Leviant Tok = next(); 1150bbe38602SEugene Leviant if (Tok == ";") 1151bbe38602SEugene Leviant break; 1152bbe38602SEugene Leviant if (Tok == "FILEHDR") 1153bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 1154bbe38602SEugene Leviant else if (Tok == "PHDRS") 1155bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 115656b21c86SEugene Leviant else if (Tok == "AT") 115756b21c86SEugene Leviant PhdrCmd.LMAExpr = readParenExpr(); 1158865bf863SEugene Leviant else if (Tok == "FLAGS") { 1159865bf863SEugene Leviant expect("("); 1160eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 1161eb685cd7SRafael Espindola // we accept expressions like ".|1". 1162eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 1163865bf863SEugene Leviant expect(")"); 1164865bf863SEugene Leviant } else 1165bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 1166bbe38602SEugene Leviant } while (!Error); 1167bbe38602SEugene Leviant } 1168bbe38602SEugene Leviant } 1169bbe38602SEugene Leviant 1170717677afSRui Ueyama void ScriptParser::readSearchDir() { 117168a39a65SDavide Italiano expect("("); 117286c5fb82SRui Ueyama StringRef Tok = next(); 11736c7ad13fSRui Ueyama if (!Config->Nostdlib) 1174cd574a5eSGeorge Rimar Config->SearchPaths.push_back(unquote(Tok)); 117568a39a65SDavide Italiano expect(")"); 117668a39a65SDavide Italiano } 117768a39a65SDavide Italiano 1178717677afSRui Ueyama void ScriptParser::readSections() { 1179e05336ffSEugene Leviant Opt.HasSections = true; 11808e3b38abSDenis Protivensky expect("{"); 118183043f23SRui Ueyama while (!Error && !consume("}")) { 1182113cdec9SRui Ueyama StringRef Tok = next(); 1183db741e72SEugene Leviant BaseCommand *Cmd = readProvideOrAssignment(Tok, true); 1184ceabe80eSEugene Leviant if (!Cmd) { 1185ceabe80eSEugene Leviant if (Tok == "ASSERT") 1186eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 1187ceabe80eSEugene Leviant else 118810416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 11898e3b38abSDenis Protivensky } 119010416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 1191652852c5SGeorge Rimar } 1192708019c4SRui Ueyama } 11938e3b38abSDenis Protivensky 1194708019c4SRui Ueyama static int precedence(StringRef Op) { 1195708019c4SRui Ueyama return StringSwitch<int>(Op) 11960120e3f2SRui Ueyama .Cases("*", "/", 5) 11970120e3f2SRui Ueyama .Cases("+", "-", 4) 11980120e3f2SRui Ueyama .Cases("<<", ">>", 3) 11999c4ac5f2SRui Ueyama .Cases("<", "<=", ">", ">=", "==", "!=", 2) 12000120e3f2SRui Ueyama .Cases("&", "|", 1) 1201708019c4SRui Ueyama .Default(-1); 1202708019c4SRui Ueyama } 1203708019c4SRui Ueyama 1204c91930a1SGeorge Rimar Regex ScriptParser::readFilePatterns() { 120510416564SRui Ueyama std::vector<StringRef> V; 120683043f23SRui Ueyama while (!Error && !consume(")")) 120710416564SRui Ueyama V.push_back(next()); 1208c91930a1SGeorge Rimar return compileGlobPatterns(V); 12090702c4e8SGeorge Rimar } 12100702c4e8SGeorge Rimar 1211be394db3SGeorge Rimar SortSectionPolicy ScriptParser::readSortKind() { 121283043f23SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 1213be394db3SGeorge Rimar return SortSectionPolicy::Name; 121483043f23SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 1215be394db3SGeorge Rimar return SortSectionPolicy::Alignment; 121683043f23SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 1217be394db3SGeorge Rimar return SortSectionPolicy::Priority; 121883043f23SRui Ueyama if (consume("SORT_NONE")) 1219be394db3SGeorge Rimar return SortSectionPolicy::None; 1220b2a0abdfSRui Ueyama return SortSectionPolicy::Default; 1221be394db3SGeorge Rimar } 1222be394db3SGeorge Rimar 1223395281cfSGeorge Rimar // Method reads a list of sequence of excluded files and section globs given in 1224395281cfSGeorge Rimar // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ 1225395281cfSGeorge Rimar // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) 1226af03be19SGeorge Rimar // The semantics of that is next: 1227af03be19SGeorge Rimar // * Include .foo.1 from every file. 1228af03be19SGeorge Rimar // * Include .foo.2 from every file but a.o 1229af03be19SGeorge Rimar // * Include .foo.3 from every file but b.o 123007171f21SGeorge Rimar std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 123107171f21SGeorge Rimar std::vector<SectionPattern> Ret; 1232601e9898SGeorge Rimar while (!Error && peek() != ")") { 1233027a9e87SRui Ueyama Regex ExcludeFileRe; 123483043f23SRui Ueyama if (consume("EXCLUDE_FILE")) { 1235395281cfSGeorge Rimar expect("("); 1236395281cfSGeorge Rimar ExcludeFileRe = readFilePatterns(); 1237395281cfSGeorge Rimar } 1238395281cfSGeorge Rimar 1239601e9898SGeorge Rimar std::vector<StringRef> V; 1240601e9898SGeorge Rimar while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE") 1241395281cfSGeorge Rimar V.push_back(next()); 1242601e9898SGeorge Rimar 1243601e9898SGeorge Rimar if (!V.empty()) 124407171f21SGeorge Rimar Ret.push_back({std::move(ExcludeFileRe), compileGlobPatterns(V)}); 1245601e9898SGeorge Rimar else 1246601e9898SGeorge Rimar setError("section pattern is expected"); 1247395281cfSGeorge Rimar } 124807171f21SGeorge Rimar return Ret; 1249395281cfSGeorge Rimar } 1250395281cfSGeorge Rimar 125107171f21SGeorge Rimar // Section pattern grammar can have complex expressions, for example: 125207171f21SGeorge Rimar // *(SORT(.foo.* EXCLUDE_FILE (*file1.o) .bar.*) .bar.* SORT(.zed.*)) 125307171f21SGeorge Rimar // Generally is a sequence of globs and excludes that may be wrapped in a SORT() 125407171f21SGeorge Rimar // commands, like: SORT(glob0) glob1 glob2 SORT(glob4) 125507171f21SGeorge Rimar // This methods handles wrapping sequences of excluded files and section globs 125607171f21SGeorge Rimar // into SORT() if that needed and reads them all. 1257a2496cbeSGeorge Rimar InputSectionDescription * 1258a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 1259c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 12600ed42b0cSDavide Italiano expect("("); 126183043f23SRui Ueyama while (!HasError && !consume(")")) { 126207171f21SGeorge Rimar SortSectionPolicy Outer = readSortKind(); 126307171f21SGeorge Rimar SortSectionPolicy Inner = SortSectionPolicy::Default; 126407171f21SGeorge Rimar std::vector<SectionPattern> V; 126507171f21SGeorge Rimar if (Outer != SortSectionPolicy::Default) { 12660702c4e8SGeorge Rimar expect("("); 126707171f21SGeorge Rimar Inner = readSortKind(); 126807171f21SGeorge Rimar if (Inner != SortSectionPolicy::Default) { 1269350ece4eSGeorge Rimar expect("("); 127007171f21SGeorge Rimar V = readInputSectionsList(); 12710702c4e8SGeorge Rimar expect(")"); 1272350ece4eSGeorge Rimar } else { 127307171f21SGeorge Rimar V = readInputSectionsList(); 1274350ece4eSGeorge Rimar } 1275350ece4eSGeorge Rimar expect(")"); 127607171f21SGeorge Rimar } else { 127707171f21SGeorge Rimar V = readInputSectionsList(); 12780659800eSGeorge Rimar } 12790702c4e8SGeorge Rimar 128007171f21SGeorge Rimar for (SectionPattern &Pat : V) { 128107171f21SGeorge Rimar Pat.SortInner = Inner; 128207171f21SGeorge Rimar Pat.SortOuter = Outer; 128307171f21SGeorge Rimar } 128407171f21SGeorge Rimar 128507171f21SGeorge Rimar std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 128607171f21SGeorge Rimar } 128710416564SRui Ueyama return Cmd; 12880659800eSGeorge Rimar } 12890659800eSGeorge Rimar 1290a2496cbeSGeorge Rimar InputSectionDescription * 1291a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 12920659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 12930659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 1294a2496cbeSGeorge Rimar if (Tok == "KEEP") { 1295e7282797SDavide Italiano expect("("); 1296a2496cbeSGeorge Rimar StringRef FilePattern = next(); 1297a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 12980ed42b0cSDavide Italiano expect(")"); 1299cf43f179SEugene Leviant Opt.KeptSections.push_back(Cmd); 130010416564SRui Ueyama return Cmd; 130110416564SRui Ueyama } 1302a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 13030659800eSGeorge Rimar } 13040659800eSGeorge Rimar 130503fc010eSGeorge Rimar void ScriptParser::readSort() { 130603fc010eSGeorge Rimar expect("("); 130703fc010eSGeorge Rimar expect("CONSTRUCTORS"); 130803fc010eSGeorge Rimar expect(")"); 130903fc010eSGeorge Rimar } 131003fc010eSGeorge Rimar 1311eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 1312eefa758eSGeorge Rimar expect("("); 1313eefa758eSGeorge Rimar Expr E = readExpr(); 1314eefa758eSGeorge Rimar expect(","); 1315cd574a5eSGeorge Rimar StringRef Msg = unquote(next()); 1316eefa758eSGeorge Rimar expect(")"); 1317eefa758eSGeorge Rimar return [=](uint64_t Dot) { 1318eefa758eSGeorge Rimar uint64_t V = E(Dot); 1319eefa758eSGeorge Rimar if (!V) 1320eefa758eSGeorge Rimar error(Msg); 1321eefa758eSGeorge Rimar return V; 1322eefa758eSGeorge Rimar }; 1323eefa758eSGeorge Rimar } 1324eefa758eSGeorge Rimar 132525150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 132625150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from 132725150e8bSRui Ueyama // what GNU linkers do. 132825150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 1329ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readFill() { 1330ff1f29e0SGeorge Rimar expect("("); 1331ff1f29e0SGeorge Rimar std::vector<uint8_t> V = readOutputSectionFiller(next()); 1332ff1f29e0SGeorge Rimar expect(")"); 1333ff1f29e0SGeorge Rimar expect(";"); 1334ff1f29e0SGeorge Rimar return V; 1335ff1f29e0SGeorge Rimar } 1336ff1f29e0SGeorge Rimar 133710416564SRui Ueyama OutputSectionCommand * 133810416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 1339076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 134058e5c4dcSGeorge Rimar 134158e5c4dcSGeorge Rimar // Read an address expression. 134258e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 134358e5c4dcSGeorge Rimar if (peek() != ":") 134458e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 134558e5c4dcSGeorge Rimar 13468e3b38abSDenis Protivensky expect(":"); 1347246f681eSDavide Italiano 134883043f23SRui Ueyama if (consume("AT")) 1349b71d6f7aSEugene Leviant Cmd->LMAExpr = readParenExpr(); 135083043f23SRui Ueyama if (consume("ALIGN")) 13516ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 135283043f23SRui Ueyama if (consume("SUBALIGN")) 1353db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1354630c6179SGeorge Rimar 1355246f681eSDavide Italiano // Parse constraints. 135683043f23SRui Ueyama if (consume("ONLY_IF_RO")) 1357efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 135883043f23SRui Ueyama if (consume("ONLY_IF_RW")) 1359efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 13608e3b38abSDenis Protivensky expect("{"); 13618ec77e64SRui Ueyama 136283043f23SRui Ueyama while (!Error && !consume("}")) { 1363ceabe80eSEugene Leviant StringRef Tok = next(); 1364db741e72SEugene Leviant if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok, false)) 1365ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1366e38cbab5SGeorge Rimar else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) 1367e38cbab5SGeorge Rimar Cmd->Commands.emplace_back(Data); 1368ff1f29e0SGeorge Rimar else if (Tok == "FILL") 1369ff1f29e0SGeorge Rimar Cmd->Filler = readFill(); 1370ceabe80eSEugene Leviant else if (Tok == "SORT") 137103fc010eSGeorge Rimar readSort(); 1372a2496cbeSGeorge Rimar else if (peek() == "(") 1373a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1374ceabe80eSEugene Leviant else 1375ceabe80eSEugene Leviant setError("unknown command " + Tok); 13768e3b38abSDenis Protivensky } 1377076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 13784ebc5620SGeorge Rimar 137983043f23SRui Ueyama if (consume("=")) 13804ebc5620SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next()); 13814ebc5620SGeorge Rimar else if (peek().startswith("=")) 1382ff1f29e0SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next().drop_front()); 13834ebc5620SGeorge Rimar 138410416564SRui Ueyama return Cmd; 1385f71caa2bSRui Ueyama } 13868ec77e64SRui Ueyama 13872c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 13882c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 13892c8f1f04SRui Ueyama // 13902c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 13912c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 13922c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 13932c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 1394ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readOutputSectionFiller(StringRef Tok) { 1395965827d6SRui Ueyama uint32_t V; 1396ff1f29e0SGeorge Rimar if (Tok.getAsInteger(0, V)) { 1397965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 1398f71caa2bSRui Ueyama return {}; 1399e2ee72b5SGeorge Rimar } 1400965827d6SRui Ueyama return {uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V)}; 14018e3b38abSDenis Protivensky } 14028e3b38abSDenis Protivensky 1403a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1404a31c91b1SEugene Leviant expect("("); 1405174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1406a35e39caSPetr Hosek Cmd->Provide = Provide; 1407174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1408a31c91b1SEugene Leviant expect(")"); 1409a31c91b1SEugene Leviant expect(";"); 141010416564SRui Ueyama return Cmd; 1411eda81a1bSEugene Leviant } 1412eda81a1bSEugene Leviant 1413db741e72SEugene Leviant SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok, 1414db741e72SEugene Leviant bool MakeAbsolute) { 1415ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1416ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1417ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1418ceabe80eSEugene Leviant expect(";"); 1419ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1420a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1421a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1422a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1423ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1424a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1425ceabe80eSEugene Leviant } 1426db741e72SEugene Leviant if (Cmd && MakeAbsolute) 1427db741e72SEugene Leviant Cmd->IsAbsolute = true; 1428ceabe80eSEugene Leviant return Cmd; 1429ceabe80eSEugene Leviant } 1430ceabe80eSEugene Leviant 143130835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { 143230835ea4SGeorge Rimar if (S == ".") 143330835ea4SGeorge Rimar return Dot; 1434884e786dSGeorge Rimar return ScriptBase->getSymbolValue(S); 1435e32a3598SGeorge Rimar } 1436e32a3598SGeorge Rimar 143730835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 143830835ea4SGeorge Rimar StringRef Op = next(); 1439db741e72SEugene Leviant bool IsAbsolute = false; 1440db741e72SEugene Leviant Expr E; 144130835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 144283043f23SRui Ueyama if (consume("ABSOLUTE")) { 14437c1381a0SRui Ueyama // The RHS may be something like "ABSOLUTE(.) & 0xff". 14447c1381a0SRui Ueyama // Call readExpr1 to read the whole expression. 14457c1381a0SRui Ueyama E = readExpr1(readParenExpr(), 0); 1446db741e72SEugene Leviant IsAbsolute = true; 1447db741e72SEugene Leviant } else { 1448db741e72SEugene Leviant E = readExpr(); 1449db741e72SEugene Leviant } 145030835ea4SGeorge Rimar if (Op == "+=") 145130835ea4SGeorge Rimar E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; 1452db741e72SEugene Leviant return new SymbolAssignment(Name, E, IsAbsolute); 145330835ea4SGeorge Rimar } 145430835ea4SGeorge Rimar 145530835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 145630835ea4SGeorge Rimar // script expression. 145730835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 145830835ea4SGeorge Rimar 145936c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 146036c1cd23SRui Ueyama if (Op == "*") 146136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 146236c1cd23SRui Ueyama if (Op == "/") { 146336c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 146436c1cd23SRui Ueyama uint64_t RHS = R(Dot); 146536c1cd23SRui Ueyama if (RHS == 0) { 146636c1cd23SRui Ueyama error("division by zero"); 146736c1cd23SRui Ueyama return 0; 146836c1cd23SRui Ueyama } 146936c1cd23SRui Ueyama return L(Dot) / RHS; 147036c1cd23SRui Ueyama }; 147136c1cd23SRui Ueyama } 147236c1cd23SRui Ueyama if (Op == "+") 147336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) + R(Dot); }; 147436c1cd23SRui Ueyama if (Op == "-") 147536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 1476c8ccd1f1SGeorge Rimar if (Op == "<<") 1477c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) << R(Dot); }; 1478c8ccd1f1SGeorge Rimar if (Op == ">>") 1479c8ccd1f1SGeorge Rimar return [=](uint64_t Dot) { return L(Dot) >> R(Dot); }; 148036c1cd23SRui Ueyama if (Op == "<") 148136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 148236c1cd23SRui Ueyama if (Op == ">") 148336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 148436c1cd23SRui Ueyama if (Op == ">=") 148536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 148636c1cd23SRui Ueyama if (Op == "<=") 148736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 148836c1cd23SRui Ueyama if (Op == "==") 148936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 149036c1cd23SRui Ueyama if (Op == "!=") 149136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 149236c1cd23SRui Ueyama if (Op == "&") 149336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 1494cc3dd629SRafael Espindola if (Op == "|") 1495cc3dd629SRafael Espindola return [=](uint64_t Dot) { return L(Dot) | R(Dot); }; 149636c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 149736c1cd23SRui Ueyama } 149836c1cd23SRui Ueyama 1499708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1500708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1501708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1502708019c4SRui Ueyama while (!atEOF() && !Error) { 1503708019c4SRui Ueyama // Read an operator and an expression. 1504708019c4SRui Ueyama StringRef Op1 = peek(); 1505708019c4SRui Ueyama if (Op1 == "?") 1506708019c4SRui Ueyama return readTernary(Lhs); 1507708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1508a31c91b1SEugene Leviant break; 15095424e7c7SJustin Bogner skip(); 1510708019c4SRui Ueyama Expr Rhs = readPrimary(); 1511708019c4SRui Ueyama 1512708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1513708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1514708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1515708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1516708019c4SRui Ueyama while (!atEOF()) { 1517708019c4SRui Ueyama StringRef Op2 = peek(); 1518708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1519eda81a1bSEugene Leviant break; 1520708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1521eda81a1bSEugene Leviant } 1522708019c4SRui Ueyama 1523708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1524708019c4SRui Ueyama } 1525708019c4SRui Ueyama return Lhs; 1526708019c4SRui Ueyama } 1527708019c4SRui Ueyama 1528708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1529e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1530708019c4SRui Ueyama return Target->PageSize; 1531e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1532997f8838SPetr Hosek return Config->MaxPageSize; 1533708019c4SRui Ueyama error("unknown constant: " + S); 1534708019c4SRui Ueyama return 0; 1535708019c4SRui Ueyama } 1536708019c4SRui Ueyama 1537626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1538626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1539626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1540626e0b08SRui Ueyama // "M" (mega) prefixes. 15419f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 1542eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1543eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1544eaeafb2bSSimon Atanasyan return false; 1545eaeafb2bSSimon Atanasyan Result = -Result; 1546eaeafb2bSSimon Atanasyan return true; 1547eaeafb2bSSimon Atanasyan } 15489f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 15499f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 15509f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 15519f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 15529f2f7ad9SGeorge Rimar 15539f2f7ad9SGeorge Rimar int Suffix = 1; 15549f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 15559f2f7ad9SGeorge Rimar Suffix = 1024; 15569f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 15579f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 15589f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 15599f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 15609f2f7ad9SGeorge Rimar } 15619f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 15629f2f7ad9SGeorge Rimar return false; 15639f2f7ad9SGeorge Rimar Result *= Suffix; 15649f2f7ad9SGeorge Rimar return true; 15659f2f7ad9SGeorge Rimar } 15669f2f7ad9SGeorge Rimar 1567e38cbab5SGeorge Rimar BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { 1568e38cbab5SGeorge Rimar int Size = StringSwitch<unsigned>(Tok) 1569e38cbab5SGeorge Rimar .Case("BYTE", 1) 1570e38cbab5SGeorge Rimar .Case("SHORT", 2) 1571e38cbab5SGeorge Rimar .Case("LONG", 4) 1572e38cbab5SGeorge Rimar .Case("QUAD", 8) 1573e38cbab5SGeorge Rimar .Default(-1); 1574e38cbab5SGeorge Rimar if (Size == -1) 1575e38cbab5SGeorge Rimar return nullptr; 1576e38cbab5SGeorge Rimar 1577e38cbab5SGeorge Rimar expect("("); 1578e38cbab5SGeorge Rimar uint64_t Val = 0; 1579e38cbab5SGeorge Rimar StringRef S = next(); 1580e38cbab5SGeorge Rimar if (!readInteger(S, Val)) 1581e38cbab5SGeorge Rimar setError("unexpected value: " + S); 1582e38cbab5SGeorge Rimar expect(")"); 1583e38cbab5SGeorge Rimar return new BytesDataCommand(Val, Size); 1584e38cbab5SGeorge Rimar } 1585e38cbab5SGeorge Rimar 1586b71d6f7aSEugene Leviant StringRef ScriptParser::readParenLiteral() { 1587b71d6f7aSEugene Leviant expect("("); 1588b71d6f7aSEugene Leviant StringRef Tok = next(); 1589b71d6f7aSEugene Leviant expect(")"); 1590b71d6f7aSEugene Leviant return Tok; 1591b71d6f7aSEugene Leviant } 1592b71d6f7aSEugene Leviant 1593708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 15946ad7dfccSRui Ueyama if (peek() == "(") 15956ad7dfccSRui Ueyama return readParenExpr(); 1596708019c4SRui Ueyama 15976ad7dfccSRui Ueyama StringRef Tok = next(); 1598708019c4SRui Ueyama 1599eaeafb2bSSimon Atanasyan if (Tok == "~") { 1600eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1601eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return ~E(Dot); }; 1602eaeafb2bSSimon Atanasyan } 1603eaeafb2bSSimon Atanasyan if (Tok == "-") { 1604eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1605eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return -E(Dot); }; 1606eaeafb2bSSimon Atanasyan } 1607eaeafb2bSSimon Atanasyan 1608708019c4SRui Ueyama // Built-in functions are parsed here. 1609708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 161096659df0SGeorge Rimar if (Tok == "ADDR") { 1611b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1612884e786dSGeorge Rimar return 1613884e786dSGeorge Rimar [=](uint64_t Dot) { return ScriptBase->getOutputSectionAddress(Name); }; 161496659df0SGeorge Rimar } 1615b71d6f7aSEugene Leviant if (Tok == "LOADADDR") { 1616b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1617b71d6f7aSEugene Leviant return [=](uint64_t Dot) { return ScriptBase->getOutputSectionLMA(Name); }; 1618b71d6f7aSEugene Leviant } 1619eefa758eSGeorge Rimar if (Tok == "ASSERT") 1620eefa758eSGeorge Rimar return readAssert(); 1621708019c4SRui Ueyama if (Tok == "ALIGN") { 16226ad7dfccSRui Ueyama Expr E = readParenExpr(); 1623708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1624708019c4SRui Ueyama } 1625708019c4SRui Ueyama if (Tok == "CONSTANT") { 1626b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1627b71d6f7aSEugene Leviant return [=](uint64_t Dot) { return getConstant(Name); }; 1628708019c4SRui Ueyama } 1629f34f45fdSGeorge Rimar if (Tok == "DEFINED") { 1630f34f45fdSGeorge Rimar expect("("); 1631f34f45fdSGeorge Rimar StringRef Tok = next(); 1632f34f45fdSGeorge Rimar expect(")"); 1633f2821028SGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->isDefined(Tok) ? 1 : 0; }; 1634f34f45fdSGeorge Rimar } 163554c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 163654c145ceSRafael Espindola expect("("); 16375424e7c7SJustin Bogner skip(); 163854c145ceSRafael Espindola expect(","); 16398c658bf8SGeorge Rimar Expr E = readExpr(); 164054c145ceSRafael Espindola expect(")"); 16418c658bf8SGeorge Rimar return [=](uint64_t Dot) { return E(Dot); }; 164254c145ceSRafael Espindola } 1643708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1644708019c4SRui Ueyama expect("("); 1645708019c4SRui Ueyama Expr E = readExpr(); 1646708019c4SRui Ueyama expect(","); 1647708019c4SRui Ueyama readExpr(); 1648708019c4SRui Ueyama expect(")"); 1649f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1650708019c4SRui Ueyama } 1651708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1652708019c4SRui Ueyama expect("("); 1653708019c4SRui Ueyama expect("."); 1654708019c4SRui Ueyama expect(")"); 1655708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1656708019c4SRui Ueyama } 1657276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1658276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1659276b4e64SGeorge Rimar // the next page boundary for simplicity. 1660276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1661276b4e64SGeorge Rimar expect("("); 166297bdc722SRafael Espindola readExpr(); 1663276b4e64SGeorge Rimar expect(","); 1664276b4e64SGeorge Rimar readExpr(); 1665276b4e64SGeorge Rimar expect(")"); 1666276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1667276b4e64SGeorge Rimar } 16689e69450eSGeorge Rimar if (Tok == "SIZEOF") { 1669b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 1670884e786dSGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; 16719e69450eSGeorge Rimar } 167236fac7f0SEugene Leviant if (Tok == "ALIGNOF") { 1673b71d6f7aSEugene Leviant StringRef Name = readParenLiteral(); 167436fac7f0SEugene Leviant return 167536fac7f0SEugene Leviant [=](uint64_t Dot) { return ScriptBase->getOutputSectionAlign(Name); }; 167636fac7f0SEugene Leviant } 1677e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 1678884e786dSGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; 1679708019c4SRui Ueyama 16809f2f7ad9SGeorge Rimar // Tok is a literal number. 16819f2f7ad9SGeorge Rimar uint64_t V; 16829f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 16839f2f7ad9SGeorge Rimar return [=](uint64_t Dot) { return V; }; 16849f2f7ad9SGeorge Rimar 16859f2f7ad9SGeorge Rimar // Tok is a symbol name. 168630835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1687708019c4SRui Ueyama setError("malformed number: " + Tok); 168830835ea4SGeorge Rimar return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }; 1689a9c5a528SGeorge Rimar } 1690708019c4SRui Ueyama 1691708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 16925424e7c7SJustin Bogner skip(); 1693708019c4SRui Ueyama Expr L = readExpr(); 1694708019c4SRui Ueyama expect(":"); 1695708019c4SRui Ueyama Expr R = readExpr(); 1696708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1697708019c4SRui Ueyama } 1698708019c4SRui Ueyama 16996ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 17006ad7dfccSRui Ueyama expect("("); 17016ad7dfccSRui Ueyama Expr E = readExpr(); 17026ad7dfccSRui Ueyama expect(")"); 17036ad7dfccSRui Ueyama return E; 17046ad7dfccSRui Ueyama } 17056ad7dfccSRui Ueyama 1706bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1707bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1708bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1709bbe38602SEugene Leviant StringRef Tok = next(); 1710bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 1711bbe38602SEugene Leviant if (Tok.empty()) { 1712bbe38602SEugene Leviant setError("section header name is empty"); 1713bbe38602SEugene Leviant break; 1714bbe38602SEugene Leviant } 1715bbe38602SEugene Leviant Phdrs.push_back(Tok); 1716bbe38602SEugene Leviant } 1717bbe38602SEugene Leviant return Phdrs; 1718bbe38602SEugene Leviant } 1719bbe38602SEugene Leviant 172095dd718cSGeorge Rimar // Read a program header type name. The next token must be a 172195dd718cSGeorge Rimar // name of a program header type or a constant (e.g. "0x3"). 1722bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1723bbe38602SEugene Leviant StringRef Tok = next(); 172495dd718cSGeorge Rimar uint64_t Val; 172595dd718cSGeorge Rimar if (readInteger(Tok, Val)) 172695dd718cSGeorge Rimar return Val; 172795dd718cSGeorge Rimar 1728b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1729b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1730b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1731b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1732b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1733b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1734b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1735b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1736b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1737b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1738b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1739b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1740270173f2SGeorge Rimar .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 1741cc6e567cSGeorge Rimar .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 1742b0f6c590SRui Ueyama .Default(-1); 1743bbe38602SEugene Leviant 1744b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1745b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1746b0f6c590SRui Ueyama return PT_NULL; 1747b0f6c590SRui Ueyama } 1748b0f6c590SRui Ueyama return Ret; 1749bbe38602SEugene Leviant } 1750bbe38602SEugene Leviant 175195769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 175220b6598cSGeorge Rimar // Identifiers start at 2 because 0 and 1 are reserved 175320b6598cSGeorge Rimar // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. 175420b6598cSGeorge Rimar size_t VersionId = Config->VersionDefinitions.size() + 2; 175520b6598cSGeorge Rimar Config->VersionDefinitions.push_back({VerStr, VersionId}); 175620b6598cSGeorge Rimar 175783043f23SRui Ueyama if (consume("global:") || peek() != "local:") 175820b6598cSGeorge Rimar readGlobal(VerStr); 175983043f23SRui Ueyama if (consume("local:")) 176020b6598cSGeorge Rimar readLocal(); 176120b6598cSGeorge Rimar expect("}"); 176220b6598cSGeorge Rimar 176320b6598cSGeorge Rimar // Each version may have a parent version. For example, "Ver2" defined as 176420b6598cSGeorge Rimar // "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This 176520b6598cSGeorge Rimar // version hierarchy is, probably against your instinct, purely for human; the 176620b6598cSGeorge Rimar // runtime doesn't care about them at all. In LLD, we simply skip the token. 176720b6598cSGeorge Rimar if (!VerStr.empty() && peek() != ";") 17685424e7c7SJustin Bogner skip(); 176920b6598cSGeorge Rimar expect(";"); 177020b6598cSGeorge Rimar } 177120b6598cSGeorge Rimar 177220b6598cSGeorge Rimar void ScriptParser::readLocal() { 177320b6598cSGeorge Rimar Config->DefaultSymbolVersion = VER_NDX_LOCAL; 177420b6598cSGeorge Rimar expect("*"); 177520b6598cSGeorge Rimar expect(";"); 177620b6598cSGeorge Rimar } 177720b6598cSGeorge Rimar 177820b6598cSGeorge Rimar void ScriptParser::readExtern(std::vector<SymbolVersion> *Globals) { 1779cd574a5eSGeorge Rimar expect("\"C++\""); 178020b6598cSGeorge Rimar expect("{"); 178120b6598cSGeorge Rimar 178220b6598cSGeorge Rimar for (;;) { 178320b6598cSGeorge Rimar if (peek() == "}" || Error) 178420b6598cSGeorge Rimar break; 1785cd574a5eSGeorge Rimar bool HasWildcard = !peek().startswith("\"") && hasWildcard(peek()); 1786cd574a5eSGeorge Rimar Globals->push_back({unquote(next()), true, HasWildcard}); 178720b6598cSGeorge Rimar expect(";"); 178820b6598cSGeorge Rimar } 178920b6598cSGeorge Rimar 179020b6598cSGeorge Rimar expect("}"); 179120b6598cSGeorge Rimar expect(";"); 179220b6598cSGeorge Rimar } 179320b6598cSGeorge Rimar 179420b6598cSGeorge Rimar void ScriptParser::readGlobal(StringRef VerStr) { 179520b6598cSGeorge Rimar std::vector<SymbolVersion> *Globals; 179620b6598cSGeorge Rimar if (VerStr.empty()) 179720b6598cSGeorge Rimar Globals = &Config->VersionScriptGlobals; 179820b6598cSGeorge Rimar else 179920b6598cSGeorge Rimar Globals = &Config->VersionDefinitions.back().Globals; 180020b6598cSGeorge Rimar 180120b6598cSGeorge Rimar for (;;) { 180283043f23SRui Ueyama if (consume("extern")) 180320b6598cSGeorge Rimar readExtern(Globals); 180420b6598cSGeorge Rimar 180520b6598cSGeorge Rimar StringRef Cur = peek(); 180620b6598cSGeorge Rimar if (Cur == "}" || Cur == "local:" || Error) 180720b6598cSGeorge Rimar return; 18085424e7c7SJustin Bogner skip(); 1809cd574a5eSGeorge Rimar Globals->push_back({unquote(Cur), false, hasWildcard(Cur)}); 181020b6598cSGeorge Rimar expect(";"); 181120b6598cSGeorge Rimar } 181220b6598cSGeorge Rimar } 181320b6598cSGeorge Rimar 181416b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 181516b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 181616b0cc9eSSimon Atanasyan return false; 181716b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 181816b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 181916b0cc9eSSimon Atanasyan return true; 182016b0cc9eSSimon Atanasyan return false; 182116b0cc9eSSimon Atanasyan } 182216b0cc9eSSimon Atanasyan 182307320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 182416b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 182520b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).readLinkerScript(); 182620b6598cSGeorge Rimar } 182720b6598cSGeorge Rimar 182820b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 182920b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), false).readVersionScript(); 1830f7c5fbb1SRui Ueyama } 18311ebc8ed7SRui Ueyama 183207320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 183307320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 183407320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 183507320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1836