LLVM API Documentation
00001 //===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 00011 #include "llvm/ADT/StringSwitch.h" 00012 #include "llvm/ADT/Twine.h" 00013 #include "llvm/MC/MCAsmInfo.h" 00014 #include "llvm/MC/MCContext.h" 00015 #include "llvm/MC/MCExpr.h" 00016 #include "llvm/MC/MCParser/MCAsmLexer.h" 00017 #include "llvm/MC/MCSectionELF.h" 00018 #include "llvm/MC/MCStreamer.h" 00019 #include "llvm/MC/MCSymbol.h" 00020 #include "llvm/Support/ELF.h" 00021 using namespace llvm; 00022 00023 namespace { 00024 00025 class ELFAsmParser : public MCAsmParserExtension { 00026 template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)> 00027 void addDirectiveHandler(StringRef Directive) { 00028 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( 00029 this, HandleDirective<ELFAsmParser, HandlerMethod>); 00030 00031 getParser().addDirectiveHandler(Directive, Handler); 00032 } 00033 00034 bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, 00035 SectionKind Kind); 00036 00037 public: 00038 ELFAsmParser() { BracketExpressionsSupported = true; } 00039 00040 void Initialize(MCAsmParser &Parser) override { 00041 // Call the base implementation. 00042 this->MCAsmParserExtension::Initialize(Parser); 00043 00044 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data"); 00045 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text"); 00046 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss"); 00047 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata"); 00048 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata"); 00049 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss"); 00050 addDirectiveHandler< 00051 &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel"); 00052 addDirectiveHandler< 00053 &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro"); 00054 addDirectiveHandler< 00055 &ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local"); 00056 addDirectiveHandler< 00057 &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame"); 00058 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section"); 00059 addDirectiveHandler< 00060 &ELFAsmParser::ParseDirectivePushSection>(".pushsection"); 00061 addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection"); 00062 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size"); 00063 addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); 00064 addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type"); 00065 addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident"); 00066 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver"); 00067 addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version"); 00068 addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref"); 00069 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); 00070 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local"); 00071 addDirectiveHandler< 00072 &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected"); 00073 addDirectiveHandler< 00074 &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal"); 00075 addDirectiveHandler< 00076 &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden"); 00077 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection"); 00078 } 00079 00080 // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is 00081 // the best way for us to get access to it? 00082 bool ParseSectionDirectiveData(StringRef, SMLoc) { 00083 return ParseSectionSwitch(".data", ELF::SHT_PROGBITS, 00084 ELF::SHF_WRITE |ELF::SHF_ALLOC, 00085 SectionKind::getDataRel()); 00086 } 00087 bool ParseSectionDirectiveText(StringRef, SMLoc) { 00088 return ParseSectionSwitch(".text", ELF::SHT_PROGBITS, 00089 ELF::SHF_EXECINSTR | 00090 ELF::SHF_ALLOC, SectionKind::getText()); 00091 } 00092 bool ParseSectionDirectiveBSS(StringRef, SMLoc) { 00093 return ParseSectionSwitch(".bss", ELF::SHT_NOBITS, 00094 ELF::SHF_WRITE | 00095 ELF::SHF_ALLOC, SectionKind::getBSS()); 00096 } 00097 bool ParseSectionDirectiveRoData(StringRef, SMLoc) { 00098 return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS, 00099 ELF::SHF_ALLOC, 00100 SectionKind::getReadOnly()); 00101 } 00102 bool ParseSectionDirectiveTData(StringRef, SMLoc) { 00103 return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS, 00104 ELF::SHF_ALLOC | 00105 ELF::SHF_TLS | ELF::SHF_WRITE, 00106 SectionKind::getThreadData()); 00107 } 00108 bool ParseSectionDirectiveTBSS(StringRef, SMLoc) { 00109 return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS, 00110 ELF::SHF_ALLOC | 00111 ELF::SHF_TLS | ELF::SHF_WRITE, 00112 SectionKind::getThreadBSS()); 00113 } 00114 bool ParseSectionDirectiveDataRel(StringRef, SMLoc) { 00115 return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS, 00116 ELF::SHF_ALLOC | 00117 ELF::SHF_WRITE, 00118 SectionKind::getDataRel()); 00119 } 00120 bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) { 00121 return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS, 00122 ELF::SHF_ALLOC | 00123 ELF::SHF_WRITE, 00124 SectionKind::getReadOnlyWithRel()); 00125 } 00126 bool ParseSectionDirectiveDataRelRoLocal(StringRef, SMLoc) { 00127 return ParseSectionSwitch(".data.rel.ro.local", ELF::SHT_PROGBITS, 00128 ELF::SHF_ALLOC | 00129 ELF::SHF_WRITE, 00130 SectionKind::getReadOnlyWithRelLocal()); 00131 } 00132 bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) { 00133 return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS, 00134 ELF::SHF_ALLOC | 00135 ELF::SHF_WRITE, 00136 SectionKind::getDataRel()); 00137 } 00138 bool ParseDirectivePushSection(StringRef, SMLoc); 00139 bool ParseDirectivePopSection(StringRef, SMLoc); 00140 bool ParseDirectiveSection(StringRef, SMLoc); 00141 bool ParseDirectiveSize(StringRef, SMLoc); 00142 bool ParseDirectivePrevious(StringRef, SMLoc); 00143 bool ParseDirectiveType(StringRef, SMLoc); 00144 bool ParseDirectiveIdent(StringRef, SMLoc); 00145 bool ParseDirectiveSymver(StringRef, SMLoc); 00146 bool ParseDirectiveVersion(StringRef, SMLoc); 00147 bool ParseDirectiveWeakref(StringRef, SMLoc); 00148 bool ParseDirectiveSymbolAttribute(StringRef, SMLoc); 00149 bool ParseDirectiveSubsection(StringRef, SMLoc); 00150 00151 private: 00152 bool ParseSectionName(StringRef &SectionName); 00153 bool ParseSectionArguments(bool IsPush, SMLoc loc); 00154 unsigned parseSunStyleSectionFlags(); 00155 }; 00156 00157 } 00158 00159 /// ParseDirectiveSymbolAttribute 00160 /// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] 00161 bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { 00162 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) 00163 .Case(".weak", MCSA_Weak) 00164 .Case(".local", MCSA_Local) 00165 .Case(".hidden", MCSA_Hidden) 00166 .Case(".internal", MCSA_Internal) 00167 .Case(".protected", MCSA_Protected) 00168 .Default(MCSA_Invalid); 00169 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); 00170 if (getLexer().isNot(AsmToken::EndOfStatement)) { 00171 for (;;) { 00172 StringRef Name; 00173 00174 if (getParser().parseIdentifier(Name)) 00175 return TokError("expected identifier in directive"); 00176 00177 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 00178 00179 getStreamer().EmitSymbolAttribute(Sym, Attr); 00180 00181 if (getLexer().is(AsmToken::EndOfStatement)) 00182 break; 00183 00184 if (getLexer().isNot(AsmToken::Comma)) 00185 return TokError("unexpected token in directive"); 00186 Lex(); 00187 } 00188 } 00189 00190 Lex(); 00191 return false; 00192 } 00193 00194 bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type, 00195 unsigned Flags, SectionKind Kind) { 00196 const MCExpr *Subsection = nullptr; 00197 if (getLexer().isNot(AsmToken::EndOfStatement)) { 00198 if (getParser().parseExpression(Subsection)) 00199 return true; 00200 } 00201 00202 getStreamer().SwitchSection(getContext().getELFSection( 00203 Section, Type, Flags, Kind), 00204 Subsection); 00205 00206 return false; 00207 } 00208 00209 bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) { 00210 StringRef Name; 00211 if (getParser().parseIdentifier(Name)) 00212 return TokError("expected identifier in directive"); 00213 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 00214 00215 if (getLexer().isNot(AsmToken::Comma)) 00216 return TokError("unexpected token in directive"); 00217 Lex(); 00218 00219 const MCExpr *Expr; 00220 if (getParser().parseExpression(Expr)) 00221 return true; 00222 00223 if (getLexer().isNot(AsmToken::EndOfStatement)) 00224 return TokError("unexpected token in directive"); 00225 00226 getStreamer().EmitELFSize(Sym, Expr); 00227 return false; 00228 } 00229 00230 bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { 00231 // A section name can contain -, so we cannot just use 00232 // parseIdentifier. 00233 SMLoc FirstLoc = getLexer().getLoc(); 00234 unsigned Size = 0; 00235 00236 if (getLexer().is(AsmToken::String)) { 00237 SectionName = getTok().getIdentifier(); 00238 Lex(); 00239 return false; 00240 } 00241 00242 for (;;) { 00243 unsigned CurSize; 00244 00245 SMLoc PrevLoc = getLexer().getLoc(); 00246 if (getLexer().is(AsmToken::Minus)) { 00247 CurSize = 1; 00248 Lex(); // Consume the "-". 00249 } else if (getLexer().is(AsmToken::String)) { 00250 CurSize = getTok().getIdentifier().size() + 2; 00251 Lex(); 00252 } else if (getLexer().is(AsmToken::Identifier)) { 00253 CurSize = getTok().getIdentifier().size(); 00254 Lex(); 00255 } else { 00256 break; 00257 } 00258 00259 Size += CurSize; 00260 SectionName = StringRef(FirstLoc.getPointer(), Size); 00261 00262 // Make sure the following token is adjacent. 00263 if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer()) 00264 break; 00265 } 00266 if (Size == 0) 00267 return true; 00268 00269 return false; 00270 } 00271 00272 static SectionKind computeSectionKind(unsigned Flags, unsigned ElemSize) { 00273 if (Flags & ELF::SHF_EXECINSTR) 00274 return SectionKind::getText(); 00275 if (Flags & ELF::SHF_TLS) 00276 return SectionKind::getThreadData(); 00277 if (Flags & ELF::SHF_MERGE) { 00278 if (Flags & ELF::SHF_STRINGS) { 00279 switch (ElemSize) { 00280 default: 00281 break; 00282 case 1: 00283 return SectionKind::getMergeable1ByteCString(); 00284 case 2: 00285 return SectionKind::getMergeable2ByteCString(); 00286 case 4: 00287 return SectionKind::getMergeable4ByteCString(); 00288 } 00289 } else { 00290 switch (ElemSize) { 00291 default: 00292 break; 00293 case 4: 00294 return SectionKind::getMergeableConst4(); 00295 case 8: 00296 return SectionKind::getMergeableConst8(); 00297 case 16: 00298 return SectionKind::getMergeableConst16(); 00299 } 00300 } 00301 } 00302 00303 return SectionKind::getDataRel(); 00304 } 00305 00306 static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { 00307 unsigned flags = 0; 00308 00309 for (unsigned i = 0; i < flagsStr.size(); i++) { 00310 switch (flagsStr[i]) { 00311 case 'a': 00312 flags |= ELF::SHF_ALLOC; 00313 break; 00314 case 'e': 00315 flags |= ELF::SHF_EXCLUDE; 00316 break; 00317 case 'x': 00318 flags |= ELF::SHF_EXECINSTR; 00319 break; 00320 case 'w': 00321 flags |= ELF::SHF_WRITE; 00322 break; 00323 case 'M': 00324 flags |= ELF::SHF_MERGE; 00325 break; 00326 case 'S': 00327 flags |= ELF::SHF_STRINGS; 00328 break; 00329 case 'T': 00330 flags |= ELF::SHF_TLS; 00331 break; 00332 case 'c': 00333 flags |= ELF::XCORE_SHF_CP_SECTION; 00334 break; 00335 case 'd': 00336 flags |= ELF::XCORE_SHF_DP_SECTION; 00337 break; 00338 case 'G': 00339 flags |= ELF::SHF_GROUP; 00340 break; 00341 case '?': 00342 *UseLastGroup = true; 00343 break; 00344 default: 00345 return -1U; 00346 } 00347 } 00348 00349 return flags; 00350 } 00351 00352 unsigned ELFAsmParser::parseSunStyleSectionFlags() { 00353 unsigned flags = 0; 00354 while (getLexer().is(AsmToken::Hash)) { 00355 Lex(); // Eat the #. 00356 00357 if (!getLexer().is(AsmToken::Identifier)) 00358 return -1U; 00359 00360 StringRef flagId = getTok().getIdentifier(); 00361 if (flagId == "alloc") 00362 flags |= ELF::SHF_ALLOC; 00363 else if (flagId == "execinstr") 00364 flags |= ELF::SHF_EXECINSTR; 00365 else if (flagId == "write") 00366 flags |= ELF::SHF_WRITE; 00367 else if (flagId == "tls") 00368 flags |= ELF::SHF_TLS; 00369 else 00370 return -1U; 00371 00372 Lex(); // Eat the flag. 00373 00374 if (!getLexer().is(AsmToken::Comma)) 00375 break; 00376 Lex(); // Eat the comma. 00377 } 00378 return flags; 00379 } 00380 00381 00382 bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) { 00383 getStreamer().PushSection(); 00384 00385 if (ParseSectionArguments(/*IsPush=*/true, loc)) { 00386 getStreamer().PopSection(); 00387 return true; 00388 } 00389 00390 return false; 00391 } 00392 00393 bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { 00394 if (!getStreamer().PopSection()) 00395 return TokError(".popsection without corresponding .pushsection"); 00396 return false; 00397 } 00398 00399 // FIXME: This is a work in progress. 00400 bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) { 00401 return ParseSectionArguments(/*IsPush=*/false, loc); 00402 } 00403 00404 bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { 00405 StringRef SectionName; 00406 00407 if (ParseSectionName(SectionName)) 00408 return TokError("expected identifier in directive"); 00409 00410 StringRef TypeName; 00411 int64_t Size = 0; 00412 StringRef GroupName; 00413 unsigned Flags = 0; 00414 const MCExpr *Subsection = nullptr; 00415 bool UseLastGroup = false; 00416 00417 // Set the defaults first. 00418 if (SectionName == ".fini" || SectionName == ".init" || 00419 SectionName == ".rodata") 00420 Flags |= ELF::SHF_ALLOC; 00421 if (SectionName == ".fini" || SectionName == ".init") 00422 Flags |= ELF::SHF_EXECINSTR; 00423 00424 if (getLexer().is(AsmToken::Comma)) { 00425 Lex(); 00426 00427 if (IsPush && getLexer().isNot(AsmToken::String)) { 00428 if (getParser().parseExpression(Subsection)) 00429 return true; 00430 if (getLexer().isNot(AsmToken::Comma)) 00431 goto EndStmt; 00432 Lex(); 00433 } 00434 00435 unsigned extraFlags; 00436 00437 if (getLexer().isNot(AsmToken::String)) { 00438 if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax() 00439 || getLexer().isNot(AsmToken::Hash)) 00440 return TokError("expected string in directive"); 00441 extraFlags = parseSunStyleSectionFlags(); 00442 } else { 00443 StringRef FlagsStr = getTok().getStringContents(); 00444 Lex(); 00445 extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); 00446 } 00447 00448 if (extraFlags == -1U) 00449 return TokError("unknown flag"); 00450 Flags |= extraFlags; 00451 00452 bool Mergeable = Flags & ELF::SHF_MERGE; 00453 bool Group = Flags & ELF::SHF_GROUP; 00454 if (Group && UseLastGroup) 00455 return TokError("Section cannot specifiy a group name while also acting " 00456 "as a member of the last group"); 00457 00458 if (getLexer().isNot(AsmToken::Comma)) { 00459 if (Mergeable) 00460 return TokError("Mergeable section must specify the type"); 00461 if (Group) 00462 return TokError("Group section must specify the type"); 00463 } else { 00464 Lex(); 00465 if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) || 00466 getLexer().is(AsmToken::String)) { 00467 if (!getLexer().is(AsmToken::String)) 00468 Lex(); 00469 } else 00470 return TokError("expected '@<type>', '%<type>' or \"<type>\""); 00471 00472 if (getParser().parseIdentifier(TypeName)) 00473 return TokError("expected identifier in directive"); 00474 00475 if (Mergeable) { 00476 if (getLexer().isNot(AsmToken::Comma)) 00477 return TokError("expected the entry size"); 00478 Lex(); 00479 if (getParser().parseAbsoluteExpression(Size)) 00480 return true; 00481 if (Size <= 0) 00482 return TokError("entry size must be positive"); 00483 } 00484 00485 if (Group) { 00486 if (getLexer().isNot(AsmToken::Comma)) 00487 return TokError("expected group name"); 00488 Lex(); 00489 if (getParser().parseIdentifier(GroupName)) 00490 return true; 00491 if (getLexer().is(AsmToken::Comma)) { 00492 Lex(); 00493 StringRef Linkage; 00494 if (getParser().parseIdentifier(Linkage)) 00495 return true; 00496 if (Linkage != "comdat") 00497 return TokError("Linkage must be 'comdat'"); 00498 } 00499 } 00500 } 00501 } 00502 00503 EndStmt: 00504 if (getLexer().isNot(AsmToken::EndOfStatement)) 00505 return TokError("unexpected token in directive"); 00506 00507 unsigned Type = ELF::SHT_PROGBITS; 00508 00509 if (TypeName.empty()) { 00510 if (SectionName.startswith(".note")) 00511 Type = ELF::SHT_NOTE; 00512 else if (SectionName == ".init_array") 00513 Type = ELF::SHT_INIT_ARRAY; 00514 else if (SectionName == ".fini_array") 00515 Type = ELF::SHT_FINI_ARRAY; 00516 else if (SectionName == ".preinit_array") 00517 Type = ELF::SHT_PREINIT_ARRAY; 00518 } else { 00519 if (TypeName == "init_array") 00520 Type = ELF::SHT_INIT_ARRAY; 00521 else if (TypeName == "fini_array") 00522 Type = ELF::SHT_FINI_ARRAY; 00523 else if (TypeName == "preinit_array") 00524 Type = ELF::SHT_PREINIT_ARRAY; 00525 else if (TypeName == "nobits") 00526 Type = ELF::SHT_NOBITS; 00527 else if (TypeName == "progbits") 00528 Type = ELF::SHT_PROGBITS; 00529 else if (TypeName == "note") 00530 Type = ELF::SHT_NOTE; 00531 else if (TypeName == "unwind") 00532 Type = ELF::SHT_X86_64_UNWIND; 00533 else 00534 return TokError("unknown section type"); 00535 } 00536 00537 if (UseLastGroup) { 00538 MCSectionSubPair CurrentSection = getStreamer().getCurrentSection(); 00539 if (const MCSectionELF *Section = 00540 cast_or_null<MCSectionELF>(CurrentSection.first)) 00541 if (const MCSymbol *Group = Section->getGroup()) { 00542 GroupName = Group->getName(); 00543 Flags |= ELF::SHF_GROUP; 00544 } 00545 } 00546 00547 SectionKind Kind = computeSectionKind(Flags, Size); 00548 const MCSection *ELFSection = getContext().getELFSection( 00549 SectionName, Type, Flags, Kind, Size, GroupName); 00550 getStreamer().SwitchSection(ELFSection, Subsection); 00551 00552 if (getContext().getGenDwarfForAssembly()) { 00553 auto &Sections = getContext().getGenDwarfSectionSyms(); 00554 auto InsertResult = Sections.insert( 00555 std::make_pair(ELFSection, std::make_pair(nullptr, nullptr))); 00556 if (InsertResult.second) { 00557 if (getContext().getDwarfVersion() <= 2) 00558 Error(loc, "DWARF2 only supports one section per compilation unit"); 00559 00560 MCSymbol *SectionStartSymbol = getContext().CreateTempSymbol(); 00561 getStreamer().EmitLabel(SectionStartSymbol); 00562 InsertResult.first->second.first = SectionStartSymbol; 00563 } 00564 } 00565 00566 return false; 00567 } 00568 00569 bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { 00570 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 00571 if (PreviousSection.first == nullptr) 00572 return TokError(".previous without corresponding .section"); 00573 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); 00574 00575 return false; 00576 } 00577 00578 static MCSymbolAttr MCAttrForString(StringRef Type) { 00579 return StringSwitch<MCSymbolAttr>(Type) 00580 .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction) 00581 .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject) 00582 .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS) 00583 .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon) 00584 .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType) 00585 .Cases("STT_GNU_IFUNC", "gnu_indirect_function", 00586 MCSA_ELF_TypeIndFunction) 00587 .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) 00588 .Default(MCSA_Invalid); 00589 } 00590 00591 /// ParseDirectiveELFType 00592 /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE> 00593 /// ::= .type identifier , #attribute 00594 /// ::= .type identifier , @attribute 00595 /// ::= .type identifier , %attribute 00596 /// ::= .type identifier , "attribute" 00597 bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { 00598 StringRef Name; 00599 if (getParser().parseIdentifier(Name)) 00600 return TokError("expected identifier in directive"); 00601 00602 // Handle the identifier as the key symbol. 00603 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 00604 00605 // NOTE the comma is optional in all cases. It is only documented as being 00606 // optional in the first case, however, GAS will silently treat the comma as 00607 // optional in all cases. Furthermore, although the documentation states that 00608 // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS 00609 // accepts both the upper case name as well as the lower case aliases. 00610 if (getLexer().is(AsmToken::Comma)) 00611 Lex(); 00612 00613 if (getLexer().isNot(AsmToken::Identifier) && 00614 getLexer().isNot(AsmToken::Hash) && getLexer().isNot(AsmToken::At) && 00615 getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::String)) 00616 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " 00617 "'%<type>' or \"<type>\""); 00618 00619 if (getLexer().isNot(AsmToken::String) && 00620 getLexer().isNot(AsmToken::Identifier)) 00621 Lex(); 00622 00623 SMLoc TypeLoc = getLexer().getLoc(); 00624 00625 StringRef Type; 00626 if (getParser().parseIdentifier(Type)) 00627 return TokError("expected symbol type in directive"); 00628 00629 MCSymbolAttr Attr = MCAttrForString(Type); 00630 if (Attr == MCSA_Invalid) 00631 return Error(TypeLoc, "unsupported attribute in '.type' directive"); 00632 00633 if (getLexer().isNot(AsmToken::EndOfStatement)) 00634 return TokError("unexpected token in '.type' directive"); 00635 Lex(); 00636 00637 getStreamer().EmitSymbolAttribute(Sym, Attr); 00638 00639 return false; 00640 } 00641 00642 /// ParseDirectiveIdent 00643 /// ::= .ident string 00644 bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { 00645 if (getLexer().isNot(AsmToken::String)) 00646 return TokError("unexpected token in '.ident' directive"); 00647 00648 StringRef Data = getTok().getIdentifier(); 00649 00650 Lex(); 00651 00652 getStreamer().EmitIdent(Data); 00653 return false; 00654 } 00655 00656 /// ParseDirectiveSymver 00657 /// ::= .symver foo, bar2@zed 00658 bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { 00659 StringRef Name; 00660 if (getParser().parseIdentifier(Name)) 00661 return TokError("expected identifier in directive"); 00662 00663 if (getLexer().isNot(AsmToken::Comma)) 00664 return TokError("expected a comma"); 00665 00666 // ARM assembly uses @ for a comment... 00667 // except when parsing the second parameter of the .symver directive. 00668 // Force the next symbol to allow @ in the identifier, which is 00669 // required for this directive and then reset it to its initial state. 00670 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier(); 00671 getLexer().setAllowAtInIdentifier(true); 00672 Lex(); 00673 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier); 00674 00675 StringRef AliasName; 00676 if (getParser().parseIdentifier(AliasName)) 00677 return TokError("expected identifier in directive"); 00678 00679 if (AliasName.find('@') == StringRef::npos) 00680 return TokError("expected a '@' in the name"); 00681 00682 MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); 00683 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 00684 const MCExpr *Value = MCSymbolRefExpr::Create(Sym, getContext()); 00685 00686 getStreamer().EmitAssignment(Alias, Value); 00687 return false; 00688 } 00689 00690 /// ParseDirectiveVersion 00691 /// ::= .version string 00692 bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) { 00693 if (getLexer().isNot(AsmToken::String)) 00694 return TokError("unexpected token in '.version' directive"); 00695 00696 StringRef Data = getTok().getIdentifier(); 00697 00698 Lex(); 00699 00700 const MCSection *Note = 00701 getContext().getELFSection(".note", ELF::SHT_NOTE, 0, 00702 SectionKind::getReadOnly()); 00703 00704 getStreamer().PushSection(); 00705 getStreamer().SwitchSection(Note); 00706 getStreamer().EmitIntValue(Data.size()+1, 4); // namesz. 00707 getStreamer().EmitIntValue(0, 4); // descsz = 0 (no description). 00708 getStreamer().EmitIntValue(1, 4); // type = NT_VERSION. 00709 getStreamer().EmitBytes(Data); // name. 00710 getStreamer().EmitIntValue(0, 1); // terminate the string. 00711 getStreamer().EmitValueToAlignment(4); // ensure 4 byte alignment. 00712 getStreamer().PopSection(); 00713 return false; 00714 } 00715 00716 /// ParseDirectiveWeakref 00717 /// ::= .weakref foo, bar 00718 bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { 00719 // FIXME: Share code with the other alias building directives. 00720 00721 StringRef AliasName; 00722 if (getParser().parseIdentifier(AliasName)) 00723 return TokError("expected identifier in directive"); 00724 00725 if (getLexer().isNot(AsmToken::Comma)) 00726 return TokError("expected a comma"); 00727 00728 Lex(); 00729 00730 StringRef Name; 00731 if (getParser().parseIdentifier(Name)) 00732 return TokError("expected identifier in directive"); 00733 00734 MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); 00735 00736 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 00737 00738 getStreamer().EmitWeakReference(Alias, Sym); 00739 return false; 00740 } 00741 00742 bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) { 00743 const MCExpr *Subsection = nullptr; 00744 if (getLexer().isNot(AsmToken::EndOfStatement)) { 00745 if (getParser().parseExpression(Subsection)) 00746 return true; 00747 } 00748 00749 if (getLexer().isNot(AsmToken::EndOfStatement)) 00750 return TokError("unexpected token in directive"); 00751 00752 getStreamer().SubSection(Subsection); 00753 return false; 00754 } 00755 00756 namespace llvm { 00757 00758 MCAsmParserExtension *createELFAsmParser() { 00759 return new ELFAsmParser; 00760 } 00761 00762 }