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 44884e786dSGeorge Rimar LinkerScriptBase *elf::ScriptBase; 4507320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 46717677afSRui Ueyama 476c55f0e3SGeorge Rimar template <class ELFT> 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 59db741e72SEugene Leviant template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) { 60db741e72SEugene Leviant if (Cmd->IsAbsolute) 61db741e72SEugene Leviant addRegular<ELFT>(Cmd); 62db741e72SEugene Leviant else 63db741e72SEugene Leviant addSynthetic<ELFT>(Cmd); 64db741e72SEugene Leviant } 651602421cSRui Ueyama // If a symbol was in PROVIDE(), we need to define it only when 661602421cSRui Ueyama // it is an undefined symbol. 671602421cSRui Ueyama template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) { 681602421cSRui Ueyama if (Cmd->Name == ".") 69ceabe80eSEugene Leviant return false; 701602421cSRui Ueyama if (!Cmd->Provide) 71ceabe80eSEugene Leviant return true; 721602421cSRui Ueyama SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 731602421cSRui Ueyama return B && B->isUndefined(); 74ceabe80eSEugene Leviant } 75ceabe80eSEugene Leviant 76076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 77076fe157SGeorge Rimar return C->Kind == AssignmentKind; 78076fe157SGeorge Rimar } 79076fe157SGeorge Rimar 80076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 81076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 82076fe157SGeorge Rimar } 83076fe157SGeorge Rimar 84eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 85eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 86eea3114fSGeorge Rimar } 87eea3114fSGeorge Rimar 88eefa758eSGeorge Rimar bool AssertCommand::classof(const BaseCommand *C) { 89eefa758eSGeorge Rimar return C->Kind == AssertKind; 90eefa758eSGeorge Rimar } 91eefa758eSGeorge Rimar 9236a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) { 93eea3114fSGeorge Rimar return !S || !S->Live; 94717677afSRui Ueyama } 95717677afSRui Ueyama 96f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::LinkerScript() {} 97f34d0e08SRui Ueyama template <class ELFT> LinkerScript<ELFT>::~LinkerScript() {} 98f34d0e08SRui Ueyama 9907320e40SRui Ueyama template <class ELFT> 10007320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 101c91930a1SGeorge Rimar for (Regex *Re : Opt.KeptSections) 102042a3f20SRafael Espindola if (Re->match(S->Name)) 103eea3114fSGeorge Rimar return true; 104eea3114fSGeorge Rimar return false; 105eea3114fSGeorge Rimar } 106eea3114fSGeorge Rimar 1070659800eSGeorge Rimar static bool fileMatches(const InputSectionDescription *Desc, 1080659800eSGeorge Rimar StringRef Filename) { 109c91930a1SGeorge Rimar return const_cast<Regex &>(Desc->FileRe).match(Filename) && 110c91930a1SGeorge Rimar !const_cast<Regex &>(Desc->ExcludedFileRe).match(Filename); 1110659800eSGeorge Rimar } 1120659800eSGeorge Rimar 1136b274810SRui Ueyama // Returns input sections filtered by given glob patterns. 1146b274810SRui Ueyama template <class ELFT> 1156b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *> 116ad10c3d8SRui Ueyama LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) { 117c91930a1SGeorge Rimar const Regex &Re = I->SectionRe; 1186b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 1196b274810SRui Ueyama for (const std::unique_ptr<ObjectFile<ELFT>> &F : 1200659800eSGeorge Rimar Symtab<ELFT>::X->getObjectFiles()) { 1210659800eSGeorge Rimar if (fileMatches(I, sys::path::filename(F->getName()))) 1226b274810SRui Ueyama for (InputSectionBase<ELFT> *S : F->getSections()) 1230659800eSGeorge Rimar if (!isDiscarded(S) && !S->OutSec && 124042a3f20SRafael Espindola const_cast<Regex &>(Re).match(S->Name)) 1256b274810SRui Ueyama Ret.push_back(S); 1260659800eSGeorge Rimar } 1273e6b0277SEugene Leviant 128c91930a1SGeorge Rimar if (const_cast<Regex &>(Re).match("COMMON")) 129ad10c3d8SRui Ueyama Ret.push_back(CommonInputSection<ELFT>::X); 1306b274810SRui Ueyama return Ret; 1316b274810SRui Ueyama } 1326b274810SRui Ueyama 133c0028d3dSRafael Espindola static bool compareName(InputSectionData *A, InputSectionData *B) { 134042a3f20SRafael Espindola return A->Name < B->Name; 1350702c4e8SGeorge Rimar } 136742c3836SRui Ueyama 137c0028d3dSRafael Espindola static bool compareAlignment(InputSectionData *A, InputSectionData *B) { 138742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 139742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 140742c3836SRui Ueyama // This is compatible with GNU. 141742c3836SRui Ueyama return A->Alignment > B->Alignment; 142742c3836SRui Ueyama } 143742c3836SRui Ueyama 144c0028d3dSRafael Espindola static std::function<bool(InputSectionData *, InputSectionData *)> 145742c3836SRui Ueyama getComparator(SortKind K) { 146742c3836SRui Ueyama if (K == SortByName) 147c0028d3dSRafael Espindola return compareName; 148c0028d3dSRafael Espindola return compareAlignment; 149742c3836SRui Ueyama } 1500702c4e8SGeorge Rimar 1510702c4e8SGeorge Rimar template <class ELFT> 15248c3f1ceSRui Ueyama void LinkerScript<ELFT>::discard(OutputSectionCommand &Cmd) { 15348c3f1ceSRui Ueyama for (const std::unique_ptr<BaseCommand> &Base : Cmd.Commands) { 15448c3f1ceSRui Ueyama if (auto *Cmd = dyn_cast<InputSectionDescription>(Base.get())) { 15548c3f1ceSRui Ueyama for (InputSectionBase<ELFT> *S : getInputSections(Cmd)) { 15648c3f1ceSRui Ueyama S->Live = false; 15748c3f1ceSRui Ueyama reportDiscarded(S); 15848c3f1ceSRui Ueyama } 15948c3f1ceSRui Ueyama } 16048c3f1ceSRui Ueyama } 16148c3f1ceSRui Ueyama } 16248c3f1ceSRui Ueyama 1638f66df92SGeorge Rimar static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) { 1648f66df92SGeorge Rimar bool RO = (Kind == ConstraintKind::ReadOnly); 1658f66df92SGeorge Rimar bool RW = (Kind == ConstraintKind::ReadWrite); 1668f66df92SGeorge Rimar bool Writable = Flags & SHF_WRITE; 167adcdb664SRui Ueyama return !(RO && Writable) && !(RW && !Writable); 1688f66df92SGeorge Rimar } 1698f66df92SGeorge Rimar 17048c3f1ceSRui Ueyama template <class ELFT> 17106ae6836SGeorge Rimar static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 17206ae6836SGeorge Rimar ConstraintKind Kind) { 1738f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 1748f66df92SGeorge Rimar return true; 1758f66df92SGeorge Rimar return llvm::all_of(Sections, [=](InputSectionBase<ELFT> *Sec) { 1768f66df92SGeorge Rimar return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind); 17706ae6836SGeorge Rimar }); 17806ae6836SGeorge Rimar } 17906ae6836SGeorge Rimar 18006ae6836SGeorge Rimar template <class ELFT> 1810b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 18206ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 1830b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 18497403d15SEugene Leviant DenseSet<InputSectionBase<ELFT> *> SectionIndex; 185e7f912cdSRui Ueyama 18606ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 18706ae6836SGeorge Rimar if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) { 18806ae6836SGeorge Rimar if (shouldDefine<ELFT>(OutCmd)) 189db741e72SEugene Leviant addSymbol<ELFT>(OutCmd); 19097403d15SEugene Leviant OutCmd->GoesAfter = Ret.empty() ? nullptr : Ret.back(); 1910b9ce6a4SRui Ueyama continue; 1920b9ce6a4SRui Ueyama } 1930b9ce6a4SRui Ueyama 1940b9ce6a4SRui Ueyama auto *Cmd = cast<InputSectionDescription>(Base.get()); 1950b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> V = getInputSections(Cmd); 19606ae6836SGeorge Rimar if (!matchConstraints<ELFT>(V, OutCmd.Constraint)) 19706ae6836SGeorge Rimar continue; 1980b9ce6a4SRui Ueyama if (Cmd->SortInner) 199c0028d3dSRafael Espindola std::stable_sort(V.begin(), V.end(), getComparator(Cmd->SortInner)); 2000b9ce6a4SRui Ueyama if (Cmd->SortOuter) 201c0028d3dSRafael Espindola std::stable_sort(V.begin(), V.end(), getComparator(Cmd->SortOuter)); 20297403d15SEugene Leviant 20397403d15SEugene Leviant // Add all input sections corresponding to rule 'Cmd' to 20497403d15SEugene Leviant // resulting vector. We do not add duplicate input sections. 20597403d15SEugene Leviant for (InputSectionBase<ELFT> *S : V) 20697403d15SEugene Leviant if (SectionIndex.insert(S).second) 20797403d15SEugene Leviant Ret.push_back(S); 2080b9ce6a4SRui Ueyama } 2090b9ce6a4SRui Ueyama return Ret; 2100b9ce6a4SRui Ueyama } 2110b9ce6a4SRui Ueyama 2126c55f0e3SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::createAssignments() { 213e5d3ca50SPetr Hosek for (const std::unique_ptr<SymbolAssignment> &Cmd : Opt.Assignments) { 214e5d3ca50SPetr Hosek if (shouldDefine<ELFT>(Cmd.get())) 215e5d3ca50SPetr Hosek addRegular<ELFT>(Cmd.get()); 216e5d3ca50SPetr Hosek if (Cmd->Sym) 217e5d3ca50SPetr Hosek cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0); 218e5d3ca50SPetr Hosek } 219e5d3ca50SPetr Hosek } 220e5d3ca50SPetr Hosek 221e5d3ca50SPetr Hosek template <class ELFT> 2220b9ce6a4SRui Ueyama void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 22348c3f1ceSRui Ueyama for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) { 2242ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 2252ab5f73dSRui Ueyama if (shouldDefine<ELFT>(Cmd)) 2262ab5f73dSRui Ueyama addRegular<ELFT>(Cmd); 2272ab5f73dSRui Ueyama continue; 2282ab5f73dSRui Ueyama } 2292ab5f73dSRui Ueyama 230ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 23148c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 23248c3f1ceSRui Ueyama discard(*Cmd); 23348c3f1ceSRui Ueyama continue; 23448c3f1ceSRui Ueyama } 2350b9ce6a4SRui Ueyama 2360b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 23797403d15SEugene Leviant if (V.empty()) 2380b9ce6a4SRui Ueyama continue; 2390b9ce6a4SRui Ueyama 240a14b13d8SGeorge Rimar for (InputSectionBase<ELFT> *Sec : V) { 2410b9ce6a4SRui Ueyama OutputSectionBase<ELFT> *OutSec; 2420b9ce6a4SRui Ueyama bool IsNew; 243a14b13d8SGeorge Rimar std::tie(OutSec, IsNew) = Factory.create(Sec, Cmd->Name); 2440b9ce6a4SRui Ueyama if (IsNew) 2450b9ce6a4SRui Ueyama OutputSections->push_back(OutSec); 246db24d9c3SGeorge Rimar 247db24d9c3SGeorge Rimar uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0; 248a14b13d8SGeorge Rimar 249db24d9c3SGeorge Rimar if (Subalign) 250db24d9c3SGeorge Rimar Sec->Alignment = Subalign; 2510b9ce6a4SRui Ueyama OutSec->addSection(Sec); 252eea3114fSGeorge Rimar } 25348c3f1ceSRui Ueyama } 254db24d9c3SGeorge Rimar } 255e63d81bdSEugene Leviant 2560b9ce6a4SRui Ueyama // Add orphan sections. 2576b274810SRui Ueyama for (const std::unique_ptr<ObjectFile<ELFT>> &F : 2580b9ce6a4SRui Ueyama Symtab<ELFT>::X->getObjectFiles()) { 2590b9ce6a4SRui Ueyama for (InputSectionBase<ELFT> *S : F->getSections()) { 2602ab5f73dSRui Ueyama if (isDiscarded(S) || S->OutSec) 2612ab5f73dSRui Ueyama continue; 2620b9ce6a4SRui Ueyama OutputSectionBase<ELFT> *OutSec; 2630b9ce6a4SRui Ueyama bool IsNew; 2640b9ce6a4SRui Ueyama std::tie(OutSec, IsNew) = Factory.create(S, getOutputSectionName(S)); 2650b9ce6a4SRui Ueyama if (IsNew) 2660b9ce6a4SRui Ueyama OutputSections->push_back(OutSec); 2670b9ce6a4SRui Ueyama OutSec->addSection(S); 2680b9ce6a4SRui Ueyama } 2690b9ce6a4SRui Ueyama } 270e63d81bdSEugene Leviant } 271e63d81bdSEugene Leviant 272db741e72SEugene Leviant // Sets value of a section-defined symbol. Two kinds of 273db741e72SEugene Leviant // symbols are processed: synthetic symbols, whose value 274db741e72SEugene Leviant // is an offset from beginning of section and regular 275db741e72SEugene Leviant // symbols whose value is absolute. 276db741e72SEugene Leviant template <class ELFT> 277db741e72SEugene Leviant static void assignSectionSymbol(SymbolAssignment *Cmd, 278db741e72SEugene Leviant OutputSectionBase<ELFT> *Sec, 279db741e72SEugene Leviant typename ELFT::uint Off) { 280db741e72SEugene Leviant if (!Cmd->Sym) 281db741e72SEugene Leviant return; 282db741e72SEugene Leviant 283db741e72SEugene Leviant if (auto *Body = dyn_cast<DefinedSynthetic<ELFT>>(Cmd->Sym)) { 284db741e72SEugene Leviant Body->Section = Sec; 285db741e72SEugene Leviant Body->Value = Cmd->Expression(Sec->getVA() + Off) - Sec->getVA(); 286db741e72SEugene Leviant return; 287db741e72SEugene Leviant } 288db741e72SEugene Leviant auto *Body = cast<DefinedRegular<ELFT>>(Cmd->Sym); 289db741e72SEugene Leviant Body->Value = Cmd->Expression(Sec->getVA() + Off); 290db741e72SEugene Leviant } 291db741e72SEugene Leviant 29220889c51SEugene Leviant // Linker script may define start and end symbols for special section types, 29320889c51SEugene Leviant // like .got, .eh_frame_hdr, .eh_frame and others. Those sections are not a list 29420889c51SEugene Leviant // of regular input input sections, therefore our way of defining symbols for 29520889c51SEugene Leviant // regular sections will not work. The approach we use for special section types 29620889c51SEugene Leviant // is not perfect - it handles only start and end symbols. 29720889c51SEugene Leviant template <class ELFT> 29820889c51SEugene Leviant void addStartEndSymbols(OutputSectionCommand *Cmd, 29920889c51SEugene Leviant OutputSectionBase<ELFT> *Sec) { 30020889c51SEugene Leviant bool Start = true; 30120889c51SEugene Leviant BaseCommand *PrevCmd = nullptr; 30220889c51SEugene Leviant 30320889c51SEugene Leviant for (std::unique_ptr<BaseCommand> &Base : Cmd->Commands) { 30420889c51SEugene Leviant if (auto *AssignCmd = dyn_cast<SymbolAssignment>(Base.get())) { 305db741e72SEugene Leviant assignSectionSymbol<ELFT>(AssignCmd, Sec, Start ? 0 : Sec->getSize()); 30620889c51SEugene Leviant } else { 30720889c51SEugene Leviant if (!Start && isa<SymbolAssignment>(PrevCmd)) 30820889c51SEugene Leviant error("section '" + Sec->getName() + 30920889c51SEugene Leviant "' supports only start and end symbols"); 31020889c51SEugene Leviant Start = false; 31120889c51SEugene Leviant } 31220889c51SEugene Leviant PrevCmd = Base.get(); 31320889c51SEugene Leviant } 31420889c51SEugene Leviant } 31520889c51SEugene Leviant 31620889c51SEugene Leviant template <class ELFT> 31720889c51SEugene Leviant void assignOffsets(OutputSectionCommand *Cmd, OutputSectionBase<ELFT> *Sec) { 318ceabe80eSEugene Leviant auto *OutSec = dyn_cast<OutputSection<ELFT>>(Sec); 3192de509c3SRui Ueyama if (!OutSec) { 3202de509c3SRui Ueyama Sec->assignOffsets(); 32120889c51SEugene Leviant // This section is not regular output section. However linker script may 32220889c51SEugene Leviant // have defined start/end symbols for it. This case is handled below. 32320889c51SEugene Leviant addStartEndSymbols(Cmd, Sec); 324ceabe80eSEugene Leviant return; 3252de509c3SRui Ueyama } 326ceabe80eSEugene Leviant typedef typename ELFT::uint uintX_t; 327ceabe80eSEugene Leviant uintX_t Off = 0; 32897403d15SEugene Leviant auto ItCmd = Cmd->Commands.begin(); 329ceabe80eSEugene Leviant 33097403d15SEugene Leviant // Assigns values to all symbols following the given 33197403d15SEugene Leviant // input section 'D' in output section 'Sec'. When symbols 33297403d15SEugene Leviant // are in the beginning of output section the value of 'D' 33397403d15SEugene Leviant // is nullptr. 33497403d15SEugene Leviant auto AssignSuccessors = [&](InputSectionData *D) { 33597403d15SEugene Leviant for (; ItCmd != Cmd->Commands.end(); ++ItCmd) { 33697403d15SEugene Leviant auto *AssignCmd = dyn_cast<SymbolAssignment>(ItCmd->get()); 33797403d15SEugene Leviant if (!AssignCmd) 33897403d15SEugene Leviant continue; 33997403d15SEugene Leviant if (D != AssignCmd->GoesAfter) 34097403d15SEugene Leviant break; 34197403d15SEugene Leviant 34297403d15SEugene Leviant if (AssignCmd->Name == ".") { 34397403d15SEugene Leviant // Update to location counter means update to section size. 344db741e72SEugene Leviant Off = AssignCmd->Expression(Sec->getVA() + Off) - Sec->getVA(); 34597403d15SEugene Leviant Sec->setSize(Off); 34697403d15SEugene Leviant continue; 34797403d15SEugene Leviant } 348db741e72SEugene Leviant assignSectionSymbol<ELFT>(AssignCmd, Sec, Off); 34997403d15SEugene Leviant } 35097403d15SEugene Leviant }; 35197403d15SEugene Leviant 35297403d15SEugene Leviant AssignSuccessors(nullptr); 35397403d15SEugene Leviant for (InputSection<ELFT> *I : OutSec->Sections) { 354ceabe80eSEugene Leviant Off = alignTo(Off, I->Alignment); 355ceabe80eSEugene Leviant I->OutSecOff = Off; 356ceabe80eSEugene Leviant Off += I->getSize(); 357ceabe80eSEugene Leviant // Update section size inside for-loop, so that SIZEOF 358ceabe80eSEugene Leviant // works correctly in the case below: 359ceabe80eSEugene Leviant // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 360ceabe80eSEugene Leviant Sec->setSize(Off); 36197403d15SEugene Leviant // Add symbols following current input section. 36297403d15SEugene Leviant AssignSuccessors(I); 363ceabe80eSEugene Leviant } 364ceabe80eSEugene Leviant } 365ceabe80eSEugene Leviant 3668f66df92SGeorge Rimar template <class ELFT> 367a14b13d8SGeorge Rimar static std::vector<OutputSectionBase<ELFT> *> 368a14b13d8SGeorge Rimar findSections(OutputSectionCommand &Cmd, 3698f66df92SGeorge Rimar ArrayRef<OutputSectionBase<ELFT> *> Sections) { 370a14b13d8SGeorge Rimar std::vector<OutputSectionBase<ELFT> *> Ret; 371a14b13d8SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : Sections) 372a14b13d8SGeorge Rimar if (Sec->getName() == Cmd.Name && 373a14b13d8SGeorge Rimar checkConstraint(Sec->getFlags(), Cmd.Constraint)) 374a14b13d8SGeorge Rimar Ret.push_back(Sec); 375a14b13d8SGeorge Rimar return Ret; 3768f66df92SGeorge Rimar } 3778f66df92SGeorge Rimar 378a4b41dcaSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::assignAddresses() { 379652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 3807c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 3817c18c28cSRui Ueyama // We place orphan sections at end of file. 3827c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 383652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 384e5cc668eSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 385652852c5SGeorge Rimar StringRef Name = Sec->getName(); 386c3e2a4b0SRui Ueyama if (getSectionIndex(Name) == INT_MAX) 387076fe157SGeorge Rimar Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name)); 388652852c5SGeorge Rimar } 389652852c5SGeorge Rimar 3907c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 3914f7500bfSRui Ueyama Dot = getHeaderSize(); 392467c4d55SEugene Leviant uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 393652852c5SGeorge Rimar uintX_t ThreadBssOffset = 0; 394652852c5SGeorge Rimar 395076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 396076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 3978d083e6aSRui Ueyama if (Cmd->Name == ".") { 3988d083e6aSRui Ueyama Dot = Cmd->Expression(Dot); 3998d083e6aSRui Ueyama } else if (Cmd->Sym) { 4008d083e6aSRui Ueyama cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot); 4018d083e6aSRui Ueyama } 40205ef4cffSRui Ueyama continue; 403652852c5SGeorge Rimar } 404652852c5SGeorge Rimar 405eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 406eefa758eSGeorge Rimar Cmd->Expression(Dot); 407eefa758eSGeorge Rimar continue; 408eefa758eSGeorge Rimar } 409eefa758eSGeorge Rimar 410076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 411a14b13d8SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : 412a14b13d8SGeorge Rimar findSections<ELFT>(*Cmd, *OutputSections)) { 413652852c5SGeorge Rimar 41458e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 41558e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 41658e5c4dcSGeorge Rimar 417630c6179SGeorge Rimar if (Cmd->AlignExpr) 418630c6179SGeorge Rimar Sec->updateAlignment(Cmd->AlignExpr(Dot)); 419630c6179SGeorge Rimar 420652852c5SGeorge Rimar if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { 421c998a8c0SRui Ueyama uintX_t TVA = Dot + ThreadBssOffset; 422424b4081SRui Ueyama TVA = alignTo(TVA, Sec->getAlignment()); 423652852c5SGeorge Rimar Sec->setVA(TVA); 42420889c51SEugene Leviant assignOffsets(Cmd, Sec); 425c998a8c0SRui Ueyama ThreadBssOffset = TVA - Dot + Sec->getSize(); 426652852c5SGeorge Rimar continue; 427652852c5SGeorge Rimar } 428652852c5SGeorge Rimar 429b6c52e8dSGeorge Rimar if (!(Sec->getFlags() & SHF_ALLOC)) { 43020889c51SEugene Leviant assignOffsets(Cmd, Sec); 431b6c52e8dSGeorge Rimar continue; 432b6c52e8dSGeorge Rimar } 433b6c52e8dSGeorge Rimar 434424b4081SRui Ueyama Dot = alignTo(Dot, Sec->getAlignment()); 435c998a8c0SRui Ueyama Sec->setVA(Dot); 43620889c51SEugene Leviant assignOffsets(Cmd, Sec); 437467c4d55SEugene Leviant MinVA = std::min(MinVA, Dot); 438c998a8c0SRui Ueyama Dot += Sec->getSize(); 439652852c5SGeorge Rimar } 440a14b13d8SGeorge Rimar } 441467c4d55SEugene Leviant 44264c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 443b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 444467c4d55SEugene Leviant MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() - 445467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->getSize(), 446467c4d55SEugene Leviant Target->PageSize); 447467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 448467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 449fb8978fcSDima Stepanov } 450652852c5SGeorge Rimar 451464daadcSRui Ueyama // Creates program headers as instructed by PHDRS linker script command. 45207320e40SRui Ueyama template <class ELFT> 453a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { 454edebbdf1SRui Ueyama std::vector<PhdrEntry<ELFT>> Ret; 455bbe38602SEugene Leviant 456464daadcSRui Ueyama // Process PHDRS and FILEHDR keywords because they are not 457464daadcSRui Ueyama // real output sections and cannot be added in the following loop. 458bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 459edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 460edebbdf1SRui Ueyama PhdrEntry<ELFT> &Phdr = Ret.back(); 461bbe38602SEugene Leviant 462bbe38602SEugene Leviant if (Cmd.HasFilehdr) 463adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 464bbe38602SEugene Leviant if (Cmd.HasPhdrs) 465adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 46656b21c86SEugene Leviant 46756b21c86SEugene Leviant if (Cmd.LMAExpr) { 46856b21c86SEugene Leviant Phdr.H.p_paddr = Cmd.LMAExpr(0); 46956b21c86SEugene Leviant Phdr.HasLMA = true; 47056b21c86SEugene Leviant } 471bbe38602SEugene Leviant } 472bbe38602SEugene Leviant 473464daadcSRui Ueyama // Add output sections to program headers. 474edebbdf1SRui Ueyama PhdrEntry<ELFT> *Load = nullptr; 475edebbdf1SRui Ueyama uintX_t Flags = PF_R; 476464daadcSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 477bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 478bbe38602SEugene Leviant break; 479bbe38602SEugene Leviant 480edebbdf1SRui Ueyama std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName()); 481bbe38602SEugene Leviant if (!PhdrIds.empty()) { 482bbe38602SEugene Leviant // Assign headers specified by linker script 483bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 484edebbdf1SRui Ueyama Ret[Id].add(Sec); 485865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 4860b113671SRafael Espindola Ret[Id].H.p_flags |= Sec->getPhdrFlags(); 487bbe38602SEugene Leviant } 488bbe38602SEugene Leviant } else { 489bbe38602SEugene Leviant // If we have no load segment or flags've changed then we want new load 490bbe38602SEugene Leviant // segment. 4910b113671SRafael Espindola uintX_t NewFlags = Sec->getPhdrFlags(); 492bbe38602SEugene Leviant if (Load == nullptr || Flags != NewFlags) { 493edebbdf1SRui Ueyama Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags); 494bbe38602SEugene Leviant Flags = NewFlags; 495bbe38602SEugene Leviant } 49618f084ffSRui Ueyama Load->add(Sec); 497bbe38602SEugene Leviant } 498bbe38602SEugene Leviant } 499edebbdf1SRui Ueyama return Ret; 500bbe38602SEugene Leviant } 501bbe38602SEugene Leviant 502f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 503f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 504f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 505f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 506f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 507f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 508f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 509f9bc3bd2SEugene Leviant } 510f9bc3bd2SEugene Leviant 511bbe38602SEugene Leviant template <class ELFT> 51207320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 513f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 514f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 515f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 516f6c3ccefSGeorge Rimar return Cmd->Filler; 517e2ee72b5SGeorge Rimar return {}; 518e2ee72b5SGeorge Rimar } 519e2ee72b5SGeorge Rimar 520206fffa1SGeorge Rimar template <class ELFT> Expr LinkerScript<ELFT>::getLma(StringRef Name) { 5218ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 5228ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 5238ceadb38SGeorge Rimar if (Cmd->LmaExpr && Cmd->Name == Name) 5248ceadb38SGeorge Rimar return Cmd->LmaExpr; 5258ceadb38SGeorge Rimar return {}; 5268ceadb38SGeorge Rimar } 5278ceadb38SGeorge Rimar 528c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 529c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 530c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 531c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 532076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 533f510fa6bSRui Ueyama int I = 0; 534f510fa6bSRui Ueyama for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 535076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 536076fe157SGeorge Rimar if (Cmd->Name == Name) 537f510fa6bSRui Ueyama return I; 538f510fa6bSRui Ueyama ++I; 539f510fa6bSRui Ueyama } 540f510fa6bSRui Ueyama return INT_MAX; 54171b26e94SGeorge Rimar } 54271b26e94SGeorge Rimar 54371b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if 54471b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0. 54507320e40SRui Ueyama template <class ELFT> 54607320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 547c3e2a4b0SRui Ueyama int I = getSectionIndex(A); 548c3e2a4b0SRui Ueyama int J = getSectionIndex(B); 549c3e2a4b0SRui Ueyama if (I == INT_MAX && J == INT_MAX) 550717677afSRui Ueyama return 0; 551717677afSRui Ueyama return I < J ? -1 : 1; 552717677afSRui Ueyama } 553717677afSRui Ueyama 554bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 555bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 556bbe38602SEugene Leviant } 557bbe38602SEugene Leviant 5589e69450eSGeorge Rimar template <class ELFT> 559884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) { 56096659df0SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 56196659df0SGeorge Rimar if (Sec->getName() == Name) 56296659df0SGeorge Rimar return Sec->getVA(); 56396659df0SGeorge Rimar error("undefined section " + Name); 56496659df0SGeorge Rimar return 0; 56596659df0SGeorge Rimar } 56696659df0SGeorge Rimar 56796659df0SGeorge Rimar template <class ELFT> 568884e786dSGeorge Rimar uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 5699e69450eSGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 5709e69450eSGeorge Rimar if (Sec->getName() == Name) 5719e69450eSGeorge Rimar return Sec->getSize(); 5729e69450eSGeorge Rimar error("undefined section " + Name); 5739e69450eSGeorge Rimar return 0; 5749e69450eSGeorge Rimar } 5759e69450eSGeorge Rimar 57636fac7f0SEugene Leviant template <class ELFT> 57736fac7f0SEugene Leviant uint64_t LinkerScript<ELFT>::getOutputSectionAlign(StringRef Name) { 57836fac7f0SEugene Leviant for (OutputSectionBase<ELFT> *Sec : *OutputSections) 57936fac7f0SEugene Leviant if (Sec->getName() == Name) 58036fac7f0SEugene Leviant return Sec->getAlignment(); 58136fac7f0SEugene Leviant error("undefined section " + Name); 58236fac7f0SEugene Leviant return 0; 58336fac7f0SEugene Leviant } 58436fac7f0SEugene Leviant 585884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() { 586e32a3598SGeorge Rimar return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 587e32a3598SGeorge Rimar } 588e32a3598SGeorge Rimar 589884e786dSGeorge Rimar template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) { 590884e786dSGeorge Rimar if (SymbolBody *B = Symtab<ELFT>::X->find(S)) 591884e786dSGeorge Rimar return B->getVA<ELFT>(); 592884e786dSGeorge Rimar error("symbol not found: " + S); 593884e786dSGeorge Rimar return 0; 594884e786dSGeorge Rimar } 595884e786dSGeorge Rimar 596bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 597bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 598bbe38602SEugene Leviant // PHDRS {} script block. 599bbe38602SEugene Leviant template <class ELFT> 600edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 601076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 602076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 603edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 60431d842f5SGeorge Rimar continue; 60531d842f5SGeorge Rimar 60629c5a2a9SRui Ueyama std::vector<size_t> Ret; 60729c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 60829c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 60929c5a2a9SRui Ueyama return Ret; 610bbe38602SEugene Leviant } 61131d842f5SGeorge Rimar return {}; 61231d842f5SGeorge Rimar } 613bbe38602SEugene Leviant 61429c5a2a9SRui Ueyama template <class ELFT> 61529c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 61629c5a2a9SRui Ueyama size_t I = 0; 61729c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 61829c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 61929c5a2a9SRui Ueyama return I; 62029c5a2a9SRui Ueyama ++I; 62129c5a2a9SRui Ueyama } 62229c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 62329c5a2a9SRui Ueyama return 0; 62429c5a2a9SRui Ueyama } 62529c5a2a9SRui Ueyama 62607320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 627c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 628c3794e58SGeorge Rimar 629f7c5fbb1SRui Ueyama public: 63007320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 631f23b2320SGeorge Rimar 63220b6598cSGeorge Rimar void readLinkerScript(); 63320b6598cSGeorge Rimar void readVersionScript(); 634f7c5fbb1SRui Ueyama 635f7c5fbb1SRui Ueyama private: 63652a1509eSRui Ueyama void addFile(StringRef Path); 63752a1509eSRui Ueyama 638f7c5fbb1SRui Ueyama void readAsNeeded(); 63990c5099eSDenis Protivensky void readEntry(); 64083f406cfSGeorge Rimar void readExtern(); 641f7c5fbb1SRui Ueyama void readGroup(); 64231aa1f83SRui Ueyama void readInclude(); 643ee59282bSRui Ueyama void readOutput(); 6449159ce93SDavide Italiano void readOutputArch(); 645f7c5fbb1SRui Ueyama void readOutputFormat(); 646bbe38602SEugene Leviant void readPhdrs(); 64768a39a65SDavide Italiano void readSearchDir(); 6488e3b38abSDenis Protivensky void readSections(); 64995769b4aSRui Ueyama void readVersion(); 65095769b4aSRui Ueyama void readVersionScriptCommand(); 6518e3b38abSDenis Protivensky 652113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 653ff1f29e0SGeorge Rimar std::vector<uint8_t> readFill(); 65410416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 655ff1f29e0SGeorge Rimar std::vector<uint8_t> readOutputSectionFiller(StringRef Tok); 656bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 657a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionDescription(StringRef Tok); 658c91930a1SGeorge Rimar Regex readFilePatterns(); 659a2496cbeSGeorge Rimar InputSectionDescription *readInputSectionRules(StringRef FilePattern); 660bbe38602SEugene Leviant unsigned readPhdrType(); 661742c3836SRui Ueyama SortKind readSortKind(); 662a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 663db741e72SEugene Leviant SymbolAssignment *readProvideOrAssignment(StringRef Tok, bool MakeAbsolute); 66403fc010eSGeorge Rimar void readSort(); 665eefa758eSGeorge Rimar Expr readAssert(); 666708019c4SRui Ueyama 667708019c4SRui Ueyama Expr readExpr(); 668708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 669708019c4SRui Ueyama Expr readPrimary(); 670708019c4SRui Ueyama Expr readTernary(Expr Cond); 6716ad7dfccSRui Ueyama Expr readParenExpr(); 672f7c5fbb1SRui Ueyama 67320b6598cSGeorge Rimar // For parsing version script. 67420b6598cSGeorge Rimar void readExtern(std::vector<SymbolVersion> *Globals); 67595769b4aSRui Ueyama void readVersionDeclaration(StringRef VerStr); 67620b6598cSGeorge Rimar void readGlobal(StringRef VerStr); 67720b6598cSGeorge Rimar void readLocal(); 67820b6598cSGeorge Rimar 67907320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 68007320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 68116b0cc9eSSimon Atanasyan bool IsUnderSysroot; 682f7c5fbb1SRui Ueyama }; 683f7c5fbb1SRui Ueyama 68420b6598cSGeorge Rimar void ScriptParser::readVersionScript() { 68595769b4aSRui Ueyama readVersionScriptCommand(); 68620b6598cSGeorge Rimar if (!atEOF()) 68795769b4aSRui Ueyama setError("EOF expected, but got " + next()); 68895769b4aSRui Ueyama } 68995769b4aSRui Ueyama 69095769b4aSRui Ueyama void ScriptParser::readVersionScriptCommand() { 69195769b4aSRui Ueyama if (skip("{")) { 69295769b4aSRui Ueyama readVersionDeclaration(""); 69320b6598cSGeorge Rimar return; 69420b6598cSGeorge Rimar } 69520b6598cSGeorge Rimar 69695769b4aSRui Ueyama while (!atEOF() && !Error && peek() != "}") { 69720b6598cSGeorge Rimar StringRef VerStr = next(); 69820b6598cSGeorge Rimar if (VerStr == "{") { 69995769b4aSRui Ueyama setError("anonymous version definition is used in " 70095769b4aSRui Ueyama "combination with other version definitions"); 70120b6598cSGeorge Rimar return; 70220b6598cSGeorge Rimar } 70320b6598cSGeorge Rimar expect("{"); 70495769b4aSRui Ueyama readVersionDeclaration(VerStr); 70520b6598cSGeorge Rimar } 70620b6598cSGeorge Rimar } 70720b6598cSGeorge Rimar 70895769b4aSRui Ueyama void ScriptParser::readVersion() { 70995769b4aSRui Ueyama expect("{"); 71095769b4aSRui Ueyama readVersionScriptCommand(); 71195769b4aSRui Ueyama expect("}"); 71295769b4aSRui Ueyama } 71395769b4aSRui Ueyama 71420b6598cSGeorge Rimar void ScriptParser::readLinkerScript() { 715f7c5fbb1SRui Ueyama while (!atEOF()) { 716f7c5fbb1SRui Ueyama StringRef Tok = next(); 717a27eeccaSRui Ueyama if (Tok == ";") 718a27eeccaSRui Ueyama continue; 719a27eeccaSRui Ueyama 720a27eeccaSRui Ueyama if (Tok == "ENTRY") { 721a27eeccaSRui Ueyama readEntry(); 722a27eeccaSRui Ueyama } else if (Tok == "EXTERN") { 723a27eeccaSRui Ueyama readExtern(); 724a27eeccaSRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 725a27eeccaSRui Ueyama readGroup(); 726a27eeccaSRui Ueyama } else if (Tok == "INCLUDE") { 727a27eeccaSRui Ueyama readInclude(); 728a27eeccaSRui Ueyama } else if (Tok == "OUTPUT") { 729a27eeccaSRui Ueyama readOutput(); 730a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 731a27eeccaSRui Ueyama readOutputArch(); 732a27eeccaSRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 733a27eeccaSRui Ueyama readOutputFormat(); 734a27eeccaSRui Ueyama } else if (Tok == "PHDRS") { 735a27eeccaSRui Ueyama readPhdrs(); 736a27eeccaSRui Ueyama } else if (Tok == "SEARCH_DIR") { 737a27eeccaSRui Ueyama readSearchDir(); 738a27eeccaSRui Ueyama } else if (Tok == "SECTIONS") { 739a27eeccaSRui Ueyama readSections(); 740a27eeccaSRui Ueyama } else if (Tok == "VERSION") { 741a27eeccaSRui Ueyama readVersion(); 742db741e72SEugene Leviant } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok, true)) { 743e5d3ca50SPetr Hosek if (Opt.HasContents) 7440df80befSPetr Hosek Opt.Commands.emplace_back(Cmd); 745c3794e58SGeorge Rimar else 746e5d3ca50SPetr Hosek Opt.Assignments.emplace_back(Cmd); 747e5d3ca50SPetr Hosek } else { 7485761042dSGeorge Rimar setError("unknown directive: " + Tok); 749f7c5fbb1SRui Ueyama } 750f7c5fbb1SRui Ueyama } 751e5d3ca50SPetr Hosek } 752f7c5fbb1SRui Ueyama 753717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 75416b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 75516b0cc9eSSimon Atanasyan SmallString<128> Path; 75616b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 75716b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 75816b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 75916b0cc9eSSimon Atanasyan return; 76016b0cc9eSSimon Atanasyan } 76116b0cc9eSSimon Atanasyan } 76216b0cc9eSSimon Atanasyan 763f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 76452a1509eSRui Ueyama Driver->addFile(S); 76552a1509eSRui Ueyama } else if (S.startswith("=")) { 76652a1509eSRui Ueyama if (Config->Sysroot.empty()) 76752a1509eSRui Ueyama Driver->addFile(S.substr(1)); 76852a1509eSRui Ueyama else 76952a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 77052a1509eSRui Ueyama } else if (S.startswith("-l")) { 77121eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 772a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 773a1b8fc3bSSimon Atanasyan Driver->addFile(S); 77452a1509eSRui Ueyama } else { 77552a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 77652a1509eSRui Ueyama if (Path.empty()) 777777f9630SGeorge Rimar setError("unable to find " + S); 778025d59b1SRui Ueyama else 77952a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 78052a1509eSRui Ueyama } 78152a1509eSRui Ueyama } 78252a1509eSRui Ueyama 783717677afSRui Ueyama void ScriptParser::readAsNeeded() { 784f7c5fbb1SRui Ueyama expect("("); 78535da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 78635da9b6eSRui Ueyama Config->AsNeeded = true; 787a2acc931SRui Ueyama while (!Error && !skip(")")) 788*cd574a5eSGeorge Rimar addFile(unquote(next())); 78935da9b6eSRui Ueyama Config->AsNeeded = Orig; 790f7c5fbb1SRui Ueyama } 791f7c5fbb1SRui Ueyama 792717677afSRui Ueyama void ScriptParser::readEntry() { 79390c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 79490c5099eSDenis Protivensky expect("("); 79590c5099eSDenis Protivensky StringRef Tok = next(); 79690c5099eSDenis Protivensky if (Config->Entry.empty()) 79790c5099eSDenis Protivensky Config->Entry = Tok; 79890c5099eSDenis Protivensky expect(")"); 79990c5099eSDenis Protivensky } 80090c5099eSDenis Protivensky 801717677afSRui Ueyama void ScriptParser::readExtern() { 80283f406cfSGeorge Rimar expect("("); 803a2acc931SRui Ueyama while (!Error && !skip(")")) 804a2acc931SRui Ueyama Config->Undefined.push_back(next()); 80583f406cfSGeorge Rimar } 80683f406cfSGeorge Rimar 807717677afSRui Ueyama void ScriptParser::readGroup() { 808f7c5fbb1SRui Ueyama expect("("); 809a2acc931SRui Ueyama while (!Error && !skip(")")) { 810f7c5fbb1SRui Ueyama StringRef Tok = next(); 811a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 812f7c5fbb1SRui Ueyama readAsNeeded(); 813a2acc931SRui Ueyama else 814*cd574a5eSGeorge Rimar addFile(unquote(Tok)); 815f7c5fbb1SRui Ueyama } 816f7c5fbb1SRui Ueyama } 817f7c5fbb1SRui Ueyama 818717677afSRui Ueyama void ScriptParser::readInclude() { 81931aa1f83SRui Ueyama StringRef Tok = next(); 820*cd574a5eSGeorge Rimar auto MBOrErr = MemoryBuffer::getFile(unquote(Tok)); 821025d59b1SRui Ueyama if (!MBOrErr) { 8225761042dSGeorge Rimar setError("cannot open " + Tok); 823025d59b1SRui Ueyama return; 824025d59b1SRui Ueyama } 82531aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 826a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 827a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 82831aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 82931aa1f83SRui Ueyama } 83031aa1f83SRui Ueyama 831717677afSRui Ueyama void ScriptParser::readOutput() { 832ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 833ee59282bSRui Ueyama expect("("); 834ee59282bSRui Ueyama StringRef Tok = next(); 835ee59282bSRui Ueyama if (Config->OutputFile.empty()) 836*cd574a5eSGeorge Rimar Config->OutputFile = unquote(Tok); 837ee59282bSRui Ueyama expect(")"); 838ee59282bSRui Ueyama } 839ee59282bSRui Ueyama 840717677afSRui Ueyama void ScriptParser::readOutputArch() { 8419159ce93SDavide Italiano // Error checking only for now. 8429159ce93SDavide Italiano expect("("); 8439159ce93SDavide Italiano next(); 8449159ce93SDavide Italiano expect(")"); 8459159ce93SDavide Italiano } 8469159ce93SDavide Italiano 847717677afSRui Ueyama void ScriptParser::readOutputFormat() { 848f7c5fbb1SRui Ueyama // Error checking only for now. 849f7c5fbb1SRui Ueyama expect("("); 850f7c5fbb1SRui Ueyama next(); 8516836c618SDavide Italiano StringRef Tok = next(); 8526836c618SDavide Italiano if (Tok == ")") 8536836c618SDavide Italiano return; 854025d59b1SRui Ueyama if (Tok != ",") { 8555761042dSGeorge Rimar setError("unexpected token: " + Tok); 856025d59b1SRui Ueyama return; 857025d59b1SRui Ueyama } 8586836c618SDavide Italiano next(); 8596836c618SDavide Italiano expect(","); 8606836c618SDavide Italiano next(); 861f7c5fbb1SRui Ueyama expect(")"); 862f7c5fbb1SRui Ueyama } 863f7c5fbb1SRui Ueyama 864bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 865bbe38602SEugene Leviant expect("{"); 866bbe38602SEugene Leviant while (!Error && !skip("}")) { 867bbe38602SEugene Leviant StringRef Tok = next(); 86856b21c86SEugene Leviant Opt.PhdrsCommands.push_back( 86956b21c86SEugene Leviant {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 870bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 871bbe38602SEugene Leviant 872bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 873bbe38602SEugene Leviant do { 874bbe38602SEugene Leviant Tok = next(); 875bbe38602SEugene Leviant if (Tok == ";") 876bbe38602SEugene Leviant break; 877bbe38602SEugene Leviant if (Tok == "FILEHDR") 878bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 879bbe38602SEugene Leviant else if (Tok == "PHDRS") 880bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 88156b21c86SEugene Leviant else if (Tok == "AT") 88256b21c86SEugene Leviant PhdrCmd.LMAExpr = readParenExpr(); 883865bf863SEugene Leviant else if (Tok == "FLAGS") { 884865bf863SEugene Leviant expect("("); 885eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 886eb685cd7SRafael Espindola // we accept expressions like ".|1". 887eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 888865bf863SEugene Leviant expect(")"); 889865bf863SEugene Leviant } else 890bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 891bbe38602SEugene Leviant } while (!Error); 892bbe38602SEugene Leviant } 893bbe38602SEugene Leviant } 894bbe38602SEugene Leviant 895717677afSRui Ueyama void ScriptParser::readSearchDir() { 89668a39a65SDavide Italiano expect("("); 89786c5fb82SRui Ueyama StringRef Tok = next(); 8986c7ad13fSRui Ueyama if (!Config->Nostdlib) 899*cd574a5eSGeorge Rimar Config->SearchPaths.push_back(unquote(Tok)); 90068a39a65SDavide Italiano expect(")"); 90168a39a65SDavide Italiano } 90268a39a65SDavide Italiano 903717677afSRui Ueyama void ScriptParser::readSections() { 9043de0a330SRui Ueyama Opt.HasContents = true; 9058e3b38abSDenis Protivensky expect("{"); 906652852c5SGeorge Rimar while (!Error && !skip("}")) { 907113cdec9SRui Ueyama StringRef Tok = next(); 908db741e72SEugene Leviant BaseCommand *Cmd = readProvideOrAssignment(Tok, true); 909ceabe80eSEugene Leviant if (!Cmd) { 910ceabe80eSEugene Leviant if (Tok == "ASSERT") 911eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 912ceabe80eSEugene Leviant else 91310416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 9148e3b38abSDenis Protivensky } 91510416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 916652852c5SGeorge Rimar } 917708019c4SRui Ueyama } 9188e3b38abSDenis Protivensky 919708019c4SRui Ueyama static int precedence(StringRef Op) { 920708019c4SRui Ueyama return StringSwitch<int>(Op) 921708019c4SRui Ueyama .Case("*", 4) 922708019c4SRui Ueyama .Case("/", 4) 923708019c4SRui Ueyama .Case("+", 3) 924708019c4SRui Ueyama .Case("-", 3) 925708019c4SRui Ueyama .Case("<", 2) 926708019c4SRui Ueyama .Case(">", 2) 927708019c4SRui Ueyama .Case(">=", 2) 928708019c4SRui Ueyama .Case("<=", 2) 929708019c4SRui Ueyama .Case("==", 2) 930708019c4SRui Ueyama .Case("!=", 2) 931708019c4SRui Ueyama .Case("&", 1) 932cc3dd629SRafael Espindola .Case("|", 1) 933708019c4SRui Ueyama .Default(-1); 934708019c4SRui Ueyama } 935708019c4SRui Ueyama 936c91930a1SGeorge Rimar Regex ScriptParser::readFilePatterns() { 93710416564SRui Ueyama std::vector<StringRef> V; 93810416564SRui Ueyama while (!Error && !skip(")")) 93910416564SRui Ueyama V.push_back(next()); 940c91930a1SGeorge Rimar return compileGlobPatterns(V); 9410702c4e8SGeorge Rimar } 9420702c4e8SGeorge Rimar 943742c3836SRui Ueyama SortKind ScriptParser::readSortKind() { 944742c3836SRui Ueyama if (skip("SORT") || skip("SORT_BY_NAME")) 945742c3836SRui Ueyama return SortByName; 946742c3836SRui Ueyama if (skip("SORT_BY_ALIGNMENT")) 947742c3836SRui Ueyama return SortByAlignment; 948742c3836SRui Ueyama return SortNone; 949742c3836SRui Ueyama } 950742c3836SRui Ueyama 951a2496cbeSGeorge Rimar InputSectionDescription * 952a2496cbeSGeorge Rimar ScriptParser::readInputSectionRules(StringRef FilePattern) { 953c91930a1SGeorge Rimar auto *Cmd = new InputSectionDescription(FilePattern); 9540ed42b0cSDavide Italiano expect("("); 955e7282797SDavide Italiano 956742c3836SRui Ueyama // Read EXCLUDE_FILE(). 957e7282797SDavide Italiano if (skip("EXCLUDE_FILE")) { 958e7282797SDavide Italiano expect("("); 959c91930a1SGeorge Rimar Cmd->ExcludedFileRe = readFilePatterns(); 960e7282797SDavide Italiano } 961e7282797SDavide Italiano 962742c3836SRui Ueyama // Read SORT(). 963742c3836SRui Ueyama if (SortKind K1 = readSortKind()) { 964742c3836SRui Ueyama Cmd->SortOuter = K1; 9650702c4e8SGeorge Rimar expect("("); 966742c3836SRui Ueyama if (SortKind K2 = readSortKind()) { 967742c3836SRui Ueyama Cmd->SortInner = K2; 968350ece4eSGeorge Rimar expect("("); 969c91930a1SGeorge Rimar Cmd->SectionRe = readFilePatterns(); 9700702c4e8SGeorge Rimar expect(")"); 971350ece4eSGeorge Rimar } else { 972c91930a1SGeorge Rimar Cmd->SectionRe = readFilePatterns(); 973350ece4eSGeorge Rimar } 974350ece4eSGeorge Rimar expect(")"); 97510416564SRui Ueyama return Cmd; 9760659800eSGeorge Rimar } 9770702c4e8SGeorge Rimar 978c91930a1SGeorge Rimar Cmd->SectionRe = readFilePatterns(); 97910416564SRui Ueyama return Cmd; 9800659800eSGeorge Rimar } 9810659800eSGeorge Rimar 982a2496cbeSGeorge Rimar InputSectionDescription * 983a2496cbeSGeorge Rimar ScriptParser::readInputSectionDescription(StringRef Tok) { 9840659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 9850659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 986a2496cbeSGeorge Rimar if (Tok == "KEEP") { 987e7282797SDavide Italiano expect("("); 988a2496cbeSGeorge Rimar StringRef FilePattern = next(); 989a2496cbeSGeorge Rimar InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 9900ed42b0cSDavide Italiano expect(")"); 991c91930a1SGeorge Rimar Opt.KeptSections.push_back(&Cmd->SectionRe); 99210416564SRui Ueyama return Cmd; 99310416564SRui Ueyama } 994a2496cbeSGeorge Rimar return readInputSectionRules(Tok); 9950659800eSGeorge Rimar } 9960659800eSGeorge Rimar 99703fc010eSGeorge Rimar void ScriptParser::readSort() { 99803fc010eSGeorge Rimar expect("("); 99903fc010eSGeorge Rimar expect("CONSTRUCTORS"); 100003fc010eSGeorge Rimar expect(")"); 100103fc010eSGeorge Rimar } 100203fc010eSGeorge Rimar 1003eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 1004eefa758eSGeorge Rimar expect("("); 1005eefa758eSGeorge Rimar Expr E = readExpr(); 1006eefa758eSGeorge Rimar expect(","); 1007*cd574a5eSGeorge Rimar StringRef Msg = unquote(next()); 1008eefa758eSGeorge Rimar expect(")"); 1009eefa758eSGeorge Rimar return [=](uint64_t Dot) { 1010eefa758eSGeorge Rimar uint64_t V = E(Dot); 1011eefa758eSGeorge Rimar if (!V) 1012eefa758eSGeorge Rimar error(Msg); 1013eefa758eSGeorge Rimar return V; 1014eefa758eSGeorge Rimar }; 1015eefa758eSGeorge Rimar } 1016eefa758eSGeorge Rimar 101725150e8bSRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 101825150e8bSRui Ueyama // alias for =fillexp section attribute, which is different from 101925150e8bSRui Ueyama // what GNU linkers do. 102025150e8bSRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 1021ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readFill() { 1022ff1f29e0SGeorge Rimar expect("("); 1023ff1f29e0SGeorge Rimar std::vector<uint8_t> V = readOutputSectionFiller(next()); 1024ff1f29e0SGeorge Rimar expect(")"); 1025ff1f29e0SGeorge Rimar expect(";"); 1026ff1f29e0SGeorge Rimar return V; 1027ff1f29e0SGeorge Rimar } 1028ff1f29e0SGeorge Rimar 102910416564SRui Ueyama OutputSectionCommand * 103010416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 1031076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 103258e5c4dcSGeorge Rimar 103358e5c4dcSGeorge Rimar // Read an address expression. 103458e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 103558e5c4dcSGeorge Rimar if (peek() != ":") 103658e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 103758e5c4dcSGeorge Rimar 10388e3b38abSDenis Protivensky expect(":"); 1039246f681eSDavide Italiano 10408ceadb38SGeorge Rimar if (skip("AT")) 10416ad7dfccSRui Ueyama Cmd->LmaExpr = readParenExpr(); 1042630c6179SGeorge Rimar if (skip("ALIGN")) 10436ad7dfccSRui Ueyama Cmd->AlignExpr = readParenExpr(); 1044db24d9c3SGeorge Rimar if (skip("SUBALIGN")) 1045db24d9c3SGeorge Rimar Cmd->SubalignExpr = readParenExpr(); 1046630c6179SGeorge Rimar 1047246f681eSDavide Italiano // Parse constraints. 1048246f681eSDavide Italiano if (skip("ONLY_IF_RO")) 1049efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 1050246f681eSDavide Italiano if (skip("ONLY_IF_RW")) 1051efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 10528e3b38abSDenis Protivensky expect("{"); 10538ec77e64SRui Ueyama 1054025d59b1SRui Ueyama while (!Error && !skip("}")) { 1055ceabe80eSEugene Leviant StringRef Tok = next(); 1056db741e72SEugene Leviant if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok, false)) 1057ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 1058ff1f29e0SGeorge Rimar else if (Tok == "FILL") 1059ff1f29e0SGeorge Rimar Cmd->Filler = readFill(); 1060ceabe80eSEugene Leviant else if (Tok == "SORT") 106103fc010eSGeorge Rimar readSort(); 1062a2496cbeSGeorge Rimar else if (peek() == "(") 1063a2496cbeSGeorge Rimar Cmd->Commands.emplace_back(readInputSectionDescription(Tok)); 1064ceabe80eSEugene Leviant else 1065ceabe80eSEugene Leviant setError("unknown command " + Tok); 10668e3b38abSDenis Protivensky } 1067076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 1068ff1f29e0SGeorge Rimar if (peek().startswith("=")) 1069ff1f29e0SGeorge Rimar Cmd->Filler = readOutputSectionFiller(next().drop_front()); 107010416564SRui Ueyama return Cmd; 1071f71caa2bSRui Ueyama } 10728ec77e64SRui Ueyama 10732c8f1f04SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 10742c8f1f04SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 10752c8f1f04SRui Ueyama // 10762c8f1f04SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 10772c8f1f04SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 10782c8f1f04SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 10792c8f1f04SRui Ueyama // because it's simpler than what ld.bfd does. 1080ff1f29e0SGeorge Rimar std::vector<uint8_t> ScriptParser::readOutputSectionFiller(StringRef Tok) { 1081965827d6SRui Ueyama uint32_t V; 1082ff1f29e0SGeorge Rimar if (Tok.getAsInteger(0, V)) { 1083965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 1084f71caa2bSRui Ueyama return {}; 1085e2ee72b5SGeorge Rimar } 1086965827d6SRui Ueyama return {uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V)}; 10878e3b38abSDenis Protivensky } 10888e3b38abSDenis Protivensky 1089a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1090a31c91b1SEugene Leviant expect("("); 1091174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1092a35e39caSPetr Hosek Cmd->Provide = Provide; 1093174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1094a31c91b1SEugene Leviant expect(")"); 1095a31c91b1SEugene Leviant expect(";"); 109610416564SRui Ueyama return Cmd; 1097eda81a1bSEugene Leviant } 1098eda81a1bSEugene Leviant 1099db741e72SEugene Leviant SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok, 1100db741e72SEugene Leviant bool MakeAbsolute) { 1101ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1102ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1103ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1104ceabe80eSEugene Leviant expect(";"); 1105ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1106a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1107a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1108a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1109ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1110a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1111ceabe80eSEugene Leviant } 1112db741e72SEugene Leviant if (Cmd && MakeAbsolute) 1113db741e72SEugene Leviant Cmd->IsAbsolute = true; 1114ceabe80eSEugene Leviant return Cmd; 1115ceabe80eSEugene Leviant } 1116ceabe80eSEugene Leviant 111730835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { 111830835ea4SGeorge Rimar if (S == ".") 111930835ea4SGeorge Rimar return Dot; 1120884e786dSGeorge Rimar return ScriptBase->getSymbolValue(S); 1121e32a3598SGeorge Rimar } 1122e32a3598SGeorge Rimar 112330835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 112430835ea4SGeorge Rimar StringRef Op = next(); 1125db741e72SEugene Leviant bool IsAbsolute = false; 1126db741e72SEugene Leviant Expr E; 112730835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 1128db741e72SEugene Leviant if (skip("ABSOLUTE")) { 1129db741e72SEugene Leviant E = readParenExpr(); 1130db741e72SEugene Leviant IsAbsolute = true; 1131db741e72SEugene Leviant } else { 1132db741e72SEugene Leviant E = readExpr(); 1133db741e72SEugene Leviant } 113430835ea4SGeorge Rimar if (Op == "+=") 113530835ea4SGeorge Rimar E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; 1136db741e72SEugene Leviant return new SymbolAssignment(Name, E, IsAbsolute); 113730835ea4SGeorge Rimar } 113830835ea4SGeorge Rimar 113930835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 114030835ea4SGeorge Rimar // script expression. 114130835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 114230835ea4SGeorge Rimar 114336c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 114436c1cd23SRui Ueyama if (Op == "*") 114536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 114636c1cd23SRui Ueyama if (Op == "/") { 114736c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 114836c1cd23SRui Ueyama uint64_t RHS = R(Dot); 114936c1cd23SRui Ueyama if (RHS == 0) { 115036c1cd23SRui Ueyama error("division by zero"); 115136c1cd23SRui Ueyama return 0; 115236c1cd23SRui Ueyama } 115336c1cd23SRui Ueyama return L(Dot) / RHS; 115436c1cd23SRui Ueyama }; 115536c1cd23SRui Ueyama } 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) { return L(Dot) - R(Dot); }; 116036c1cd23SRui Ueyama if (Op == "<") 116136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 116236c1cd23SRui Ueyama if (Op == ">") 116336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 116436c1cd23SRui Ueyama if (Op == ">=") 116536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 116636c1cd23SRui Ueyama if (Op == "<=") 116736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 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); }; 1174cc3dd629SRafael Espindola if (Op == "|") 1175cc3dd629SRafael Espindola return [=](uint64_t Dot) { return L(Dot) | R(Dot); }; 117636c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 117736c1cd23SRui Ueyama } 117836c1cd23SRui Ueyama 1179708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1180708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1181708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1182708019c4SRui Ueyama while (!atEOF() && !Error) { 1183708019c4SRui Ueyama // Read an operator and an expression. 1184708019c4SRui Ueyama StringRef Op1 = peek(); 1185708019c4SRui Ueyama if (Op1 == "?") 1186708019c4SRui Ueyama return readTernary(Lhs); 1187708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1188a31c91b1SEugene Leviant break; 1189a31c91b1SEugene Leviant next(); 1190708019c4SRui Ueyama Expr Rhs = readPrimary(); 1191708019c4SRui Ueyama 1192708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1193708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1194708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1195708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1196708019c4SRui Ueyama while (!atEOF()) { 1197708019c4SRui Ueyama StringRef Op2 = peek(); 1198708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1199eda81a1bSEugene Leviant break; 1200708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1201eda81a1bSEugene Leviant } 1202708019c4SRui Ueyama 1203708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1204708019c4SRui Ueyama } 1205708019c4SRui Ueyama return Lhs; 1206708019c4SRui Ueyama } 1207708019c4SRui Ueyama 1208708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1209e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1210708019c4SRui Ueyama return Target->PageSize; 1211e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1212e2cc07bcSMichael J. Spencer return Target->MaxPageSize; 1213708019c4SRui Ueyama error("unknown constant: " + S); 1214708019c4SRui Ueyama return 0; 1215708019c4SRui Ueyama } 1216708019c4SRui Ueyama 1217626e0b08SRui Ueyama // Parses Tok as an integer. Returns true if successful. 1218626e0b08SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 1219626e0b08SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 1220626e0b08SRui Ueyama // "M" (mega) prefixes. 12219f2f7ad9SGeorge Rimar static bool readInteger(StringRef Tok, uint64_t &Result) { 1222eaeafb2bSSimon Atanasyan if (Tok.startswith("-")) { 1223eaeafb2bSSimon Atanasyan if (!readInteger(Tok.substr(1), Result)) 1224eaeafb2bSSimon Atanasyan return false; 1225eaeafb2bSSimon Atanasyan Result = -Result; 1226eaeafb2bSSimon Atanasyan return true; 1227eaeafb2bSSimon Atanasyan } 12289f2f7ad9SGeorge Rimar if (Tok.startswith_lower("0x")) 12299f2f7ad9SGeorge Rimar return !Tok.substr(2).getAsInteger(16, Result); 12309f2f7ad9SGeorge Rimar if (Tok.endswith_lower("H")) 12319f2f7ad9SGeorge Rimar return !Tok.drop_back().getAsInteger(16, Result); 12329f2f7ad9SGeorge Rimar 12339f2f7ad9SGeorge Rimar int Suffix = 1; 12349f2f7ad9SGeorge Rimar if (Tok.endswith_lower("K")) { 12359f2f7ad9SGeorge Rimar Suffix = 1024; 12369f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 12379f2f7ad9SGeorge Rimar } else if (Tok.endswith_lower("M")) { 12389f2f7ad9SGeorge Rimar Suffix = 1024 * 1024; 12399f2f7ad9SGeorge Rimar Tok = Tok.drop_back(); 12409f2f7ad9SGeorge Rimar } 12419f2f7ad9SGeorge Rimar if (Tok.getAsInteger(10, Result)) 12429f2f7ad9SGeorge Rimar return false; 12439f2f7ad9SGeorge Rimar Result *= Suffix; 12449f2f7ad9SGeorge Rimar return true; 12459f2f7ad9SGeorge Rimar } 12469f2f7ad9SGeorge Rimar 1247708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 12486ad7dfccSRui Ueyama if (peek() == "(") 12496ad7dfccSRui Ueyama return readParenExpr(); 1250708019c4SRui Ueyama 12516ad7dfccSRui Ueyama StringRef Tok = next(); 1252708019c4SRui Ueyama 1253eaeafb2bSSimon Atanasyan if (Tok == "~") { 1254eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1255eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return ~E(Dot); }; 1256eaeafb2bSSimon Atanasyan } 1257eaeafb2bSSimon Atanasyan if (Tok == "-") { 1258eaeafb2bSSimon Atanasyan Expr E = readPrimary(); 1259eaeafb2bSSimon Atanasyan return [=](uint64_t Dot) { return -E(Dot); }; 1260eaeafb2bSSimon Atanasyan } 1261eaeafb2bSSimon Atanasyan 1262708019c4SRui Ueyama // Built-in functions are parsed here. 1263708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 126496659df0SGeorge Rimar if (Tok == "ADDR") { 126596659df0SGeorge Rimar expect("("); 126696659df0SGeorge Rimar StringRef Name = next(); 126796659df0SGeorge Rimar expect(")"); 1268884e786dSGeorge Rimar return 1269884e786dSGeorge Rimar [=](uint64_t Dot) { return ScriptBase->getOutputSectionAddress(Name); }; 127096659df0SGeorge Rimar } 1271eefa758eSGeorge Rimar if (Tok == "ASSERT") 1272eefa758eSGeorge Rimar return readAssert(); 1273708019c4SRui Ueyama if (Tok == "ALIGN") { 12746ad7dfccSRui Ueyama Expr E = readParenExpr(); 1275708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1276708019c4SRui Ueyama } 1277708019c4SRui Ueyama if (Tok == "CONSTANT") { 1278708019c4SRui Ueyama expect("("); 1279708019c4SRui Ueyama StringRef Tok = next(); 1280708019c4SRui Ueyama expect(")"); 1281708019c4SRui Ueyama return [=](uint64_t Dot) { return getConstant(Tok); }; 1282708019c4SRui Ueyama } 128354c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 128454c145ceSRafael Espindola expect("("); 128554c145ceSRafael Espindola next(); 128654c145ceSRafael Espindola expect(","); 128754c145ceSRafael Espindola uint64_t Val; 128854c145ceSRafael Espindola next().getAsInteger(0, Val); 128954c145ceSRafael Espindola expect(")"); 129054c145ceSRafael Espindola return [=](uint64_t Dot) { return Val; }; 129154c145ceSRafael Espindola } 1292708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1293708019c4SRui Ueyama expect("("); 1294708019c4SRui Ueyama Expr E = readExpr(); 1295708019c4SRui Ueyama expect(","); 1296708019c4SRui Ueyama readExpr(); 1297708019c4SRui Ueyama expect(")"); 1298f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1299708019c4SRui Ueyama } 1300708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1301708019c4SRui Ueyama expect("("); 1302708019c4SRui Ueyama expect("."); 1303708019c4SRui Ueyama expect(")"); 1304708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1305708019c4SRui Ueyama } 1306276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1307276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1308276b4e64SGeorge Rimar // the next page boundary for simplicity. 1309276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1310276b4e64SGeorge Rimar expect("("); 1311276b4e64SGeorge Rimar next(); 1312276b4e64SGeorge Rimar expect(","); 1313276b4e64SGeorge Rimar readExpr(); 1314276b4e64SGeorge Rimar expect(")"); 1315276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1316276b4e64SGeorge Rimar } 13179e69450eSGeorge Rimar if (Tok == "SIZEOF") { 13189e69450eSGeorge Rimar expect("("); 13199e69450eSGeorge Rimar StringRef Name = next(); 13209e69450eSGeorge Rimar expect(")"); 1321884e786dSGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; 13229e69450eSGeorge Rimar } 132336fac7f0SEugene Leviant if (Tok == "ALIGNOF") { 132436fac7f0SEugene Leviant expect("("); 132536fac7f0SEugene Leviant StringRef Name = next(); 132636fac7f0SEugene Leviant expect(")"); 132736fac7f0SEugene Leviant return 132836fac7f0SEugene Leviant [=](uint64_t Dot) { return ScriptBase->getOutputSectionAlign(Name); }; 132936fac7f0SEugene Leviant } 1330e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 1331884e786dSGeorge Rimar return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; 1332708019c4SRui Ueyama 13339f2f7ad9SGeorge Rimar // Tok is a literal number. 13349f2f7ad9SGeorge Rimar uint64_t V; 13359f2f7ad9SGeorge Rimar if (readInteger(Tok, V)) 13369f2f7ad9SGeorge Rimar return [=](uint64_t Dot) { return V; }; 13379f2f7ad9SGeorge Rimar 13389f2f7ad9SGeorge Rimar // Tok is a symbol name. 133930835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1340708019c4SRui Ueyama setError("malformed number: " + Tok); 134130835ea4SGeorge Rimar return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }; 1342a9c5a528SGeorge Rimar } 1343708019c4SRui Ueyama 1344708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1345708019c4SRui Ueyama next(); 1346708019c4SRui Ueyama Expr L = readExpr(); 1347708019c4SRui Ueyama expect(":"); 1348708019c4SRui Ueyama Expr R = readExpr(); 1349708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1350708019c4SRui Ueyama } 1351708019c4SRui Ueyama 13526ad7dfccSRui Ueyama Expr ScriptParser::readParenExpr() { 13536ad7dfccSRui Ueyama expect("("); 13546ad7dfccSRui Ueyama Expr E = readExpr(); 13556ad7dfccSRui Ueyama expect(")"); 13566ad7dfccSRui Ueyama return E; 13576ad7dfccSRui Ueyama } 13586ad7dfccSRui Ueyama 1359bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1360bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1361bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1362bbe38602SEugene Leviant StringRef Tok = next(); 1363bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 1364bbe38602SEugene Leviant if (Tok.empty()) { 1365bbe38602SEugene Leviant setError("section header name is empty"); 1366bbe38602SEugene Leviant break; 1367bbe38602SEugene Leviant } 1368bbe38602SEugene Leviant Phdrs.push_back(Tok); 1369bbe38602SEugene Leviant } 1370bbe38602SEugene Leviant return Phdrs; 1371bbe38602SEugene Leviant } 1372bbe38602SEugene Leviant 1373bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1374bbe38602SEugene Leviant StringRef Tok = next(); 1375b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1376b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1377b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1378b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1379b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1380b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1381b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1382b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1383b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1384b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1385b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1386b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1387b0f6c590SRui Ueyama .Default(-1); 1388bbe38602SEugene Leviant 1389b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1390b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1391b0f6c590SRui Ueyama return PT_NULL; 1392b0f6c590SRui Ueyama } 1393b0f6c590SRui Ueyama return Ret; 1394bbe38602SEugene Leviant } 1395bbe38602SEugene Leviant 139695769b4aSRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 139720b6598cSGeorge Rimar // Identifiers start at 2 because 0 and 1 are reserved 139820b6598cSGeorge Rimar // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. 139920b6598cSGeorge Rimar size_t VersionId = Config->VersionDefinitions.size() + 2; 140020b6598cSGeorge Rimar Config->VersionDefinitions.push_back({VerStr, VersionId}); 140120b6598cSGeorge Rimar 140220b6598cSGeorge Rimar if (skip("global:") || peek() != "local:") 140320b6598cSGeorge Rimar readGlobal(VerStr); 140420b6598cSGeorge Rimar if (skip("local:")) 140520b6598cSGeorge Rimar readLocal(); 140620b6598cSGeorge Rimar expect("}"); 140720b6598cSGeorge Rimar 140820b6598cSGeorge Rimar // Each version may have a parent version. For example, "Ver2" defined as 140920b6598cSGeorge Rimar // "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This 141020b6598cSGeorge Rimar // version hierarchy is, probably against your instinct, purely for human; the 141120b6598cSGeorge Rimar // runtime doesn't care about them at all. In LLD, we simply skip the token. 141220b6598cSGeorge Rimar if (!VerStr.empty() && peek() != ";") 141320b6598cSGeorge Rimar next(); 141420b6598cSGeorge Rimar expect(";"); 141520b6598cSGeorge Rimar } 141620b6598cSGeorge Rimar 141720b6598cSGeorge Rimar void ScriptParser::readLocal() { 141820b6598cSGeorge Rimar Config->DefaultSymbolVersion = VER_NDX_LOCAL; 141920b6598cSGeorge Rimar expect("*"); 142020b6598cSGeorge Rimar expect(";"); 142120b6598cSGeorge Rimar } 142220b6598cSGeorge Rimar 142320b6598cSGeorge Rimar void ScriptParser::readExtern(std::vector<SymbolVersion> *Globals) { 1424*cd574a5eSGeorge Rimar expect("\"C++\""); 142520b6598cSGeorge Rimar expect("{"); 142620b6598cSGeorge Rimar 142720b6598cSGeorge Rimar for (;;) { 142820b6598cSGeorge Rimar if (peek() == "}" || Error) 142920b6598cSGeorge Rimar break; 1430*cd574a5eSGeorge Rimar bool HasWildcard = !peek().startswith("\"") && hasWildcard(peek()); 1431*cd574a5eSGeorge Rimar Globals->push_back({unquote(next()), true, HasWildcard}); 143220b6598cSGeorge Rimar expect(";"); 143320b6598cSGeorge Rimar } 143420b6598cSGeorge Rimar 143520b6598cSGeorge Rimar expect("}"); 143620b6598cSGeorge Rimar expect(";"); 143720b6598cSGeorge Rimar } 143820b6598cSGeorge Rimar 143920b6598cSGeorge Rimar void ScriptParser::readGlobal(StringRef VerStr) { 144020b6598cSGeorge Rimar std::vector<SymbolVersion> *Globals; 144120b6598cSGeorge Rimar if (VerStr.empty()) 144220b6598cSGeorge Rimar Globals = &Config->VersionScriptGlobals; 144320b6598cSGeorge Rimar else 144420b6598cSGeorge Rimar Globals = &Config->VersionDefinitions.back().Globals; 144520b6598cSGeorge Rimar 144620b6598cSGeorge Rimar for (;;) { 144720b6598cSGeorge Rimar if (skip("extern")) 144820b6598cSGeorge Rimar readExtern(Globals); 144920b6598cSGeorge Rimar 145020b6598cSGeorge Rimar StringRef Cur = peek(); 145120b6598cSGeorge Rimar if (Cur == "}" || Cur == "local:" || Error) 145220b6598cSGeorge Rimar return; 145320b6598cSGeorge Rimar next(); 1454*cd574a5eSGeorge Rimar Globals->push_back({unquote(Cur), false, hasWildcard(Cur)}); 145520b6598cSGeorge Rimar expect(";"); 145620b6598cSGeorge Rimar } 145720b6598cSGeorge Rimar } 145820b6598cSGeorge Rimar 145916b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 146016b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 146116b0cc9eSSimon Atanasyan return false; 146216b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 146316b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 146416b0cc9eSSimon Atanasyan return true; 146516b0cc9eSSimon Atanasyan return false; 146616b0cc9eSSimon Atanasyan } 146716b0cc9eSSimon Atanasyan 146807320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 146916b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 147020b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).readLinkerScript(); 147120b6598cSGeorge Rimar } 147220b6598cSGeorge Rimar 147320b6598cSGeorge Rimar void elf::readVersionScript(MemoryBufferRef MB) { 147420b6598cSGeorge Rimar ScriptParser(MB.getBuffer(), false).readVersionScript(); 1475f7c5fbb1SRui Ueyama } 14761ebc8ed7SRui Ueyama 147707320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 147807320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 147907320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 148007320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1481