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. 11f7c5fbb1SRui Ueyama // It does not construct an AST but consume linker script directives directly. 1234f29246SRui Ueyama // Results are written to Driver or Config object. 13f7c5fbb1SRui Ueyama // 14f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===// 15f7c5fbb1SRui Ueyama 16717677afSRui Ueyama #include "LinkerScript.h" 17f7c5fbb1SRui Ueyama #include "Config.h" 18f7c5fbb1SRui Ueyama #include "Driver.h" 191ebc8ed7SRui Ueyama #include "InputSection.h" 20652852c5SGeorge Rimar #include "OutputSections.h" 21e77b5bf6SAdhemerval Zanella #include "ScriptParser.h" 22f7c5fbb1SRui Ueyama #include "SymbolTable.h" 23960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 24652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 25f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 26f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h" 27f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 28a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h" 29f7c5fbb1SRui Ueyama 30f7c5fbb1SRui Ueyama using namespace llvm; 31652852c5SGeorge Rimar using namespace llvm::ELF; 321ebc8ed7SRui Ueyama using namespace llvm::object; 33f7c5fbb1SRui Ueyama using namespace lld; 34e0df00b9SRafael Espindola using namespace lld::elf; 35f7c5fbb1SRui Ueyama 3607320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 37717677afSRui Ueyama 38652852c5SGeorge Rimar static uint64_t getInteger(StringRef S) { 39652852c5SGeorge Rimar uint64_t V; 40652852c5SGeorge Rimar if (S.getAsInteger(0, V)) { 41652852c5SGeorge Rimar error("malformed number: " + S); 42652852c5SGeorge Rimar return 0; 43652852c5SGeorge Rimar } 44652852c5SGeorge Rimar return V; 45652852c5SGeorge Rimar } 46652852c5SGeorge Rimar 47960504b9SRui Ueyama static int precedence(StringRef Op) { 48960504b9SRui Ueyama return StringSwitch<int>(Op) 49960504b9SRui Ueyama .Case("*", 4) 50960504b9SRui Ueyama .Case("/", 3) 51960504b9SRui Ueyama .Case("+", 2) 52960504b9SRui Ueyama .Case("-", 2) 53960504b9SRui Ueyama .Case("&", 1) 54960504b9SRui Ueyama .Default(-1); 55960504b9SRui Ueyama } 56960504b9SRui Ueyama 57960504b9SRui Ueyama static StringRef next(ArrayRef<StringRef> &Tokens) { 58960504b9SRui Ueyama if (Tokens.empty()) { 59960504b9SRui Ueyama error("no next token"); 60960504b9SRui Ueyama return ""; 61960504b9SRui Ueyama } 62960504b9SRui Ueyama StringRef Tok = Tokens.front(); 63960504b9SRui Ueyama Tokens = Tokens.slice(1); 64960504b9SRui Ueyama return Tok; 65960504b9SRui Ueyama } 66960504b9SRui Ueyama 67*99e519cdSRui Ueyama static uint64_t parseExpr(ArrayRef<StringRef> &Tokens, uint64_t Dot); 68960504b9SRui Ueyama 69960504b9SRui Ueyama // This is a part of the operator-precedence parser to evaluate 70960504b9SRui Ueyama // arithmetic expressions in SECTIONS command. This function evaluates an 71960504b9SRui Ueyama // integer literal, a parenthesized expression or the special variable ".". 72960504b9SRui Ueyama static uint64_t parsePrimary(ArrayRef<StringRef> &Tokens, uint64_t Dot) { 73960504b9SRui Ueyama StringRef Tok = next(Tokens); 74960504b9SRui Ueyama if (Tok == ".") 75960504b9SRui Ueyama return Dot; 76960504b9SRui Ueyama if (Tok == "(") { 77*99e519cdSRui Ueyama uint64_t V = parseExpr(Tokens, Dot); 78960504b9SRui Ueyama if (Tokens.empty()) { 79960504b9SRui Ueyama error(") expected"); 80960504b9SRui Ueyama } else { 81960504b9SRui Ueyama Tok = next(Tokens); 82960504b9SRui Ueyama if (Tok != ")") 83960504b9SRui Ueyama error(") expected, but got " + Tok); 84960504b9SRui Ueyama } 85960504b9SRui Ueyama return V; 86960504b9SRui Ueyama } 87960504b9SRui Ueyama return getInteger(Tok); 88960504b9SRui Ueyama } 89960504b9SRui Ueyama 90960504b9SRui Ueyama static uint64_t apply(StringRef Op, uint64_t L, uint64_t R) { 91960504b9SRui Ueyama if (Op == "+") 92960504b9SRui Ueyama return L + R; 93960504b9SRui Ueyama if (Op == "-") 94960504b9SRui Ueyama return L - R; 95960504b9SRui Ueyama if (Op == "*") 96960504b9SRui Ueyama return L * R; 97960504b9SRui Ueyama if (Op == "/") { 98960504b9SRui Ueyama if (R == 0) { 99960504b9SRui Ueyama error("division by zero"); 100960504b9SRui Ueyama return 0; 101960504b9SRui Ueyama } 102960504b9SRui Ueyama return L / R; 103960504b9SRui Ueyama } 104960504b9SRui Ueyama if (Op == "&") 105960504b9SRui Ueyama return L & R; 1067a81d674SRui Ueyama llvm_unreachable("invalid operator"); 107652852c5SGeorge Rimar return 0; 108652852c5SGeorge Rimar } 109652852c5SGeorge Rimar 110960504b9SRui Ueyama // This is an operator-precedence parser to evaluate 111960504b9SRui Ueyama // arithmetic expressions in SECTIONS command. 112*99e519cdSRui Ueyama // Tokens should start with an operator. 113*99e519cdSRui Ueyama static uint64_t parseExpr1(uint64_t Lhs, int MinPrec, 114960504b9SRui Ueyama ArrayRef<StringRef> &Tokens, uint64_t Dot) { 115960504b9SRui Ueyama while (!Tokens.empty()) { 116960504b9SRui Ueyama // Read an operator and an expression. 117960504b9SRui Ueyama StringRef Op1 = Tokens.front(); 118960504b9SRui Ueyama if (precedence(Op1) < MinPrec) 119960504b9SRui Ueyama return Lhs; 120960504b9SRui Ueyama next(Tokens); 121960504b9SRui Ueyama uint64_t Rhs = parsePrimary(Tokens, Dot); 122960504b9SRui Ueyama 123960504b9SRui Ueyama // Evaluate the remaining part of the expression first if the 124960504b9SRui Ueyama // next operator has greater precedence than the previous one. 125960504b9SRui Ueyama // For example, if we have read "+" and "3", and if the next 126960504b9SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 127960504b9SRui Ueyama while (!Tokens.empty()) { 128960504b9SRui Ueyama StringRef Op2 = Tokens.front(); 129960504b9SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 130960504b9SRui Ueyama break; 131*99e519cdSRui Ueyama Rhs = parseExpr1(Rhs, precedence(Op2), Tokens, Dot); 132652852c5SGeorge Rimar } 133960504b9SRui Ueyama 134960504b9SRui Ueyama Lhs = apply(Op1, Lhs, Rhs); 135960504b9SRui Ueyama } 136960504b9SRui Ueyama return Lhs; 137960504b9SRui Ueyama } 138960504b9SRui Ueyama 139*99e519cdSRui Ueyama static uint64_t parseExpr(ArrayRef<StringRef> &Tokens, uint64_t Dot) { 140*99e519cdSRui Ueyama uint64_t V = parsePrimary(Tokens, Dot); 141*99e519cdSRui Ueyama return parseExpr1(V, 0, Tokens, Dot); 142*99e519cdSRui Ueyama } 143*99e519cdSRui Ueyama 144960504b9SRui Ueyama // Evaluates the expression given by list of tokens. 1450536ec02SRui Ueyama static uint64_t evaluate(ArrayRef<StringRef> Tokens, uint64_t Dot) { 146*99e519cdSRui Ueyama uint64_t V = parseExpr(Tokens, Dot); 147960504b9SRui Ueyama if (!Tokens.empty()) 148960504b9SRui Ueyama error("stray token: " + Tokens[0]); 149960504b9SRui Ueyama return V; 150652852c5SGeorge Rimar } 151652852c5SGeorge Rimar 1521ebc8ed7SRui Ueyama template <class ELFT> 15307320e40SRui Ueyama SectionRule *LinkerScript<ELFT>::find(InputSectionBase<ELFT> *S) { 15407320e40SRui Ueyama for (SectionRule &R : Opt.Sections) 1551ebc8ed7SRui Ueyama if (R.match(S)) 156481c2ce6SGeorge Rimar return &R; 157481c2ce6SGeorge Rimar return nullptr; 158481c2ce6SGeorge Rimar } 159481c2ce6SGeorge Rimar 160481c2ce6SGeorge Rimar template <class ELFT> 16107320e40SRui Ueyama StringRef LinkerScript<ELFT>::getOutputSection(InputSectionBase<ELFT> *S) { 162481c2ce6SGeorge Rimar SectionRule *R = find(S); 163481c2ce6SGeorge Rimar return R ? R->Dest : ""; 164717677afSRui Ueyama } 165717677afSRui Ueyama 1661ebc8ed7SRui Ueyama template <class ELFT> 16707320e40SRui Ueyama bool LinkerScript<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) { 1681ebc8ed7SRui Ueyama return getOutputSection(S) == "/DISCARD/"; 169717677afSRui Ueyama } 170717677afSRui Ueyama 17107320e40SRui Ueyama template <class ELFT> 17207320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 173481c2ce6SGeorge Rimar SectionRule *R = find(S); 174481c2ce6SGeorge Rimar return R && R->Keep; 175481c2ce6SGeorge Rimar } 176481c2ce6SGeorge Rimar 177652852c5SGeorge Rimar template <class ELFT> 1787c18c28cSRui Ueyama static OutputSectionBase<ELFT> * 1797c18c28cSRui Ueyama findSection(std::vector<OutputSectionBase<ELFT> *> &V, StringRef Name) { 1807c18c28cSRui Ueyama for (OutputSectionBase<ELFT> *Sec : V) 1817c18c28cSRui Ueyama if (Sec->getName() == Name) 1827c18c28cSRui Ueyama return Sec; 1837c18c28cSRui Ueyama return nullptr; 1847c18c28cSRui Ueyama } 1857c18c28cSRui Ueyama 1867c18c28cSRui Ueyama template <class ELFT> 18707320e40SRui Ueyama void LinkerScript<ELFT>::assignAddresses( 1887c18c28cSRui Ueyama std::vector<OutputSectionBase<ELFT> *> &Sections) { 1897c18c28cSRui Ueyama typedef typename ELFT::uint uintX_t; 1907c18c28cSRui Ueyama 191652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 1927c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 1937c18c28cSRui Ueyama // We place orphan sections at end of file. 1947c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 195652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 1967c18c28cSRui Ueyama for (OutputSectionBase<ELFT> *Sec : Sections) { 197652852c5SGeorge Rimar StringRef Name = Sec->getName(); 19807320e40SRui Ueyama auto I = std::find(Opt.SectionOrder.begin(), Opt.SectionOrder.end(), Name); 19907320e40SRui Ueyama if (I == Opt.SectionOrder.end()) 20007320e40SRui Ueyama Opt.Commands.push_back({SectionKind, {}, Name}); 201652852c5SGeorge Rimar } 202652852c5SGeorge Rimar 2037c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 204652852c5SGeorge Rimar uintX_t ThreadBssOffset = 0; 205652852c5SGeorge Rimar uintX_t VA = 206652852c5SGeorge Rimar Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 207652852c5SGeorge Rimar 20807320e40SRui Ueyama for (SectionsCommand &Cmd : Opt.Commands) { 2099e957a0aSRui Ueyama if (Cmd.Kind == ExprKind) { 2109e957a0aSRui Ueyama VA = evaluate(Cmd.Expr, VA); 211652852c5SGeorge Rimar continue; 212652852c5SGeorge Rimar } 213652852c5SGeorge Rimar 2149e957a0aSRui Ueyama OutputSectionBase<ELFT> *Sec = findSection(Sections, Cmd.SectionName); 2157c18c28cSRui Ueyama if (!Sec) 216652852c5SGeorge Rimar continue; 217652852c5SGeorge Rimar 218652852c5SGeorge Rimar if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { 219652852c5SGeorge Rimar uintX_t TVA = VA + ThreadBssOffset; 2207c18c28cSRui Ueyama TVA = alignTo(TVA, Sec->getAlign()); 221652852c5SGeorge Rimar Sec->setVA(TVA); 222652852c5SGeorge Rimar ThreadBssOffset = TVA - VA + Sec->getSize(); 223652852c5SGeorge Rimar continue; 224652852c5SGeorge Rimar } 225652852c5SGeorge Rimar 226652852c5SGeorge Rimar if (Sec->getFlags() & SHF_ALLOC) { 2277c18c28cSRui Ueyama VA = alignTo(VA, Sec->getAlign()); 228652852c5SGeorge Rimar Sec->setVA(VA); 229652852c5SGeorge Rimar VA += Sec->getSize(); 230652852c5SGeorge Rimar continue; 231652852c5SGeorge Rimar } 232652852c5SGeorge Rimar } 233652852c5SGeorge Rimar } 234652852c5SGeorge Rimar 23507320e40SRui Ueyama template <class ELFT> 23607320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 23707320e40SRui Ueyama auto I = Opt.Filler.find(Name); 23807320e40SRui Ueyama if (I == Opt.Filler.end()) 239e2ee72b5SGeorge Rimar return {}; 2403e808976SRui Ueyama return I->second; 241e2ee72b5SGeorge Rimar } 242e2ee72b5SGeorge Rimar 243e9c58065SRui Ueyama // A compartor to sort output sections. Returns -1 or 1 if both 244e9c58065SRui Ueyama // A and B are mentioned in linker scripts. Otherwise, returns 0 245e9c58065SRui Ueyama // to use the default rule which is implemented in Writer.cpp. 24607320e40SRui Ueyama template <class ELFT> 24707320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 24807320e40SRui Ueyama auto E = Opt.SectionOrder.end(); 24907320e40SRui Ueyama auto I = std::find(Opt.SectionOrder.begin(), E, A); 25007320e40SRui Ueyama auto J = std::find(Opt.SectionOrder.begin(), E, B); 2513e808976SRui Ueyama if (I == E || J == E) 252717677afSRui Ueyama return 0; 253717677afSRui Ueyama return I < J ? -1 : 1; 254717677afSRui Ueyama } 255717677afSRui Ueyama 256cb2aeb66SGeorge Rimar // Returns true if S matches T. S can contain glob meta-characters. 257cb2aeb66SGeorge Rimar // The asterisk ('*') matches zero or more characacters, and the question 258cb2aeb66SGeorge Rimar // mark ('?') matches one character. 2591ebc8ed7SRui Ueyama static bool matchStr(StringRef S, StringRef T) { 2601ebc8ed7SRui Ueyama for (;;) { 2611ebc8ed7SRui Ueyama if (S.empty()) 2621ebc8ed7SRui Ueyama return T.empty(); 2631ebc8ed7SRui Ueyama if (S[0] == '*') { 2641ebc8ed7SRui Ueyama S = S.substr(1); 2651ebc8ed7SRui Ueyama if (S.empty()) 2661ebc8ed7SRui Ueyama // Fast path. If a pattern is '*', it matches anything. 2671ebc8ed7SRui Ueyama return true; 2681ebc8ed7SRui Ueyama for (size_t I = 0, E = T.size(); I < E; ++I) 2691ebc8ed7SRui Ueyama if (matchStr(S, T.substr(I))) 2701ebc8ed7SRui Ueyama return true; 2711ebc8ed7SRui Ueyama return false; 2721ebc8ed7SRui Ueyama } 273cb2aeb66SGeorge Rimar if (T.empty() || (S[0] != T[0] && S[0] != '?')) 2741ebc8ed7SRui Ueyama return false; 2751ebc8ed7SRui Ueyama S = S.substr(1); 2761ebc8ed7SRui Ueyama T = T.substr(1); 2771ebc8ed7SRui Ueyama } 2781ebc8ed7SRui Ueyama } 2791ebc8ed7SRui Ueyama 2801ebc8ed7SRui Ueyama template <class ELFT> bool SectionRule::match(InputSectionBase<ELFT> *S) { 2811ebc8ed7SRui Ueyama return matchStr(SectionPattern, S->getSectionName()); 2821ebc8ed7SRui Ueyama } 2831ebc8ed7SRui Ueyama 28407320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 285c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 286c3794e58SGeorge Rimar 287f7c5fbb1SRui Ueyama public: 28807320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 289f23b2320SGeorge Rimar 290e77b5bf6SAdhemerval Zanella void run() override; 291f7c5fbb1SRui Ueyama 292f7c5fbb1SRui Ueyama private: 29352a1509eSRui Ueyama void addFile(StringRef Path); 29452a1509eSRui Ueyama 295f7c5fbb1SRui Ueyama void readAsNeeded(); 29690c5099eSDenis Protivensky void readEntry(); 29783f406cfSGeorge Rimar void readExtern(); 298f7c5fbb1SRui Ueyama void readGroup(); 29931aa1f83SRui Ueyama void readInclude(); 300c3794e58SGeorge Rimar void readNothing() {} 301ee59282bSRui Ueyama void readOutput(); 3029159ce93SDavide Italiano void readOutputArch(); 303f7c5fbb1SRui Ueyama void readOutputFormat(); 30468a39a65SDavide Italiano void readSearchDir(); 3058e3b38abSDenis Protivensky void readSections(); 3068e3b38abSDenis Protivensky 307652852c5SGeorge Rimar void readLocationCounterValue(); 3088e3b38abSDenis Protivensky void readOutputSectionDescription(); 309481c2ce6SGeorge Rimar void readSectionPatterns(StringRef OutSec, bool Keep); 310f7c5fbb1SRui Ueyama 311c3794e58SGeorge Rimar const static StringMap<Handler> Cmd; 31207320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 31307320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 31416b0cc9eSSimon Atanasyan bool IsUnderSysroot; 315f7c5fbb1SRui Ueyama }; 316f7c5fbb1SRui Ueyama 317e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = { 318c3794e58SGeorge Rimar {"ENTRY", &ScriptParser::readEntry}, 319c3794e58SGeorge Rimar {"EXTERN", &ScriptParser::readExtern}, 320c3794e58SGeorge Rimar {"GROUP", &ScriptParser::readGroup}, 321c3794e58SGeorge Rimar {"INCLUDE", &ScriptParser::readInclude}, 322c3794e58SGeorge Rimar {"INPUT", &ScriptParser::readGroup}, 323c3794e58SGeorge Rimar {"OUTPUT", &ScriptParser::readOutput}, 324c3794e58SGeorge Rimar {"OUTPUT_ARCH", &ScriptParser::readOutputArch}, 325c3794e58SGeorge Rimar {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat}, 326c3794e58SGeorge Rimar {"SEARCH_DIR", &ScriptParser::readSearchDir}, 327c3794e58SGeorge Rimar {"SECTIONS", &ScriptParser::readSections}, 328c3794e58SGeorge Rimar {";", &ScriptParser::readNothing}}; 329c3794e58SGeorge Rimar 330717677afSRui Ueyama void ScriptParser::run() { 331f7c5fbb1SRui Ueyama while (!atEOF()) { 332f7c5fbb1SRui Ueyama StringRef Tok = next(); 333c3794e58SGeorge Rimar if (Handler Fn = Cmd.lookup(Tok)) 334c3794e58SGeorge Rimar (this->*Fn)(); 335c3794e58SGeorge Rimar else 3365761042dSGeorge Rimar setError("unknown directive: " + Tok); 337f7c5fbb1SRui Ueyama } 338f7c5fbb1SRui Ueyama } 339f7c5fbb1SRui Ueyama 340717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 34116b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 34216b0cc9eSSimon Atanasyan SmallString<128> Path; 34316b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 34416b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 34516b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 34616b0cc9eSSimon Atanasyan return; 34716b0cc9eSSimon Atanasyan } 34816b0cc9eSSimon Atanasyan } 34916b0cc9eSSimon Atanasyan 350f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 35152a1509eSRui Ueyama Driver->addFile(S); 35252a1509eSRui Ueyama } else if (S.startswith("=")) { 35352a1509eSRui Ueyama if (Config->Sysroot.empty()) 35452a1509eSRui Ueyama Driver->addFile(S.substr(1)); 35552a1509eSRui Ueyama else 35652a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 35752a1509eSRui Ueyama } else if (S.startswith("-l")) { 35821eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 359a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 360a1b8fc3bSSimon Atanasyan Driver->addFile(S); 36152a1509eSRui Ueyama } else { 36252a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 36352a1509eSRui Ueyama if (Path.empty()) 364777f9630SGeorge Rimar setError("unable to find " + S); 365025d59b1SRui Ueyama else 36652a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 36752a1509eSRui Ueyama } 36852a1509eSRui Ueyama } 36952a1509eSRui Ueyama 370717677afSRui Ueyama void ScriptParser::readAsNeeded() { 371f7c5fbb1SRui Ueyama expect("("); 37235da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 37335da9b6eSRui Ueyama Config->AsNeeded = true; 374025d59b1SRui Ueyama while (!Error) { 375f7c5fbb1SRui Ueyama StringRef Tok = next(); 376f7c5fbb1SRui Ueyama if (Tok == ")") 37735da9b6eSRui Ueyama break; 37852a1509eSRui Ueyama addFile(Tok); 379f7c5fbb1SRui Ueyama } 38035da9b6eSRui Ueyama Config->AsNeeded = Orig; 381f7c5fbb1SRui Ueyama } 382f7c5fbb1SRui Ueyama 383717677afSRui Ueyama void ScriptParser::readEntry() { 38490c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 38590c5099eSDenis Protivensky expect("("); 38690c5099eSDenis Protivensky StringRef Tok = next(); 38790c5099eSDenis Protivensky if (Config->Entry.empty()) 38890c5099eSDenis Protivensky Config->Entry = Tok; 38990c5099eSDenis Protivensky expect(")"); 39090c5099eSDenis Protivensky } 39190c5099eSDenis Protivensky 392717677afSRui Ueyama void ScriptParser::readExtern() { 39383f406cfSGeorge Rimar expect("("); 394025d59b1SRui Ueyama while (!Error) { 39583f406cfSGeorge Rimar StringRef Tok = next(); 39683f406cfSGeorge Rimar if (Tok == ")") 39783f406cfSGeorge Rimar return; 39883f406cfSGeorge Rimar Config->Undefined.push_back(Tok); 39983f406cfSGeorge Rimar } 40083f406cfSGeorge Rimar } 40183f406cfSGeorge Rimar 402717677afSRui Ueyama void ScriptParser::readGroup() { 403f7c5fbb1SRui Ueyama expect("("); 404025d59b1SRui Ueyama while (!Error) { 405f7c5fbb1SRui Ueyama StringRef Tok = next(); 406f7c5fbb1SRui Ueyama if (Tok == ")") 407f7c5fbb1SRui Ueyama return; 408f7c5fbb1SRui Ueyama if (Tok == "AS_NEEDED") { 409f7c5fbb1SRui Ueyama readAsNeeded(); 410f7c5fbb1SRui Ueyama continue; 411f7c5fbb1SRui Ueyama } 41252a1509eSRui Ueyama addFile(Tok); 413f7c5fbb1SRui Ueyama } 414f7c5fbb1SRui Ueyama } 415f7c5fbb1SRui Ueyama 416717677afSRui Ueyama void ScriptParser::readInclude() { 41731aa1f83SRui Ueyama StringRef Tok = next(); 41831aa1f83SRui Ueyama auto MBOrErr = MemoryBuffer::getFile(Tok); 419025d59b1SRui Ueyama if (!MBOrErr) { 4205761042dSGeorge Rimar setError("cannot open " + Tok); 421025d59b1SRui Ueyama return; 422025d59b1SRui Ueyama } 42331aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 424a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 425a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 42631aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 42731aa1f83SRui Ueyama } 42831aa1f83SRui Ueyama 429717677afSRui Ueyama void ScriptParser::readOutput() { 430ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 431ee59282bSRui Ueyama expect("("); 432ee59282bSRui Ueyama StringRef Tok = next(); 433ee59282bSRui Ueyama if (Config->OutputFile.empty()) 434ee59282bSRui Ueyama Config->OutputFile = Tok; 435ee59282bSRui Ueyama expect(")"); 436ee59282bSRui Ueyama } 437ee59282bSRui Ueyama 438717677afSRui Ueyama void ScriptParser::readOutputArch() { 4399159ce93SDavide Italiano // Error checking only for now. 4409159ce93SDavide Italiano expect("("); 4419159ce93SDavide Italiano next(); 4429159ce93SDavide Italiano expect(")"); 4439159ce93SDavide Italiano } 4449159ce93SDavide Italiano 445717677afSRui Ueyama void ScriptParser::readOutputFormat() { 446f7c5fbb1SRui Ueyama // Error checking only for now. 447f7c5fbb1SRui Ueyama expect("("); 448f7c5fbb1SRui Ueyama next(); 4496836c618SDavide Italiano StringRef Tok = next(); 4506836c618SDavide Italiano if (Tok == ")") 4516836c618SDavide Italiano return; 452025d59b1SRui Ueyama if (Tok != ",") { 4535761042dSGeorge Rimar setError("unexpected token: " + Tok); 454025d59b1SRui Ueyama return; 455025d59b1SRui Ueyama } 4566836c618SDavide Italiano next(); 4576836c618SDavide Italiano expect(","); 4586836c618SDavide Italiano next(); 459f7c5fbb1SRui Ueyama expect(")"); 460f7c5fbb1SRui Ueyama } 461f7c5fbb1SRui Ueyama 462717677afSRui Ueyama void ScriptParser::readSearchDir() { 46368a39a65SDavide Italiano expect("("); 46406501920SRafael Espindola Config->SearchPaths.push_back(next()); 46568a39a65SDavide Italiano expect(")"); 46668a39a65SDavide Italiano } 46768a39a65SDavide Italiano 468717677afSRui Ueyama void ScriptParser::readSections() { 46907320e40SRui Ueyama Opt.DoLayout = true; 4708e3b38abSDenis Protivensky expect("{"); 471652852c5SGeorge Rimar while (!Error && !skip("}")) { 472652852c5SGeorge Rimar StringRef Tok = peek(); 473652852c5SGeorge Rimar if (Tok == ".") 474652852c5SGeorge Rimar readLocationCounterValue(); 475652852c5SGeorge Rimar else 4768e3b38abSDenis Protivensky readOutputSectionDescription(); 4778e3b38abSDenis Protivensky } 478652852c5SGeorge Rimar } 4798e3b38abSDenis Protivensky 480481c2ce6SGeorge Rimar void ScriptParser::readSectionPatterns(StringRef OutSec, bool Keep) { 481481c2ce6SGeorge Rimar expect("("); 482481c2ce6SGeorge Rimar while (!Error && !skip(")")) 48307320e40SRui Ueyama Opt.Sections.emplace_back(OutSec, next(), Keep); 484481c2ce6SGeorge Rimar } 485481c2ce6SGeorge Rimar 486652852c5SGeorge Rimar void ScriptParser::readLocationCounterValue() { 487652852c5SGeorge Rimar expect("."); 488652852c5SGeorge Rimar expect("="); 48907320e40SRui Ueyama Opt.Commands.push_back({ExprKind, {}, ""}); 49007320e40SRui Ueyama SectionsCommand &Cmd = Opt.Commands.back(); 491652852c5SGeorge Rimar while (!Error) { 492652852c5SGeorge Rimar StringRef Tok = next(); 493652852c5SGeorge Rimar if (Tok == ";") 494652852c5SGeorge Rimar break; 4959e957a0aSRui Ueyama Cmd.Expr.push_back(Tok); 496652852c5SGeorge Rimar } 4979e957a0aSRui Ueyama if (Cmd.Expr.empty()) 498652852c5SGeorge Rimar error("error in location counter expression"); 499652852c5SGeorge Rimar } 500652852c5SGeorge Rimar 501717677afSRui Ueyama void ScriptParser::readOutputSectionDescription() { 5023e808976SRui Ueyama StringRef OutSec = next(); 50307320e40SRui Ueyama Opt.SectionOrder.push_back(OutSec); 50407320e40SRui Ueyama Opt.Commands.push_back({SectionKind, {}, OutSec}); 5058e3b38abSDenis Protivensky expect(":"); 5068e3b38abSDenis Protivensky expect("{"); 507025d59b1SRui Ueyama while (!Error && !skip("}")) { 508481c2ce6SGeorge Rimar StringRef Tok = next(); 509481c2ce6SGeorge Rimar if (Tok == "*") { 5103e808976SRui Ueyama readSectionPatterns(OutSec, false); 511481c2ce6SGeorge Rimar } else if (Tok == "KEEP") { 5128e3b38abSDenis Protivensky expect("("); 513481c2ce6SGeorge Rimar next(); // Skip * 5143e808976SRui Ueyama readSectionPatterns(OutSec, true); 515481c2ce6SGeorge Rimar expect(")"); 516481c2ce6SGeorge Rimar } else { 517777f9630SGeorge Rimar setError("unknown command " + Tok); 518481c2ce6SGeorge Rimar } 5198e3b38abSDenis Protivensky } 520e2ee72b5SGeorge Rimar StringRef Tok = peek(); 521e2ee72b5SGeorge Rimar if (Tok.startswith("=")) { 522e2ee72b5SGeorge Rimar if (!Tok.startswith("=0x")) { 5233ed2f069SRui Ueyama setError("filler should be a hexadecimal value"); 524e2ee72b5SGeorge Rimar return; 525e2ee72b5SGeorge Rimar } 5263e808976SRui Ueyama Tok = Tok.substr(3); 52707320e40SRui Ueyama Opt.Filler[OutSec] = parseHex(Tok); 528e2ee72b5SGeorge Rimar next(); 529e2ee72b5SGeorge Rimar } 5308e3b38abSDenis Protivensky } 5318e3b38abSDenis Protivensky 53216b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 53316b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 53416b0cc9eSSimon Atanasyan return false; 53516b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 53616b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 53716b0cc9eSSimon Atanasyan return true; 53816b0cc9eSSimon Atanasyan return false; 53916b0cc9eSSimon Atanasyan } 54016b0cc9eSSimon Atanasyan 54107320e40SRui Ueyama // Entry point. 54207320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 54316b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 54407320e40SRui Ueyama ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run(); 545f7c5fbb1SRui Ueyama } 5461ebc8ed7SRui Ueyama 54707320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 54807320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 54907320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 55007320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 551