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 'G': 325 flags |= ELF::SHF_GROUP; 326 break; 327 case '?': 328 *UseLastGroup = true; 329 break; 330 default: 331 return -1U; 332 } 333 } 334 335 return flags; 336 } 337 338 unsigned ELFAsmParser::parseSunStyleSectionFlags() { 339 unsigned flags = 0; 340 while (getLexer().is(AsmToken::Hash)) { 341 Lex(); // Eat the #. 342 343 if (!getLexer().is(AsmToken::Identifier)) 344 return -1U; 345 346 StringRef flagId = getTok().getIdentifier(); 347 if (flagId == "alloc") 348 flags |= ELF::SHF_ALLOC; 349 else if (flagId == "execinstr") 350 flags |= ELF::SHF_EXECINSTR; 351 else if (flagId == "write") 352 flags |= ELF::SHF_WRITE; 353 else if (flagId == "tls") 354 flags |= ELF::SHF_TLS; 355 else 356 return -1U; 357 358 Lex(); // Eat the flag. 359 360 if (!getLexer().is(AsmToken::Comma)) 361 break; 362 Lex(); // Eat the comma. 363 } 364 return flags; 365 } 366 367 368 bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) { 369 getStreamer().PushSection(); 370 371 if (ParseSectionArguments(/*IsPush=*/true, loc)) { 372 getStreamer().PopSection(); 373 return true; 374 } 375 376 return false; 377 } 378 379 bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { 380 if (!getStreamer().PopSection()) 381 return TokError(".popsection without corresponding .pushsection"); 382 return false; 383 } 384 385 bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) { 386 return ParseSectionArguments(/*IsPush=*/false, loc); 387 } 388 389 bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) { 390 MCAsmLexer &L = getLexer(); 391 if (L.isNot(AsmToken::Comma)) 392 return false; 393 Lex(); 394 if (L.isNot(AsmToken::At) && L.isNot(AsmToken::Percent) && 395 L.isNot(AsmToken::String)) { 396 if (L.getAllowAtInIdentifier()) 397 return TokError("expected '@<type>', '%<type>' or \"<type>\""); 398 else 399 return TokError("expected '%<type>' or \"<type>\""); 400 } 401 if (!L.is(AsmToken::String)) 402 Lex(); 403 if (L.is(AsmToken::Integer)) { 404 TypeName = getTok().getString(); 405 Lex(); 406 } else if (getParser().parseIdentifier(TypeName)) 407 return TokError("expected identifier in directive"); 408 return false; 409 } 410 411 bool ELFAsmParser::parseMergeSize(int64_t &Size) { 412 if (getLexer().isNot(AsmToken::Comma)) 413 return TokError("expected the entry size"); 414 Lex(); 415 if (getParser().parseAbsoluteExpression(Size)) 416 return true; 417 if (Size <= 0) 418 return TokError("entry size must be positive"); 419 return false; 420 } 421 422 bool ELFAsmParser::parseGroup(StringRef &GroupName) { 423 MCAsmLexer &L = getLexer(); 424 if (L.isNot(AsmToken::Comma)) 425 return TokError("expected group name"); 426 Lex(); 427 if (L.is(AsmToken::Integer)) { 428 GroupName = getTok().getString(); 429 Lex(); 430 } else if (getParser().parseIdentifier(GroupName)) { 431 return TokError("invalid group name"); 432 } 433 if (L.is(AsmToken::Comma)) { 434 Lex(); 435 StringRef Linkage; 436 if (getParser().parseIdentifier(Linkage)) 437 return TokError("invalid linkage"); 438 if (Linkage != "comdat") 439 return TokError("Linkage must be 'comdat'"); 440 } 441 return false; 442 } 443 444 bool ELFAsmParser::parseMetadataSym(MCSymbolELF *&Associated) { 445 MCAsmLexer &L = getLexer(); 446 if (L.isNot(AsmToken::Comma)) 447 return TokError("expected metadata symbol"); 448 Lex(); 449 StringRef Name; 450 if (getParser().parseIdentifier(Name)) 451 return TokError("invalid metadata symbol"); 452 Associated = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name)); 453 if (!Associated || !Associated->isInSection()) 454 return TokError("symbol is not in a section: " + Name); 455 return false; 456 } 457 458 bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) { 459 MCAsmLexer &L = getLexer(); 460 if (L.isNot(AsmToken::Comma)) 461 return false; 462 Lex(); 463 StringRef UniqueStr; 464 if (getParser().parseIdentifier(UniqueStr)) 465 return TokError("expected identifier in directive"); 466 if (UniqueStr != "unique") 467 return TokError("expected 'unique'"); 468 if (L.isNot(AsmToken::Comma)) 469 return TokError("expected commma"); 470 Lex(); 471 if (getParser().parseAbsoluteExpression(UniqueID)) 472 return true; 473 if (UniqueID < 0) 474 return TokError("unique id must be positive"); 475 if (!isUInt<32>(UniqueID) || UniqueID == ~0U) 476 return TokError("unique id is too large"); 477 return false; 478 } 479 480 static bool hasPrefix(StringRef SectionName, StringRef Prefix) { 481 return SectionName.startswith(Prefix) || SectionName == Prefix.drop_back(); 482 } 483 484 bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { 485 StringRef SectionName; 486 487 if (ParseSectionName(SectionName)) 488 return TokError("expected identifier in directive"); 489 490 StringRef TypeName; 491 int64_t Size = 0; 492 StringRef GroupName; 493 unsigned Flags = 0; 494 const MCExpr *Subsection = nullptr; 495 bool UseLastGroup = false; 496 MCSymbolELF *Associated = nullptr; 497 int64_t UniqueID = ~0; 498 499 // Set the defaults first. 500 if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1") 501 Flags |= ELF::SHF_ALLOC; 502 else if (SectionName == ".fini" || SectionName == ".init" || 503 hasPrefix(SectionName, ".text.")) 504 Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; 505 else if (hasPrefix(SectionName, ".data.") || SectionName == ".data1" || 506 hasPrefix(SectionName, ".bss.") || 507 hasPrefix(SectionName, ".init_array.") || 508 hasPrefix(SectionName, ".fini_array.") || 509 hasPrefix(SectionName, ".preinit_array.")) 510 Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE; 511 else if (hasPrefix(SectionName, ".tdata.") || 512 hasPrefix(SectionName, ".tbss.")) 513 Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS; 514 515 if (getLexer().is(AsmToken::Comma)) { 516 Lex(); 517 518 if (IsPush && getLexer().isNot(AsmToken::String)) { 519 if (getParser().parseExpression(Subsection)) 520 return true; 521 if (getLexer().isNot(AsmToken::Comma)) 522 goto EndStmt; 523 Lex(); 524 } 525 526 unsigned extraFlags; 527 528 if (getLexer().isNot(AsmToken::String)) { 529 if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax() 530 || getLexer().isNot(AsmToken::Hash)) 531 return TokError("expected string in directive"); 532 extraFlags = parseSunStyleSectionFlags(); 533 } else { 534 StringRef FlagsStr = getTok().getStringContents(); 535 Lex(); 536 extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); 537 } 538 539 if (extraFlags == -1U) 540 return TokError("unknown flag"); 541 Flags |= extraFlags; 542 543 bool Mergeable = Flags & ELF::SHF_MERGE; 544 bool Group = Flags & ELF::SHF_GROUP; 545 if (Group && UseLastGroup) 546 return TokError("Section cannot specifiy a group name while also acting " 547 "as a member of the last group"); 548 549 if (maybeParseSectionType(TypeName)) 550 return true; 551 552 MCAsmLexer &L = getLexer(); 553 if (TypeName.empty()) { 554 if (Mergeable) 555 return TokError("Mergeable section must specify the type"); 556 if (Group) 557 return TokError("Group section must specify the type"); 558 if (L.isNot(AsmToken::EndOfStatement)) 559 return TokError("unexpected token in directive"); 560 } 561 562 if (Mergeable) 563 if (parseMergeSize(Size)) 564 return true; 565 if (Group) 566 if (parseGroup(GroupName)) 567 return true; 568 if (Flags & ELF::SHF_LINK_ORDER) 569 if (parseMetadataSym(Associated)) 570 return true; 571 if (maybeParseUniqueID(UniqueID)) 572 return true; 573 } 574 575 EndStmt: 576 if (getLexer().isNot(AsmToken::EndOfStatement)) 577 return TokError("unexpected token in directive"); 578 Lex(); 579 580 unsigned Type = ELF::SHT_PROGBITS; 581 582 if (TypeName.empty()) { 583 if (SectionName.startswith(".note")) 584 Type = ELF::SHT_NOTE; 585 else if (hasPrefix(SectionName, ".init_array.")) 586 Type = ELF::SHT_INIT_ARRAY; 587 else if (hasPrefix(SectionName, ".bss.")) 588 Type = ELF::SHT_NOBITS; 589 else if (hasPrefix(SectionName, ".tbss.")) 590 Type = ELF::SHT_NOBITS; 591 else if (hasPrefix(SectionName, ".fini_array.")) 592 Type = ELF::SHT_FINI_ARRAY; 593 else if (hasPrefix(SectionName, ".preinit_array.")) 594 Type = ELF::SHT_PREINIT_ARRAY; 595 } else { 596 if (TypeName == "init_array") 597 Type = ELF::SHT_INIT_ARRAY; 598 else if (TypeName == "fini_array") 599 Type = ELF::SHT_FINI_ARRAY; 600 else if (TypeName == "preinit_array") 601 Type = ELF::SHT_PREINIT_ARRAY; 602 else if (TypeName == "nobits") 603 Type = ELF::SHT_NOBITS; 604 else if (TypeName == "progbits") 605 Type = ELF::SHT_PROGBITS; 606 else if (TypeName == "note") 607 Type = ELF::SHT_NOTE; 608 else if (TypeName == "unwind") 609 Type = ELF::SHT_X86_64_UNWIND; 610 else if (TypeName == "llvm_odrtab") 611 Type = ELF::SHT_LLVM_ODRTAB; 612 else if (TypeName == "llvm_linker_options") 613 Type = ELF::SHT_LLVM_LINKER_OPTIONS; 614 else if (TypeName == "llvm_call_graph_profile") 615 Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE; 616 else if (TypeName.getAsInteger(0, Type)) 617 return TokError("unknown section type"); 618 } 619 620 if (UseLastGroup) { 621 MCSectionSubPair CurrentSection = getStreamer().getCurrentSection(); 622 if (const MCSectionELF *Section = 623 cast_or_null<MCSectionELF>(CurrentSection.first)) 624 if (const MCSymbol *Group = Section->getGroup()) { 625 GroupName = Group->getName(); 626 Flags |= ELF::SHF_GROUP; 627 } 628 } 629 630 MCSection *ELFSection = 631 getContext().getELFSection(SectionName, Type, Flags, Size, GroupName, 632 UniqueID, Associated); 633 getStreamer().SwitchSection(ELFSection, Subsection); 634 635 if (getContext().getGenDwarfForAssembly()) { 636 bool InsertResult = getContext().addGenDwarfSection(ELFSection); 637 if (InsertResult) { 638 if (getContext().getDwarfVersion() <= 2) 639 Warning(loc, "DWARF2 only supports one section per compilation unit"); 640 641 if (!ELFSection->getBeginSymbol()) { 642 MCSymbol *SectionStartSymbol = getContext().createTempSymbol(); 643 getStreamer().EmitLabel(SectionStartSymbol); 644 ELFSection->setBeginSymbol(SectionStartSymbol); 645 } 646 } 647 } 648 649 return false; 650 } 651 652 bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { 653 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 654 if (PreviousSection.first == nullptr) 655 return TokError(".previous without corresponding .section"); 656 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); 657 658 return false; 659 } 660 661 static MCSymbolAttr MCAttrForString(StringRef Type) { 662 return StringSwitch<MCSymbolAttr>(Type) 663 .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction) 664 .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject) 665 .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS) 666 .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon) 667 .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType) 668 .Cases("STT_GNU_IFUNC", "gnu_indirect_function", 669 MCSA_ELF_TypeIndFunction) 670 .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) 671 .Default(MCSA_Invalid); 672 } 673 674 /// ParseDirectiveELFType 675 /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE> 676 /// ::= .type identifier , #attribute 677 /// ::= .type identifier , @attribute 678 /// ::= .type identifier , %attribute 679 /// ::= .type identifier , "attribute" 680 bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { 681 StringRef Name; 682 if (getParser().parseIdentifier(Name)) 683 return TokError("expected identifier in directive"); 684 685 // Handle the identifier as the key symbol. 686 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 687 688 // NOTE the comma is optional in all cases. It is only documented as being 689 // optional in the first case, however, GAS will silently treat the comma as 690 // optional in all cases. Furthermore, although the documentation states that 691 // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS 692 // accepts both the upper case name as well as the lower case aliases. 693 if (getLexer().is(AsmToken::Comma)) 694 Lex(); 695 696 if (getLexer().isNot(AsmToken::Identifier) && 697 getLexer().isNot(AsmToken::Hash) && 698 getLexer().isNot(AsmToken::Percent) && 699 getLexer().isNot(AsmToken::String)) { 700 if (!getLexer().getAllowAtInIdentifier()) 701 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', " 702 "'%<type>' or \"<type>\""); 703 else if (getLexer().isNot(AsmToken::At)) 704 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " 705 "'%<type>' or \"<type>\""); 706 } 707 708 if (getLexer().isNot(AsmToken::String) && 709 getLexer().isNot(AsmToken::Identifier)) 710 Lex(); 711 712 SMLoc TypeLoc = getLexer().getLoc(); 713 714 StringRef Type; 715 if (getParser().parseIdentifier(Type)) 716 return TokError("expected symbol type in directive"); 717 718 MCSymbolAttr Attr = MCAttrForString(Type); 719 if (Attr == MCSA_Invalid) 720 return Error(TypeLoc, "unsupported attribute in '.type' directive"); 721 722 if (getLexer().isNot(AsmToken::EndOfStatement)) 723 return TokError("unexpected token in '.type' directive"); 724 Lex(); 725 726 getStreamer().EmitSymbolAttribute(Sym, Attr); 727 728 return false; 729 } 730 731 /// ParseDirectiveIdent 732 /// ::= .ident string 733 bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { 734 if (getLexer().isNot(AsmToken::String)) 735 return TokError("unexpected token in '.ident' directive"); 736 737 StringRef Data = getTok().getIdentifier(); 738 739 Lex(); 740 741 if (getLexer().isNot(AsmToken::EndOfStatement)) 742 return TokError("unexpected token in '.ident' directive"); 743 Lex(); 744 745 getStreamer().EmitIdent(Data); 746 return false; 747 } 748 749 /// ParseDirectiveSymver 750 /// ::= .symver foo, bar2@zed 751 bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { 752 StringRef Name; 753 if (getParser().parseIdentifier(Name)) 754 return TokError("expected identifier in directive"); 755 756 if (getLexer().isNot(AsmToken::Comma)) 757 return TokError("expected a comma"); 758 759 // ARM assembly uses @ for a comment... 760 // except when parsing the second parameter of the .symver directive. 761 // Force the next symbol to allow @ in the identifier, which is 762 // required for this directive and then reset it to its initial state. 763 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier(); 764 getLexer().setAllowAtInIdentifier(true); 765 Lex(); 766 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier); 767 768 StringRef AliasName; 769 if (getParser().parseIdentifier(AliasName)) 770 return TokError("expected identifier in directive"); 771 772 if (AliasName.find('@') == StringRef::npos) 773 return TokError("expected a '@' in the name"); 774 775 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 776 getStreamer().emitELFSymverDirective(AliasName, Sym); 777 return false; 778 } 779 780 /// ParseDirectiveVersion 781 /// ::= .version string 782 bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) { 783 if (getLexer().isNot(AsmToken::String)) 784 return TokError("unexpected token in '.version' directive"); 785 786 StringRef Data = getTok().getIdentifier(); 787 788 Lex(); 789 790 MCSection *Note = getContext().getELFSection(".note", ELF::SHT_NOTE, 0); 791 792 getStreamer().PushSection(); 793 getStreamer().SwitchSection(Note); 794 getStreamer().EmitIntValue(Data.size()+1, 4); // namesz. 795 getStreamer().EmitIntValue(0, 4); // descsz = 0 (no description). 796 getStreamer().EmitIntValue(1, 4); // type = NT_VERSION. 797 getStreamer().EmitBytes(Data); // name. 798 getStreamer().EmitIntValue(0, 1); // terminate the string. 799 getStreamer().EmitValueToAlignment(4); // ensure 4 byte alignment. 800 getStreamer().PopSection(); 801 return false; 802 } 803 804 /// ParseDirectiveWeakref 805 /// ::= .weakref foo, bar 806 bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { 807 // FIXME: Share code with the other alias building directives. 808 809 StringRef AliasName; 810 if (getParser().parseIdentifier(AliasName)) 811 return TokError("expected identifier in directive"); 812 813 if (getLexer().isNot(AsmToken::Comma)) 814 return TokError("expected a comma"); 815 816 Lex(); 817 818 StringRef Name; 819 if (getParser().parseIdentifier(Name)) 820 return TokError("expected identifier in directive"); 821 822 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); 823 824 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 825 826 getStreamer().EmitWeakReference(Alias, Sym); 827 return false; 828 } 829 830 bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) { 831 const MCExpr *Subsection = nullptr; 832 if (getLexer().isNot(AsmToken::EndOfStatement)) { 833 if (getParser().parseExpression(Subsection)) 834 return true; 835 } 836 837 if (getLexer().isNot(AsmToken::EndOfStatement)) 838 return TokError("unexpected token in directive"); 839 840 Lex(); 841 842 getStreamer().SubSection(Subsection); 843 return false; 844 } 845 846 /// ParseDirectiveCGProfile 847 /// ::= .cg_profile identifier, identifier, <number> 848 bool ELFAsmParser::ParseDirectiveCGProfile(StringRef, SMLoc) { 849 StringRef From; 850 SMLoc FromLoc = getLexer().getLoc(); 851 if (getParser().parseIdentifier(From)) 852 return TokError("expected identifier in directive"); 853 854 if (getLexer().isNot(AsmToken::Comma)) 855 return TokError("expected a comma"); 856 Lex(); 857 858 StringRef To; 859 SMLoc ToLoc = getLexer().getLoc(); 860 if (getParser().parseIdentifier(To)) 861 return TokError("expected identifier in directive"); 862 863 if (getLexer().isNot(AsmToken::Comma)) 864 return TokError("expected a comma"); 865 Lex(); 866 867 int64_t Count; 868 if (getParser().parseIntToken( 869 Count, "expected integer count in '.cg_profile' directive")) 870 return true; 871 872 if (getLexer().isNot(AsmToken::EndOfStatement)) 873 return TokError("unexpected token in directive"); 874 875 MCSymbol *FromSym = getContext().getOrCreateSymbol(From); 876 MCSymbol *ToSym = getContext().getOrCreateSymbol(To); 877 878 getStreamer().emitCGProfileEntry( 879 MCSymbolRefExpr::create(FromSym, MCSymbolRefExpr::VK_None, getContext(), 880 FromLoc), 881 MCSymbolRefExpr::create(ToSym, MCSymbolRefExpr::VK_None, getContext(), 882 ToLoc), 883 Count); 884 return false; 885 } 886 887 namespace llvm { 888 889 MCAsmParserExtension *createELFAsmParser() { 890 return new ELFAsmParser; 891 } 892 893 } // end namespace llvm 894