diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index ddf988faa64..072befadd5f 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -118,6 +118,9 @@ public: bool ParseDirectiveSection(StringRef, SMLoc); bool ParseDirectiveSize(StringRef, SMLoc); bool ParseDirectivePrevious(StringRef, SMLoc); + +private: + bool ParseSectionName(StringRef &SectionName); }; } @@ -155,11 +158,43 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) { return false; } +bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { + // A section name can contain -, so we cannot just use + // ParseIdentifier. + SMLoc FirstLoc = getLexer().getLoc(); + unsigned Size = 0; + + for (;;) { + StringRef Tmp; + unsigned CurSize; + + SMLoc PrevLoc = getLexer().getLoc(); + if (getLexer().is(AsmToken::Minus)) { + CurSize = 1; + Lex(); // Consume the "-". + } else if (!getParser().ParseIdentifier(Tmp)) + CurSize = Tmp.size(); + else + break; + + Size += CurSize; + SectionName = StringRef(FirstLoc.getPointer(), Size); + + // Make sure the following token is adjacent. + if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer()) + break; + } + if (Size == 0) + return true; + + return false; +} + // FIXME: This is a work in progress. bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { StringRef SectionName; - // FIXME: This doesn't parse section names like ".note.GNU-stack" correctly. - if (getParser().ParseIdentifier(SectionName)) + + if (ParseSectionName(SectionName)) return TokError("expected identifier in directive"); std::string FlagsStr; diff --git a/test/MC/ELF/section.s b/test/MC/ELF/section.s new file mode 100644 index 00000000000..4622cb41592 --- /dev/null +++ b/test/MC/ELF/section.s @@ -0,0 +1,11 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck %s + +// Test that these names are accepted. + +.section .note.GNU-stack,"",@progbits +.section .note.GNU-,"",@progbits +.section -.note.GNU,"",@progbits + +// CHECK: ('sh_name', 18) # '.note.GNU-stack' +// CHECK: ('sh_name', 34) # '.note.GNU-' +// CHECK: ('sh_name', 45) # '-.note.GNU'