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 46076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) { 47076fe157SGeorge Rimar return C->Kind == AssignmentKind; 48076fe157SGeorge Rimar } 49076fe157SGeorge Rimar 50076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) { 51076fe157SGeorge Rimar return C->Kind == OutputSectionKind; 52076fe157SGeorge Rimar } 53076fe157SGeorge Rimar 54eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) { 55eea3114fSGeorge Rimar return C->Kind == InputSectionKind; 56eea3114fSGeorge Rimar } 57eea3114fSGeorge Rimar 589c1112d0SRui Ueyama // This is an operator-precedence parser to parse and evaluate 599c1112d0SRui Ueyama // a linker script expression. For each linker script arithmetic 609c1112d0SRui Ueyama // expression (e.g. ". = . + 0x1000"), a new instance of ExprParser 619c1112d0SRui Ueyama // is created and ran. 629c1112d0SRui Ueyama namespace { 639c1112d0SRui Ueyama class ExprParser : public ScriptParserBase { 649c1112d0SRui Ueyama public: 659c1112d0SRui Ueyama ExprParser(std::vector<StringRef> &Tokens, uint64_t Dot) 669c1112d0SRui Ueyama : ScriptParserBase(Tokens), Dot(Dot) {} 679c1112d0SRui Ueyama 689c1112d0SRui Ueyama uint64_t run(); 699c1112d0SRui Ueyama 709c1112d0SRui Ueyama private: 719c1112d0SRui Ueyama uint64_t parsePrimary(); 729c1112d0SRui Ueyama uint64_t parseTernary(uint64_t Cond); 739c1112d0SRui Ueyama uint64_t apply(StringRef Op, uint64_t L, uint64_t R); 749c1112d0SRui Ueyama uint64_t parseExpr1(uint64_t Lhs, int MinPrec); 759c1112d0SRui Ueyama uint64_t parseExpr(); 769c1112d0SRui Ueyama 779c1112d0SRui Ueyama uint64_t Dot; 789c1112d0SRui Ueyama }; 799c1112d0SRui Ueyama } 809c1112d0SRui Ueyama 81960504b9SRui Ueyama static int precedence(StringRef Op) { 82960504b9SRui Ueyama return StringSwitch<int>(Op) 83960504b9SRui Ueyama .Case("*", 4) 84ab939066SGeorge Rimar .Case("/", 4) 85ab939066SGeorge Rimar .Case("+", 3) 86ab939066SGeorge Rimar .Case("-", 3) 87ab939066SGeorge Rimar .Case("<", 2) 88ab939066SGeorge Rimar .Case(">", 2) 89ab939066SGeorge Rimar .Case(">=", 2) 90ab939066SGeorge Rimar .Case("<=", 2) 91ab939066SGeorge Rimar .Case("==", 2) 92ab939066SGeorge Rimar .Case("!=", 2) 93960504b9SRui Ueyama .Case("&", 1) 94960504b9SRui Ueyama .Default(-1); 95960504b9SRui Ueyama } 96960504b9SRui Ueyama 979c1112d0SRui Ueyama static uint64_t evalExpr(std::vector<StringRef> &Tokens, uint64_t Dot) { 989c1112d0SRui Ueyama return ExprParser(Tokens, Dot).run(); 99960504b9SRui Ueyama } 100960504b9SRui Ueyama 1019c1112d0SRui Ueyama uint64_t ExprParser::run() { 1029c1112d0SRui Ueyama uint64_t V = parseExpr(); 1039c1112d0SRui Ueyama if (!atEOF() && !Error) 1049c1112d0SRui Ueyama setError("stray token: " + peek()); 1059c1112d0SRui Ueyama return V; 1066011811bSRui Ueyama } 1076011811bSRui Ueyama 10892e93fb4SGeorge Rimar uint64_t static getConstantValue(StringRef C) { 10992e93fb4SGeorge Rimar if (C == "COMMONPAGESIZE" || C == "MAXPAGESIZE") 11092e93fb4SGeorge Rimar return Target->PageSize; 11192e93fb4SGeorge Rimar error("unknown constant: " + C); 11292e93fb4SGeorge Rimar return 0; 11392e93fb4SGeorge Rimar } 11492e93fb4SGeorge Rimar 115960504b9SRui Ueyama // This is a part of the operator-precedence parser to evaluate 116960504b9SRui Ueyama // arithmetic expressions in SECTIONS command. This function evaluates an 117e29a975dSRui Ueyama // integer literal, a parenthesized expression, the ALIGN function, 118e29a975dSRui Ueyama // or the special variable ".". 1199c1112d0SRui Ueyama uint64_t ExprParser::parsePrimary() { 1209c1112d0SRui Ueyama StringRef Tok = next(); 121960504b9SRui Ueyama if (Tok == ".") 122960504b9SRui Ueyama return Dot; 123960504b9SRui Ueyama if (Tok == "(") { 1249c1112d0SRui Ueyama uint64_t V = parseExpr(); 1259c1112d0SRui Ueyama expect(")"); 126960504b9SRui Ueyama return V; 127960504b9SRui Ueyama } 128dffc1410SGeorge Rimar if (Tok == "ALIGN") { 1299c1112d0SRui Ueyama expect("("); 1309c1112d0SRui Ueyama uint64_t V = parseExpr(); 1319c1112d0SRui Ueyama expect(")"); 132dffc1410SGeorge Rimar return alignTo(Dot, V); 133dffc1410SGeorge Rimar } 13492e93fb4SGeorge Rimar if (Tok == "CONSTANT") { 13592e93fb4SGeorge Rimar expect("("); 13692e93fb4SGeorge Rimar uint64_t V = getConstantValue(next()); 13792e93fb4SGeorge Rimar expect(")"); 13892e93fb4SGeorge Rimar return V; 13992e93fb4SGeorge Rimar } 14092e93fb4SGeorge Rimar // Documentations says there are two ways to compute 14192e93fb4SGeorge Rimar // the value of DATA_SEGMENT_ALIGN command, depending on whether the second 14292e93fb4SGeorge Rimar // uses fewer COMMONPAGESIZE sized pages for the data segment(area between the 14392e93fb4SGeorge Rimar // result of this expression and `DATA_SEGMENT_END') than the first or not. 14492e93fb4SGeorge Rimar // That is possible optimization, that we do not support, so we compute that 14592e93fb4SGeorge Rimar // function always as (ALIGN(MAXPAGESIZE) + (. & (MAXPAGESIZE - 1))) now. 14692e93fb4SGeorge Rimar if (Tok == "DATA_SEGMENT_ALIGN") { 14792e93fb4SGeorge Rimar expect("("); 14892e93fb4SGeorge Rimar uint64_t L = parseExpr(); 14992e93fb4SGeorge Rimar expect(","); 15092e93fb4SGeorge Rimar parseExpr(); 15192e93fb4SGeorge Rimar expect(")"); 15292e93fb4SGeorge Rimar return alignTo(Dot, L) + (Dot & (L - 1)); 15392e93fb4SGeorge Rimar } 15492e93fb4SGeorge Rimar // Since we do not support the optimization from comment above, 15592e93fb4SGeorge Rimar // we can just ignore that command. 15692e93fb4SGeorge Rimar if (Tok == "DATA_SEGMENT_END") { 15792e93fb4SGeorge Rimar expect("("); 15892e93fb4SGeorge Rimar expect("."); 15992e93fb4SGeorge Rimar expect(")"); 16092e93fb4SGeorge Rimar return Dot; 16192e93fb4SGeorge Rimar } 1625fa60985SRui Ueyama uint64_t V = 0; 1635fa60985SRui Ueyama if (Tok.getAsInteger(0, V)) 1649c1112d0SRui Ueyama setError("malformed number: " + Tok); 1655fa60985SRui Ueyama return V; 166960504b9SRui Ueyama } 167960504b9SRui Ueyama 1689c1112d0SRui Ueyama uint64_t ExprParser::parseTernary(uint64_t Cond) { 1699c1112d0SRui Ueyama next(); 1709c1112d0SRui Ueyama uint64_t V = parseExpr(); 1719c1112d0SRui Ueyama expect(":"); 1729c1112d0SRui Ueyama uint64_t W = parseExpr(); 173fba45c41SGeorge Rimar return Cond ? V : W; 174fba45c41SGeorge Rimar } 175fba45c41SGeorge Rimar 1769c1112d0SRui Ueyama uint64_t ExprParser::apply(StringRef Op, uint64_t L, uint64_t R) { 177960504b9SRui Ueyama if (Op == "*") 178960504b9SRui Ueyama return L * R; 179960504b9SRui Ueyama if (Op == "/") { 180960504b9SRui Ueyama if (R == 0) { 181960504b9SRui Ueyama error("division by zero"); 182960504b9SRui Ueyama return 0; 183960504b9SRui Ueyama } 184960504b9SRui Ueyama return L / R; 185960504b9SRui Ueyama } 186ab939066SGeorge Rimar if (Op == "+") 187ab939066SGeorge Rimar return L + R; 188ab939066SGeorge Rimar if (Op == "-") 189ab939066SGeorge Rimar return L - R; 190ab939066SGeorge Rimar if (Op == "<") 191ab939066SGeorge Rimar return L < R; 192ab939066SGeorge Rimar if (Op == ">") 193ab939066SGeorge Rimar return L > R; 194ab939066SGeorge Rimar if (Op == ">=") 195ab939066SGeorge Rimar return L >= R; 196ab939066SGeorge Rimar if (Op == "<=") 197ab939066SGeorge Rimar return L <= R; 198ab939066SGeorge Rimar if (Op == "==") 199ab939066SGeorge Rimar return L == R; 200ab939066SGeorge Rimar if (Op == "!=") 201ab939066SGeorge Rimar return L != R; 202960504b9SRui Ueyama if (Op == "&") 203960504b9SRui Ueyama return L & R; 2047a81d674SRui Ueyama llvm_unreachable("invalid operator"); 205652852c5SGeorge Rimar } 206652852c5SGeorge Rimar 2079c1112d0SRui Ueyama // This is a part of the operator-precedence parser. 2089c1112d0SRui Ueyama // This function assumes that the remaining token stream starts 2099c1112d0SRui Ueyama // with an operator. 2109c1112d0SRui Ueyama uint64_t ExprParser::parseExpr1(uint64_t Lhs, int MinPrec) { 2119c1112d0SRui Ueyama while (!atEOF()) { 212960504b9SRui Ueyama // Read an operator and an expression. 2139c1112d0SRui Ueyama StringRef Op1 = peek(); 214fba45c41SGeorge Rimar if (Op1 == "?") 2159c1112d0SRui Ueyama return parseTernary(Lhs); 216960504b9SRui Ueyama if (precedence(Op1) < MinPrec) 217960504b9SRui Ueyama return Lhs; 2189c1112d0SRui Ueyama next(); 2199c1112d0SRui Ueyama uint64_t Rhs = parsePrimary(); 220960504b9SRui Ueyama 221960504b9SRui Ueyama // Evaluate the remaining part of the expression first if the 222960504b9SRui Ueyama // next operator has greater precedence than the previous one. 223960504b9SRui Ueyama // For example, if we have read "+" and "3", and if the next 224960504b9SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 2259c1112d0SRui Ueyama while (!atEOF()) { 2269c1112d0SRui Ueyama StringRef Op2 = peek(); 227960504b9SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 228960504b9SRui Ueyama break; 2299c1112d0SRui Ueyama Rhs = parseExpr1(Rhs, precedence(Op2)); 230652852c5SGeorge Rimar } 231960504b9SRui Ueyama 232960504b9SRui Ueyama Lhs = apply(Op1, Lhs, Rhs); 233960504b9SRui Ueyama } 234960504b9SRui Ueyama return Lhs; 235960504b9SRui Ueyama } 236960504b9SRui Ueyama 2379c1112d0SRui Ueyama // Reads and evaluates an arithmetic expression. 2389c1112d0SRui Ueyama uint64_t ExprParser::parseExpr() { return parseExpr1(parsePrimary(), 0); } 239652852c5SGeorge Rimar 24036a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) { 241eea3114fSGeorge Rimar return !S || !S->Live; 242717677afSRui Ueyama } 243717677afSRui Ueyama 24407320e40SRui Ueyama template <class ELFT> 24507320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 2468ec77e64SRui Ueyama for (StringRef Pat : Opt.KeptSections) 247722830a5SRui Ueyama if (globMatch(Pat, S->getSectionName())) 2488ec77e64SRui Ueyama return true; 2498ec77e64SRui Ueyama return false; 250481c2ce6SGeorge Rimar } 251481c2ce6SGeorge Rimar 252eea3114fSGeorge Rimar static bool match(StringRef Pattern, ArrayRef<StringRef> Arr) { 253eea3114fSGeorge Rimar for (StringRef S : Arr) 254eea3114fSGeorge Rimar if (globMatch(S, Pattern)) 255eea3114fSGeorge Rimar return true; 256eea3114fSGeorge Rimar return false; 257eea3114fSGeorge Rimar } 258eea3114fSGeorge Rimar 259652852c5SGeorge Rimar template <class ELFT> 260a7f7884dSRui Ueyama std::vector<OutputSectionBase<ELFT> *> 261e63d81bdSEugene Leviant LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 262eea3114fSGeorge Rimar typedef const std::unique_ptr<ObjectFile<ELFT>> ObjectFile; 263a7f7884dSRui Ueyama std::vector<OutputSectionBase<ELFT> *> Result; 264*8a9bb7baSRui Ueyama DenseSet<OutputSectionBase<ELFT> *> Removed; 265a7f7884dSRui Ueyama 266e63d81bdSEugene Leviant // Add input section to output section. If there is no output section yet, 267e63d81bdSEugene Leviant // then create it and add to output section list. 268*8a9bb7baSRui Ueyama auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name, 269*8a9bb7baSRui Ueyama ConstraintKind Constraint) { 270e63d81bdSEugene Leviant OutputSectionBase<ELFT> *Sec; 271e63d81bdSEugene Leviant bool IsNew; 272e63d81bdSEugene Leviant std::tie(Sec, IsNew) = Factory.create(C, Name); 273e63d81bdSEugene Leviant if (IsNew) 274a7f7884dSRui Ueyama Result.push_back(Sec); 275*8a9bb7baSRui Ueyama if ((!(C->getSectionHdr()->sh_flags & SHF_WRITE)) && 276*8a9bb7baSRui Ueyama Constraint == ReadWrite) { 277*8a9bb7baSRui Ueyama Removed.insert(Sec); 278*8a9bb7baSRui Ueyama return; 279*8a9bb7baSRui Ueyama } 280*8a9bb7baSRui Ueyama if ((C->getSectionHdr()->sh_flags & SHF_WRITE) && Constraint == ReadOnly) { 281*8a9bb7baSRui Ueyama Removed.insert(Sec); 282*8a9bb7baSRui Ueyama return; 283*8a9bb7baSRui Ueyama } 284e63d81bdSEugene Leviant Sec->addSection(C); 285e63d81bdSEugene Leviant }; 286e63d81bdSEugene Leviant 287e63d81bdSEugene Leviant // Select input sections matching rule and add them to corresponding 288e63d81bdSEugene Leviant // output section. Section rules are processed in order they're listed 289e63d81bdSEugene Leviant // in script, so correct input section order is maintained by design. 290eea3114fSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 291eea3114fSGeorge Rimar auto *OutCmd = dyn_cast<OutputSectionCommand>(Base.get()); 292eea3114fSGeorge Rimar if (!OutCmd) 293eea3114fSGeorge Rimar continue; 294eea3114fSGeorge Rimar 295eea3114fSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Cmd : OutCmd->Commands) { 296eea3114fSGeorge Rimar auto *InCmd = dyn_cast<InputSectionDescription>(Cmd.get()); 297eea3114fSGeorge Rimar if (!InCmd) 298eea3114fSGeorge Rimar continue; 299eea3114fSGeorge Rimar 300eea3114fSGeorge Rimar for (ObjectFile &F : Symtab<ELFT>::X->getObjectFiles()) { 301eea3114fSGeorge Rimar for (InputSectionBase<ELFT> *S : F->getSections()) { 302eea3114fSGeorge Rimar if (isDiscarded(S) || S->OutSec) 303eea3114fSGeorge Rimar continue; 304eea3114fSGeorge Rimar 305eea3114fSGeorge Rimar if (match(S->getSectionName(), InCmd->Patterns)) { 306eea3114fSGeorge Rimar if (OutCmd->Name == "/DISCARD/") 307eea3114fSGeorge Rimar S->Live = false; 308eea3114fSGeorge Rimar else 309*8a9bb7baSRui Ueyama AddInputSec(S, OutCmd->Name, OutCmd->Constraint); 310eea3114fSGeorge Rimar } 311eea3114fSGeorge Rimar } 312eea3114fSGeorge Rimar } 313eea3114fSGeorge Rimar } 314eea3114fSGeorge Rimar } 315e63d81bdSEugene Leviant 316e63d81bdSEugene Leviant // Add all other input sections, which are not listed in script. 317eea3114fSGeorge Rimar for (ObjectFile &F : Symtab<ELFT>::X->getObjectFiles()) 3183c944ec8SReid Kleckner for (InputSectionBase<ELFT> *S : F->getSections()) { 319e63d81bdSEugene Leviant if (!isDiscarded(S)) { 320e63d81bdSEugene Leviant if (!S->OutSec) 321*8a9bb7baSRui Ueyama AddInputSec(S, getOutputSectionName(S), NoConstraint); 322e63d81bdSEugene Leviant } else 323e63d81bdSEugene Leviant reportDiscarded(S, F); 3243c944ec8SReid Kleckner } 325e63d81bdSEugene Leviant 326*8a9bb7baSRui Ueyama // Remove from the output all the sections which did not met the constraints. 327*8a9bb7baSRui Ueyama Result.erase(std::remove_if(Result.begin(), Result.end(), 328*8a9bb7baSRui Ueyama [&](OutputSectionBase<ELFT> *Sec) { 329*8a9bb7baSRui Ueyama return Removed.count(Sec); 330*8a9bb7baSRui Ueyama }), 331*8a9bb7baSRui Ueyama Result.end()); 332*8a9bb7baSRui Ueyama return Result; 333e63d81bdSEugene Leviant } 334e63d81bdSEugene Leviant 335e63d81bdSEugene Leviant template <class ELFT> 33610e576e1SGeorge Rimar void LinkerScript<ELFT>::dispatchAssignment(SymbolAssignment *Cmd) { 33710e576e1SGeorge Rimar uint64_t Val = evalExpr(Cmd->Expr, Dot); 33810e576e1SGeorge Rimar if (Cmd->Name == ".") { 33910e576e1SGeorge Rimar Dot = Val; 340a31c91b1SEugene Leviant } else if (!Cmd->Ignore) { 34110e576e1SGeorge Rimar auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd->Name)); 34210e576e1SGeorge Rimar D->Value = Val; 34310e576e1SGeorge Rimar } 34410e576e1SGeorge Rimar } 34510e576e1SGeorge Rimar 34610e576e1SGeorge Rimar template <class ELFT> 34707320e40SRui Ueyama void LinkerScript<ELFT>::assignAddresses( 348dbbd8b15SGeorge Rimar ArrayRef<OutputSectionBase<ELFT> *> Sections) { 349652852c5SGeorge Rimar // Orphan sections are sections present in the input files which 3507c18c28cSRui Ueyama // are not explicitly placed into the output file by the linker script. 3517c18c28cSRui Ueyama // We place orphan sections at end of file. 3527c18c28cSRui Ueyama // Other linkers places them using some heuristics as described in 353652852c5SGeorge Rimar // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 3547c18c28cSRui Ueyama for (OutputSectionBase<ELFT> *Sec : Sections) { 355652852c5SGeorge Rimar StringRef Name = Sec->getName(); 356c3e2a4b0SRui Ueyama if (getSectionIndex(Name) == INT_MAX) 357076fe157SGeorge Rimar Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name)); 358652852c5SGeorge Rimar } 359652852c5SGeorge Rimar 3607c18c28cSRui Ueyama // Assign addresses as instructed by linker script SECTIONS sub-commands. 361c998a8c0SRui Ueyama Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 362467c4d55SEugene Leviant uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 363652852c5SGeorge Rimar uintX_t ThreadBssOffset = 0; 364652852c5SGeorge Rimar 365076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 366076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { 36710e576e1SGeorge Rimar dispatchAssignment(Cmd); 36805ef4cffSRui Ueyama continue; 369652852c5SGeorge Rimar } 370652852c5SGeorge Rimar 371fb8978fcSDima Stepanov // Find all the sections with required name. There can be more than 3726ad330acSGeorge Rimar // one section with such name, if the alignment, flags or type 373fb8978fcSDima Stepanov // attribute differs. 374076fe157SGeorge Rimar auto *Cmd = cast<OutputSectionCommand>(Base.get()); 375fb8978fcSDima Stepanov for (OutputSectionBase<ELFT> *Sec : Sections) { 376076fe157SGeorge Rimar if (Sec->getName() != Cmd->Name) 377652852c5SGeorge Rimar continue; 378652852c5SGeorge Rimar 379652852c5SGeorge Rimar if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { 380c998a8c0SRui Ueyama uintX_t TVA = Dot + ThreadBssOffset; 381424b4081SRui Ueyama TVA = alignTo(TVA, Sec->getAlignment()); 382652852c5SGeorge Rimar Sec->setVA(TVA); 383c998a8c0SRui Ueyama ThreadBssOffset = TVA - Dot + Sec->getSize(); 384652852c5SGeorge Rimar continue; 385652852c5SGeorge Rimar } 386652852c5SGeorge Rimar 387652852c5SGeorge Rimar if (Sec->getFlags() & SHF_ALLOC) { 388424b4081SRui Ueyama Dot = alignTo(Dot, Sec->getAlignment()); 389c998a8c0SRui Ueyama Sec->setVA(Dot); 390467c4d55SEugene Leviant MinVA = std::min(MinVA, Dot); 391c998a8c0SRui Ueyama Dot += Sec->getSize(); 392652852c5SGeorge Rimar continue; 393652852c5SGeorge Rimar } 394652852c5SGeorge Rimar } 395652852c5SGeorge Rimar } 396467c4d55SEugene Leviant 39764c32d6fSRafael Espindola // ELF and Program headers need to be right before the first section in 398b91e7118SGeorge Rimar // memory. Set their addresses accordingly. 399467c4d55SEugene Leviant MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() - 400467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->getSize(), 401467c4d55SEugene Leviant Target->PageSize); 402467c4d55SEugene Leviant Out<ELFT>::ElfHeader->setVA(MinVA); 403467c4d55SEugene Leviant Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 404fb8978fcSDima Stepanov } 405652852c5SGeorge Rimar 40607320e40SRui Ueyama template <class ELFT> 40774df5c7eSRafael Espindola std::vector<PhdrEntry<ELFT>> 408bbe38602SEugene Leviant LinkerScript<ELFT>::createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> Sections) { 409bbe38602SEugene Leviant int TlsNum = -1; 410bbe38602SEugene Leviant int NoteNum = -1; 411bbe38602SEugene Leviant int RelroNum = -1; 412adca245fSRui Ueyama PhdrEntry<ELFT> *Load = nullptr; 413bbe38602SEugene Leviant uintX_t Flags = PF_R; 414adca245fSRui Ueyama std::vector<PhdrEntry<ELFT>> Phdrs; 415bbe38602SEugene Leviant 416bbe38602SEugene Leviant for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 417865bf863SEugene Leviant Phdrs.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); 418adca245fSRui Ueyama PhdrEntry<ELFT> &Phdr = Phdrs.back(); 419bbe38602SEugene Leviant 420bbe38602SEugene Leviant if (Cmd.HasFilehdr) 421adca245fSRui Ueyama Phdr.add(Out<ELFT>::ElfHeader); 422bbe38602SEugene Leviant if (Cmd.HasPhdrs) 423adca245fSRui Ueyama Phdr.add(Out<ELFT>::ProgramHeaders); 424bbe38602SEugene Leviant 425bbe38602SEugene Leviant switch (Cmd.Type) { 426bbe38602SEugene Leviant case PT_INTERP: 427fd03cfd2SRui Ueyama if (Out<ELFT>::Interp) 428adca245fSRui Ueyama Phdr.add(Out<ELFT>::Interp); 429bbe38602SEugene Leviant break; 430bbe38602SEugene Leviant case PT_DYNAMIC: 431bbe38602SEugene Leviant if (isOutputDynamic<ELFT>()) { 432adca245fSRui Ueyama Phdr.H.p_flags = toPhdrFlags(Out<ELFT>::Dynamic->getFlags()); 433adca245fSRui Ueyama Phdr.add(Out<ELFT>::Dynamic); 434bbe38602SEugene Leviant } 435bbe38602SEugene Leviant break; 436bbe38602SEugene Leviant case PT_TLS: 437bbe38602SEugene Leviant TlsNum = Phdrs.size() - 1; 438bbe38602SEugene Leviant break; 439bbe38602SEugene Leviant case PT_NOTE: 440bbe38602SEugene Leviant NoteNum = Phdrs.size() - 1; 441bbe38602SEugene Leviant break; 442bbe38602SEugene Leviant case PT_GNU_RELRO: 443bbe38602SEugene Leviant RelroNum = Phdrs.size() - 1; 444bbe38602SEugene Leviant break; 445bbe38602SEugene Leviant case PT_GNU_EH_FRAME: 446bbe38602SEugene Leviant if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) { 447adca245fSRui Ueyama Phdr.H.p_flags = toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags()); 448adca245fSRui Ueyama Phdr.add(Out<ELFT>::EhFrameHdr); 449bbe38602SEugene Leviant } 450bbe38602SEugene Leviant break; 451bbe38602SEugene Leviant } 452bbe38602SEugene Leviant } 453bbe38602SEugene Leviant 454bbe38602SEugene Leviant for (OutputSectionBase<ELFT> *Sec : Sections) { 455bbe38602SEugene Leviant if (!(Sec->getFlags() & SHF_ALLOC)) 456bbe38602SEugene Leviant break; 457bbe38602SEugene Leviant 458bbe38602SEugene Leviant if (TlsNum != -1 && (Sec->getFlags() & SHF_TLS)) 45918f084ffSRui Ueyama Phdrs[TlsNum].add(Sec); 460bbe38602SEugene Leviant 461bbe38602SEugene Leviant if (!needsPtLoad<ELFT>(Sec)) 462bbe38602SEugene Leviant continue; 463bbe38602SEugene Leviant 464bbe38602SEugene Leviant const std::vector<size_t> &PhdrIds = 465bbe38602SEugene Leviant getPhdrIndicesForSection(Sec->getName()); 466bbe38602SEugene Leviant if (!PhdrIds.empty()) { 467bbe38602SEugene Leviant // Assign headers specified by linker script 468bbe38602SEugene Leviant for (size_t Id : PhdrIds) { 46918f084ffSRui Ueyama Phdrs[Id].add(Sec); 470865bf863SEugene Leviant if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) 471865bf863SEugene Leviant Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags()); 472bbe38602SEugene Leviant } 473bbe38602SEugene Leviant } else { 474bbe38602SEugene Leviant // If we have no load segment or flags've changed then we want new load 475bbe38602SEugene Leviant // segment. 476bbe38602SEugene Leviant uintX_t NewFlags = toPhdrFlags(Sec->getFlags()); 477bbe38602SEugene Leviant if (Load == nullptr || Flags != NewFlags) { 478bbe38602SEugene Leviant Load = &*Phdrs.emplace(Phdrs.end(), PT_LOAD, NewFlags); 479bbe38602SEugene Leviant Flags = NewFlags; 480bbe38602SEugene Leviant } 48118f084ffSRui Ueyama Load->add(Sec); 482bbe38602SEugene Leviant } 483bbe38602SEugene Leviant 484bbe38602SEugene Leviant if (RelroNum != -1 && isRelroSection(Sec)) 48518f084ffSRui Ueyama Phdrs[RelroNum].add(Sec); 486bbe38602SEugene Leviant if (NoteNum != -1 && Sec->getType() == SHT_NOTE) 48718f084ffSRui Ueyama Phdrs[NoteNum].add(Sec); 488bbe38602SEugene Leviant } 489bbe38602SEugene Leviant return Phdrs; 490bbe38602SEugene Leviant } 491bbe38602SEugene Leviant 492bbe38602SEugene Leviant template <class ELFT> 49307320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 494f6c3ccefSGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) 495f6c3ccefSGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 496f6c3ccefSGeorge Rimar if (Cmd->Name == Name) 497f6c3ccefSGeorge Rimar return Cmd->Filler; 498e2ee72b5SGeorge Rimar return {}; 499e2ee72b5SGeorge Rimar } 500e2ee72b5SGeorge Rimar 501c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script 502c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they 503c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script, 504c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file. 505076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 50671b26e94SGeorge Rimar auto Begin = Opt.Commands.begin(); 50771b26e94SGeorge Rimar auto End = Opt.Commands.end(); 508076fe157SGeorge Rimar auto I = 509076fe157SGeorge Rimar std::find_if(Begin, End, [&](const std::unique_ptr<BaseCommand> &Base) { 510076fe157SGeorge Rimar if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get())) 511076fe157SGeorge Rimar if (Cmd->Name == Name) 512076fe157SGeorge Rimar return true; 513076fe157SGeorge Rimar return false; 51471b26e94SGeorge Rimar }); 515c3e2a4b0SRui Ueyama return I == End ? INT_MAX : (I - Begin); 51671b26e94SGeorge Rimar } 51771b26e94SGeorge Rimar 51871b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if 51971b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0. 52007320e40SRui Ueyama template <class ELFT> 52107320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 522c3e2a4b0SRui Ueyama int I = getSectionIndex(A); 523c3e2a4b0SRui Ueyama int J = getSectionIndex(B); 524c3e2a4b0SRui Ueyama if (I == INT_MAX && J == INT_MAX) 525717677afSRui Ueyama return 0; 526717677afSRui Ueyama return I < J ? -1 : 1; 527717677afSRui Ueyama } 528717677afSRui Ueyama 529076fe157SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::addScriptedSymbols() { 530a31c91b1SEugene Leviant for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 531a31c91b1SEugene Leviant auto *Cmd = dyn_cast<SymbolAssignment>(Base.get()); 532a31c91b1SEugene Leviant if (!Cmd || Cmd->Name == ".") 533a31c91b1SEugene Leviant continue; 534a31c91b1SEugene Leviant 5358ab4108dSDavide Italiano SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name); 5368ab4108dSDavide Italiano if (!B || B->isUndefined()) 537a31c91b1SEugene Leviant Symtab<ELFT>::X->addAbsolute(Cmd->Name, 538a31c91b1SEugene Leviant Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT); 539a31c91b1SEugene Leviant else 540a31c91b1SEugene Leviant // Symbol already exists in symbol table. If it is provided 541a31c91b1SEugene Leviant // then we can't override its value. 542a31c91b1SEugene Leviant Cmd->Ignore = Cmd->Provide; 543a31c91b1SEugene Leviant } 544eda81a1bSEugene Leviant } 545eda81a1bSEugene Leviant 546bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 547bbe38602SEugene Leviant return !Opt.PhdrsCommands.empty(); 548bbe38602SEugene Leviant } 549bbe38602SEugene Leviant 550bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified 551bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within 552bbe38602SEugene Leviant // PHDRS {} script block. 553bbe38602SEugene Leviant template <class ELFT> 554bbe38602SEugene Leviant std::vector<size_t> 555bbe38602SEugene Leviant LinkerScript<ELFT>::getPhdrIndicesForSection(StringRef Name) { 556076fe157SGeorge Rimar for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { 557076fe157SGeorge Rimar auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()); 558076fe157SGeorge Rimar if (!Cmd || Cmd->Name != Name) 55931d842f5SGeorge Rimar continue; 56031d842f5SGeorge Rimar 561bbe38602SEugene Leviant std::vector<size_t> Indices; 562076fe157SGeorge Rimar for (StringRef PhdrName : Cmd->Phdrs) { 56331d842f5SGeorge Rimar auto ItPhdr = 56431d842f5SGeorge Rimar std::find_if(Opt.PhdrsCommands.rbegin(), Opt.PhdrsCommands.rend(), 565076fe157SGeorge Rimar [&](PhdrsCommand &P) { return P.Name == PhdrName; }); 566bbe38602SEugene Leviant if (ItPhdr == Opt.PhdrsCommands.rend()) 567bbe38602SEugene Leviant error("section header '" + PhdrName + "' is not listed in PHDRS"); 568bbe38602SEugene Leviant else 569bbe38602SEugene Leviant Indices.push_back(std::distance(ItPhdr, Opt.PhdrsCommands.rend()) - 1); 570bbe38602SEugene Leviant } 571bbe38602SEugene Leviant return Indices; 572bbe38602SEugene Leviant } 57331d842f5SGeorge Rimar return {}; 57431d842f5SGeorge Rimar } 575bbe38602SEugene Leviant 57607320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase { 577c3794e58SGeorge Rimar typedef void (ScriptParser::*Handler)(); 578c3794e58SGeorge Rimar 579f7c5fbb1SRui Ueyama public: 58007320e40SRui Ueyama ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 581f23b2320SGeorge Rimar 5824a46539cSRui Ueyama void run(); 583f7c5fbb1SRui Ueyama 584f7c5fbb1SRui Ueyama private: 58552a1509eSRui Ueyama void addFile(StringRef Path); 58652a1509eSRui Ueyama 587f7c5fbb1SRui Ueyama void readAsNeeded(); 58890c5099eSDenis Protivensky void readEntry(); 58983f406cfSGeorge Rimar void readExtern(); 590f7c5fbb1SRui Ueyama void readGroup(); 59131aa1f83SRui Ueyama void readInclude(); 592c3794e58SGeorge Rimar void readNothing() {} 593ee59282bSRui Ueyama void readOutput(); 5949159ce93SDavide Italiano void readOutputArch(); 595f7c5fbb1SRui Ueyama void readOutputFormat(); 596bbe38602SEugene Leviant void readPhdrs(); 59768a39a65SDavide Italiano void readSearchDir(); 5988e3b38abSDenis Protivensky void readSections(); 5998e3b38abSDenis Protivensky 600652852c5SGeorge Rimar void readLocationCounterValue(); 601eda81a1bSEugene Leviant void readOutputSectionDescription(StringRef OutSec); 602bbe38602SEugene Leviant std::vector<StringRef> readOutputSectionPhdrs(); 603bbe38602SEugene Leviant unsigned readPhdrType(); 604a31c91b1SEugene Leviant void readProvide(bool Hidden); 605a31c91b1SEugene Leviant SymbolAssignment *readSymbolAssignment(StringRef Name); 606eda81a1bSEugene Leviant std::vector<StringRef> readSectionsCommandExpr(); 607f7c5fbb1SRui Ueyama 608c3794e58SGeorge Rimar const static StringMap<Handler> Cmd; 60907320e40SRui Ueyama ScriptConfiguration &Opt = *ScriptConfig; 61007320e40SRui Ueyama StringSaver Saver = {ScriptConfig->Alloc}; 61116b0cc9eSSimon Atanasyan bool IsUnderSysroot; 612f7c5fbb1SRui Ueyama }; 613f7c5fbb1SRui Ueyama 614e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = { 615c3794e58SGeorge Rimar {"ENTRY", &ScriptParser::readEntry}, 616c3794e58SGeorge Rimar {"EXTERN", &ScriptParser::readExtern}, 617c3794e58SGeorge Rimar {"GROUP", &ScriptParser::readGroup}, 618c3794e58SGeorge Rimar {"INCLUDE", &ScriptParser::readInclude}, 619c3794e58SGeorge Rimar {"INPUT", &ScriptParser::readGroup}, 620c3794e58SGeorge Rimar {"OUTPUT", &ScriptParser::readOutput}, 621c3794e58SGeorge Rimar {"OUTPUT_ARCH", &ScriptParser::readOutputArch}, 622c3794e58SGeorge Rimar {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat}, 623bbe38602SEugene Leviant {"PHDRS", &ScriptParser::readPhdrs}, 624c3794e58SGeorge Rimar {"SEARCH_DIR", &ScriptParser::readSearchDir}, 625c3794e58SGeorge Rimar {"SECTIONS", &ScriptParser::readSections}, 626c3794e58SGeorge Rimar {";", &ScriptParser::readNothing}}; 627c3794e58SGeorge Rimar 628717677afSRui Ueyama void ScriptParser::run() { 629f7c5fbb1SRui Ueyama while (!atEOF()) { 630f7c5fbb1SRui Ueyama StringRef Tok = next(); 631c3794e58SGeorge Rimar if (Handler Fn = Cmd.lookup(Tok)) 632c3794e58SGeorge Rimar (this->*Fn)(); 633c3794e58SGeorge Rimar else 6345761042dSGeorge Rimar setError("unknown directive: " + Tok); 635f7c5fbb1SRui Ueyama } 636f7c5fbb1SRui Ueyama } 637f7c5fbb1SRui Ueyama 638717677afSRui Ueyama void ScriptParser::addFile(StringRef S) { 63916b0cc9eSSimon Atanasyan if (IsUnderSysroot && S.startswith("/")) { 64016b0cc9eSSimon Atanasyan SmallString<128> Path; 64116b0cc9eSSimon Atanasyan (Config->Sysroot + S).toStringRef(Path); 64216b0cc9eSSimon Atanasyan if (sys::fs::exists(Path)) { 64316b0cc9eSSimon Atanasyan Driver->addFile(Saver.save(Path.str())); 64416b0cc9eSSimon Atanasyan return; 64516b0cc9eSSimon Atanasyan } 64616b0cc9eSSimon Atanasyan } 64716b0cc9eSSimon Atanasyan 648f03f3cc1SRui Ueyama if (sys::path::is_absolute(S)) { 64952a1509eSRui Ueyama Driver->addFile(S); 65052a1509eSRui Ueyama } else if (S.startswith("=")) { 65152a1509eSRui Ueyama if (Config->Sysroot.empty()) 65252a1509eSRui Ueyama Driver->addFile(S.substr(1)); 65352a1509eSRui Ueyama else 65452a1509eSRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 65552a1509eSRui Ueyama } else if (S.startswith("-l")) { 65621eecb4fSRui Ueyama Driver->addLibrary(S.substr(2)); 657a1b8fc3bSSimon Atanasyan } else if (sys::fs::exists(S)) { 658a1b8fc3bSSimon Atanasyan Driver->addFile(S); 65952a1509eSRui Ueyama } else { 66052a1509eSRui Ueyama std::string Path = findFromSearchPaths(S); 66152a1509eSRui Ueyama if (Path.empty()) 662777f9630SGeorge Rimar setError("unable to find " + S); 663025d59b1SRui Ueyama else 66452a1509eSRui Ueyama Driver->addFile(Saver.save(Path)); 66552a1509eSRui Ueyama } 66652a1509eSRui Ueyama } 66752a1509eSRui Ueyama 668717677afSRui Ueyama void ScriptParser::readAsNeeded() { 669f7c5fbb1SRui Ueyama expect("("); 67035da9b6eSRui Ueyama bool Orig = Config->AsNeeded; 67135da9b6eSRui Ueyama Config->AsNeeded = true; 672025d59b1SRui Ueyama while (!Error) { 673f7c5fbb1SRui Ueyama StringRef Tok = next(); 674f7c5fbb1SRui Ueyama if (Tok == ")") 67535da9b6eSRui Ueyama break; 67652a1509eSRui Ueyama addFile(Tok); 677f7c5fbb1SRui Ueyama } 67835da9b6eSRui Ueyama Config->AsNeeded = Orig; 679f7c5fbb1SRui Ueyama } 680f7c5fbb1SRui Ueyama 681717677afSRui Ueyama void ScriptParser::readEntry() { 68290c5099eSDenis Protivensky // -e <symbol> takes predecence over ENTRY(<symbol>). 68390c5099eSDenis Protivensky expect("("); 68490c5099eSDenis Protivensky StringRef Tok = next(); 68590c5099eSDenis Protivensky if (Config->Entry.empty()) 68690c5099eSDenis Protivensky Config->Entry = Tok; 68790c5099eSDenis Protivensky expect(")"); 68890c5099eSDenis Protivensky } 68990c5099eSDenis Protivensky 690717677afSRui Ueyama void ScriptParser::readExtern() { 69183f406cfSGeorge Rimar expect("("); 692025d59b1SRui Ueyama while (!Error) { 69383f406cfSGeorge Rimar StringRef Tok = next(); 69483f406cfSGeorge Rimar if (Tok == ")") 69583f406cfSGeorge Rimar return; 69683f406cfSGeorge Rimar Config->Undefined.push_back(Tok); 69783f406cfSGeorge Rimar } 69883f406cfSGeorge Rimar } 69983f406cfSGeorge Rimar 700717677afSRui Ueyama void ScriptParser::readGroup() { 701f7c5fbb1SRui Ueyama expect("("); 702025d59b1SRui Ueyama while (!Error) { 703f7c5fbb1SRui Ueyama StringRef Tok = next(); 704f7c5fbb1SRui Ueyama if (Tok == ")") 705f7c5fbb1SRui Ueyama return; 706f7c5fbb1SRui Ueyama if (Tok == "AS_NEEDED") { 707f7c5fbb1SRui Ueyama readAsNeeded(); 708f7c5fbb1SRui Ueyama continue; 709f7c5fbb1SRui Ueyama } 71052a1509eSRui Ueyama addFile(Tok); 711f7c5fbb1SRui Ueyama } 712f7c5fbb1SRui Ueyama } 713f7c5fbb1SRui Ueyama 714717677afSRui Ueyama void ScriptParser::readInclude() { 71531aa1f83SRui Ueyama StringRef Tok = next(); 71631aa1f83SRui Ueyama auto MBOrErr = MemoryBuffer::getFile(Tok); 717025d59b1SRui Ueyama if (!MBOrErr) { 7185761042dSGeorge Rimar setError("cannot open " + Tok); 719025d59b1SRui Ueyama return; 720025d59b1SRui Ueyama } 72131aa1f83SRui Ueyama std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 722a47ee68dSRui Ueyama StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 723a47ee68dSRui Ueyama std::vector<StringRef> V = tokenize(S); 72431aa1f83SRui Ueyama Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 72531aa1f83SRui Ueyama } 72631aa1f83SRui Ueyama 727717677afSRui Ueyama void ScriptParser::readOutput() { 728ee59282bSRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 729ee59282bSRui Ueyama expect("("); 730ee59282bSRui Ueyama StringRef Tok = next(); 731ee59282bSRui Ueyama if (Config->OutputFile.empty()) 732ee59282bSRui Ueyama Config->OutputFile = Tok; 733ee59282bSRui Ueyama expect(")"); 734ee59282bSRui Ueyama } 735ee59282bSRui Ueyama 736717677afSRui Ueyama void ScriptParser::readOutputArch() { 7379159ce93SDavide Italiano // Error checking only for now. 7389159ce93SDavide Italiano expect("("); 7399159ce93SDavide Italiano next(); 7409159ce93SDavide Italiano expect(")"); 7419159ce93SDavide Italiano } 7429159ce93SDavide Italiano 743717677afSRui Ueyama void ScriptParser::readOutputFormat() { 744f7c5fbb1SRui Ueyama // Error checking only for now. 745f7c5fbb1SRui Ueyama expect("("); 746f7c5fbb1SRui Ueyama next(); 7476836c618SDavide Italiano StringRef Tok = next(); 7486836c618SDavide Italiano if (Tok == ")") 7496836c618SDavide Italiano return; 750025d59b1SRui Ueyama if (Tok != ",") { 7515761042dSGeorge Rimar setError("unexpected token: " + Tok); 752025d59b1SRui Ueyama return; 753025d59b1SRui Ueyama } 7546836c618SDavide Italiano next(); 7556836c618SDavide Italiano expect(","); 7566836c618SDavide Italiano next(); 757f7c5fbb1SRui Ueyama expect(")"); 758f7c5fbb1SRui Ueyama } 759f7c5fbb1SRui Ueyama 760bbe38602SEugene Leviant void ScriptParser::readPhdrs() { 761bbe38602SEugene Leviant expect("{"); 762bbe38602SEugene Leviant while (!Error && !skip("}")) { 763bbe38602SEugene Leviant StringRef Tok = next(); 764865bf863SEugene Leviant Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX}); 765bbe38602SEugene Leviant PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 766bbe38602SEugene Leviant 767bbe38602SEugene Leviant PhdrCmd.Type = readPhdrType(); 768bbe38602SEugene Leviant do { 769bbe38602SEugene Leviant Tok = next(); 770bbe38602SEugene Leviant if (Tok == ";") 771bbe38602SEugene Leviant break; 772bbe38602SEugene Leviant if (Tok == "FILEHDR") 773bbe38602SEugene Leviant PhdrCmd.HasFilehdr = true; 774bbe38602SEugene Leviant else if (Tok == "PHDRS") 775bbe38602SEugene Leviant PhdrCmd.HasPhdrs = true; 776865bf863SEugene Leviant else if (Tok == "FLAGS") { 777865bf863SEugene Leviant expect("("); 778865bf863SEugene Leviant next().getAsInteger(0, PhdrCmd.Flags); 779865bf863SEugene Leviant expect(")"); 780865bf863SEugene Leviant } else 781bbe38602SEugene Leviant setError("unexpected header attribute: " + Tok); 782bbe38602SEugene Leviant } while (!Error); 783bbe38602SEugene Leviant } 784bbe38602SEugene Leviant } 785bbe38602SEugene Leviant 786717677afSRui Ueyama void ScriptParser::readSearchDir() { 78768a39a65SDavide Italiano expect("("); 78806501920SRafael Espindola Config->SearchPaths.push_back(next()); 78968a39a65SDavide Italiano expect(")"); 79068a39a65SDavide Italiano } 79168a39a65SDavide Italiano 792717677afSRui Ueyama void ScriptParser::readSections() { 79307320e40SRui Ueyama Opt.DoLayout = true; 7948e3b38abSDenis Protivensky expect("{"); 795652852c5SGeorge Rimar while (!Error && !skip("}")) { 796652852c5SGeorge Rimar StringRef Tok = peek(); 797eda81a1bSEugene Leviant if (Tok == ".") { 798652852c5SGeorge Rimar readLocationCounterValue(); 799eda81a1bSEugene Leviant continue; 800eda81a1bSEugene Leviant } 801eda81a1bSEugene Leviant next(); 802a31c91b1SEugene Leviant if (Tok == "PROVIDE") 803a31c91b1SEugene Leviant readProvide(false); 804a31c91b1SEugene Leviant else if (Tok == "PROVIDE_HIDDEN") 805a31c91b1SEugene Leviant readProvide(true); 806a31c91b1SEugene Leviant else if (peek() == "=") 807eda81a1bSEugene Leviant readSymbolAssignment(Tok); 808652852c5SGeorge Rimar else 809eda81a1bSEugene Leviant readOutputSectionDescription(Tok); 8108e3b38abSDenis Protivensky } 811652852c5SGeorge Rimar } 8128e3b38abSDenis Protivensky 813652852c5SGeorge Rimar void ScriptParser::readLocationCounterValue() { 814652852c5SGeorge Rimar expect("."); 815652852c5SGeorge Rimar expect("="); 816eda81a1bSEugene Leviant std::vector<StringRef> Expr = readSectionsCommandExpr(); 817eda81a1bSEugene Leviant if (Expr.empty()) 818652852c5SGeorge Rimar error("error in location counter expression"); 819eda81a1bSEugene Leviant else 820076fe157SGeorge Rimar Opt.Commands.push_back(llvm::make_unique<SymbolAssignment>(".", Expr)); 821652852c5SGeorge Rimar } 822652852c5SGeorge Rimar 823eda81a1bSEugene Leviant void ScriptParser::readOutputSectionDescription(StringRef OutSec) { 824076fe157SGeorge Rimar OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); 825076fe157SGeorge Rimar Opt.Commands.emplace_back(Cmd); 8268e3b38abSDenis Protivensky expect(":"); 827246f681eSDavide Italiano 828246f681eSDavide Italiano // Parse constraints. 829246f681eSDavide Italiano if (skip("ONLY_IF_RO")) 830246f681eSDavide Italiano Cmd->Constraint = ReadOnly; 831246f681eSDavide Italiano if (skip("ONLY_IF_RW")) 832246f681eSDavide Italiano Cmd->Constraint = ReadWrite; 8338e3b38abSDenis Protivensky expect("{"); 8348ec77e64SRui Ueyama 835025d59b1SRui Ueyama while (!Error && !skip("}")) { 836481c2ce6SGeorge Rimar StringRef Tok = next(); 837481c2ce6SGeorge Rimar if (Tok == "*") { 838eea3114fSGeorge Rimar auto *InCmd = new InputSectionDescription(); 839eea3114fSGeorge Rimar Cmd->Commands.emplace_back(InCmd); 8408ec77e64SRui Ueyama expect("("); 8418ec77e64SRui Ueyama while (!Error && !skip(")")) 842eea3114fSGeorge Rimar InCmd->Patterns.push_back(next()); 843481c2ce6SGeorge Rimar } else if (Tok == "KEEP") { 8448e3b38abSDenis Protivensky expect("("); 8458ec77e64SRui Ueyama expect("*"); 8468ec77e64SRui Ueyama expect("("); 847eea3114fSGeorge Rimar auto *InCmd = new InputSectionDescription(); 848eea3114fSGeorge Rimar Cmd->Commands.emplace_back(InCmd); 8498ec77e64SRui Ueyama while (!Error && !skip(")")) { 850eea3114fSGeorge Rimar Opt.KeptSections.push_back(peek()); 851eea3114fSGeorge Rimar InCmd->Patterns.push_back(next()); 8528ec77e64SRui Ueyama } 853481c2ce6SGeorge Rimar expect(")"); 854481c2ce6SGeorge Rimar } else { 855777f9630SGeorge Rimar setError("unknown command " + Tok); 856481c2ce6SGeorge Rimar } 8578e3b38abSDenis Protivensky } 858076fe157SGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 8598ec77e64SRui Ueyama 860e2ee72b5SGeorge Rimar StringRef Tok = peek(); 861e2ee72b5SGeorge Rimar if (Tok.startswith("=")) { 862e2ee72b5SGeorge Rimar if (!Tok.startswith("=0x")) { 8633ed2f069SRui Ueyama setError("filler should be a hexadecimal value"); 864e2ee72b5SGeorge Rimar return; 865e2ee72b5SGeorge Rimar } 8663e808976SRui Ueyama Tok = Tok.substr(3); 867f6c3ccefSGeorge Rimar Cmd->Filler = parseHex(Tok); 868e2ee72b5SGeorge Rimar next(); 869e2ee72b5SGeorge Rimar } 8708e3b38abSDenis Protivensky } 8718e3b38abSDenis Protivensky 872a31c91b1SEugene Leviant void ScriptParser::readProvide(bool Hidden) { 873a31c91b1SEugene Leviant expect("("); 874a31c91b1SEugene Leviant if (SymbolAssignment *Assignment = readSymbolAssignment(next())) { 875a31c91b1SEugene Leviant Assignment->Provide = true; 876a31c91b1SEugene Leviant Assignment->Hidden = Hidden; 877a31c91b1SEugene Leviant } 878a31c91b1SEugene Leviant expect(")"); 879a31c91b1SEugene Leviant expect(";"); 880eda81a1bSEugene Leviant } 881eda81a1bSEugene Leviant 882a31c91b1SEugene Leviant SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) { 883a31c91b1SEugene Leviant expect("="); 884a31c91b1SEugene Leviant std::vector<StringRef> Expr = readSectionsCommandExpr(); 885a31c91b1SEugene Leviant if (Expr.empty()) { 886a31c91b1SEugene Leviant error("error in symbol assignment expression"); 887a31c91b1SEugene Leviant } else { 888a31c91b1SEugene Leviant Opt.Commands.push_back(llvm::make_unique<SymbolAssignment>(Name, Expr)); 889a31c91b1SEugene Leviant return static_cast<SymbolAssignment *>(Opt.Commands.back().get()); 890a31c91b1SEugene Leviant } 891a31c91b1SEugene Leviant return nullptr; 892a31c91b1SEugene Leviant } 893a31c91b1SEugene Leviant 894a31c91b1SEugene Leviant // This function reads balanced expression until semicolon is seen. 895eda81a1bSEugene Leviant std::vector<StringRef> ScriptParser::readSectionsCommandExpr() { 896a31c91b1SEugene Leviant int Braces = 0; 897eda81a1bSEugene Leviant std::vector<StringRef> Expr; 898eda81a1bSEugene Leviant while (!Error) { 899a31c91b1SEugene Leviant StringRef Tok = peek(); 900a31c91b1SEugene Leviant 901a31c91b1SEugene Leviant if (Tok == "(") 902a31c91b1SEugene Leviant Braces++; 903a31c91b1SEugene Leviant else if (Tok == ")") 904a31c91b1SEugene Leviant if (--Braces < 0) 905a31c91b1SEugene Leviant break; 906a31c91b1SEugene Leviant 907a31c91b1SEugene Leviant next(); 908eda81a1bSEugene Leviant if (Tok == ";") 909eda81a1bSEugene Leviant break; 910eda81a1bSEugene Leviant Expr.push_back(Tok); 911eda81a1bSEugene Leviant } 912eda81a1bSEugene Leviant return Expr; 913eda81a1bSEugene Leviant } 914eda81a1bSEugene Leviant 915bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 916bbe38602SEugene Leviant std::vector<StringRef> Phdrs; 917bbe38602SEugene Leviant while (!Error && peek().startswith(":")) { 918bbe38602SEugene Leviant StringRef Tok = next(); 919bbe38602SEugene Leviant Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 920bbe38602SEugene Leviant if (Tok.empty()) { 921bbe38602SEugene Leviant setError("section header name is empty"); 922bbe38602SEugene Leviant break; 923bbe38602SEugene Leviant } 924bbe38602SEugene Leviant Phdrs.push_back(Tok); 925bbe38602SEugene Leviant } 926bbe38602SEugene Leviant return Phdrs; 927bbe38602SEugene Leviant } 928bbe38602SEugene Leviant 929bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() { 930bbe38602SEugene Leviant StringRef Tok = next(); 931b0f6c590SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 932b0f6c590SRui Ueyama .Case("PT_NULL", PT_NULL) 933b0f6c590SRui Ueyama .Case("PT_LOAD", PT_LOAD) 934b0f6c590SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 935b0f6c590SRui Ueyama .Case("PT_INTERP", PT_INTERP) 936b0f6c590SRui Ueyama .Case("PT_NOTE", PT_NOTE) 937b0f6c590SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 938b0f6c590SRui Ueyama .Case("PT_PHDR", PT_PHDR) 939b0f6c590SRui Ueyama .Case("PT_TLS", PT_TLS) 940b0f6c590SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 941b0f6c590SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 942b0f6c590SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 943b0f6c590SRui Ueyama .Default(-1); 944bbe38602SEugene Leviant 945b0f6c590SRui Ueyama if (Ret == (unsigned)-1) { 946b0f6c590SRui Ueyama setError("invalid program header type: " + Tok); 947b0f6c590SRui Ueyama return PT_NULL; 948b0f6c590SRui Ueyama } 949b0f6c590SRui Ueyama return Ret; 950bbe38602SEugene Leviant } 951bbe38602SEugene Leviant 95216b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) { 95316b0cc9eSSimon Atanasyan if (Config->Sysroot == "") 95416b0cc9eSSimon Atanasyan return false; 95516b0cc9eSSimon Atanasyan for (; !Path.empty(); Path = sys::path::parent_path(Path)) 95616b0cc9eSSimon Atanasyan if (sys::fs::equivalent(Config->Sysroot, Path)) 95716b0cc9eSSimon Atanasyan return true; 95816b0cc9eSSimon Atanasyan return false; 95916b0cc9eSSimon Atanasyan } 96016b0cc9eSSimon Atanasyan 96107320e40SRui Ueyama // Entry point. 96207320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 96316b0cc9eSSimon Atanasyan StringRef Path = MB.getBufferIdentifier(); 96407320e40SRui Ueyama ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run(); 965f7c5fbb1SRui Ueyama } 9661ebc8ed7SRui Ueyama 96707320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>; 96807320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>; 96907320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>; 97007320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>; 971