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) { 540c70d3ccSRui Ueyama Symbol *Sym = Symtab<ELFT>::X->addSynthetic(Cmd->Name, nullptr, 0); 551602421cSRui Ueyama Sym->Visibility = 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) { 958ec77e64SRui Ueyama for (StringRef Pat : Opt.KeptSections) 96722830a5SRui Ueyama if (globMatch(Pat, S->getSectionName())) 978ec77e64SRui Ueyama return true; 988ec77e64SRui Ueyama return false; 99481c2ce6SGeorge Rimar } 100481c2ce6SGeorge Rimar 10163dc6509SRui Ueyama static bool match(ArrayRef<StringRef> Patterns, StringRef S) { 10263dc6509SRui Ueyama for (StringRef Pat : Patterns) 10363dc6509SRui Ueyama if (globMatch(Pat, S)) 104eea3114fSGeorge Rimar return true; 105eea3114fSGeorge Rimar return false; 106eea3114fSGeorge Rimar } 107eea3114fSGeorge Rimar 1080659800eSGeorge Rimar static bool fileMatches(const InputSectionDescription *Desc, 1090659800eSGeorge Rimar StringRef Filename) { 1100659800eSGeorge Rimar if (!globMatch(Desc->FilePattern, Filename)) 1110659800eSGeorge Rimar return false; 1120659800eSGeorge Rimar return Desc->ExcludedFiles.empty() || !match(Desc->ExcludedFiles, Filename); 1130659800eSGeorge Rimar } 1140659800eSGeorge Rimar 1156b274810SRui Ueyama // Returns input sections filtered by given glob patterns. 1166b274810SRui Ueyama template <class ELFT> 1176b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *> 118ad10c3d8SRui Ueyama LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) { 1190659800eSGeorge Rimar ArrayRef<StringRef> Patterns = I->SectionPatterns; 1206b274810SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 1216b274810SRui Ueyama for (const std::unique_ptr<ObjectFile<ELFT>> &F : 1220659800eSGeorge Rimar Symtab<ELFT>::X->getObjectFiles()) { 1230659800eSGeorge Rimar if (fileMatches(I, sys::path::filename(F->getName()))) 1246b274810SRui Ueyama for (InputSectionBase<ELFT> *S : F->getSections()) 1250659800eSGeorge Rimar if (!isDiscarded(S) && !S->OutSec && 1260659800eSGeorge Rimar match(Patterns, S->getSectionName())) 1276b274810SRui Ueyama Ret.push_back(S); 1280659800eSGeorge Rimar } 1293e6b0277SEugene Leviant 1307ad9d6d2SRui Ueyama if (llvm::find(Patterns, "COMMON") != Patterns.end()) 131ad10c3d8SRui Ueyama Ret.push_back(CommonInputSection<ELFT>::X); 1323e6b0277SEugene Leviant 1336b274810SRui Ueyama return Ret; 1346b274810SRui Ueyama } 1356b274810SRui Ueyama 136dd81fe31SRui Ueyama // You can define new symbols using linker scripts. For example, 137dd81fe31SRui Ueyama // ".text { abc.o(.text); foo = .; def.o(.text); }" defines symbol 138dd81fe31SRui Ueyama // foo just after abc.o's text section contents. This class is to 139dd81fe31SRui Ueyama // handle such symbol definitions. 140dd81fe31SRui Ueyama // 141dd81fe31SRui Ueyama // In order to handle scripts like the above one, we want to 142dd81fe31SRui Ueyama // keep symbol definitions in output sections. Because output sections 143dd81fe31SRui Ueyama // can contain only input sections, we wrap symbol definitions 144dd81fe31SRui Ueyama // with dummy input sections. This class serves that purpose. 145f34d0e08SRui Ueyama template <class ELFT> 146f34d0e08SRui Ueyama class elf::LayoutInputSection : public InputSectionBase<ELFT> { 147ceabe80eSEugene Leviant public: 148f34d0e08SRui Ueyama explicit LayoutInputSection(SymbolAssignment *Cmd); 149ceabe80eSEugene Leviant static bool classof(const InputSectionBase<ELFT> *S); 150ceabe80eSEugene Leviant SymbolAssignment *Cmd; 151ceabe80eSEugene Leviant 152ceabe80eSEugene Leviant private: 153ceabe80eSEugene Leviant typename ELFT::Shdr Hdr; 154ceabe80eSEugene Leviant }; 155ceabe80eSEugene Leviant 1560b9ce6a4SRui Ueyama template <class ELFT> 1570b9ce6a4SRui Ueyama static InputSectionBase<ELFT> * 1580b9ce6a4SRui Ueyama getNonLayoutSection(std::vector<InputSectionBase<ELFT> *> &Vec) { 1590b9ce6a4SRui Ueyama for (InputSectionBase<ELFT> *S : Vec) 1600b9ce6a4SRui Ueyama if (!isa<LayoutInputSection<ELFT>>(S)) 1610b9ce6a4SRui Ueyama return S; 1620b9ce6a4SRui Ueyama return nullptr; 1630b9ce6a4SRui Ueyama } 164ceabe80eSEugene Leviant 165ceabe80eSEugene Leviant template <class T> static T *zero(T *Val) { 166ceabe80eSEugene Leviant memset(Val, 0, sizeof(*Val)); 167ceabe80eSEugene Leviant return Val; 168ceabe80eSEugene Leviant } 169ceabe80eSEugene Leviant 170ceabe80eSEugene Leviant template <class ELFT> 171ceabe80eSEugene Leviant LayoutInputSection<ELFT>::LayoutInputSection(SymbolAssignment *Cmd) 1722c3f5010SRui Ueyama : InputSectionBase<ELFT>(nullptr, zero(&Hdr), 1732c3f5010SRui Ueyama InputSectionBase<ELFT>::Layout), 1742c3f5010SRui Ueyama Cmd(Cmd) { 175ceabe80eSEugene Leviant this->Live = true; 176ceabe80eSEugene Leviant Hdr.sh_type = SHT_NOBITS; 177ceabe80eSEugene Leviant } 178ceabe80eSEugene Leviant 179ceabe80eSEugene Leviant template <class ELFT> 180ceabe80eSEugene Leviant bool LayoutInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) { 181ceabe80eSEugene Leviant return S->SectionKind == InputSectionBase<ELFT>::Layout; 182ceabe80eSEugene Leviant } 183ceabe80eSEugene Leviant 184ceabe80eSEugene Leviant template <class ELFT> 185742c3836SRui Ueyama static bool compareName(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) { 186742c3836SRui Ueyama return A->getSectionName() < B->getSectionName(); 1870702c4e8SGeorge Rimar } 188742c3836SRui Ueyama 189742c3836SRui Ueyama template <class ELFT> 190742c3836SRui Ueyama static bool compareAlignment(InputSectionBase<ELFT> *A, 191742c3836SRui Ueyama InputSectionBase<ELFT> *B) { 192742c3836SRui Ueyama // ">" is not a mistake. Larger alignments are placed before smaller 193742c3836SRui Ueyama // alignments in order to reduce the amount of padding necessary. 194742c3836SRui Ueyama // This is compatible with GNU. 195742c3836SRui Ueyama return A->Alignment > B->Alignment; 196742c3836SRui Ueyama } 197742c3836SRui Ueyama 198742c3836SRui Ueyama template <class ELFT> 199742c3836SRui Ueyama static std::function<bool(InputSectionBase<ELFT> *, InputSectionBase<ELFT> *)> 200742c3836SRui Ueyama getComparator(SortKind K) { 201742c3836SRui Ueyama if (K == SortByName) 202742c3836SRui Ueyama return compareName<ELFT>; 203742c3836SRui Ueyama return compareAlignment<ELFT>; 204742c3836SRui Ueyama } 2050702c4e8SGeorge Rimar 2060702c4e8SGeorge Rimar template <class ELFT> 20748c3f1ceSRui Ueyama void LinkerScript<ELFT>::discard(OutputSectionCommand &Cmd) { 20848c3f1ceSRui Ueyama for (const std::unique_ptr<BaseCommand> &Base : Cmd.Commands) { 20948c3f1ceSRui Ueyama if (auto *Cmd = dyn_cast<InputSectionDescription>(Base.get())) { 21048c3f1ceSRui Ueyama for (InputSectionBase<ELFT> *S : getInputSections(Cmd)) { 21148c3f1ceSRui Ueyama S->Live = false; 21248c3f1ceSRui Ueyama reportDiscarded(S); 21348c3f1ceSRui Ueyama } 21448c3f1ceSRui Ueyama } 21548c3f1ceSRui Ueyama } 21648c3f1ceSRui Ueyama } 21748c3f1ceSRui Ueyama 2188f66df92SGeorge Rimar static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) { 2198f66df92SGeorge Rimar bool RO = (Kind == ConstraintKind::ReadOnly); 2208f66df92SGeorge Rimar bool RW = (Kind == ConstraintKind::ReadWrite); 2218f66df92SGeorge Rimar bool Writable = Flags & SHF_WRITE; 2228f66df92SGeorge Rimar return !((RO && Writable) || (RW && !Writable)); 2238f66df92SGeorge Rimar } 2248f66df92SGeorge Rimar 22548c3f1ceSRui Ueyama template <class ELFT> 22606ae6836SGeorge Rimar static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections, 22706ae6836SGeorge Rimar ConstraintKind Kind) { 2288f66df92SGeorge Rimar if (Kind == ConstraintKind::NoConstraint) 2298f66df92SGeorge Rimar return true; 2308f66df92SGeorge Rimar return llvm::all_of(Sections, [=](InputSectionBase<ELFT> *Sec) { 2318f66df92SGeorge Rimar return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind); 23206ae6836SGeorge Rimar }); 23306ae6836SGeorge Rimar } 23406ae6836SGeorge Rimar 23506ae6836SGeorge Rimar template <class ELFT> 2360b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> 23706ae6836SGeorge Rimar LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { 2380b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> Ret; 239e7f912cdSRui Ueyama 24006ae6836SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : OutCmd.Commands) { 24106ae6836SGeorge Rimar if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get())) { 24206ae6836SGeorge Rimar if (shouldDefine<ELFT>(OutCmd)) 24306ae6836SGeorge Rimar addSynthetic<ELFT>(OutCmd); 24406ae6836SGeorge Rimar Ret.push_back(new (LAlloc.Allocate()) LayoutInputSection<ELFT>(OutCmd)); 2450b9ce6a4SRui Ueyama continue; 2460b9ce6a4SRui Ueyama } 2470b9ce6a4SRui Ueyama 2480b9ce6a4SRui Ueyama auto *Cmd = cast<InputSectionDescription>(Base.get()); 2490b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> V = getInputSections(Cmd); 25006ae6836SGeorge Rimar if (!matchConstraints<ELFT>(V, OutCmd.Constraint)) 25106ae6836SGeorge Rimar continue; 2520b9ce6a4SRui Ueyama if (Cmd->SortInner) 2530b9ce6a4SRui Ueyama std::stable_sort(V.begin(), V.end(), getComparator<ELFT>(Cmd->SortInner)); 2540b9ce6a4SRui Ueyama if (Cmd->SortOuter) 2550b9ce6a4SRui Ueyama std::stable_sort(V.begin(), V.end(), getComparator<ELFT>(Cmd->SortOuter)); 2560b9ce6a4SRui Ueyama Ret.insert(Ret.end(), V.begin(), V.end()); 2570b9ce6a4SRui Ueyama } 2580b9ce6a4SRui Ueyama return Ret; 2590b9ce6a4SRui Ueyama } 2600b9ce6a4SRui Ueyama 2610b9ce6a4SRui Ueyama template <class ELFT> 2620b9ce6a4SRui Ueyama void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 26348c3f1ceSRui Ueyama for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) { 2642ab5f73dSRui Ueyama if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { 2652ab5f73dSRui Ueyama if (shouldDefine<ELFT>(Cmd)) 2662ab5f73dSRui Ueyama addRegular<ELFT>(Cmd); 2672ab5f73dSRui Ueyama continue; 2682ab5f73dSRui Ueyama } 2692ab5f73dSRui Ueyama 270ceabe80eSEugene Leviant if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) { 27148c3f1ceSRui Ueyama if (Cmd->Name == "/DISCARD/") { 27248c3f1ceSRui Ueyama discard(*Cmd); 27348c3f1ceSRui Ueyama continue; 27448c3f1ceSRui Ueyama } 2750b9ce6a4SRui Ueyama 2760b9ce6a4SRui Ueyama std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd); 2770b9ce6a4SRui Ueyama InputSectionBase<ELFT> *Head = getNonLayoutSection<ELFT>(V); 2780b9ce6a4SRui Ueyama if (!Head) 2790b9ce6a4SRui Ueyama continue; 2800b9ce6a4SRui Ueyama 2810b9ce6a4SRui Ueyama OutputSectionBase<ELFT> *OutSec; 2820b9ce6a4SRui Ueyama bool IsNew; 2830b9ce6a4SRui Ueyama std::tie(OutSec, IsNew) = Factory.create(Head, Cmd->Name); 2840b9ce6a4SRui Ueyama if (IsNew) 2850b9ce6a4SRui Ueyama OutputSections->push_back(OutSec); 2860c70d3ccSRui Ueyama for (InputSectionBase<ELFT> *Sec : V) 2870b9ce6a4SRui Ueyama OutSec->addSection(Sec); 288eea3114fSGeorge Rimar } 28948c3f1ceSRui Ueyama } 290e63d81bdSEugene Leviant 2910b9ce6a4SRui Ueyama // Add orphan sections. 2926b274810SRui Ueyama for (const std::unique_ptr<ObjectFile<ELFT>> &F : 2930b9ce6a4SRui Ueyama Symtab<ELFT>::X->getObjectFiles()) { 2940b9ce6a4SRui Ueyama for (InputSectionBase<ELFT> *S : F->getSections()) { 2952ab5f73dSRui Ueyama if (isDiscarded(S) || S->OutSec) 2962ab5f73dSRui Ueyama continue; 2970b9ce6a4SRui Ueyama OutputSectionBase<ELFT> *OutSec; 2980b9ce6a4SRui Ueyama bool IsNew; 2990b9ce6a4SRui Ueyama std::tie(OutSec, IsNew) = Factory.create(S, getOutputSectionName(S)); 3000b9ce6a4SRui Ueyama if (IsNew) 3010b9ce6a4SRui Ueyama OutputSections->push_back(OutSec); 3020b9ce6a4SRui Ueyama OutSec->addSection(S); 3030b9ce6a4SRui Ueyama } 3040b9ce6a4SRui Ueyama } 305e63d81bdSEugene Leviant } 306e63d81bdSEugene Leviant 307ceabe80eSEugene Leviant template <class ELFT> void assignOffsets(OutputSectionBase<ELFT> *Sec) { 308ceabe80eSEugene Leviant auto *OutSec = dyn_cast<OutputSection<ELFT>>(Sec); 3092de509c3SRui Ueyama if (!OutSec) { 3102de509c3SRui Ueyama Sec->assignOffsets(); 311ceabe80eSEugene Leviant return; 3122de509c3SRui Ueyama } 313ceabe80eSEugene Leviant 314ceabe80eSEugene Leviant typedef typename ELFT::uint uintX_t; 315ceabe80eSEugene Leviant uintX_t Off = 0; 316ceabe80eSEugene Leviant 317ceabe80eSEugene Leviant for (InputSection<ELFT> *I : OutSec->Sections) { 318ceabe80eSEugene Leviant if (auto *L = dyn_cast<LayoutInputSection<ELFT>>(I)) { 319ceabe80eSEugene Leviant uintX_t Value = L->Cmd->Expression(Sec->getVA() + Off) - Sec->getVA(); 3200c70d3ccSRui Ueyama if (L->Cmd->Name == ".") { 321ceabe80eSEugene Leviant Off = Value; 322b6f1bb13SEugene Leviant } else if (auto *Sym = 323b6f1bb13SEugene Leviant cast_or_null<DefinedSynthetic<ELFT>>(L->Cmd->Sym)) { 324b6f1bb13SEugene Leviant // shouldDefine could have returned false, so we need to check Sym, 325b6f1bb13SEugene Leviant // for non-null value. 3260c70d3ccSRui Ueyama Sym->Section = OutSec; 3270c70d3ccSRui Ueyama Sym->Value = Value; 3280c70d3ccSRui Ueyama } 329ceabe80eSEugene Leviant } else { 330ceabe80eSEugene Leviant Off = alignTo(Off, I->Alignment); 331ceabe80eSEugene Leviant I->OutSecOff = Off; 332ceabe80eSEugene Leviant Off += I->getSize(); 333ceabe80eSEugene Leviant } 334ceabe80eSEugene Leviant // Update section size inside for-loop, so that SIZEOF 335ceabe80eSEugene Leviant // works correctly in the case below: 336ceabe80eSEugene Leviant // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } 337ceabe80eSEugene Leviant Sec->setSize(Off); 338ceabe80eSEugene Leviant } 339ceabe80eSEugene Leviant } 340ceabe80eSEugene Leviant 3418f66df92SGeorge Rimar template <class ELFT> 3428f66df92SGeorge Rimar static OutputSectionBase<ELFT> * 3438f66df92SGeorge Rimar findSection(OutputSectionCommand &Cmd, 3448f66df92SGeorge Rimar ArrayRef<OutputSectionBase<ELFT> *> Sections) { 3458f66df92SGeorge Rimar for (OutputSectionBase<ELFT> *Sec : Sections) { 3468f66df92SGeorge Rimar if (Sec->getName() != Cmd.Name) 3478f66df92SGeorge Rimar continue; 3488f66df92SGeorge Rimar if (checkConstraint(Sec->getFlags(), Cmd.Constraint)) 3498f66df92SGeorge Rimar return Sec; 3508f66df92SGeorge Rimar } 3518f66df92SGeorge Rimar return nullptr; 3528f66df92SGeorge Rimar } 3538f66df92SGeorge Rimar 354a4b41dcaSRafael Espindola template <class ELFT> void LinkerScript<ELFT>::assignAddresses() { 355652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 3567c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 3577c18c28cSRui Ueyama // We place orphan sections at end of file. 3587c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 359652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 360e5cc668eSRui Ueyama for (OutputSectionBase<ELFT> *Sec : *OutputSections) { 361652852c5SGeorge Rimar StringRef Name = Sec->getName(); 362c3e2a4b0SRui Ueyama if (getSectionIndex(Name) == INT_MAX) 363076fe157SGeorge Rimar Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name)); 364652852c5SGeorge Rimar } 365652852c5SGeorge Rimar 3667c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 3674f7500bfSRui Ueyama Dot = getHeaderSize(); 368467c4d55SEugene Leviant uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 369652852c5SGeorge Rimar uintX_t ThreadBssOffset = 0; 370652852c5SGeorge Rimar 371076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 372076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 3738d083e6aSRui Ueyama if (Cmd->Name == ".") { 3748d083e6aSRui Ueyama Dot = Cmd->Expression(Dot); 3758d083e6aSRui Ueyama } else if (Cmd->Sym) { 3768d083e6aSRui Ueyama cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot); 3778d083e6aSRui Ueyama } 37805ef4cffSRui Ueyama continue; 379652852c5SGeorge Rimar } 380652852c5SGeorge Rimar 381eefa758eSGeorge Rimar if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) { 382eefa758eSGeorge Rimar Cmd->Expression(Dot); 383eefa758eSGeorge Rimar continue; 384eefa758eSGeorge Rimar } 385eefa758eSGeorge Rimar 386076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 3878f66df92SGeorge Rimar OutputSectionBase<ELFT> *Sec = findSection<ELFT>(*Cmd, *OutputSections); 3888f66df92SGeorge Rimar if (!Sec) 389652852c5SGeorge Rimar continue; 390652852c5SGeorge Rimar 39158e5c4dcSGeorge Rimar if (Cmd->AddrExpr) 39258e5c4dcSGeorge Rimar Dot = Cmd->AddrExpr(Dot); 39358e5c4dcSGeorge Rimar 394630c6179SGeorge Rimar if (Cmd->AlignExpr) 395630c6179SGeorge Rimar Sec->updateAlignment(Cmd->AlignExpr(Dot)); 396630c6179SGeorge Rimar 397652852c5SGeorge Rimar if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { 398c998a8c0SRui Ueyama uintX_t TVA = Dot + ThreadBssOffset; 399424b4081SRui Ueyama TVA = alignTo(TVA, Sec->getAlignment()); 400652852c5SGeorge Rimar Sec->setVA(TVA); 401ceabe80eSEugene Leviant assignOffsets(Sec); 402c998a8c0SRui Ueyama ThreadBssOffset = TVA - Dot + Sec->getSize(); 403652852c5SGeorge Rimar continue; 404652852c5SGeorge Rimar } 405652852c5SGeorge Rimar 406b6c52e8dSGeorge Rimar if (!(Sec->getFlags() & SHF_ALLOC)) { 407b6c52e8dSGeorge Rimar Sec->assignOffsets(); 408b6c52e8dSGeorge Rimar continue; 409b6c52e8dSGeorge Rimar } 410b6c52e8dSGeorge Rimar 411424b4081SRui Ueyama Dot = alignTo(Dot, Sec->getAlignment()); 412c998a8c0SRui Ueyama Sec->setVA(Dot); 413ceabe80eSEugene Leviant assignOffsets(Sec); 414467c4d55SEugene Leviant MinVA = std::min(MinVA, Dot); 415c998a8c0SRui Ueyama Dot += Sec->getSize(); 416652852c5SGeorge Rimar } 417467c4d55SEugene Leviant 41864c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 419b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 420467c4d55SEugene Leviant MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() - 421467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->getSize(), 422467c4d55SEugene Leviant Target->PageSize); 423467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 424467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 425fb8978fcSDima Stepanov } 426652852c5SGeorge Rimar 42707320e40SRui Ueyama template <class ELFT> 428a4b41dcaSRafael Espindola std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { 429a4b41dcaSRafael Espindola ArrayRef<OutputSectionBase<ELFT> *> Sections = *OutputSections; 430edebbdf1SRui Ueyama std::vector<PhdrEntry<ELFT>> Ret; 431bbe38602SEugene Leviant 432bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 433edebbdf1SRui Ueyama Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 434edebbdf1SRui Ueyama PhdrEntry<ELFT> &Phdr = Ret.back(); 435bbe38602SEugene Leviant 436bbe38602SEugene Leviant if (Cmd.HasFilehdr) 437adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 438bbe38602SEugene Leviant if (Cmd.HasPhdrs) 439adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 440bbe38602SEugene Leviant 441bbe38602SEugene Leviant switch (Cmd.Type) { 442bbe38602SEugene Leviant case PT_INTERP: 443fd03cfd2SRui Ueyama if (Out<ELFT>::Interp) 444adca245fSRui Ueyama Phdr.add(Out<ELFT>::Interp); 445bbe38602SEugene Leviant break; 446bbe38602SEugene Leviant case PT_DYNAMIC: 4471034c9e3SRui Ueyama if (Out<ELFT>::DynSymTab) { 4480b113671SRafael Espindola Phdr.H.p_flags = Out<ELFT>::Dynamic->getPhdrFlags(); 449adca245fSRui Ueyama Phdr.add(Out<ELFT>::Dynamic); 450bbe38602SEugene Leviant } 451bbe38602SEugene Leviant break; 452bbe38602SEugene Leviant case PT_GNU_EH_FRAME: 453bbe38602SEugene Leviant if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) { 4540b113671SRafael Espindola Phdr.H.p_flags = Out<ELFT>::EhFrameHdr->getPhdrFlags(); 455adca245fSRui Ueyama Phdr.add(Out<ELFT>::EhFrameHdr); 456bbe38602SEugene Leviant } 457bbe38602SEugene Leviant break; 458bbe38602SEugene Leviant } 459bbe38602SEugene Leviant } 460bbe38602SEugene Leviant 461edebbdf1SRui Ueyama PhdrEntry<ELFT> *Load = nullptr; 462edebbdf1SRui Ueyama uintX_t Flags = PF_R; 463bbe38602SEugene Leviant for (OutputSectionBase<ELFT> *Sec : Sections) { 464bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 465bbe38602SEugene Leviant break; 466bbe38602SEugene Leviant 467edebbdf1SRui Ueyama std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName()); 468bbe38602SEugene Leviant if (!PhdrIds.empty()) { 469bbe38602SEugene Leviant // Assign headers specified by linker script 470bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 471edebbdf1SRui Ueyama Ret[Id].add(Sec); 472865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 4730b113671SRafael Espindola Ret[Id].H.p_flags |= Sec->getPhdrFlags(); 474bbe38602SEugene Leviant } 475bbe38602SEugene Leviant } else { 476bbe38602SEugene Leviant // If we have no load segment or flags've changed then we want new load 477bbe38602SEugene Leviant // segment. 4780b113671SRafael Espindola uintX_t NewFlags = Sec->getPhdrFlags(); 479bbe38602SEugene Leviant if (Load == nullptr || Flags != NewFlags) { 480edebbdf1SRui Ueyama Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags); 481bbe38602SEugene Leviant Flags = NewFlags; 482bbe38602SEugene Leviant } 48318f084ffSRui Ueyama Load->add(Sec); 484bbe38602SEugene Leviant } 485bbe38602SEugene Leviant } 486edebbdf1SRui Ueyama return Ret; 487bbe38602SEugene Leviant } 488bbe38602SEugene Leviant 489f9bc3bd2SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { 490f9bc3bd2SEugene Leviant // Ignore .interp section in case we have PHDRS specification 491f9bc3bd2SEugene Leviant // and PT_INTERP isn't listed. 492f9bc3bd2SEugene Leviant return !Opt.PhdrsCommands.empty() && 493f9bc3bd2SEugene Leviant llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { 494f9bc3bd2SEugene Leviant return Cmd.Type == PT_INTERP; 495f9bc3bd2SEugene Leviant }) == Opt.PhdrsCommands.end(); 496f9bc3bd2SEugene Leviant } 497f9bc3bd2SEugene Leviant 498bbe38602SEugene Leviant template <class ELFT> 49907320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 500f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 501f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 502f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 503f6c3ccefSGeorge Rimar return Cmd->Filler; 504e2ee72b5SGeorge Rimar return {}; 505e2ee72b5SGeorge Rimar } 506e2ee72b5SGeorge Rimar 507c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 508c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 509c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 510c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 511076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 512f510fa6bSRui Ueyama int I = 0; 513f510fa6bSRui Ueyama for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 514076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 515076fe157SGeorge Rimar if (Cmd->Name == Name) 516f510fa6bSRui Ueyama return I; 517f510fa6bSRui Ueyama ++I; 518f510fa6bSRui Ueyama } 519f510fa6bSRui Ueyama return INT_MAX; 52071b26e94SGeorge Rimar } 52171b26e94SGeorge Rimar 52271b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if 52371b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0. 52407320e40SRui Ueyama template <class ELFT> 52507320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 526c3e2a4b0SRui Ueyama int I = getSectionIndex(A); 527c3e2a4b0SRui Ueyama int J = getSectionIndex(B); 528c3e2a4b0SRui Ueyama if (I == INT_MAX && J == INT_MAX) 529717677afSRui Ueyama return 0; 530717677afSRui Ueyama return I < J ? -1 : 1; 531717677afSRui Ueyama } 532717677afSRui Ueyama 533bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 534bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 535bbe38602SEugene Leviant } 536bbe38602SEugene Leviant 5379e69450eSGeorge Rimar template <class ELFT> 5389e69450eSGeorge Rimar typename ELFT::uint LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 5399e69450eSGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 5409e69450eSGeorge Rimar if (Sec->getName() == Name) 5419e69450eSGeorge Rimar return Sec->getSize(); 5429e69450eSGeorge Rimar error("undefined section " + Name); 5439e69450eSGeorge Rimar return 0; 5449e69450eSGeorge Rimar } 5459e69450eSGeorge Rimar 546e32a3598SGeorge Rimar template <class ELFT> 5474f7500bfSRui Ueyama typename ELFT::uint LinkerScript<ELFT>::getHeaderSize() { 548e32a3598SGeorge Rimar return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 549e32a3598SGeorge Rimar } 550e32a3598SGeorge Rimar 551bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 552bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 553bbe38602SEugene Leviant // PHDRS {} script block. 554bbe38602SEugene Leviant template <class ELFT> 555edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 556076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 557076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 558edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 55931d842f5SGeorge Rimar continue; 56031d842f5SGeorge Rimar 56129c5a2a9SRui Ueyama std::vector<size_t> Ret; 56229c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 56329c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 56429c5a2a9SRui Ueyama return Ret; 565bbe38602SEugene Leviant } 56631d842f5SGeorge Rimar return {}; 56731d842f5SGeorge Rimar } 568bbe38602SEugene Leviant 56929c5a2a9SRui Ueyama template <class ELFT> 57029c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 57129c5a2a9SRui Ueyama size_t I = 0; 57229c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 57329c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 57429c5a2a9SRui Ueyama return I; 57529c5a2a9SRui Ueyama ++I; 57629c5a2a9SRui Ueyama } 57729c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 57829c5a2a9SRui Ueyama return 0; 57929c5a2a9SRui Ueyama } 58029c5a2a9SRui Ueyama 58107320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 582c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 583c3794e58SGeorge Rimar 584f7c5fbb1SRui Ueyama public: 58507320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 586f23b2320SGeorge Rimar 5874a46539cSRui Ueyama void run(); 588f7c5fbb1SRui Ueyama 589f7c5fbb1SRui Ueyama private: 59052a1509eSRui Ueyama void addFile(StringRef Path); 59152a1509eSRui Ueyama 592f7c5fbb1SRui Ueyama void readAsNeeded(); 59390c5099eSDenis Protivensky void readEntry(); 59483f406cfSGeorge Rimar void readExtern(); 595f7c5fbb1SRui Ueyama void readGroup(); 59631aa1f83SRui Ueyama void readInclude(); 597c3794e58SGeorge Rimar void readNothing() {} 598ee59282bSRui Ueyama void readOutput(); 5999159ce93SDavide Italiano void readOutputArch(); 600f7c5fbb1SRui Ueyama void readOutputFormat(); 601bbe38602SEugene Leviant void readPhdrs(); 60268a39a65SDavide Italiano void readSearchDir(); 6038e3b38abSDenis Protivensky void readSections(); 6048e3b38abSDenis Protivensky 605113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 60610416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 607f71caa2bSRui Ueyama std::vector<uint8_t> readOutputSectionFiller(); 608bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 60910416564SRui Ueyama InputSectionDescription *readInputSectionDescription(); 61010416564SRui Ueyama std::vector<StringRef> readInputFilePatterns(); 61110416564SRui Ueyama InputSectionDescription *readInputSectionRules(); 612bbe38602SEugene Leviant unsigned readPhdrType(); 613742c3836SRui Ueyama SortKind readSortKind(); 614a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 615ceabe80eSEugene Leviant SymbolAssignment *readProvideOrAssignment(StringRef Tok); 61610416564SRui Ueyama Expr readAlign(); 61703fc010eSGeorge Rimar void readSort(); 618eefa758eSGeorge Rimar Expr readAssert(); 619708019c4SRui Ueyama 620708019c4SRui Ueyama Expr readExpr(); 621708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 622708019c4SRui Ueyama Expr readPrimary(); 623708019c4SRui Ueyama Expr readTernary(Expr Cond); 624f7c5fbb1SRui Ueyama 625c3794e58SGeorge Rimar const static StringMap<Handler> Cmd; 62607320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 62707320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 62816b0cc9eSSimon Atanasyan bool IsUnderSysroot; 629f7c5fbb1SRui Ueyama }; 630f7c5fbb1SRui Ueyama 631e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = { 632c3794e58SGeorge Rimar {"ENTRY", &ScriptParser::readEntry}, 633c3794e58SGeorge Rimar {"EXTERN", &ScriptParser::readExtern}, 634c3794e58SGeorge Rimar {"GROUP", &ScriptParser::readGroup}, 635c3794e58SGeorge Rimar {"INCLUDE", &ScriptParser::readInclude}, 636c3794e58SGeorge Rimar {"INPUT", &ScriptParser::readGroup}, 637c3794e58SGeorge Rimar {"OUTPUT", &ScriptParser::readOutput}, 638c3794e58SGeorge Rimar {"OUTPUT_ARCH", &ScriptParser::readOutputArch}, 639c3794e58SGeorge Rimar {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat}, 640bbe38602SEugene Leviant {"PHDRS", &ScriptParser::readPhdrs}, 641c3794e58SGeorge Rimar {"SEARCH_DIR", &ScriptParser::readSearchDir}, 642c3794e58SGeorge Rimar {"SECTIONS", &ScriptParser::readSections}, 643c3794e58SGeorge Rimar {";", &ScriptParser::readNothing}}; 644c3794e58SGeorge Rimar 645717677afSRui Ueyama void ScriptParser::run() { 646f7c5fbb1SRui Ueyama while (!atEOF()) { 647f7c5fbb1SRui Ueyama StringRef Tok = next(); 648c3794e58SGeorge Rimar if (Handler Fn = Cmd.lookup(Tok)) 649c3794e58SGeorge Rimar (this->*Fn)(); 650c3794e58SGeorge Rimar else 6515761042dSGeorge Rimar setError("unknown directive: " + Tok); 652f7c5fbb1SRui Ueyama } 653f7c5fbb1SRui Ueyama } 654f7c5fbb1SRui Ueyama 655717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 65616b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 65716b0cc9eSSimon Atanasyan SmallString<128> Path; 65816b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 65916b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 66016b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 66116b0cc9eSSimon Atanasyan return; 66216b0cc9eSSimon Atanasyan } 66316b0cc9eSSimon Atanasyan } 66416b0cc9eSSimon Atanasyan 665f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 66652a1509eSRui Ueyama Driver->addFile(S); 66752a1509eSRui Ueyama } else if (S.startswith("=")) { 66852a1509eSRui Ueyama if (Config->Sysroot.empty()) 66952a1509eSRui Ueyama Driver->addFile(S.substr(1)); 67052a1509eSRui Ueyama else 67152a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 67252a1509eSRui Ueyama } else if (S.startswith("-l")) { 67321eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 674a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 675a1b8fc3bSSimon Atanasyan Driver->addFile(S); 67652a1509eSRui Ueyama } else { 67752a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 67852a1509eSRui Ueyama if (Path.empty()) 679777f9630SGeorge Rimar setError("unable to find " + S); 680025d59b1SRui Ueyama else 68152a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 68252a1509eSRui Ueyama } 68352a1509eSRui Ueyama } 68452a1509eSRui Ueyama 685717677afSRui Ueyama void ScriptParser::readAsNeeded() { 686f7c5fbb1SRui Ueyama expect("("); 68735da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 68835da9b6eSRui Ueyama Config->AsNeeded = true; 689a2acc931SRui Ueyama while (!Error && !skip(")")) 690a2acc931SRui Ueyama addFile(next()); 69135da9b6eSRui Ueyama Config->AsNeeded = Orig; 692f7c5fbb1SRui Ueyama } 693f7c5fbb1SRui Ueyama 694717677afSRui Ueyama void ScriptParser::readEntry() { 69590c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 69690c5099eSDenis Protivensky expect("("); 69790c5099eSDenis Protivensky StringRef Tok = next(); 69890c5099eSDenis Protivensky if (Config->Entry.empty()) 69990c5099eSDenis Protivensky Config->Entry = Tok; 70090c5099eSDenis Protivensky expect(")"); 70190c5099eSDenis Protivensky } 70290c5099eSDenis Protivensky 703717677afSRui Ueyama void ScriptParser::readExtern() { 70483f406cfSGeorge Rimar expect("("); 705a2acc931SRui Ueyama while (!Error && !skip(")")) 706a2acc931SRui Ueyama Config->Undefined.push_back(next()); 70783f406cfSGeorge Rimar } 70883f406cfSGeorge Rimar 709717677afSRui Ueyama void ScriptParser::readGroup() { 710f7c5fbb1SRui Ueyama expect("("); 711a2acc931SRui Ueyama while (!Error && !skip(")")) { 712f7c5fbb1SRui Ueyama StringRef Tok = next(); 713a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 714f7c5fbb1SRui Ueyama readAsNeeded(); 715a2acc931SRui Ueyama else 71652a1509eSRui Ueyama addFile(Tok); 717f7c5fbb1SRui Ueyama } 718f7c5fbb1SRui Ueyama } 719f7c5fbb1SRui Ueyama 720717677afSRui Ueyama void ScriptParser::readInclude() { 72131aa1f83SRui Ueyama StringRef Tok = next(); 72231aa1f83SRui Ueyama auto MBOrErr = MemoryBuffer::getFile(Tok); 723025d59b1SRui Ueyama if (!MBOrErr) { 7245761042dSGeorge Rimar setError("cannot open " + Tok); 725025d59b1SRui Ueyama return; 726025d59b1SRui Ueyama } 72731aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 728a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 729a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 73031aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 73131aa1f83SRui Ueyama } 73231aa1f83SRui Ueyama 733717677afSRui Ueyama void ScriptParser::readOutput() { 734ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 735ee59282bSRui Ueyama expect("("); 736ee59282bSRui Ueyama StringRef Tok = next(); 737ee59282bSRui Ueyama if (Config->OutputFile.empty()) 738ee59282bSRui Ueyama Config->OutputFile = Tok; 739ee59282bSRui Ueyama expect(")"); 740ee59282bSRui Ueyama } 741ee59282bSRui Ueyama 742717677afSRui Ueyama void ScriptParser::readOutputArch() { 7439159ce93SDavide Italiano // Error checking only for now. 7449159ce93SDavide Italiano expect("("); 7459159ce93SDavide Italiano next(); 7469159ce93SDavide Italiano expect(")"); 7479159ce93SDavide Italiano } 7489159ce93SDavide Italiano 749717677afSRui Ueyama void ScriptParser::readOutputFormat() { 750f7c5fbb1SRui Ueyama // Error checking only for now. 751f7c5fbb1SRui Ueyama expect("("); 752f7c5fbb1SRui Ueyama next(); 7536836c618SDavide Italiano StringRef Tok = next(); 7546836c618SDavide Italiano if (Tok == ")") 7556836c618SDavide Italiano return; 756025d59b1SRui Ueyama if (Tok != ",") { 7575761042dSGeorge Rimar setError("unexpected token: " + Tok); 758025d59b1SRui Ueyama return; 759025d59b1SRui Ueyama } 7606836c618SDavide Italiano next(); 7616836c618SDavide Italiano expect(","); 7626836c618SDavide Italiano next(); 763f7c5fbb1SRui Ueyama expect(")"); 764f7c5fbb1SRui Ueyama } 765f7c5fbb1SRui Ueyama 766bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 767bbe38602SEugene Leviant expect("{"); 768bbe38602SEugene Leviant while (!Error && !skip("}")) { 769bbe38602SEugene Leviant StringRef Tok = next(); 770865bf863SEugene Leviant Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX}); 771bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 772bbe38602SEugene Leviant 773bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 774bbe38602SEugene Leviant do { 775bbe38602SEugene Leviant Tok = next(); 776bbe38602SEugene Leviant if (Tok == ";") 777bbe38602SEugene Leviant break; 778bbe38602SEugene Leviant if (Tok == "FILEHDR") 779bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 780bbe38602SEugene Leviant else if (Tok == "PHDRS") 781bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 782865bf863SEugene Leviant else if (Tok == "FLAGS") { 783865bf863SEugene Leviant expect("("); 784eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 785eb685cd7SRafael Espindola // we accept expressions like ".|1". 786eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 787865bf863SEugene Leviant expect(")"); 788865bf863SEugene Leviant } else 789bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 790bbe38602SEugene Leviant } while (!Error); 791bbe38602SEugene Leviant } 792bbe38602SEugene Leviant } 793bbe38602SEugene Leviant 794717677afSRui Ueyama void ScriptParser::readSearchDir() { 79568a39a65SDavide Italiano expect("("); 79606501920SRafael Espindola Config->SearchPaths.push_back(next()); 79768a39a65SDavide Italiano expect(")"); 79868a39a65SDavide Italiano } 79968a39a65SDavide Italiano 800717677afSRui Ueyama void ScriptParser::readSections() { 8013de0a330SRui Ueyama Opt.HasContents = true; 8028e3b38abSDenis Protivensky expect("{"); 803652852c5SGeorge Rimar while (!Error && !skip("}")) { 804113cdec9SRui Ueyama StringRef Tok = next(); 805ceabe80eSEugene Leviant BaseCommand *Cmd = readProvideOrAssignment(Tok); 806ceabe80eSEugene Leviant if (!Cmd) { 807ceabe80eSEugene Leviant if (Tok == "ASSERT") 808eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 809ceabe80eSEugene Leviant else 81010416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 8118e3b38abSDenis Protivensky } 81210416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 813652852c5SGeorge Rimar } 814708019c4SRui Ueyama } 8158e3b38abSDenis Protivensky 816708019c4SRui Ueyama static int precedence(StringRef Op) { 817708019c4SRui Ueyama return StringSwitch<int>(Op) 818708019c4SRui Ueyama .Case("*", 4) 819708019c4SRui Ueyama .Case("/", 4) 820708019c4SRui Ueyama .Case("+", 3) 821708019c4SRui Ueyama .Case("-", 3) 822708019c4SRui Ueyama .Case("<", 2) 823708019c4SRui Ueyama .Case(">", 2) 824708019c4SRui Ueyama .Case(">=", 2) 825708019c4SRui Ueyama .Case("<=", 2) 826708019c4SRui Ueyama .Case("==", 2) 827708019c4SRui Ueyama .Case("!=", 2) 828708019c4SRui Ueyama .Case("&", 1) 829708019c4SRui Ueyama .Default(-1); 830708019c4SRui Ueyama } 831708019c4SRui Ueyama 83210416564SRui Ueyama std::vector<StringRef> ScriptParser::readInputFilePatterns() { 83310416564SRui Ueyama std::vector<StringRef> V; 83410416564SRui Ueyama while (!Error && !skip(")")) 83510416564SRui Ueyama V.push_back(next()); 83610416564SRui Ueyama return V; 8370702c4e8SGeorge Rimar } 8380702c4e8SGeorge Rimar 839742c3836SRui Ueyama SortKind ScriptParser::readSortKind() { 840742c3836SRui Ueyama if (skip("SORT") || skip("SORT_BY_NAME")) 841742c3836SRui Ueyama return SortByName; 842742c3836SRui Ueyama if (skip("SORT_BY_ALIGNMENT")) 843742c3836SRui Ueyama return SortByAlignment; 844742c3836SRui Ueyama return SortNone; 845742c3836SRui Ueyama } 846742c3836SRui Ueyama 84710416564SRui Ueyama InputSectionDescription *ScriptParser::readInputSectionRules() { 84810416564SRui Ueyama auto *Cmd = new InputSectionDescription; 84910416564SRui Ueyama Cmd->FilePattern = next(); 8500ed42b0cSDavide Italiano expect("("); 851e7282797SDavide Italiano 852742c3836SRui Ueyama // Read EXCLUDE_FILE(). 853e7282797SDavide Italiano if (skip("EXCLUDE_FILE")) { 854e7282797SDavide Italiano expect("("); 855e7282797SDavide Italiano while (!Error && !skip(")")) 85610416564SRui Ueyama Cmd->ExcludedFiles.push_back(next()); 857e7282797SDavide Italiano } 858e7282797SDavide Italiano 859742c3836SRui Ueyama // Read SORT(). 860742c3836SRui Ueyama if (SortKind K1 = readSortKind()) { 861742c3836SRui Ueyama Cmd->SortOuter = K1; 8620702c4e8SGeorge Rimar expect("("); 863742c3836SRui Ueyama if (SortKind K2 = readSortKind()) { 864742c3836SRui Ueyama Cmd->SortInner = K2; 865350ece4eSGeorge Rimar expect("("); 86610416564SRui Ueyama Cmd->SectionPatterns = readInputFilePatterns(); 8670702c4e8SGeorge Rimar expect(")"); 868350ece4eSGeorge Rimar } else { 86910416564SRui Ueyama Cmd->SectionPatterns = readInputFilePatterns(); 870350ece4eSGeorge Rimar } 871350ece4eSGeorge Rimar expect(")"); 87210416564SRui Ueyama return Cmd; 8730659800eSGeorge Rimar } 8740702c4e8SGeorge Rimar 87510416564SRui Ueyama Cmd->SectionPatterns = readInputFilePatterns(); 87610416564SRui Ueyama return Cmd; 8770659800eSGeorge Rimar } 8780659800eSGeorge Rimar 87910416564SRui Ueyama InputSectionDescription *ScriptParser::readInputSectionDescription() { 8800659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 8810659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 8820659800eSGeorge Rimar if (skip("KEEP")) { 883e7282797SDavide Italiano expect("("); 88410416564SRui Ueyama InputSectionDescription *Cmd = readInputSectionRules(); 8850ed42b0cSDavide Italiano expect(")"); 88610416564SRui Ueyama Opt.KeptSections.insert(Opt.KeptSections.end(), 88710416564SRui Ueyama Cmd->SectionPatterns.begin(), 88810416564SRui Ueyama Cmd->SectionPatterns.end()); 88910416564SRui Ueyama return Cmd; 89010416564SRui Ueyama } 89110416564SRui Ueyama return readInputSectionRules(); 8920659800eSGeorge Rimar } 8930659800eSGeorge Rimar 89410416564SRui Ueyama Expr ScriptParser::readAlign() { 895630c6179SGeorge Rimar expect("("); 89610416564SRui Ueyama Expr E = readExpr(); 897630c6179SGeorge Rimar expect(")"); 89810416564SRui Ueyama return E; 899630c6179SGeorge Rimar } 900630c6179SGeorge Rimar 90103fc010eSGeorge Rimar void ScriptParser::readSort() { 90203fc010eSGeorge Rimar expect("("); 90303fc010eSGeorge Rimar expect("CONSTRUCTORS"); 90403fc010eSGeorge Rimar expect(")"); 90503fc010eSGeorge Rimar } 90603fc010eSGeorge Rimar 907eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 908eefa758eSGeorge Rimar expect("("); 909eefa758eSGeorge Rimar Expr E = readExpr(); 910eefa758eSGeorge Rimar expect(","); 911eefa758eSGeorge Rimar StringRef Msg = next(); 912eefa758eSGeorge Rimar expect(")"); 913eefa758eSGeorge Rimar return [=](uint64_t Dot) { 914eefa758eSGeorge Rimar uint64_t V = E(Dot); 915eefa758eSGeorge Rimar if (!V) 916eefa758eSGeorge Rimar error(Msg); 917eefa758eSGeorge Rimar return V; 918eefa758eSGeorge Rimar }; 919eefa758eSGeorge Rimar } 920eefa758eSGeorge Rimar 92110416564SRui Ueyama OutputSectionCommand * 92210416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 923076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 92458e5c4dcSGeorge Rimar 92558e5c4dcSGeorge Rimar // Read an address expression. 92658e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 92758e5c4dcSGeorge Rimar if (peek() != ":") 92858e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 92958e5c4dcSGeorge Rimar 9308e3b38abSDenis Protivensky expect(":"); 931246f681eSDavide Italiano 932630c6179SGeorge Rimar if (skip("ALIGN")) 93310416564SRui Ueyama Cmd->AlignExpr = readAlign(); 934630c6179SGeorge Rimar 935246f681eSDavide Italiano // Parse constraints. 936246f681eSDavide Italiano if (skip("ONLY_IF_RO")) 937efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 938246f681eSDavide Italiano if (skip("ONLY_IF_RW")) 939efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 9408e3b38abSDenis Protivensky expect("{"); 9418ec77e64SRui Ueyama 942025d59b1SRui Ueyama while (!Error && !skip("}")) { 943f586ff7eSGeorge Rimar if (peek().startswith("*") || peek() == "KEEP") { 94410416564SRui Ueyama Cmd->Commands.emplace_back(readInputSectionDescription()); 9450659800eSGeorge Rimar continue; 9460659800eSGeorge Rimar } 947ceabe80eSEugene Leviant 948ceabe80eSEugene Leviant StringRef Tok = next(); 949ceabe80eSEugene Leviant if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) 950ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 951ceabe80eSEugene Leviant else if (Tok == "SORT") 95203fc010eSGeorge Rimar readSort(); 953ceabe80eSEugene Leviant else 954ceabe80eSEugene Leviant setError("unknown command " + Tok); 9558e3b38abSDenis Protivensky } 956076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 957f71caa2bSRui Ueyama Cmd->Filler = readOutputSectionFiller(); 95810416564SRui Ueyama return Cmd; 959f71caa2bSRui Ueyama } 9608ec77e64SRui Ueyama 961f71caa2bSRui Ueyama std::vector<uint8_t> ScriptParser::readOutputSectionFiller() { 962e2ee72b5SGeorge Rimar StringRef Tok = peek(); 963f71caa2bSRui Ueyama if (!Tok.startswith("=")) 964f71caa2bSRui Ueyama return {}; 9655ac0d7c5SDavide Italiano next(); 966965827d6SRui Ueyama 967965827d6SRui Ueyama // Read a hexstring of arbitrary length. 9685ac0d7c5SDavide Italiano if (Tok.startswith("=0x")) 9695ac0d7c5SDavide Italiano return parseHex(Tok.substr(3)); 9705ac0d7c5SDavide Italiano 971965827d6SRui Ueyama // Read a decimal or octal value as a big-endian 32 bit value. 972965827d6SRui Ueyama // Why do this? I don't know, but that's what gold does. 973965827d6SRui Ueyama uint32_t V; 974965827d6SRui Ueyama if (Tok.substr(1).getAsInteger(0, V)) { 975965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 976f71caa2bSRui Ueyama return {}; 977e2ee72b5SGeorge Rimar } 978965827d6SRui Ueyama return { uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V) }; 9798e3b38abSDenis Protivensky } 9808e3b38abSDenis Protivensky 981a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 982a31c91b1SEugene Leviant expect("("); 983174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 984a35e39caSPetr Hosek Cmd->Provide = Provide; 985174e0a16SRui Ueyama Cmd->Hidden = Hidden; 986a31c91b1SEugene Leviant expect(")"); 987a31c91b1SEugene Leviant expect(";"); 98810416564SRui Ueyama return Cmd; 989eda81a1bSEugene Leviant } 990eda81a1bSEugene Leviant 991ceabe80eSEugene Leviant SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 992ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 993ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 994ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 995ceabe80eSEugene Leviant expect(";"); 996ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 997a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 998a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 999a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1000ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1001a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1002ceabe80eSEugene Leviant } 1003ceabe80eSEugene Leviant return Cmd; 1004ceabe80eSEugene Leviant } 1005ceabe80eSEugene Leviant 100630835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { 100730835ea4SGeorge Rimar if (S == ".") 100830835ea4SGeorge Rimar return Dot; 1009a31c91b1SEugene Leviant 1010a9c5a528SGeorge Rimar switch (Config->EKind) { 1011a9c5a528SGeorge Rimar case ELF32LEKind: 1012a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF32LE>::X->find(S)) 1013a9c5a528SGeorge Rimar return B->getVA<ELF32LE>(); 1014a9c5a528SGeorge Rimar break; 1015a9c5a528SGeorge Rimar case ELF32BEKind: 1016a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF32BE>::X->find(S)) 1017a9c5a528SGeorge Rimar return B->getVA<ELF32BE>(); 1018a9c5a528SGeorge Rimar break; 1019a9c5a528SGeorge Rimar case ELF64LEKind: 1020a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF64LE>::X->find(S)) 1021a9c5a528SGeorge Rimar return B->getVA<ELF64LE>(); 1022a9c5a528SGeorge Rimar break; 1023a9c5a528SGeorge Rimar case ELF64BEKind: 1024a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF64BE>::X->find(S)) 1025a9c5a528SGeorge Rimar return B->getVA<ELF64BE>(); 1026a9c5a528SGeorge Rimar break; 10276930a6dcSGeorge Rimar default: 1028b567b628SGeorge Rimar llvm_unreachable("unsupported target"); 1029a9c5a528SGeorge Rimar } 1030a9c5a528SGeorge Rimar error("symbol not found: " + S); 1031a9c5a528SGeorge Rimar return 0; 1032a9c5a528SGeorge Rimar } 1033a9c5a528SGeorge Rimar 10349e69450eSGeorge Rimar static uint64_t getSectionSize(StringRef Name) { 10359e69450eSGeorge Rimar switch (Config->EKind) { 10369e69450eSGeorge Rimar case ELF32LEKind: 10379e69450eSGeorge Rimar return Script<ELF32LE>::X->getOutputSectionSize(Name); 10389e69450eSGeorge Rimar case ELF32BEKind: 10399e69450eSGeorge Rimar return Script<ELF32BE>::X->getOutputSectionSize(Name); 10409e69450eSGeorge Rimar case ELF64LEKind: 10419e69450eSGeorge Rimar return Script<ELF64LE>::X->getOutputSectionSize(Name); 10429e69450eSGeorge Rimar case ELF64BEKind: 10439e69450eSGeorge Rimar return Script<ELF64BE>::X->getOutputSectionSize(Name); 10449e69450eSGeorge Rimar default: 10459e69450eSGeorge Rimar llvm_unreachable("unsupported target"); 10469e69450eSGeorge Rimar } 10479e69450eSGeorge Rimar } 10489e69450eSGeorge Rimar 10494f7500bfSRui Ueyama static uint64_t getHeaderSize() { 1050e32a3598SGeorge Rimar switch (Config->EKind) { 1051e32a3598SGeorge Rimar case ELF32LEKind: 10524f7500bfSRui Ueyama return Script<ELF32LE>::X->getHeaderSize(); 1053e32a3598SGeorge Rimar case ELF32BEKind: 10544f7500bfSRui Ueyama return Script<ELF32BE>::X->getHeaderSize(); 1055e32a3598SGeorge Rimar case ELF64LEKind: 10564f7500bfSRui Ueyama return Script<ELF64LE>::X->getHeaderSize(); 1057e32a3598SGeorge Rimar case ELF64BEKind: 10584f7500bfSRui Ueyama return Script<ELF64BE>::X->getHeaderSize(); 1059e32a3598SGeorge Rimar default: 1060e32a3598SGeorge Rimar llvm_unreachable("unsupported target"); 1061e32a3598SGeorge Rimar } 1062e32a3598SGeorge Rimar } 1063e32a3598SGeorge Rimar 106430835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 106530835ea4SGeorge Rimar StringRef Op = next(); 106630835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 106730835ea4SGeorge Rimar Expr E = readExpr(); 106830835ea4SGeorge Rimar if (Op == "+=") 106930835ea4SGeorge Rimar E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; 107010416564SRui Ueyama return new SymbolAssignment(Name, E); 107130835ea4SGeorge Rimar } 107230835ea4SGeorge Rimar 107330835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 107430835ea4SGeorge Rimar // script expression. 107530835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 107630835ea4SGeorge Rimar 107736c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 107836c1cd23SRui Ueyama if (Op == "*") 107936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; 108036c1cd23SRui Ueyama if (Op == "/") { 108136c1cd23SRui Ueyama return [=](uint64_t Dot) -> uint64_t { 108236c1cd23SRui Ueyama uint64_t RHS = R(Dot); 108336c1cd23SRui Ueyama if (RHS == 0) { 108436c1cd23SRui Ueyama error("division by zero"); 108536c1cd23SRui Ueyama return 0; 108636c1cd23SRui Ueyama } 108736c1cd23SRui Ueyama return L(Dot) / RHS; 108836c1cd23SRui Ueyama }; 108936c1cd23SRui Ueyama } 109036c1cd23SRui Ueyama if (Op == "+") 109136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) + R(Dot); }; 109236c1cd23SRui Ueyama if (Op == "-") 109336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 109436c1cd23SRui Ueyama if (Op == "<") 109536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 109636c1cd23SRui Ueyama if (Op == ">") 109736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 109836c1cd23SRui Ueyama if (Op == ">=") 109936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 110036c1cd23SRui Ueyama if (Op == "<=") 110136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 110236c1cd23SRui Ueyama if (Op == "==") 110336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 110436c1cd23SRui Ueyama if (Op == "!=") 110536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 110636c1cd23SRui Ueyama if (Op == "&") 110736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 110836c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 110936c1cd23SRui Ueyama } 111036c1cd23SRui Ueyama 1111708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1112708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1113708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1114708019c4SRui Ueyama while (!atEOF() && !Error) { 1115708019c4SRui Ueyama // Read an operator and an expression. 1116708019c4SRui Ueyama StringRef Op1 = peek(); 1117708019c4SRui Ueyama if (Op1 == "?") 1118708019c4SRui Ueyama return readTernary(Lhs); 1119708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1120a31c91b1SEugene Leviant break; 1121a31c91b1SEugene Leviant next(); 1122708019c4SRui Ueyama Expr Rhs = readPrimary(); 1123708019c4SRui Ueyama 1124708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1125708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1126708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1127708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1128708019c4SRui Ueyama while (!atEOF()) { 1129708019c4SRui Ueyama StringRef Op2 = peek(); 1130708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1131eda81a1bSEugene Leviant break; 1132708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1133eda81a1bSEugene Leviant } 1134708019c4SRui Ueyama 1135708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1136708019c4SRui Ueyama } 1137708019c4SRui Ueyama return Lhs; 1138708019c4SRui Ueyama } 1139708019c4SRui Ueyama 1140708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1141*e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1142708019c4SRui Ueyama return Target->PageSize; 1143*e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1144*e2cc07bcSMichael J. Spencer return Target->MaxPageSize; 1145708019c4SRui Ueyama error("unknown constant: " + S); 1146708019c4SRui Ueyama return 0; 1147708019c4SRui Ueyama } 1148708019c4SRui Ueyama 1149708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 1150708019c4SRui Ueyama StringRef Tok = next(); 1151708019c4SRui Ueyama 1152708019c4SRui Ueyama if (Tok == "(") { 1153708019c4SRui Ueyama Expr E = readExpr(); 1154708019c4SRui Ueyama expect(")"); 1155708019c4SRui Ueyama return E; 1156708019c4SRui Ueyama } 1157708019c4SRui Ueyama 1158708019c4SRui Ueyama // Built-in functions are parsed here. 1159708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 1160eefa758eSGeorge Rimar if (Tok == "ASSERT") 1161eefa758eSGeorge Rimar return readAssert(); 1162708019c4SRui Ueyama if (Tok == "ALIGN") { 1163708019c4SRui Ueyama expect("("); 1164708019c4SRui Ueyama Expr E = readExpr(); 1165708019c4SRui Ueyama expect(")"); 1166708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1167708019c4SRui Ueyama } 1168708019c4SRui Ueyama if (Tok == "CONSTANT") { 1169708019c4SRui Ueyama expect("("); 1170708019c4SRui Ueyama StringRef Tok = next(); 1171708019c4SRui Ueyama expect(")"); 1172708019c4SRui Ueyama return [=](uint64_t Dot) { return getConstant(Tok); }; 1173708019c4SRui Ueyama } 117454c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 117554c145ceSRafael Espindola expect("("); 117654c145ceSRafael Espindola next(); 117754c145ceSRafael Espindola expect(","); 117854c145ceSRafael Espindola uint64_t Val; 117954c145ceSRafael Espindola next().getAsInteger(0, Val); 118054c145ceSRafael Espindola expect(")"); 118154c145ceSRafael Espindola return [=](uint64_t Dot) { return Val; }; 118254c145ceSRafael Espindola } 1183708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1184708019c4SRui Ueyama expect("("); 1185708019c4SRui Ueyama Expr E = readExpr(); 1186708019c4SRui Ueyama expect(","); 1187708019c4SRui Ueyama readExpr(); 1188708019c4SRui Ueyama expect(")"); 1189f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1190708019c4SRui Ueyama } 1191708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1192708019c4SRui Ueyama expect("("); 1193708019c4SRui Ueyama expect("."); 1194708019c4SRui Ueyama expect(")"); 1195708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1196708019c4SRui Ueyama } 1197276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1198276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1199276b4e64SGeorge Rimar // the next page boundary for simplicity. 1200276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1201276b4e64SGeorge Rimar expect("("); 1202276b4e64SGeorge Rimar next(); 1203276b4e64SGeorge Rimar expect(","); 1204276b4e64SGeorge Rimar readExpr(); 1205276b4e64SGeorge Rimar expect(")"); 1206276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1207276b4e64SGeorge Rimar } 12089e69450eSGeorge Rimar if (Tok == "SIZEOF") { 12099e69450eSGeorge Rimar expect("("); 12109e69450eSGeorge Rimar StringRef Name = next(); 12119e69450eSGeorge Rimar expect(")"); 12129e69450eSGeorge Rimar return [=](uint64_t Dot) { return getSectionSize(Name); }; 12139e69450eSGeorge Rimar } 1214e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 12154f7500bfSRui Ueyama return [=](uint64_t Dot) { return getHeaderSize(); }; 1216708019c4SRui Ueyama 1217a9c5a528SGeorge Rimar // Parse a symbol name or a number literal. 1218708019c4SRui Ueyama uint64_t V = 0; 1219a9c5a528SGeorge Rimar if (Tok.getAsInteger(0, V)) { 122030835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1221708019c4SRui Ueyama setError("malformed number: " + Tok); 122230835ea4SGeorge Rimar return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }; 1223a9c5a528SGeorge Rimar } 1224708019c4SRui Ueyama return [=](uint64_t Dot) { return V; }; 1225708019c4SRui Ueyama } 1226708019c4SRui Ueyama 1227708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1228708019c4SRui Ueyama next(); 1229708019c4SRui Ueyama Expr L = readExpr(); 1230708019c4SRui Ueyama expect(":"); 1231708019c4SRui Ueyama Expr R = readExpr(); 1232708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1233708019c4SRui Ueyama } 1234708019c4SRui Ueyama 1235bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1236bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1237bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1238bbe38602SEugene Leviant StringRef Tok = next(); 1239bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 1240bbe38602SEugene Leviant if (Tok.empty()) { 1241bbe38602SEugene Leviant setError("section header name is empty"); 1242bbe38602SEugene Leviant break; 1243bbe38602SEugene Leviant } 1244bbe38602SEugene Leviant Phdrs.push_back(Tok); 1245bbe38602SEugene Leviant } 1246bbe38602SEugene Leviant return Phdrs; 1247bbe38602SEugene Leviant } 1248bbe38602SEugene Leviant 1249bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1250bbe38602SEugene Leviant StringRef Tok = next(); 1251b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1252b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1253b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1254b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1255b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1256b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1257b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1258b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1259b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1260b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1261b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1262b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1263b0f6c590SRui Ueyama .Default(-1); 1264bbe38602SEugene Leviant 1265b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1266b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1267b0f6c590SRui Ueyama return PT_NULL; 1268b0f6c590SRui Ueyama } 1269b0f6c590SRui Ueyama return Ret; 1270bbe38602SEugene Leviant } 1271bbe38602SEugene Leviant 127216b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 127316b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 127416b0cc9eSSimon Atanasyan return false; 127516b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 127616b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 127716b0cc9eSSimon Atanasyan return true; 127816b0cc9eSSimon Atanasyan return false; 127916b0cc9eSSimon Atanasyan } 128016b0cc9eSSimon Atanasyan 128107320e40SRui Ueyama // Entry point. 128207320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 128316b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 128407320e40SRui Ueyama ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run(); 1285f7c5fbb1SRui Ueyama } 12861ebc8ed7SRui Ueyama 128707320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 128807320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 128907320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 129007320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1291