10b57cec5SDimitry Andric //===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 906c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h" 100b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 110b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h" 120b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 130b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 140b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCDirectives.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParserExtension.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 230b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h" 240b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 250b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 260b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h" 270b57cec5SDimitry Andric #include <cassert> 280b57cec5SDimitry Andric #include <cstdint> 290b57cec5SDimitry Andric #include <utility> 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric using namespace llvm; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric namespace { 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric class ELFAsmParser : public MCAsmParserExtension { 360b57cec5SDimitry Andric template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)> 370b57cec5SDimitry Andric void addDirectiveHandler(StringRef Directive) { 380b57cec5SDimitry Andric MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( 390b57cec5SDimitry Andric this, HandleDirective<ELFAsmParser, HandlerMethod>); 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric getParser().addDirectiveHandler(Directive, Handler); 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, 450b57cec5SDimitry Andric SectionKind Kind); 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric public: 480b57cec5SDimitry Andric ELFAsmParser() { BracketExpressionsSupported = true; } 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric void Initialize(MCAsmParser &Parser) override { 510b57cec5SDimitry Andric // Call the base implementation. 520b57cec5SDimitry Andric this->MCAsmParserExtension::Initialize(Parser); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data"); 550b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text"); 560b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss"); 570b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata"); 580b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata"); 590b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss"); 600b57cec5SDimitry Andric addDirectiveHandler< 610b57cec5SDimitry Andric &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel"); 620b57cec5SDimitry Andric addDirectiveHandler< 630b57cec5SDimitry Andric &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro"); 640b57cec5SDimitry Andric addDirectiveHandler< 650b57cec5SDimitry Andric &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame"); 660b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section"); 670b57cec5SDimitry Andric addDirectiveHandler< 680b57cec5SDimitry Andric &ELFAsmParser::ParseDirectivePushSection>(".pushsection"); 690b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection"); 700b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size"); 710b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); 720b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type"); 730b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident"); 740b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver"); 750b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version"); 760b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref"); 770b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); 780b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local"); 790b57cec5SDimitry Andric addDirectiveHandler< 800b57cec5SDimitry Andric &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected"); 810b57cec5SDimitry Andric addDirectiveHandler< 820b57cec5SDimitry Andric &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal"); 830b57cec5SDimitry Andric addDirectiveHandler< 840b57cec5SDimitry Andric &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden"); 850b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection"); 860b57cec5SDimitry Andric addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(".cg_profile"); 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is 900b57cec5SDimitry Andric // the best way for us to get access to it? 910b57cec5SDimitry Andric bool ParseSectionDirectiveData(StringRef, SMLoc) { 920b57cec5SDimitry Andric return ParseSectionSwitch(".data", ELF::SHT_PROGBITS, 930b57cec5SDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC, 940b57cec5SDimitry Andric SectionKind::getData()); 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric bool ParseSectionDirectiveText(StringRef, SMLoc) { 970b57cec5SDimitry Andric return ParseSectionSwitch(".text", ELF::SHT_PROGBITS, 980b57cec5SDimitry Andric ELF::SHF_EXECINSTR | 990b57cec5SDimitry Andric ELF::SHF_ALLOC, SectionKind::getText()); 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric bool ParseSectionDirectiveBSS(StringRef, SMLoc) { 1020b57cec5SDimitry Andric return ParseSectionSwitch(".bss", ELF::SHT_NOBITS, 1030b57cec5SDimitry Andric ELF::SHF_WRITE | 1040b57cec5SDimitry Andric ELF::SHF_ALLOC, SectionKind::getBSS()); 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric bool ParseSectionDirectiveRoData(StringRef, SMLoc) { 1070b57cec5SDimitry Andric return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS, 1080b57cec5SDimitry Andric ELF::SHF_ALLOC, 1090b57cec5SDimitry Andric SectionKind::getReadOnly()); 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric bool ParseSectionDirectiveTData(StringRef, SMLoc) { 1120b57cec5SDimitry Andric return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS, 1130b57cec5SDimitry Andric ELF::SHF_ALLOC | 1140b57cec5SDimitry Andric ELF::SHF_TLS | ELF::SHF_WRITE, 1150b57cec5SDimitry Andric SectionKind::getThreadData()); 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric bool ParseSectionDirectiveTBSS(StringRef, SMLoc) { 1180b57cec5SDimitry Andric return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS, 1190b57cec5SDimitry Andric ELF::SHF_ALLOC | 1200b57cec5SDimitry Andric ELF::SHF_TLS | ELF::SHF_WRITE, 1210b57cec5SDimitry Andric SectionKind::getThreadBSS()); 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric bool ParseSectionDirectiveDataRel(StringRef, SMLoc) { 1240b57cec5SDimitry Andric return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS, 1250b57cec5SDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE, 1260b57cec5SDimitry Andric SectionKind::getData()); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) { 1290b57cec5SDimitry Andric return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS, 1300b57cec5SDimitry Andric ELF::SHF_ALLOC | 1310b57cec5SDimitry Andric ELF::SHF_WRITE, 1320b57cec5SDimitry Andric SectionKind::getReadOnlyWithRel()); 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) { 1350b57cec5SDimitry Andric return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS, 1360b57cec5SDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE, 1370b57cec5SDimitry Andric SectionKind::getData()); 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric bool ParseDirectivePushSection(StringRef, SMLoc); 1400b57cec5SDimitry Andric bool ParseDirectivePopSection(StringRef, SMLoc); 1410b57cec5SDimitry Andric bool ParseDirectiveSection(StringRef, SMLoc); 1420b57cec5SDimitry Andric bool ParseDirectiveSize(StringRef, SMLoc); 1430b57cec5SDimitry Andric bool ParseDirectivePrevious(StringRef, SMLoc); 1440b57cec5SDimitry Andric bool ParseDirectiveType(StringRef, SMLoc); 1450b57cec5SDimitry Andric bool ParseDirectiveIdent(StringRef, SMLoc); 1460b57cec5SDimitry Andric bool ParseDirectiveSymver(StringRef, SMLoc); 1470b57cec5SDimitry Andric bool ParseDirectiveVersion(StringRef, SMLoc); 1480b57cec5SDimitry Andric bool ParseDirectiveWeakref(StringRef, SMLoc); 1490b57cec5SDimitry Andric bool ParseDirectiveSymbolAttribute(StringRef, SMLoc); 1500b57cec5SDimitry Andric bool ParseDirectiveSubsection(StringRef, SMLoc); 1510b57cec5SDimitry Andric bool ParseDirectiveCGProfile(StringRef, SMLoc); 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric private: 1540b57cec5SDimitry Andric bool ParseSectionName(StringRef &SectionName); 1550b57cec5SDimitry Andric bool ParseSectionArguments(bool IsPush, SMLoc loc); 1560b57cec5SDimitry Andric unsigned parseSunStyleSectionFlags(); 1570b57cec5SDimitry Andric bool maybeParseSectionType(StringRef &TypeName); 1580b57cec5SDimitry Andric bool parseMergeSize(int64_t &Size); 159fe6060f1SDimitry Andric bool parseGroup(StringRef &GroupName, bool &IsComdat); 1605ffd83dbSDimitry Andric bool parseLinkedToSym(MCSymbolELF *&LinkedToSym); 1610b57cec5SDimitry Andric bool maybeParseUniqueID(int64_t &UniqueID); 1620b57cec5SDimitry Andric }; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric } // end anonymous namespace 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric /// ParseDirectiveSymbolAttribute 1670b57cec5SDimitry Andric /// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] 1680b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { 1690b57cec5SDimitry Andric MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) 1700b57cec5SDimitry Andric .Case(".weak", MCSA_Weak) 1710b57cec5SDimitry Andric .Case(".local", MCSA_Local) 1720b57cec5SDimitry Andric .Case(".hidden", MCSA_Hidden) 1730b57cec5SDimitry Andric .Case(".internal", MCSA_Internal) 1740b57cec5SDimitry Andric .Case(".protected", MCSA_Protected) 1750b57cec5SDimitry Andric .Default(MCSA_Invalid); 1760b57cec5SDimitry Andric assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); 1770b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) { 1780b57cec5SDimitry Andric while (true) { 1790b57cec5SDimitry Andric StringRef Name; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric if (getParser().parseIdentifier(Name)) 182bdd1243dSDimitry Andric return TokError("expected identifier"); 1830b57cec5SDimitry Andric 184fe6060f1SDimitry Andric if (getParser().discardLTOSymbol(Name)) { 185fe6060f1SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 186fe6060f1SDimitry Andric break; 187fe6060f1SDimitry Andric continue; 188fe6060f1SDimitry Andric } 189fe6060f1SDimitry Andric 1900b57cec5SDimitry Andric MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 1910b57cec5SDimitry Andric 1925ffd83dbSDimitry Andric getStreamer().emitSymbolAttribute(Sym, Attr); 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 1950b57cec5SDimitry Andric break; 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 198bdd1243dSDimitry Andric return TokError("expected comma"); 1990b57cec5SDimitry Andric Lex(); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric Lex(); 2040b57cec5SDimitry Andric return false; 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type, 2080b57cec5SDimitry Andric unsigned Flags, SectionKind Kind) { 2090b57cec5SDimitry Andric const MCExpr *Subsection = nullptr; 2100b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) { 2110b57cec5SDimitry Andric if (getParser().parseExpression(Subsection)) 2120b57cec5SDimitry Andric return true; 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric Lex(); 2150b57cec5SDimitry Andric 21681ad6265SDimitry Andric getStreamer().switchSection(getContext().getELFSection(Section, Type, Flags), 2170b57cec5SDimitry Andric Subsection); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric return false; 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) { 2230b57cec5SDimitry Andric StringRef Name; 2240b57cec5SDimitry Andric if (getParser().parseIdentifier(Name)) 225bdd1243dSDimitry Andric return TokError("expected identifier"); 2260b57cec5SDimitry Andric MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name)); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 229bdd1243dSDimitry Andric return TokError("expected comma"); 2300b57cec5SDimitry Andric Lex(); 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric const MCExpr *Expr; 2330b57cec5SDimitry Andric if (getParser().parseExpression(Expr)) 2340b57cec5SDimitry Andric return true; 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 237bdd1243dSDimitry Andric return TokError("unexpected token"); 2380b57cec5SDimitry Andric Lex(); 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric getStreamer().emitELFSize(Sym, Expr); 2410b57cec5SDimitry Andric return false; 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { 2450b57cec5SDimitry Andric // A section name can contain -, so we cannot just use 2460b57cec5SDimitry Andric // parseIdentifier. 2470b57cec5SDimitry Andric SMLoc FirstLoc = getLexer().getLoc(); 2480b57cec5SDimitry Andric unsigned Size = 0; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric if (getLexer().is(AsmToken::String)) { 2510b57cec5SDimitry Andric SectionName = getTok().getIdentifier(); 2520b57cec5SDimitry Andric Lex(); 2530b57cec5SDimitry Andric return false; 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric while (!getParser().hasPendingError()) { 2570b57cec5SDimitry Andric SMLoc PrevLoc = getLexer().getLoc(); 2580b57cec5SDimitry Andric if (getLexer().is(AsmToken::Comma) || 2590b57cec5SDimitry Andric getLexer().is(AsmToken::EndOfStatement)) 2600b57cec5SDimitry Andric break; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric unsigned CurSize; 2630b57cec5SDimitry Andric if (getLexer().is(AsmToken::String)) { 2640b57cec5SDimitry Andric CurSize = getTok().getIdentifier().size() + 2; 2650b57cec5SDimitry Andric Lex(); 2660b57cec5SDimitry Andric } else if (getLexer().is(AsmToken::Identifier)) { 2670b57cec5SDimitry Andric CurSize = getTok().getIdentifier().size(); 2680b57cec5SDimitry Andric Lex(); 2690b57cec5SDimitry Andric } else { 2700b57cec5SDimitry Andric CurSize = getTok().getString().size(); 2710b57cec5SDimitry Andric Lex(); 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric Size += CurSize; 2740b57cec5SDimitry Andric SectionName = StringRef(FirstLoc.getPointer(), Size); 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric // Make sure the following token is adjacent. 2770b57cec5SDimitry Andric if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer()) 2780b57cec5SDimitry Andric break; 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric if (Size == 0) 2810b57cec5SDimitry Andric return true; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric return false; 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 28681ad6265SDimitry Andric static unsigned parseSectionFlags(const Triple &TT, StringRef flagsStr, 28781ad6265SDimitry Andric bool *UseLastGroup) { 2880b57cec5SDimitry Andric unsigned flags = 0; 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric // If a valid numerical value is set for the section flag, use it verbatim 2910b57cec5SDimitry Andric if (!flagsStr.getAsInteger(0, flags)) 2920b57cec5SDimitry Andric return flags; 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric for (char i : flagsStr) { 2950b57cec5SDimitry Andric switch (i) { 2960b57cec5SDimitry Andric case 'a': 2970b57cec5SDimitry Andric flags |= ELF::SHF_ALLOC; 2980b57cec5SDimitry Andric break; 2990b57cec5SDimitry Andric case 'e': 3000b57cec5SDimitry Andric flags |= ELF::SHF_EXCLUDE; 3010b57cec5SDimitry Andric break; 3020b57cec5SDimitry Andric case 'x': 3030b57cec5SDimitry Andric flags |= ELF::SHF_EXECINSTR; 3040b57cec5SDimitry Andric break; 3050b57cec5SDimitry Andric case 'w': 3060b57cec5SDimitry Andric flags |= ELF::SHF_WRITE; 3070b57cec5SDimitry Andric break; 3080b57cec5SDimitry Andric case 'o': 3090b57cec5SDimitry Andric flags |= ELF::SHF_LINK_ORDER; 3100b57cec5SDimitry Andric break; 3110b57cec5SDimitry Andric case 'M': 3120b57cec5SDimitry Andric flags |= ELF::SHF_MERGE; 3130b57cec5SDimitry Andric break; 3140b57cec5SDimitry Andric case 'S': 3150b57cec5SDimitry Andric flags |= ELF::SHF_STRINGS; 3160b57cec5SDimitry Andric break; 3170b57cec5SDimitry Andric case 'T': 3180b57cec5SDimitry Andric flags |= ELF::SHF_TLS; 3190b57cec5SDimitry Andric break; 3200b57cec5SDimitry Andric case 'c': 32106c3fb27SDimitry Andric if (TT.getArch() != Triple::xcore) 32206c3fb27SDimitry Andric return -1U; 3230b57cec5SDimitry Andric flags |= ELF::XCORE_SHF_CP_SECTION; 3240b57cec5SDimitry Andric break; 3250b57cec5SDimitry Andric case 'd': 32606c3fb27SDimitry Andric if (TT.getArch() != Triple::xcore) 32706c3fb27SDimitry Andric return -1U; 3280b57cec5SDimitry Andric flags |= ELF::XCORE_SHF_DP_SECTION; 3290b57cec5SDimitry Andric break; 3300b57cec5SDimitry Andric case 'y': 33106c3fb27SDimitry Andric if (!(TT.isARM() || TT.isThumb())) 33206c3fb27SDimitry Andric return -1U; 3330b57cec5SDimitry Andric flags |= ELF::SHF_ARM_PURECODE; 3340b57cec5SDimitry Andric break; 3350b57cec5SDimitry Andric case 's': 33606c3fb27SDimitry Andric if (TT.getArch() != Triple::hexagon) 33706c3fb27SDimitry Andric return -1U; 3380b57cec5SDimitry Andric flags |= ELF::SHF_HEX_GPREL; 3390b57cec5SDimitry Andric break; 3400b57cec5SDimitry Andric case 'G': 3410b57cec5SDimitry Andric flags |= ELF::SHF_GROUP; 3420b57cec5SDimitry Andric break; 34306c3fb27SDimitry Andric case 'l': 34406c3fb27SDimitry Andric if (TT.getArch() != Triple::x86_64) 34506c3fb27SDimitry Andric return -1U; 34606c3fb27SDimitry Andric flags |= ELF::SHF_X86_64_LARGE; 34706c3fb27SDimitry Andric break; 348fe6060f1SDimitry Andric case 'R': 34981ad6265SDimitry Andric if (TT.isOSSolaris()) 35081ad6265SDimitry Andric flags |= ELF::SHF_SUNW_NODISCARD; 35181ad6265SDimitry Andric else 352fe6060f1SDimitry Andric flags |= ELF::SHF_GNU_RETAIN; 353fe6060f1SDimitry Andric break; 3540b57cec5SDimitry Andric case '?': 3550b57cec5SDimitry Andric *UseLastGroup = true; 3560b57cec5SDimitry Andric break; 3570b57cec5SDimitry Andric default: 3580b57cec5SDimitry Andric return -1U; 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric return flags; 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric unsigned ELFAsmParser::parseSunStyleSectionFlags() { 3660b57cec5SDimitry Andric unsigned flags = 0; 3670b57cec5SDimitry Andric while (getLexer().is(AsmToken::Hash)) { 3680b57cec5SDimitry Andric Lex(); // Eat the #. 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric if (!getLexer().is(AsmToken::Identifier)) 3710b57cec5SDimitry Andric return -1U; 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric StringRef flagId = getTok().getIdentifier(); 3740b57cec5SDimitry Andric if (flagId == "alloc") 3750b57cec5SDimitry Andric flags |= ELF::SHF_ALLOC; 3760b57cec5SDimitry Andric else if (flagId == "execinstr") 3770b57cec5SDimitry Andric flags |= ELF::SHF_EXECINSTR; 3780b57cec5SDimitry Andric else if (flagId == "write") 3790b57cec5SDimitry Andric flags |= ELF::SHF_WRITE; 3800b57cec5SDimitry Andric else if (flagId == "tls") 3810b57cec5SDimitry Andric flags |= ELF::SHF_TLS; 3820b57cec5SDimitry Andric else 3830b57cec5SDimitry Andric return -1U; 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric Lex(); // Eat the flag. 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric if (!getLexer().is(AsmToken::Comma)) 3880b57cec5SDimitry Andric break; 3890b57cec5SDimitry Andric Lex(); // Eat the comma. 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric return flags; 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) { 39681ad6265SDimitry Andric getStreamer().pushSection(); 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric if (ParseSectionArguments(/*IsPush=*/true, loc)) { 39981ad6265SDimitry Andric getStreamer().popSection(); 4000b57cec5SDimitry Andric return true; 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric return false; 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { 40781ad6265SDimitry Andric if (!getStreamer().popSection()) 4080b57cec5SDimitry Andric return TokError(".popsection without corresponding .pushsection"); 4090b57cec5SDimitry Andric return false; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) { 4130b57cec5SDimitry Andric return ParseSectionArguments(/*IsPush=*/false, loc); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) { 4170b57cec5SDimitry Andric MCAsmLexer &L = getLexer(); 4180b57cec5SDimitry Andric if (L.isNot(AsmToken::Comma)) 4190b57cec5SDimitry Andric return false; 4200b57cec5SDimitry Andric Lex(); 4210b57cec5SDimitry Andric if (L.isNot(AsmToken::At) && L.isNot(AsmToken::Percent) && 4220b57cec5SDimitry Andric L.isNot(AsmToken::String)) { 4230b57cec5SDimitry Andric if (L.getAllowAtInIdentifier()) 4240b57cec5SDimitry Andric return TokError("expected '@<type>', '%<type>' or \"<type>\""); 4250b57cec5SDimitry Andric else 4260b57cec5SDimitry Andric return TokError("expected '%<type>' or \"<type>\""); 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric if (!L.is(AsmToken::String)) 4290b57cec5SDimitry Andric Lex(); 4300b57cec5SDimitry Andric if (L.is(AsmToken::Integer)) { 4310b57cec5SDimitry Andric TypeName = getTok().getString(); 4320b57cec5SDimitry Andric Lex(); 4330b57cec5SDimitry Andric } else if (getParser().parseIdentifier(TypeName)) 434bdd1243dSDimitry Andric return TokError("expected identifier"); 4350b57cec5SDimitry Andric return false; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric bool ELFAsmParser::parseMergeSize(int64_t &Size) { 4390b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 4400b57cec5SDimitry Andric return TokError("expected the entry size"); 4410b57cec5SDimitry Andric Lex(); 4420b57cec5SDimitry Andric if (getParser().parseAbsoluteExpression(Size)) 4430b57cec5SDimitry Andric return true; 4440b57cec5SDimitry Andric if (Size <= 0) 4450b57cec5SDimitry Andric return TokError("entry size must be positive"); 4460b57cec5SDimitry Andric return false; 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 449fe6060f1SDimitry Andric bool ELFAsmParser::parseGroup(StringRef &GroupName, bool &IsComdat) { 4500b57cec5SDimitry Andric MCAsmLexer &L = getLexer(); 4510b57cec5SDimitry Andric if (L.isNot(AsmToken::Comma)) 4520b57cec5SDimitry Andric return TokError("expected group name"); 4530b57cec5SDimitry Andric Lex(); 4540b57cec5SDimitry Andric if (L.is(AsmToken::Integer)) { 4550b57cec5SDimitry Andric GroupName = getTok().getString(); 4560b57cec5SDimitry Andric Lex(); 4570b57cec5SDimitry Andric } else if (getParser().parseIdentifier(GroupName)) { 4580b57cec5SDimitry Andric return TokError("invalid group name"); 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric if (L.is(AsmToken::Comma)) { 4610b57cec5SDimitry Andric Lex(); 4620b57cec5SDimitry Andric StringRef Linkage; 4630b57cec5SDimitry Andric if (getParser().parseIdentifier(Linkage)) 4640b57cec5SDimitry Andric return TokError("invalid linkage"); 4650b57cec5SDimitry Andric if (Linkage != "comdat") 4660b57cec5SDimitry Andric return TokError("Linkage must be 'comdat'"); 467fe6060f1SDimitry Andric IsComdat = true; 468fe6060f1SDimitry Andric } else { 469fe6060f1SDimitry Andric IsComdat = false; 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric return false; 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric 4745ffd83dbSDimitry Andric bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) { 4750b57cec5SDimitry Andric MCAsmLexer &L = getLexer(); 4760b57cec5SDimitry Andric if (L.isNot(AsmToken::Comma)) 4775ffd83dbSDimitry Andric return TokError("expected linked-to symbol"); 4780b57cec5SDimitry Andric Lex(); 4790b57cec5SDimitry Andric StringRef Name; 4805ffd83dbSDimitry Andric SMLoc StartLoc = L.getLoc(); 481e8d8bef9SDimitry Andric if (getParser().parseIdentifier(Name)) { 482e8d8bef9SDimitry Andric if (getParser().getTok().getString() == "0") { 483e8d8bef9SDimitry Andric getParser().Lex(); 484e8d8bef9SDimitry Andric LinkedToSym = nullptr; 485e8d8bef9SDimitry Andric return false; 486e8d8bef9SDimitry Andric } 4875ffd83dbSDimitry Andric return TokError("invalid linked-to symbol"); 488e8d8bef9SDimitry Andric } 4895ffd83dbSDimitry Andric LinkedToSym = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name)); 4905ffd83dbSDimitry Andric if (!LinkedToSym || !LinkedToSym->isInSection()) 4915ffd83dbSDimitry Andric return Error(StartLoc, "linked-to symbol is not in a section: " + Name); 4920b57cec5SDimitry Andric return false; 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) { 4960b57cec5SDimitry Andric MCAsmLexer &L = getLexer(); 4970b57cec5SDimitry Andric if (L.isNot(AsmToken::Comma)) 4980b57cec5SDimitry Andric return false; 4990b57cec5SDimitry Andric Lex(); 5000b57cec5SDimitry Andric StringRef UniqueStr; 5010b57cec5SDimitry Andric if (getParser().parseIdentifier(UniqueStr)) 502bdd1243dSDimitry Andric return TokError("expected identifier"); 5030b57cec5SDimitry Andric if (UniqueStr != "unique") 5040b57cec5SDimitry Andric return TokError("expected 'unique'"); 5050b57cec5SDimitry Andric if (L.isNot(AsmToken::Comma)) 5060b57cec5SDimitry Andric return TokError("expected commma"); 5070b57cec5SDimitry Andric Lex(); 5080b57cec5SDimitry Andric if (getParser().parseAbsoluteExpression(UniqueID)) 5090b57cec5SDimitry Andric return true; 5100b57cec5SDimitry Andric if (UniqueID < 0) 5110b57cec5SDimitry Andric return TokError("unique id must be positive"); 5120b57cec5SDimitry Andric if (!isUInt<32>(UniqueID) || UniqueID == ~0U) 5130b57cec5SDimitry Andric return TokError("unique id is too large"); 5140b57cec5SDimitry Andric return false; 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric static bool hasPrefix(StringRef SectionName, StringRef Prefix) { 51804eeddc0SDimitry Andric return SectionName.consume_front(Prefix) && 51904eeddc0SDimitry Andric (SectionName.empty() || SectionName[0] == '.'); 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric 522349cc55cSDimitry Andric static bool allowSectionTypeMismatch(const Triple &TT, StringRef SectionName, 523349cc55cSDimitry Andric unsigned Type) { 524349cc55cSDimitry Andric if (TT.getArch() == Triple::x86_64) { 525349cc55cSDimitry Andric // x86-64 psABI names SHT_X86_64_UNWIND as the canonical type for .eh_frame, 526349cc55cSDimitry Andric // but GNU as emits SHT_PROGBITS .eh_frame for .cfi_* directives. Don't 527349cc55cSDimitry Andric // error for SHT_PROGBITS .eh_frame 528349cc55cSDimitry Andric return SectionName == ".eh_frame" && Type == ELF::SHT_PROGBITS; 529349cc55cSDimitry Andric } 530349cc55cSDimitry Andric if (TT.isMIPS()) { 531349cc55cSDimitry Andric // MIPS .debug_* sections should have SHT_MIPS_DWARF section type to 532349cc55cSDimitry Andric // distinguish among sections contain DWARF and ECOFF debug formats, 533349cc55cSDimitry Andric // but in assembly files these sections have SHT_PROGBITS type. 5345f757f3fSDimitry Andric return SectionName.starts_with(".debug_") && Type == ELF::SHT_PROGBITS; 535349cc55cSDimitry Andric } 536349cc55cSDimitry Andric return false; 537349cc55cSDimitry Andric } 538349cc55cSDimitry Andric 5390b57cec5SDimitry Andric bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { 5400b57cec5SDimitry Andric StringRef SectionName; 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric if (ParseSectionName(SectionName)) 543bdd1243dSDimitry Andric return TokError("expected identifier"); 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric StringRef TypeName; 5460b57cec5SDimitry Andric int64_t Size = 0; 5470b57cec5SDimitry Andric StringRef GroupName; 548fe6060f1SDimitry Andric bool IsComdat = false; 5490b57cec5SDimitry Andric unsigned Flags = 0; 550fe6060f1SDimitry Andric unsigned extraFlags = 0; 5510b57cec5SDimitry Andric const MCExpr *Subsection = nullptr; 5520b57cec5SDimitry Andric bool UseLastGroup = false; 5535ffd83dbSDimitry Andric MCSymbolELF *LinkedToSym = nullptr; 5540b57cec5SDimitry Andric int64_t UniqueID = ~0; 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric // Set the defaults first. 55704eeddc0SDimitry Andric if (hasPrefix(SectionName, ".rodata") || SectionName == ".rodata1") 5580b57cec5SDimitry Andric Flags |= ELF::SHF_ALLOC; 5590b57cec5SDimitry Andric else if (SectionName == ".fini" || SectionName == ".init" || 56004eeddc0SDimitry Andric hasPrefix(SectionName, ".text")) 5610b57cec5SDimitry Andric Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; 56204eeddc0SDimitry Andric else if (hasPrefix(SectionName, ".data") || SectionName == ".data1" || 56304eeddc0SDimitry Andric hasPrefix(SectionName, ".bss") || 56404eeddc0SDimitry Andric hasPrefix(SectionName, ".init_array") || 56504eeddc0SDimitry Andric hasPrefix(SectionName, ".fini_array") || 56604eeddc0SDimitry Andric hasPrefix(SectionName, ".preinit_array")) 5670b57cec5SDimitry Andric Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE; 56804eeddc0SDimitry Andric else if (hasPrefix(SectionName, ".tdata") || hasPrefix(SectionName, ".tbss")) 5690b57cec5SDimitry Andric Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS; 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric if (getLexer().is(AsmToken::Comma)) { 5720b57cec5SDimitry Andric Lex(); 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric if (IsPush && getLexer().isNot(AsmToken::String)) { 5750b57cec5SDimitry Andric if (getParser().parseExpression(Subsection)) 5760b57cec5SDimitry Andric return true; 5770b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 5780b57cec5SDimitry Andric goto EndStmt; 5790b57cec5SDimitry Andric Lex(); 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::String)) { 583a4a491e2SDimitry Andric if (getLexer().isNot(AsmToken::Hash)) 584bdd1243dSDimitry Andric return TokError("expected string"); 5850b57cec5SDimitry Andric extraFlags = parseSunStyleSectionFlags(); 5860b57cec5SDimitry Andric } else { 5870b57cec5SDimitry Andric StringRef FlagsStr = getTok().getStringContents(); 5880b57cec5SDimitry Andric Lex(); 58981ad6265SDimitry Andric extraFlags = parseSectionFlags(getContext().getTargetTriple(), FlagsStr, 59081ad6265SDimitry Andric &UseLastGroup); 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric if (extraFlags == -1U) 5940b57cec5SDimitry Andric return TokError("unknown flag"); 5950b57cec5SDimitry Andric Flags |= extraFlags; 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric bool Mergeable = Flags & ELF::SHF_MERGE; 5980b57cec5SDimitry Andric bool Group = Flags & ELF::SHF_GROUP; 5990b57cec5SDimitry Andric if (Group && UseLastGroup) 6000b57cec5SDimitry Andric return TokError("Section cannot specifiy a group name while also acting " 6010b57cec5SDimitry Andric "as a member of the last group"); 6020b57cec5SDimitry Andric 6030b57cec5SDimitry Andric if (maybeParseSectionType(TypeName)) 6040b57cec5SDimitry Andric return true; 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric MCAsmLexer &L = getLexer(); 6070b57cec5SDimitry Andric if (TypeName.empty()) { 6080b57cec5SDimitry Andric if (Mergeable) 6090b57cec5SDimitry Andric return TokError("Mergeable section must specify the type"); 6100b57cec5SDimitry Andric if (Group) 6110b57cec5SDimitry Andric return TokError("Group section must specify the type"); 6120b57cec5SDimitry Andric if (L.isNot(AsmToken::EndOfStatement)) 613bdd1243dSDimitry Andric return TokError("expected end of directive"); 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric if (Mergeable) 6170b57cec5SDimitry Andric if (parseMergeSize(Size)) 6180b57cec5SDimitry Andric return true; 6190b57cec5SDimitry Andric if (Flags & ELF::SHF_LINK_ORDER) 6205ffd83dbSDimitry Andric if (parseLinkedToSym(LinkedToSym)) 6210b57cec5SDimitry Andric return true; 622297eecfbSDimitry Andric if (Group) 623297eecfbSDimitry Andric if (parseGroup(GroupName, IsComdat)) 624297eecfbSDimitry Andric return true; 6250b57cec5SDimitry Andric if (maybeParseUniqueID(UniqueID)) 6260b57cec5SDimitry Andric return true; 6270b57cec5SDimitry Andric } 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric EndStmt: 6300b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 631bdd1243dSDimitry Andric return TokError("expected end of directive"); 6320b57cec5SDimitry Andric Lex(); 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric unsigned Type = ELF::SHT_PROGBITS; 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric if (TypeName.empty()) { 6375f757f3fSDimitry Andric if (SectionName.starts_with(".note")) 6380b57cec5SDimitry Andric Type = ELF::SHT_NOTE; 63904eeddc0SDimitry Andric else if (hasPrefix(SectionName, ".init_array")) 6400b57cec5SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 64104eeddc0SDimitry Andric else if (hasPrefix(SectionName, ".bss")) 6420b57cec5SDimitry Andric Type = ELF::SHT_NOBITS; 64304eeddc0SDimitry Andric else if (hasPrefix(SectionName, ".tbss")) 6440b57cec5SDimitry Andric Type = ELF::SHT_NOBITS; 64504eeddc0SDimitry Andric else if (hasPrefix(SectionName, ".fini_array")) 6460b57cec5SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 64704eeddc0SDimitry Andric else if (hasPrefix(SectionName, ".preinit_array")) 6480b57cec5SDimitry Andric Type = ELF::SHT_PREINIT_ARRAY; 6490b57cec5SDimitry Andric } else { 6500b57cec5SDimitry Andric if (TypeName == "init_array") 6510b57cec5SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 6520b57cec5SDimitry Andric else if (TypeName == "fini_array") 6530b57cec5SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 6540b57cec5SDimitry Andric else if (TypeName == "preinit_array") 6550b57cec5SDimitry Andric Type = ELF::SHT_PREINIT_ARRAY; 6560b57cec5SDimitry Andric else if (TypeName == "nobits") 6570b57cec5SDimitry Andric Type = ELF::SHT_NOBITS; 6580b57cec5SDimitry Andric else if (TypeName == "progbits") 6590b57cec5SDimitry Andric Type = ELF::SHT_PROGBITS; 6600b57cec5SDimitry Andric else if (TypeName == "note") 6610b57cec5SDimitry Andric Type = ELF::SHT_NOTE; 6620b57cec5SDimitry Andric else if (TypeName == "unwind") 6630b57cec5SDimitry Andric Type = ELF::SHT_X86_64_UNWIND; 6640b57cec5SDimitry Andric else if (TypeName == "llvm_odrtab") 6650b57cec5SDimitry Andric Type = ELF::SHT_LLVM_ODRTAB; 6660b57cec5SDimitry Andric else if (TypeName == "llvm_linker_options") 6670b57cec5SDimitry Andric Type = ELF::SHT_LLVM_LINKER_OPTIONS; 6680b57cec5SDimitry Andric else if (TypeName == "llvm_call_graph_profile") 6690b57cec5SDimitry Andric Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE; 6700b57cec5SDimitry Andric else if (TypeName == "llvm_dependent_libraries") 6710b57cec5SDimitry Andric Type = ELF::SHT_LLVM_DEPENDENT_LIBRARIES; 6720b57cec5SDimitry Andric else if (TypeName == "llvm_sympart") 6730b57cec5SDimitry Andric Type = ELF::SHT_LLVM_SYMPART; 674e8d8bef9SDimitry Andric else if (TypeName == "llvm_bb_addr_map") 675e8d8bef9SDimitry Andric Type = ELF::SHT_LLVM_BB_ADDR_MAP; 676753f127fSDimitry Andric else if (TypeName == "llvm_offloading") 677753f127fSDimitry Andric Type = ELF::SHT_LLVM_OFFLOADING; 67806c3fb27SDimitry Andric else if (TypeName == "llvm_lto") 67906c3fb27SDimitry Andric Type = ELF::SHT_LLVM_LTO; 6800b57cec5SDimitry Andric else if (TypeName.getAsInteger(0, Type)) 6810b57cec5SDimitry Andric return TokError("unknown section type"); 6820b57cec5SDimitry Andric } 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andric if (UseLastGroup) { 6850b57cec5SDimitry Andric if (const MCSectionELF *Section = 686*0fca6ea1SDimitry Andric cast_or_null<MCSectionELF>(getStreamer().getCurrentSectionOnly())) 6870b57cec5SDimitry Andric if (const MCSymbol *Group = Section->getGroup()) { 6880b57cec5SDimitry Andric GroupName = Group->getName(); 689fe6060f1SDimitry Andric IsComdat = Section->isComdat(); 6900b57cec5SDimitry Andric Flags |= ELF::SHF_GROUP; 6910b57cec5SDimitry Andric } 6920b57cec5SDimitry Andric } 6930b57cec5SDimitry Andric 694fe6060f1SDimitry Andric MCSectionELF *Section = 695fe6060f1SDimitry Andric getContext().getELFSection(SectionName, Type, Flags, Size, GroupName, 696fe6060f1SDimitry Andric IsComdat, UniqueID, LinkedToSym); 69781ad6265SDimitry Andric getStreamer().switchSection(Section, Subsection); 6984824e7fdSDimitry Andric // Check that flags are used consistently. However, the GNU assembler permits 6994824e7fdSDimitry Andric // to leave out in subsequent uses of the same sections; for compatibility, 7004824e7fdSDimitry Andric // do likewise. 7014824e7fdSDimitry Andric if (!TypeName.empty() && Section->getType() != Type && 702349cc55cSDimitry Andric !allowSectionTypeMismatch(getContext().getTargetTriple(), SectionName, 703349cc55cSDimitry Andric Type)) 7045ffd83dbSDimitry Andric Error(loc, "changed section type for " + SectionName + ", expected: 0x" + 7055ffd83dbSDimitry Andric utohexstr(Section->getType())); 706fe6060f1SDimitry Andric if ((extraFlags || Size || !TypeName.empty()) && Section->getFlags() != Flags) 7075ffd83dbSDimitry Andric Error(loc, "changed section flags for " + SectionName + ", expected: 0x" + 7085ffd83dbSDimitry Andric utohexstr(Section->getFlags())); 709fe6060f1SDimitry Andric if ((extraFlags || Size || !TypeName.empty()) && 710fe6060f1SDimitry Andric Section->getEntrySize() != Size) 7115ffd83dbSDimitry Andric Error(loc, "changed section entsize for " + SectionName + 7125ffd83dbSDimitry Andric ", expected: " + Twine(Section->getEntrySize())); 7130b57cec5SDimitry Andric 714e8d8bef9SDimitry Andric if (getContext().getGenDwarfForAssembly() && 715e8d8bef9SDimitry Andric (Section->getFlags() & ELF::SHF_ALLOC) && 716e8d8bef9SDimitry Andric (Section->getFlags() & ELF::SHF_EXECINSTR)) { 7175ffd83dbSDimitry Andric bool InsertResult = getContext().addGenDwarfSection(Section); 718*0fca6ea1SDimitry Andric if (InsertResult && getContext().getDwarfVersion() <= 2) 7190b57cec5SDimitry Andric Warning(loc, "DWARF2 only supports one section per compilation unit"); 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric 7220b57cec5SDimitry Andric return false; 7230b57cec5SDimitry Andric } 7240b57cec5SDimitry Andric 7250b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { 7260b57cec5SDimitry Andric MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 7270b57cec5SDimitry Andric if (PreviousSection.first == nullptr) 7280b57cec5SDimitry Andric return TokError(".previous without corresponding .section"); 72981ad6265SDimitry Andric getStreamer().switchSection(PreviousSection.first, PreviousSection.second); 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric return false; 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric static MCSymbolAttr MCAttrForString(StringRef Type) { 7350b57cec5SDimitry Andric return StringSwitch<MCSymbolAttr>(Type) 7360b57cec5SDimitry Andric .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction) 7370b57cec5SDimitry Andric .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject) 7380b57cec5SDimitry Andric .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS) 7390b57cec5SDimitry Andric .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon) 7400b57cec5SDimitry Andric .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType) 7410b57cec5SDimitry Andric .Cases("STT_GNU_IFUNC", "gnu_indirect_function", 7420b57cec5SDimitry Andric MCSA_ELF_TypeIndFunction) 7430b57cec5SDimitry Andric .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) 7440b57cec5SDimitry Andric .Default(MCSA_Invalid); 7450b57cec5SDimitry Andric } 7460b57cec5SDimitry Andric 7470b57cec5SDimitry Andric /// ParseDirectiveELFType 7480b57cec5SDimitry Andric /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE> 7490b57cec5SDimitry Andric /// ::= .type identifier , #attribute 7500b57cec5SDimitry Andric /// ::= .type identifier , @attribute 7510b57cec5SDimitry Andric /// ::= .type identifier , %attribute 7520b57cec5SDimitry Andric /// ::= .type identifier , "attribute" 7530b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { 7540b57cec5SDimitry Andric StringRef Name; 7550b57cec5SDimitry Andric if (getParser().parseIdentifier(Name)) 756bdd1243dSDimitry Andric return TokError("expected identifier"); 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric // Handle the identifier as the key symbol. 7590b57cec5SDimitry Andric MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric // NOTE the comma is optional in all cases. It is only documented as being 7620b57cec5SDimitry Andric // optional in the first case, however, GAS will silently treat the comma as 7630b57cec5SDimitry Andric // optional in all cases. Furthermore, although the documentation states that 7640b57cec5SDimitry Andric // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS 7650b57cec5SDimitry Andric // accepts both the upper case name as well as the lower case aliases. 7660b57cec5SDimitry Andric if (getLexer().is(AsmToken::Comma)) 7670b57cec5SDimitry Andric Lex(); 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Identifier) && 7700b57cec5SDimitry Andric getLexer().isNot(AsmToken::Hash) && 7710b57cec5SDimitry Andric getLexer().isNot(AsmToken::Percent) && 7720b57cec5SDimitry Andric getLexer().isNot(AsmToken::String)) { 7730b57cec5SDimitry Andric if (!getLexer().getAllowAtInIdentifier()) 7740b57cec5SDimitry Andric return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', " 7750b57cec5SDimitry Andric "'%<type>' or \"<type>\""); 7760b57cec5SDimitry Andric else if (getLexer().isNot(AsmToken::At)) 7770b57cec5SDimitry Andric return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " 7780b57cec5SDimitry Andric "'%<type>' or \"<type>\""); 7790b57cec5SDimitry Andric } 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::String) && 7820b57cec5SDimitry Andric getLexer().isNot(AsmToken::Identifier)) 7830b57cec5SDimitry Andric Lex(); 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric SMLoc TypeLoc = getLexer().getLoc(); 7860b57cec5SDimitry Andric 7870b57cec5SDimitry Andric StringRef Type; 7880b57cec5SDimitry Andric if (getParser().parseIdentifier(Type)) 789bdd1243dSDimitry Andric return TokError("expected symbol type"); 7900b57cec5SDimitry Andric 7910b57cec5SDimitry Andric MCSymbolAttr Attr = MCAttrForString(Type); 7920b57cec5SDimitry Andric if (Attr == MCSA_Invalid) 793bdd1243dSDimitry Andric return Error(TypeLoc, "unsupported attribute"); 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 796bdd1243dSDimitry Andric return TokError("expected end of directive"); 7970b57cec5SDimitry Andric Lex(); 7980b57cec5SDimitry Andric 7995ffd83dbSDimitry Andric getStreamer().emitSymbolAttribute(Sym, Attr); 8000b57cec5SDimitry Andric 8010b57cec5SDimitry Andric return false; 8020b57cec5SDimitry Andric } 8030b57cec5SDimitry Andric 8040b57cec5SDimitry Andric /// ParseDirectiveIdent 8050b57cec5SDimitry Andric /// ::= .ident string 8060b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { 8070b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::String)) 808bdd1243dSDimitry Andric return TokError("expected string"); 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric StringRef Data = getTok().getIdentifier(); 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andric Lex(); 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 815bdd1243dSDimitry Andric return TokError("expected end of directive"); 8160b57cec5SDimitry Andric Lex(); 8170b57cec5SDimitry Andric 8185ffd83dbSDimitry Andric getStreamer().emitIdent(Data); 8190b57cec5SDimitry Andric return false; 8200b57cec5SDimitry Andric } 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andric /// ParseDirectiveSymver 8230b57cec5SDimitry Andric /// ::= .symver foo, bar2@zed 8240b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { 825fe6060f1SDimitry Andric StringRef OriginalName, Name, Action; 826fe6060f1SDimitry Andric if (getParser().parseIdentifier(OriginalName)) 827bdd1243dSDimitry Andric return TokError("expected identifier"); 8280b57cec5SDimitry Andric 8290b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 8300b57cec5SDimitry Andric return TokError("expected a comma"); 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric // ARM assembly uses @ for a comment... 8330b57cec5SDimitry Andric // except when parsing the second parameter of the .symver directive. 8340b57cec5SDimitry Andric // Force the next symbol to allow @ in the identifier, which is 8350b57cec5SDimitry Andric // required for this directive and then reset it to its initial state. 8360b57cec5SDimitry Andric const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier(); 8370b57cec5SDimitry Andric getLexer().setAllowAtInIdentifier(true); 8380b57cec5SDimitry Andric Lex(); 8390b57cec5SDimitry Andric getLexer().setAllowAtInIdentifier(AllowAtInIdentifier); 8400b57cec5SDimitry Andric 841fe6060f1SDimitry Andric if (getParser().parseIdentifier(Name)) 842bdd1243dSDimitry Andric return TokError("expected identifier"); 8430b57cec5SDimitry Andric 844349cc55cSDimitry Andric if (!Name.contains('@')) 8450b57cec5SDimitry Andric return TokError("expected a '@' in the name"); 846fe6060f1SDimitry Andric bool KeepOriginalSym = !Name.contains("@@@"); 847fe6060f1SDimitry Andric if (parseOptionalToken(AsmToken::Comma)) { 848fe6060f1SDimitry Andric if (getParser().parseIdentifier(Action) || Action != "remove") 849fe6060f1SDimitry Andric return TokError("expected 'remove'"); 850fe6060f1SDimitry Andric KeepOriginalSym = false; 851fe6060f1SDimitry Andric } 852fe6060f1SDimitry Andric (void)parseOptionalToken(AsmToken::EndOfStatement); 8530b57cec5SDimitry Andric 854fe6060f1SDimitry Andric getStreamer().emitELFSymverDirective( 855fe6060f1SDimitry Andric getContext().getOrCreateSymbol(OriginalName), Name, KeepOriginalSym); 8560b57cec5SDimitry Andric return false; 8570b57cec5SDimitry Andric } 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andric /// ParseDirectiveVersion 8600b57cec5SDimitry Andric /// ::= .version string 8610b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) { 8620b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::String)) 863bdd1243dSDimitry Andric return TokError("expected string"); 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric StringRef Data = getTok().getIdentifier(); 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric Lex(); 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric MCSection *Note = getContext().getELFSection(".note", ELF::SHT_NOTE, 0); 8700b57cec5SDimitry Andric 87181ad6265SDimitry Andric getStreamer().pushSection(); 87281ad6265SDimitry Andric getStreamer().switchSection(Note); 8735ffd83dbSDimitry Andric getStreamer().emitInt32(Data.size() + 1); // namesz 8745ffd83dbSDimitry Andric getStreamer().emitInt32(0); // descsz = 0 (no description). 8755ffd83dbSDimitry Andric getStreamer().emitInt32(1); // type = NT_VERSION 8765ffd83dbSDimitry Andric getStreamer().emitBytes(Data); // name 8775ffd83dbSDimitry Andric getStreamer().emitInt8(0); // NUL 878bdd1243dSDimitry Andric getStreamer().emitValueToAlignment(Align(4)); 87981ad6265SDimitry Andric getStreamer().popSection(); 8800b57cec5SDimitry Andric return false; 8810b57cec5SDimitry Andric } 8820b57cec5SDimitry Andric 8830b57cec5SDimitry Andric /// ParseDirectiveWeakref 8840b57cec5SDimitry Andric /// ::= .weakref foo, bar 8850b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { 8860b57cec5SDimitry Andric // FIXME: Share code with the other alias building directives. 8870b57cec5SDimitry Andric 8880b57cec5SDimitry Andric StringRef AliasName; 8890b57cec5SDimitry Andric if (getParser().parseIdentifier(AliasName)) 890bdd1243dSDimitry Andric return TokError("expected identifier"); 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 8930b57cec5SDimitry Andric return TokError("expected a comma"); 8940b57cec5SDimitry Andric 8950b57cec5SDimitry Andric Lex(); 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andric StringRef Name; 8980b57cec5SDimitry Andric if (getParser().parseIdentifier(Name)) 899bdd1243dSDimitry Andric return TokError("expected identifier"); 9000b57cec5SDimitry Andric 9010b57cec5SDimitry Andric MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); 9020b57cec5SDimitry Andric 9030b57cec5SDimitry Andric MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 9040b57cec5SDimitry Andric 9055ffd83dbSDimitry Andric getStreamer().emitWeakReference(Alias, Sym); 9060b57cec5SDimitry Andric return false; 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) { 910*0fca6ea1SDimitry Andric const MCExpr *Subsection = MCConstantExpr::create(0, getContext()); 9110b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) { 9120b57cec5SDimitry Andric if (getParser().parseExpression(Subsection)) 9130b57cec5SDimitry Andric return true; 9140b57cec5SDimitry Andric } 9150b57cec5SDimitry Andric 9160b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 917bdd1243dSDimitry Andric return TokError("expected end of directive"); 9180b57cec5SDimitry Andric 9190b57cec5SDimitry Andric Lex(); 9200b57cec5SDimitry Andric 921*0fca6ea1SDimitry Andric return getStreamer().switchSection(getStreamer().getCurrentSectionOnly(), 922*0fca6ea1SDimitry Andric Subsection); 9230b57cec5SDimitry Andric } 9240b57cec5SDimitry Andric 9255ffd83dbSDimitry Andric bool ELFAsmParser::ParseDirectiveCGProfile(StringRef S, SMLoc Loc) { 9265ffd83dbSDimitry Andric return MCAsmParserExtension::ParseDirectiveCGProfile(S, Loc); 9270b57cec5SDimitry Andric } 9280b57cec5SDimitry Andric 9290b57cec5SDimitry Andric namespace llvm { 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric MCAsmParserExtension *createELFAsmParser() { 9320b57cec5SDimitry Andric return new ELFAsmParser; 9330b57cec5SDimitry Andric } 9340b57cec5SDimitry Andric 9350b57cec5SDimitry Andric } // end namespace llvm 936