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 46ceabe80eSEugene Leviant template <class ELFT> 471602421cSRui Ueyama static void addRegular(SymbolAssignment *Cmd) { 481602421cSRui Ueyama Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, STB_GLOBAL, STV_DEFAULT); 491602421cSRui Ueyama Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; 501602421cSRui Ueyama Cmd->Sym = Sym->body(); 51ceabe80eSEugene Leviant } 52ceabe80eSEugene Leviant 530c70d3ccSRui Ueyama template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) { 54e1937bb5SGeorge Rimar Symbol *Sym = Symtab<ELFT>::X->addSynthetic( 55e1937bb5SGeorge Rimar Cmd->Name, nullptr, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT); 561602421cSRui Ueyama Cmd->Sym = Sym->body(); 57ceabe80eSEugene Leviant } 58ceabe80eSEugene Leviant 591602421cSRui Ueyama // If a symbol was in PROVIDE(), we need to define it only when 601602421cSRui Ueyama // it is an undefined symbol. 611602421cSRui Ueyama template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) { 621602421cSRui Ueyama if (Cmd->Name == ".") 63ceabe80eSEugene Leviant return false; 641602421cSRui Ueyama if (!Cmd->Provide) 65ceabe80eSEugene Leviant return true; 661602421cSRui Ueyama SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 671602421cSRui Ueyama return B && B->isUndefined(); 68ceabe80eSEugene Leviant } 69ceabe80eSEugene Leviant 70076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 71076fe157SGeorge Rimar return C->Kind == AssignmentKind; 72076fe157SGeorge Rimar } 73076fe157SGeorge Rimar 74076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 75076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 76076fe157SGeorge Rimar } 77076fe157SGeorge Rimar 78eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 79eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 80eea3114fSGeorge Rimar } 81eea3114fSGeorge Rimar 82eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 83eefa758eSGeorge Rimar return C->Kind == AssertKind; 84eefa758eSGeorge Rimar } 85eefa758eSGeorge Rimar 8636a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) { 87eea3114fSGeorge Rimar return !S || !S->Live; 88717677afSRui Ueyama } 89717677afSRui Ueyama 90f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::LinkerScript() {} 91f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::~LinkerScript() {} 92f34d0e08SRui Ueyama 9307320e40SRui Ueyama template <class ELFT> 9407320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 95c91930a1SGeorge Rimar for (Regex *Re : Opt.KeptSections) 96c91930a1SGeorge Rimar if (Re->match(S->getSectionName())) 97eea3114fSGeorge Rimar return true; 98eea3114fSGeorge Rimar return false; 99eea3114fSGeorge Rimar } 100eea3114fSGeorge Rimar 1010659800eSGeorge Rimar static bool fileMatches(const InputSectionDescription *Desc, 1020659800eSGeorge Rimar StringRef Filename) { 103c91930a1SGeorge Rimar return const_cast<Regex &>(Desc->FileRe).match(Filename) && 104c91930a1SGeorge Rimar !const_cast<Regex &>(Desc->ExcludedFileRe).match(Filename); 1050659800eSGeorge Rimar } 1060659800eSGeorge Rimar 1076b274810SRui Ueyama // Returns input sections filtered by given glob patterns. 1086b274810SRui Ueyama template <class ELFT> 1096b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *> 110ad10c3d8SRui Ueyama LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) { 111c91930a1SGeorge Rimar const Regex &Re = I->SectionRe; 1126b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 1136b274810SRui Ueyama for (const std::unique_ptr<ObjectFile<ELFT>> &F : 1140659800eSGeorge Rimar Symtab<ELFT>::X->getObjectFiles()) { 1150659800eSGeorge Rimar if (fileMatches(I, sys::path::filename(F->getName()))) 1166b274810SRui Ueyama for (InputSectionBase<ELFT> *S : F->getSections()) 1170659800eSGeorge Rimar if (!isDiscarded(S) && !S->OutSec && 118c91930a1SGeorge Rimar const_cast<Regex &>(Re).match(S->getSectionName())) 1196b274810SRui Ueyama Ret.push_back(S); 1200659800eSGeorge Rimar } 1213e6b0277SEugene Leviant 122c91930a1SGeorge Rimar if (const_cast<Regex &>(Re).match("COMMON")) 123ad10c3d8SRui Ueyama Ret.push_back(CommonInputSection<ELFT>::X); 1246b274810SRui Ueyama return Ret; 1256b274810SRui Ueyama } 1266b274810SRui Ueyama 127ceabe80eSEugene Leviant template <class ELFT> 128742c3836SRui Ueyama static bool compareName(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) { 129742c3836SRui Ueyama return A->getSectionName() < B->getSectionName(); 1300702c4e8SGeorge Rimar } 131742c3836SRui Ueyama 132742c3836SRui Ueyama template <class ELFT> 133742c3836SRui Ueyama static bool compareAlignment(InputSectionBase<ELFT> *A, 134742c3836SRui Ueyama InputSectionBase<ELFT> *B) { 135742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 136742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 137742c3836SRui Ueyama // This is compatible with GNU. 138742c3836SRui Ueyama return A->Alignment > B->Alignment; 139742c3836SRui Ueyama } 140742c3836SRui Ueyama 141742c3836SRui Ueyama template <class ELFT> 142742c3836SRui Ueyama static std::function<bool(InputSectionBase<ELFT> *, InputSectionBase<ELFT> *)> 143742c3836SRui Ueyama getComparator(SortKind K) { 144742c3836SRui Ueyama if (K == SortByName) 145742c3836SRui Ueyama return compareName<ELFT>; 146742c3836SRui Ueyama return compareAlignment<ELFT>; 147742c3836SRui Ueyama } 1480702c4e8SGeorge Rimar 1490702c4e8SGeorge Rimar template <class ELFT> 15048c3f1ceSRui Ueyama void LinkerScript<ELFT>::discard(OutputSectionCommand &Cmd) { 15148c3f1ceSRui Ueyama for (const std::unique_ptr<BaseCommand> &Base : Cmd.Commands) { 15248c3f1ceSRui Ueyama if (auto *Cmd = dyn_cast<InputSectionDescription>(Base.get())) { 15348c3f1ceSRui Ueyama for (InputSectionBase<ELFT> *S : getInputSections(Cmd)) { 15448c3f1ceSRui Ueyama S->Live = false; 15548c3f1ceSRui Ueyama reportDiscarded(S); 15648c3f1ceSRui Ueyama } 15748c3f1ceSRui Ueyama } 15848c3f1ceSRui Ueyama } 15948c3f1ceSRui Ueyama } 16048c3f1ceSRui Ueyama 1618f66df92SGeorge Rimar static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) { 1628f66df92SGeorge Rimar bool RO = (Kind == ConstraintKind::ReadOnly); 1638f66df92SGeorge Rimar bool RW = (Kind == ConstraintKind::ReadWrite); 1648f66df92SGeorge Rimar bool Writable = Flags & SHF_WRITE; 1658f66df92SGeorge Rimar return !((RO && Writable) || (RW && !Writable)); 1668f66df92SGeorge Rimar } 1678f66df92SGeorge Rimar 16848c3f1ceSRui Ueyama template <class ELFT> 16906ae6836SGeorge Rimar static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 17006ae6836SGeorge Rimar ConstraintKind Kind) { 1718f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 1728f66df92SGeorge Rimar return true; 1738f66df92SGeorge Rimar return llvm::all_of(Sections, [=](InputSectionBase<ELFT> *Sec) { 1748f66df92SGeorge Rimar return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind); 17506ae6836SGeorge Rimar }); 17606ae6836SGeorge Rimar } 17706ae6836SGeorge Rimar 17806ae6836SGeorge Rimar template <class ELFT> 1790b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 18006ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 1810b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 18297403d15SEugene Leviant DenseSet<InputSectionBase<ELFT> *> SectionIndex; 183e7f912cdSRui Ueyama 18406ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 18506ae6836SGeorge Rimar if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) { 18606ae6836SGeorge Rimar if (shouldDefine<ELFT>(OutCmd)) 18706ae6836SGeorge Rimar addSynthetic<ELFT>(OutCmd); 18897403d15SEugene Leviant OutCmd->GoesAfter = Ret.empty() ? nullptr : Ret.back(); 1890b9ce6a4SRui Ueyama continue; 1900b9ce6a4SRui Ueyama } 1910b9ce6a4SRui Ueyama 1920b9ce6a4SRui Ueyama auto *Cmd = cast<InputSectionDescription>(Base.get()); 1930b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> V = getInputSections(Cmd); 19406ae6836SGeorge Rimar if (!matchConstraints<ELFT>(V, OutCmd.Constraint)) 19506ae6836SGeorge Rimar continue; 1960b9ce6a4SRui Ueyama if (Cmd->SortInner) 1970b9ce6a4SRui Ueyama std::stable_sort(V.begin(), V.end(), getComparator<ELFT>(Cmd->SortInner)); 1980b9ce6a4SRui Ueyama if (Cmd->SortOuter) 1990b9ce6a4SRui Ueyama std::stable_sort(V.begin(), V.end(), getComparator<ELFT>(Cmd->SortOuter)); 20097403d15SEugene Leviant 20197403d15SEugene Leviant // Add all input sections corresponding to rule 'Cmd' to 20297403d15SEugene Leviant // resulting vector. We do not add duplicate input sections. 20397403d15SEugene Leviant for (InputSectionBase<ELFT> *S : V) 20497403d15SEugene Leviant if (SectionIndex.insert(S).second) 20597403d15SEugene Leviant Ret.push_back(S); 2060b9ce6a4SRui Ueyama } 2070b9ce6a4SRui Ueyama return Ret; 2080b9ce6a4SRui Ueyama } 2090b9ce6a4SRui Ueyama 2100b9ce6a4SRui Ueyama template <class ELFT> 211e5d3ca50SPetr Hosek void LinkerScript<ELFT>::createAssignments() { 212e5d3ca50SPetr Hosek for (const std::unique_ptr<SymbolAssignment> &Cmd : Opt.Assignments) { 213e5d3ca50SPetr Hosek if (shouldDefine<ELFT>(Cmd.get())) 214e5d3ca50SPetr Hosek addRegular<ELFT>(Cmd.get()); 215e5d3ca50SPetr Hosek if (Cmd->Sym) 216e5d3ca50SPetr Hosek cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0); 217e5d3ca50SPetr Hosek } 218e5d3ca50SPetr Hosek } 219e5d3ca50SPetr Hosek 220e5d3ca50SPetr Hosek template <class ELFT> 2210b9ce6a4SRui Ueyama void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 22248c3f1ceSRui Ueyama for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) { 2232ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 2242ab5f73dSRui Ueyama if (shouldDefine<ELFT>(Cmd)) 2252ab5f73dSRui Ueyama addRegular<ELFT>(Cmd); 2262ab5f73dSRui Ueyama continue; 2272ab5f73dSRui Ueyama } 2282ab5f73dSRui Ueyama 229ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 23048c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 23148c3f1ceSRui Ueyama discard(*Cmd); 23248c3f1ceSRui Ueyama continue; 23348c3f1ceSRui Ueyama } 2340b9ce6a4SRui Ueyama 2350b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 23697403d15SEugene Leviant if (V.empty()) 2370b9ce6a4SRui Ueyama continue; 2380b9ce6a4SRui Ueyama 2390b9ce6a4SRui Ueyama OutputSectionBase<ELFT> *OutSec; 2400b9ce6a4SRui Ueyama bool IsNew; 24197403d15SEugene Leviant std::tie(OutSec, IsNew) = Factory.create(V.front(), Cmd->Name); 2420b9ce6a4SRui Ueyama if (IsNew) 2430b9ce6a4SRui Ueyama OutputSections->push_back(OutSec); 244db24d9c3SGeorge Rimar 245db24d9c3SGeorge Rimar uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0; 246db24d9c3SGeorge Rimar for (InputSectionBase<ELFT> *Sec : V) { 247db24d9c3SGeorge Rimar if (Subalign) 248db24d9c3SGeorge Rimar Sec->Alignment = Subalign; 2490b9ce6a4SRui Ueyama OutSec->addSection(Sec); 250eea3114fSGeorge Rimar } 25148c3f1ceSRui Ueyama } 252db24d9c3SGeorge Rimar } 253e63d81bdSEugene Leviant 2540b9ce6a4SRui Ueyama // Add orphan sections. 2556b274810SRui Ueyama for (const std::unique_ptr<ObjectFile<ELFT>> &F : 2560b9ce6a4SRui Ueyama Symtab<ELFT>::X->getObjectFiles()) { 2570b9ce6a4SRui Ueyama for (InputSectionBase<ELFT> *S : F->getSections()) { 2582ab5f73dSRui Ueyama if (isDiscarded(S) || S->OutSec) 2592ab5f73dSRui Ueyama continue; 2600b9ce6a4SRui Ueyama OutputSectionBase<ELFT> *OutSec; 2610b9ce6a4SRui Ueyama bool IsNew; 2620b9ce6a4SRui Ueyama std::tie(OutSec, IsNew) = Factory.create(S, getOutputSectionName(S)); 2630b9ce6a4SRui Ueyama if (IsNew) 2640b9ce6a4SRui Ueyama OutputSections->push_back(OutSec); 2650b9ce6a4SRui Ueyama OutSec->addSection(S); 2660b9ce6a4SRui Ueyama } 2670b9ce6a4SRui Ueyama } 268e63d81bdSEugene Leviant } 269e63d81bdSEugene Leviant 27020889c51SEugene Leviant // Linker script may define start and end symbols for special section types, 27120889c51SEugene Leviant // like .got, .eh_frame_hdr, .eh_frame and others. Those sections are not a list 27220889c51SEugene Leviant // of regular input input sections, therefore our way of defining symbols for 27320889c51SEugene Leviant // regular sections will not work. The approach we use for special section types 27420889c51SEugene Leviant // is not perfect - it handles only start and end symbols. 27520889c51SEugene Leviant template <class ELFT> 27620889c51SEugene Leviant void addStartEndSymbols(OutputSectionCommand *Cmd, 27720889c51SEugene Leviant OutputSectionBase<ELFT> *Sec) { 27820889c51SEugene Leviant bool Start = true; 27920889c51SEugene Leviant BaseCommand *PrevCmd = nullptr; 28020889c51SEugene Leviant 28120889c51SEugene Leviant for (std::unique_ptr<BaseCommand> &Base : Cmd->Commands) { 28220889c51SEugene Leviant if (auto *AssignCmd = dyn_cast<SymbolAssignment>(Base.get())) { 28320889c51SEugene Leviant if (auto *Sym = cast_or_null<DefinedSynthetic<ELFT>>(AssignCmd->Sym)) { 28420889c51SEugene Leviant Sym->Section = Sec; 28520889c51SEugene Leviant Sym->Value = 28620889c51SEugene Leviant AssignCmd->Expression(Sec->getVA() + (Start ? 0 : Sec->getSize())) - 28720889c51SEugene Leviant Sec->getVA(); 28820889c51SEugene Leviant } 28920889c51SEugene Leviant } else { 29020889c51SEugene Leviant if (!Start && isa<SymbolAssignment>(PrevCmd)) 29120889c51SEugene Leviant error("section '" + Sec->getName() + 29220889c51SEugene Leviant "' supports only start and end symbols"); 29320889c51SEugene Leviant Start = false; 29420889c51SEugene Leviant } 29520889c51SEugene Leviant PrevCmd = Base.get(); 29620889c51SEugene Leviant } 29720889c51SEugene Leviant } 29820889c51SEugene Leviant 29920889c51SEugene Leviant template <class ELFT> 30020889c51SEugene Leviant void assignOffsets(OutputSectionCommand *Cmd, OutputSectionBase<ELFT> *Sec) { 301ceabe80eSEugene Leviant auto *OutSec = dyn_cast<OutputSection<ELFT>>(Sec); 3022de509c3SRui Ueyama if (!OutSec) { 3032de509c3SRui Ueyama Sec->assignOffsets(); 30420889c51SEugene Leviant // This section is not regular output section. However linker script may 30520889c51SEugene Leviant // have defined start/end symbols for it. This case is handled below. 30620889c51SEugene Leviant addStartEndSymbols(Cmd, Sec); 307ceabe80eSEugene Leviant return; 3082de509c3SRui Ueyama } 309ceabe80eSEugene Leviant typedef typename ELFT::uint uintX_t; 310ceabe80eSEugene Leviant uintX_t Off = 0; 31197403d15SEugene Leviant auto ItCmd = Cmd->Commands.begin(); 312ceabe80eSEugene Leviant 31397403d15SEugene Leviant // Assigns values to all symbols following the given 31497403d15SEugene Leviant // input section 'D' in output section 'Sec'. When symbols 31597403d15SEugene Leviant // are in the beginning of output section the value of 'D' 31697403d15SEugene Leviant // is nullptr. 31797403d15SEugene Leviant auto AssignSuccessors = [&](InputSectionData *D) { 31897403d15SEugene Leviant for (; ItCmd != Cmd->Commands.end(); ++ItCmd) { 31997403d15SEugene Leviant auto *AssignCmd = dyn_cast<SymbolAssignment>(ItCmd->get()); 32097403d15SEugene Leviant if (!AssignCmd) 32197403d15SEugene Leviant continue; 32297403d15SEugene Leviant if (D != AssignCmd->GoesAfter) 32397403d15SEugene Leviant break; 32497403d15SEugene Leviant 32597403d15SEugene Leviant uintX_t Value = AssignCmd->Expression(Sec->getVA() + Off) - Sec->getVA(); 32697403d15SEugene Leviant if (AssignCmd->Name == ".") { 32797403d15SEugene Leviant // Update to location counter means update to section size. 328ceabe80eSEugene Leviant Off = Value; 32997403d15SEugene Leviant Sec->setSize(Off); 33097403d15SEugene Leviant continue; 33197403d15SEugene Leviant } 33297403d15SEugene Leviant 33397403d15SEugene Leviant if (DefinedSynthetic<ELFT> *Sym = 33497403d15SEugene Leviant cast_or_null<DefinedSynthetic<ELFT>>(AssignCmd->Sym)) { 3350c70d3ccSRui Ueyama Sym->Section = OutSec; 3360c70d3ccSRui Ueyama Sym->Value = Value; 3370c70d3ccSRui Ueyama } 33897403d15SEugene Leviant } 33997403d15SEugene Leviant }; 34097403d15SEugene Leviant 34197403d15SEugene Leviant AssignSuccessors(nullptr); 34297403d15SEugene Leviant for (InputSection<ELFT> *I : OutSec->Sections) { 343ceabe80eSEugene Leviant Off = alignTo(Off, I->Alignment); 344ceabe80eSEugene Leviant I->OutSecOff = Off; 345ceabe80eSEugene Leviant Off += I->getSize(); 346ceabe80eSEugene Leviant // Update section size inside for-loop, so that SIZEOF 347ceabe80eSEugene Leviant // works correctly in the case below: 348ceabe80eSEugene Leviant // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 349ceabe80eSEugene Leviant Sec->setSize(Off); 35097403d15SEugene Leviant // Add symbols following current input section. 35197403d15SEugene Leviant AssignSuccessors(I); 352ceabe80eSEugene Leviant } 353ceabe80eSEugene Leviant } 354ceabe80eSEugene Leviant 3558f66df92SGeorge Rimar template <class ELFT> 3568f66df92SGeorge Rimar static OutputSectionBase<ELFT> * 3578f66df92SGeorge Rimar findSection(OutputSectionCommand &Cmd, 3588f66df92SGeorge Rimar ArrayRef<OutputSectionBase<ELFT> *> Sections) { 3598f66df92SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : Sections) { 3608f66df92SGeorge Rimar if (Sec->getName() != Cmd.Name) 3618f66df92SGeorge Rimar continue; 3628f66df92SGeorge Rimar if (checkConstraint(Sec->getFlags(), Cmd.Constraint)) 3638f66df92SGeorge Rimar return Sec; 3648f66df92SGeorge Rimar } 3658f66df92SGeorge Rimar return nullptr; 3668f66df92SGeorge Rimar } 3678f66df92SGeorge Rimar 368a4b41dcaSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::assignAddresses() { 369652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 3707c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 3717c18c28cSRui Ueyama // We place orphan sections at end of file. 3727c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 373652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 374e5cc668eSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 375652852c5SGeorge Rimar StringRef Name = Sec->getName(); 376c3e2a4b0SRui Ueyama if (getSectionIndex(Name) == INT_MAX) 377076fe157SGeorge Rimar Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name)); 378652852c5SGeorge Rimar } 379652852c5SGeorge Rimar 3807c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 3814f7500bfSRui Ueyama Dot = getHeaderSize(); 382467c4d55SEugene Leviant uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 383652852c5SGeorge Rimar uintX_t ThreadBssOffset = 0; 384652852c5SGeorge Rimar 385076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 386076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 3878d083e6aSRui Ueyama if (Cmd->Name == ".") { 3888d083e6aSRui Ueyama Dot = Cmd->Expression(Dot); 3898d083e6aSRui Ueyama } else if (Cmd->Sym) { 3908d083e6aSRui Ueyama cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot); 3918d083e6aSRui Ueyama } 39205ef4cffSRui Ueyama continue; 393652852c5SGeorge Rimar } 394652852c5SGeorge Rimar 395eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 396eefa758eSGeorge Rimar Cmd->Expression(Dot); 397eefa758eSGeorge Rimar continue; 398eefa758eSGeorge Rimar } 399eefa758eSGeorge Rimar 400076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 4018f66df92SGeorge Rimar OutputSectionBase<ELFT> *Sec = findSection<ELFT>(*Cmd, *OutputSections); 4028f66df92SGeorge Rimar if (!Sec) 403652852c5SGeorge Rimar continue; 404652852c5SGeorge Rimar 40558e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 40658e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 40758e5c4dcSGeorge Rimar 408630c6179SGeorge Rimar if (Cmd->AlignExpr) 409630c6179SGeorge Rimar Sec->updateAlignment(Cmd->AlignExpr(Dot)); 410630c6179SGeorge Rimar 411652852c5SGeorge Rimar if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { 412c998a8c0SRui Ueyama uintX_t TVA = Dot + ThreadBssOffset; 413424b4081SRui Ueyama TVA = alignTo(TVA, Sec->getAlignment()); 414652852c5SGeorge Rimar Sec->setVA(TVA); 41520889c51SEugene Leviant assignOffsets(Cmd, Sec); 416c998a8c0SRui Ueyama ThreadBssOffset = TVA - Dot + Sec->getSize(); 417652852c5SGeorge Rimar continue; 418652852c5SGeorge Rimar } 419652852c5SGeorge Rimar 420b6c52e8dSGeorge Rimar if (!(Sec->getFlags() & SHF_ALLOC)) { 42120889c51SEugene Leviant assignOffsets(Cmd, Sec); 422b6c52e8dSGeorge Rimar continue; 423b6c52e8dSGeorge Rimar } 424b6c52e8dSGeorge Rimar 425424b4081SRui Ueyama Dot = alignTo(Dot, Sec->getAlignment()); 426c998a8c0SRui Ueyama Sec->setVA(Dot); 42720889c51SEugene Leviant assignOffsets(Cmd, Sec); 428467c4d55SEugene Leviant MinVA = std::min(MinVA, Dot); 429c998a8c0SRui Ueyama Dot += Sec->getSize(); 430652852c5SGeorge Rimar } 431467c4d55SEugene Leviant 43264c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 433b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 434467c4d55SEugene Leviant MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() - 435467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->getSize(), 436467c4d55SEugene Leviant Target->PageSize); 437467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 438467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 439fb8978fcSDima Stepanov } 440652852c5SGeorge Rimar 441464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 44207320e40SRui Ueyama template <class ELFT> 443a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { 444edebbdf1SRui Ueyama std::vector<PhdrEntry<ELFT>> Ret; 445bbe38602SEugene Leviant 446464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 447464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 448bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 449edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 450edebbdf1SRui Ueyama PhdrEntry<ELFT> &Phdr = Ret.back(); 451bbe38602SEugene Leviant 452bbe38602SEugene Leviant if (Cmd.HasFilehdr) 453adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 454bbe38602SEugene Leviant if (Cmd.HasPhdrs) 455adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 456bbe38602SEugene Leviant } 457bbe38602SEugene Leviant 458464daadcSRui Ueyama // Add output sections to program headers. 459edebbdf1SRui Ueyama PhdrEntry<ELFT> *Load = nullptr; 460edebbdf1SRui Ueyama uintX_t Flags = PF_R; 461464daadcSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 462bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 463bbe38602SEugene Leviant break; 464bbe38602SEugene Leviant 465edebbdf1SRui Ueyama std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName()); 466bbe38602SEugene Leviant if (!PhdrIds.empty()) { 467bbe38602SEugene Leviant // Assign headers specified by linker script 468bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 469edebbdf1SRui Ueyama Ret[Id].add(Sec); 470865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 4710b113671SRafael Espindola Ret[Id].H.p_flags |= Sec->getPhdrFlags(); 472bbe38602SEugene Leviant } 473bbe38602SEugene Leviant } else { 474bbe38602SEugene Leviant // If we have no load segment or flags've changed then we want new load 475bbe38602SEugene Leviant // segment. 4760b113671SRafael Espindola uintX_t NewFlags = Sec->getPhdrFlags(); 477bbe38602SEugene Leviant if (Load == nullptr || Flags != NewFlags) { 478edebbdf1SRui Ueyama Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags); 479bbe38602SEugene Leviant Flags = NewFlags; 480bbe38602SEugene Leviant } 48118f084ffSRui Ueyama Load->add(Sec); 482bbe38602SEugene Leviant } 483bbe38602SEugene Leviant } 484edebbdf1SRui Ueyama return Ret; 485bbe38602SEugene Leviant } 486bbe38602SEugene Leviant 487f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 488f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 489f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 490f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 491f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 492f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 493f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 494f9bc3bd2SEugene Leviant } 495f9bc3bd2SEugene Leviant 496bbe38602SEugene Leviant template <class ELFT> 49707320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 498f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 499f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 500f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 501f6c3ccefSGeorge Rimar return Cmd->Filler; 502e2ee72b5SGeorge Rimar return {}; 503e2ee72b5SGeorge Rimar } 504e2ee72b5SGeorge Rimar 505206fffa1SGeorge Rimar template <class ELFT> Expr LinkerScript<ELFT>::getLma(StringRef Name) { 5068ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 5078ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 5088ceadb38SGeorge Rimar if (Cmd->LmaExpr && Cmd->Name == Name) 5098ceadb38SGeorge Rimar return Cmd->LmaExpr; 5108ceadb38SGeorge Rimar return {}; 5118ceadb38SGeorge Rimar } 5128ceadb38SGeorge Rimar 513c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 514c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 515c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 516c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 517076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 518f510fa6bSRui Ueyama int I = 0; 519f510fa6bSRui Ueyama for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 520076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 521076fe157SGeorge Rimar if (Cmd->Name == Name) 522f510fa6bSRui Ueyama return I; 523f510fa6bSRui Ueyama ++I; 524f510fa6bSRui Ueyama } 525f510fa6bSRui Ueyama return INT_MAX; 52671b26e94SGeorge Rimar } 52771b26e94SGeorge Rimar 52871b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if 52971b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0. 53007320e40SRui Ueyama template <class ELFT> 53107320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 532c3e2a4b0SRui Ueyama int I = getSectionIndex(A); 533c3e2a4b0SRui Ueyama int J = getSectionIndex(B); 534c3e2a4b0SRui Ueyama if (I == INT_MAX && J == INT_MAX) 535717677afSRui Ueyama return 0; 536717677afSRui Ueyama return I < J ? -1 : 1; 537717677afSRui Ueyama } 538717677afSRui Ueyama 539bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 540bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 541bbe38602SEugene Leviant } 542bbe38602SEugene Leviant 5439e69450eSGeorge Rimar template <class ELFT> 54496659df0SGeorge Rimar typename ELFT::uint 54596659df0SGeorge Rimar LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) { 54696659df0SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 54796659df0SGeorge Rimar if (Sec->getName() == Name) 54896659df0SGeorge Rimar return Sec->getVA(); 54996659df0SGeorge Rimar error("undefined section " + Name); 55096659df0SGeorge Rimar return 0; 55196659df0SGeorge Rimar } 55296659df0SGeorge Rimar 55396659df0SGeorge Rimar template <class ELFT> 5549e69450eSGeorge Rimar typename ELFT::uint LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 5559e69450eSGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 5569e69450eSGeorge Rimar if (Sec->getName() == Name) 5579e69450eSGeorge Rimar return Sec->getSize(); 5589e69450eSGeorge Rimar error("undefined section " + Name); 5599e69450eSGeorge Rimar return 0; 5609e69450eSGeorge Rimar } 5619e69450eSGeorge Rimar 562e32a3598SGeorge Rimar template <class ELFT> 5634f7500bfSRui Ueyama typename ELFT::uint LinkerScript<ELFT>::getHeaderSize() { 564e32a3598SGeorge Rimar return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 565e32a3598SGeorge Rimar } 566e32a3598SGeorge Rimar 567bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 568bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 569bbe38602SEugene Leviant // PHDRS {} script block. 570bbe38602SEugene Leviant template <class ELFT> 571edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 572076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 573076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 574edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 57531d842f5SGeorge Rimar continue; 57631d842f5SGeorge Rimar 57729c5a2a9SRui Ueyama std::vector<size_t> Ret; 57829c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 57929c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 58029c5a2a9SRui Ueyama return Ret; 581bbe38602SEugene Leviant } 58231d842f5SGeorge Rimar return {}; 58331d842f5SGeorge Rimar } 584bbe38602SEugene Leviant 58529c5a2a9SRui Ueyama template <class ELFT> 58629c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 58729c5a2a9SRui Ueyama size_t I = 0; 58829c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 58929c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 59029c5a2a9SRui Ueyama return I; 59129c5a2a9SRui Ueyama ++I; 59229c5a2a9SRui Ueyama } 59329c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 59429c5a2a9SRui Ueyama return 0; 59529c5a2a9SRui Ueyama } 59629c5a2a9SRui Ueyama 59707320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 598c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 599c3794e58SGeorge Rimar 600f7c5fbb1SRui Ueyama public: 60107320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 602f23b2320SGeorge Rimar 60320b6598cSGeorge Rimar void readLinkerScript(); 60420b6598cSGeorge Rimar void readVersionScript(); 605f7c5fbb1SRui Ueyama 606f7c5fbb1SRui Ueyama private: 60752a1509eSRui Ueyama void addFile(StringRef Path); 60852a1509eSRui Ueyama 609f7c5fbb1SRui Ueyama void readAsNeeded(); 61090c5099eSDenis Protivensky void readEntry(); 61183f406cfSGeorge Rimar void readExtern(); 612f7c5fbb1SRui Ueyama void readGroup(); 61331aa1f83SRui Ueyama void readInclude(); 614ee59282bSRui Ueyama void readOutput(); 6159159ce93SDavide Italiano void readOutputArch(); 616f7c5fbb1SRui Ueyama void readOutputFormat(); 617bbe38602SEugene Leviant void readPhdrs(); 61868a39a65SDavide Italiano void readSearchDir(); 6198e3b38abSDenis Protivensky void readSections(); 62095769b4aSRui Ueyama void readVersion(); 62195769b4aSRui Ueyama void readVersionScriptCommand(); 6228e3b38abSDenis Protivensky 623113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 62410416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 625f71caa2bSRui Ueyama std::vector<uint8_t> readOutputSectionFiller(); 626bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 627a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 628c91930a1SGeorge Rimar Regex readFilePatterns(); 629a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 630bbe38602SEugene Leviant unsigned readPhdrType(); 631742c3836SRui Ueyama SortKind readSortKind(); 632a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 633ceabe80eSEugene Leviant SymbolAssignment *readProvideOrAssignment(StringRef Tok); 63403fc010eSGeorge Rimar void readSort(); 635eefa758eSGeorge Rimar Expr readAssert(); 636708019c4SRui Ueyama 637708019c4SRui Ueyama Expr readExpr(); 638708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 639708019c4SRui Ueyama Expr readPrimary(); 640708019c4SRui Ueyama Expr readTernary(Expr Cond); 6416ad7dfccSRui Ueyama Expr readParenExpr(); 642f7c5fbb1SRui Ueyama 64320b6598cSGeorge Rimar // For parsing version script. 64420b6598cSGeorge Rimar void readExtern(std::vector<SymbolVersion> *Globals); 64595769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 64620b6598cSGeorge Rimar void readGlobal(StringRef VerStr); 64720b6598cSGeorge Rimar void readLocal(); 64820b6598cSGeorge Rimar 64907320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 65007320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 65116b0cc9eSSimon Atanasyan bool IsUnderSysroot; 652f7c5fbb1SRui Ueyama }; 653f7c5fbb1SRui Ueyama 65420b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 65595769b4aSRui Ueyama readVersionScriptCommand(); 65620b6598cSGeorge Rimar if (!atEOF()) 65795769b4aSRui Ueyama setError("EOF expected, but got " + next()); 65895769b4aSRui Ueyama } 65995769b4aSRui Ueyama 66095769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 66195769b4aSRui Ueyama if (skip("{")) { 66295769b4aSRui Ueyama readVersionDeclaration(""); 66320b6598cSGeorge Rimar return; 66420b6598cSGeorge Rimar } 66520b6598cSGeorge Rimar 66695769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 66720b6598cSGeorge Rimar StringRef VerStr = next(); 66820b6598cSGeorge Rimar if (VerStr == "{") { 66995769b4aSRui Ueyama setError("anonymous version definition is used in " 67095769b4aSRui Ueyama "combination with other version definitions"); 67120b6598cSGeorge Rimar return; 67220b6598cSGeorge Rimar } 67320b6598cSGeorge Rimar expect("{"); 67495769b4aSRui Ueyama readVersionDeclaration(VerStr); 67520b6598cSGeorge Rimar } 67620b6598cSGeorge Rimar } 67720b6598cSGeorge Rimar 67895769b4aSRui Ueyama void ScriptParser::readVersion() { 67995769b4aSRui Ueyama expect("{"); 68095769b4aSRui Ueyama readVersionScriptCommand(); 68195769b4aSRui Ueyama expect("}"); 68295769b4aSRui Ueyama } 68395769b4aSRui Ueyama 68420b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 685f7c5fbb1SRui Ueyama while (!atEOF()) { 686f7c5fbb1SRui Ueyama StringRef Tok = next(); 687a27eeccaSRui Ueyama if (Tok == ";") 688a27eeccaSRui Ueyama continue; 689a27eeccaSRui Ueyama 690a27eeccaSRui Ueyama if (Tok == "ENTRY") { 691a27eeccaSRui Ueyama readEntry(); 692a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 693a27eeccaSRui Ueyama readExtern(); 694a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 695a27eeccaSRui Ueyama readGroup(); 696a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 697a27eeccaSRui Ueyama readInclude(); 698a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 699a27eeccaSRui Ueyama readOutput(); 700a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 701a27eeccaSRui Ueyama readOutputArch(); 702a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 703a27eeccaSRui Ueyama readOutputFormat(); 704a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 705a27eeccaSRui Ueyama readPhdrs(); 706a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 707a27eeccaSRui Ueyama readSearchDir(); 708a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 709a27eeccaSRui Ueyama readSections(); 710a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 711a27eeccaSRui Ueyama readVersion(); 712e5d3ca50SPetr Hosek } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { 713e5d3ca50SPetr Hosek if (Opt.HasContents) 7140df80befSPetr Hosek Opt.Commands.emplace_back(Cmd); 715c3794e58SGeorge Rimar else 716e5d3ca50SPetr Hosek Opt.Assignments.emplace_back(Cmd); 717e5d3ca50SPetr Hosek } else { 7185761042dSGeorge Rimar setError("unknown directive: " + Tok); 719f7c5fbb1SRui Ueyama } 720f7c5fbb1SRui Ueyama } 721e5d3ca50SPetr Hosek } 722f7c5fbb1SRui Ueyama 723717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 72416b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 72516b0cc9eSSimon Atanasyan SmallString<128> Path; 72616b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 72716b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 72816b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 72916b0cc9eSSimon Atanasyan return; 73016b0cc9eSSimon Atanasyan } 73116b0cc9eSSimon Atanasyan } 73216b0cc9eSSimon Atanasyan 733f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 73452a1509eSRui Ueyama Driver->addFile(S); 73552a1509eSRui Ueyama } else if (S.startswith("=")) { 73652a1509eSRui Ueyama if (Config->Sysroot.empty()) 73752a1509eSRui Ueyama Driver->addFile(S.substr(1)); 73852a1509eSRui Ueyama else 73952a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 74052a1509eSRui Ueyama } else if (S.startswith("-l")) { 74121eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 742a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 743a1b8fc3bSSimon Atanasyan Driver->addFile(S); 74452a1509eSRui Ueyama } else { 74552a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 74652a1509eSRui Ueyama if (Path.empty()) 747777f9630SGeorge Rimar setError("unable to find " + S); 748025d59b1SRui Ueyama else 74952a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 75052a1509eSRui Ueyama } 75152a1509eSRui Ueyama } 75252a1509eSRui Ueyama 753717677afSRui Ueyama void ScriptParser::readAsNeeded() { 754f7c5fbb1SRui Ueyama expect("("); 75535da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 75635da9b6eSRui Ueyama Config->AsNeeded = true; 757a2acc931SRui Ueyama while (!Error && !skip(")")) 758a2acc931SRui Ueyama addFile(next()); 75935da9b6eSRui Ueyama Config->AsNeeded = Orig; 760f7c5fbb1SRui Ueyama } 761f7c5fbb1SRui Ueyama 762717677afSRui Ueyama void ScriptParser::readEntry() { 76390c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 76490c5099eSDenis Protivensky expect("("); 76590c5099eSDenis Protivensky StringRef Tok = next(); 76690c5099eSDenis Protivensky if (Config->Entry.empty()) 76790c5099eSDenis Protivensky Config->Entry = Tok; 76890c5099eSDenis Protivensky expect(")"); 76990c5099eSDenis Protivensky } 77090c5099eSDenis Protivensky 771717677afSRui Ueyama void ScriptParser::readExtern() { 77283f406cfSGeorge Rimar expect("("); 773a2acc931SRui Ueyama while (!Error && !skip(")")) 774a2acc931SRui Ueyama Config->Undefined.push_back(next()); 77583f406cfSGeorge Rimar } 77683f406cfSGeorge Rimar 777717677afSRui Ueyama void ScriptParser::readGroup() { 778f7c5fbb1SRui Ueyama expect("("); 779a2acc931SRui Ueyama while (!Error && !skip(")")) { 780f7c5fbb1SRui Ueyama StringRef Tok = next(); 781a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 782f7c5fbb1SRui Ueyama readAsNeeded(); 783a2acc931SRui Ueyama else 78452a1509eSRui Ueyama addFile(Tok); 785f7c5fbb1SRui Ueyama } 786f7c5fbb1SRui Ueyama } 787f7c5fbb1SRui Ueyama 788717677afSRui Ueyama void ScriptParser::readInclude() { 78931aa1f83SRui Ueyama StringRef Tok = next(); 79031aa1f83SRui Ueyama auto MBOrErr = MemoryBuffer::getFile(Tok); 791025d59b1SRui Ueyama if (!MBOrErr) { 7925761042dSGeorge Rimar setError("cannot open " + Tok); 793025d59b1SRui Ueyama return; 794025d59b1SRui Ueyama } 79531aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 796a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 797a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 79831aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 79931aa1f83SRui Ueyama } 80031aa1f83SRui Ueyama 801717677afSRui Ueyama void ScriptParser::readOutput() { 802ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 803ee59282bSRui Ueyama expect("("); 804ee59282bSRui Ueyama StringRef Tok = next(); 805ee59282bSRui Ueyama if (Config->OutputFile.empty()) 806ee59282bSRui Ueyama Config->OutputFile = Tok; 807ee59282bSRui Ueyama expect(")"); 808ee59282bSRui Ueyama } 809ee59282bSRui Ueyama 810717677afSRui Ueyama void ScriptParser::readOutputArch() { 8119159ce93SDavide Italiano // Error checking only for now. 8129159ce93SDavide Italiano expect("("); 8139159ce93SDavide Italiano next(); 8149159ce93SDavide Italiano expect(")"); 8159159ce93SDavide Italiano } 8169159ce93SDavide Italiano 817717677afSRui Ueyama void ScriptParser::readOutputFormat() { 818f7c5fbb1SRui Ueyama // Error checking only for now. 819f7c5fbb1SRui Ueyama expect("("); 820f7c5fbb1SRui Ueyama next(); 8216836c618SDavide Italiano StringRef Tok = next(); 8226836c618SDavide Italiano if (Tok == ")") 8236836c618SDavide Italiano return; 824025d59b1SRui Ueyama if (Tok != ",") { 8255761042dSGeorge Rimar setError("unexpected token: " + Tok); 826025d59b1SRui Ueyama return; 827025d59b1SRui Ueyama } 8286836c618SDavide Italiano next(); 8296836c618SDavide Italiano expect(","); 8306836c618SDavide Italiano next(); 831f7c5fbb1SRui Ueyama expect(")"); 832f7c5fbb1SRui Ueyama } 833f7c5fbb1SRui Ueyama 834bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 835bbe38602SEugene Leviant expect("{"); 836bbe38602SEugene Leviant while (!Error && !skip("}")) { 837bbe38602SEugene Leviant StringRef Tok = next(); 838865bf863SEugene Leviant Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX}); 839bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 840bbe38602SEugene Leviant 841bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 842bbe38602SEugene Leviant do { 843bbe38602SEugene Leviant Tok = next(); 844bbe38602SEugene Leviant if (Tok == ";") 845bbe38602SEugene Leviant break; 846bbe38602SEugene Leviant if (Tok == "FILEHDR") 847bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 848bbe38602SEugene Leviant else if (Tok == "PHDRS") 849bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 850865bf863SEugene Leviant else if (Tok == "FLAGS") { 851865bf863SEugene Leviant expect("("); 852eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 853eb685cd7SRafael Espindola // we accept expressions like ".|1". 854eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 855865bf863SEugene Leviant expect(")"); 856865bf863SEugene Leviant } else 857bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 858bbe38602SEugene Leviant } while (!Error); 859bbe38602SEugene Leviant } 860bbe38602SEugene Leviant } 861bbe38602SEugene Leviant 862717677afSRui Ueyama void ScriptParser::readSearchDir() { 86368a39a65SDavide Italiano expect("("); 8646c7ad13fSRui Ueyama if (!Config->Nostdlib) 86506501920SRafael Espindola Config->SearchPaths.push_back(next()); 86668a39a65SDavide Italiano expect(")"); 86768a39a65SDavide Italiano } 86868a39a65SDavide Italiano 869717677afSRui Ueyama void ScriptParser::readSections() { 8703de0a330SRui Ueyama Opt.HasContents = true; 8718e3b38abSDenis Protivensky expect("{"); 872652852c5SGeorge Rimar while (!Error && !skip("}")) { 873113cdec9SRui Ueyama StringRef Tok = next(); 874ceabe80eSEugene Leviant BaseCommand *Cmd = readProvideOrAssignment(Tok); 875ceabe80eSEugene Leviant if (!Cmd) { 876ceabe80eSEugene Leviant if (Tok == "ASSERT") 877eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 878ceabe80eSEugene Leviant else 87910416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 8808e3b38abSDenis Protivensky } 88110416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 882652852c5SGeorge Rimar } 883708019c4SRui Ueyama } 8848e3b38abSDenis Protivensky 885708019c4SRui Ueyama static int precedence(StringRef Op) { 886708019c4SRui Ueyama return StringSwitch<int>(Op) 887708019c4SRui Ueyama .Case("*", 4) 888708019c4SRui Ueyama .Case("/", 4) 889708019c4SRui Ueyama .Case("+", 3) 890708019c4SRui Ueyama .Case("-", 3) 891708019c4SRui Ueyama .Case("<", 2) 892708019c4SRui Ueyama .Case(">", 2) 893708019c4SRui Ueyama .Case(">=", 2) 894708019c4SRui Ueyama .Case("<=", 2) 895708019c4SRui Ueyama .Case("==", 2) 896708019c4SRui Ueyama .Case("!=", 2) 897708019c4SRui Ueyama .Case("&", 1) 898cc3dd629SRafael Espindola .Case("|", 1) 899708019c4SRui Ueyama .Default(-1); 900708019c4SRui Ueyama } 901708019c4SRui Ueyama 902c91930a1SGeorge Rimar Regex ScriptParser::readFilePatterns() { 90310416564SRui Ueyama std::vector<StringRef> V; 90410416564SRui Ueyama while (!Error && !skip(")")) 90510416564SRui Ueyama V.push_back(next()); 906c91930a1SGeorge Rimar return compileGlobPatterns(V); 9070702c4e8SGeorge Rimar } 9080702c4e8SGeorge Rimar 909742c3836SRui Ueyama SortKind ScriptParser::readSortKind() { 910742c3836SRui Ueyama if (skip("SORT") || skip("SORT_BY_NAME")) 911742c3836SRui Ueyama return SortByName; 912742c3836SRui Ueyama if (skip("SORT_BY_ALIGNMENT")) 913742c3836SRui Ueyama return SortByAlignment; 914742c3836SRui Ueyama return SortNone; 915742c3836SRui Ueyama } 916742c3836SRui Ueyama 917a2496cbeSGeorge Rimar InputSectionDescription * 918a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 919c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 9200ed42b0cSDavide Italiano expect("("); 921e7282797SDavide Italiano 922742c3836SRui Ueyama // Read EXCLUDE_FILE(). 923e7282797SDavide Italiano if (skip("EXCLUDE_FILE")) { 924e7282797SDavide Italiano expect("("); 925c91930a1SGeorge Rimar Cmd->ExcludedFileRe = readFilePatterns(); 926e7282797SDavide Italiano } 927e7282797SDavide Italiano 928742c3836SRui Ueyama // Read SORT(). 929742c3836SRui Ueyama if (SortKind K1 = readSortKind()) { 930742c3836SRui Ueyama Cmd->SortOuter = K1; 9310702c4e8SGeorge Rimar expect("("); 932742c3836SRui Ueyama if (SortKind K2 = readSortKind()) { 933742c3836SRui Ueyama Cmd->SortInner = K2; 934350ece4eSGeorge Rimar expect("("); 935c91930a1SGeorge Rimar Cmd->SectionRe = readFilePatterns(); 9360702c4e8SGeorge Rimar expect(")"); 937350ece4eSGeorge Rimar } else { 938c91930a1SGeorge Rimar Cmd->SectionRe = readFilePatterns(); 939350ece4eSGeorge Rimar } 940350ece4eSGeorge Rimar expect(")"); 94110416564SRui Ueyama return Cmd; 9420659800eSGeorge Rimar } 9430702c4e8SGeorge Rimar 944c91930a1SGeorge Rimar Cmd->SectionRe = readFilePatterns(); 94510416564SRui Ueyama return Cmd; 9460659800eSGeorge Rimar } 9470659800eSGeorge Rimar 948a2496cbeSGeorge Rimar InputSectionDescription * 949a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 9500659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 9510659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 952a2496cbeSGeorge Rimar if (Tok == "KEEP") { 953e7282797SDavide Italiano expect("("); 954a2496cbeSGeorge Rimar StringRef FilePattern = next(); 955a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 9560ed42b0cSDavide Italiano expect(")"); 957c91930a1SGeorge Rimar Opt.KeptSections.push_back(&Cmd->SectionRe); 95810416564SRui Ueyama return Cmd; 95910416564SRui Ueyama } 960a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 9610659800eSGeorge Rimar } 9620659800eSGeorge Rimar 96303fc010eSGeorge Rimar void ScriptParser::readSort() { 96403fc010eSGeorge Rimar expect("("); 96503fc010eSGeorge Rimar expect("CONSTRUCTORS"); 96603fc010eSGeorge Rimar expect(")"); 96703fc010eSGeorge Rimar } 96803fc010eSGeorge Rimar 969eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 970eefa758eSGeorge Rimar expect("("); 971eefa758eSGeorge Rimar Expr E = readExpr(); 972eefa758eSGeorge Rimar expect(","); 973eefa758eSGeorge Rimar StringRef Msg = next(); 974eefa758eSGeorge Rimar expect(")"); 975eefa758eSGeorge Rimar return [=](uint64_t Dot) { 976eefa758eSGeorge Rimar uint64_t V = E(Dot); 977eefa758eSGeorge Rimar if (!V) 978eefa758eSGeorge Rimar error(Msg); 979eefa758eSGeorge Rimar return V; 980eefa758eSGeorge Rimar }; 981eefa758eSGeorge Rimar } 982eefa758eSGeorge Rimar 98310416564SRui Ueyama OutputSectionCommand * 98410416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 985076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 98658e5c4dcSGeorge Rimar 98758e5c4dcSGeorge Rimar // Read an address expression. 98858e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 98958e5c4dcSGeorge Rimar if (peek() != ":") 99058e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 99158e5c4dcSGeorge Rimar 9928e3b38abSDenis Protivensky expect(":"); 993246f681eSDavide Italiano 9948ceadb38SGeorge Rimar if (skip("AT")) 9956ad7dfccSRui Ueyama Cmd->LmaExpr = readParenExpr(); 996630c6179SGeorge Rimar if (skip("ALIGN")) 9976ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 998db24d9c3SGeorge Rimar if (skip("SUBALIGN")) 999db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1000630c6179SGeorge Rimar 1001246f681eSDavide Italiano // Parse constraints. 1002246f681eSDavide Italiano if (skip("ONLY_IF_RO")) 1003efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 1004246f681eSDavide Italiano if (skip("ONLY_IF_RW")) 1005efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 10068e3b38abSDenis Protivensky expect("{"); 10078ec77e64SRui Ueyama 1008025d59b1SRui Ueyama while (!Error && !skip("}")) { 1009ceabe80eSEugene Leviant StringRef Tok = next(); 1010ceabe80eSEugene Leviant if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) 1011ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1012ceabe80eSEugene Leviant else if (Tok == "SORT") 101303fc010eSGeorge Rimar readSort(); 1014a2496cbeSGeorge Rimar else if (peek() == "(") 1015a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1016ceabe80eSEugene Leviant else 1017ceabe80eSEugene Leviant setError("unknown command " + Tok); 10188e3b38abSDenis Protivensky } 1019076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 1020f71caa2bSRui Ueyama Cmd->Filler = readOutputSectionFiller(); 102110416564SRui Ueyama return Cmd; 1022f71caa2bSRui Ueyama } 10238ec77e64SRui Ueyama 10242c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 10252c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 10262c8f1f04SRui Ueyama // 10272c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 10282c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 10292c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 10302c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 1031f71caa2bSRui Ueyama std::vector<uint8_t> ScriptParser::readOutputSectionFiller() { 10322c8f1f04SRui Ueyama if (!peek().startswith("=")) 1033f71caa2bSRui Ueyama return {}; 1034965827d6SRui Ueyama 10352c8f1f04SRui Ueyama StringRef Tok = next(); 1036965827d6SRui Ueyama uint32_t V; 1037965827d6SRui Ueyama if (Tok.substr(1).getAsInteger(0, V)) { 1038965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 1039f71caa2bSRui Ueyama return {}; 1040e2ee72b5SGeorge Rimar } 1041965827d6SRui Ueyama return {uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V)}; 10428e3b38abSDenis Protivensky } 10438e3b38abSDenis Protivensky 1044a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1045a31c91b1SEugene Leviant expect("("); 1046174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1047a35e39caSPetr Hosek Cmd->Provide = Provide; 1048174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1049a31c91b1SEugene Leviant expect(")"); 1050a31c91b1SEugene Leviant expect(";"); 105110416564SRui Ueyama return Cmd; 1052eda81a1bSEugene Leviant } 1053eda81a1bSEugene Leviant 1054ceabe80eSEugene Leviant SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 1055ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1056ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1057ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1058ceabe80eSEugene Leviant expect(";"); 1059ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1060a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1061a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1062a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1063ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1064a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1065ceabe80eSEugene Leviant } 1066ceabe80eSEugene Leviant return Cmd; 1067ceabe80eSEugene Leviant } 1068ceabe80eSEugene Leviant 106930835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { 107030835ea4SGeorge Rimar if (S == ".") 107130835ea4SGeorge Rimar return Dot; 1072a31c91b1SEugene Leviant 1073a9c5a528SGeorge Rimar switch (Config->EKind) { 1074a9c5a528SGeorge Rimar case ELF32LEKind: 1075a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF32LE>::X->find(S)) 1076a9c5a528SGeorge Rimar return B->getVA<ELF32LE>(); 1077a9c5a528SGeorge Rimar break; 1078a9c5a528SGeorge Rimar case ELF32BEKind: 1079a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF32BE>::X->find(S)) 1080a9c5a528SGeorge Rimar return B->getVA<ELF32BE>(); 1081a9c5a528SGeorge Rimar break; 1082a9c5a528SGeorge Rimar case ELF64LEKind: 1083a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF64LE>::X->find(S)) 1084a9c5a528SGeorge Rimar return B->getVA<ELF64LE>(); 1085a9c5a528SGeorge Rimar break; 1086a9c5a528SGeorge Rimar case ELF64BEKind: 1087a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF64BE>::X->find(S)) 1088a9c5a528SGeorge Rimar return B->getVA<ELF64BE>(); 1089a9c5a528SGeorge Rimar break; 10906930a6dcSGeorge Rimar default: 1091b567b628SGeorge Rimar llvm_unreachable("unsupported target"); 1092a9c5a528SGeorge Rimar } 1093a9c5a528SGeorge Rimar error("symbol not found: " + S); 1094a9c5a528SGeorge Rimar return 0; 1095a9c5a528SGeorge Rimar } 1096a9c5a528SGeorge Rimar 10979e69450eSGeorge Rimar static uint64_t getSectionSize(StringRef Name) { 10989e69450eSGeorge Rimar switch (Config->EKind) { 10999e69450eSGeorge Rimar case ELF32LEKind: 11009e69450eSGeorge Rimar return Script<ELF32LE>::X->getOutputSectionSize(Name); 11019e69450eSGeorge Rimar case ELF32BEKind: 11029e69450eSGeorge Rimar return Script<ELF32BE>::X->getOutputSectionSize(Name); 11039e69450eSGeorge Rimar case ELF64LEKind: 11049e69450eSGeorge Rimar return Script<ELF64LE>::X->getOutputSectionSize(Name); 11059e69450eSGeorge Rimar case ELF64BEKind: 11069e69450eSGeorge Rimar return Script<ELF64BE>::X->getOutputSectionSize(Name); 11079e69450eSGeorge Rimar default: 11089e69450eSGeorge Rimar llvm_unreachable("unsupported target"); 11099e69450eSGeorge Rimar } 11109e69450eSGeorge Rimar } 11119e69450eSGeorge Rimar 111296659df0SGeorge Rimar static uint64_t getSectionAddress(StringRef Name) { 111396659df0SGeorge Rimar switch (Config->EKind) { 111496659df0SGeorge Rimar case ELF32LEKind: 111596659df0SGeorge Rimar return Script<ELF32LE>::X->getOutputSectionAddress(Name); 111696659df0SGeorge Rimar case ELF32BEKind: 111796659df0SGeorge Rimar return Script<ELF32BE>::X->getOutputSectionAddress(Name); 111896659df0SGeorge Rimar case ELF64LEKind: 111996659df0SGeorge Rimar return Script<ELF64LE>::X->getOutputSectionAddress(Name); 112096659df0SGeorge Rimar case ELF64BEKind: 112196659df0SGeorge Rimar return Script<ELF64BE>::X->getOutputSectionAddress(Name); 112296659df0SGeorge Rimar default: 112396659df0SGeorge Rimar llvm_unreachable("unsupported target"); 112496659df0SGeorge Rimar } 112596659df0SGeorge Rimar } 112696659df0SGeorge Rimar 11274f7500bfSRui Ueyama static uint64_t getHeaderSize() { 1128e32a3598SGeorge Rimar switch (Config->EKind) { 1129e32a3598SGeorge Rimar case ELF32LEKind: 11304f7500bfSRui Ueyama return Script<ELF32LE>::X->getHeaderSize(); 1131e32a3598SGeorge Rimar case ELF32BEKind: 11324f7500bfSRui Ueyama return Script<ELF32BE>::X->getHeaderSize(); 1133e32a3598SGeorge Rimar case ELF64LEKind: 11344f7500bfSRui Ueyama return Script<ELF64LE>::X->getHeaderSize(); 1135e32a3598SGeorge Rimar case ELF64BEKind: 11364f7500bfSRui Ueyama return Script<ELF64BE>::X->getHeaderSize(); 1137e32a3598SGeorge Rimar default: 1138e32a3598SGeorge Rimar llvm_unreachable("unsupported target"); 1139e32a3598SGeorge Rimar } 1140e32a3598SGeorge Rimar } 1141e32a3598SGeorge Rimar 114230835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 114330835ea4SGeorge Rimar StringRef Op = next(); 114430835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 114530835ea4SGeorge Rimar Expr E = readExpr(); 114630835ea4SGeorge Rimar if (Op == "+=") 114730835ea4SGeorge Rimar E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; 114810416564SRui Ueyama return new SymbolAssignment(Name, E); 114930835ea4SGeorge Rimar } 115030835ea4SGeorge Rimar 115130835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 115230835ea4SGeorge Rimar // script expression. 115330835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 115430835ea4SGeorge Rimar 115536c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 115636c1cd23SRui Ueyama if (Op == "*") 115736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 115836c1cd23SRui Ueyama if (Op == "/") { 115936c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 116036c1cd23SRui Ueyama uint64_t RHS = R(Dot); 116136c1cd23SRui Ueyama if (RHS == 0) { 116236c1cd23SRui Ueyama error("division by zero"); 116336c1cd23SRui Ueyama return 0; 116436c1cd23SRui Ueyama } 116536c1cd23SRui Ueyama return L(Dot) / RHS; 116636c1cd23SRui Ueyama }; 116736c1cd23SRui Ueyama } 116836c1cd23SRui Ueyama if (Op == "+") 116936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) + R(Dot); }; 117036c1cd23SRui Ueyama if (Op == "-") 117136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 117236c1cd23SRui Ueyama if (Op == "<") 117336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 117436c1cd23SRui Ueyama if (Op == ">") 117536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 117636c1cd23SRui Ueyama if (Op == ">=") 117736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 117836c1cd23SRui Ueyama if (Op == "<=") 117936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 118036c1cd23SRui Ueyama if (Op == "==") 118136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 118236c1cd23SRui Ueyama if (Op == "!=") 118336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 118436c1cd23SRui Ueyama if (Op == "&") 118536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 1186cc3dd629SRafael Espindola if (Op == "|") 1187cc3dd629SRafael Espindola return [=](uint64_t Dot) { return L(Dot) | R(Dot); }; 118836c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 118936c1cd23SRui Ueyama } 119036c1cd23SRui Ueyama 1191708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1192708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1193708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1194708019c4SRui Ueyama while (!atEOF() && !Error) { 1195708019c4SRui Ueyama // Read an operator and an expression. 1196708019c4SRui Ueyama StringRef Op1 = peek(); 1197708019c4SRui Ueyama if (Op1 == "?") 1198708019c4SRui Ueyama return readTernary(Lhs); 1199708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1200a31c91b1SEugene Leviant break; 1201a31c91b1SEugene Leviant next(); 1202708019c4SRui Ueyama Expr Rhs = readPrimary(); 1203708019c4SRui Ueyama 1204708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1205708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1206708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1207708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1208708019c4SRui Ueyama while (!atEOF()) { 1209708019c4SRui Ueyama StringRef Op2 = peek(); 1210708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1211eda81a1bSEugene Leviant break; 1212708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1213eda81a1bSEugene Leviant } 1214708019c4SRui Ueyama 1215708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1216708019c4SRui Ueyama } 1217708019c4SRui Ueyama return Lhs; 1218708019c4SRui Ueyama } 1219708019c4SRui Ueyama 1220708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1221e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1222708019c4SRui Ueyama return Target->PageSize; 1223e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1224e2cc07bcSMichael J. Spencer return Target->MaxPageSize; 1225708019c4SRui Ueyama error("unknown constant: " + S); 1226708019c4SRui Ueyama return 0; 1227708019c4SRui Ueyama } 1228708019c4SRui Ueyama 1229626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1230626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1231626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1232626e0b08SRui Ueyama // "M" (mega) prefixes. 12339f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 1234*eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1235*eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1236*eaeafb2bSSimon Atanasyan return false; 1237*eaeafb2bSSimon Atanasyan Result = -Result; 1238*eaeafb2bSSimon Atanasyan return true; 1239*eaeafb2bSSimon Atanasyan } 12409f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 12419f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 12429f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 12439f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 12449f2f7ad9SGeorge Rimar 12459f2f7ad9SGeorge Rimar int Suffix = 1; 12469f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 12479f2f7ad9SGeorge Rimar Suffix = 1024; 12489f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 12499f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 12509f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 12519f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 12529f2f7ad9SGeorge Rimar } 12539f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 12549f2f7ad9SGeorge Rimar return false; 12559f2f7ad9SGeorge Rimar Result *= Suffix; 12569f2f7ad9SGeorge Rimar return true; 12579f2f7ad9SGeorge Rimar } 12589f2f7ad9SGeorge Rimar 1259708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 12606ad7dfccSRui Ueyama if (peek() == "(") 12616ad7dfccSRui Ueyama return readParenExpr(); 1262708019c4SRui Ueyama 12636ad7dfccSRui Ueyama StringRef Tok = next(); 1264708019c4SRui Ueyama 1265*eaeafb2bSSimon Atanasyan if (Tok == "~") { 1266*eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1267*eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return ~E(Dot); }; 1268*eaeafb2bSSimon Atanasyan } 1269*eaeafb2bSSimon Atanasyan if (Tok == "-") { 1270*eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1271*eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return -E(Dot); }; 1272*eaeafb2bSSimon Atanasyan } 1273*eaeafb2bSSimon Atanasyan 1274708019c4SRui Ueyama // Built-in functions are parsed here. 1275708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 127696659df0SGeorge Rimar if (Tok == "ADDR") { 127796659df0SGeorge Rimar expect("("); 127896659df0SGeorge Rimar StringRef Name = next(); 127996659df0SGeorge Rimar expect(")"); 128096659df0SGeorge Rimar return [=](uint64_t Dot) { return getSectionAddress(Name); }; 128196659df0SGeorge Rimar } 1282eefa758eSGeorge Rimar if (Tok == "ASSERT") 1283eefa758eSGeorge Rimar return readAssert(); 1284708019c4SRui Ueyama if (Tok == "ALIGN") { 12856ad7dfccSRui Ueyama Expr E = readParenExpr(); 1286708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1287708019c4SRui Ueyama } 1288708019c4SRui Ueyama if (Tok == "CONSTANT") { 1289708019c4SRui Ueyama expect("("); 1290708019c4SRui Ueyama StringRef Tok = next(); 1291708019c4SRui Ueyama expect(")"); 1292708019c4SRui Ueyama return [=](uint64_t Dot) { return getConstant(Tok); }; 1293708019c4SRui Ueyama } 129454c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 129554c145ceSRafael Espindola expect("("); 129654c145ceSRafael Espindola next(); 129754c145ceSRafael Espindola expect(","); 129854c145ceSRafael Espindola uint64_t Val; 129954c145ceSRafael Espindola next().getAsInteger(0, Val); 130054c145ceSRafael Espindola expect(")"); 130154c145ceSRafael Espindola return [=](uint64_t Dot) { return Val; }; 130254c145ceSRafael Espindola } 1303708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1304708019c4SRui Ueyama expect("("); 1305708019c4SRui Ueyama Expr E = readExpr(); 1306708019c4SRui Ueyama expect(","); 1307708019c4SRui Ueyama readExpr(); 1308708019c4SRui Ueyama expect(")"); 1309f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1310708019c4SRui Ueyama } 1311708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1312708019c4SRui Ueyama expect("("); 1313708019c4SRui Ueyama expect("."); 1314708019c4SRui Ueyama expect(")"); 1315708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1316708019c4SRui Ueyama } 1317276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1318276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1319276b4e64SGeorge Rimar // the next page boundary for simplicity. 1320276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1321276b4e64SGeorge Rimar expect("("); 1322276b4e64SGeorge Rimar next(); 1323276b4e64SGeorge Rimar expect(","); 1324276b4e64SGeorge Rimar readExpr(); 1325276b4e64SGeorge Rimar expect(")"); 1326276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1327276b4e64SGeorge Rimar } 13289e69450eSGeorge Rimar if (Tok == "SIZEOF") { 13299e69450eSGeorge Rimar expect("("); 13309e69450eSGeorge Rimar StringRef Name = next(); 13319e69450eSGeorge Rimar expect(")"); 13329e69450eSGeorge Rimar return [=](uint64_t Dot) { return getSectionSize(Name); }; 13339e69450eSGeorge Rimar } 1334e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 13354f7500bfSRui Ueyama return [=](uint64_t Dot) { return getHeaderSize(); }; 1336708019c4SRui Ueyama 13379f2f7ad9SGeorge Rimar // Tok is a literal number. 13389f2f7ad9SGeorge Rimar uint64_t V; 13399f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 13409f2f7ad9SGeorge Rimar return [=](uint64_t Dot) { return V; }; 13419f2f7ad9SGeorge Rimar 13429f2f7ad9SGeorge Rimar // Tok is a symbol name. 134330835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1344708019c4SRui Ueyama setError("malformed number: " + Tok); 134530835ea4SGeorge Rimar return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }; 1346a9c5a528SGeorge Rimar } 1347708019c4SRui Ueyama 1348708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1349708019c4SRui Ueyama next(); 1350708019c4SRui Ueyama Expr L = readExpr(); 1351708019c4SRui Ueyama expect(":"); 1352708019c4SRui Ueyama Expr R = readExpr(); 1353708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1354708019c4SRui Ueyama } 1355708019c4SRui Ueyama 13566ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 13576ad7dfccSRui Ueyama expect("("); 13586ad7dfccSRui Ueyama Expr E = readExpr(); 13596ad7dfccSRui Ueyama expect(")"); 13606ad7dfccSRui Ueyama return E; 13616ad7dfccSRui Ueyama } 13626ad7dfccSRui Ueyama 1363bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1364bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1365bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1366bbe38602SEugene Leviant StringRef Tok = next(); 1367bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 1368bbe38602SEugene Leviant if (Tok.empty()) { 1369bbe38602SEugene Leviant setError("section header name is empty"); 1370bbe38602SEugene Leviant break; 1371bbe38602SEugene Leviant } 1372bbe38602SEugene Leviant Phdrs.push_back(Tok); 1373bbe38602SEugene Leviant } 1374bbe38602SEugene Leviant return Phdrs; 1375bbe38602SEugene Leviant } 1376bbe38602SEugene Leviant 1377bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1378bbe38602SEugene Leviant StringRef Tok = next(); 1379b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1380b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1381b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1382b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1383b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1384b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1385b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1386b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1387b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1388b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1389b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1390b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1391b0f6c590SRui Ueyama .Default(-1); 1392bbe38602SEugene Leviant 1393b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1394b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1395b0f6c590SRui Ueyama return PT_NULL; 1396b0f6c590SRui Ueyama } 1397b0f6c590SRui Ueyama return Ret; 1398bbe38602SEugene Leviant } 1399bbe38602SEugene Leviant 140095769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 140120b6598cSGeorge Rimar // Identifiers start at 2 because 0 and 1 are reserved 140220b6598cSGeorge Rimar // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. 140320b6598cSGeorge Rimar size_t VersionId = Config->VersionDefinitions.size() + 2; 140420b6598cSGeorge Rimar Config->VersionDefinitions.push_back({VerStr, VersionId}); 140520b6598cSGeorge Rimar 140620b6598cSGeorge Rimar if (skip("global:") || peek() != "local:") 140720b6598cSGeorge Rimar readGlobal(VerStr); 140820b6598cSGeorge Rimar if (skip("local:")) 140920b6598cSGeorge Rimar readLocal(); 141020b6598cSGeorge Rimar expect("}"); 141120b6598cSGeorge Rimar 141220b6598cSGeorge Rimar // Each version may have a parent version. For example, "Ver2" defined as 141320b6598cSGeorge Rimar // "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This 141420b6598cSGeorge Rimar // version hierarchy is, probably against your instinct, purely for human; the 141520b6598cSGeorge Rimar // runtime doesn't care about them at all. In LLD, we simply skip the token. 141620b6598cSGeorge Rimar if (!VerStr.empty() && peek() != ";") 141720b6598cSGeorge Rimar next(); 141820b6598cSGeorge Rimar expect(";"); 141920b6598cSGeorge Rimar } 142020b6598cSGeorge Rimar 142120b6598cSGeorge Rimar void ScriptParser::readLocal() { 142220b6598cSGeorge Rimar Config->DefaultSymbolVersion = VER_NDX_LOCAL; 142320b6598cSGeorge Rimar expect("*"); 142420b6598cSGeorge Rimar expect(";"); 142520b6598cSGeorge Rimar } 142620b6598cSGeorge Rimar 142720b6598cSGeorge Rimar void ScriptParser::readExtern(std::vector<SymbolVersion> *Globals) { 142820b6598cSGeorge Rimar expect("C++"); 142920b6598cSGeorge Rimar expect("{"); 143020b6598cSGeorge Rimar 143120b6598cSGeorge Rimar for (;;) { 143220b6598cSGeorge Rimar if (peek() == "}" || Error) 143320b6598cSGeorge Rimar break; 143420b6598cSGeorge Rimar Globals->push_back({next(), true}); 143520b6598cSGeorge Rimar expect(";"); 143620b6598cSGeorge Rimar } 143720b6598cSGeorge Rimar 143820b6598cSGeorge Rimar expect("}"); 143920b6598cSGeorge Rimar expect(";"); 144020b6598cSGeorge Rimar } 144120b6598cSGeorge Rimar 144220b6598cSGeorge Rimar void ScriptParser::readGlobal(StringRef VerStr) { 144320b6598cSGeorge Rimar std::vector<SymbolVersion> *Globals; 144420b6598cSGeorge Rimar if (VerStr.empty()) 144520b6598cSGeorge Rimar Globals = &Config->VersionScriptGlobals; 144620b6598cSGeorge Rimar else 144720b6598cSGeorge Rimar Globals = &Config->VersionDefinitions.back().Globals; 144820b6598cSGeorge Rimar 144920b6598cSGeorge Rimar for (;;) { 145020b6598cSGeorge Rimar if (skip("extern")) 145120b6598cSGeorge Rimar readExtern(Globals); 145220b6598cSGeorge Rimar 145320b6598cSGeorge Rimar StringRef Cur = peek(); 145420b6598cSGeorge Rimar if (Cur == "}" || Cur == "local:" || Error) 145520b6598cSGeorge Rimar return; 145620b6598cSGeorge Rimar next(); 145720b6598cSGeorge Rimar Globals->push_back({Cur, false}); 145820b6598cSGeorge Rimar expect(";"); 145920b6598cSGeorge Rimar } 146020b6598cSGeorge Rimar } 146120b6598cSGeorge Rimar 146216b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 146316b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 146416b0cc9eSSimon Atanasyan return false; 146516b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 146616b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 146716b0cc9eSSimon Atanasyan return true; 146816b0cc9eSSimon Atanasyan return false; 146916b0cc9eSSimon Atanasyan } 147016b0cc9eSSimon Atanasyan 147107320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 147216b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 147320b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).readLinkerScript(); 147420b6598cSGeorge Rimar } 147520b6598cSGeorge Rimar 147620b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 147720b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), false).readVersionScript(); 1478f7c5fbb1SRui Ueyama } 14791ebc8ed7SRui Ueyama 148007320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 148107320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 148207320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 148307320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1484