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