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