1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===// 2f7c5fbb1SRui Ueyama // 3f7c5fbb1SRui Ueyama // The LLVM Linker 4f7c5fbb1SRui Ueyama // 5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source 6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details. 7f7c5fbb1SRui Ueyama // 8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 9f7c5fbb1SRui Ueyama // 10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script. 11629e0aa5SRui Ueyama // It parses a linker script and write the result to Config or ScriptConfig 12629e0aa5SRui Ueyama // objects. 13629e0aa5SRui Ueyama // 14629e0aa5SRui Ueyama // If SECTIONS command is used, a ScriptConfig contains an AST 15629e0aa5SRui Ueyama // of the command which will later be consumed by createSections() and 16629e0aa5SRui Ueyama // assignAddresses(). 17f7c5fbb1SRui Ueyama // 18f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 19f7c5fbb1SRui Ueyama 20717677afSRui Ueyama #include "LinkerScript.h" 21f7c5fbb1SRui Ueyama #include "Config.h" 22f7c5fbb1SRui Ueyama #include "Driver.h" 231ebc8ed7SRui Ueyama #include "InputSection.h" 24652852c5SGeorge Rimar #include "OutputSections.h" 25e77b5bf6SAdhemerval Zanella #include "ScriptParser.h" 2693c9af42SRui Ueyama #include "Strings.h" 27eda81a1bSEugene Leviant #include "Symbols.h" 28f7c5fbb1SRui Ueyama #include "SymbolTable.h" 29467c4d55SEugene Leviant #include "Target.h" 30bbe38602SEugene Leviant #include "Writer.h" 31960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 32652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 33f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 34f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h" 35f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 36a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h" 37f7c5fbb1SRui Ueyama 38f7c5fbb1SRui Ueyama using namespace llvm; 39652852c5SGeorge Rimar using namespace llvm::ELF; 401ebc8ed7SRui Ueyama using namespace llvm::object; 41f7c5fbb1SRui Ueyama using namespace lld; 42e0df00b9SRafael Espindola using namespace lld::elf; 43f7c5fbb1SRui Ueyama 4407320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 45717677afSRui Ueyama 46076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 47076fe157SGeorge Rimar return C->Kind == AssignmentKind; 48076fe157SGeorge Rimar } 49076fe157SGeorge Rimar 50076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 51076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 52076fe157SGeorge Rimar } 53076fe157SGeorge Rimar 54eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 55eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 56eea3114fSGeorge Rimar } 57eea3114fSGeorge Rimar 5836a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) { 59eea3114fSGeorge Rimar return !S || !S->Live; 60717677afSRui Ueyama } 61717677afSRui Ueyama 6207320e40SRui Ueyama template <class ELFT> 6307320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 648ec77e64SRui Ueyama for (StringRef Pat : Opt.KeptSections) 65722830a5SRui Ueyama if (globMatch(Pat, S->getSectionName())) 668ec77e64SRui Ueyama return true; 678ec77e64SRui Ueyama return false; 68481c2ce6SGeorge Rimar } 69481c2ce6SGeorge Rimar 7063dc6509SRui Ueyama static bool match(ArrayRef<StringRef> Patterns, StringRef S) { 7163dc6509SRui Ueyama for (StringRef Pat : Patterns) 7263dc6509SRui Ueyama if (globMatch(Pat, S)) 73eea3114fSGeorge Rimar return true; 74eea3114fSGeorge Rimar return false; 75eea3114fSGeorge Rimar } 76eea3114fSGeorge Rimar 776b274810SRui Ueyama // Create a vector of (<output section name>, <input section name patterns>). 786b274810SRui Ueyama // For example, if a returned vector contains (".text" (".foo.*" ".bar.*")), 796b274810SRui Ueyama // input sections start with ".foo." or ".bar." should be added to 806b274810SRui Ueyama // ".text" section. 816b274810SRui Ueyama template <class ELFT> 82e7282797SDavide Italiano std::vector<std::pair<StringRef, const InputSectionDescription *>> 836b274810SRui Ueyama LinkerScript<ELFT>::getSectionMap() { 84e7282797SDavide Italiano std::vector<std::pair<StringRef, const InputSectionDescription *>> Ret; 856b274810SRui Ueyama 866b274810SRui Ueyama for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) 876b274810SRui Ueyama if (auto *Cmd1 = dyn_cast<OutputSectionCommand>(Base1.get())) 886b274810SRui Ueyama for (const std::unique_ptr<BaseCommand> &Base2 : Cmd1->Commands) 896b274810SRui Ueyama if (auto *Cmd2 = dyn_cast<InputSectionDescription>(Base2.get())) 90e7282797SDavide Italiano Ret.emplace_back(Cmd1->Name, Cmd2); 916b274810SRui Ueyama 926b274810SRui Ueyama return Ret; 936b274810SRui Ueyama } 946b274810SRui Ueyama 956b274810SRui Ueyama // Returns input sections filtered by given glob patterns. 966b274810SRui Ueyama template <class ELFT> 976b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *> 98e7282797SDavide Italiano LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) { 99e7282797SDavide Italiano ArrayRef<StringRef> Patterns = I->Patterns; 100e7282797SDavide Italiano ArrayRef<StringRef> ExcludedFiles = I->ExcludedFiles; 1016b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 1026b274810SRui Ueyama for (const std::unique_ptr<ObjectFile<ELFT>> &F : 1036b274810SRui Ueyama Symtab<ELFT>::X->getObjectFiles()) 1046b274810SRui Ueyama for (InputSectionBase<ELFT> *S : F->getSections()) 1056b274810SRui Ueyama if (!isDiscarded(S) && !S->OutSec && match(Patterns, S->getSectionName())) 106e7282797SDavide Italiano if (ExcludedFiles.empty() || 107e7282797SDavide Italiano !match(ExcludedFiles, sys::path::filename(F->getName()))) 1086b274810SRui Ueyama Ret.push_back(S); 1096b274810SRui Ueyama return Ret; 1106b274810SRui Ueyama } 1116b274810SRui Ueyama 112652852c5SGeorge Rimar template <class ELFT> 113a7f7884dSRui Ueyama std::vector<OutputSectionBase<ELFT> *> 114e63d81bdSEugene Leviant LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 1156b274810SRui Ueyama std::vector<OutputSectionBase<ELFT> *> Ret; 116a7f7884dSRui Ueyama 117e63d81bdSEugene Leviant // Add input section to output section. If there is no output section yet, 118e63d81bdSEugene Leviant // then create it and add to output section list. 1196b274810SRui Ueyama auto Add = [&](InputSectionBase<ELFT> *C, StringRef Name) { 120e63d81bdSEugene Leviant OutputSectionBase<ELFT> *Sec; 121e63d81bdSEugene Leviant bool IsNew; 122e63d81bdSEugene Leviant std::tie(Sec, IsNew) = Factory.create(C, Name); 123e63d81bdSEugene Leviant if (IsNew) 1246b274810SRui Ueyama Ret.push_back(Sec); 125e63d81bdSEugene Leviant Sec->addSection(C); 126e63d81bdSEugene Leviant }; 127e63d81bdSEugene Leviant 1286b274810SRui Ueyama for (auto &P : getSectionMap()) { 1296b274810SRui Ueyama StringRef OutputName = P.first; 130e7282797SDavide Italiano const InputSectionDescription *I = P.second; 131e7282797SDavide Italiano for (InputSectionBase<ELFT> *S : getInputSections(I)) { 1326b274810SRui Ueyama if (OutputName == "/DISCARD/") { 133eea3114fSGeorge Rimar S->Live = false; 1346b274810SRui Ueyama reportDiscarded(S); 1356b274810SRui Ueyama continue; 136eea3114fSGeorge Rimar } 1376b274810SRui Ueyama Add(S, OutputName); 138eea3114fSGeorge Rimar } 139eea3114fSGeorge Rimar } 140e63d81bdSEugene Leviant 141e63d81bdSEugene Leviant // Add all other input sections, which are not listed in script. 1426b274810SRui Ueyama for (const std::unique_ptr<ObjectFile<ELFT>> &F : 1436b274810SRui Ueyama Symtab<ELFT>::X->getObjectFiles()) 1446b274810SRui Ueyama for (InputSectionBase<ELFT> *S : F->getSections()) 1456b274810SRui Ueyama if (!isDiscarded(S) && !S->OutSec) 1466b274810SRui Ueyama Add(S, getOutputSectionName(S)); 147e63d81bdSEugene Leviant 1483c291e1aSRui Ueyama // Remove from the output all the sections which did not meet 1493c291e1aSRui Ueyama // the optional constraints. 1506b274810SRui Ueyama return filter(Ret); 1513c291e1aSRui Ueyama } 1523c291e1aSRui Ueyama 1533c291e1aSRui Ueyama // Process ONLY_IF_RO and ONLY_IF_RW. 1543c291e1aSRui Ueyama template <class ELFT> 1553c291e1aSRui Ueyama std::vector<OutputSectionBase<ELFT> *> 1563c291e1aSRui Ueyama LinkerScript<ELFT>::filter(std::vector<OutputSectionBase<ELFT> *> &Sections) { 1573c291e1aSRui Ueyama // In this loop, we remove output sections if they don't satisfy 1583c291e1aSRui Ueyama // requested properties. 1593c291e1aSRui Ueyama for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 1603c291e1aSRui Ueyama auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 1613c291e1aSRui Ueyama if (!Cmd || Cmd->Name == "/DISCARD/") 1623c291e1aSRui Ueyama continue; 1633c291e1aSRui Ueyama 164bfc4a4b7SGeorge Rimar if (Cmd->Constraint == ConstraintKind::NoConstraint) 1653c291e1aSRui Ueyama continue; 166bfc4a4b7SGeorge Rimar 167bfc4a4b7SGeorge Rimar auto It = llvm::find_if(Sections, [&](OutputSectionBase<ELFT> *S) { 168bfc4a4b7SGeorge Rimar return S->getName() == Cmd->Name; 169bfc4a4b7SGeorge Rimar }); 170bfc4a4b7SGeorge Rimar if (It == Sections.end()) 171bfc4a4b7SGeorge Rimar continue; 1723c291e1aSRui Ueyama 1733c291e1aSRui Ueyama OutputSectionBase<ELFT> *Sec = *It; 1743c291e1aSRui Ueyama bool Writable = (Sec->getFlags() & SHF_WRITE); 1753c291e1aSRui Ueyama bool RO = (Cmd->Constraint == ConstraintKind::ReadOnly); 1763c291e1aSRui Ueyama bool RW = (Cmd->Constraint == ConstraintKind::ReadWrite); 1773c291e1aSRui Ueyama 1783c291e1aSRui Ueyama if ((RO && Writable) || (RW && !Writable)) { 1793c291e1aSRui Ueyama Sections.erase(It); 1803c291e1aSRui Ueyama continue; 1813c291e1aSRui Ueyama } 1823c291e1aSRui Ueyama } 1833c291e1aSRui Ueyama return Sections; 184e63d81bdSEugene Leviant } 185e63d81bdSEugene Leviant 186e63d81bdSEugene Leviant template <class ELFT> 18710e576e1SGeorge Rimar void LinkerScript<ELFT>::dispatchAssignment(SymbolAssignment *Cmd) { 188708019c4SRui Ueyama uint64_t Val = Cmd->Expression(Dot); 18910e576e1SGeorge Rimar if (Cmd->Name == ".") { 19010e576e1SGeorge Rimar Dot = Val; 191a31c91b1SEugene Leviant } else if (!Cmd->Ignore) { 19210e576e1SGeorge Rimar auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd->Name)); 19310e576e1SGeorge Rimar D->Value = Val; 19410e576e1SGeorge Rimar } 19510e576e1SGeorge Rimar } 19610e576e1SGeorge Rimar 19710e576e1SGeorge Rimar template <class ELFT> 19807320e40SRui Ueyama void LinkerScript<ELFT>::assignAddresses( 199dbbd8b15SGeorge Rimar ArrayRef<OutputSectionBase<ELFT> *> Sections) { 200652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 2017c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 2027c18c28cSRui Ueyama // We place orphan sections at end of file. 2037c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 204652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 2057c18c28cSRui Ueyama for (OutputSectionBase<ELFT> *Sec : Sections) { 206652852c5SGeorge Rimar StringRef Name = Sec->getName(); 207c3e2a4b0SRui Ueyama if (getSectionIndex(Name) == INT_MAX) 208076fe157SGeorge Rimar Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name)); 209652852c5SGeorge Rimar } 210652852c5SGeorge Rimar 2117c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 212c998a8c0SRui Ueyama Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 213467c4d55SEugene Leviant uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 214652852c5SGeorge Rimar uintX_t ThreadBssOffset = 0; 215652852c5SGeorge Rimar 216076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 217076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 21810e576e1SGeorge Rimar dispatchAssignment(Cmd); 21905ef4cffSRui Ueyama continue; 220652852c5SGeorge Rimar } 221652852c5SGeorge Rimar 222fb8978fcSDima Stepanov // Find all the sections with required name. There can be more than 2236ad330acSGeorge Rimar // one section with such name, if the alignment, flags or type 224fb8978fcSDima Stepanov // attribute differs. 225076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 226fb8978fcSDima Stepanov for (OutputSectionBase<ELFT> *Sec : Sections) { 227076fe157SGeorge Rimar if (Sec->getName() != Cmd->Name) 228652852c5SGeorge Rimar continue; 229652852c5SGeorge Rimar 23058e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 23158e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 23258e5c4dcSGeorge Rimar 233630c6179SGeorge Rimar if (Cmd->AlignExpr) 234630c6179SGeorge Rimar Sec->updateAlignment(Cmd->AlignExpr(Dot)); 235630c6179SGeorge Rimar 236652852c5SGeorge Rimar if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { 237c998a8c0SRui Ueyama uintX_t TVA = Dot + ThreadBssOffset; 238424b4081SRui Ueyama TVA = alignTo(TVA, Sec->getAlignment()); 239652852c5SGeorge Rimar Sec->setVA(TVA); 240c998a8c0SRui Ueyama ThreadBssOffset = TVA - Dot + Sec->getSize(); 241652852c5SGeorge Rimar continue; 242652852c5SGeorge Rimar } 243652852c5SGeorge Rimar 244652852c5SGeorge Rimar if (Sec->getFlags() & SHF_ALLOC) { 245424b4081SRui Ueyama Dot = alignTo(Dot, Sec->getAlignment()); 246c998a8c0SRui Ueyama Sec->setVA(Dot); 247467c4d55SEugene Leviant MinVA = std::min(MinVA, Dot); 248c998a8c0SRui Ueyama Dot += Sec->getSize(); 249652852c5SGeorge Rimar continue; 250652852c5SGeorge Rimar } 251652852c5SGeorge Rimar } 252652852c5SGeorge Rimar } 253467c4d55SEugene Leviant 25464c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 255b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 256467c4d55SEugene Leviant MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() - 257467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->getSize(), 258467c4d55SEugene Leviant Target->PageSize); 259467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 260467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 261fb8978fcSDima Stepanov } 262652852c5SGeorge Rimar 26307320e40SRui Ueyama template <class ELFT> 26474df5c7eSRafael Espindola std::vector<PhdrEntry<ELFT>> 265bbe38602SEugene Leviant LinkerScript<ELFT>::createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> Sections) { 266edebbdf1SRui Ueyama std::vector<PhdrEntry<ELFT>> Ret; 267bbe38602SEugene Leviant 268bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 269edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 270edebbdf1SRui Ueyama PhdrEntry<ELFT> &Phdr = Ret.back(); 271bbe38602SEugene Leviant 272bbe38602SEugene Leviant if (Cmd.HasFilehdr) 273adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 274bbe38602SEugene Leviant if (Cmd.HasPhdrs) 275adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 276bbe38602SEugene Leviant 277bbe38602SEugene Leviant switch (Cmd.Type) { 278bbe38602SEugene Leviant case PT_INTERP: 279fd03cfd2SRui Ueyama if (Out<ELFT>::Interp) 280adca245fSRui Ueyama Phdr.add(Out<ELFT>::Interp); 281bbe38602SEugene Leviant break; 282bbe38602SEugene Leviant case PT_DYNAMIC: 283bbe38602SEugene Leviant if (isOutputDynamic<ELFT>()) { 2840b113671SRafael Espindola Phdr.H.p_flags = Out<ELFT>::Dynamic->getPhdrFlags(); 285adca245fSRui Ueyama Phdr.add(Out<ELFT>::Dynamic); 286bbe38602SEugene Leviant } 287bbe38602SEugene Leviant break; 288bbe38602SEugene Leviant case PT_GNU_EH_FRAME: 289bbe38602SEugene Leviant if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) { 2900b113671SRafael Espindola Phdr.H.p_flags = Out<ELFT>::EhFrameHdr->getPhdrFlags(); 291adca245fSRui Ueyama Phdr.add(Out<ELFT>::EhFrameHdr); 292bbe38602SEugene Leviant } 293bbe38602SEugene Leviant break; 294bbe38602SEugene Leviant } 295bbe38602SEugene Leviant } 296bbe38602SEugene Leviant 297edebbdf1SRui Ueyama PhdrEntry<ELFT> *Load = nullptr; 298edebbdf1SRui Ueyama uintX_t Flags = PF_R; 299bbe38602SEugene Leviant for (OutputSectionBase<ELFT> *Sec : Sections) { 300bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 301bbe38602SEugene Leviant break; 302bbe38602SEugene Leviant 303edebbdf1SRui Ueyama std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName()); 304bbe38602SEugene Leviant if (!PhdrIds.empty()) { 305bbe38602SEugene Leviant // Assign headers specified by linker script 306bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 307edebbdf1SRui Ueyama Ret[Id].add(Sec); 308865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 3090b113671SRafael Espindola Ret[Id].H.p_flags |= Sec->getPhdrFlags(); 310bbe38602SEugene Leviant } 311bbe38602SEugene Leviant } else { 312bbe38602SEugene Leviant // If we have no load segment or flags've changed then we want new load 313bbe38602SEugene Leviant // segment. 3140b113671SRafael Espindola uintX_t NewFlags = Sec->getPhdrFlags(); 315bbe38602SEugene Leviant if (Load == nullptr || Flags != NewFlags) { 316edebbdf1SRui Ueyama Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags); 317bbe38602SEugene Leviant Flags = NewFlags; 318bbe38602SEugene Leviant } 31918f084ffSRui Ueyama Load->add(Sec); 320bbe38602SEugene Leviant } 321bbe38602SEugene Leviant } 322edebbdf1SRui Ueyama return Ret; 323bbe38602SEugene Leviant } 324bbe38602SEugene Leviant 325bbe38602SEugene Leviant template <class ELFT> 32607320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 327f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 328f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 329f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 330f6c3ccefSGeorge Rimar return Cmd->Filler; 331e2ee72b5SGeorge Rimar return {}; 332e2ee72b5SGeorge Rimar } 333e2ee72b5SGeorge Rimar 334c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 335c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 336c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 337c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 338076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 339f510fa6bSRui Ueyama int I = 0; 340f510fa6bSRui Ueyama for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 341076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 342076fe157SGeorge Rimar if (Cmd->Name == Name) 343f510fa6bSRui Ueyama return I; 344f510fa6bSRui Ueyama ++I; 345f510fa6bSRui Ueyama } 346f510fa6bSRui Ueyama return INT_MAX; 34771b26e94SGeorge Rimar } 34871b26e94SGeorge Rimar 34971b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if 35071b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0. 35107320e40SRui Ueyama template <class ELFT> 35207320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 353c3e2a4b0SRui Ueyama int I = getSectionIndex(A); 354c3e2a4b0SRui Ueyama int J = getSectionIndex(B); 355c3e2a4b0SRui Ueyama if (I == INT_MAX && J == INT_MAX) 356717677afSRui Ueyama return 0; 357717677afSRui Ueyama return I < J ? -1 : 1; 358717677afSRui Ueyama } 359717677afSRui Ueyama 360076fe157SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::addScriptedSymbols() { 361a31c91b1SEugene Leviant for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 362a31c91b1SEugene Leviant auto *Cmd = dyn_cast<SymbolAssignment>(Base.get()); 363a31c91b1SEugene Leviant if (!Cmd || Cmd->Name == ".") 364a31c91b1SEugene Leviant continue; 365a31c91b1SEugene Leviant 3668ab4108dSDavide Italiano SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 367373a533aSDavide Italiano // The semantic of PROVIDE is that of introducing a symbol only if 368373a533aSDavide Italiano // it's not defined and there's at least a reference to it. 369373a533aSDavide Italiano if ((!B && !Cmd->Provide) || (B && B->isUndefined())) 370a31c91b1SEugene Leviant Symtab<ELFT>::X->addAbsolute(Cmd->Name, 371a31c91b1SEugene Leviant Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT); 372a31c91b1SEugene Leviant else 373a31c91b1SEugene Leviant // Symbol already exists in symbol table. If it is provided 374a31c91b1SEugene Leviant // then we can't override its value. 375a31c91b1SEugene Leviant Cmd->Ignore = Cmd->Provide; 376a31c91b1SEugene Leviant } 377eda81a1bSEugene Leviant } 378eda81a1bSEugene Leviant 379bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 380bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 381bbe38602SEugene Leviant } 382bbe38602SEugene Leviant 383bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 384bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 385bbe38602SEugene Leviant // PHDRS {} script block. 386bbe38602SEugene Leviant template <class ELFT> 387edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 388076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 389076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 390edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 39131d842f5SGeorge Rimar continue; 39231d842f5SGeorge Rimar 39329c5a2a9SRui Ueyama std::vector<size_t> Ret; 39429c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 39529c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 39629c5a2a9SRui Ueyama return Ret; 397bbe38602SEugene Leviant } 39831d842f5SGeorge Rimar return {}; 39931d842f5SGeorge Rimar } 400bbe38602SEugene Leviant 40129c5a2a9SRui Ueyama template <class ELFT> 40229c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 40329c5a2a9SRui Ueyama size_t I = 0; 40429c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 40529c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 40629c5a2a9SRui Ueyama return I; 40729c5a2a9SRui Ueyama ++I; 40829c5a2a9SRui Ueyama } 40929c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 41029c5a2a9SRui Ueyama return 0; 41129c5a2a9SRui Ueyama } 41229c5a2a9SRui Ueyama 41307320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 414c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 415c3794e58SGeorge Rimar 416f7c5fbb1SRui Ueyama public: 41707320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 418f23b2320SGeorge Rimar 4194a46539cSRui Ueyama void run(); 420f7c5fbb1SRui Ueyama 421f7c5fbb1SRui Ueyama private: 42252a1509eSRui Ueyama void addFile(StringRef Path); 42352a1509eSRui Ueyama 424f7c5fbb1SRui Ueyama void readAsNeeded(); 42590c5099eSDenis Protivensky void readEntry(); 42683f406cfSGeorge Rimar void readExtern(); 427e7282797SDavide Italiano std::unique_ptr<InputSectionDescription> readFilePattern(); 428f7c5fbb1SRui Ueyama void readGroup(); 4290ed42b0cSDavide Italiano void readKeep(OutputSectionCommand *Cmd); 43031aa1f83SRui Ueyama void readInclude(); 431c3794e58SGeorge Rimar void readNothing() {} 432ee59282bSRui Ueyama void readOutput(); 4339159ce93SDavide Italiano void readOutputArch(); 434f7c5fbb1SRui Ueyama void readOutputFormat(); 435bbe38602SEugene Leviant void readPhdrs(); 43668a39a65SDavide Italiano void readSearchDir(); 4378e3b38abSDenis Protivensky void readSections(); 4388e3b38abSDenis Protivensky 439113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 440eda81a1bSEugene Leviant void readOutputSectionDescription(StringRef OutSec); 441bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 442bbe38602SEugene Leviant unsigned readPhdrType(); 443a31c91b1SEugene Leviant void readProvide(bool Hidden); 444630c6179SGeorge Rimar void readAlign(OutputSectionCommand *Cmd); 445*03fc010eSGeorge Rimar void readSort(); 446708019c4SRui Ueyama 447708019c4SRui Ueyama Expr readExpr(); 448708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 449708019c4SRui Ueyama Expr readPrimary(); 450708019c4SRui Ueyama Expr readTernary(Expr Cond); 451708019c4SRui Ueyama Expr combine(StringRef Op, Expr Lhs, Expr Rhs); 452f7c5fbb1SRui Ueyama 453c3794e58SGeorge Rimar const static StringMap<Handler> Cmd; 45407320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 45507320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 45616b0cc9eSSimon Atanasyan bool IsUnderSysroot; 457f7c5fbb1SRui Ueyama }; 458f7c5fbb1SRui Ueyama 459e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = { 460c3794e58SGeorge Rimar {"ENTRY", &ScriptParser::readEntry}, 461c3794e58SGeorge Rimar {"EXTERN", &ScriptParser::readExtern}, 462c3794e58SGeorge Rimar {"GROUP", &ScriptParser::readGroup}, 463c3794e58SGeorge Rimar {"INCLUDE", &ScriptParser::readInclude}, 464c3794e58SGeorge Rimar {"INPUT", &ScriptParser::readGroup}, 465c3794e58SGeorge Rimar {"OUTPUT", &ScriptParser::readOutput}, 466c3794e58SGeorge Rimar {"OUTPUT_ARCH", &ScriptParser::readOutputArch}, 467c3794e58SGeorge Rimar {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat}, 468bbe38602SEugene Leviant {"PHDRS", &ScriptParser::readPhdrs}, 469c3794e58SGeorge Rimar {"SEARCH_DIR", &ScriptParser::readSearchDir}, 470c3794e58SGeorge Rimar {"SECTIONS", &ScriptParser::readSections}, 471c3794e58SGeorge Rimar {";", &ScriptParser::readNothing}}; 472c3794e58SGeorge Rimar 473717677afSRui Ueyama void ScriptParser::run() { 474f7c5fbb1SRui Ueyama while (!atEOF()) { 475f7c5fbb1SRui Ueyama StringRef Tok = next(); 476c3794e58SGeorge Rimar if (Handler Fn = Cmd.lookup(Tok)) 477c3794e58SGeorge Rimar (this->*Fn)(); 478c3794e58SGeorge Rimar else 4795761042dSGeorge Rimar setError("unknown directive: " + Tok); 480f7c5fbb1SRui Ueyama } 481f7c5fbb1SRui Ueyama } 482f7c5fbb1SRui Ueyama 483717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 48416b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 48516b0cc9eSSimon Atanasyan SmallString<128> Path; 48616b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 48716b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 48816b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 48916b0cc9eSSimon Atanasyan return; 49016b0cc9eSSimon Atanasyan } 49116b0cc9eSSimon Atanasyan } 49216b0cc9eSSimon Atanasyan 493f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 49452a1509eSRui Ueyama Driver->addFile(S); 49552a1509eSRui Ueyama } else if (S.startswith("=")) { 49652a1509eSRui Ueyama if (Config->Sysroot.empty()) 49752a1509eSRui Ueyama Driver->addFile(S.substr(1)); 49852a1509eSRui Ueyama else 49952a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 50052a1509eSRui Ueyama } else if (S.startswith("-l")) { 50121eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 502a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 503a1b8fc3bSSimon Atanasyan Driver->addFile(S); 50452a1509eSRui Ueyama } else { 50552a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 50652a1509eSRui Ueyama if (Path.empty()) 507777f9630SGeorge Rimar setError("unable to find " + S); 508025d59b1SRui Ueyama else 50952a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 51052a1509eSRui Ueyama } 51152a1509eSRui Ueyama } 51252a1509eSRui Ueyama 513717677afSRui Ueyama void ScriptParser::readAsNeeded() { 514f7c5fbb1SRui Ueyama expect("("); 51535da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 51635da9b6eSRui Ueyama Config->AsNeeded = true; 517025d59b1SRui Ueyama while (!Error) { 518f7c5fbb1SRui Ueyama StringRef Tok = next(); 519f7c5fbb1SRui Ueyama if (Tok == ")") 52035da9b6eSRui Ueyama break; 52152a1509eSRui Ueyama addFile(Tok); 522f7c5fbb1SRui Ueyama } 52335da9b6eSRui Ueyama Config->AsNeeded = Orig; 524f7c5fbb1SRui Ueyama } 525f7c5fbb1SRui Ueyama 526717677afSRui Ueyama void ScriptParser::readEntry() { 52790c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 52890c5099eSDenis Protivensky expect("("); 52990c5099eSDenis Protivensky StringRef Tok = next(); 53090c5099eSDenis Protivensky if (Config->Entry.empty()) 53190c5099eSDenis Protivensky Config->Entry = Tok; 53290c5099eSDenis Protivensky expect(")"); 53390c5099eSDenis Protivensky } 53490c5099eSDenis Protivensky 535717677afSRui Ueyama void ScriptParser::readExtern() { 53683f406cfSGeorge Rimar expect("("); 537025d59b1SRui Ueyama while (!Error) { 53883f406cfSGeorge Rimar StringRef Tok = next(); 53983f406cfSGeorge Rimar if (Tok == ")") 54083f406cfSGeorge Rimar return; 54183f406cfSGeorge Rimar Config->Undefined.push_back(Tok); 54283f406cfSGeorge Rimar } 54383f406cfSGeorge Rimar } 54483f406cfSGeorge Rimar 545717677afSRui Ueyama void ScriptParser::readGroup() { 546f7c5fbb1SRui Ueyama expect("("); 547025d59b1SRui Ueyama while (!Error) { 548f7c5fbb1SRui Ueyama StringRef Tok = next(); 549f7c5fbb1SRui Ueyama if (Tok == ")") 550f7c5fbb1SRui Ueyama return; 551f7c5fbb1SRui Ueyama if (Tok == "AS_NEEDED") { 552f7c5fbb1SRui Ueyama readAsNeeded(); 553f7c5fbb1SRui Ueyama continue; 554f7c5fbb1SRui Ueyama } 55552a1509eSRui Ueyama addFile(Tok); 556f7c5fbb1SRui Ueyama } 557f7c5fbb1SRui Ueyama } 558f7c5fbb1SRui Ueyama 559717677afSRui Ueyama void ScriptParser::readInclude() { 56031aa1f83SRui Ueyama StringRef Tok = next(); 56131aa1f83SRui Ueyama auto MBOrErr = MemoryBuffer::getFile(Tok); 562025d59b1SRui Ueyama if (!MBOrErr) { 5635761042dSGeorge Rimar setError("cannot open " + Tok); 564025d59b1SRui Ueyama return; 565025d59b1SRui Ueyama } 56631aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 567a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 568a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 56931aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 57031aa1f83SRui Ueyama } 57131aa1f83SRui Ueyama 572717677afSRui Ueyama void ScriptParser::readOutput() { 573ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 574ee59282bSRui Ueyama expect("("); 575ee59282bSRui Ueyama StringRef Tok = next(); 576ee59282bSRui Ueyama if (Config->OutputFile.empty()) 577ee59282bSRui Ueyama Config->OutputFile = Tok; 578ee59282bSRui Ueyama expect(")"); 579ee59282bSRui Ueyama } 580ee59282bSRui Ueyama 581717677afSRui Ueyama void ScriptParser::readOutputArch() { 5829159ce93SDavide Italiano // Error checking only for now. 5839159ce93SDavide Italiano expect("("); 5849159ce93SDavide Italiano next(); 5859159ce93SDavide Italiano expect(")"); 5869159ce93SDavide Italiano } 5879159ce93SDavide Italiano 588717677afSRui Ueyama void ScriptParser::readOutputFormat() { 589f7c5fbb1SRui Ueyama // Error checking only for now. 590f7c5fbb1SRui Ueyama expect("("); 591f7c5fbb1SRui Ueyama next(); 5926836c618SDavide Italiano StringRef Tok = next(); 5936836c618SDavide Italiano if (Tok == ")") 5946836c618SDavide Italiano return; 595025d59b1SRui Ueyama if (Tok != ",") { 5965761042dSGeorge Rimar setError("unexpected token: " + Tok); 597025d59b1SRui Ueyama return; 598025d59b1SRui Ueyama } 5996836c618SDavide Italiano next(); 6006836c618SDavide Italiano expect(","); 6016836c618SDavide Italiano next(); 602f7c5fbb1SRui Ueyama expect(")"); 603f7c5fbb1SRui Ueyama } 604f7c5fbb1SRui Ueyama 605bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 606bbe38602SEugene Leviant expect("{"); 607bbe38602SEugene Leviant while (!Error && !skip("}")) { 608bbe38602SEugene Leviant StringRef Tok = next(); 609865bf863SEugene Leviant Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX}); 610bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 611bbe38602SEugene Leviant 612bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 613bbe38602SEugene Leviant do { 614bbe38602SEugene Leviant Tok = next(); 615bbe38602SEugene Leviant if (Tok == ";") 616bbe38602SEugene Leviant break; 617bbe38602SEugene Leviant if (Tok == "FILEHDR") 618bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 619bbe38602SEugene Leviant else if (Tok == "PHDRS") 620bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 621865bf863SEugene Leviant else if (Tok == "FLAGS") { 622865bf863SEugene Leviant expect("("); 623865bf863SEugene Leviant next().getAsInteger(0, PhdrCmd.Flags); 624865bf863SEugene Leviant expect(")"); 625865bf863SEugene Leviant } else 626bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 627bbe38602SEugene Leviant } while (!Error); 628bbe38602SEugene Leviant } 629bbe38602SEugene Leviant } 630bbe38602SEugene Leviant 631717677afSRui Ueyama void ScriptParser::readSearchDir() { 63268a39a65SDavide Italiano expect("("); 63306501920SRafael Espindola Config->SearchPaths.push_back(next()); 63468a39a65SDavide Italiano expect(")"); 63568a39a65SDavide Italiano } 63668a39a65SDavide Italiano 637717677afSRui Ueyama void ScriptParser::readSections() { 63807320e40SRui Ueyama Opt.DoLayout = true; 6398e3b38abSDenis Protivensky expect("{"); 640652852c5SGeorge Rimar while (!Error && !skip("}")) { 641113cdec9SRui Ueyama StringRef Tok = next(); 642113cdec9SRui Ueyama if (peek() == "=") { 643113cdec9SRui Ueyama readAssignment(Tok); 644113cdec9SRui Ueyama expect(";"); 645113cdec9SRui Ueyama } else if (Tok == "PROVIDE") { 646a31c91b1SEugene Leviant readProvide(false); 647708019c4SRui Ueyama } else if (Tok == "PROVIDE_HIDDEN") { 648a31c91b1SEugene Leviant readProvide(true); 649708019c4SRui Ueyama } else { 650eda81a1bSEugene Leviant readOutputSectionDescription(Tok); 6518e3b38abSDenis Protivensky } 652652852c5SGeorge Rimar } 653708019c4SRui Ueyama } 6548e3b38abSDenis Protivensky 655708019c4SRui Ueyama static int precedence(StringRef Op) { 656708019c4SRui Ueyama return StringSwitch<int>(Op) 657708019c4SRui Ueyama .Case("*", 4) 658708019c4SRui Ueyama .Case("/", 4) 659708019c4SRui Ueyama .Case("+", 3) 660708019c4SRui Ueyama .Case("-", 3) 661708019c4SRui Ueyama .Case("<", 2) 662708019c4SRui Ueyama .Case(">", 2) 663708019c4SRui Ueyama .Case(">=", 2) 664708019c4SRui Ueyama .Case("<=", 2) 665708019c4SRui Ueyama .Case("==", 2) 666708019c4SRui Ueyama .Case("!=", 2) 667708019c4SRui Ueyama .Case("&", 1) 668708019c4SRui Ueyama .Default(-1); 669708019c4SRui Ueyama } 670708019c4SRui Ueyama 671e7282797SDavide Italiano std::unique_ptr<InputSectionDescription> ScriptParser::readFilePattern() { 6720ed42b0cSDavide Italiano expect("*"); 6730ed42b0cSDavide Italiano expect("("); 674e7282797SDavide Italiano 675e7282797SDavide Italiano auto InCmd = llvm::make_unique<InputSectionDescription>(); 676e7282797SDavide Italiano 677e7282797SDavide Italiano if (skip("EXCLUDE_FILE")) { 678e7282797SDavide Italiano expect("("); 679e7282797SDavide Italiano while (!Error && !skip(")")) 680e7282797SDavide Italiano InCmd->ExcludedFiles.push_back(next()); 681e7282797SDavide Italiano InCmd->Patterns.push_back(next()); 682e7282797SDavide Italiano expect(")"); 683e7282797SDavide Italiano } else { 684e7282797SDavide Italiano while (!Error && !skip(")")) 6850ed42b0cSDavide Italiano InCmd->Patterns.push_back(next()); 6860ed42b0cSDavide Italiano } 687e7282797SDavide Italiano return InCmd; 688e7282797SDavide Italiano } 689e7282797SDavide Italiano 690e7282797SDavide Italiano void ScriptParser::readKeep(OutputSectionCommand *Cmd) { 691e7282797SDavide Italiano expect("("); 692e7282797SDavide Italiano std::unique_ptr<InputSectionDescription> InCmd = readFilePattern(); 693e7282797SDavide Italiano Opt.KeptSections.insert(Opt.KeptSections.end(), InCmd->Patterns.begin(), 694e7282797SDavide Italiano InCmd->Patterns.end()); 695e7282797SDavide Italiano Cmd->Commands.push_back(std::move(InCmd)); 6960ed42b0cSDavide Italiano expect(")"); 6970ed42b0cSDavide Italiano } 6980ed42b0cSDavide Italiano 699630c6179SGeorge Rimar void ScriptParser::readAlign(OutputSectionCommand *Cmd) { 700630c6179SGeorge Rimar expect("("); 701630c6179SGeorge Rimar Cmd->AlignExpr = readExpr(); 702630c6179SGeorge Rimar expect(")"); 703630c6179SGeorge Rimar } 704630c6179SGeorge Rimar 705*03fc010eSGeorge Rimar void ScriptParser::readSort() { 706*03fc010eSGeorge Rimar expect("("); 707*03fc010eSGeorge Rimar expect("CONSTRUCTORS"); 708*03fc010eSGeorge Rimar expect(")"); 709*03fc010eSGeorge Rimar } 710*03fc010eSGeorge Rimar 711eda81a1bSEugene Leviant void ScriptParser::readOutputSectionDescription(StringRef OutSec) { 712076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 713076fe157SGeorge Rimar Opt.Commands.emplace_back(Cmd); 71458e5c4dcSGeorge Rimar 71558e5c4dcSGeorge Rimar // Read an address expression. 71658e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 71758e5c4dcSGeorge Rimar if (peek() != ":") 71858e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 71958e5c4dcSGeorge Rimar 7208e3b38abSDenis Protivensky expect(":"); 721246f681eSDavide Italiano 722630c6179SGeorge Rimar if (skip("ALIGN")) 723630c6179SGeorge Rimar readAlign(Cmd); 724630c6179SGeorge Rimar 725246f681eSDavide Italiano // Parse constraints. 726246f681eSDavide Italiano if (skip("ONLY_IF_RO")) 727efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 728246f681eSDavide Italiano if (skip("ONLY_IF_RW")) 729efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 7308e3b38abSDenis Protivensky expect("{"); 7318ec77e64SRui Ueyama 732025d59b1SRui Ueyama while (!Error && !skip("}")) { 733481c2ce6SGeorge Rimar StringRef Tok = next(); 734481c2ce6SGeorge Rimar if (Tok == "*") { 735eea3114fSGeorge Rimar auto *InCmd = new InputSectionDescription(); 736eea3114fSGeorge Rimar Cmd->Commands.emplace_back(InCmd); 7378ec77e64SRui Ueyama expect("("); 7388ec77e64SRui Ueyama while (!Error && !skip(")")) 739eea3114fSGeorge Rimar InCmd->Patterns.push_back(next()); 740481c2ce6SGeorge Rimar } else if (Tok == "KEEP") { 7410ed42b0cSDavide Italiano readKeep(Cmd); 742054a6796SDavide Italiano } else if (Tok == "PROVIDE") { 743054a6796SDavide Italiano readProvide(false); 744054a6796SDavide Italiano } else if (Tok == "PROVIDE_HIDDEN") { 745054a6796SDavide Italiano readProvide(true); 746*03fc010eSGeorge Rimar } else if (Tok == "SORT") { 747*03fc010eSGeorge Rimar readSort(); 748481c2ce6SGeorge Rimar } else { 749777f9630SGeorge Rimar setError("unknown command " + Tok); 750481c2ce6SGeorge Rimar } 7518e3b38abSDenis Protivensky } 752076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 7538ec77e64SRui Ueyama 754e2ee72b5SGeorge Rimar StringRef Tok = peek(); 755e2ee72b5SGeorge Rimar if (Tok.startswith("=")) { 756e2ee72b5SGeorge Rimar if (!Tok.startswith("=0x")) { 7573ed2f069SRui Ueyama setError("filler should be a hexadecimal value"); 758e2ee72b5SGeorge Rimar return; 759e2ee72b5SGeorge Rimar } 7603e808976SRui Ueyama Tok = Tok.substr(3); 761f6c3ccefSGeorge Rimar Cmd->Filler = parseHex(Tok); 762e2ee72b5SGeorge Rimar next(); 763e2ee72b5SGeorge Rimar } 7648e3b38abSDenis Protivensky } 7658e3b38abSDenis Protivensky 766a31c91b1SEugene Leviant void ScriptParser::readProvide(bool Hidden) { 767a31c91b1SEugene Leviant expect("("); 768113cdec9SRui Ueyama if (SymbolAssignment *Assignment = readAssignment(next())) { 769a31c91b1SEugene Leviant Assignment->Provide = true; 770a31c91b1SEugene Leviant Assignment->Hidden = Hidden; 771a31c91b1SEugene Leviant } 772a31c91b1SEugene Leviant expect(")"); 773a31c91b1SEugene Leviant expect(";"); 774eda81a1bSEugene Leviant } 775eda81a1bSEugene Leviant 776113cdec9SRui Ueyama SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 777a31c91b1SEugene Leviant expect("="); 778708019c4SRui Ueyama Expr E = readExpr(); 779113cdec9SRui Ueyama auto *Cmd = new SymbolAssignment(Name, E); 780113cdec9SRui Ueyama Opt.Commands.emplace_back(Cmd); 781113cdec9SRui Ueyama return Cmd; 782a31c91b1SEugene Leviant } 783a31c91b1SEugene Leviant 784708019c4SRui Ueyama // This is an operator-precedence parser to parse a linker 785708019c4SRui Ueyama // script expression. 786708019c4SRui Ueyama Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 787a31c91b1SEugene Leviant 788a9c5a528SGeorge Rimar static uint64_t getSymbolValue(StringRef S) { 789a9c5a528SGeorge Rimar switch (Config->EKind) { 790a9c5a528SGeorge Rimar case ELF32LEKind: 791a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF32LE>::X->find(S)) 792a9c5a528SGeorge Rimar return B->getVA<ELF32LE>(); 793a9c5a528SGeorge Rimar break; 794a9c5a528SGeorge Rimar case ELF32BEKind: 795a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF32BE>::X->find(S)) 796a9c5a528SGeorge Rimar return B->getVA<ELF32BE>(); 797a9c5a528SGeorge Rimar break; 798a9c5a528SGeorge Rimar case ELF64LEKind: 799a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF64LE>::X->find(S)) 800a9c5a528SGeorge Rimar return B->getVA<ELF64LE>(); 801a9c5a528SGeorge Rimar break; 802a9c5a528SGeorge Rimar case ELF64BEKind: 803a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF64BE>::X->find(S)) 804a9c5a528SGeorge Rimar return B->getVA<ELF64BE>(); 805a9c5a528SGeorge Rimar break; 8066930a6dcSGeorge Rimar default: 807b567b628SGeorge Rimar llvm_unreachable("unsupported target"); 808a9c5a528SGeorge Rimar } 809a9c5a528SGeorge Rimar error("symbol not found: " + S); 810a9c5a528SGeorge Rimar return 0; 811a9c5a528SGeorge Rimar } 812a9c5a528SGeorge Rimar 813708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 814708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 815708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 816708019c4SRui Ueyama while (!atEOF() && !Error) { 817708019c4SRui Ueyama // Read an operator and an expression. 818708019c4SRui Ueyama StringRef Op1 = peek(); 819708019c4SRui Ueyama if (Op1 == "?") 820708019c4SRui Ueyama return readTernary(Lhs); 821708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 822a31c91b1SEugene Leviant break; 823a31c91b1SEugene Leviant next(); 824708019c4SRui Ueyama Expr Rhs = readPrimary(); 825708019c4SRui Ueyama 826708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 827708019c4SRui Ueyama // next operator has greater precedence than the previous one. 828708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 829708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 830708019c4SRui Ueyama while (!atEOF()) { 831708019c4SRui Ueyama StringRef Op2 = peek(); 832708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 833eda81a1bSEugene Leviant break; 834708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 835eda81a1bSEugene Leviant } 836708019c4SRui Ueyama 837708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 838708019c4SRui Ueyama } 839708019c4SRui Ueyama return Lhs; 840708019c4SRui Ueyama } 841708019c4SRui Ueyama 842708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 843708019c4SRui Ueyama if (S == "COMMONPAGESIZE" || S == "MAXPAGESIZE") 844708019c4SRui Ueyama return Target->PageSize; 845708019c4SRui Ueyama error("unknown constant: " + S); 846708019c4SRui Ueyama return 0; 847708019c4SRui Ueyama } 848708019c4SRui Ueyama 849708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 850708019c4SRui Ueyama StringRef Tok = next(); 851708019c4SRui Ueyama 852708019c4SRui Ueyama if (Tok == ".") 853708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 854708019c4SRui Ueyama 855708019c4SRui Ueyama if (Tok == "(") { 856708019c4SRui Ueyama Expr E = readExpr(); 857708019c4SRui Ueyama expect(")"); 858708019c4SRui Ueyama return E; 859708019c4SRui Ueyama } 860708019c4SRui Ueyama 861708019c4SRui Ueyama // Built-in functions are parsed here. 862708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 863708019c4SRui Ueyama if (Tok == "ALIGN") { 864708019c4SRui Ueyama expect("("); 865708019c4SRui Ueyama Expr E = readExpr(); 866708019c4SRui Ueyama expect(")"); 867708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 868708019c4SRui Ueyama } 869708019c4SRui Ueyama if (Tok == "CONSTANT") { 870708019c4SRui Ueyama expect("("); 871708019c4SRui Ueyama StringRef Tok = next(); 872708019c4SRui Ueyama expect(")"); 873708019c4SRui Ueyama return [=](uint64_t Dot) { return getConstant(Tok); }; 874708019c4SRui Ueyama } 875708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 876708019c4SRui Ueyama expect("("); 877708019c4SRui Ueyama Expr E = readExpr(); 878708019c4SRui Ueyama expect(","); 879708019c4SRui Ueyama readExpr(); 880708019c4SRui Ueyama expect(")"); 881f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 882708019c4SRui Ueyama } 883708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 884708019c4SRui Ueyama expect("("); 885708019c4SRui Ueyama expect("."); 886708019c4SRui Ueyama expect(")"); 887708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 888708019c4SRui Ueyama } 889276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 890276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 891276b4e64SGeorge Rimar // the next page boundary for simplicity. 892276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 893276b4e64SGeorge Rimar expect("("); 894276b4e64SGeorge Rimar next(); 895276b4e64SGeorge Rimar expect(","); 896276b4e64SGeorge Rimar readExpr(); 897276b4e64SGeorge Rimar expect(")"); 898276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 899276b4e64SGeorge Rimar } 900708019c4SRui Ueyama 901a9c5a528SGeorge Rimar // Parse a symbol name or a number literal. 902708019c4SRui Ueyama uint64_t V = 0; 903a9c5a528SGeorge Rimar if (Tok.getAsInteger(0, V)) { 904a9c5a528SGeorge Rimar if (!isValidCIdentifier(Tok)) 905708019c4SRui Ueyama setError("malformed number: " + Tok); 906a9c5a528SGeorge Rimar return [=](uint64_t Dot) { return getSymbolValue(Tok); }; 907a9c5a528SGeorge Rimar } 908708019c4SRui Ueyama return [=](uint64_t Dot) { return V; }; 909708019c4SRui Ueyama } 910708019c4SRui Ueyama 911708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 912708019c4SRui Ueyama next(); 913708019c4SRui Ueyama Expr L = readExpr(); 914708019c4SRui Ueyama expect(":"); 915708019c4SRui Ueyama Expr R = readExpr(); 916708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 917708019c4SRui Ueyama } 918708019c4SRui Ueyama 919708019c4SRui Ueyama Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) { 920708019c4SRui Ueyama if (Op == "*") 921708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 922708019c4SRui Ueyama if (Op == "/") { 923708019c4SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 924708019c4SRui Ueyama uint64_t RHS = R(Dot); 925708019c4SRui Ueyama if (RHS == 0) { 926708019c4SRui Ueyama error("division by zero"); 927708019c4SRui Ueyama return 0; 928708019c4SRui Ueyama } 929708019c4SRui Ueyama return L(Dot) / RHS; 930708019c4SRui Ueyama }; 931708019c4SRui Ueyama } 932708019c4SRui Ueyama if (Op == "+") 933708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) + R(Dot); }; 934708019c4SRui Ueyama if (Op == "-") 935708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 936708019c4SRui Ueyama if (Op == "<") 937708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 938708019c4SRui Ueyama if (Op == ">") 939708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 940708019c4SRui Ueyama if (Op == ">=") 941708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 942708019c4SRui Ueyama if (Op == "<=") 943708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 944708019c4SRui Ueyama if (Op == "==") 945708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 946708019c4SRui Ueyama if (Op == "!=") 947708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 948708019c4SRui Ueyama if (Op == "&") 949708019c4SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 950708019c4SRui Ueyama llvm_unreachable("invalid operator"); 951eda81a1bSEugene Leviant } 952eda81a1bSEugene Leviant 953bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 954bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 955bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 956bbe38602SEugene Leviant StringRef Tok = next(); 957bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 958bbe38602SEugene Leviant if (Tok.empty()) { 959bbe38602SEugene Leviant setError("section header name is empty"); 960bbe38602SEugene Leviant break; 961bbe38602SEugene Leviant } 962bbe38602SEugene Leviant Phdrs.push_back(Tok); 963bbe38602SEugene Leviant } 964bbe38602SEugene Leviant return Phdrs; 965bbe38602SEugene Leviant } 966bbe38602SEugene Leviant 967bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 968bbe38602SEugene Leviant StringRef Tok = next(); 969b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 970b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 971b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 972b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 973b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 974b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 975b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 976b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 977b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 978b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 979b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 980b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 981b0f6c590SRui Ueyama .Default(-1); 982bbe38602SEugene Leviant 983b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 984b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 985b0f6c590SRui Ueyama return PT_NULL; 986b0f6c590SRui Ueyama } 987b0f6c590SRui Ueyama return Ret; 988bbe38602SEugene Leviant } 989bbe38602SEugene Leviant 99016b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 99116b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 99216b0cc9eSSimon Atanasyan return false; 99316b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 99416b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 99516b0cc9eSSimon Atanasyan return true; 99616b0cc9eSSimon Atanasyan return false; 99716b0cc9eSSimon Atanasyan } 99816b0cc9eSSimon Atanasyan 99907320e40SRui Ueyama // Entry point. 100007320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 100116b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 100207320e40SRui Ueyama ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run(); 1003f7c5fbb1SRui Ueyama } 10041ebc8ed7SRui Ueyama 100507320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 100607320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 100707320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 100807320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1009