1 //===- LinkerScript.cpp ---------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the parser/evaluator of the linker script. 11 // It does not construct an AST but consume linker script directives directly. 12 // Results are written to Driver or Config object. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "LinkerScript.h" 17 #include "Config.h" 18 #include "Driver.h" 19 #include "InputSection.h" 20 #include "OutputSections.h" 21 #include "ScriptParser.h" 22 #include "Strings.h" 23 #include "Symbols.h" 24 #include "SymbolTable.h" 25 #include "Target.h" 26 #include "Writer.h" 27 #include "llvm/ADT/StringSwitch.h" 28 #include "llvm/Support/ELF.h" 29 #include "llvm/Support/FileSystem.h" 30 #include "llvm/Support/MemoryBuffer.h" 31 #include "llvm/Support/Path.h" 32 #include "llvm/Support/StringSaver.h" 33 34 using namespace llvm; 35 using namespace llvm::ELF; 36 using namespace llvm::object; 37 using namespace lld; 38 using namespace lld::elf; 39 40 ScriptConfiguration *elf::ScriptConfig; 41 42 // This is an operator-precedence parser to parse and evaluate 43 // a linker script expression. For each linker script arithmetic 44 // expression (e.g. ". = . + 0x1000"), a new instance of ExprParser 45 // is created and ran. 46 namespace { 47 class ExprParser : public ScriptParserBase { 48 public: 49 ExprParser(std::vector<StringRef> &Tokens, uint64_t Dot) 50 : ScriptParserBase(Tokens), Dot(Dot) {} 51 52 uint64_t run(); 53 54 private: 55 uint64_t parsePrimary(); 56 uint64_t parseTernary(uint64_t Cond); 57 uint64_t apply(StringRef Op, uint64_t L, uint64_t R); 58 uint64_t parseExpr1(uint64_t Lhs, int MinPrec); 59 uint64_t parseExpr(); 60 61 uint64_t Dot; 62 }; 63 } 64 65 static int precedence(StringRef Op) { 66 return StringSwitch<int>(Op) 67 .Case("*", 4) 68 .Case("/", 4) 69 .Case("+", 3) 70 .Case("-", 3) 71 .Case("<", 2) 72 .Case(">", 2) 73 .Case(">=", 2) 74 .Case("<=", 2) 75 .Case("==", 2) 76 .Case("!=", 2) 77 .Case("&", 1) 78 .Default(-1); 79 } 80 81 static uint64_t evalExpr(std::vector<StringRef> &Tokens, uint64_t Dot) { 82 return ExprParser(Tokens, Dot).run(); 83 } 84 85 uint64_t ExprParser::run() { 86 uint64_t V = parseExpr(); 87 if (!atEOF() && !Error) 88 setError("stray token: " + peek()); 89 return V; 90 } 91 92 // This is a part of the operator-precedence parser to evaluate 93 // arithmetic expressions in SECTIONS command. This function evaluates an 94 // integer literal, a parenthesized expression, the ALIGN function, 95 // or the special variable ".". 96 uint64_t ExprParser::parsePrimary() { 97 StringRef Tok = next(); 98 if (Tok == ".") 99 return Dot; 100 if (Tok == "(") { 101 uint64_t V = parseExpr(); 102 expect(")"); 103 return V; 104 } 105 if (Tok == "ALIGN") { 106 expect("("); 107 uint64_t V = parseExpr(); 108 expect(")"); 109 return alignTo(Dot, V); 110 } 111 uint64_t V = 0; 112 if (Tok.getAsInteger(0, V)) 113 setError("malformed number: " + Tok); 114 return V; 115 } 116 117 uint64_t ExprParser::parseTernary(uint64_t Cond) { 118 next(); 119 uint64_t V = parseExpr(); 120 expect(":"); 121 uint64_t W = parseExpr(); 122 return Cond ? V : W; 123 } 124 125 uint64_t ExprParser::apply(StringRef Op, uint64_t L, uint64_t R) { 126 if (Op == "*") 127 return L * R; 128 if (Op == "/") { 129 if (R == 0) { 130 error("division by zero"); 131 return 0; 132 } 133 return L / R; 134 } 135 if (Op == "+") 136 return L + R; 137 if (Op == "-") 138 return L - R; 139 if (Op == "<") 140 return L < R; 141 if (Op == ">") 142 return L > R; 143 if (Op == ">=") 144 return L >= R; 145 if (Op == "<=") 146 return L <= R; 147 if (Op == "==") 148 return L == R; 149 if (Op == "!=") 150 return L != R; 151 if (Op == "&") 152 return L & R; 153 llvm_unreachable("invalid operator"); 154 } 155 156 // This is a part of the operator-precedence parser. 157 // This function assumes that the remaining token stream starts 158 // with an operator. 159 uint64_t ExprParser::parseExpr1(uint64_t Lhs, int MinPrec) { 160 while (!atEOF()) { 161 // Read an operator and an expression. 162 StringRef Op1 = peek(); 163 if (Op1 == "?") 164 return parseTernary(Lhs); 165 if (precedence(Op1) < MinPrec) 166 return Lhs; 167 next(); 168 uint64_t Rhs = parsePrimary(); 169 170 // Evaluate the remaining part of the expression first if the 171 // next operator has greater precedence than the previous one. 172 // For example, if we have read "+" and "3", and if the next 173 // operator is "*", then we'll evaluate 3 * ... part first. 174 while (!atEOF()) { 175 StringRef Op2 = peek(); 176 if (precedence(Op2) <= precedence(Op1)) 177 break; 178 Rhs = parseExpr1(Rhs, precedence(Op2)); 179 } 180 181 Lhs = apply(Op1, Lhs, Rhs); 182 } 183 return Lhs; 184 } 185 186 // Reads and evaluates an arithmetic expression. 187 uint64_t ExprParser::parseExpr() { return parseExpr1(parsePrimary(), 0); } 188 189 template <class ELFT> 190 StringRef LinkerScript<ELFT>::getOutputSection(InputSectionBase<ELFT> *S) { 191 for (SectionRule &R : Opt.Sections) 192 if (globMatch(R.SectionPattern, S->getSectionName())) 193 return R.Dest; 194 return ""; 195 } 196 197 template <class ELFT> 198 bool LinkerScript<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) { 199 return !S || !S->Live || getOutputSection(S) == "/DISCARD/"; 200 } 201 202 template <class ELFT> 203 bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) { 204 for (StringRef Pat : Opt.KeptSections) 205 if (globMatch(Pat, S->getSectionName())) 206 return true; 207 return false; 208 } 209 210 template <class ELFT> 211 std::vector<OutputSectionBase<ELFT> *> 212 LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { 213 std::vector<OutputSectionBase<ELFT> *> Result; 214 215 // Add input section to output section. If there is no output section yet, 216 // then create it and add to output section list. 217 auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name) { 218 OutputSectionBase<ELFT> *Sec; 219 bool IsNew; 220 std::tie(Sec, IsNew) = Factory.create(C, Name); 221 if (IsNew) 222 Result.push_back(Sec); 223 Sec->addSection(C); 224 }; 225 226 // Select input sections matching rule and add them to corresponding 227 // output section. Section rules are processed in order they're listed 228 // in script, so correct input section order is maintained by design. 229 for (SectionRule &R : Opt.Sections) 230 for (const std::unique_ptr<ObjectFile<ELFT>> &F : 231 Symtab<ELFT>::X->getObjectFiles()) 232 for (InputSectionBase<ELFT> *S : F->getSections()) 233 if (!isDiscarded(S) && !S->OutSec && 234 globMatch(R.SectionPattern, S->getSectionName())) 235 // Add single input section to output section. 236 AddInputSec(S, R.Dest); 237 238 // Add all other input sections, which are not listed in script. 239 for (const std::unique_ptr<ObjectFile<ELFT>> &F : 240 Symtab<ELFT>::X->getObjectFiles()) 241 for (InputSectionBase<ELFT> *S : F->getSections()) 242 if (!isDiscarded(S)) { 243 if (!S->OutSec) 244 AddInputSec(S, getOutputSectionName(S)); 245 } else 246 reportDiscarded(S, F); 247 248 return Result; 249 } 250 251 template <class ELFT> 252 void LinkerScript<ELFT>::assignAddresses( 253 ArrayRef<OutputSectionBase<ELFT> *> Sections) { 254 // Orphan sections are sections present in the input files which 255 // are not explicitly placed into the output file by the linker script. 256 // We place orphan sections at end of file. 257 // Other linkers places them using some heuristics as described in 258 // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 259 for (OutputSectionBase<ELFT> *Sec : Sections) { 260 StringRef Name = Sec->getName(); 261 if (getSectionIndex(Name) == INT_MAX) 262 Opt.Commands.push_back({SectionKind, {}, Name, {}}); 263 } 264 265 // Assign addresses as instructed by linker script SECTIONS sub-commands. 266 Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 267 uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 268 uintX_t ThreadBssOffset = 0; 269 270 for (SectionsCommand &Cmd : Opt.Commands) { 271 if (Cmd.Kind == AssignmentKind) { 272 uint64_t Val = evalExpr(Cmd.Expr, Dot); 273 274 if (Cmd.Name == ".") { 275 Dot = Val; 276 } else { 277 auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd.Name)); 278 D->Value = Val; 279 } 280 continue; 281 } 282 283 // Find all the sections with required name. There can be more than 284 // one section with such name, if the alignment, flags or type 285 // attribute differs. 286 assert(Cmd.Kind == SectionKind); 287 for (OutputSectionBase<ELFT> *Sec : Sections) { 288 if (Sec->getName() != Cmd.Name) 289 continue; 290 291 if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { 292 uintX_t TVA = Dot + ThreadBssOffset; 293 TVA = alignTo(TVA, Sec->getAlignment()); 294 Sec->setVA(TVA); 295 ThreadBssOffset = TVA - Dot + Sec->getSize(); 296 continue; 297 } 298 299 if (Sec->getFlags() & SHF_ALLOC) { 300 Dot = alignTo(Dot, Sec->getAlignment()); 301 Sec->setVA(Dot); 302 MinVA = std::min(MinVA, Dot); 303 Dot += Sec->getSize(); 304 continue; 305 } 306 } 307 } 308 309 // ELF and Program headers need to be right before the first section in 310 // memory. Set their addresses accordingly. 311 MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() - 312 Out<ELFT>::ProgramHeaders->getSize(), 313 Target->PageSize); 314 Out<ELFT>::ElfHeader->setVA(MinVA); 315 Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 316 } 317 318 template <class ELFT> 319 std::vector<PhdrEntry<ELFT>> 320 LinkerScript<ELFT>::createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> Sections) { 321 int TlsNum = -1; 322 int NoteNum = -1; 323 int RelroNum = -1; 324 Phdr *Load = nullptr; 325 uintX_t Flags = PF_R; 326 std::vector<Phdr> Phdrs; 327 328 for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 329 Phdrs.emplace_back(Cmd.Type, PF_R); 330 Phdr &Added = Phdrs.back(); 331 332 if (Cmd.HasFilehdr) 333 Added.add(Out<ELFT>::ElfHeader); 334 if (Cmd.HasPhdrs) 335 Added.add(Out<ELFT>::ProgramHeaders); 336 337 switch (Cmd.Type) { 338 case PT_INTERP: 339 if (needsInterpSection<ELFT>()) 340 Added.add(Out<ELFT>::Interp); 341 break; 342 case PT_DYNAMIC: 343 if (isOutputDynamic<ELFT>()) { 344 Added.H.p_flags = toPhdrFlags(Out<ELFT>::Dynamic->getFlags()); 345 Added.add(Out<ELFT>::Dynamic); 346 } 347 break; 348 case PT_TLS: 349 TlsNum = Phdrs.size() - 1; 350 break; 351 case PT_NOTE: 352 NoteNum = Phdrs.size() - 1; 353 break; 354 case PT_GNU_RELRO: 355 RelroNum = Phdrs.size() - 1; 356 break; 357 case PT_GNU_EH_FRAME: 358 if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) { 359 Added.H.p_flags = toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags()); 360 Added.add(Out<ELFT>::EhFrameHdr); 361 } 362 break; 363 } 364 } 365 366 for (OutputSectionBase<ELFT> *Sec : Sections) { 367 if (!(Sec->getFlags() & SHF_ALLOC)) 368 break; 369 370 if (TlsNum != -1 && (Sec->getFlags() & SHF_TLS)) 371 Phdrs[TlsNum].add(Sec); 372 373 if (!needsPtLoad<ELFT>(Sec)) 374 continue; 375 376 const std::vector<size_t> &PhdrIds = 377 getPhdrIndicesForSection(Sec->getName()); 378 if (!PhdrIds.empty()) { 379 // Assign headers specified by linker script 380 for (size_t Id : PhdrIds) { 381 Phdrs[Id].add(Sec); 382 Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags()); 383 } 384 } else { 385 // If we have no load segment or flags've changed then we want new load 386 // segment. 387 uintX_t NewFlags = toPhdrFlags(Sec->getFlags()); 388 if (Load == nullptr || Flags != NewFlags) { 389 Load = &*Phdrs.emplace(Phdrs.end(), PT_LOAD, NewFlags); 390 Flags = NewFlags; 391 } 392 Load->add(Sec); 393 } 394 395 if (RelroNum != -1 && isRelroSection(Sec)) 396 Phdrs[RelroNum].add(Sec); 397 if (NoteNum != -1 && Sec->getType() == SHT_NOTE) 398 Phdrs[NoteNum].add(Sec); 399 } 400 return Phdrs; 401 } 402 403 template <class ELFT> 404 ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 405 auto I = Opt.Filler.find(Name); 406 if (I == Opt.Filler.end()) 407 return {}; 408 return I->second; 409 } 410 411 // Returns the index of the given section name in linker script 412 // SECTIONS commands. Sections are laid out as the same order as they 413 // were in the script. If a given name did not appear in the script, 414 // it returns INT_MAX, so that it will be laid out at end of file. 415 template <class ELFT> 416 int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 417 auto Begin = Opt.Commands.begin(); 418 auto End = Opt.Commands.end(); 419 auto I = std::find_if(Begin, End, [&](SectionsCommand &N) { 420 return N.Kind == SectionKind && N.Name == Name; 421 }); 422 return I == End ? INT_MAX : (I - Begin); 423 } 424 425 // A compartor to sort output sections. Returns -1 or 1 if 426 // A or B are mentioned in linker script. Otherwise, returns 0. 427 template <class ELFT> 428 int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 429 int I = getSectionIndex(A); 430 int J = getSectionIndex(B); 431 if (I == INT_MAX && J == INT_MAX) 432 return 0; 433 return I < J ? -1 : 1; 434 } 435 436 template <class ELFT> 437 void LinkerScript<ELFT>::addScriptedSymbols() { 438 for (SectionsCommand &Cmd : Opt.Commands) 439 if (Cmd.Kind == AssignmentKind) 440 if (Cmd.Name != "." && Symtab<ELFT>::X->find(Cmd.Name) == nullptr) 441 Symtab<ELFT>::X->addAbsolute(Cmd.Name, STV_DEFAULT); 442 } 443 444 template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 445 return !Opt.PhdrsCommands.empty(); 446 } 447 448 // Returns indices of ELF headers containing specific section, identified 449 // by Name. Each index is a zero based number of ELF header listed within 450 // PHDRS {} script block. 451 template <class ELFT> 452 std::vector<size_t> 453 LinkerScript<ELFT>::getPhdrIndicesForSection(StringRef Name) { 454 for (SectionsCommand &Cmd : Opt.Commands) { 455 if (Cmd.Kind != SectionKind || Cmd.Name != Name) 456 continue; 457 458 std::vector<size_t> Indices; 459 for (StringRef PhdrName : Cmd.Phdrs) { 460 auto ItPhdr = 461 std::find_if(Opt.PhdrsCommands.rbegin(), Opt.PhdrsCommands.rend(), 462 [&](PhdrsCommand &Cmd) { return Cmd.Name == PhdrName; }); 463 if (ItPhdr == Opt.PhdrsCommands.rend()) 464 error("section header '" + PhdrName + "' is not listed in PHDRS"); 465 else 466 Indices.push_back(std::distance(ItPhdr, Opt.PhdrsCommands.rend()) - 1); 467 } 468 return Indices; 469 } 470 return {}; 471 } 472 473 class elf::ScriptParser : public ScriptParserBase { 474 typedef void (ScriptParser::*Handler)(); 475 476 public: 477 ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 478 479 void run(); 480 481 private: 482 void addFile(StringRef Path); 483 484 void readAsNeeded(); 485 void readEntry(); 486 void readExtern(); 487 void readGroup(); 488 void readInclude(); 489 void readNothing() {} 490 void readOutput(); 491 void readOutputArch(); 492 void readOutputFormat(); 493 void readPhdrs(); 494 void readSearchDir(); 495 void readSections(); 496 497 void readLocationCounterValue(); 498 void readOutputSectionDescription(StringRef OutSec); 499 std::vector<StringRef> readOutputSectionPhdrs(); 500 unsigned readPhdrType(); 501 void readSymbolAssignment(StringRef Name); 502 std::vector<StringRef> readSectionsCommandExpr(); 503 504 const static StringMap<Handler> Cmd; 505 ScriptConfiguration &Opt = *ScriptConfig; 506 StringSaver Saver = {ScriptConfig->Alloc}; 507 bool IsUnderSysroot; 508 }; 509 510 const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = { 511 {"ENTRY", &ScriptParser::readEntry}, 512 {"EXTERN", &ScriptParser::readExtern}, 513 {"GROUP", &ScriptParser::readGroup}, 514 {"INCLUDE", &ScriptParser::readInclude}, 515 {"INPUT", &ScriptParser::readGroup}, 516 {"OUTPUT", &ScriptParser::readOutput}, 517 {"OUTPUT_ARCH", &ScriptParser::readOutputArch}, 518 {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat}, 519 {"PHDRS", &ScriptParser::readPhdrs}, 520 {"SEARCH_DIR", &ScriptParser::readSearchDir}, 521 {"SECTIONS", &ScriptParser::readSections}, 522 {";", &ScriptParser::readNothing}}; 523 524 void ScriptParser::run() { 525 while (!atEOF()) { 526 StringRef Tok = next(); 527 if (Handler Fn = Cmd.lookup(Tok)) 528 (this->*Fn)(); 529 else 530 setError("unknown directive: " + Tok); 531 } 532 } 533 534 void ScriptParser::addFile(StringRef S) { 535 if (IsUnderSysroot && S.startswith("/")) { 536 SmallString<128> Path; 537 (Config->Sysroot + S).toStringRef(Path); 538 if (sys::fs::exists(Path)) { 539 Driver->addFile(Saver.save(Path.str())); 540 return; 541 } 542 } 543 544 if (sys::path::is_absolute(S)) { 545 Driver->addFile(S); 546 } else if (S.startswith("=")) { 547 if (Config->Sysroot.empty()) 548 Driver->addFile(S.substr(1)); 549 else 550 Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 551 } else if (S.startswith("-l")) { 552 Driver->addLibrary(S.substr(2)); 553 } else if (sys::fs::exists(S)) { 554 Driver->addFile(S); 555 } else { 556 std::string Path = findFromSearchPaths(S); 557 if (Path.empty()) 558 setError("unable to find " + S); 559 else 560 Driver->addFile(Saver.save(Path)); 561 } 562 } 563 564 void ScriptParser::readAsNeeded() { 565 expect("("); 566 bool Orig = Config->AsNeeded; 567 Config->AsNeeded = true; 568 while (!Error) { 569 StringRef Tok = next(); 570 if (Tok == ")") 571 break; 572 addFile(Tok); 573 } 574 Config->AsNeeded = Orig; 575 } 576 577 void ScriptParser::readEntry() { 578 // -e <symbol> takes predecence over ENTRY(<symbol>). 579 expect("("); 580 StringRef Tok = next(); 581 if (Config->Entry.empty()) 582 Config->Entry = Tok; 583 expect(")"); 584 } 585 586 void ScriptParser::readExtern() { 587 expect("("); 588 while (!Error) { 589 StringRef Tok = next(); 590 if (Tok == ")") 591 return; 592 Config->Undefined.push_back(Tok); 593 } 594 } 595 596 void ScriptParser::readGroup() { 597 expect("("); 598 while (!Error) { 599 StringRef Tok = next(); 600 if (Tok == ")") 601 return; 602 if (Tok == "AS_NEEDED") { 603 readAsNeeded(); 604 continue; 605 } 606 addFile(Tok); 607 } 608 } 609 610 void ScriptParser::readInclude() { 611 StringRef Tok = next(); 612 auto MBOrErr = MemoryBuffer::getFile(Tok); 613 if (!MBOrErr) { 614 setError("cannot open " + Tok); 615 return; 616 } 617 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 618 StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 619 std::vector<StringRef> V = tokenize(S); 620 Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 621 } 622 623 void ScriptParser::readOutput() { 624 // -o <file> takes predecence over OUTPUT(<file>). 625 expect("("); 626 StringRef Tok = next(); 627 if (Config->OutputFile.empty()) 628 Config->OutputFile = Tok; 629 expect(")"); 630 } 631 632 void ScriptParser::readOutputArch() { 633 // Error checking only for now. 634 expect("("); 635 next(); 636 expect(")"); 637 } 638 639 void ScriptParser::readOutputFormat() { 640 // Error checking only for now. 641 expect("("); 642 next(); 643 StringRef Tok = next(); 644 if (Tok == ")") 645 return; 646 if (Tok != ",") { 647 setError("unexpected token: " + Tok); 648 return; 649 } 650 next(); 651 expect(","); 652 next(); 653 expect(")"); 654 } 655 656 void ScriptParser::readPhdrs() { 657 expect("{"); 658 while (!Error && !skip("}")) { 659 StringRef Tok = next(); 660 Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false}); 661 PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 662 663 PhdrCmd.Type = readPhdrType(); 664 do { 665 Tok = next(); 666 if (Tok == ";") 667 break; 668 if (Tok == "FILEHDR") 669 PhdrCmd.HasFilehdr = true; 670 else if (Tok == "PHDRS") 671 PhdrCmd.HasPhdrs = true; 672 else 673 setError("unexpected header attribute: " + Tok); 674 } while (!Error); 675 } 676 } 677 678 void ScriptParser::readSearchDir() { 679 expect("("); 680 Config->SearchPaths.push_back(next()); 681 expect(")"); 682 } 683 684 void ScriptParser::readSections() { 685 Opt.DoLayout = true; 686 expect("{"); 687 while (!Error && !skip("}")) { 688 StringRef Tok = peek(); 689 if (Tok == ".") { 690 readLocationCounterValue(); 691 continue; 692 } 693 next(); 694 if (peek() == "=") 695 readSymbolAssignment(Tok); 696 else 697 readOutputSectionDescription(Tok); 698 } 699 } 700 701 void ScriptParser::readLocationCounterValue() { 702 expect("."); 703 expect("="); 704 std::vector<StringRef> Expr = readSectionsCommandExpr(); 705 if (Expr.empty()) 706 error("error in location counter expression"); 707 else 708 Opt.Commands.push_back({AssignmentKind, std::move(Expr), ".", {}}); 709 } 710 711 void ScriptParser::readOutputSectionDescription(StringRef OutSec) { 712 Opt.Commands.push_back({SectionKind, {}, OutSec, {}}); 713 SectionsCommand &Cmd = Opt.Commands.back(); 714 expect(":"); 715 expect("{"); 716 717 while (!Error && !skip("}")) { 718 StringRef Tok = next(); 719 if (Tok == "*") { 720 expect("("); 721 while (!Error && !skip(")")) 722 Opt.Sections.emplace_back(OutSec, next()); 723 } else if (Tok == "KEEP") { 724 expect("("); 725 expect("*"); 726 expect("("); 727 while (!Error && !skip(")")) { 728 StringRef Sec = next(); 729 Opt.Sections.emplace_back(OutSec, Sec); 730 Opt.KeptSections.push_back(Sec); 731 } 732 expect(")"); 733 } else { 734 setError("unknown command " + Tok); 735 } 736 } 737 Cmd.Phdrs = readOutputSectionPhdrs(); 738 739 StringRef Tok = peek(); 740 if (Tok.startswith("=")) { 741 if (!Tok.startswith("=0x")) { 742 setError("filler should be a hexadecimal value"); 743 return; 744 } 745 Tok = Tok.substr(3); 746 Opt.Filler[OutSec] = parseHex(Tok); 747 next(); 748 } 749 } 750 751 void ScriptParser::readSymbolAssignment(StringRef Name) { 752 expect("="); 753 std::vector<StringRef> Expr = readSectionsCommandExpr(); 754 if (Expr.empty()) 755 error("error in symbol assignment expression"); 756 else 757 Opt.Commands.push_back({AssignmentKind, std::move(Expr), Name, {}}); 758 } 759 760 std::vector<StringRef> ScriptParser::readSectionsCommandExpr() { 761 std::vector<StringRef> Expr; 762 while (!Error) { 763 StringRef Tok = next(); 764 if (Tok == ";") 765 break; 766 Expr.push_back(Tok); 767 } 768 return Expr; 769 } 770 771 std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 772 std::vector<StringRef> Phdrs; 773 while (!Error && peek().startswith(":")) { 774 StringRef Tok = next(); 775 Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 776 if (Tok.empty()) { 777 setError("section header name is empty"); 778 break; 779 } 780 Phdrs.push_back(Tok); 781 } 782 return Phdrs; 783 } 784 785 unsigned ScriptParser::readPhdrType() { 786 StringRef Tok = next(); 787 unsigned Ret = StringSwitch<unsigned>(Tok) 788 .Case("PT_NULL", PT_NULL) 789 .Case("PT_LOAD", PT_LOAD) 790 .Case("PT_DYNAMIC", PT_DYNAMIC) 791 .Case("PT_INTERP", PT_INTERP) 792 .Case("PT_NOTE", PT_NOTE) 793 .Case("PT_SHLIB", PT_SHLIB) 794 .Case("PT_PHDR", PT_PHDR) 795 .Case("PT_TLS", PT_TLS) 796 .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 797 .Case("PT_GNU_STACK", PT_GNU_STACK) 798 .Case("PT_GNU_RELRO", PT_GNU_RELRO) 799 .Default(-1); 800 801 if (Ret == (unsigned)-1) { 802 setError("invalid program header type: " + Tok); 803 return PT_NULL; 804 } 805 return Ret; 806 } 807 808 static bool isUnderSysroot(StringRef Path) { 809 if (Config->Sysroot == "") 810 return false; 811 for (; !Path.empty(); Path = sys::path::parent_path(Path)) 812 if (sys::fs::equivalent(Config->Sysroot, Path)) 813 return true; 814 return false; 815 } 816 817 // Entry point. 818 void elf::readLinkerScript(MemoryBufferRef MB) { 819 StringRef Path = MB.getBufferIdentifier(); 820 ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run(); 821 } 822 823 template class elf::LinkerScript<ELF32LE>; 824 template class elf::LinkerScript<ELF32BE>; 825 template class elf::LinkerScript<ELF64LE>; 826 template class elf::LinkerScript<ELF64BE>; 827