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 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 void LinkerScript<ELFT>::assignAddresses( 212 ArrayRef<OutputSectionBase<ELFT> *> Sections) { 213 // Orphan sections are sections present in the input files which 214 // are not explicitly placed into the output file by the linker script. 215 // We place orphan sections at end of file. 216 // Other linkers places them using some heuristics as described in 217 // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. 218 for (OutputSectionBase<ELFT> *Sec : Sections) { 219 StringRef Name = Sec->getName(); 220 if (getSectionIndex(Name) == INT_MAX) 221 Opt.Commands.push_back({SectionKind, {}, Name, {}}); 222 } 223 224 // Assign addresses as instructed by linker script SECTIONS sub-commands. 225 Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); 226 uintX_t MinVA = std::numeric_limits<uintX_t>::max(); 227 uintX_t ThreadBssOffset = 0; 228 229 for (SectionsCommand &Cmd : Opt.Commands) { 230 if (Cmd.Kind == AssignmentKind) { 231 uint64_t Val = evalExpr(Cmd.Expr, Dot); 232 233 if (Cmd.Name == ".") { 234 Dot = Val; 235 } else { 236 auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd.Name)); 237 D->Value = Val; 238 } 239 continue; 240 } 241 242 // Find all the sections with required name. There can be more than 243 // one section with such name, if the alignment, flags or type 244 // attribute differs. 245 assert(Cmd.Kind == SectionKind); 246 for (OutputSectionBase<ELFT> *Sec : Sections) { 247 if (Sec->getName() != Cmd.Name) 248 continue; 249 250 if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { 251 uintX_t TVA = Dot + ThreadBssOffset; 252 TVA = alignTo(TVA, Sec->getAlignment()); 253 Sec->setVA(TVA); 254 ThreadBssOffset = TVA - Dot + Sec->getSize(); 255 continue; 256 } 257 258 if (Sec->getFlags() & SHF_ALLOC) { 259 Dot = alignTo(Dot, Sec->getAlignment()); 260 Sec->setVA(Dot); 261 MinVA = std::min(MinVA, Dot); 262 Dot += Sec->getSize(); 263 continue; 264 } 265 } 266 } 267 268 // ELF and Program headers need to be right before the first section in 269 // memory. Set their addresses accordingly. 270 MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() - 271 Out<ELFT>::ProgramHeaders->getSize(), 272 Target->PageSize); 273 Out<ELFT>::ElfHeader->setVA(MinVA); 274 Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA); 275 } 276 277 template <class ELFT> 278 std::vector<PhdrEntry<ELFT>> 279 LinkerScript<ELFT>::createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> Sections) { 280 int TlsNum = -1; 281 int NoteNum = -1; 282 int RelroNum = -1; 283 Phdr *Load = nullptr; 284 uintX_t Flags = PF_R; 285 std::vector<Phdr> Phdrs; 286 287 for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { 288 Phdrs.emplace_back(Cmd.Type, PF_R); 289 Phdr &Added = Phdrs.back(); 290 291 if (Cmd.HasFilehdr) 292 Added.AddSec(Out<ELFT>::ElfHeader); 293 if (Cmd.HasPhdrs) 294 Added.AddSec(Out<ELFT>::ProgramHeaders); 295 296 switch (Cmd.Type) { 297 case PT_INTERP: 298 if (needsInterpSection<ELFT>()) 299 Added.AddSec(Out<ELFT>::Interp); 300 break; 301 case PT_DYNAMIC: 302 if (isOutputDynamic<ELFT>()) { 303 Added.H.p_flags = toPhdrFlags(Out<ELFT>::Dynamic->getFlags()); 304 Added.AddSec(Out<ELFT>::Dynamic); 305 } 306 break; 307 case PT_TLS: 308 TlsNum = Phdrs.size() - 1; 309 break; 310 case PT_NOTE: 311 NoteNum = Phdrs.size() - 1; 312 break; 313 case PT_GNU_RELRO: 314 RelroNum = Phdrs.size() - 1; 315 break; 316 case PT_GNU_EH_FRAME: 317 if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) { 318 Added.H.p_flags = toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags()); 319 Added.AddSec(Out<ELFT>::EhFrameHdr); 320 } 321 break; 322 } 323 } 324 325 for (OutputSectionBase<ELFT> *Sec : Sections) { 326 if (!(Sec->getFlags() & SHF_ALLOC)) 327 break; 328 329 if (TlsNum != -1 && (Sec->getFlags() & SHF_TLS)) 330 Phdrs[TlsNum].AddSec(Sec); 331 332 if (!needsPtLoad<ELFT>(Sec)) 333 continue; 334 335 const std::vector<size_t> &PhdrIds = 336 getPhdrIndicesForSection(Sec->getName()); 337 if (!PhdrIds.empty()) { 338 // Assign headers specified by linker script 339 for (size_t Id : PhdrIds) { 340 Phdrs[Id].AddSec(Sec); 341 Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags()); 342 } 343 } else { 344 // If we have no load segment or flags've changed then we want new load 345 // segment. 346 uintX_t NewFlags = toPhdrFlags(Sec->getFlags()); 347 if (Load == nullptr || Flags != NewFlags) { 348 Load = &*Phdrs.emplace(Phdrs.end(), PT_LOAD, NewFlags); 349 Flags = NewFlags; 350 } 351 Load->AddSec(Sec); 352 } 353 354 if (RelroNum != -1 && isRelroSection(Sec)) 355 Phdrs[RelroNum].AddSec(Sec); 356 if (NoteNum != -1 && Sec->getType() == SHT_NOTE) 357 Phdrs[NoteNum].AddSec(Sec); 358 } 359 return Phdrs; 360 } 361 362 template <class ELFT> 363 ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { 364 auto I = Opt.Filler.find(Name); 365 if (I == Opt.Filler.end()) 366 return {}; 367 return I->second; 368 } 369 370 // Returns the index of the given section name in linker script 371 // SECTIONS commands. Sections are laid out as the same order as they 372 // were in the script. If a given name did not appear in the script, 373 // it returns INT_MAX, so that it will be laid out at end of file. 374 template <class ELFT> 375 int LinkerScript<ELFT>::getSectionIndex(StringRef Name) { 376 auto Begin = Opt.Commands.begin(); 377 auto End = Opt.Commands.end(); 378 auto I = std::find_if(Begin, End, [&](SectionsCommand &N) { 379 return N.Kind == SectionKind && N.Name == Name; 380 }); 381 return I == End ? INT_MAX : (I - Begin); 382 } 383 384 // A compartor to sort output sections. Returns -1 or 1 if 385 // A or B are mentioned in linker script. Otherwise, returns 0. 386 template <class ELFT> 387 int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) { 388 int I = getSectionIndex(A); 389 int J = getSectionIndex(B); 390 if (I == INT_MAX && J == INT_MAX) 391 return 0; 392 return I < J ? -1 : 1; 393 } 394 395 template <class ELFT> 396 void LinkerScript<ELFT>::addScriptedSymbols() { 397 for (SectionsCommand &Cmd : Opt.Commands) 398 if (Cmd.Kind == AssignmentKind) 399 if (Cmd.Name != "." && Symtab<ELFT>::X->find(Cmd.Name) == nullptr) 400 Symtab<ELFT>::X->addAbsolute(Cmd.Name, STV_DEFAULT); 401 } 402 403 template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() { 404 return !Opt.PhdrsCommands.empty(); 405 } 406 407 // Returns indices of ELF headers containing specific section, identified 408 // by Name. Each index is a zero based number of ELF header listed within 409 // PHDRS {} script block. 410 template <class ELFT> 411 std::vector<size_t> 412 LinkerScript<ELFT>::getPhdrIndicesForSection(StringRef Name) { 413 std::vector<size_t> Indices; 414 auto ItSect = std::find_if( 415 Opt.Commands.begin(), Opt.Commands.end(), 416 [Name](const SectionsCommand &Cmd) { return Cmd.Name == Name; }); 417 if (ItSect != Opt.Commands.end()) { 418 SectionsCommand &SecCmd = (*ItSect); 419 for (StringRef PhdrName : SecCmd.Phdrs) { 420 auto ItPhdr = std::find_if( 421 Opt.PhdrsCommands.rbegin(), Opt.PhdrsCommands.rend(), 422 [PhdrName](PhdrsCommand &Cmd) { return Cmd.Name == PhdrName; }); 423 if (ItPhdr == Opt.PhdrsCommands.rend()) 424 error("section header '" + PhdrName + "' is not listed in PHDRS"); 425 else 426 Indices.push_back(std::distance(ItPhdr, Opt.PhdrsCommands.rend()) - 1); 427 } 428 } 429 return Indices; 430 } 431 432 class elf::ScriptParser : public ScriptParserBase { 433 typedef void (ScriptParser::*Handler)(); 434 435 public: 436 ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {} 437 438 void run(); 439 440 private: 441 void addFile(StringRef Path); 442 443 void readAsNeeded(); 444 void readEntry(); 445 void readExtern(); 446 void readGroup(); 447 void readInclude(); 448 void readNothing() {} 449 void readOutput(); 450 void readOutputArch(); 451 void readOutputFormat(); 452 void readPhdrs(); 453 void readSearchDir(); 454 void readSections(); 455 456 void readLocationCounterValue(); 457 void readOutputSectionDescription(StringRef OutSec); 458 std::vector<StringRef> readOutputSectionPhdrs(); 459 unsigned readPhdrType(); 460 void readSymbolAssignment(StringRef Name); 461 std::vector<StringRef> readSectionsCommandExpr(); 462 463 const static StringMap<Handler> Cmd; 464 ScriptConfiguration &Opt = *ScriptConfig; 465 StringSaver Saver = {ScriptConfig->Alloc}; 466 bool IsUnderSysroot; 467 }; 468 469 const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = { 470 {"ENTRY", &ScriptParser::readEntry}, 471 {"EXTERN", &ScriptParser::readExtern}, 472 {"GROUP", &ScriptParser::readGroup}, 473 {"INCLUDE", &ScriptParser::readInclude}, 474 {"INPUT", &ScriptParser::readGroup}, 475 {"OUTPUT", &ScriptParser::readOutput}, 476 {"OUTPUT_ARCH", &ScriptParser::readOutputArch}, 477 {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat}, 478 {"PHDRS", &ScriptParser::readPhdrs}, 479 {"SEARCH_DIR", &ScriptParser::readSearchDir}, 480 {"SECTIONS", &ScriptParser::readSections}, 481 {";", &ScriptParser::readNothing}}; 482 483 void ScriptParser::run() { 484 while (!atEOF()) { 485 StringRef Tok = next(); 486 if (Handler Fn = Cmd.lookup(Tok)) 487 (this->*Fn)(); 488 else 489 setError("unknown directive: " + Tok); 490 } 491 } 492 493 void ScriptParser::addFile(StringRef S) { 494 if (IsUnderSysroot && S.startswith("/")) { 495 SmallString<128> Path; 496 (Config->Sysroot + S).toStringRef(Path); 497 if (sys::fs::exists(Path)) { 498 Driver->addFile(Saver.save(Path.str())); 499 return; 500 } 501 } 502 503 if (sys::path::is_absolute(S)) { 504 Driver->addFile(S); 505 } else if (S.startswith("=")) { 506 if (Config->Sysroot.empty()) 507 Driver->addFile(S.substr(1)); 508 else 509 Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 510 } else if (S.startswith("-l")) { 511 Driver->addLibrary(S.substr(2)); 512 } else if (sys::fs::exists(S)) { 513 Driver->addFile(S); 514 } else { 515 std::string Path = findFromSearchPaths(S); 516 if (Path.empty()) 517 setError("unable to find " + S); 518 else 519 Driver->addFile(Saver.save(Path)); 520 } 521 } 522 523 void ScriptParser::readAsNeeded() { 524 expect("("); 525 bool Orig = Config->AsNeeded; 526 Config->AsNeeded = true; 527 while (!Error) { 528 StringRef Tok = next(); 529 if (Tok == ")") 530 break; 531 addFile(Tok); 532 } 533 Config->AsNeeded = Orig; 534 } 535 536 void ScriptParser::readEntry() { 537 // -e <symbol> takes predecence over ENTRY(<symbol>). 538 expect("("); 539 StringRef Tok = next(); 540 if (Config->Entry.empty()) 541 Config->Entry = Tok; 542 expect(")"); 543 } 544 545 void ScriptParser::readExtern() { 546 expect("("); 547 while (!Error) { 548 StringRef Tok = next(); 549 if (Tok == ")") 550 return; 551 Config->Undefined.push_back(Tok); 552 } 553 } 554 555 void ScriptParser::readGroup() { 556 expect("("); 557 while (!Error) { 558 StringRef Tok = next(); 559 if (Tok == ")") 560 return; 561 if (Tok == "AS_NEEDED") { 562 readAsNeeded(); 563 continue; 564 } 565 addFile(Tok); 566 } 567 } 568 569 void ScriptParser::readInclude() { 570 StringRef Tok = next(); 571 auto MBOrErr = MemoryBuffer::getFile(Tok); 572 if (!MBOrErr) { 573 setError("cannot open " + Tok); 574 return; 575 } 576 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 577 StringRef S = Saver.save(MB->getMemBufferRef().getBuffer()); 578 std::vector<StringRef> V = tokenize(S); 579 Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); 580 } 581 582 void ScriptParser::readOutput() { 583 // -o <file> takes predecence over OUTPUT(<file>). 584 expect("("); 585 StringRef Tok = next(); 586 if (Config->OutputFile.empty()) 587 Config->OutputFile = Tok; 588 expect(")"); 589 } 590 591 void ScriptParser::readOutputArch() { 592 // Error checking only for now. 593 expect("("); 594 next(); 595 expect(")"); 596 } 597 598 void ScriptParser::readOutputFormat() { 599 // Error checking only for now. 600 expect("("); 601 next(); 602 StringRef Tok = next(); 603 if (Tok == ")") 604 return; 605 if (Tok != ",") { 606 setError("unexpected token: " + Tok); 607 return; 608 } 609 next(); 610 expect(","); 611 next(); 612 expect(")"); 613 } 614 615 void ScriptParser::readPhdrs() { 616 expect("{"); 617 while (!Error && !skip("}")) { 618 StringRef Tok = next(); 619 Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false}); 620 PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); 621 622 PhdrCmd.Type = readPhdrType(); 623 do { 624 Tok = next(); 625 if (Tok == ";") 626 break; 627 if (Tok == "FILEHDR") 628 PhdrCmd.HasFilehdr = true; 629 else if (Tok == "PHDRS") 630 PhdrCmd.HasPhdrs = true; 631 else 632 setError("unexpected header attribute: " + Tok); 633 } while (!Error); 634 } 635 } 636 637 void ScriptParser::readSearchDir() { 638 expect("("); 639 Config->SearchPaths.push_back(next()); 640 expect(")"); 641 } 642 643 void ScriptParser::readSections() { 644 Opt.DoLayout = true; 645 expect("{"); 646 while (!Error && !skip("}")) { 647 StringRef Tok = peek(); 648 if (Tok == ".") { 649 readLocationCounterValue(); 650 continue; 651 } 652 next(); 653 if (peek() == "=") 654 readSymbolAssignment(Tok); 655 else 656 readOutputSectionDescription(Tok); 657 } 658 } 659 660 void ScriptParser::readLocationCounterValue() { 661 expect("."); 662 expect("="); 663 std::vector<StringRef> Expr = readSectionsCommandExpr(); 664 if (Expr.empty()) 665 error("error in location counter expression"); 666 else 667 Opt.Commands.push_back({AssignmentKind, std::move(Expr), ".", {}}); 668 } 669 670 void ScriptParser::readOutputSectionDescription(StringRef OutSec) { 671 Opt.Commands.push_back({SectionKind, {}, OutSec, {}}); 672 SectionsCommand &Cmd = Opt.Commands.back(); 673 expect(":"); 674 expect("{"); 675 676 while (!Error && !skip("}")) { 677 StringRef Tok = next(); 678 if (Tok == "*") { 679 expect("("); 680 while (!Error && !skip(")")) 681 Opt.Sections.emplace_back(OutSec, next()); 682 } else if (Tok == "KEEP") { 683 expect("("); 684 expect("*"); 685 expect("("); 686 while (!Error && !skip(")")) { 687 StringRef Sec = next(); 688 Opt.Sections.emplace_back(OutSec, Sec); 689 Opt.KeptSections.push_back(Sec); 690 } 691 expect(")"); 692 } else { 693 setError("unknown command " + Tok); 694 } 695 } 696 Cmd.Phdrs = readOutputSectionPhdrs(); 697 698 StringRef Tok = peek(); 699 if (Tok.startswith("=")) { 700 if (!Tok.startswith("=0x")) { 701 setError("filler should be a hexadecimal value"); 702 return; 703 } 704 Tok = Tok.substr(3); 705 Opt.Filler[OutSec] = parseHex(Tok); 706 next(); 707 } 708 } 709 710 void ScriptParser::readSymbolAssignment(StringRef Name) { 711 expect("="); 712 std::vector<StringRef> Expr = readSectionsCommandExpr(); 713 if (Expr.empty()) 714 error("error in symbol assignment expression"); 715 else 716 Opt.Commands.push_back({AssignmentKind, std::move(Expr), Name, {}}); 717 } 718 719 std::vector<StringRef> ScriptParser::readSectionsCommandExpr() { 720 std::vector<StringRef> Expr; 721 while (!Error) { 722 StringRef Tok = next(); 723 if (Tok == ";") 724 break; 725 Expr.push_back(Tok); 726 } 727 return Expr; 728 } 729 730 std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 731 std::vector<StringRef> Phdrs; 732 while (!Error && peek().startswith(":")) { 733 StringRef Tok = next(); 734 Tok = (Tok.size() == 1) ? next() : Tok.substr(1); 735 if (Tok.empty()) { 736 setError("section header name is empty"); 737 break; 738 } 739 else 740 Phdrs.push_back(Tok); 741 } 742 return Phdrs; 743 } 744 745 unsigned ScriptParser::readPhdrType() { 746 static const char *typeNames[] = { 747 "PT_NULL", "PT_LOAD", "PT_DYNAMIC", "PT_INTERP", 748 "PT_NOTE", "PT_SHLIB", "PT_PHDR", "PT_TLS", 749 "PT_GNU_EH_FRAME", "PT_GNU_STACK", "PT_GNU_RELRO"}; 750 static unsigned typeCodes[] = { 751 PT_NULL, PT_LOAD, PT_DYNAMIC, PT_INTERP, PT_NOTE, PT_SHLIB, 752 PT_PHDR, PT_TLS, PT_GNU_EH_FRAME, PT_GNU_STACK, PT_GNU_RELRO}; 753 754 unsigned PhdrType = PT_NULL; 755 StringRef Tok = next(); 756 auto It = std::find(std::begin(typeNames), std::end(typeNames), Tok); 757 if (It != std::end(typeNames)) 758 PhdrType = typeCodes[std::distance(std::begin(typeNames), It)]; 759 else 760 setError("invalid program header type"); 761 762 return PhdrType; 763 } 764 765 static bool isUnderSysroot(StringRef Path) { 766 if (Config->Sysroot == "") 767 return false; 768 for (; !Path.empty(); Path = sys::path::parent_path(Path)) 769 if (sys::fs::equivalent(Config->Sysroot, Path)) 770 return true; 771 return false; 772 } 773 774 // Entry point. 775 void elf::readLinkerScript(MemoryBufferRef MB) { 776 StringRef Path = MB.getBufferIdentifier(); 777 ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run(); 778 } 779 780 template class elf::LinkerScript<ELF32LE>; 781 template class elf::LinkerScript<ELF32BE>; 782 template class elf::LinkerScript<ELF64LE>; 783 template class elf::LinkerScript<ELF64BE>; 784