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" 2293c9af42SRui Ueyama #include "Strings.h" 23eda81a1bSEugene Leviant #include "Symbols.h" 24f7c5fbb1SRui Ueyama #include "SymbolTable.h" 25467c4d55SEugene Leviant #include "Target.h" 26bbe38602SEugene Leviant #include "Writer.h" 27960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h" 28652852c5SGeorge Rimar #include "llvm/Support/ELF.h" 29f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h" 30f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h" 31f03f3cc1SRui Ueyama #include "llvm/Support/Path.h" 32a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h" 33f7c5fbb1SRui Ueyama 34f7c5fbb1SRui Ueyama using namespace llvm; 35652852c5SGeorge Rimar using namespace llvm::ELF; 361ebc8ed7SRui Ueyama using namespace llvm::object; 37f7c5fbb1SRui Ueyama using namespace lld; 38e0df00b9SRafael Espindola using namespace lld::elf; 39f7c5fbb1SRui Ueyama 4007320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig; 41717677afSRui Ueyama 42076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 43076fe157SGeorge Rimar return C->Kind == AssignmentKind; 44076fe157SGeorge Rimar } 45076fe157SGeorge Rimar 46076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 47076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 48076fe157SGeorge Rimar } 49076fe157SGeorge Rimar 509c1112d0SRui Ueyama // This is an operator-precedence parser to parse and evaluate 519c1112d0SRui Ueyama // a linker script expression. For each linker script arithmetic 529c1112d0SRui Ueyama // expression (e.g. ". = . + 0x1000"), a new instance of ExprParser 539c1112d0SRui Ueyama // is created and ran. 549c1112d0SRui Ueyama namespace { 559c1112d0SRui Ueyama class ExprParser : public ScriptParserBase { 569c1112d0SRui Ueyama public: 579c1112d0SRui Ueyama ExprParser(std::vector<StringRef> &Tokens, uint64_t Dot) 589c1112d0SRui Ueyama : ScriptParserBase(Tokens), Dot(Dot) {} 599c1112d0SRui Ueyama 609c1112d0SRui Ueyama uint64_t run(); 619c1112d0SRui Ueyama 629c1112d0SRui Ueyama private: 639c1112d0SRui Ueyama uint64_t parsePrimary(); 649c1112d0SRui Ueyama uint64_t parseTernary(uint64_t Cond); 659c1112d0SRui Ueyama uint64_t apply(StringRef Op, uint64_t L, uint64_t R); 669c1112d0SRui Ueyama uint64_t parseExpr1(uint64_t Lhs, int MinPrec); 679c1112d0SRui Ueyama uint64_t parseExpr(); 689c1112d0SRui Ueyama 699c1112d0SRui Ueyama uint64_t Dot; 709c1112d0SRui Ueyama }; 719c1112d0SRui Ueyama } 729c1112d0SRui Ueyama 73960504b9SRui Ueyama static int precedence(StringRef Op) { 74960504b9SRui Ueyama return StringSwitch<int>(Op) 75960504b9SRui Ueyama .Case("*", 4) 76ab939066SGeorge Rimar .Case("/", 4) 77ab939066SGeorge Rimar .Case("+", 3) 78ab939066SGeorge Rimar .Case("-", 3) 79ab939066SGeorge Rimar .Case("<", 2) 80ab939066SGeorge Rimar .Case(">", 2) 81ab939066SGeorge Rimar .Case(">=", 2) 82ab939066SGeorge Rimar .Case("<=", 2) 83ab939066SGeorge Rimar .Case("==", 2) 84ab939066SGeorge Rimar .Case("!=", 2) 85960504b9SRui Ueyama .Case("&", 1) 86960504b9SRui Ueyama .Default(-1); 87960504b9SRui Ueyama } 88960504b9SRui Ueyama 899c1112d0SRui Ueyama static uint64_t evalExpr(std::vector<StringRef> &Tokens, uint64_t Dot) { 909c1112d0SRui Ueyama return ExprParser(Tokens, Dot).run(); 91960504b9SRui Ueyama } 92960504b9SRui Ueyama 939c1112d0SRui Ueyama uint64_t ExprParser::run() { 949c1112d0SRui Ueyama uint64_t V = parseExpr(); 959c1112d0SRui Ueyama if (!atEOF() && !Error) 969c1112d0SRui Ueyama setError("stray token: " + peek()); 979c1112d0SRui Ueyama return V; 986011811bSRui Ueyama } 996011811bSRui Ueyama 100960504b9SRui Ueyama // This is a part of the operator-precedence parser to evaluate 101960504b9SRui Ueyama // arithmetic expressions in SECTIONS command. This function evaluates an 102e29a975dSRui Ueyama // integer literal, a parenthesized expression, the ALIGN function, 103e29a975dSRui Ueyama // or the special variable ".". 1049c1112d0SRui Ueyama uint64_t ExprParser::parsePrimary() { 1059c1112d0SRui Ueyama StringRef Tok = next(); 106960504b9SRui Ueyama if (Tok == ".") 107960504b9SRui Ueyama return Dot; 108960504b9SRui Ueyama if (Tok == "(") { 1099c1112d0SRui Ueyama uint64_t V = parseExpr(); 1109c1112d0SRui Ueyama expect(")"); 111960504b9SRui Ueyama return V; 112960504b9SRui Ueyama } 113dffc1410SGeorge Rimar if (Tok == "ALIGN") { 1149c1112d0SRui Ueyama expect("("); 1159c1112d0SRui Ueyama uint64_t V = parseExpr(); 1169c1112d0SRui Ueyama expect(")"); 117dffc1410SGeorge Rimar return alignTo(Dot, V); 118dffc1410SGeorge Rimar } 1195fa60985SRui Ueyama uint64_t V = 0; 1205fa60985SRui Ueyama if (Tok.getAsInteger(0, V)) 1219c1112d0SRui Ueyama setError("malformed number: " + Tok); 1225fa60985SRui Ueyama return V; 123960504b9SRui Ueyama } 124960504b9SRui Ueyama 1259c1112d0SRui Ueyama uint64_t ExprParser::parseTernary(uint64_t Cond) { 1269c1112d0SRui Ueyama next(); 1279c1112d0SRui Ueyama uint64_t V = parseExpr(); 1289c1112d0SRui Ueyama expect(":"); 1299c1112d0SRui Ueyama uint64_t W = parseExpr(); 130fba45c41SGeorge Rimar return Cond ? V : W; 131fba45c41SGeorge Rimar } 132fba45c41SGeorge Rimar 1339c1112d0SRui Ueyama uint64_t ExprParser::apply(StringRef Op, uint64_t L, uint64_t R) { 134960504b9SRui Ueyama if (Op == "*") 135960504b9SRui Ueyama return L * R; 136960504b9SRui Ueyama if (Op == "/") { 137960504b9SRui Ueyama if (R == 0) { 138960504b9SRui Ueyama error("division by zero"); 139960504b9SRui Ueyama return 0; 140960504b9SRui Ueyama } 141960504b9SRui Ueyama return L / R; 142960504b9SRui Ueyama } 143ab939066SGeorge Rimar if (Op == "+") 144ab939066SGeorge Rimar return L + R; 145ab939066SGeorge Rimar if (Op == "-") 146ab939066SGeorge Rimar return L - R; 147ab939066SGeorge Rimar if (Op == "<") 148ab939066SGeorge Rimar return L < R; 149ab939066SGeorge Rimar if (Op == ">") 150ab939066SGeorge Rimar return L > R; 151ab939066SGeorge Rimar if (Op == ">=") 152ab939066SGeorge Rimar return L >= R; 153ab939066SGeorge Rimar if (Op == "<=") 154ab939066SGeorge Rimar return L <= R; 155ab939066SGeorge Rimar if (Op == "==") 156ab939066SGeorge Rimar return L == R; 157ab939066SGeorge Rimar if (Op == "!=") 158ab939066SGeorge Rimar return L != R; 159960504b9SRui Ueyama if (Op == "&") 160960504b9SRui Ueyama return L & R; 1617a81d674SRui Ueyama llvm_unreachable("invalid operator"); 162652852c5SGeorge Rimar } 163652852c5SGeorge Rimar 1649c1112d0SRui Ueyama // This is a part of the operator-precedence parser. 1659c1112d0SRui Ueyama // This function assumes that the remaining token stream starts 1669c1112d0SRui Ueyama // with an operator. 1679c1112d0SRui Ueyama uint64_t ExprParser::parseExpr1(uint64_t Lhs, int MinPrec) { 1689c1112d0SRui Ueyama while (!atEOF()) { 169960504b9SRui Ueyama // Read an operator and an expression. 1709c1112d0SRui Ueyama StringRef Op1 = peek(); 171fba45c41SGeorge Rimar if (Op1 == "?") 1729c1112d0SRui Ueyama return parseTernary(Lhs); 173960504b9SRui Ueyama if (precedence(Op1) < MinPrec) 174960504b9SRui Ueyama return Lhs; 1759c1112d0SRui Ueyama next(); 1769c1112d0SRui Ueyama uint64_t Rhs = parsePrimary(); 177960504b9SRui Ueyama 178960504b9SRui Ueyama // Evaluate the remaining part of the expression first if the 179960504b9SRui Ueyama // next operator has greater precedence than the previous one. 180960504b9SRui Ueyama // For example, if we have read "+" and "3", and if the next 181960504b9SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 1829c1112d0SRui Ueyama while (!atEOF()) { 1839c1112d0SRui Ueyama StringRef Op2 = peek(); 184960504b9SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 185960504b9SRui Ueyama break; 1869c1112d0SRui Ueyama Rhs = parseExpr1(Rhs, precedence(Op2)); 187652852c5SGeorge Rimar } 188960504b9SRui Ueyama 189960504b9SRui Ueyama Lhs = apply(Op1, Lhs, Rhs); 190960504b9SRui Ueyama } 191960504b9SRui Ueyama return Lhs; 192960504b9SRui Ueyama } 193960504b9SRui Ueyama 1949c1112d0SRui Ueyama // Reads and evaluates an arithmetic expression. 1959c1112d0SRui Ueyama uint64_t ExprParser::parseExpr() { return parseExpr1(parsePrimary(), 0); } 196652852c5SGeorge Rimar 1971ebc8ed7SRui Ueyama template <class ELFT> 1988ec77e64SRui Ueyama StringRef LinkerScript<ELFT>::getOutputSection(InputSectionBase<ELFT> *S) { 19907320e40SRui Ueyama for (SectionRule &R : Opt.Sections) 200722830a5SRui Ueyama if (globMatch(R.SectionPattern, S->getSectionName())) 2018ec77e64SRui Ueyama return R.Dest; 2028ec77e64SRui Ueyama return ""; 203717677afSRui Ueyama } 204717677afSRui Ueyama 2051ebc8ed7SRui Ueyama template <class ELFT> 20607320e40SRui Ueyama bool LinkerScript<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) { 207e63d81bdSEugene Leviant return !S || !S->Live || getOutputSection(S) == "/DISCARD/"; 208717677afSRui Ueyama } 209717677afSRui Ueyama 21007320e40SRui Ueyama template <class ELFT> 21107320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 2128ec77e64SRui Ueyama for (StringRef Pat : Opt.KeptSections) 213722830a5SRui Ueyama if (globMatch(Pat, S->getSectionName())) 2148ec77e64SRui Ueyama return true; 2158ec77e64SRui Ueyama return false; 216481c2ce6SGeorge Rimar } 217481c2ce6SGeorge Rimar 218652852c5SGeorge Rimar template <class ELFT> 219a7f7884dSRui Ueyama std::vector<OutputSectionBase<ELFT> *> 220e63d81bdSEugene Leviant LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 221a7f7884dSRui Ueyama std::vector<OutputSectionBase<ELFT> *> Result; 222a7f7884dSRui Ueyama 223e63d81bdSEugene Leviant // Add input section to output section. If there is no output section yet, 224e63d81bdSEugene Leviant // then create it and add to output section list. 225e63d81bdSEugene Leviant auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name) { 226e63d81bdSEugene Leviant OutputSectionBase<ELFT> *Sec; 227e63d81bdSEugene Leviant bool IsNew; 228e63d81bdSEugene Leviant std::tie(Sec, IsNew) = Factory.create(C, Name); 229e63d81bdSEugene Leviant if (IsNew) 230a7f7884dSRui Ueyama Result.push_back(Sec); 231e63d81bdSEugene Leviant Sec->addSection(C); 232e63d81bdSEugene Leviant }; 233e63d81bdSEugene Leviant 234e63d81bdSEugene Leviant // Select input sections matching rule and add them to corresponding 235e63d81bdSEugene Leviant // output section. Section rules are processed in order they're listed 236e63d81bdSEugene Leviant // in script, so correct input section order is maintained by design. 237e63d81bdSEugene Leviant for (SectionRule &R : Opt.Sections) 238e63d81bdSEugene Leviant for (const std::unique_ptr<ObjectFile<ELFT>> &F : 239e63d81bdSEugene Leviant Symtab<ELFT>::X->getObjectFiles()) 240e63d81bdSEugene Leviant for (InputSectionBase<ELFT> *S : F->getSections()) 241e63d81bdSEugene Leviant if (!isDiscarded(S) && !S->OutSec && 242e63d81bdSEugene Leviant globMatch(R.SectionPattern, S->getSectionName())) 243e63d81bdSEugene Leviant // Add single input section to output section. 244e63d81bdSEugene Leviant AddInputSec(S, R.Dest); 245e63d81bdSEugene Leviant 246e63d81bdSEugene Leviant // Add all other input sections, which are not listed in script. 247e63d81bdSEugene Leviant for (const std::unique_ptr<ObjectFile<ELFT>> &F : 248e63d81bdSEugene Leviant Symtab<ELFT>::X->getObjectFiles()) 249e63d81bdSEugene Leviant for (InputSectionBase<ELFT> *S : F->getSections()) 250e63d81bdSEugene Leviant if (!isDiscarded(S)) { 251e63d81bdSEugene Leviant if (!S->OutSec) 252e63d81bdSEugene Leviant AddInputSec(S, getOutputSectionName(S)); 253e63d81bdSEugene Leviant } else 254e63d81bdSEugene Leviant reportDiscarded(S, F); 255e63d81bdSEugene Leviant 256e63d81bdSEugene Leviant return Result; 257e63d81bdSEugene Leviant } 258e63d81bdSEugene Leviant 259e63d81bdSEugene Leviant template <class ELFT> 26007320e40SRui Ueyama void LinkerScript<ELFT>::assignAddresses( 261dbbd8b15SGeorge Rimar ArrayRef<OutputSectionBase<ELFT> *> Sections) { 262652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 2637c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 2647c18c28cSRui Ueyama // We place orphan sections at end of file. 2657c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 266652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 2677c18c28cSRui Ueyama for (OutputSectionBase<ELFT> *Sec : Sections) { 268652852c5SGeorge Rimar StringRef Name = Sec->getName(); 269c3e2a4b0SRui Ueyama if (getSectionIndex(Name) == INT_MAX) 270076fe157SGeorge Rimar Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name)); 271652852c5SGeorge Rimar } 272652852c5SGeorge Rimar 2737c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 274c998a8c0SRui Ueyama Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 275467c4d55SEugene Leviant uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 276652852c5SGeorge Rimar uintX_t ThreadBssOffset = 0; 277652852c5SGeorge Rimar 278076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 279076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 280076fe157SGeorge Rimar uint64_t Val = evalExpr(Cmd->Expr, Dot); 281076fe157SGeorge Rimar if (Cmd->Name == ".") { 28205ef4cffSRui Ueyama 28305ef4cffSRui Ueyama Dot = Val; 28405ef4cffSRui Ueyama } else { 285076fe157SGeorge Rimar auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd->Name)); 28605ef4cffSRui Ueyama D->Value = Val; 287eda81a1bSEugene Leviant } 28805ef4cffSRui Ueyama continue; 289652852c5SGeorge Rimar } 290652852c5SGeorge Rimar 291fb8978fcSDima Stepanov // Find all the sections with required name. There can be more than 2926ad330acSGeorge Rimar // one section with such name, if the alignment, flags or type 293fb8978fcSDima Stepanov // attribute differs. 294076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 295fb8978fcSDima Stepanov for (OutputSectionBase<ELFT> *Sec : Sections) { 296076fe157SGeorge Rimar if (Sec->getName() != Cmd->Name) 297652852c5SGeorge Rimar continue; 298652852c5SGeorge Rimar 299652852c5SGeorge Rimar if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { 300c998a8c0SRui Ueyama uintX_t TVA = Dot + ThreadBssOffset; 301424b4081SRui Ueyama TVA = alignTo(TVA, Sec->getAlignment()); 302652852c5SGeorge Rimar Sec->setVA(TVA); 303c998a8c0SRui Ueyama ThreadBssOffset = TVA - Dot + Sec->getSize(); 304652852c5SGeorge Rimar continue; 305652852c5SGeorge Rimar } 306652852c5SGeorge Rimar 307652852c5SGeorge Rimar if (Sec->getFlags() & SHF_ALLOC) { 308424b4081SRui Ueyama Dot = alignTo(Dot, Sec->getAlignment()); 309c998a8c0SRui Ueyama Sec->setVA(Dot); 310467c4d55SEugene Leviant MinVA = std::min(MinVA, Dot); 311c998a8c0SRui Ueyama Dot += Sec->getSize(); 312652852c5SGeorge Rimar continue; 313652852c5SGeorge Rimar } 314652852c5SGeorge Rimar } 315652852c5SGeorge Rimar } 316467c4d55SEugene Leviant 31764c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 318b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 319467c4d55SEugene Leviant MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() - 320467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->getSize(), 321467c4d55SEugene Leviant Target->PageSize); 322467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 323467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 324fb8978fcSDima Stepanov } 325652852c5SGeorge Rimar 32607320e40SRui Ueyama template <class ELFT> 32774df5c7eSRafael Espindola std::vector<PhdrEntry<ELFT>> 328bbe38602SEugene Leviant LinkerScript<ELFT>::createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> Sections) { 329bbe38602SEugene Leviant int TlsNum = -1; 330bbe38602SEugene Leviant int NoteNum = -1; 331bbe38602SEugene Leviant int RelroNum = -1; 332bbe38602SEugene Leviant Phdr *Load = nullptr; 333bbe38602SEugene Leviant uintX_t Flags = PF_R; 334bbe38602SEugene Leviant std::vector<Phdr> Phdrs; 335bbe38602SEugene Leviant 336bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 337865bf863SEugene Leviant Phdrs.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 338bbe38602SEugene Leviant Phdr &Added = Phdrs.back(); 339bbe38602SEugene Leviant 340bbe38602SEugene Leviant if (Cmd.HasFilehdr) 34118f084ffSRui Ueyama Added.add(Out<ELFT>::ElfHeader); 342bbe38602SEugene Leviant if (Cmd.HasPhdrs) 34318f084ffSRui Ueyama Added.add(Out<ELFT>::ProgramHeaders); 344bbe38602SEugene Leviant 345bbe38602SEugene Leviant switch (Cmd.Type) { 346bbe38602SEugene Leviant case PT_INTERP: 347*fd03cfd2SRui Ueyama if (Out<ELFT>::Interp) 34818f084ffSRui Ueyama Added.add(Out<ELFT>::Interp); 349bbe38602SEugene Leviant break; 350bbe38602SEugene Leviant case PT_DYNAMIC: 351bbe38602SEugene Leviant if (isOutputDynamic<ELFT>()) { 352bbe38602SEugene Leviant Added.H.p_flags = toPhdrFlags(Out<ELFT>::Dynamic->getFlags()); 35318f084ffSRui Ueyama Added.add(Out<ELFT>::Dynamic); 354bbe38602SEugene Leviant } 355bbe38602SEugene Leviant break; 356bbe38602SEugene Leviant case PT_TLS: 357bbe38602SEugene Leviant TlsNum = Phdrs.size() - 1; 358bbe38602SEugene Leviant break; 359bbe38602SEugene Leviant case PT_NOTE: 360bbe38602SEugene Leviant NoteNum = Phdrs.size() - 1; 361bbe38602SEugene Leviant break; 362bbe38602SEugene Leviant case PT_GNU_RELRO: 363bbe38602SEugene Leviant RelroNum = Phdrs.size() - 1; 364bbe38602SEugene Leviant break; 365bbe38602SEugene Leviant case PT_GNU_EH_FRAME: 366bbe38602SEugene Leviant if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) { 367bbe38602SEugene Leviant Added.H.p_flags = toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags()); 36818f084ffSRui Ueyama Added.add(Out<ELFT>::EhFrameHdr); 369bbe38602SEugene Leviant } 370bbe38602SEugene Leviant break; 371bbe38602SEugene Leviant } 372bbe38602SEugene Leviant } 373bbe38602SEugene Leviant 374bbe38602SEugene Leviant for (OutputSectionBase<ELFT> *Sec : Sections) { 375bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 376bbe38602SEugene Leviant break; 377bbe38602SEugene Leviant 378bbe38602SEugene Leviant if (TlsNum != -1 && (Sec->getFlags() & SHF_TLS)) 37918f084ffSRui Ueyama Phdrs[TlsNum].add(Sec); 380bbe38602SEugene Leviant 381bbe38602SEugene Leviant if (!needsPtLoad<ELFT>(Sec)) 382bbe38602SEugene Leviant continue; 383bbe38602SEugene Leviant 384bbe38602SEugene Leviant const std::vector<size_t> &PhdrIds = 385bbe38602SEugene Leviant getPhdrIndicesForSection(Sec->getName()); 386bbe38602SEugene Leviant if (!PhdrIds.empty()) { 387bbe38602SEugene Leviant // Assign headers specified by linker script 388bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 38918f084ffSRui Ueyama Phdrs[Id].add(Sec); 390865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 391865bf863SEugene Leviant Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags()); 392bbe38602SEugene Leviant Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags()); 393bbe38602SEugene Leviant } 394bbe38602SEugene Leviant } else { 395bbe38602SEugene Leviant // If we have no load segment or flags've changed then we want new load 396bbe38602SEugene Leviant // segment. 397bbe38602SEugene Leviant uintX_t NewFlags = toPhdrFlags(Sec->getFlags()); 398bbe38602SEugene Leviant if (Load == nullptr || Flags != NewFlags) { 399bbe38602SEugene Leviant Load = &*Phdrs.emplace(Phdrs.end(), PT_LOAD, NewFlags); 400bbe38602SEugene Leviant Flags = NewFlags; 401bbe38602SEugene Leviant } 40218f084ffSRui Ueyama Load->add(Sec); 403bbe38602SEugene Leviant } 404bbe38602SEugene Leviant 405bbe38602SEugene Leviant if (RelroNum != -1 && isRelroSection(Sec)) 40618f084ffSRui Ueyama Phdrs[RelroNum].add(Sec); 407bbe38602SEugene Leviant if (NoteNum != -1 && Sec->getType() == SHT_NOTE) 40818f084ffSRui Ueyama Phdrs[NoteNum].add(Sec); 409bbe38602SEugene Leviant } 410bbe38602SEugene Leviant return Phdrs; 411bbe38602SEugene Leviant } 412bbe38602SEugene Leviant 413bbe38602SEugene Leviant template <class ELFT> 41407320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 415f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 416f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 417f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 418f6c3ccefSGeorge Rimar return Cmd->Filler; 419e2ee72b5SGeorge Rimar return {}; 420e2ee72b5SGeorge Rimar } 421e2ee72b5SGeorge Rimar 422c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 423c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 424c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 425c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 426076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 42771b26e94SGeorge Rimar auto Begin = Opt.Commands.begin(); 42871b26e94SGeorge Rimar auto End = Opt.Commands.end(); 429076fe157SGeorge Rimar auto I = 430076fe157SGeorge Rimar std::find_if(Begin, End, [&](const std::unique_ptr<BaseCommand> &Base) { 431076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 432076fe157SGeorge Rimar if (Cmd->Name == Name) 433076fe157SGeorge Rimar return true; 434076fe157SGeorge Rimar return false; 43571b26e94SGeorge Rimar }); 436c3e2a4b0SRui Ueyama return I == End ? INT_MAX : (I - Begin); 43771b26e94SGeorge Rimar } 43871b26e94SGeorge Rimar 43971b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if 44071b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0. 44107320e40SRui Ueyama template <class ELFT> 44207320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 443c3e2a4b0SRui Ueyama int I = getSectionIndex(A); 444c3e2a4b0SRui Ueyama int J = getSectionIndex(B); 445c3e2a4b0SRui Ueyama if (I == INT_MAX && J == INT_MAX) 446717677afSRui Ueyama return 0; 447717677afSRui Ueyama return I < J ? -1 : 1; 448717677afSRui Ueyama } 449717677afSRui Ueyama 450076fe157SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::addScriptedSymbols() { 451076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 452076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) 453076fe157SGeorge Rimar if (Cmd->Name != "." && Symtab<ELFT>::X->find(Cmd->Name) == nullptr) 454076fe157SGeorge Rimar Symtab<ELFT>::X->addAbsolute(Cmd->Name, STV_DEFAULT); 455eda81a1bSEugene Leviant } 456eda81a1bSEugene Leviant 457bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 458bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 459bbe38602SEugene Leviant } 460bbe38602SEugene Leviant 461bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 462bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 463bbe38602SEugene Leviant // PHDRS {} script block. 464bbe38602SEugene Leviant template <class ELFT> 465bbe38602SEugene Leviant std::vector<size_t> 466bbe38602SEugene Leviant LinkerScript<ELFT>::getPhdrIndicesForSection(StringRef Name) { 467076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 468076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 469076fe157SGeorge Rimar if (!Cmd || Cmd->Name != Name) 47031d842f5SGeorge Rimar continue; 47131d842f5SGeorge Rimar 472bbe38602SEugene Leviant std::vector<size_t> Indices; 473076fe157SGeorge Rimar for (StringRef PhdrName : Cmd->Phdrs) { 47431d842f5SGeorge Rimar auto ItPhdr = 47531d842f5SGeorge Rimar std::find_if(Opt.PhdrsCommands.rbegin(), Opt.PhdrsCommands.rend(), 476076fe157SGeorge Rimar [&](PhdrsCommand &P) { return P.Name == PhdrName; }); 477bbe38602SEugene Leviant if (ItPhdr == Opt.PhdrsCommands.rend()) 478bbe38602SEugene Leviant error("section header '" + PhdrName + "' is not listed in PHDRS"); 479bbe38602SEugene Leviant else 480bbe38602SEugene Leviant Indices.push_back(std::distance(ItPhdr, Opt.PhdrsCommands.rend()) - 1); 481bbe38602SEugene Leviant } 482bbe38602SEugene Leviant return Indices; 483bbe38602SEugene Leviant } 48431d842f5SGeorge Rimar return {}; 48531d842f5SGeorge Rimar } 486bbe38602SEugene Leviant 48707320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 488c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 489c3794e58SGeorge Rimar 490f7c5fbb1SRui Ueyama public: 49107320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 492f23b2320SGeorge Rimar 4934a46539cSRui Ueyama void run(); 494f7c5fbb1SRui Ueyama 495f7c5fbb1SRui Ueyama private: 49652a1509eSRui Ueyama void addFile(StringRef Path); 49752a1509eSRui Ueyama 498f7c5fbb1SRui Ueyama void readAsNeeded(); 49990c5099eSDenis Protivensky void readEntry(); 50083f406cfSGeorge Rimar void readExtern(); 501f7c5fbb1SRui Ueyama void readGroup(); 50231aa1f83SRui Ueyama void readInclude(); 503c3794e58SGeorge Rimar void readNothing() {} 504ee59282bSRui Ueyama void readOutput(); 5059159ce93SDavide Italiano void readOutputArch(); 506f7c5fbb1SRui Ueyama void readOutputFormat(); 507bbe38602SEugene Leviant void readPhdrs(); 50868a39a65SDavide Italiano void readSearchDir(); 5098e3b38abSDenis Protivensky void readSections(); 5108e3b38abSDenis Protivensky 511652852c5SGeorge Rimar void readLocationCounterValue(); 512eda81a1bSEugene Leviant void readOutputSectionDescription(StringRef OutSec); 513bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 514bbe38602SEugene Leviant unsigned readPhdrType(); 515eda81a1bSEugene Leviant void readSymbolAssignment(StringRef Name); 516eda81a1bSEugene Leviant std::vector<StringRef> readSectionsCommandExpr(); 517f7c5fbb1SRui Ueyama 518c3794e58SGeorge Rimar const static StringMap<Handler> Cmd; 51907320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 52007320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 52116b0cc9eSSimon Atanasyan bool IsUnderSysroot; 522f7c5fbb1SRui Ueyama }; 523f7c5fbb1SRui Ueyama 524e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = { 525c3794e58SGeorge Rimar {"ENTRY", &ScriptParser::readEntry}, 526c3794e58SGeorge Rimar {"EXTERN", &ScriptParser::readExtern}, 527c3794e58SGeorge Rimar {"GROUP", &ScriptParser::readGroup}, 528c3794e58SGeorge Rimar {"INCLUDE", &ScriptParser::readInclude}, 529c3794e58SGeorge Rimar {"INPUT", &ScriptParser::readGroup}, 530c3794e58SGeorge Rimar {"OUTPUT", &ScriptParser::readOutput}, 531c3794e58SGeorge Rimar {"OUTPUT_ARCH", &ScriptParser::readOutputArch}, 532c3794e58SGeorge Rimar {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat}, 533bbe38602SEugene Leviant {"PHDRS", &ScriptParser::readPhdrs}, 534c3794e58SGeorge Rimar {"SEARCH_DIR", &ScriptParser::readSearchDir}, 535c3794e58SGeorge Rimar {"SECTIONS", &ScriptParser::readSections}, 536c3794e58SGeorge Rimar {";", &ScriptParser::readNothing}}; 537c3794e58SGeorge Rimar 538717677afSRui Ueyama void ScriptParser::run() { 539f7c5fbb1SRui Ueyama while (!atEOF()) { 540f7c5fbb1SRui Ueyama StringRef Tok = next(); 541c3794e58SGeorge Rimar if (Handler Fn = Cmd.lookup(Tok)) 542c3794e58SGeorge Rimar (this->*Fn)(); 543c3794e58SGeorge Rimar else 5445761042dSGeorge Rimar setError("unknown directive: " + Tok); 545f7c5fbb1SRui Ueyama } 546f7c5fbb1SRui Ueyama } 547f7c5fbb1SRui Ueyama 548717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 54916b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 55016b0cc9eSSimon Atanasyan SmallString<128> Path; 55116b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 55216b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 55316b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 55416b0cc9eSSimon Atanasyan return; 55516b0cc9eSSimon Atanasyan } 55616b0cc9eSSimon Atanasyan } 55716b0cc9eSSimon Atanasyan 558f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 55952a1509eSRui Ueyama Driver->addFile(S); 56052a1509eSRui Ueyama } else if (S.startswith("=")) { 56152a1509eSRui Ueyama if (Config->Sysroot.empty()) 56252a1509eSRui Ueyama Driver->addFile(S.substr(1)); 56352a1509eSRui Ueyama else 56452a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 56552a1509eSRui Ueyama } else if (S.startswith("-l")) { 56621eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 567a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 568a1b8fc3bSSimon Atanasyan Driver->addFile(S); 56952a1509eSRui Ueyama } else { 57052a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 57152a1509eSRui Ueyama if (Path.empty()) 572777f9630SGeorge Rimar setError("unable to find " + S); 573025d59b1SRui Ueyama else 57452a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 57552a1509eSRui Ueyama } 57652a1509eSRui Ueyama } 57752a1509eSRui Ueyama 578717677afSRui Ueyama void ScriptParser::readAsNeeded() { 579f7c5fbb1SRui Ueyama expect("("); 58035da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 58135da9b6eSRui Ueyama Config->AsNeeded = true; 582025d59b1SRui Ueyama while (!Error) { 583f7c5fbb1SRui Ueyama StringRef Tok = next(); 584f7c5fbb1SRui Ueyama if (Tok == ")") 58535da9b6eSRui Ueyama break; 58652a1509eSRui Ueyama addFile(Tok); 587f7c5fbb1SRui Ueyama } 58835da9b6eSRui Ueyama Config->AsNeeded = Orig; 589f7c5fbb1SRui Ueyama } 590f7c5fbb1SRui Ueyama 591717677afSRui Ueyama void ScriptParser::readEntry() { 59290c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 59390c5099eSDenis Protivensky expect("("); 59490c5099eSDenis Protivensky StringRef Tok = next(); 59590c5099eSDenis Protivensky if (Config->Entry.empty()) 59690c5099eSDenis Protivensky Config->Entry = Tok; 59790c5099eSDenis Protivensky expect(")"); 59890c5099eSDenis Protivensky } 59990c5099eSDenis Protivensky 600717677afSRui Ueyama void ScriptParser::readExtern() { 60183f406cfSGeorge Rimar expect("("); 602025d59b1SRui Ueyama while (!Error) { 60383f406cfSGeorge Rimar StringRef Tok = next(); 60483f406cfSGeorge Rimar if (Tok == ")") 60583f406cfSGeorge Rimar return; 60683f406cfSGeorge Rimar Config->Undefined.push_back(Tok); 60783f406cfSGeorge Rimar } 60883f406cfSGeorge Rimar } 60983f406cfSGeorge Rimar 610717677afSRui Ueyama void ScriptParser::readGroup() { 611f7c5fbb1SRui Ueyama expect("("); 612025d59b1SRui Ueyama while (!Error) { 613f7c5fbb1SRui Ueyama StringRef Tok = next(); 614f7c5fbb1SRui Ueyama if (Tok == ")") 615f7c5fbb1SRui Ueyama return; 616f7c5fbb1SRui Ueyama if (Tok == "AS_NEEDED") { 617f7c5fbb1SRui Ueyama readAsNeeded(); 618f7c5fbb1SRui Ueyama continue; 619f7c5fbb1SRui Ueyama } 62052a1509eSRui Ueyama addFile(Tok); 621f7c5fbb1SRui Ueyama } 622f7c5fbb1SRui Ueyama } 623f7c5fbb1SRui Ueyama 624717677afSRui Ueyama void ScriptParser::readInclude() { 62531aa1f83SRui Ueyama StringRef Tok = next(); 62631aa1f83SRui Ueyama auto MBOrErr = MemoryBuffer::getFile(Tok); 627025d59b1SRui Ueyama if (!MBOrErr) { 6285761042dSGeorge Rimar setError("cannot open " + Tok); 629025d59b1SRui Ueyama return; 630025d59b1SRui Ueyama } 63131aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 632a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 633a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 63431aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 63531aa1f83SRui Ueyama } 63631aa1f83SRui Ueyama 637717677afSRui Ueyama void ScriptParser::readOutput() { 638ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 639ee59282bSRui Ueyama expect("("); 640ee59282bSRui Ueyama StringRef Tok = next(); 641ee59282bSRui Ueyama if (Config->OutputFile.empty()) 642ee59282bSRui Ueyama Config->OutputFile = Tok; 643ee59282bSRui Ueyama expect(")"); 644ee59282bSRui Ueyama } 645ee59282bSRui Ueyama 646717677afSRui Ueyama void ScriptParser::readOutputArch() { 6479159ce93SDavide Italiano // Error checking only for now. 6489159ce93SDavide Italiano expect("("); 6499159ce93SDavide Italiano next(); 6509159ce93SDavide Italiano expect(")"); 6519159ce93SDavide Italiano } 6529159ce93SDavide Italiano 653717677afSRui Ueyama void ScriptParser::readOutputFormat() { 654f7c5fbb1SRui Ueyama // Error checking only for now. 655f7c5fbb1SRui Ueyama expect("("); 656f7c5fbb1SRui Ueyama next(); 6576836c618SDavide Italiano StringRef Tok = next(); 6586836c618SDavide Italiano if (Tok == ")") 6596836c618SDavide Italiano return; 660025d59b1SRui Ueyama if (Tok != ",") { 6615761042dSGeorge Rimar setError("unexpected token: " + Tok); 662025d59b1SRui Ueyama return; 663025d59b1SRui Ueyama } 6646836c618SDavide Italiano next(); 6656836c618SDavide Italiano expect(","); 6666836c618SDavide Italiano next(); 667f7c5fbb1SRui Ueyama expect(")"); 668f7c5fbb1SRui Ueyama } 669f7c5fbb1SRui Ueyama 670bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 671bbe38602SEugene Leviant expect("{"); 672bbe38602SEugene Leviant while (!Error && !skip("}")) { 673bbe38602SEugene Leviant StringRef Tok = next(); 674865bf863SEugene Leviant Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX}); 675bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 676bbe38602SEugene Leviant 677bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 678bbe38602SEugene Leviant do { 679bbe38602SEugene Leviant Tok = next(); 680bbe38602SEugene Leviant if (Tok == ";") 681bbe38602SEugene Leviant break; 682bbe38602SEugene Leviant if (Tok == "FILEHDR") 683bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 684bbe38602SEugene Leviant else if (Tok == "PHDRS") 685bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 686865bf863SEugene Leviant else if (Tok == "FLAGS") { 687865bf863SEugene Leviant expect("("); 688865bf863SEugene Leviant next().getAsInteger(0, PhdrCmd.Flags); 689865bf863SEugene Leviant expect(")"); 690865bf863SEugene Leviant } else 691bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 692bbe38602SEugene Leviant } while (!Error); 693bbe38602SEugene Leviant } 694bbe38602SEugene Leviant } 695bbe38602SEugene Leviant 696717677afSRui Ueyama void ScriptParser::readSearchDir() { 69768a39a65SDavide Italiano expect("("); 69806501920SRafael Espindola Config->SearchPaths.push_back(next()); 69968a39a65SDavide Italiano expect(")"); 70068a39a65SDavide Italiano } 70168a39a65SDavide Italiano 702717677afSRui Ueyama void ScriptParser::readSections() { 70307320e40SRui Ueyama Opt.DoLayout = true; 7048e3b38abSDenis Protivensky expect("{"); 705652852c5SGeorge Rimar while (!Error && !skip("}")) { 706652852c5SGeorge Rimar StringRef Tok = peek(); 707eda81a1bSEugene Leviant if (Tok == ".") { 708652852c5SGeorge Rimar readLocationCounterValue(); 709eda81a1bSEugene Leviant continue; 710eda81a1bSEugene Leviant } 711eda81a1bSEugene Leviant next(); 712eda81a1bSEugene Leviant if (peek() == "=") 713eda81a1bSEugene Leviant readSymbolAssignment(Tok); 714652852c5SGeorge Rimar else 715eda81a1bSEugene Leviant readOutputSectionDescription(Tok); 7168e3b38abSDenis Protivensky } 717652852c5SGeorge Rimar } 7188e3b38abSDenis Protivensky 719652852c5SGeorge Rimar void ScriptParser::readLocationCounterValue() { 720652852c5SGeorge Rimar expect("."); 721652852c5SGeorge Rimar expect("="); 722eda81a1bSEugene Leviant std::vector<StringRef> Expr = readSectionsCommandExpr(); 723eda81a1bSEugene Leviant if (Expr.empty()) 724652852c5SGeorge Rimar error("error in location counter expression"); 725eda81a1bSEugene Leviant else 726076fe157SGeorge Rimar Opt.Commands.push_back(llvm::make_unique<SymbolAssignment>(".", Expr)); 727652852c5SGeorge Rimar } 728652852c5SGeorge Rimar 729eda81a1bSEugene Leviant void ScriptParser::readOutputSectionDescription(StringRef OutSec) { 730076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 731076fe157SGeorge Rimar Opt.Commands.emplace_back(Cmd); 7328e3b38abSDenis Protivensky expect(":"); 7338e3b38abSDenis Protivensky expect("{"); 7348ec77e64SRui Ueyama 735025d59b1SRui Ueyama while (!Error && !skip("}")) { 736481c2ce6SGeorge Rimar StringRef Tok = next(); 737481c2ce6SGeorge Rimar if (Tok == "*") { 7388ec77e64SRui Ueyama expect("("); 7398ec77e64SRui Ueyama while (!Error && !skip(")")) 7408ec77e64SRui Ueyama Opt.Sections.emplace_back(OutSec, next()); 741481c2ce6SGeorge Rimar } else if (Tok == "KEEP") { 7428e3b38abSDenis Protivensky expect("("); 7438ec77e64SRui Ueyama expect("*"); 7448ec77e64SRui Ueyama expect("("); 7458ec77e64SRui Ueyama while (!Error && !skip(")")) { 7468ec77e64SRui Ueyama StringRef Sec = next(); 7478ec77e64SRui Ueyama Opt.Sections.emplace_back(OutSec, Sec); 7488ec77e64SRui Ueyama Opt.KeptSections.push_back(Sec); 7498ec77e64SRui Ueyama } 750481c2ce6SGeorge Rimar expect(")"); 751481c2ce6SGeorge Rimar } else { 752777f9630SGeorge Rimar setError("unknown command " + Tok); 753481c2ce6SGeorge Rimar } 7548e3b38abSDenis Protivensky } 755076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 7568ec77e64SRui Ueyama 757e2ee72b5SGeorge Rimar StringRef Tok = peek(); 758e2ee72b5SGeorge Rimar if (Tok.startswith("=")) { 759e2ee72b5SGeorge Rimar if (!Tok.startswith("=0x")) { 7603ed2f069SRui Ueyama setError("filler should be a hexadecimal value"); 761e2ee72b5SGeorge Rimar return; 762e2ee72b5SGeorge Rimar } 7633e808976SRui Ueyama Tok = Tok.substr(3); 764f6c3ccefSGeorge Rimar Cmd->Filler = parseHex(Tok); 765e2ee72b5SGeorge Rimar next(); 766e2ee72b5SGeorge Rimar } 7678e3b38abSDenis Protivensky } 7688e3b38abSDenis Protivensky 769eda81a1bSEugene Leviant void ScriptParser::readSymbolAssignment(StringRef Name) { 770eda81a1bSEugene Leviant expect("="); 771eda81a1bSEugene Leviant std::vector<StringRef> Expr = readSectionsCommandExpr(); 772eda81a1bSEugene Leviant if (Expr.empty()) 773eda81a1bSEugene Leviant error("error in symbol assignment expression"); 774eda81a1bSEugene Leviant else 775076fe157SGeorge Rimar Opt.Commands.push_back(llvm::make_unique<SymbolAssignment>(Name, Expr)); 776eda81a1bSEugene Leviant } 777eda81a1bSEugene Leviant 778eda81a1bSEugene Leviant std::vector<StringRef> ScriptParser::readSectionsCommandExpr() { 779eda81a1bSEugene Leviant std::vector<StringRef> Expr; 780eda81a1bSEugene Leviant while (!Error) { 781eda81a1bSEugene Leviant StringRef Tok = next(); 782eda81a1bSEugene Leviant if (Tok == ";") 783eda81a1bSEugene Leviant break; 784eda81a1bSEugene Leviant Expr.push_back(Tok); 785eda81a1bSEugene Leviant } 786eda81a1bSEugene Leviant return Expr; 787eda81a1bSEugene Leviant } 788eda81a1bSEugene Leviant 789bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 790bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 791bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 792bbe38602SEugene Leviant StringRef Tok = next(); 793bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 794bbe38602SEugene Leviant if (Tok.empty()) { 795bbe38602SEugene Leviant setError("section header name is empty"); 796bbe38602SEugene Leviant break; 797bbe38602SEugene Leviant } 798bbe38602SEugene Leviant Phdrs.push_back(Tok); 799bbe38602SEugene Leviant } 800bbe38602SEugene Leviant return Phdrs; 801bbe38602SEugene Leviant } 802bbe38602SEugene Leviant 803bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 804bbe38602SEugene Leviant StringRef Tok = next(); 805b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 806b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 807b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 808b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 809b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 810b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 811b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 812b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 813b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 814b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 815b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 816b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 817b0f6c590SRui Ueyama .Default(-1); 818bbe38602SEugene Leviant 819b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 820b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 821b0f6c590SRui Ueyama return PT_NULL; 822b0f6c590SRui Ueyama } 823b0f6c590SRui Ueyama return Ret; 824bbe38602SEugene Leviant } 825bbe38602SEugene Leviant 82616b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 82716b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 82816b0cc9eSSimon Atanasyan return false; 82916b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 83016b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 83116b0cc9eSSimon Atanasyan return true; 83216b0cc9eSSimon Atanasyan return false; 83316b0cc9eSSimon Atanasyan } 83416b0cc9eSSimon Atanasyan 83507320e40SRui Ueyama // Entry point. 83607320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 83716b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 83807320e40SRui Ueyama ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run(); 839f7c5fbb1SRui Ueyama } 8401ebc8ed7SRui Ueyama 84107320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 84207320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 84307320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 84407320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 845