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 507*206fffa1SGeorge Rimar template <class ELFT> Expr LinkerScript<ELFT>::getLma(StringRef Name) { 5088ceadb38SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 5098ceadb38SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 5108ceadb38SGeorge Rimar if (Cmd->LmaExpr && Cmd->Name == Name) 5118ceadb38SGeorge Rimar return Cmd->LmaExpr; 5128ceadb38SGeorge Rimar return {}; 5138ceadb38SGeorge Rimar } 5148ceadb38SGeorge Rimar 515c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 516c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 517c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 518c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 519076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 520f510fa6bSRui Ueyama int I = 0; 521f510fa6bSRui Ueyama for (std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 522076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 523076fe157SGeorge Rimar if (Cmd->Name == Name) 524f510fa6bSRui Ueyama return I; 525f510fa6bSRui Ueyama ++I; 526f510fa6bSRui Ueyama } 527f510fa6bSRui Ueyama return INT_MAX; 52871b26e94SGeorge Rimar } 52971b26e94SGeorge Rimar 53071b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if 53171b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0. 53207320e40SRui Ueyama template <class ELFT> 53307320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 534c3e2a4b0SRui Ueyama int I = getSectionIndex(A); 535c3e2a4b0SRui Ueyama int J = getSectionIndex(B); 536c3e2a4b0SRui Ueyama if (I == INT_MAX && J == INT_MAX) 537717677afSRui Ueyama return 0; 538717677afSRui Ueyama return I < J ? -1 : 1; 539717677afSRui Ueyama } 540717677afSRui Ueyama 541bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 542bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 543bbe38602SEugene Leviant } 544bbe38602SEugene Leviant 5459e69450eSGeorge Rimar template <class ELFT> 5469e69450eSGeorge Rimar typename ELFT::uint LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) { 5479e69450eSGeorge Rimar for (OutputSectionBase<ELFT> *Sec : *OutputSections) 5489e69450eSGeorge Rimar if (Sec->getName() == Name) 5499e69450eSGeorge Rimar return Sec->getSize(); 5509e69450eSGeorge Rimar error("undefined section " + Name); 5519e69450eSGeorge Rimar return 0; 5529e69450eSGeorge Rimar } 5539e69450eSGeorge Rimar 554e32a3598SGeorge Rimar template <class ELFT> 5554f7500bfSRui Ueyama typename ELFT::uint LinkerScript<ELFT>::getHeaderSize() { 556e32a3598SGeorge Rimar return Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 557e32a3598SGeorge Rimar } 558e32a3598SGeorge Rimar 559bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 560bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 561bbe38602SEugene Leviant // PHDRS {} script block. 562bbe38602SEugene Leviant template <class ELFT> 563edebbdf1SRui Ueyama std::vector<size_t> LinkerScript<ELFT>::getPhdrIndices(StringRef SectionName) { 564076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 565076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 566edebbdf1SRui Ueyama if (!Cmd || Cmd->Name != SectionName) 56731d842f5SGeorge Rimar continue; 56831d842f5SGeorge Rimar 56929c5a2a9SRui Ueyama std::vector<size_t> Ret; 57029c5a2a9SRui Ueyama for (StringRef PhdrName : Cmd->Phdrs) 57129c5a2a9SRui Ueyama Ret.push_back(getPhdrIndex(PhdrName)); 57229c5a2a9SRui Ueyama return Ret; 573bbe38602SEugene Leviant } 57431d842f5SGeorge Rimar return {}; 57531d842f5SGeorge Rimar } 576bbe38602SEugene Leviant 57729c5a2a9SRui Ueyama template <class ELFT> 57829c5a2a9SRui Ueyama size_t LinkerScript<ELFT>::getPhdrIndex(StringRef PhdrName) { 57929c5a2a9SRui Ueyama size_t I = 0; 58029c5a2a9SRui Ueyama for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { 58129c5a2a9SRui Ueyama if (Cmd.Name == PhdrName) 58229c5a2a9SRui Ueyama return I; 58329c5a2a9SRui Ueyama ++I; 58429c5a2a9SRui Ueyama } 58529c5a2a9SRui Ueyama error("section header '" + PhdrName + "' is not listed in PHDRS"); 58629c5a2a9SRui Ueyama return 0; 58729c5a2a9SRui Ueyama } 58829c5a2a9SRui Ueyama 58907320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 590c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 591c3794e58SGeorge Rimar 592f7c5fbb1SRui Ueyama public: 59307320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 594f23b2320SGeorge Rimar 5954a46539cSRui Ueyama void run(); 596f7c5fbb1SRui Ueyama 597f7c5fbb1SRui Ueyama private: 59852a1509eSRui Ueyama void addFile(StringRef Path); 59952a1509eSRui Ueyama 600f7c5fbb1SRui Ueyama void readAsNeeded(); 60190c5099eSDenis Protivensky void readEntry(); 60283f406cfSGeorge Rimar void readExtern(); 603f7c5fbb1SRui Ueyama void readGroup(); 60431aa1f83SRui Ueyama void readInclude(); 605c3794e58SGeorge Rimar void readNothing() {} 606ee59282bSRui Ueyama void readOutput(); 6079159ce93SDavide Italiano void readOutputArch(); 608f7c5fbb1SRui Ueyama void readOutputFormat(); 609bbe38602SEugene Leviant void readPhdrs(); 61068a39a65SDavide Italiano void readSearchDir(); 6118e3b38abSDenis Protivensky void readSections(); 6128e3b38abSDenis Protivensky 613113cdec9SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 61410416564SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 615f71caa2bSRui Ueyama std::vector<uint8_t> readOutputSectionFiller(); 616bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 61710416564SRui Ueyama InputSectionDescription *readInputSectionDescription(); 61810416564SRui Ueyama std::vector<StringRef> readInputFilePatterns(); 61910416564SRui Ueyama InputSectionDescription *readInputSectionRules(); 620bbe38602SEugene Leviant unsigned readPhdrType(); 621742c3836SRui Ueyama SortKind readSortKind(); 622a35e39caSPetr Hosek SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 623ceabe80eSEugene Leviant SymbolAssignment *readProvideOrAssignment(StringRef Tok); 6248ceadb38SGeorge Rimar void readAt(OutputSectionCommand *Cmd); 62510416564SRui Ueyama Expr readAlign(); 62603fc010eSGeorge Rimar void readSort(); 627eefa758eSGeorge Rimar Expr readAssert(); 628708019c4SRui Ueyama 629708019c4SRui Ueyama Expr readExpr(); 630708019c4SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 631708019c4SRui Ueyama Expr readPrimary(); 632708019c4SRui Ueyama Expr readTernary(Expr Cond); 633f7c5fbb1SRui Ueyama 634c3794e58SGeorge Rimar const static StringMap<Handler> Cmd; 63507320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 63607320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 63716b0cc9eSSimon Atanasyan bool IsUnderSysroot; 638f7c5fbb1SRui Ueyama }; 639f7c5fbb1SRui Ueyama 640e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = { 641c3794e58SGeorge Rimar {"ENTRY", &ScriptParser::readEntry}, 642c3794e58SGeorge Rimar {"EXTERN", &ScriptParser::readExtern}, 643c3794e58SGeorge Rimar {"GROUP", &ScriptParser::readGroup}, 644c3794e58SGeorge Rimar {"INCLUDE", &ScriptParser::readInclude}, 645c3794e58SGeorge Rimar {"INPUT", &ScriptParser::readGroup}, 646c3794e58SGeorge Rimar {"OUTPUT", &ScriptParser::readOutput}, 647c3794e58SGeorge Rimar {"OUTPUT_ARCH", &ScriptParser::readOutputArch}, 648c3794e58SGeorge Rimar {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat}, 649bbe38602SEugene Leviant {"PHDRS", &ScriptParser::readPhdrs}, 650c3794e58SGeorge Rimar {"SEARCH_DIR", &ScriptParser::readSearchDir}, 651c3794e58SGeorge Rimar {"SECTIONS", &ScriptParser::readSections}, 652c3794e58SGeorge Rimar {";", &ScriptParser::readNothing}}; 653c3794e58SGeorge Rimar 654717677afSRui Ueyama void ScriptParser::run() { 655f7c5fbb1SRui Ueyama while (!atEOF()) { 656f7c5fbb1SRui Ueyama StringRef Tok = next(); 657c3794e58SGeorge Rimar if (Handler Fn = Cmd.lookup(Tok)) 658c3794e58SGeorge Rimar (this->*Fn)(); 659c3794e58SGeorge Rimar else 6605761042dSGeorge Rimar setError("unknown directive: " + Tok); 661f7c5fbb1SRui Ueyama } 662f7c5fbb1SRui Ueyama } 663f7c5fbb1SRui Ueyama 664717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 66516b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 66616b0cc9eSSimon Atanasyan SmallString<128> Path; 66716b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 66816b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 66916b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 67016b0cc9eSSimon Atanasyan return; 67116b0cc9eSSimon Atanasyan } 67216b0cc9eSSimon Atanasyan } 67316b0cc9eSSimon Atanasyan 674f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 67552a1509eSRui Ueyama Driver->addFile(S); 67652a1509eSRui Ueyama } else if (S.startswith("=")) { 67752a1509eSRui Ueyama if (Config->Sysroot.empty()) 67852a1509eSRui Ueyama Driver->addFile(S.substr(1)); 67952a1509eSRui Ueyama else 68052a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 68152a1509eSRui Ueyama } else if (S.startswith("-l")) { 68221eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 683a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 684a1b8fc3bSSimon Atanasyan Driver->addFile(S); 68552a1509eSRui Ueyama } else { 68652a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 68752a1509eSRui Ueyama if (Path.empty()) 688777f9630SGeorge Rimar setError("unable to find " + S); 689025d59b1SRui Ueyama else 69052a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 69152a1509eSRui Ueyama } 69252a1509eSRui Ueyama } 69352a1509eSRui Ueyama 694717677afSRui Ueyama void ScriptParser::readAsNeeded() { 695f7c5fbb1SRui Ueyama expect("("); 69635da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 69735da9b6eSRui Ueyama Config->AsNeeded = true; 698a2acc931SRui Ueyama while (!Error && !skip(")")) 699a2acc931SRui Ueyama addFile(next()); 70035da9b6eSRui Ueyama Config->AsNeeded = Orig; 701f7c5fbb1SRui Ueyama } 702f7c5fbb1SRui Ueyama 703717677afSRui Ueyama void ScriptParser::readEntry() { 70490c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 70590c5099eSDenis Protivensky expect("("); 70690c5099eSDenis Protivensky StringRef Tok = next(); 70790c5099eSDenis Protivensky if (Config->Entry.empty()) 70890c5099eSDenis Protivensky Config->Entry = Tok; 70990c5099eSDenis Protivensky expect(")"); 71090c5099eSDenis Protivensky } 71190c5099eSDenis Protivensky 712717677afSRui Ueyama void ScriptParser::readExtern() { 71383f406cfSGeorge Rimar expect("("); 714a2acc931SRui Ueyama while (!Error && !skip(")")) 715a2acc931SRui Ueyama Config->Undefined.push_back(next()); 71683f406cfSGeorge Rimar } 71783f406cfSGeorge Rimar 718717677afSRui Ueyama void ScriptParser::readGroup() { 719f7c5fbb1SRui Ueyama expect("("); 720a2acc931SRui Ueyama while (!Error && !skip(")")) { 721f7c5fbb1SRui Ueyama StringRef Tok = next(); 722a2acc931SRui Ueyama if (Tok == "AS_NEEDED") 723f7c5fbb1SRui Ueyama readAsNeeded(); 724a2acc931SRui Ueyama else 72552a1509eSRui Ueyama addFile(Tok); 726f7c5fbb1SRui Ueyama } 727f7c5fbb1SRui Ueyama } 728f7c5fbb1SRui Ueyama 729717677afSRui Ueyama void ScriptParser::readInclude() { 73031aa1f83SRui Ueyama StringRef Tok = next(); 73131aa1f83SRui Ueyama auto MBOrErr = MemoryBuffer::getFile(Tok); 732025d59b1SRui Ueyama if (!MBOrErr) { 7335761042dSGeorge Rimar setError("cannot open " + Tok); 734025d59b1SRui Ueyama return; 735025d59b1SRui Ueyama } 73631aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 737a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 738a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 73931aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 74031aa1f83SRui Ueyama } 74131aa1f83SRui Ueyama 742717677afSRui Ueyama void ScriptParser::readOutput() { 743ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 744ee59282bSRui Ueyama expect("("); 745ee59282bSRui Ueyama StringRef Tok = next(); 746ee59282bSRui Ueyama if (Config->OutputFile.empty()) 747ee59282bSRui Ueyama Config->OutputFile = Tok; 748ee59282bSRui Ueyama expect(")"); 749ee59282bSRui Ueyama } 750ee59282bSRui Ueyama 751717677afSRui Ueyama void ScriptParser::readOutputArch() { 7529159ce93SDavide Italiano // Error checking only for now. 7539159ce93SDavide Italiano expect("("); 7549159ce93SDavide Italiano next(); 7559159ce93SDavide Italiano expect(")"); 7569159ce93SDavide Italiano } 7579159ce93SDavide Italiano 758717677afSRui Ueyama void ScriptParser::readOutputFormat() { 759f7c5fbb1SRui Ueyama // Error checking only for now. 760f7c5fbb1SRui Ueyama expect("("); 761f7c5fbb1SRui Ueyama next(); 7626836c618SDavide Italiano StringRef Tok = next(); 7636836c618SDavide Italiano if (Tok == ")") 7646836c618SDavide Italiano return; 765025d59b1SRui Ueyama if (Tok != ",") { 7665761042dSGeorge Rimar setError("unexpected token: " + Tok); 767025d59b1SRui Ueyama return; 768025d59b1SRui Ueyama } 7696836c618SDavide Italiano next(); 7706836c618SDavide Italiano expect(","); 7716836c618SDavide Italiano next(); 772f7c5fbb1SRui Ueyama expect(")"); 773f7c5fbb1SRui Ueyama } 774f7c5fbb1SRui Ueyama 775bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 776bbe38602SEugene Leviant expect("{"); 777bbe38602SEugene Leviant while (!Error && !skip("}")) { 778bbe38602SEugene Leviant StringRef Tok = next(); 779865bf863SEugene Leviant Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX}); 780bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 781bbe38602SEugene Leviant 782bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 783bbe38602SEugene Leviant do { 784bbe38602SEugene Leviant Tok = next(); 785bbe38602SEugene Leviant if (Tok == ";") 786bbe38602SEugene Leviant break; 787bbe38602SEugene Leviant if (Tok == "FILEHDR") 788bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 789bbe38602SEugene Leviant else if (Tok == "PHDRS") 790bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 791865bf863SEugene Leviant else if (Tok == "FLAGS") { 792865bf863SEugene Leviant expect("("); 793eb685cd7SRafael Espindola // Passing 0 for the value of dot is a bit of a hack. It means that 794eb685cd7SRafael Espindola // we accept expressions like ".|1". 795eb685cd7SRafael Espindola PhdrCmd.Flags = readExpr()(0); 796865bf863SEugene Leviant expect(")"); 797865bf863SEugene Leviant } else 798bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 799bbe38602SEugene Leviant } while (!Error); 800bbe38602SEugene Leviant } 801bbe38602SEugene Leviant } 802bbe38602SEugene Leviant 803717677afSRui Ueyama void ScriptParser::readSearchDir() { 80468a39a65SDavide Italiano expect("("); 80506501920SRafael Espindola Config->SearchPaths.push_back(next()); 80668a39a65SDavide Italiano expect(")"); 80768a39a65SDavide Italiano } 80868a39a65SDavide Italiano 809717677afSRui Ueyama void ScriptParser::readSections() { 8103de0a330SRui Ueyama Opt.HasContents = true; 8118e3b38abSDenis Protivensky expect("{"); 812652852c5SGeorge Rimar while (!Error && !skip("}")) { 813113cdec9SRui Ueyama StringRef Tok = next(); 814ceabe80eSEugene Leviant BaseCommand *Cmd = readProvideOrAssignment(Tok); 815ceabe80eSEugene Leviant if (!Cmd) { 816ceabe80eSEugene Leviant if (Tok == "ASSERT") 817eefa758eSGeorge Rimar Cmd = new AssertCommand(readAssert()); 818ceabe80eSEugene Leviant else 81910416564SRui Ueyama Cmd = readOutputSectionDescription(Tok); 8208e3b38abSDenis Protivensky } 82110416564SRui Ueyama Opt.Commands.emplace_back(Cmd); 822652852c5SGeorge Rimar } 823708019c4SRui Ueyama } 8248e3b38abSDenis Protivensky 825708019c4SRui Ueyama static int precedence(StringRef Op) { 826708019c4SRui Ueyama return StringSwitch<int>(Op) 827708019c4SRui Ueyama .Case("*", 4) 828708019c4SRui Ueyama .Case("/", 4) 829708019c4SRui Ueyama .Case("+", 3) 830708019c4SRui Ueyama .Case("-", 3) 831708019c4SRui Ueyama .Case("<", 2) 832708019c4SRui Ueyama .Case(">", 2) 833708019c4SRui Ueyama .Case(">=", 2) 834708019c4SRui Ueyama .Case("<=", 2) 835708019c4SRui Ueyama .Case("==", 2) 836708019c4SRui Ueyama .Case("!=", 2) 837708019c4SRui Ueyama .Case("&", 1) 838708019c4SRui Ueyama .Default(-1); 839708019c4SRui Ueyama } 840708019c4SRui Ueyama 84110416564SRui Ueyama std::vector<StringRef> ScriptParser::readInputFilePatterns() { 84210416564SRui Ueyama std::vector<StringRef> V; 84310416564SRui Ueyama while (!Error && !skip(")")) 84410416564SRui Ueyama V.push_back(next()); 84510416564SRui Ueyama return V; 8460702c4e8SGeorge Rimar } 8470702c4e8SGeorge Rimar 848742c3836SRui Ueyama SortKind ScriptParser::readSortKind() { 849742c3836SRui Ueyama if (skip("SORT") || skip("SORT_BY_NAME")) 850742c3836SRui Ueyama return SortByName; 851742c3836SRui Ueyama if (skip("SORT_BY_ALIGNMENT")) 852742c3836SRui Ueyama return SortByAlignment; 853742c3836SRui Ueyama return SortNone; 854742c3836SRui Ueyama } 855742c3836SRui Ueyama 85610416564SRui Ueyama InputSectionDescription *ScriptParser::readInputSectionRules() { 85710416564SRui Ueyama auto *Cmd = new InputSectionDescription; 85810416564SRui Ueyama Cmd->FilePattern = next(); 8590ed42b0cSDavide Italiano expect("("); 860e7282797SDavide Italiano 861742c3836SRui Ueyama // Read EXCLUDE_FILE(). 862e7282797SDavide Italiano if (skip("EXCLUDE_FILE")) { 863e7282797SDavide Italiano expect("("); 864e7282797SDavide Italiano while (!Error && !skip(")")) 86510416564SRui Ueyama Cmd->ExcludedFiles.push_back(next()); 866e7282797SDavide Italiano } 867e7282797SDavide Italiano 868742c3836SRui Ueyama // Read SORT(). 869742c3836SRui Ueyama if (SortKind K1 = readSortKind()) { 870742c3836SRui Ueyama Cmd->SortOuter = K1; 8710702c4e8SGeorge Rimar expect("("); 872742c3836SRui Ueyama if (SortKind K2 = readSortKind()) { 873742c3836SRui Ueyama Cmd->SortInner = K2; 874350ece4eSGeorge Rimar expect("("); 87510416564SRui Ueyama Cmd->SectionPatterns = readInputFilePatterns(); 8760702c4e8SGeorge Rimar expect(")"); 877350ece4eSGeorge Rimar } else { 87810416564SRui Ueyama Cmd->SectionPatterns = readInputFilePatterns(); 879350ece4eSGeorge Rimar } 880350ece4eSGeorge Rimar expect(")"); 88110416564SRui Ueyama return Cmd; 8820659800eSGeorge Rimar } 8830702c4e8SGeorge Rimar 88410416564SRui Ueyama Cmd->SectionPatterns = readInputFilePatterns(); 88510416564SRui Ueyama return Cmd; 8860659800eSGeorge Rimar } 8870659800eSGeorge Rimar 88810416564SRui Ueyama InputSectionDescription *ScriptParser::readInputSectionDescription() { 8890659800eSGeorge Rimar // Input section wildcard can be surrounded by KEEP. 8900659800eSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 8910659800eSGeorge Rimar if (skip("KEEP")) { 892e7282797SDavide Italiano expect("("); 89310416564SRui Ueyama InputSectionDescription *Cmd = readInputSectionRules(); 8940ed42b0cSDavide Italiano expect(")"); 89510416564SRui Ueyama Opt.KeptSections.insert(Opt.KeptSections.end(), 89610416564SRui Ueyama Cmd->SectionPatterns.begin(), 89710416564SRui Ueyama Cmd->SectionPatterns.end()); 89810416564SRui Ueyama return Cmd; 89910416564SRui Ueyama } 90010416564SRui Ueyama return readInputSectionRules(); 9010659800eSGeorge Rimar } 9020659800eSGeorge Rimar 90310416564SRui Ueyama Expr ScriptParser::readAlign() { 904630c6179SGeorge Rimar expect("("); 90510416564SRui Ueyama Expr E = readExpr(); 906630c6179SGeorge Rimar expect(")"); 90710416564SRui Ueyama return E; 908630c6179SGeorge Rimar } 909630c6179SGeorge Rimar 91003fc010eSGeorge Rimar void ScriptParser::readSort() { 91103fc010eSGeorge Rimar expect("("); 91203fc010eSGeorge Rimar expect("CONSTRUCTORS"); 91303fc010eSGeorge Rimar expect(")"); 91403fc010eSGeorge Rimar } 91503fc010eSGeorge Rimar 916eefa758eSGeorge Rimar Expr ScriptParser::readAssert() { 917eefa758eSGeorge Rimar expect("("); 918eefa758eSGeorge Rimar Expr E = readExpr(); 919eefa758eSGeorge Rimar expect(","); 920eefa758eSGeorge Rimar StringRef Msg = next(); 921eefa758eSGeorge Rimar expect(")"); 922eefa758eSGeorge Rimar return [=](uint64_t Dot) { 923eefa758eSGeorge Rimar uint64_t V = E(Dot); 924eefa758eSGeorge Rimar if (!V) 925eefa758eSGeorge Rimar error(Msg); 926eefa758eSGeorge Rimar return V; 927eefa758eSGeorge Rimar }; 928eefa758eSGeorge Rimar } 929eefa758eSGeorge Rimar 9308ceadb38SGeorge Rimar void ScriptParser::readAt(OutputSectionCommand *Cmd) { 9318ceadb38SGeorge Rimar expect("("); 9328ceadb38SGeorge Rimar Cmd->LmaExpr = readExpr(); 9338ceadb38SGeorge Rimar expect(")"); 9348ceadb38SGeorge Rimar } 9358ceadb38SGeorge Rimar 93610416564SRui Ueyama OutputSectionCommand * 93710416564SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 938076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 93958e5c4dcSGeorge Rimar 94058e5c4dcSGeorge Rimar // Read an address expression. 94158e5c4dcSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 94258e5c4dcSGeorge Rimar if (peek() != ":") 94358e5c4dcSGeorge Rimar Cmd->AddrExpr = readExpr(); 94458e5c4dcSGeorge Rimar 9458e3b38abSDenis Protivensky expect(":"); 946246f681eSDavide Italiano 9478ceadb38SGeorge Rimar if (skip("AT")) 9488ceadb38SGeorge Rimar readAt(Cmd); 9498ceadb38SGeorge Rimar 950630c6179SGeorge Rimar if (skip("ALIGN")) 95110416564SRui Ueyama Cmd->AlignExpr = readAlign(); 952630c6179SGeorge Rimar 953246f681eSDavide Italiano // Parse constraints. 954246f681eSDavide Italiano if (skip("ONLY_IF_RO")) 955efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 956246f681eSDavide Italiano if (skip("ONLY_IF_RW")) 957efc4066bSRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 9588e3b38abSDenis Protivensky expect("{"); 9598ec77e64SRui Ueyama 960025d59b1SRui Ueyama while (!Error && !skip("}")) { 961f586ff7eSGeorge Rimar if (peek().startswith("*") || peek() == "KEEP") { 96210416564SRui Ueyama Cmd->Commands.emplace_back(readInputSectionDescription()); 9630659800eSGeorge Rimar continue; 9640659800eSGeorge Rimar } 965ceabe80eSEugene Leviant 966ceabe80eSEugene Leviant StringRef Tok = next(); 967ceabe80eSEugene Leviant if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) 968ceabe80eSEugene Leviant Cmd->Commands.emplace_back(Assignment); 969ceabe80eSEugene Leviant else if (Tok == "SORT") 97003fc010eSGeorge Rimar readSort(); 971ceabe80eSEugene Leviant else 972ceabe80eSEugene Leviant setError("unknown command " + Tok); 9738e3b38abSDenis Protivensky } 974076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 975f71caa2bSRui Ueyama Cmd->Filler = readOutputSectionFiller(); 97610416564SRui Ueyama return Cmd; 977f71caa2bSRui Ueyama } 9788ec77e64SRui Ueyama 979f71caa2bSRui Ueyama std::vector<uint8_t> ScriptParser::readOutputSectionFiller() { 980e2ee72b5SGeorge Rimar StringRef Tok = peek(); 981f71caa2bSRui Ueyama if (!Tok.startswith("=")) 982f71caa2bSRui Ueyama return {}; 9835ac0d7c5SDavide Italiano next(); 984965827d6SRui Ueyama 985965827d6SRui Ueyama // Read a hexstring of arbitrary length. 9865ac0d7c5SDavide Italiano if (Tok.startswith("=0x")) 9875ac0d7c5SDavide Italiano return parseHex(Tok.substr(3)); 9885ac0d7c5SDavide Italiano 989965827d6SRui Ueyama // Read a decimal or octal value as a big-endian 32 bit value. 990965827d6SRui Ueyama // Why do this? I don't know, but that's what gold does. 991965827d6SRui Ueyama uint32_t V; 992965827d6SRui Ueyama if (Tok.substr(1).getAsInteger(0, V)) { 993965827d6SRui Ueyama setError("invalid filler expression: " + Tok); 994f71caa2bSRui Ueyama return {}; 995e2ee72b5SGeorge Rimar } 996965827d6SRui Ueyama return { uint8_t(V >> 24), uint8_t(V >> 16), uint8_t(V >> 8), uint8_t(V) }; 9978e3b38abSDenis Protivensky } 9988e3b38abSDenis Protivensky 999a35e39caSPetr Hosek SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 1000a31c91b1SEugene Leviant expect("("); 1001174e0a16SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 1002a35e39caSPetr Hosek Cmd->Provide = Provide; 1003174e0a16SRui Ueyama Cmd->Hidden = Hidden; 1004a31c91b1SEugene Leviant expect(")"); 1005a31c91b1SEugene Leviant expect(";"); 100610416564SRui Ueyama return Cmd; 1007eda81a1bSEugene Leviant } 1008eda81a1bSEugene Leviant 1009ceabe80eSEugene Leviant SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 1010ceabe80eSEugene Leviant SymbolAssignment *Cmd = nullptr; 1011ceabe80eSEugene Leviant if (peek() == "=" || peek() == "+=") { 1012ceabe80eSEugene Leviant Cmd = readAssignment(Tok); 1013ceabe80eSEugene Leviant expect(";"); 1014ceabe80eSEugene Leviant } else if (Tok == "PROVIDE") { 1015a35e39caSPetr Hosek Cmd = readProvideHidden(true, false); 1016a35e39caSPetr Hosek } else if (Tok == "HIDDEN") { 1017a35e39caSPetr Hosek Cmd = readProvideHidden(false, true); 1018ceabe80eSEugene Leviant } else if (Tok == "PROVIDE_HIDDEN") { 1019a35e39caSPetr Hosek Cmd = readProvideHidden(true, true); 1020ceabe80eSEugene Leviant } 1021ceabe80eSEugene Leviant return Cmd; 1022ceabe80eSEugene Leviant } 1023ceabe80eSEugene Leviant 102430835ea4SGeorge Rimar static uint64_t getSymbolValue(StringRef S, uint64_t Dot) { 102530835ea4SGeorge Rimar if (S == ".") 102630835ea4SGeorge Rimar return Dot; 1027a31c91b1SEugene Leviant 1028a9c5a528SGeorge Rimar switch (Config->EKind) { 1029a9c5a528SGeorge Rimar case ELF32LEKind: 1030a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF32LE>::X->find(S)) 1031a9c5a528SGeorge Rimar return B->getVA<ELF32LE>(); 1032a9c5a528SGeorge Rimar break; 1033a9c5a528SGeorge Rimar case ELF32BEKind: 1034a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF32BE>::X->find(S)) 1035a9c5a528SGeorge Rimar return B->getVA<ELF32BE>(); 1036a9c5a528SGeorge Rimar break; 1037a9c5a528SGeorge Rimar case ELF64LEKind: 1038a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF64LE>::X->find(S)) 1039a9c5a528SGeorge Rimar return B->getVA<ELF64LE>(); 1040a9c5a528SGeorge Rimar break; 1041a9c5a528SGeorge Rimar case ELF64BEKind: 1042a9c5a528SGeorge Rimar if (SymbolBody *B = Symtab<ELF64BE>::X->find(S)) 1043a9c5a528SGeorge Rimar return B->getVA<ELF64BE>(); 1044a9c5a528SGeorge Rimar break; 10456930a6dcSGeorge Rimar default: 1046b567b628SGeorge Rimar llvm_unreachable("unsupported target"); 1047a9c5a528SGeorge Rimar } 1048a9c5a528SGeorge Rimar error("symbol not found: " + S); 1049a9c5a528SGeorge Rimar return 0; 1050a9c5a528SGeorge Rimar } 1051a9c5a528SGeorge Rimar 10529e69450eSGeorge Rimar static uint64_t getSectionSize(StringRef Name) { 10539e69450eSGeorge Rimar switch (Config->EKind) { 10549e69450eSGeorge Rimar case ELF32LEKind: 10559e69450eSGeorge Rimar return Script<ELF32LE>::X->getOutputSectionSize(Name); 10569e69450eSGeorge Rimar case ELF32BEKind: 10579e69450eSGeorge Rimar return Script<ELF32BE>::X->getOutputSectionSize(Name); 10589e69450eSGeorge Rimar case ELF64LEKind: 10599e69450eSGeorge Rimar return Script<ELF64LE>::X->getOutputSectionSize(Name); 10609e69450eSGeorge Rimar case ELF64BEKind: 10619e69450eSGeorge Rimar return Script<ELF64BE>::X->getOutputSectionSize(Name); 10629e69450eSGeorge Rimar default: 10639e69450eSGeorge Rimar llvm_unreachable("unsupported target"); 10649e69450eSGeorge Rimar } 10659e69450eSGeorge Rimar } 10669e69450eSGeorge Rimar 10674f7500bfSRui Ueyama static uint64_t getHeaderSize() { 1068e32a3598SGeorge Rimar switch (Config->EKind) { 1069e32a3598SGeorge Rimar case ELF32LEKind: 10704f7500bfSRui Ueyama return Script<ELF32LE>::X->getHeaderSize(); 1071e32a3598SGeorge Rimar case ELF32BEKind: 10724f7500bfSRui Ueyama return Script<ELF32BE>::X->getHeaderSize(); 1073e32a3598SGeorge Rimar case ELF64LEKind: 10744f7500bfSRui Ueyama return Script<ELF64LE>::X->getHeaderSize(); 1075e32a3598SGeorge Rimar case ELF64BEKind: 10764f7500bfSRui Ueyama return Script<ELF64BE>::X->getHeaderSize(); 1077e32a3598SGeorge Rimar default: 1078e32a3598SGeorge Rimar llvm_unreachable("unsupported target"); 1079e32a3598SGeorge Rimar } 1080e32a3598SGeorge Rimar } 1081e32a3598SGeorge Rimar 108230835ea4SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 108330835ea4SGeorge Rimar StringRef Op = next(); 108430835ea4SGeorge Rimar assert(Op == "=" || Op == "+="); 108530835ea4SGeorge Rimar Expr E = readExpr(); 108630835ea4SGeorge Rimar if (Op == "+=") 108730835ea4SGeorge Rimar E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; 108810416564SRui Ueyama return new SymbolAssignment(Name, E); 108930835ea4SGeorge Rimar } 109030835ea4SGeorge Rimar 109130835ea4SGeorge Rimar // This is an operator-precedence parser to parse a linker 109230835ea4SGeorge Rimar // script expression. 109330835ea4SGeorge Rimar Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); } 109430835ea4SGeorge Rimar 109536c1cd23SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 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) -> uint64_t { 110036c1cd23SRui Ueyama uint64_t RHS = R(Dot); 110136c1cd23SRui Ueyama if (RHS == 0) { 110236c1cd23SRui Ueyama error("division by zero"); 110336c1cd23SRui Ueyama return 0; 110436c1cd23SRui Ueyama } 110536c1cd23SRui Ueyama return L(Dot) / RHS; 110636c1cd23SRui Ueyama }; 110736c1cd23SRui Ueyama } 110836c1cd23SRui Ueyama if (Op == "+") 110936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) + R(Dot); }; 111036c1cd23SRui Ueyama if (Op == "-") 111136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; 111236c1cd23SRui Ueyama if (Op == "<") 111336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; 111436c1cd23SRui Ueyama if (Op == ">") 111536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; 111636c1cd23SRui Ueyama if (Op == ">=") 111736c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; 111836c1cd23SRui Ueyama if (Op == "<=") 111936c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; 112036c1cd23SRui Ueyama if (Op == "==") 112136c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; 112236c1cd23SRui Ueyama if (Op == "!=") 112336c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; 112436c1cd23SRui Ueyama if (Op == "&") 112536c1cd23SRui Ueyama return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; 112636c1cd23SRui Ueyama llvm_unreachable("invalid operator"); 112736c1cd23SRui Ueyama } 112836c1cd23SRui Ueyama 1129708019c4SRui Ueyama // This is a part of the operator-precedence parser. This function 1130708019c4SRui Ueyama // assumes that the remaining token stream starts with an operator. 1131708019c4SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1132708019c4SRui Ueyama while (!atEOF() && !Error) { 1133708019c4SRui Ueyama // Read an operator and an expression. 1134708019c4SRui Ueyama StringRef Op1 = peek(); 1135708019c4SRui Ueyama if (Op1 == "?") 1136708019c4SRui Ueyama return readTernary(Lhs); 1137708019c4SRui Ueyama if (precedence(Op1) < MinPrec) 1138a31c91b1SEugene Leviant break; 1139a31c91b1SEugene Leviant next(); 1140708019c4SRui Ueyama Expr Rhs = readPrimary(); 1141708019c4SRui Ueyama 1142708019c4SRui Ueyama // Evaluate the remaining part of the expression first if the 1143708019c4SRui Ueyama // next operator has greater precedence than the previous one. 1144708019c4SRui Ueyama // For example, if we have read "+" and "3", and if the next 1145708019c4SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1146708019c4SRui Ueyama while (!atEOF()) { 1147708019c4SRui Ueyama StringRef Op2 = peek(); 1148708019c4SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 1149eda81a1bSEugene Leviant break; 1150708019c4SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 1151eda81a1bSEugene Leviant } 1152708019c4SRui Ueyama 1153708019c4SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 1154708019c4SRui Ueyama } 1155708019c4SRui Ueyama return Lhs; 1156708019c4SRui Ueyama } 1157708019c4SRui Ueyama 1158708019c4SRui Ueyama uint64_t static getConstant(StringRef S) { 1159e2cc07bcSMichael J. Spencer if (S == "COMMONPAGESIZE") 1160708019c4SRui Ueyama return Target->PageSize; 1161e2cc07bcSMichael J. Spencer if (S == "MAXPAGESIZE") 1162e2cc07bcSMichael J. Spencer return Target->MaxPageSize; 1163708019c4SRui Ueyama error("unknown constant: " + S); 1164708019c4SRui Ueyama return 0; 1165708019c4SRui Ueyama } 1166708019c4SRui Ueyama 1167708019c4SRui Ueyama Expr ScriptParser::readPrimary() { 1168708019c4SRui Ueyama StringRef Tok = next(); 1169708019c4SRui Ueyama 1170708019c4SRui Ueyama if (Tok == "(") { 1171708019c4SRui Ueyama Expr E = readExpr(); 1172708019c4SRui Ueyama expect(")"); 1173708019c4SRui Ueyama return E; 1174708019c4SRui Ueyama } 1175708019c4SRui Ueyama 1176708019c4SRui Ueyama // Built-in functions are parsed here. 1177708019c4SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 1178eefa758eSGeorge Rimar if (Tok == "ASSERT") 1179eefa758eSGeorge Rimar return readAssert(); 1180708019c4SRui Ueyama if (Tok == "ALIGN") { 1181708019c4SRui Ueyama expect("("); 1182708019c4SRui Ueyama Expr E = readExpr(); 1183708019c4SRui Ueyama expect(")"); 1184708019c4SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1185708019c4SRui Ueyama } 1186708019c4SRui Ueyama if (Tok == "CONSTANT") { 1187708019c4SRui Ueyama expect("("); 1188708019c4SRui Ueyama StringRef Tok = next(); 1189708019c4SRui Ueyama expect(")"); 1190708019c4SRui Ueyama return [=](uint64_t Dot) { return getConstant(Tok); }; 1191708019c4SRui Ueyama } 119254c145ceSRafael Espindola if (Tok == "SEGMENT_START") { 119354c145ceSRafael Espindola expect("("); 119454c145ceSRafael Espindola next(); 119554c145ceSRafael Espindola expect(","); 119654c145ceSRafael Espindola uint64_t Val; 119754c145ceSRafael Espindola next().getAsInteger(0, Val); 119854c145ceSRafael Espindola expect(")"); 119954c145ceSRafael Espindola return [=](uint64_t Dot) { return Val; }; 120054c145ceSRafael Espindola } 1201708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 1202708019c4SRui Ueyama expect("("); 1203708019c4SRui Ueyama Expr E = readExpr(); 1204708019c4SRui Ueyama expect(","); 1205708019c4SRui Ueyama readExpr(); 1206708019c4SRui Ueyama expect(")"); 1207f7791bb9SRui Ueyama return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; 1208708019c4SRui Ueyama } 1209708019c4SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 1210708019c4SRui Ueyama expect("("); 1211708019c4SRui Ueyama expect("."); 1212708019c4SRui Ueyama expect(")"); 1213708019c4SRui Ueyama return [](uint64_t Dot) { return Dot; }; 1214708019c4SRui Ueyama } 1215276b4e64SGeorge Rimar // GNU linkers implements more complicated logic to handle 1216276b4e64SGeorge Rimar // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to 1217276b4e64SGeorge Rimar // the next page boundary for simplicity. 1218276b4e64SGeorge Rimar if (Tok == "DATA_SEGMENT_RELRO_END") { 1219276b4e64SGeorge Rimar expect("("); 1220276b4e64SGeorge Rimar next(); 1221276b4e64SGeorge Rimar expect(","); 1222276b4e64SGeorge Rimar readExpr(); 1223276b4e64SGeorge Rimar expect(")"); 1224276b4e64SGeorge Rimar return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; 1225276b4e64SGeorge Rimar } 12269e69450eSGeorge Rimar if (Tok == "SIZEOF") { 12279e69450eSGeorge Rimar expect("("); 12289e69450eSGeorge Rimar StringRef Name = next(); 12299e69450eSGeorge Rimar expect(")"); 12309e69450eSGeorge Rimar return [=](uint64_t Dot) { return getSectionSize(Name); }; 12319e69450eSGeorge Rimar } 1232e32a3598SGeorge Rimar if (Tok == "SIZEOF_HEADERS") 12334f7500bfSRui Ueyama return [=](uint64_t Dot) { return getHeaderSize(); }; 1234708019c4SRui Ueyama 1235a9c5a528SGeorge Rimar // Parse a symbol name or a number literal. 1236708019c4SRui Ueyama uint64_t V = 0; 1237a9c5a528SGeorge Rimar if (Tok.getAsInteger(0, V)) { 123830835ea4SGeorge Rimar if (Tok != "." && !isValidCIdentifier(Tok)) 1239708019c4SRui Ueyama setError("malformed number: " + Tok); 124030835ea4SGeorge Rimar return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }; 1241a9c5a528SGeorge Rimar } 1242708019c4SRui Ueyama return [=](uint64_t Dot) { return V; }; 1243708019c4SRui Ueyama } 1244708019c4SRui Ueyama 1245708019c4SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 1246708019c4SRui Ueyama next(); 1247708019c4SRui Ueyama Expr L = readExpr(); 1248708019c4SRui Ueyama expect(":"); 1249708019c4SRui Ueyama Expr R = readExpr(); 1250708019c4SRui Ueyama return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; 1251708019c4SRui Ueyama } 1252708019c4SRui Ueyama 1253bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1254bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 1255bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 1256bbe38602SEugene Leviant StringRef Tok = next(); 1257bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 1258bbe38602SEugene Leviant if (Tok.empty()) { 1259bbe38602SEugene Leviant setError("section header name is empty"); 1260bbe38602SEugene Leviant break; 1261bbe38602SEugene Leviant } 1262bbe38602SEugene Leviant Phdrs.push_back(Tok); 1263bbe38602SEugene Leviant } 1264bbe38602SEugene Leviant return Phdrs; 1265bbe38602SEugene Leviant } 1266bbe38602SEugene Leviant 1267bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 1268bbe38602SEugene Leviant StringRef Tok = next(); 1269b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 1270b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 1271b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 1272b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 1273b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 1274b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 1275b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 1276b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 1277b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 1278b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1279b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 1280b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1281b0f6c590SRui Ueyama .Default(-1); 1282bbe38602SEugene Leviant 1283b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 1284b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 1285b0f6c590SRui Ueyama return PT_NULL; 1286b0f6c590SRui Ueyama } 1287b0f6c590SRui Ueyama return Ret; 1288bbe38602SEugene Leviant } 1289bbe38602SEugene Leviant 129016b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 129116b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 129216b0cc9eSSimon Atanasyan return false; 129316b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 129416b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 129516b0cc9eSSimon Atanasyan return true; 129616b0cc9eSSimon Atanasyan return false; 129716b0cc9eSSimon Atanasyan } 129816b0cc9eSSimon Atanasyan 129907320e40SRui Ueyama // Entry point. 130007320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 130116b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 130207320e40SRui Ueyama ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run(); 1303f7c5fbb1SRui Ueyama } 13041ebc8ed7SRui Ueyama 130507320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 130607320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 130707320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 130807320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 1309