diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 83c562bf4a4..62cf6c6e7a0 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -198,7 +198,7 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { if (ParseSectionName(SectionName)) return TokError("expected identifier in directive"); - std::string FlagsStr; + StringRef FlagsStr; StringRef TypeName; int64_t Size = 0; if (getLexer().is(AsmToken::Comma)) { @@ -216,21 +216,47 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { else TypeStartToken = AsmToken::At; - if (getLexer().is(AsmToken::Comma)) { - Lex(); - if (getLexer().is(TypeStartToken)) { - Lex(); - if (getParser().ParseIdentifier(TypeName)) - return TokError("expected identifier in directive"); + bool Mergeable = FlagsStr.find('M') != StringRef::npos; + bool Group = FlagsStr.find('G') != StringRef::npos; + if (getLexer().isNot(AsmToken::Comma)) { + if (Mergeable) + return TokError("Mergeable section must specify the type"); + if (Group) + return TokError("Group section must specify the type"); + } else { + Lex(); + if (getLexer().isNot(TypeStartToken)) + return TokError("expected the type"); + + Lex(); + 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)) + return true; + if (Size <= 0) + return TokError("entry size must be positive"); + } + + if (Group) { + if (getLexer().isNot(AsmToken::Comma)) + return TokError("expected group name"); + Lex(); + StringRef GroupName; + if (getParser().ParseIdentifier(GroupName)) + return true; if (getLexer().is(AsmToken::Comma)) { Lex(); - - if (getParser().ParseAbsoluteExpression(Size)) + StringRef Linkage; + if (getParser().ParseIdentifier(Linkage)) return true; - - if (Size <= 0) - return TokError("section size must be positive"); + if (Linkage != "comdat" && Linkage != ".gnu.linkonce") + return TokError("Linkage must be 'comdat' or '.gnu.linkonce'"); } } } @@ -275,6 +301,8 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { case 'd': Flags |= MCSectionELF::XCORE_SHF_DP_SECTION; break; + case 'G': + break; default: return TokError("unknown flag"); } diff --git a/test/MC/ELF/section.s b/test/MC/ELF/section.s index ea89a80f6ef..9c7288036df 100644 --- a/test/MC/ELF/section.s +++ b/test/MC/ELF/section.s @@ -37,3 +37,8 @@ // CHECK-NEXT: ('sh_info', 0x00000000) // CHECK-NEXT: ('sh_addralign', 0x00000001) // CHECK-NEXT: ('sh_entsize', 0x00000000) + + +// Test that we can parse these +.section .text.foo,"axG",@progbits,foo,comdat +.section .text.bar,"axMG",@progbits,42,bar,.gnu.linkonce