1 //===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/ScopeExit.h" 10 #include "llvm/ADT/StringExtras.h" 11 #include "llvm/ADT/StringRef.h" 12 #include "llvm/ADT/StringSwitch.h" 13 #include "llvm/BinaryFormat/ELF.h" 14 #include "llvm/MC/MCAsmInfo.h" 15 #include "llvm/MC/MCContext.h" 16 #include "llvm/MC/MCDirectives.h" 17 #include "llvm/MC/MCParser/AsmLexer.h" 18 #include "llvm/MC/MCParser/MCAsmParser.h" 19 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 20 #include "llvm/MC/MCSectionELF.h" 21 #include "llvm/MC/MCStreamer.h" 22 #include "llvm/MC/MCSymbol.h" 23 #include "llvm/MC/MCSymbolELF.h" 24 #include "llvm/MC/SectionKind.h" 25 #include "llvm/Support/Casting.h" 26 #include "llvm/Support/SMLoc.h" 27 #include <cassert> 28 #include <cstdint> 29 #include <utility> 30 31 using namespace llvm; 32 33 namespace { 34 35 class ELFAsmParser : public MCAsmParserExtension { 36 template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)> 37 void addDirectiveHandler(StringRef Directive) { 38 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( 39 this, HandleDirective<ELFAsmParser, HandlerMethod>); 40 41 getParser().addDirectiveHandler(Directive, Handler); 42 } 43 44 bool parseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, 45 SectionKind Kind); 46 47 public: 48 ELFAsmParser() { BracketExpressionsSupported = true; } 49 50 void Initialize(MCAsmParser &Parser) override { 51 // Call the base implementation. 52 this->MCAsmParserExtension::Initialize(Parser); 53 54 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveData>(".data"); 55 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveText>(".text"); 56 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveBSS>(".bss"); 57 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveRoData>(".rodata"); 58 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveTData>(".tdata"); 59 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveTBSS>(".tbss"); 60 addDirectiveHandler<&ELFAsmParser::parseDirectiveSection>(".section"); 61 addDirectiveHandler< 62 &ELFAsmParser::parseDirectivePushSection>(".pushsection"); 63 addDirectiveHandler<&ELFAsmParser::parseDirectivePopSection>(".popsection"); 64 addDirectiveHandler<&ELFAsmParser::parseDirectiveSize>(".size"); 65 addDirectiveHandler<&ELFAsmParser::parseDirectivePrevious>(".previous"); 66 addDirectiveHandler<&ELFAsmParser::parseDirectiveType>(".type"); 67 addDirectiveHandler<&ELFAsmParser::parseDirectiveIdent>(".ident"); 68 addDirectiveHandler<&ELFAsmParser::parseDirectiveSymver>(".symver"); 69 addDirectiveHandler<&ELFAsmParser::parseDirectiveVersion>(".version"); 70 addDirectiveHandler<&ELFAsmParser::parseDirectiveWeakref>(".weakref"); 71 addDirectiveHandler<&ELFAsmParser::parseDirectiveSymbolAttribute>(".weak"); 72 addDirectiveHandler<&ELFAsmParser::parseDirectiveSymbolAttribute>(".local"); 73 addDirectiveHandler< 74 &ELFAsmParser::parseDirectiveSymbolAttribute>(".protected"); 75 addDirectiveHandler< 76 &ELFAsmParser::parseDirectiveSymbolAttribute>(".internal"); 77 addDirectiveHandler< 78 &ELFAsmParser::parseDirectiveSymbolAttribute>(".hidden"); 79 addDirectiveHandler<&ELFAsmParser::parseDirectiveSubsection>(".subsection"); 80 addDirectiveHandler<&ELFAsmParser::parseDirectiveCGProfile>(".cg_profile"); 81 } 82 83 // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is 84 // the best way for us to get access to it? 85 bool parseSectionDirectiveData(StringRef, SMLoc) { 86 return parseSectionSwitch(".data", ELF::SHT_PROGBITS, 87 ELF::SHF_WRITE | ELF::SHF_ALLOC, 88 SectionKind::getData()); 89 } 90 bool parseSectionDirectiveText(StringRef, SMLoc) { 91 return parseSectionSwitch(".text", ELF::SHT_PROGBITS, 92 ELF::SHF_EXECINSTR | 93 ELF::SHF_ALLOC, SectionKind::getText()); 94 } 95 bool parseSectionDirectiveBSS(StringRef, SMLoc) { 96 return parseSectionSwitch(".bss", ELF::SHT_NOBITS, 97 ELF::SHF_WRITE | 98 ELF::SHF_ALLOC, SectionKind::getBSS()); 99 } 100 bool parseSectionDirectiveRoData(StringRef, SMLoc) { 101 return parseSectionSwitch(".rodata", ELF::SHT_PROGBITS, 102 ELF::SHF_ALLOC, 103 SectionKind::getReadOnly()); 104 } 105 bool parseSectionDirectiveTData(StringRef, SMLoc) { 106 return parseSectionSwitch(".tdata", ELF::SHT_PROGBITS, 107 ELF::SHF_ALLOC | 108 ELF::SHF_TLS | ELF::SHF_WRITE, 109 SectionKind::getThreadData()); 110 } 111 bool parseSectionDirectiveTBSS(StringRef, SMLoc) { 112 return parseSectionSwitch(".tbss", ELF::SHT_NOBITS, 113 ELF::SHF_ALLOC | 114 ELF::SHF_TLS | ELF::SHF_WRITE, 115 SectionKind::getThreadBSS()); 116 } 117 bool parseDirectivePushSection(StringRef, SMLoc); 118 bool parseDirectivePopSection(StringRef, SMLoc); 119 bool parseDirectiveSection(StringRef, SMLoc); 120 bool parseDirectiveSize(StringRef, SMLoc); 121 bool parseDirectivePrevious(StringRef, SMLoc); 122 bool parseDirectiveType(StringRef, SMLoc); 123 bool parseDirectiveIdent(StringRef, SMLoc); 124 bool parseDirectiveSymver(StringRef, SMLoc); 125 bool parseDirectiveVersion(StringRef, SMLoc); 126 bool parseDirectiveWeakref(StringRef, SMLoc); 127 bool parseDirectiveSymbolAttribute(StringRef, SMLoc); 128 bool parseDirectiveSubsection(StringRef, SMLoc); 129 bool parseDirectiveCGProfile(StringRef, SMLoc); 130 131 private: 132 bool parseSectionName(StringRef &SectionName); 133 bool parseSectionArguments(bool IsPush, SMLoc loc); 134 unsigned parseSunStyleSectionFlags(); 135 bool maybeParseSectionType(StringRef &TypeName); 136 bool parseMergeSize(int64_t &Size); 137 bool parseGroup(StringRef &GroupName, bool &IsComdat); 138 bool parseLinkedToSym(MCSymbolELF *&LinkedToSym); 139 }; 140 141 } // end anonymous namespace 142 143 /// parseDirectiveSymbolAttribute 144 /// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] 145 bool ELFAsmParser::parseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { 146 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) 147 .Case(".weak", MCSA_Weak) 148 .Case(".local", MCSA_Local) 149 .Case(".hidden", MCSA_Hidden) 150 .Case(".internal", MCSA_Internal) 151 .Case(".protected", MCSA_Protected) 152 .Default(MCSA_Invalid); 153 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); 154 if (getLexer().isNot(AsmToken::EndOfStatement)) { 155 while (true) { 156 StringRef Name; 157 158 if (getParser().parseIdentifier(Name)) 159 return TokError("expected identifier"); 160 161 if (getParser().discardLTOSymbol(Name)) { 162 if (getLexer().is(AsmToken::EndOfStatement)) 163 break; 164 continue; 165 } 166 167 MCSymbol *Sym = getContext().parseSymbol(Name); 168 169 getStreamer().emitSymbolAttribute(Sym, Attr); 170 171 if (getLexer().is(AsmToken::EndOfStatement)) 172 break; 173 174 if (getLexer().isNot(AsmToken::Comma)) 175 return TokError("expected comma"); 176 Lex(); 177 } 178 } 179 180 Lex(); 181 return false; 182 } 183 184 bool ELFAsmParser::parseSectionSwitch(StringRef Section, unsigned Type, 185 unsigned Flags, SectionKind Kind) { 186 const MCExpr *Subsection = nullptr; 187 if (getLexer().isNot(AsmToken::EndOfStatement)) { 188 if (getParser().parseExpression(Subsection)) 189 return true; 190 } 191 Lex(); 192 193 getStreamer().switchSection(getContext().getELFSection(Section, Type, Flags), 194 Subsection); 195 196 return false; 197 } 198 199 bool ELFAsmParser::parseDirectiveSize(StringRef, SMLoc) { 200 MCSymbol *Sym; 201 if (getParser().parseSymbol(Sym)) 202 return TokError("expected identifier"); 203 204 if (getLexer().isNot(AsmToken::Comma)) 205 return TokError("expected comma"); 206 Lex(); 207 208 const MCExpr *Expr; 209 if (getParser().parseExpression(Expr)) 210 return true; 211 212 if (getLexer().isNot(AsmToken::EndOfStatement)) 213 return TokError("unexpected token"); 214 Lex(); 215 216 getStreamer().emitELFSize(Sym, Expr); 217 return false; 218 } 219 220 bool ELFAsmParser::parseSectionName(StringRef &SectionName) { 221 // A section name can contain -, so we cannot just use 222 // parseIdentifier. 223 SMLoc FirstLoc = getLexer().getLoc(); 224 unsigned Size = 0; 225 226 if (getLexer().is(AsmToken::String)) { 227 SectionName = getTok().getIdentifier(); 228 Lex(); 229 return false; 230 } 231 232 while (!getParser().hasPendingError()) { 233 SMLoc PrevLoc = getLexer().getLoc(); 234 if (getLexer().is(AsmToken::Comma) || 235 getLexer().is(AsmToken::EndOfStatement)) 236 break; 237 238 unsigned CurSize; 239 if (getLexer().is(AsmToken::String)) { 240 CurSize = getTok().getIdentifier().size() + 2; 241 Lex(); 242 } else if (getLexer().is(AsmToken::Identifier)) { 243 CurSize = getTok().getIdentifier().size(); 244 Lex(); 245 } else { 246 CurSize = getTok().getString().size(); 247 Lex(); 248 } 249 Size += CurSize; 250 SectionName = StringRef(FirstLoc.getPointer(), Size); 251 252 // Make sure the following token is adjacent. 253 if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer()) 254 break; 255 } 256 if (Size == 0) 257 return true; 258 259 return false; 260 } 261 262 static unsigned parseSectionFlags(const Triple &TT, StringRef flagsStr, 263 bool *UseLastGroup) { 264 unsigned flags = 0; 265 266 // If a valid numerical value is set for the section flag, use it verbatim 267 if (!flagsStr.getAsInteger(0, flags)) 268 return flags; 269 270 for (char i : flagsStr) { 271 switch (i) { 272 case 'a': 273 flags |= ELF::SHF_ALLOC; 274 break; 275 case 'e': 276 flags |= ELF::SHF_EXCLUDE; 277 break; 278 case 'x': 279 flags |= ELF::SHF_EXECINSTR; 280 break; 281 case 'w': 282 flags |= ELF::SHF_WRITE; 283 break; 284 case 'o': 285 flags |= ELF::SHF_LINK_ORDER; 286 break; 287 case 'M': 288 flags |= ELF::SHF_MERGE; 289 break; 290 case 'S': 291 flags |= ELF::SHF_STRINGS; 292 break; 293 case 'T': 294 flags |= ELF::SHF_TLS; 295 break; 296 case 'c': 297 if (TT.getArch() != Triple::xcore) 298 return -1U; 299 flags |= ELF::XCORE_SHF_CP_SECTION; 300 break; 301 case 'd': 302 if (TT.getArch() != Triple::xcore) 303 return -1U; 304 flags |= ELF::XCORE_SHF_DP_SECTION; 305 break; 306 case 'y': 307 if (TT.isARM() || TT.isThumb()) 308 flags |= ELF::SHF_ARM_PURECODE; 309 else if (TT.isAArch64()) 310 flags |= ELF::SHF_AARCH64_PURECODE; 311 else 312 return -1U; 313 break; 314 case 's': 315 if (TT.getArch() != Triple::hexagon) 316 return -1U; 317 flags |= ELF::SHF_HEX_GPREL; 318 break; 319 case 'G': 320 flags |= ELF::SHF_GROUP; 321 break; 322 case 'l': 323 if (TT.getArch() != Triple::x86_64) 324 return -1U; 325 flags |= ELF::SHF_X86_64_LARGE; 326 break; 327 case 'R': 328 if (TT.isOSSolaris()) 329 flags |= ELF::SHF_SUNW_NODISCARD; 330 else 331 flags |= ELF::SHF_GNU_RETAIN; 332 break; 333 case '?': 334 *UseLastGroup = true; 335 break; 336 default: 337 return -1U; 338 } 339 } 340 341 return flags; 342 } 343 344 unsigned ELFAsmParser::parseSunStyleSectionFlags() { 345 unsigned flags = 0; 346 while (getLexer().is(AsmToken::Hash)) { 347 Lex(); // Eat the #. 348 349 if (!getLexer().is(AsmToken::Identifier)) 350 return -1U; 351 352 StringRef flagId = getTok().getIdentifier(); 353 if (flagId == "alloc") 354 flags |= ELF::SHF_ALLOC; 355 else if (flagId == "execinstr") 356 flags |= ELF::SHF_EXECINSTR; 357 else if (flagId == "write") 358 flags |= ELF::SHF_WRITE; 359 else if (flagId == "tls") 360 flags |= ELF::SHF_TLS; 361 else 362 return -1U; 363 364 Lex(); // Eat the flag. 365 366 if (!getLexer().is(AsmToken::Comma)) 367 break; 368 Lex(); // Eat the comma. 369 } 370 return flags; 371 } 372 373 374 bool ELFAsmParser::parseDirectivePushSection(StringRef s, SMLoc loc) { 375 getStreamer().pushSection(); 376 377 if (parseSectionArguments(/*IsPush=*/true, loc)) { 378 getStreamer().popSection(); 379 return true; 380 } 381 382 return false; 383 } 384 385 bool ELFAsmParser::parseDirectivePopSection(StringRef, SMLoc) { 386 if (!getStreamer().popSection()) 387 return TokError(".popsection without corresponding .pushsection"); 388 return false; 389 } 390 391 bool ELFAsmParser::parseDirectiveSection(StringRef, SMLoc loc) { 392 return parseSectionArguments(/*IsPush=*/false, loc); 393 } 394 395 bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) { 396 AsmLexer &L = getLexer(); 397 if (L.isNot(AsmToken::Comma)) 398 return false; 399 Lex(); 400 if (L.isNot(AsmToken::At) && L.isNot(AsmToken::Percent) && 401 L.isNot(AsmToken::String)) { 402 if (getContext().getAsmInfo()->getCommentString().starts_with('@')) 403 return TokError("expected '%<type>' or \"<type>\""); 404 else 405 return TokError("expected '@<type>', '%<type>' or \"<type>\""); 406 } 407 if (!L.is(AsmToken::String)) 408 Lex(); 409 if (L.is(AsmToken::Integer)) { 410 TypeName = getTok().getString(); 411 Lex(); 412 } else if (getParser().parseIdentifier(TypeName)) 413 return TokError("expected identifier"); 414 return false; 415 } 416 417 bool ELFAsmParser::parseMergeSize(int64_t &Size) { 418 if (getLexer().isNot(AsmToken::Comma)) 419 return TokError("expected the entry size"); 420 Lex(); 421 if (getParser().parseAbsoluteExpression(Size)) 422 return true; 423 if (Size <= 0) 424 return TokError("entry size must be positive"); 425 return false; 426 } 427 428 bool ELFAsmParser::parseGroup(StringRef &GroupName, bool &IsComdat) { 429 AsmLexer &L = getLexer(); 430 if (L.isNot(AsmToken::Comma)) 431 return TokError("expected group name"); 432 Lex(); 433 if (L.is(AsmToken::Integer)) { 434 GroupName = getTok().getString(); 435 Lex(); 436 } else if (getParser().parseIdentifier(GroupName)) { 437 return TokError("invalid group name"); 438 } 439 if (L.is(AsmToken::Comma)) { 440 Lex(); 441 StringRef Linkage; 442 if (getParser().parseIdentifier(Linkage)) 443 return TokError("invalid linkage"); 444 if (Linkage != "comdat") 445 return TokError("Linkage must be 'comdat'"); 446 IsComdat = true; 447 } else { 448 IsComdat = false; 449 } 450 return false; 451 } 452 453 bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) { 454 AsmLexer &L = getLexer(); 455 if (L.isNot(AsmToken::Comma)) 456 return TokError("expected linked-to symbol"); 457 Lex(); 458 StringRef Name; 459 SMLoc StartLoc = L.getLoc(); 460 if (getParser().parseIdentifier(Name)) { 461 if (getParser().getTok().getString() == "0") { 462 getParser().Lex(); 463 LinkedToSym = nullptr; 464 return false; 465 } 466 return TokError("invalid linked-to symbol"); 467 } 468 LinkedToSym = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name)); 469 if (!LinkedToSym || !LinkedToSym->isInSection()) 470 return Error(StartLoc, "linked-to symbol is not in a section: " + Name); 471 return false; 472 } 473 474 static bool hasPrefix(StringRef SectionName, StringRef Prefix) { 475 return SectionName.consume_front(Prefix) && 476 (SectionName.empty() || SectionName[0] == '.'); 477 } 478 479 static bool allowSectionTypeMismatch(const Triple &TT, StringRef SectionName, 480 unsigned Type) { 481 if (TT.getArch() == Triple::x86_64) { 482 // x86-64 psABI names SHT_X86_64_UNWIND as the canonical type for .eh_frame, 483 // but GNU as emits SHT_PROGBITS .eh_frame for .cfi_* directives. Don't 484 // error for SHT_PROGBITS .eh_frame 485 return SectionName == ".eh_frame" && Type == ELF::SHT_PROGBITS; 486 } 487 if (TT.isMIPS()) { 488 // MIPS .debug_* sections should have SHT_MIPS_DWARF section type to 489 // distinguish among sections contain DWARF and ECOFF debug formats, 490 // but in assembly files these sections have SHT_PROGBITS type. 491 return SectionName.starts_with(".debug_") && Type == ELF::SHT_PROGBITS; 492 } 493 return false; 494 } 495 496 bool ELFAsmParser::parseSectionArguments(bool IsPush, SMLoc loc) { 497 StringRef SectionName; 498 499 if (parseSectionName(SectionName)) 500 return TokError("expected identifier"); 501 502 StringRef TypeName; 503 int64_t Size = 0; 504 StringRef GroupName; 505 bool IsComdat = false; 506 unsigned Flags = 0; 507 unsigned extraFlags = 0; 508 const MCExpr *Subsection = nullptr; 509 bool UseLastGroup = false; 510 MCSymbolELF *LinkedToSym = nullptr; 511 int64_t UniqueID = ~0; 512 513 // Set the defaults first. 514 if (hasPrefix(SectionName, ".rodata") || SectionName == ".rodata1") 515 Flags |= ELF::SHF_ALLOC; 516 else if (SectionName == ".fini" || SectionName == ".init" || 517 hasPrefix(SectionName, ".text")) 518 Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; 519 else if (hasPrefix(SectionName, ".data") || SectionName == ".data1" || 520 hasPrefix(SectionName, ".bss") || 521 hasPrefix(SectionName, ".init_array") || 522 hasPrefix(SectionName, ".fini_array") || 523 hasPrefix(SectionName, ".preinit_array")) 524 Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE; 525 else if (hasPrefix(SectionName, ".tdata") || hasPrefix(SectionName, ".tbss")) 526 Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS; 527 528 if (getLexer().is(AsmToken::Comma)) { 529 Lex(); 530 531 if (IsPush && getLexer().isNot(AsmToken::String)) { 532 if (getParser().parseExpression(Subsection)) 533 return true; 534 if (getLexer().isNot(AsmToken::Comma)) 535 goto EndStmt; 536 Lex(); 537 } 538 539 if (getLexer().isNot(AsmToken::String)) { 540 if (getLexer().isNot(AsmToken::Hash)) 541 return TokError("expected string"); 542 extraFlags = parseSunStyleSectionFlags(); 543 } else { 544 StringRef FlagsStr = getTok().getStringContents(); 545 Lex(); 546 extraFlags = parseSectionFlags(getContext().getTargetTriple(), FlagsStr, 547 &UseLastGroup); 548 } 549 550 if (extraFlags == -1U) 551 return TokError("unknown flag"); 552 Flags |= extraFlags; 553 554 bool Mergeable = Flags & ELF::SHF_MERGE; 555 bool Group = Flags & ELF::SHF_GROUP; 556 if (Group && UseLastGroup) 557 return TokError("Section cannot specifiy a group name while also acting " 558 "as a member of the last group"); 559 560 if (maybeParseSectionType(TypeName)) 561 return true; 562 563 AsmLexer &L = getLexer(); 564 if (TypeName.empty()) { 565 if (Mergeable) 566 return TokError("Mergeable section must specify the type"); 567 if (Group) 568 return TokError("Group section must specify the type"); 569 if (L.isNot(AsmToken::EndOfStatement)) 570 return TokError("expected end of directive"); 571 } 572 573 if (Mergeable) 574 if (parseMergeSize(Size)) 575 return true; 576 if (Flags & ELF::SHF_LINK_ORDER) 577 if (parseLinkedToSym(LinkedToSym)) 578 return true; 579 if (Group) 580 if (parseGroup(GroupName, IsComdat)) 581 return true; 582 if (maybeParseUniqueID(UniqueID)) 583 return true; 584 } 585 586 EndStmt: 587 if (getLexer().isNot(AsmToken::EndOfStatement)) 588 return TokError("expected end of directive"); 589 Lex(); 590 591 unsigned Type = ELF::SHT_PROGBITS; 592 593 if (TypeName.empty()) { 594 if (SectionName.starts_with(".note")) 595 Type = ELF::SHT_NOTE; 596 else if (hasPrefix(SectionName, ".init_array")) 597 Type = ELF::SHT_INIT_ARRAY; 598 else if (hasPrefix(SectionName, ".bss")) 599 Type = ELF::SHT_NOBITS; 600 else if (hasPrefix(SectionName, ".tbss")) 601 Type = ELF::SHT_NOBITS; 602 else if (hasPrefix(SectionName, ".fini_array")) 603 Type = ELF::SHT_FINI_ARRAY; 604 else if (hasPrefix(SectionName, ".preinit_array")) 605 Type = ELF::SHT_PREINIT_ARRAY; 606 } else { 607 if (TypeName == "init_array") 608 Type = ELF::SHT_INIT_ARRAY; 609 else if (TypeName == "fini_array") 610 Type = ELF::SHT_FINI_ARRAY; 611 else if (TypeName == "preinit_array") 612 Type = ELF::SHT_PREINIT_ARRAY; 613 else if (TypeName == "nobits") 614 Type = ELF::SHT_NOBITS; 615 else if (TypeName == "progbits") 616 Type = ELF::SHT_PROGBITS; 617 else if (TypeName == "note") 618 Type = ELF::SHT_NOTE; 619 else if (TypeName == "unwind") 620 Type = ELF::SHT_X86_64_UNWIND; 621 else if (TypeName == "llvm_odrtab") 622 Type = ELF::SHT_LLVM_ODRTAB; 623 else if (TypeName == "llvm_linker_options") 624 Type = ELF::SHT_LLVM_LINKER_OPTIONS; 625 else if (TypeName == "llvm_call_graph_profile") 626 Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE; 627 else if (TypeName == "llvm_dependent_libraries") 628 Type = ELF::SHT_LLVM_DEPENDENT_LIBRARIES; 629 else if (TypeName == "llvm_sympart") 630 Type = ELF::SHT_LLVM_SYMPART; 631 else if (TypeName == "llvm_bb_addr_map") 632 Type = ELF::SHT_LLVM_BB_ADDR_MAP; 633 else if (TypeName == "llvm_offloading") 634 Type = ELF::SHT_LLVM_OFFLOADING; 635 else if (TypeName == "llvm_lto") 636 Type = ELF::SHT_LLVM_LTO; 637 else if (TypeName == "llvm_jt_sizes") 638 Type = ELF::SHT_LLVM_JT_SIZES; 639 else if (TypeName.getAsInteger(0, Type)) 640 return TokError("unknown section type"); 641 } 642 643 if (UseLastGroup) { 644 if (const MCSectionELF *Section = 645 cast_or_null<MCSectionELF>(getStreamer().getCurrentSectionOnly())) 646 if (const MCSymbol *Group = Section->getGroup()) { 647 GroupName = Group->getName(); 648 IsComdat = Section->isComdat(); 649 Flags |= ELF::SHF_GROUP; 650 } 651 } 652 653 MCSectionELF *Section = 654 getContext().getELFSection(SectionName, Type, Flags, Size, GroupName, 655 IsComdat, UniqueID, LinkedToSym); 656 getStreamer().switchSection(Section, Subsection); 657 // Check that flags are used consistently. However, the GNU assembler permits 658 // to leave out in subsequent uses of the same sections; for compatibility, 659 // do likewise. 660 if (!TypeName.empty() && Section->getType() != Type && 661 !allowSectionTypeMismatch(getContext().getTargetTriple(), SectionName, 662 Type)) 663 Error(loc, "changed section type for " + SectionName + ", expected: 0x" + 664 utohexstr(Section->getType())); 665 if ((extraFlags || Size || !TypeName.empty()) && Section->getFlags() != Flags) 666 Error(loc, "changed section flags for " + SectionName + ", expected: 0x" + 667 utohexstr(Section->getFlags())); 668 if ((extraFlags || Size || !TypeName.empty()) && 669 Section->getEntrySize() != Size) 670 Error(loc, "changed section entsize for " + SectionName + 671 ", expected: " + Twine(Section->getEntrySize())); 672 673 if (getContext().getGenDwarfForAssembly() && 674 (Section->getFlags() & ELF::SHF_ALLOC) && 675 (Section->getFlags() & ELF::SHF_EXECINSTR)) { 676 bool InsertResult = getContext().addGenDwarfSection(Section); 677 if (InsertResult && getContext().getDwarfVersion() <= 2) 678 Warning(loc, "DWARF2 only supports one section per compilation unit"); 679 } 680 681 return false; 682 } 683 684 bool ELFAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) { 685 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 686 if (PreviousSection.first == nullptr) 687 return TokError(".previous without corresponding .section"); 688 getStreamer().switchSection(PreviousSection.first, PreviousSection.second); 689 690 return false; 691 } 692 693 static MCSymbolAttr MCAttrForString(StringRef Type) { 694 return StringSwitch<MCSymbolAttr>(Type) 695 .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction) 696 .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject) 697 .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS) 698 .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon) 699 .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType) 700 .Cases("STT_GNU_IFUNC", "gnu_indirect_function", 701 MCSA_ELF_TypeIndFunction) 702 .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) 703 .Default(MCSA_Invalid); 704 } 705 706 /// parseDirectiveELFType 707 /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE> 708 /// ::= .type identifier , #attribute 709 /// ::= .type identifier , @attribute 710 /// ::= .type identifier , %attribute 711 /// ::= .type identifier , "attribute" 712 bool ELFAsmParser::parseDirectiveType(StringRef, SMLoc) { 713 MCSymbol *Sym; 714 if (getParser().parseSymbol(Sym)) 715 return TokError("expected identifier"); 716 717 bool AllowAt = getLexer().getAllowAtInIdentifier(); 718 if (!AllowAt && 719 !getContext().getAsmInfo()->getCommentString().starts_with("@")) 720 getLexer().setAllowAtInIdentifier(true); 721 auto _ = 722 make_scope_exit([&]() { getLexer().setAllowAtInIdentifier(AllowAt); }); 723 724 // NOTE the comma is optional in all cases. It is only documented as being 725 // optional in the first case, however, GAS will silently treat the comma as 726 // optional in all cases. Furthermore, although the documentation states that 727 // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS 728 // accepts both the upper case name as well as the lower case aliases. 729 if (getLexer().is(AsmToken::Comma)) 730 Lex(); 731 732 if (getLexer().isNot(AsmToken::Identifier) && 733 getLexer().isNot(AsmToken::Hash) && 734 getLexer().isNot(AsmToken::Percent) && 735 getLexer().isNot(AsmToken::String)) { 736 if (!getLexer().getAllowAtInIdentifier()) 737 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', " 738 "'%<type>' or \"<type>\""); 739 else if (getLexer().isNot(AsmToken::At)) 740 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " 741 "'%<type>' or \"<type>\""); 742 } 743 744 if (getLexer().isNot(AsmToken::String) && 745 getLexer().isNot(AsmToken::Identifier)) 746 Lex(); 747 748 SMLoc TypeLoc = getLexer().getLoc(); 749 750 StringRef Type; 751 if (getParser().parseIdentifier(Type)) 752 return TokError("expected symbol type"); 753 754 MCSymbolAttr Attr = MCAttrForString(Type); 755 if (Attr == MCSA_Invalid) 756 return Error(TypeLoc, "unsupported attribute"); 757 758 if (getLexer().isNot(AsmToken::EndOfStatement)) 759 return TokError("expected end of directive"); 760 Lex(); 761 762 getStreamer().emitSymbolAttribute(Sym, Attr); 763 764 return false; 765 } 766 767 /// parseDirectiveIdent 768 /// ::= .ident string 769 bool ELFAsmParser::parseDirectiveIdent(StringRef, SMLoc) { 770 if (getLexer().isNot(AsmToken::String)) 771 return TokError("expected string"); 772 773 StringRef Data = getTok().getIdentifier(); 774 775 Lex(); 776 777 if (getLexer().isNot(AsmToken::EndOfStatement)) 778 return TokError("expected end of directive"); 779 Lex(); 780 781 getStreamer().emitIdent(Data); 782 return false; 783 } 784 785 /// parseDirectiveSymver 786 /// ::= .symver foo, bar2@zed 787 bool ELFAsmParser::parseDirectiveSymver(StringRef, SMLoc) { 788 MCSymbol *OriginalSym; 789 StringRef Name, Action; 790 if (getParser().parseSymbol(OriginalSym)) 791 return TokError("expected identifier"); 792 793 if (getLexer().isNot(AsmToken::Comma)) 794 return TokError("expected a comma"); 795 796 // ARM assembly uses @ for a comment... 797 // except when parsing the second parameter of the .symver directive. 798 // Force the next symbol to allow @ in the identifier, which is 799 // required for this directive and then reset it to its initial state. 800 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier(); 801 getLexer().setAllowAtInIdentifier(true); 802 Lex(); 803 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier); 804 805 if (getParser().parseIdentifier(Name)) 806 return TokError("expected identifier"); 807 808 if (!Name.contains('@')) 809 return TokError("expected a '@' in the name"); 810 bool KeepOriginalSym = !Name.contains("@@@"); 811 if (parseOptionalToken(AsmToken::Comma)) { 812 if (getParser().parseIdentifier(Action) || Action != "remove") 813 return TokError("expected 'remove'"); 814 KeepOriginalSym = false; 815 } 816 (void)parseOptionalToken(AsmToken::EndOfStatement); 817 818 getStreamer().emitELFSymverDirective(OriginalSym, Name, KeepOriginalSym); 819 return false; 820 } 821 822 /// parseDirectiveVersion 823 /// ::= .version string 824 bool ELFAsmParser::parseDirectiveVersion(StringRef, SMLoc) { 825 if (getLexer().isNot(AsmToken::String)) 826 return TokError("expected string"); 827 828 StringRef Data = getTok().getIdentifier(); 829 830 Lex(); 831 832 MCSection *Note = getContext().getELFSection(".note", ELF::SHT_NOTE, 0); 833 834 getStreamer().pushSection(); 835 getStreamer().switchSection(Note); 836 getStreamer().emitInt32(Data.size() + 1); // namesz 837 getStreamer().emitInt32(0); // descsz = 0 (no description). 838 getStreamer().emitInt32(1); // type = NT_VERSION 839 getStreamer().emitBytes(Data); // name 840 getStreamer().emitInt8(0); // NUL 841 getStreamer().emitValueToAlignment(Align(4)); 842 getStreamer().popSection(); 843 return false; 844 } 845 846 /// parseDirectiveWeakref 847 /// ::= .weakref foo, bar 848 bool ELFAsmParser::parseDirectiveWeakref(StringRef, SMLoc) { 849 // FIXME: Share code with the other alias building directives. 850 851 MCSymbol *Alias; 852 if (getParser().parseSymbol(Alias)) 853 return TokError("expected identifier"); 854 855 if (getLexer().isNot(AsmToken::Comma)) 856 return TokError("expected a comma"); 857 858 Lex(); 859 860 MCSymbol *Sym; 861 if (getParser().parseSymbol(Sym)) 862 return TokError("expected identifier"); 863 864 getStreamer().emitWeakReference(Alias, Sym); 865 return false; 866 } 867 868 bool ELFAsmParser::parseDirectiveSubsection(StringRef, SMLoc) { 869 const MCExpr *Subsection = MCConstantExpr::create(0, getContext()); 870 if (getLexer().isNot(AsmToken::EndOfStatement)) { 871 if (getParser().parseExpression(Subsection)) 872 return true; 873 } 874 875 if (getLexer().isNot(AsmToken::EndOfStatement)) 876 return TokError("expected end of directive"); 877 878 Lex(); 879 880 return getStreamer().switchSection(getStreamer().getCurrentSectionOnly(), 881 Subsection); 882 } 883 884 bool ELFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) { 885 return MCAsmParserExtension::parseDirectiveCGProfile(S, Loc); 886 } 887 888 namespace llvm { 889 890 MCAsmParserExtension *createELFAsmParser() { 891 return new ELFAsmParser; 892 } 893 894 } // end namespace llvm 895