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 (L.is(AsmToken::Integer)) { 427 GroupName = getTok().getString(); 428 Lex(); 429 } else if (getParser().parseIdentifier(GroupName)) { 430 return TokError("invalid group name"); 431 } 432 if (L.is(AsmToken::Comma)) { 433 Lex(); 434 StringRef Linkage; 435 if (getParser().parseIdentifier(Linkage)) 436 return TokError("invalid linkage"); 437 if (Linkage != "comdat") 438 return TokError("Linkage must be 'comdat'"); 439 } 440 return false; 441 } 442 443 bool ELFAsmParser::parseMetadataSym(MCSymbolELF *&Associated) { 444 MCAsmLexer &L = getLexer(); 445 if (L.isNot(AsmToken::Comma)) 446 return TokError("expected metadata symbol"); 447 Lex(); 448 StringRef Name; 449 if (getParser().parseIdentifier(Name)) 450 return TokError("invalid metadata symbol"); 451 Associated = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name)); 452 if (!Associated || !Associated->isInSection()) 453 return TokError("symbol is not in a section: " + Name); 454 return false; 455 } 456 457 bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) { 458 MCAsmLexer &L = getLexer(); 459 if (L.isNot(AsmToken::Comma)) 460 return false; 461 Lex(); 462 StringRef UniqueStr; 463 if (getParser().parseIdentifier(UniqueStr)) 464 return TokError("expected identifier in directive"); 465 if (UniqueStr != "unique") 466 return TokError("expected 'unique'"); 467 if (L.isNot(AsmToken::Comma)) 468 return TokError("expected commma"); 469 Lex(); 470 if (getParser().parseAbsoluteExpression(UniqueID)) 471 return true; 472 if (UniqueID < 0) 473 return TokError("unique id must be positive"); 474 if (!isUInt<32>(UniqueID) || UniqueID == ~0U) 475 return TokError("unique id is too large"); 476 return false; 477 } 478 479 static bool hasPrefix(StringRef SectionName, StringRef Prefix) { 480 return SectionName.startswith(Prefix) || SectionName == Prefix.drop_back(); 481 } 482 483 bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { 484 StringRef SectionName; 485 486 if (ParseSectionName(SectionName)) 487 return TokError("expected identifier in directive"); 488 489 StringRef TypeName; 490 int64_t Size = 0; 491 StringRef GroupName; 492 unsigned Flags = 0; 493 const MCExpr *Subsection = nullptr; 494 bool UseLastGroup = false; 495 MCSymbolELF *Associated = nullptr; 496 int64_t UniqueID = ~0; 497 498 // Set the defaults first. 499 if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1") 500 Flags |= ELF::SHF_ALLOC; 501 if (SectionName == ".fini" || SectionName == ".init" || 502 hasPrefix(SectionName, ".text.")) 503 Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; 504 if (hasPrefix(SectionName, ".data.") || SectionName == ".data1" || 505 hasPrefix(SectionName, ".bss.") || 506 hasPrefix(SectionName, ".init_array.") || 507 hasPrefix(SectionName, ".fini_array.") || 508 hasPrefix(SectionName, ".preinit_array.")) 509 Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE; 510 if (hasPrefix(SectionName, ".tdata.") || 511 hasPrefix(SectionName, ".tbss.")) 512 Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS; 513 514 if (getLexer().is(AsmToken::Comma)) { 515 Lex(); 516 517 if (IsPush && getLexer().isNot(AsmToken::String)) { 518 if (getParser().parseExpression(Subsection)) 519 return true; 520 if (getLexer().isNot(AsmToken::Comma)) 521 goto EndStmt; 522 Lex(); 523 } 524 525 unsigned extraFlags; 526 527 if (getLexer().isNot(AsmToken::String)) { 528 if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax() 529 || getLexer().isNot(AsmToken::Hash)) 530 return TokError("expected string in directive"); 531 extraFlags = parseSunStyleSectionFlags(); 532 } else { 533 StringRef FlagsStr = getTok().getStringContents(); 534 Lex(); 535 extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); 536 } 537 538 if (extraFlags == -1U) 539 return TokError("unknown flag"); 540 Flags |= extraFlags; 541 542 bool Mergeable = Flags & ELF::SHF_MERGE; 543 bool Group = Flags & ELF::SHF_GROUP; 544 if (Group && UseLastGroup) 545 return TokError("Section cannot specifiy a group name while also acting " 546 "as a member of the last group"); 547 548 if (maybeParseSectionType(TypeName)) 549 return true; 550 551 MCAsmLexer &L = getLexer(); 552 if (TypeName.empty()) { 553 if (Mergeable) 554 return TokError("Mergeable section must specify the type"); 555 if (Group) 556 return TokError("Group section must specify the type"); 557 if (L.isNot(AsmToken::EndOfStatement)) 558 return TokError("unexpected token in directive"); 559 } 560 561 if (Mergeable) 562 if (parseMergeSize(Size)) 563 return true; 564 if (Group) 565 if (parseGroup(GroupName)) 566 return true; 567 if (Flags & ELF::SHF_LINK_ORDER) 568 if (parseMetadataSym(Associated)) 569 return true; 570 if (maybeParseUniqueID(UniqueID)) 571 return true; 572 } 573 574 EndStmt: 575 if (getLexer().isNot(AsmToken::EndOfStatement)) 576 return TokError("unexpected token in directive"); 577 Lex(); 578 579 unsigned Type = ELF::SHT_PROGBITS; 580 581 if (TypeName.empty()) { 582 if (SectionName.startswith(".note")) 583 Type = ELF::SHT_NOTE; 584 else if (hasPrefix(SectionName, ".init_array.")) 585 Type = ELF::SHT_INIT_ARRAY; 586 else if (hasPrefix(SectionName, ".bss.")) 587 Type = ELF::SHT_NOBITS; 588 else if (hasPrefix(SectionName, ".tbss.")) 589 Type = ELF::SHT_NOBITS; 590 else if (hasPrefix(SectionName, ".fini_array.")) 591 Type = ELF::SHT_FINI_ARRAY; 592 else if (hasPrefix(SectionName, ".preinit_array.")) 593 Type = ELF::SHT_PREINIT_ARRAY; 594 } else { 595 if (TypeName == "init_array") 596 Type = ELF::SHT_INIT_ARRAY; 597 else if (TypeName == "fini_array") 598 Type = ELF::SHT_FINI_ARRAY; 599 else if (TypeName == "preinit_array") 600 Type = ELF::SHT_PREINIT_ARRAY; 601 else if (TypeName == "nobits") 602 Type = ELF::SHT_NOBITS; 603 else if (TypeName == "progbits") 604 Type = ELF::SHT_PROGBITS; 605 else if (TypeName == "note") 606 Type = ELF::SHT_NOTE; 607 else if (TypeName == "unwind") 608 Type = ELF::SHT_X86_64_UNWIND; 609 else if (TypeName == "llvm_odrtab") 610 Type = ELF::SHT_LLVM_ODRTAB; 611 else if (TypeName.getAsInteger(0, Type)) 612 return TokError("unknown section type"); 613 } 614 615 if (UseLastGroup) { 616 MCSectionSubPair CurrentSection = getStreamer().getCurrentSection(); 617 if (const MCSectionELF *Section = 618 cast_or_null<MCSectionELF>(CurrentSection.first)) 619 if (const MCSymbol *Group = Section->getGroup()) { 620 GroupName = Group->getName(); 621 Flags |= ELF::SHF_GROUP; 622 } 623 } 624 625 MCSection *ELFSection = 626 getContext().getELFSection(SectionName, Type, Flags, Size, GroupName, 627 UniqueID, Associated); 628 getStreamer().SwitchSection(ELFSection, Subsection); 629 630 if (getContext().getGenDwarfForAssembly()) { 631 bool InsertResult = getContext().addGenDwarfSection(ELFSection); 632 if (InsertResult) { 633 if (getContext().getDwarfVersion() <= 2) 634 Warning(loc, "DWARF2 only supports one section per compilation unit"); 635 636 if (!ELFSection->getBeginSymbol()) { 637 MCSymbol *SectionStartSymbol = getContext().createTempSymbol(); 638 getStreamer().EmitLabel(SectionStartSymbol); 639 ELFSection->setBeginSymbol(SectionStartSymbol); 640 } 641 } 642 } 643 644 return false; 645 } 646 647 bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { 648 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 649 if (PreviousSection.first == nullptr) 650 return TokError(".previous without corresponding .section"); 651 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); 652 653 return false; 654 } 655 656 static MCSymbolAttr MCAttrForString(StringRef Type) { 657 return StringSwitch<MCSymbolAttr>(Type) 658 .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction) 659 .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject) 660 .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS) 661 .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon) 662 .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType) 663 .Cases("STT_GNU_IFUNC", "gnu_indirect_function", 664 MCSA_ELF_TypeIndFunction) 665 .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) 666 .Default(MCSA_Invalid); 667 } 668 669 /// ParseDirectiveELFType 670 /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE> 671 /// ::= .type identifier , #attribute 672 /// ::= .type identifier , @attribute 673 /// ::= .type identifier , %attribute 674 /// ::= .type identifier , "attribute" 675 bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { 676 StringRef Name; 677 if (getParser().parseIdentifier(Name)) 678 return TokError("expected identifier in directive"); 679 680 // Handle the identifier as the key symbol. 681 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 682 683 // NOTE the comma is optional in all cases. It is only documented as being 684 // optional in the first case, however, GAS will silently treat the comma as 685 // optional in all cases. Furthermore, although the documentation states that 686 // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS 687 // accepts both the upper case name as well as the lower case aliases. 688 if (getLexer().is(AsmToken::Comma)) 689 Lex(); 690 691 if (getLexer().isNot(AsmToken::Identifier) && 692 getLexer().isNot(AsmToken::Hash) && 693 getLexer().isNot(AsmToken::Percent) && 694 getLexer().isNot(AsmToken::String)) { 695 if (!getLexer().getAllowAtInIdentifier()) 696 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', " 697 "'%<type>' or \"<type>\""); 698 else if (getLexer().isNot(AsmToken::At)) 699 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " 700 "'%<type>' or \"<type>\""); 701 } 702 703 if (getLexer().isNot(AsmToken::String) && 704 getLexer().isNot(AsmToken::Identifier)) 705 Lex(); 706 707 SMLoc TypeLoc = getLexer().getLoc(); 708 709 StringRef Type; 710 if (getParser().parseIdentifier(Type)) 711 return TokError("expected symbol type in directive"); 712 713 MCSymbolAttr Attr = MCAttrForString(Type); 714 if (Attr == MCSA_Invalid) 715 return Error(TypeLoc, "unsupported attribute in '.type' directive"); 716 717 if (getLexer().isNot(AsmToken::EndOfStatement)) 718 return TokError("unexpected token in '.type' directive"); 719 Lex(); 720 721 getStreamer().EmitSymbolAttribute(Sym, Attr); 722 723 return false; 724 } 725 726 /// ParseDirectiveIdent 727 /// ::= .ident string 728 bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { 729 if (getLexer().isNot(AsmToken::String)) 730 return TokError("unexpected token in '.ident' directive"); 731 732 StringRef Data = getTok().getIdentifier(); 733 734 Lex(); 735 736 if (getLexer().isNot(AsmToken::EndOfStatement)) 737 return TokError("unexpected token in '.ident' directive"); 738 Lex(); 739 740 getStreamer().EmitIdent(Data); 741 return false; 742 } 743 744 /// ParseDirectiveSymver 745 /// ::= .symver foo, bar2@zed 746 bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { 747 StringRef Name; 748 if (getParser().parseIdentifier(Name)) 749 return TokError("expected identifier in directive"); 750 751 if (getLexer().isNot(AsmToken::Comma)) 752 return TokError("expected a comma"); 753 754 // ARM assembly uses @ for a comment... 755 // except when parsing the second parameter of the .symver directive. 756 // Force the next symbol to allow @ in the identifier, which is 757 // required for this directive and then reset it to its initial state. 758 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier(); 759 getLexer().setAllowAtInIdentifier(true); 760 Lex(); 761 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier); 762 763 StringRef AliasName; 764 if (getParser().parseIdentifier(AliasName)) 765 return TokError("expected identifier in directive"); 766 767 if (AliasName.find('@') == StringRef::npos) 768 return TokError("expected a '@' in the name"); 769 770 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 771 getStreamer().emitELFSymverDirective(AliasName, 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