X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FMC%2FMCParser%2FELFAsmParser.cpp;h=e3585bd276327f72e6096524e0b2a0f60b95aeaa;hp=87126f0e3ed2032ffe417426c72a6159efd8854d;hb=cd52a7a381a73c53ec4ef517ad87f19808cb1a28;hpb=68ca56285f9b6e82eb16ff8ea02a301f2c489fae diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 87126f0e3ed..e3585bd2763 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -16,64 +16,65 @@ #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbolELF.h" #include "llvm/Support/ELF.h" using namespace llvm; namespace { class ELFAsmParser : public MCAsmParserExtension { - template - void AddDirectiveHandler(StringRef Directive) { - getParser().AddDirectiveHandler(this, Directive, - HandleDirective); + template + void addDirectiveHandler(StringRef Directive) { + MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( + this, HandleDirective); + + getParser().addDirectiveHandler(Directive, Handler); } - bool ParseSectionSwitch(StringRef Section, unsigned Type, - unsigned Flags, SectionKind Kind); - bool SeenIdent; + bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, + SectionKind Kind); public: - ELFAsmParser() : SeenIdent(false) { - BracketExpressionsSupported = true; - } + ELFAsmParser() { BracketExpressionsSupported = true; } - virtual void Initialize(MCAsmParser &Parser) { + void Initialize(MCAsmParser &Parser) override { // Call the base implementation. this->MCAsmParserExtension::Initialize(Parser); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data"); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text"); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss"); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata"); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata"); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss"); - AddDirectiveHandler< + addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data"); + addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text"); + addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss"); + addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata"); + addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata"); + addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss"); + addDirectiveHandler< &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel"); - AddDirectiveHandler< + addDirectiveHandler< &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro"); - AddDirectiveHandler< + addDirectiveHandler< &ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local"); - AddDirectiveHandler< + addDirectiveHandler< &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section"); - AddDirectiveHandler< + addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section"); + addDirectiveHandler< &ELFAsmParser::ParseDirectivePushSection>(".pushsection"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local"); - AddDirectiveHandler< + addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection"); + addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size"); + addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); + addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type"); + addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident"); + addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver"); + addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version"); + addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref"); + addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); + addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local"); + addDirectiveHandler< &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected"); - AddDirectiveHandler< + addDirectiveHandler< &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal"); - AddDirectiveHandler< + addDirectiveHandler< &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden"); + addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection"); } // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is @@ -145,9 +146,12 @@ public: bool ParseDirectiveVersion(StringRef, SMLoc); bool ParseDirectiveWeakref(StringRef, SMLoc); bool ParseDirectiveSymbolAttribute(StringRef, SMLoc); + bool ParseDirectiveSubsection(StringRef, SMLoc); private: bool ParseSectionName(StringRef &SectionName); + bool ParseSectionArguments(bool IsPush, SMLoc loc); + unsigned parseSunStyleSectionFlags(); }; } @@ -167,10 +171,10 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { for (;;) { StringRef Name; - if (getParser().ParseIdentifier(Name)) + if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); getStreamer().EmitSymbolAttribute(Sym, Attr); @@ -189,40 +193,42 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind) { - if (getLexer().isNot(AsmToken::EndOfStatement)) - return TokError("unexpected token in section switching directive"); - Lex(); + const MCExpr *Subsection = nullptr; + if (getLexer().isNot(AsmToken::EndOfStatement)) { + if (getParser().parseExpression(Subsection)) + return true; + } - getStreamer().SwitchSection(getContext().getELFSection( - Section, Type, Flags, Kind)); + getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags), + Subsection); return false; } bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) { StringRef Name; - if (getParser().ParseIdentifier(Name)) + if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbolELF *Sym = cast(getContext().getOrCreateSymbol(Name)); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); Lex(); const MCExpr *Expr; - if (getParser().ParseExpression(Expr)) + if (getParser().parseExpression(Expr)) return true; if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); - getStreamer().EmitELFSize(Sym, Expr); + getStreamer().emitELFSize(Sym, Expr); return false; } bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { // A section name can contain -, so we cannot just use - // ParseIdentifier. + // parseIdentifier. SMLoc FirstLoc = getLexer().getLoc(); unsigned Size = 0; @@ -233,7 +239,6 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { } for (;;) { - StringRef Tmp; unsigned CurSize; SMLoc PrevLoc = getLexer().getLoc(); @@ -263,22 +268,17 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { return false; } -static SectionKind computeSectionKind(unsigned Flags) { - if (Flags & ELF::SHF_EXECINSTR) - return SectionKind::getText(); - if (Flags & ELF::SHF_TLS) - return SectionKind::getThreadData(); - return SectionKind::getDataRel(); -} - -static int parseSectionFlags(StringRef flagsStr) { - int flags = 0; +static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { + unsigned flags = 0; for (unsigned i = 0; i < flagsStr.size(); i++) { switch (flagsStr[i]) { case 'a': flags |= ELF::SHF_ALLOC; break; + case 'e': + flags |= ELF::SHF_EXCLUDE; + break; case 'x': flags |= ELF::SHF_EXECINSTR; break; @@ -303,18 +303,51 @@ static int parseSectionFlags(StringRef flagsStr) { case 'G': flags |= ELF::SHF_GROUP; break; + case '?': + *UseLastGroup = true; + break; default: - return -1; + return -1U; } } return flags; } +unsigned ELFAsmParser::parseSunStyleSectionFlags() { + unsigned flags = 0; + while (getLexer().is(AsmToken::Hash)) { + Lex(); // Eat the #. + + if (!getLexer().is(AsmToken::Identifier)) + return -1U; + + StringRef flagId = getTok().getIdentifier(); + if (flagId == "alloc") + flags |= ELF::SHF_ALLOC; + else if (flagId == "execinstr") + flags |= ELF::SHF_EXECINSTR; + else if (flagId == "write") + flags |= ELF::SHF_WRITE; + else if (flagId == "tls") + flags |= ELF::SHF_TLS; + else + return -1U; + + Lex(); // Eat the flag. + + if (!getLexer().is(AsmToken::Comma)) + break; + Lex(); // Eat the comma. + } + return flags; +} + + bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) { getStreamer().PushSection(); - if (ParseDirectiveSection(s, loc)) { + if (ParseSectionArguments(/*IsPush=*/true, loc)) { getStreamer().PopSection(); return true; } @@ -329,7 +362,11 @@ bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { } // FIXME: This is a work in progress. -bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { +bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) { + return ParseSectionArguments(/*IsPush=*/false, loc); +} + +bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { StringRef SectionName; if (ParseSectionName(SectionName)) @@ -339,6 +376,10 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { int64_t Size = 0; StringRef GroupName; unsigned Flags = 0; + const MCExpr *Subsection = nullptr; + bool UseLastGroup = false; + StringRef UniqueStr; + int64_t UniqueID = ~0; // Set the defaults first. if (SectionName == ".fini" || SectionName == ".init" || @@ -350,19 +391,36 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { if (getLexer().is(AsmToken::Comma)) { Lex(); - if (getLexer().isNot(AsmToken::String)) - return TokError("expected string in directive"); + if (IsPush && getLexer().isNot(AsmToken::String)) { + if (getParser().parseExpression(Subsection)) + return true; + if (getLexer().isNot(AsmToken::Comma)) + goto EndStmt; + Lex(); + } - StringRef FlagsStr = getTok().getStringContents(); - Lex(); + unsigned extraFlags; - int extraFlags = parseSectionFlags(FlagsStr); - if (extraFlags < 0) + if (getLexer().isNot(AsmToken::String)) { + if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax() + || getLexer().isNot(AsmToken::Hash)) + return TokError("expected string in directive"); + extraFlags = parseSunStyleSectionFlags(); + } else { + StringRef FlagsStr = getTok().getStringContents(); + Lex(); + extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); + } + + if (extraFlags == -1U) return TokError("unknown flag"); Flags |= extraFlags; bool Mergeable = Flags & ELF::SHF_MERGE; bool Group = Flags & ELF::SHF_GROUP; + if (Group && UseLastGroup) + return TokError("Section cannot specifiy a group name while also acting " + "as a member of the last group"); if (getLexer().isNot(AsmToken::Comma)) { if (Mergeable) @@ -371,18 +429,21 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { return TokError("Group section must specify the type"); } else { Lex(); - if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At)) - return TokError("expected '@' or '%' before type"); + if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) || + getLexer().is(AsmToken::String)) { + if (!getLexer().is(AsmToken::String)) + Lex(); + } else + return TokError("expected '@', '%' or \"\""); - Lex(); - if (getParser().ParseIdentifier(TypeName)) + if (getParser().parseIdentifier(TypeName)) return TokError("expected identifier in directive"); if (Mergeable) { if (getLexer().isNot(AsmToken::Comma)) return TokError("expected the entry size"); Lex(); - if (getParser().ParseAbsoluteExpression(Size)) + if (getParser().parseAbsoluteExpression(Size)) return true; if (Size <= 0) return TokError("entry size must be positive"); @@ -392,26 +453,52 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { if (getLexer().isNot(AsmToken::Comma)) return TokError("expected group name"); Lex(); - if (getParser().ParseIdentifier(GroupName)) + if (getParser().parseIdentifier(GroupName)) return true; if (getLexer().is(AsmToken::Comma)) { Lex(); StringRef Linkage; - if (getParser().ParseIdentifier(Linkage)) + if (getParser().parseIdentifier(Linkage)) return true; if (Linkage != "comdat") return TokError("Linkage must be 'comdat'"); } } + if (getLexer().is(AsmToken::Comma)) { + Lex(); + if (getParser().parseIdentifier(UniqueStr)) + return TokError("expected identifier in directive"); + if (UniqueStr != "unique") + return TokError("expected 'unique'"); + if (getLexer().isNot(AsmToken::Comma)) + return TokError("expected commma"); + Lex(); + if (getParser().parseAbsoluteExpression(UniqueID)) + return true; + if (UniqueID < 0) + return TokError("unique id must be positive"); + if (!isUInt<32>(UniqueID) || UniqueID == ~0U) + return TokError("unique id is too large"); + } } } +EndStmt: if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); unsigned Type = ELF::SHT_PROGBITS; - if (!TypeName.empty()) { + if (TypeName.empty()) { + if (SectionName.startswith(".note")) + Type = ELF::SHT_NOTE; + else if (SectionName == ".init_array") + Type = ELF::SHT_INIT_ARRAY; + else if (SectionName == ".fini_array") + Type = ELF::SHT_FINI_ARRAY; + else if (SectionName == ".preinit_array") + Type = ELF::SHT_PREINIT_ARRAY; + } else { if (TypeName == "init_array") Type = ELF::SHT_INIT_ARRAY; else if (TypeName == "fini_array") @@ -430,63 +517,103 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { return TokError("unknown section type"); } - SectionKind Kind = computeSectionKind(Flags); - getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type, - Flags, Kind, Size, - GroupName)); + if (UseLastGroup) { + MCSectionSubPair CurrentSection = getStreamer().getCurrentSection(); + if (const MCSectionELF *Section = + cast_or_null(CurrentSection.first)) + if (const MCSymbol *Group = Section->getGroup()) { + GroupName = Group->getName(); + Flags |= ELF::SHF_GROUP; + } + } + + MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags, + Size, GroupName, UniqueID); + getStreamer().SwitchSection(ELFSection, Subsection); + + if (getContext().getGenDwarfForAssembly()) { + bool InsertResult = getContext().addGenDwarfSection(ELFSection); + if (InsertResult) { + if (getContext().getDwarfVersion() <= 2) + Warning(loc, "DWARF2 only supports one section per compilation unit"); + + if (!ELFSection->getBeginSymbol()) { + MCSymbol *SectionStartSymbol = getContext().createTempSymbol(); + getStreamer().EmitLabel(SectionStartSymbol); + ELFSection->setBeginSymbol(SectionStartSymbol); + } + } + } + return false; } bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { - const MCSection *PreviousSection = getStreamer().getPreviousSection(); - if (PreviousSection == NULL) + MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); + if (PreviousSection.first == nullptr) return TokError(".previous without corresponding .section"); - getStreamer().SwitchSection(PreviousSection); + getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); return false; } +static MCSymbolAttr MCAttrForString(StringRef Type) { + return StringSwitch(Type) + .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction) + .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject) + .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS) + .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon) + .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType) + .Cases("STT_GNU_IFUNC", "gnu_indirect_function", + MCSA_ELF_TypeIndFunction) + .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) + .Default(MCSA_Invalid); +} + /// ParseDirectiveELFType +/// ::= .type identifier , STT_ +/// ::= .type identifier , #attribute /// ::= .type identifier , @attribute +/// ::= .type identifier , %attribute +/// ::= .type identifier , "attribute" bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { StringRef Name; - if (getParser().ParseIdentifier(Name)) + if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); + + // NOTE the comma is optional in all cases. It is only documented as being + // optional in the first case, however, GAS will silently treat the comma as + // optional in all cases. Furthermore, although the documentation states that + // the first form only accepts STT_, in reality, GAS + // accepts both the upper case name as well as the lower case aliases. + if (getLexer().is(AsmToken::Comma)) + Lex(); - if (getLexer().isNot(AsmToken::Comma)) - return TokError("unexpected token in '.type' directive"); - Lex(); + if (getLexer().isNot(AsmToken::Identifier) && + getLexer().isNot(AsmToken::Hash) && getLexer().isNot(AsmToken::At) && + getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::String)) + return TokError("expected STT_, '#', '@', " + "'%' or \"\""); - if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At)) - return TokError("expected '@' or '%' before type"); - Lex(); + if (getLexer().isNot(AsmToken::String) && + getLexer().isNot(AsmToken::Identifier)) + Lex(); - StringRef Type; - SMLoc TypeLoc; + SMLoc TypeLoc = getLexer().getLoc(); - TypeLoc = getLexer().getLoc(); - if (getParser().ParseIdentifier(Type)) + StringRef Type; + if (getParser().parseIdentifier(Type)) return TokError("expected symbol type in directive"); - MCSymbolAttr Attr = StringSwitch(Type) - .Case("function", MCSA_ELF_TypeFunction) - .Case("object", MCSA_ELF_TypeObject) - .Case("tls_object", MCSA_ELF_TypeTLS) - .Case("common", MCSA_ELF_TypeCommon) - .Case("notype", MCSA_ELF_TypeNoType) - .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) - .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction) - .Default(MCSA_Invalid); - + MCSymbolAttr Attr = MCAttrForString(Type); if (Attr == MCSA_Invalid) return Error(TypeLoc, "unsupported attribute in '.type' directive"); if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.type' directive"); - Lex(); getStreamer().EmitSymbolAttribute(Sym, Attr); @@ -504,22 +631,7 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { Lex(); - const MCSection *Comment = - getContext().getELFSection(".comment", ELF::SHT_PROGBITS, - ELF::SHF_MERGE | - ELF::SHF_STRINGS, - SectionKind::getReadOnly(), - 1, ""); - - getStreamer().PushSection(); - getStreamer().SwitchSection(Comment); - if (!SeenIdent) { - getStreamer().EmitIntValue(0, 1); - SeenIdent = true; - } - getStreamer().EmitBytes(Data); - getStreamer().EmitIntValue(0, 1); - getStreamer().PopSection(); + getStreamer().EmitIdent(Data); return false; } @@ -527,24 +639,31 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { /// ::= .symver foo, bar2@zed bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { StringRef Name; - if (getParser().ParseIdentifier(Name)) + if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); if (getLexer().isNot(AsmToken::Comma)) return TokError("expected a comma"); + // ARM assembly uses @ for a comment... + // except when parsing the second parameter of the .symver directive. + // Force the next symbol to allow @ in the identifier, which is + // required for this directive and then reset it to its initial state. + const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier(); + getLexer().setAllowAtInIdentifier(true); Lex(); + getLexer().setAllowAtInIdentifier(AllowAtInIdentifier); StringRef AliasName; - if (getParser().ParseIdentifier(AliasName)) + if (getParser().parseIdentifier(AliasName)) return TokError("expected identifier in directive"); if (AliasName.find('@') == StringRef::npos) return TokError("expected a '@' in the name"); - MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); - const MCExpr *Value = MCSymbolRefExpr::Create(Sym, getContext()); + MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); + const MCExpr *Value = MCSymbolRefExpr::create(Sym, getContext()); getStreamer().EmitAssignment(Alias, Value); return false; @@ -560,9 +679,7 @@ bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) { Lex(); - const MCSection *Note = - getContext().getELFSection(".note", ELF::SHT_NOTE, 0, - SectionKind::getReadOnly()); + MCSection *Note = getContext().getELFSection(".note", ELF::SHT_NOTE, 0); getStreamer().PushSection(); getStreamer().SwitchSection(Note); @@ -582,7 +699,7 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { // FIXME: Share code with the other alias building directives. StringRef AliasName; - if (getParser().ParseIdentifier(AliasName)) + if (getParser().parseIdentifier(AliasName)) return TokError("expected identifier in directive"); if (getLexer().isNot(AsmToken::Comma)) @@ -591,17 +708,31 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { Lex(); StringRef Name; - if (getParser().ParseIdentifier(Name)) + if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); + MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); getStreamer().EmitWeakReference(Alias, Sym); return false; } +bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) { + const MCExpr *Subsection = nullptr; + if (getLexer().isNot(AsmToken::EndOfStatement)) { + if (getParser().parseExpression(Subsection)) + return true; + } + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + getStreamer().SubSection(Subsection); + return false; +} + namespace llvm { MCAsmParserExtension *createELFAsmParser() {