LCOV - code coverage report
Current view: top level - lib/MC/MCParser - ELFAsmParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 415 465 89.2 %
Date: 2017-09-14 15:23:50 Functions: 26 27 96.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13