1 //===- ScriptParser.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 a recursive-descendent parser for linker scripts. 11 // Parsed results are stored to Config and Script global objects. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "ScriptParser.h" 16 #include "Config.h" 17 #include "Driver.h" 18 #include "InputSection.h" 19 #include "LinkerScript.h" 20 #include "OutputSections.h" 21 #include "ScriptLexer.h" 22 #include "Symbols.h" 23 #include "Target.h" 24 #include "lld/Common/Memory.h" 25 #include "llvm/ADT/SmallString.h" 26 #include "llvm/ADT/StringRef.h" 27 #include "llvm/ADT/StringSet.h" 28 #include "llvm/ADT/StringSwitch.h" 29 #include "llvm/BinaryFormat/ELF.h" 30 #include "llvm/Support/Casting.h" 31 #include "llvm/Support/ErrorHandling.h" 32 #include "llvm/Support/FileSystem.h" 33 #include "llvm/Support/Path.h" 34 #include <cassert> 35 #include <limits> 36 #include <vector> 37 38 using namespace llvm; 39 using namespace llvm::ELF; 40 using namespace llvm::support::endian; 41 using namespace lld; 42 using namespace lld::elf; 43 44 static bool isUnderSysroot(StringRef Path); 45 46 namespace { 47 class ScriptParser final : ScriptLexer { 48 public: 49 ScriptParser(MemoryBufferRef MB) 50 : ScriptLexer(MB), 51 IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {} 52 53 void readLinkerScript(); 54 void readVersionScript(); 55 void readDynamicList(); 56 void readDefsym(StringRef Name); 57 58 private: 59 void addFile(StringRef Path); 60 61 void readAsNeeded(); 62 void readEntry(); 63 void readExtern(); 64 void readGroup(); 65 void readInclude(); 66 void readMemory(); 67 void readOutput(); 68 void readOutputArch(); 69 void readOutputFormat(); 70 void readPhdrs(); 71 void readRegionAlias(); 72 void readSearchDir(); 73 void readSections(); 74 void readVersion(); 75 void readVersionScriptCommand(); 76 77 SymbolAssignment *readAssignment(StringRef Name); 78 ByteCommand *readByteCommand(StringRef Tok); 79 uint32_t readFill(); 80 uint32_t parseFill(StringRef Tok); 81 void readSectionAddressType(OutputSection *Cmd); 82 OutputSection *readOutputSectionDescription(StringRef OutSec); 83 std::vector<StringRef> readOutputSectionPhdrs(); 84 InputSectionDescription *readInputSectionDescription(StringRef Tok); 85 StringMatcher readFilePatterns(); 86 std::vector<SectionPattern> readInputSectionsList(); 87 InputSectionDescription *readInputSectionRules(StringRef FilePattern); 88 unsigned readPhdrType(); 89 SortSectionPolicy readSortKind(); 90 SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 91 SymbolAssignment *readProvideOrAssignment(StringRef Tok); 92 void readSort(); 93 AssertCommand *readAssert(); 94 Expr readAssertExpr(); 95 Expr readConstant(); 96 Expr getPageSize(); 97 98 uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); 99 std::pair<uint32_t, uint32_t> readMemoryAttributes(); 100 101 Expr combine(StringRef Op, Expr L, Expr R); 102 Expr readExpr(); 103 Expr readExpr1(Expr Lhs, int MinPrec); 104 StringRef readParenLiteral(); 105 Expr readPrimary(); 106 Expr readTernary(Expr Cond); 107 Expr readParenExpr(); 108 109 // For parsing version script. 110 std::vector<SymbolVersion> readVersionExtern(); 111 void readAnonymousDeclaration(); 112 void readVersionDeclaration(StringRef VerStr); 113 114 std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 115 readSymbols(); 116 117 // True if a script being read is in a subdirectory specified by -sysroot. 118 bool IsUnderSysroot; 119 120 // A set to detect an INCLUDE() cycle. 121 StringSet<> Seen; 122 }; 123 } // namespace 124 125 static StringRef unquote(StringRef S) { 126 if (S.startswith("\"")) 127 return S.substr(1, S.size() - 2); 128 return S; 129 } 130 131 static bool isUnderSysroot(StringRef Path) { 132 if (Config->Sysroot == "") 133 return false; 134 for (; !Path.empty(); Path = sys::path::parent_path(Path)) 135 if (sys::fs::equivalent(Config->Sysroot, Path)) 136 return true; 137 return false; 138 } 139 140 // Some operations only support one non absolute value. Move the 141 // absolute one to the right hand side for convenience. 142 static void moveAbsRight(ExprValue &A, ExprValue &B) { 143 if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute())) 144 std::swap(A, B); 145 if (!B.isAbsolute()) 146 error(A.Loc + ": at least one side of the expression must be absolute"); 147 } 148 149 static ExprValue add(ExprValue A, ExprValue B) { 150 moveAbsRight(A, B); 151 return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc}; 152 } 153 154 static ExprValue sub(ExprValue A, ExprValue B) { 155 // The distance between two symbols in sections is absolute. 156 if (!A.isAbsolute() && !B.isAbsolute()) 157 return A.getValue() - B.getValue(); 158 return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc}; 159 } 160 161 static ExprValue bitAnd(ExprValue A, ExprValue B) { 162 moveAbsRight(A, B); 163 return {A.Sec, A.ForceAbsolute, 164 (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc}; 165 } 166 167 static ExprValue bitOr(ExprValue A, ExprValue B) { 168 moveAbsRight(A, B); 169 return {A.Sec, A.ForceAbsolute, 170 (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc}; 171 } 172 173 void ScriptParser::readDynamicList() { 174 Config->HasDynamicList = true; 175 expect("{"); 176 std::vector<SymbolVersion> Locals; 177 std::vector<SymbolVersion> Globals; 178 std::tie(Locals, Globals) = readSymbols(); 179 expect(";"); 180 181 if (!atEOF()) { 182 setError("EOF expected, but got " + next()); 183 return; 184 } 185 if (!Locals.empty()) { 186 setError("\"local:\" scope not supported in --dynamic-list"); 187 return; 188 } 189 190 for (SymbolVersion V : Globals) 191 Config->DynamicList.push_back(V); 192 } 193 194 void ScriptParser::readVersionScript() { 195 readVersionScriptCommand(); 196 if (!atEOF()) 197 setError("EOF expected, but got " + next()); 198 } 199 200 void ScriptParser::readVersionScriptCommand() { 201 if (consume("{")) { 202 readAnonymousDeclaration(); 203 return; 204 } 205 206 while (!atEOF() && !errorCount() && peek() != "}") { 207 StringRef VerStr = next(); 208 if (VerStr == "{") { 209 setError("anonymous version definition is used in " 210 "combination with other version definitions"); 211 return; 212 } 213 expect("{"); 214 readVersionDeclaration(VerStr); 215 } 216 } 217 218 void ScriptParser::readVersion() { 219 expect("{"); 220 readVersionScriptCommand(); 221 expect("}"); 222 } 223 224 void ScriptParser::readLinkerScript() { 225 while (!atEOF()) { 226 StringRef Tok = next(); 227 if (Tok == ";") 228 continue; 229 230 if (Tok == "ASSERT") { 231 Script->SectionCommands.push_back(readAssert()); 232 } else if (Tok == "ENTRY") { 233 readEntry(); 234 } else if (Tok == "EXTERN") { 235 readExtern(); 236 } else if (Tok == "GROUP" || Tok == "INPUT") { 237 readGroup(); 238 } else if (Tok == "INCLUDE") { 239 readInclude(); 240 } else if (Tok == "MEMORY") { 241 readMemory(); 242 } else if (Tok == "OUTPUT") { 243 readOutput(); 244 } else if (Tok == "OUTPUT_ARCH") { 245 readOutputArch(); 246 } else if (Tok == "OUTPUT_FORMAT") { 247 readOutputFormat(); 248 } else if (Tok == "PHDRS") { 249 readPhdrs(); 250 } else if (Tok == "REGION_ALIAS") { 251 readRegionAlias(); 252 } else if (Tok == "SEARCH_DIR") { 253 readSearchDir(); 254 } else if (Tok == "SECTIONS") { 255 readSections(); 256 } else if (Tok == "VERSION") { 257 readVersion(); 258 } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { 259 Script->SectionCommands.push_back(Cmd); 260 } else { 261 setError("unknown directive: " + Tok); 262 } 263 } 264 } 265 266 void ScriptParser::readDefsym(StringRef Name) { 267 Expr E = readExpr(); 268 if (!atEOF()) 269 setError("EOF expected, but got " + next()); 270 SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation()); 271 Script->SectionCommands.push_back(Cmd); 272 } 273 274 void ScriptParser::addFile(StringRef S) { 275 if (IsUnderSysroot && S.startswith("/")) { 276 SmallString<128> PathData; 277 StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 278 if (sys::fs::exists(Path)) { 279 Driver->addFile(Saver.save(Path), /*WithLOption=*/false); 280 return; 281 } 282 } 283 284 if (S.startswith("/")) { 285 Driver->addFile(S, /*WithLOption=*/false); 286 } else if (S.startswith("=")) { 287 if (Config->Sysroot.empty()) 288 Driver->addFile(S.substr(1), /*WithLOption=*/false); 289 else 290 Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)), 291 /*WithLOption=*/false); 292 } else if (S.startswith("-l")) { 293 Driver->addLibrary(S.substr(2)); 294 } else if (sys::fs::exists(S)) { 295 Driver->addFile(S, /*WithLOption=*/false); 296 } else { 297 if (Optional<std::string> Path = findFromSearchPaths(S)) 298 Driver->addFile(Saver.save(*Path), /*WithLOption=*/true); 299 else 300 setError("unable to find " + S); 301 } 302 } 303 304 void ScriptParser::readAsNeeded() { 305 expect("("); 306 bool Orig = Config->AsNeeded; 307 Config->AsNeeded = true; 308 while (!errorCount() && !consume(")")) 309 addFile(unquote(next())); 310 Config->AsNeeded = Orig; 311 } 312 313 void ScriptParser::readEntry() { 314 // -e <symbol> takes predecence over ENTRY(<symbol>). 315 expect("("); 316 StringRef Tok = next(); 317 if (Config->Entry.empty()) 318 Config->Entry = Tok; 319 expect(")"); 320 } 321 322 void ScriptParser::readExtern() { 323 expect("("); 324 while (!errorCount() && !consume(")")) 325 Config->Undefined.push_back(next()); 326 } 327 328 void ScriptParser::readGroup() { 329 expect("("); 330 while (!errorCount() && !consume(")")) { 331 if (consume("AS_NEEDED")) 332 readAsNeeded(); 333 else 334 addFile(unquote(next())); 335 } 336 } 337 338 void ScriptParser::readInclude() { 339 StringRef Tok = unquote(next()); 340 341 if (!Seen.insert(Tok).second) { 342 setError("there is a cycle in linker script INCLUDEs"); 343 return; 344 } 345 346 if (Optional<std::string> Path = searchLinkerScript(Tok)) { 347 if (Optional<MemoryBufferRef> MB = readFile(*Path)) 348 tokenize(*MB); 349 return; 350 } 351 setError("cannot find linker script " + Tok); 352 } 353 354 void ScriptParser::readOutput() { 355 // -o <file> takes predecence over OUTPUT(<file>). 356 expect("("); 357 StringRef Tok = next(); 358 if (Config->OutputFile.empty()) 359 Config->OutputFile = unquote(Tok); 360 expect(")"); 361 } 362 363 void ScriptParser::readOutputArch() { 364 // OUTPUT_ARCH is ignored for now. 365 expect("("); 366 while (!errorCount() && !consume(")")) 367 skip(); 368 } 369 370 void ScriptParser::readOutputFormat() { 371 // Error checking only for now. 372 expect("("); 373 skip(); 374 if (consume(")")) 375 return; 376 expect(","); 377 skip(); 378 expect(","); 379 skip(); 380 expect(")"); 381 } 382 383 void ScriptParser::readPhdrs() { 384 expect("{"); 385 386 while (!errorCount() && !consume("}")) { 387 PhdrsCommand Cmd; 388 Cmd.Name = next(); 389 Cmd.Type = readPhdrType(); 390 391 while (!errorCount() && !consume(";")) { 392 if (consume("FILEHDR")) 393 Cmd.HasFilehdr = true; 394 else if (consume("PHDRS")) 395 Cmd.HasPhdrs = true; 396 else if (consume("AT")) 397 Cmd.LMAExpr = readParenExpr(); 398 else if (consume("FLAGS")) 399 Cmd.Flags = readParenExpr()().getValue(); 400 else 401 setError("unexpected header attribute: " + next()); 402 } 403 404 Script->PhdrsCommands.push_back(Cmd); 405 } 406 } 407 408 void ScriptParser::readRegionAlias() { 409 expect("("); 410 StringRef Alias = unquote(next()); 411 expect(","); 412 StringRef Name = next(); 413 expect(")"); 414 415 if (Script->MemoryRegions.count(Alias)) 416 setError("redefinition of memory region '" + Alias + "'"); 417 if (!Script->MemoryRegions.count(Name)) 418 setError("memory region '" + Name + "' is not defined"); 419 Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]}); 420 } 421 422 void ScriptParser::readSearchDir() { 423 expect("("); 424 StringRef Tok = next(); 425 if (!Config->Nostdlib) 426 Config->SearchPaths.push_back(unquote(Tok)); 427 expect(")"); 428 } 429 430 void ScriptParser::readSections() { 431 Script->HasSectionsCommand = true; 432 433 // -no-rosegment is used to avoid placing read only non-executable sections in 434 // their own segment. We do the same if SECTIONS command is present in linker 435 // script. See comment for computeFlags(). 436 Config->SingleRoRx = true; 437 438 expect("{"); 439 std::vector<BaseCommand *> V; 440 while (!errorCount() && !consume("}")) { 441 StringRef Tok = next(); 442 BaseCommand *Cmd = readProvideOrAssignment(Tok); 443 if (!Cmd) { 444 if (Tok == "ASSERT") 445 Cmd = readAssert(); 446 else 447 Cmd = readOutputSectionDescription(Tok); 448 } 449 V.push_back(Cmd); 450 } 451 452 if (!atEOF() && consume("INSERT")) { 453 std::vector<BaseCommand *> *Dest = nullptr; 454 if (consume("AFTER")) 455 Dest = &Script->InsertAfterCommands[next()]; 456 else if (consume("BEFORE")) 457 Dest = &Script->InsertBeforeCommands[next()]; 458 else 459 setError("expected AFTER/BEFORE, but got '" + next() + "'"); 460 if (Dest) 461 Dest->insert(Dest->end(), V.begin(), V.end()); 462 return; 463 } 464 465 Script->SectionCommands.insert(Script->SectionCommands.end(), V.begin(), 466 V.end()); 467 } 468 469 static int precedence(StringRef Op) { 470 return StringSwitch<int>(Op) 471 .Cases("*", "/", "%", 6) 472 .Cases("+", "-", 5) 473 .Cases("<<", ">>", 4) 474 .Cases("<", "<=", ">", ">=", "==", "!=", 3) 475 .Case("&", 2) 476 .Case("|", 1) 477 .Default(-1); 478 } 479 480 StringMatcher ScriptParser::readFilePatterns() { 481 std::vector<StringRef> V; 482 while (!errorCount() && !consume(")")) 483 V.push_back(next()); 484 return StringMatcher(V); 485 } 486 487 SortSectionPolicy ScriptParser::readSortKind() { 488 if (consume("SORT") || consume("SORT_BY_NAME")) 489 return SortSectionPolicy::Name; 490 if (consume("SORT_BY_ALIGNMENT")) 491 return SortSectionPolicy::Alignment; 492 if (consume("SORT_BY_INIT_PRIORITY")) 493 return SortSectionPolicy::Priority; 494 if (consume("SORT_NONE")) 495 return SortSectionPolicy::None; 496 return SortSectionPolicy::Default; 497 } 498 499 // Reads SECTIONS command contents in the following form: 500 // 501 // <contents> ::= <elem>* 502 // <elem> ::= <exclude>? <glob-pattern> 503 // <exclude> ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")" 504 // 505 // For example, 506 // 507 // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz) 508 // 509 // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o". 510 // The semantics of that is section .foo in any file, section .bar in 511 // any file but a.o, and section .baz in any file but b.o. 512 std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 513 std::vector<SectionPattern> Ret; 514 while (!errorCount() && peek() != ")") { 515 StringMatcher ExcludeFilePat; 516 if (consume("EXCLUDE_FILE")) { 517 expect("("); 518 ExcludeFilePat = readFilePatterns(); 519 } 520 521 std::vector<StringRef> V; 522 while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE") 523 V.push_back(next()); 524 525 if (!V.empty()) 526 Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); 527 else 528 setError("section pattern is expected"); 529 } 530 return Ret; 531 } 532 533 // Reads contents of "SECTIONS" directive. That directive contains a 534 // list of glob patterns for input sections. The grammar is as follows. 535 // 536 // <patterns> ::= <section-list> 537 // | <sort> "(" <section-list> ")" 538 // | <sort> "(" <sort> "(" <section-list> ")" ")" 539 // 540 // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 541 // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 542 // 543 // <section-list> is parsed by readInputSectionsList(). 544 InputSectionDescription * 545 ScriptParser::readInputSectionRules(StringRef FilePattern) { 546 auto *Cmd = make<InputSectionDescription>(FilePattern); 547 expect("("); 548 549 while (!errorCount() && !consume(")")) { 550 SortSectionPolicy Outer = readSortKind(); 551 SortSectionPolicy Inner = SortSectionPolicy::Default; 552 std::vector<SectionPattern> V; 553 if (Outer != SortSectionPolicy::Default) { 554 expect("("); 555 Inner = readSortKind(); 556 if (Inner != SortSectionPolicy::Default) { 557 expect("("); 558 V = readInputSectionsList(); 559 expect(")"); 560 } else { 561 V = readInputSectionsList(); 562 } 563 expect(")"); 564 } else { 565 V = readInputSectionsList(); 566 } 567 568 for (SectionPattern &Pat : V) { 569 Pat.SortInner = Inner; 570 Pat.SortOuter = Outer; 571 } 572 573 std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 574 } 575 return Cmd; 576 } 577 578 InputSectionDescription * 579 ScriptParser::readInputSectionDescription(StringRef Tok) { 580 // Input section wildcard can be surrounded by KEEP. 581 // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 582 if (Tok == "KEEP") { 583 expect("("); 584 StringRef FilePattern = next(); 585 InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 586 expect(")"); 587 Script->KeptSections.push_back(Cmd); 588 return Cmd; 589 } 590 return readInputSectionRules(Tok); 591 } 592 593 void ScriptParser::readSort() { 594 expect("("); 595 expect("CONSTRUCTORS"); 596 expect(")"); 597 } 598 599 AssertCommand *ScriptParser::readAssert() { 600 return make<AssertCommand>(readAssertExpr()); 601 } 602 603 Expr ScriptParser::readAssertExpr() { 604 expect("("); 605 Expr E = readExpr(); 606 expect(","); 607 StringRef Msg = unquote(next()); 608 expect(")"); 609 610 return [=] { 611 if (!E().getValue()) 612 error(Msg); 613 return Script->getDot(); 614 }; 615 } 616 617 // Reads a FILL(expr) command. We handle the FILL command as an 618 // alias for =fillexp section attribute, which is different from 619 // what GNU linkers do. 620 // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 621 uint32_t ScriptParser::readFill() { 622 expect("("); 623 uint32_t V = parseFill(next()); 624 expect(")"); 625 return V; 626 } 627 628 // Reads an expression and/or the special directive for an output 629 // section definition. Directive is one of following: "(NOLOAD)", 630 // "(COPY)", "(INFO)" or "(OVERLAY)". 631 // 632 // An output section name can be followed by an address expression 633 // and/or directive. This grammar is not LL(1) because "(" can be 634 // interpreted as either the beginning of some expression or beginning 635 // of directive. 636 // 637 // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html 638 // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html 639 void ScriptParser::readSectionAddressType(OutputSection *Cmd) { 640 if (consume("(")) { 641 if (consume("NOLOAD")) { 642 expect(")"); 643 Cmd->Noload = true; 644 return; 645 } 646 if (consume("COPY") || consume("INFO") || consume("OVERLAY")) { 647 expect(")"); 648 Cmd->NonAlloc = true; 649 return; 650 } 651 Cmd->AddrExpr = readExpr(); 652 expect(")"); 653 } else { 654 Cmd->AddrExpr = readExpr(); 655 } 656 657 if (consume("(")) { 658 expect("NOLOAD"); 659 expect(")"); 660 Cmd->Noload = true; 661 } 662 } 663 664 static Expr checkAlignment(Expr E, std::string &Loc) { 665 return [=] { 666 uint64_t Alignment = std::max((uint64_t)1, E().getValue()); 667 if (!isPowerOf2_64(Alignment)) { 668 error(Loc + ": alignment must be power of 2"); 669 return (uint64_t)1; // Return a dummy value. 670 } 671 return Alignment; 672 }; 673 } 674 675 OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { 676 OutputSection *Cmd = 677 Script->createOutputSection(OutSec, getCurrentLocation()); 678 679 size_t SymbolsReferenced = Script->ReferencedSymbols.size(); 680 681 if (peek() != ":") 682 readSectionAddressType(Cmd); 683 expect(":"); 684 685 std::string Location = getCurrentLocation(); 686 if (consume("AT")) 687 Cmd->LMAExpr = readParenExpr(); 688 if (consume("ALIGN")) 689 Cmd->AlignExpr = checkAlignment(readParenExpr(), Location); 690 if (consume("SUBALIGN")) 691 Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location); 692 693 // Parse constraints. 694 if (consume("ONLY_IF_RO")) 695 Cmd->Constraint = ConstraintKind::ReadOnly; 696 if (consume("ONLY_IF_RW")) 697 Cmd->Constraint = ConstraintKind::ReadWrite; 698 expect("{"); 699 700 while (!errorCount() && !consume("}")) { 701 StringRef Tok = next(); 702 if (Tok == ";") { 703 // Empty commands are allowed. Do nothing here. 704 } else if (SymbolAssignment *Assign = readProvideOrAssignment(Tok)) { 705 Cmd->SectionCommands.push_back(Assign); 706 } else if (ByteCommand *Data = readByteCommand(Tok)) { 707 Cmd->SectionCommands.push_back(Data); 708 } else if (Tok == "ASSERT") { 709 Cmd->SectionCommands.push_back(readAssert()); 710 expect(";"); 711 } else if (Tok == "CONSTRUCTORS") { 712 // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors 713 // by name. This is for very old file formats such as ECOFF/XCOFF. 714 // For ELF, we should ignore. 715 } else if (Tok == "FILL") { 716 Cmd->Filler = readFill(); 717 } else if (Tok == "SORT") { 718 readSort(); 719 } else if (peek() == "(") { 720 Cmd->SectionCommands.push_back(readInputSectionDescription(Tok)); 721 } else { 722 setError("unknown command " + Tok); 723 } 724 } 725 726 if (consume(">")) 727 Cmd->MemoryRegionName = next(); 728 729 if (consume("AT")) { 730 expect(">"); 731 Cmd->LMARegionName = next(); 732 } 733 734 if (Cmd->LMAExpr && !Cmd->LMARegionName.empty()) 735 error("section can't have both LMA and a load region"); 736 737 Cmd->Phdrs = readOutputSectionPhdrs(); 738 739 if (consume("=")) 740 Cmd->Filler = parseFill(next()); 741 else if (peek().startswith("=")) 742 Cmd->Filler = parseFill(next().drop_front()); 743 744 // Consume optional comma following output section command. 745 consume(","); 746 747 if (Script->ReferencedSymbols.size() > SymbolsReferenced) 748 Cmd->ExpressionsUseSymbols = true; 749 return Cmd; 750 } 751 752 // Parses a given string as a octal/decimal/hexadecimal number and 753 // returns it as a big-endian number. Used for `=<fillexp>`. 754 // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 755 // 756 // When reading a hexstring, ld.bfd handles it as a blob of arbitrary 757 // size, while ld.gold always handles it as a 32-bit big-endian number. 758 // We are compatible with ld.gold because it's easier to implement. 759 uint32_t ScriptParser::parseFill(StringRef Tok) { 760 uint32_t V = 0; 761 if (!to_integer(Tok, V)) 762 setError("invalid filler expression: " + Tok); 763 764 uint32_t Buf; 765 write32be(&Buf, V); 766 return Buf; 767 } 768 769 SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 770 expect("("); 771 SymbolAssignment *Cmd = readAssignment(next()); 772 Cmd->Provide = Provide; 773 Cmd->Hidden = Hidden; 774 expect(")"); 775 return Cmd; 776 } 777 778 SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 779 size_t OldPos = Pos; 780 SymbolAssignment *Cmd = nullptr; 781 if (peek() == "=" || peek() == "+=") 782 Cmd = readAssignment(Tok); 783 else if (Tok == "PROVIDE") 784 Cmd = readProvideHidden(true, false); 785 else if (Tok == "HIDDEN") 786 Cmd = readProvideHidden(false, true); 787 else if (Tok == "PROVIDE_HIDDEN") 788 Cmd = readProvideHidden(true, true); 789 790 if (Cmd) { 791 Cmd->CommandString = 792 Tok.str() + " " + 793 llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " "); 794 expect(";"); 795 } 796 return Cmd; 797 } 798 799 SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 800 StringRef Op = next(); 801 assert(Op == "=" || Op == "+="); 802 Expr E = readExpr(); 803 if (Op == "+=") { 804 std::string Loc = getCurrentLocation(); 805 E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); }; 806 } 807 return make<SymbolAssignment>(Name, E, getCurrentLocation()); 808 } 809 810 // This is an operator-precedence parser to parse a linker 811 // script expression. 812 Expr ScriptParser::readExpr() { 813 // Our lexer is context-aware. Set the in-expression bit so that 814 // they apply different tokenization rules. 815 bool Orig = InExpr; 816 InExpr = true; 817 Expr E = readExpr1(readPrimary(), 0); 818 InExpr = Orig; 819 return E; 820 } 821 822 Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) { 823 if (Op == "+") 824 return [=] { return add(L(), R()); }; 825 if (Op == "-") 826 return [=] { return sub(L(), R()); }; 827 if (Op == "*") 828 return [=] { return L().getValue() * R().getValue(); }; 829 if (Op == "/") { 830 std::string Loc = getCurrentLocation(); 831 return [=]() -> uint64_t { 832 if (uint64_t RV = R().getValue()) 833 return L().getValue() / RV; 834 error(Loc + ": division by zero"); 835 return 0; 836 }; 837 } 838 if (Op == "%") { 839 std::string Loc = getCurrentLocation(); 840 return [=]() -> uint64_t { 841 if (uint64_t RV = R().getValue()) 842 return L().getValue() % RV; 843 error(Loc + ": modulo by zero"); 844 return 0; 845 }; 846 } 847 if (Op == "<<") 848 return [=] { return L().getValue() << R().getValue(); }; 849 if (Op == ">>") 850 return [=] { return L().getValue() >> R().getValue(); }; 851 if (Op == "<") 852 return [=] { return L().getValue() < R().getValue(); }; 853 if (Op == ">") 854 return [=] { return L().getValue() > R().getValue(); }; 855 if (Op == ">=") 856 return [=] { return L().getValue() >= R().getValue(); }; 857 if (Op == "<=") 858 return [=] { return L().getValue() <= R().getValue(); }; 859 if (Op == "==") 860 return [=] { return L().getValue() == R().getValue(); }; 861 if (Op == "!=") 862 return [=] { return L().getValue() != R().getValue(); }; 863 if (Op == "&") 864 return [=] { return bitAnd(L(), R()); }; 865 if (Op == "|") 866 return [=] { return bitOr(L(), R()); }; 867 llvm_unreachable("invalid operator"); 868 } 869 870 // This is a part of the operator-precedence parser. This function 871 // assumes that the remaining token stream starts with an operator. 872 Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 873 while (!atEOF() && !errorCount()) { 874 // Read an operator and an expression. 875 if (consume("?")) 876 return readTernary(Lhs); 877 StringRef Op1 = peek(); 878 if (precedence(Op1) < MinPrec) 879 break; 880 skip(); 881 Expr Rhs = readPrimary(); 882 883 // Evaluate the remaining part of the expression first if the 884 // next operator has greater precedence than the previous one. 885 // For example, if we have read "+" and "3", and if the next 886 // operator is "*", then we'll evaluate 3 * ... part first. 887 while (!atEOF()) { 888 StringRef Op2 = peek(); 889 if (precedence(Op2) <= precedence(Op1)) 890 break; 891 Rhs = readExpr1(Rhs, precedence(Op2)); 892 } 893 894 Lhs = combine(Op1, Lhs, Rhs); 895 } 896 return Lhs; 897 } 898 899 Expr ScriptParser::getPageSize() { 900 std::string Location = getCurrentLocation(); 901 return [=]() -> uint64_t { 902 if (Target) 903 return Target->PageSize; 904 error(Location + ": unable to calculate page size"); 905 return 4096; // Return a dummy value. 906 }; 907 } 908 909 Expr ScriptParser::readConstant() { 910 StringRef S = readParenLiteral(); 911 if (S == "COMMONPAGESIZE") 912 return getPageSize(); 913 if (S == "MAXPAGESIZE") 914 return [] { return Config->MaxPageSize; }; 915 setError("unknown constant: " + S); 916 return [] { return 0; }; 917 } 918 919 // Parses Tok as an integer. It recognizes hexadecimal (prefixed with 920 // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may 921 // have "K" (Ki) or "M" (Mi) suffixes. 922 static Optional<uint64_t> parseInt(StringRef Tok) { 923 // Hexadecimal 924 uint64_t Val; 925 if (Tok.startswith_lower("0x")) { 926 if (!to_integer(Tok.substr(2), Val, 16)) 927 return None; 928 return Val; 929 } 930 if (Tok.endswith_lower("H")) { 931 if (!to_integer(Tok.drop_back(), Val, 16)) 932 return None; 933 return Val; 934 } 935 936 // Decimal 937 if (Tok.endswith_lower("K")) { 938 if (!to_integer(Tok.drop_back(), Val, 10)) 939 return None; 940 return Val * 1024; 941 } 942 if (Tok.endswith_lower("M")) { 943 if (!to_integer(Tok.drop_back(), Val, 10)) 944 return None; 945 return Val * 1024 * 1024; 946 } 947 if (!to_integer(Tok, Val, 10)) 948 return None; 949 return Val; 950 } 951 952 ByteCommand *ScriptParser::readByteCommand(StringRef Tok) { 953 int Size = StringSwitch<int>(Tok) 954 .Case("BYTE", 1) 955 .Case("SHORT", 2) 956 .Case("LONG", 4) 957 .Case("QUAD", 8) 958 .Default(-1); 959 if (Size == -1) 960 return nullptr; 961 962 size_t OldPos = Pos; 963 Expr E = readParenExpr(); 964 std::string CommandString = 965 Tok.str() + " " + 966 llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " "); 967 return make<ByteCommand>(E, Size, CommandString); 968 } 969 970 StringRef ScriptParser::readParenLiteral() { 971 expect("("); 972 bool Orig = InExpr; 973 InExpr = false; 974 StringRef Tok = next(); 975 InExpr = Orig; 976 expect(")"); 977 return Tok; 978 } 979 980 static void checkIfExists(OutputSection *Cmd, StringRef Location) { 981 if (Cmd->Location.empty() && Script->ErrorOnMissingSection) 982 error(Location + ": undefined section " + Cmd->Name); 983 } 984 985 Expr ScriptParser::readPrimary() { 986 if (peek() == "(") 987 return readParenExpr(); 988 989 if (consume("~")) { 990 Expr E = readPrimary(); 991 return [=] { return ~E().getValue(); }; 992 } 993 if (consume("!")) { 994 Expr E = readPrimary(); 995 return [=] { return !E().getValue(); }; 996 } 997 if (consume("-")) { 998 Expr E = readPrimary(); 999 return [=] { return -E().getValue(); }; 1000 } 1001 1002 StringRef Tok = next(); 1003 std::string Location = getCurrentLocation(); 1004 1005 // Built-in functions are parsed here. 1006 // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 1007 if (Tok == "ABSOLUTE") { 1008 Expr Inner = readParenExpr(); 1009 return [=] { 1010 ExprValue I = Inner(); 1011 I.ForceAbsolute = true; 1012 return I; 1013 }; 1014 } 1015 if (Tok == "ADDR") { 1016 StringRef Name = readParenLiteral(); 1017 OutputSection *Sec = Script->getOrCreateOutputSection(Name); 1018 return [=]() -> ExprValue { 1019 checkIfExists(Sec, Location); 1020 return {Sec, false, 0, Location}; 1021 }; 1022 } 1023 if (Tok == "ALIGN") { 1024 expect("("); 1025 Expr E = readExpr(); 1026 if (consume(")")) { 1027 E = checkAlignment(E, Location); 1028 return [=] { return alignTo(Script->getDot(), E().getValue()); }; 1029 } 1030 expect(","); 1031 Expr E2 = checkAlignment(readExpr(), Location); 1032 expect(")"); 1033 return [=] { 1034 ExprValue V = E(); 1035 V.Alignment = E2().getValue(); 1036 return V; 1037 }; 1038 } 1039 if (Tok == "ALIGNOF") { 1040 StringRef Name = readParenLiteral(); 1041 OutputSection *Cmd = Script->getOrCreateOutputSection(Name); 1042 return [=] { 1043 checkIfExists(Cmd, Location); 1044 return Cmd->Alignment; 1045 }; 1046 } 1047 if (Tok == "ASSERT") 1048 return readAssertExpr(); 1049 if (Tok == "CONSTANT") 1050 return readConstant(); 1051 if (Tok == "DATA_SEGMENT_ALIGN") { 1052 expect("("); 1053 Expr E = readExpr(); 1054 expect(","); 1055 readExpr(); 1056 expect(")"); 1057 return [=] { 1058 return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue())); 1059 }; 1060 } 1061 if (Tok == "DATA_SEGMENT_END") { 1062 expect("("); 1063 expect("."); 1064 expect(")"); 1065 return [] { return Script->getDot(); }; 1066 } 1067 if (Tok == "DATA_SEGMENT_RELRO_END") { 1068 // GNU linkers implements more complicated logic to handle 1069 // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and 1070 // just align to the next page boundary for simplicity. 1071 expect("("); 1072 readExpr(); 1073 expect(","); 1074 readExpr(); 1075 expect(")"); 1076 Expr E = getPageSize(); 1077 return [=] { return alignTo(Script->getDot(), E().getValue()); }; 1078 } 1079 if (Tok == "DEFINED") { 1080 StringRef Name = readParenLiteral(); 1081 return [=] { return Symtab->find(Name) ? 1 : 0; }; 1082 } 1083 if (Tok == "LENGTH") { 1084 StringRef Name = readParenLiteral(); 1085 if (Script->MemoryRegions.count(Name) == 0) { 1086 setError("memory region not defined: " + Name); 1087 return [] { return 0; }; 1088 } 1089 return [=] { return Script->MemoryRegions[Name]->Length; }; 1090 } 1091 if (Tok == "LOADADDR") { 1092 StringRef Name = readParenLiteral(); 1093 OutputSection *Cmd = Script->getOrCreateOutputSection(Name); 1094 return [=] { 1095 checkIfExists(Cmd, Location); 1096 return Cmd->getLMA(); 1097 }; 1098 } 1099 if (Tok == "MAX" || Tok == "MIN") { 1100 expect("("); 1101 Expr A = readExpr(); 1102 expect(","); 1103 Expr B = readExpr(); 1104 expect(")"); 1105 if (Tok == "MIN") 1106 return [=] { return std::min(A().getValue(), B().getValue()); }; 1107 return [=] { return std::max(A().getValue(), B().getValue()); }; 1108 } 1109 if (Tok == "ORIGIN") { 1110 StringRef Name = readParenLiteral(); 1111 if (Script->MemoryRegions.count(Name) == 0) { 1112 setError("memory region not defined: " + Name); 1113 return [] { return 0; }; 1114 } 1115 return [=] { return Script->MemoryRegions[Name]->Origin; }; 1116 } 1117 if (Tok == "SEGMENT_START") { 1118 expect("("); 1119 skip(); 1120 expect(","); 1121 Expr E = readExpr(); 1122 expect(")"); 1123 return [=] { return E(); }; 1124 } 1125 if (Tok == "SIZEOF") { 1126 StringRef Name = readParenLiteral(); 1127 OutputSection *Cmd = Script->getOrCreateOutputSection(Name); 1128 // Linker script does not create an output section if its content is empty. 1129 // We want to allow SIZEOF(.foo) where .foo is a section which happened to 1130 // be empty. 1131 return [=] { return Cmd->Size; }; 1132 } 1133 if (Tok == "SIZEOF_HEADERS") 1134 return [=] { return elf::getHeaderSize(); }; 1135 1136 // Tok is the dot. 1137 if (Tok == ".") 1138 return [=] { return Script->getSymbolValue(Tok, Location); }; 1139 1140 // Tok is a literal number. 1141 if (Optional<uint64_t> Val = parseInt(Tok)) 1142 return [=] { return *Val; }; 1143 1144 // Tok is a symbol name. 1145 if (!isValidCIdentifier(Tok)) 1146 setError("malformed number: " + Tok); 1147 Script->ReferencedSymbols.push_back(Tok); 1148 return [=] { return Script->getSymbolValue(Tok, Location); }; 1149 } 1150 1151 Expr ScriptParser::readTernary(Expr Cond) { 1152 Expr L = readExpr(); 1153 expect(":"); 1154 Expr R = readExpr(); 1155 return [=] { return Cond().getValue() ? L() : R(); }; 1156 } 1157 1158 Expr ScriptParser::readParenExpr() { 1159 expect("("); 1160 Expr E = readExpr(); 1161 expect(")"); 1162 return E; 1163 } 1164 1165 std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 1166 std::vector<StringRef> Phdrs; 1167 while (!errorCount() && peek().startswith(":")) { 1168 StringRef Tok = next(); 1169 Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); 1170 } 1171 return Phdrs; 1172 } 1173 1174 // Read a program header type name. The next token must be a 1175 // name of a program header type or a constant (e.g. "0x3"). 1176 unsigned ScriptParser::readPhdrType() { 1177 StringRef Tok = next(); 1178 if (Optional<uint64_t> Val = parseInt(Tok)) 1179 return *Val; 1180 1181 unsigned Ret = StringSwitch<unsigned>(Tok) 1182 .Case("PT_NULL", PT_NULL) 1183 .Case("PT_LOAD", PT_LOAD) 1184 .Case("PT_DYNAMIC", PT_DYNAMIC) 1185 .Case("PT_INTERP", PT_INTERP) 1186 .Case("PT_NOTE", PT_NOTE) 1187 .Case("PT_SHLIB", PT_SHLIB) 1188 .Case("PT_PHDR", PT_PHDR) 1189 .Case("PT_TLS", PT_TLS) 1190 .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 1191 .Case("PT_GNU_STACK", PT_GNU_STACK) 1192 .Case("PT_GNU_RELRO", PT_GNU_RELRO) 1193 .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 1194 .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 1195 .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) 1196 .Default(-1); 1197 1198 if (Ret == (unsigned)-1) { 1199 setError("invalid program header type: " + Tok); 1200 return PT_NULL; 1201 } 1202 return Ret; 1203 } 1204 1205 // Reads an anonymous version declaration. 1206 void ScriptParser::readAnonymousDeclaration() { 1207 std::vector<SymbolVersion> Locals; 1208 std::vector<SymbolVersion> Globals; 1209 std::tie(Locals, Globals) = readSymbols(); 1210 1211 for (SymbolVersion V : Locals) { 1212 if (V.Name == "*") 1213 Config->DefaultSymbolVersion = VER_NDX_LOCAL; 1214 else 1215 Config->VersionScriptLocals.push_back(V); 1216 } 1217 1218 for (SymbolVersion V : Globals) 1219 Config->VersionScriptGlobals.push_back(V); 1220 1221 expect(";"); 1222 } 1223 1224 // Reads a non-anonymous version definition, 1225 // e.g. "VerStr { global: foo; bar; local: *; };". 1226 void ScriptParser::readVersionDeclaration(StringRef VerStr) { 1227 // Read a symbol list. 1228 std::vector<SymbolVersion> Locals; 1229 std::vector<SymbolVersion> Globals; 1230 std::tie(Locals, Globals) = readSymbols(); 1231 1232 for (SymbolVersion V : Locals) { 1233 if (V.Name == "*") 1234 Config->DefaultSymbolVersion = VER_NDX_LOCAL; 1235 else 1236 Config->VersionScriptLocals.push_back(V); 1237 } 1238 1239 // Create a new version definition and add that to the global symbols. 1240 VersionDefinition Ver; 1241 Ver.Name = VerStr; 1242 Ver.Globals = Globals; 1243 1244 // User-defined version number starts from 2 because 0 and 1 are 1245 // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively. 1246 Ver.Id = Config->VersionDefinitions.size() + 2; 1247 Config->VersionDefinitions.push_back(Ver); 1248 1249 // Each version may have a parent version. For example, "Ver2" 1250 // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 1251 // as a parent. This version hierarchy is, probably against your 1252 // instinct, purely for hint; the runtime doesn't care about it 1253 // at all. In LLD, we simply ignore it. 1254 if (peek() != ";") 1255 skip(); 1256 expect(";"); 1257 } 1258 1259 static bool hasWildcard(StringRef S) { 1260 return S.find_first_of("?*[") != StringRef::npos; 1261 } 1262 1263 // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 1264 std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 1265 ScriptParser::readSymbols() { 1266 std::vector<SymbolVersion> Locals; 1267 std::vector<SymbolVersion> Globals; 1268 std::vector<SymbolVersion> *V = &Globals; 1269 1270 while (!errorCount()) { 1271 if (consume("}")) 1272 break; 1273 if (consumeLabel("local")) { 1274 V = &Locals; 1275 continue; 1276 } 1277 if (consumeLabel("global")) { 1278 V = &Globals; 1279 continue; 1280 } 1281 1282 if (consume("extern")) { 1283 std::vector<SymbolVersion> Ext = readVersionExtern(); 1284 V->insert(V->end(), Ext.begin(), Ext.end()); 1285 } else { 1286 StringRef Tok = next(); 1287 V->push_back({unquote(Tok), false, hasWildcard(Tok)}); 1288 } 1289 expect(";"); 1290 } 1291 return {Locals, Globals}; 1292 } 1293 1294 // Reads an "extern C++" directive, e.g., 1295 // "extern "C++" { ns::*; "f(int, double)"; };" 1296 // 1297 // The last semicolon is optional. E.g. this is OK: 1298 // "extern "C++" { ns::*; "f(int, double)" };" 1299 std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 1300 StringRef Tok = next(); 1301 bool IsCXX = Tok == "\"C++\""; 1302 if (!IsCXX && Tok != "\"C\"") 1303 setError("Unknown language"); 1304 expect("{"); 1305 1306 std::vector<SymbolVersion> Ret; 1307 while (!errorCount() && peek() != "}") { 1308 StringRef Tok = next(); 1309 bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); 1310 Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); 1311 if (consume("}")) 1312 return Ret; 1313 expect(";"); 1314 } 1315 1316 expect("}"); 1317 return Ret; 1318 } 1319 1320 uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2, 1321 StringRef S3) { 1322 if (!consume(S1) && !consume(S2) && !consume(S3)) { 1323 setError("expected one of: " + S1 + ", " + S2 + ", or " + S3); 1324 return 0; 1325 } 1326 expect("="); 1327 return readExpr()().getValue(); 1328 } 1329 1330 // Parse the MEMORY command as specified in: 1331 // https://sourceware.org/binutils/docs/ld/MEMORY.html 1332 // 1333 // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } 1334 void ScriptParser::readMemory() { 1335 expect("{"); 1336 while (!errorCount() && !consume("}")) { 1337 StringRef Name = next(); 1338 1339 uint32_t Flags = 0; 1340 uint32_t NegFlags = 0; 1341 if (consume("(")) { 1342 std::tie(Flags, NegFlags) = readMemoryAttributes(); 1343 expect(")"); 1344 } 1345 expect(":"); 1346 1347 uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o"); 1348 expect(","); 1349 uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); 1350 1351 // Add the memory region to the region map. 1352 MemoryRegion *MR = 1353 make<MemoryRegion>(Name, Origin, Length, Flags, NegFlags); 1354 if (!Script->MemoryRegions.insert({Name, MR}).second) 1355 setError("region '" + Name + "' already defined"); 1356 } 1357 } 1358 1359 // This function parses the attributes used to match against section 1360 // flags when placing output sections in a memory region. These flags 1361 // are only used when an explicit memory region name is not used. 1362 std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { 1363 uint32_t Flags = 0; 1364 uint32_t NegFlags = 0; 1365 bool Invert = false; 1366 1367 for (char C : next().lower()) { 1368 uint32_t Flag = 0; 1369 if (C == '!') 1370 Invert = !Invert; 1371 else if (C == 'w') 1372 Flag = SHF_WRITE; 1373 else if (C == 'x') 1374 Flag = SHF_EXECINSTR; 1375 else if (C == 'a') 1376 Flag = SHF_ALLOC; 1377 else if (C != 'r') 1378 setError("invalid memory region attribute"); 1379 1380 if (Invert) 1381 NegFlags |= Flag; 1382 else 1383 Flags |= Flag; 1384 } 1385 return {Flags, NegFlags}; 1386 } 1387 1388 void elf::readLinkerScript(MemoryBufferRef MB) { 1389 ScriptParser(MB).readLinkerScript(); 1390 } 1391 1392 void elf::readVersionScript(MemoryBufferRef MB) { 1393 ScriptParser(MB).readVersionScript(); 1394 } 1395 1396 void elf::readDynamicList(MemoryBufferRef MB) { 1397 ScriptParser(MB).readDynamicList(); 1398 } 1399 1400 void elf::readDefsym(StringRef Name, MemoryBufferRef MB) { 1401 ScriptParser(MB).readDefsym(Name); 1402 } 1403