diff options
author | David Majnemer <david.majnemer@gmail.com> | 2013-09-21 05:25:12 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2013-09-21 05:25:12 +0000 |
commit | 60c81c939755601931bea8dbde174ff52cd904dd (patch) | |
tree | f5db513a0c21a3f6786d4fb092c90e331bf6e309 | |
parent | 7cdc37064116f8688bb695fc9f30f128c25dcd84 (diff) | |
download | external_llvm-60c81c939755601931bea8dbde174ff52cd904dd.zip external_llvm-60c81c939755601931bea8dbde174ff52cd904dd.tar.gz external_llvm-60c81c939755601931bea8dbde174ff52cd904dd.tar.bz2 |
ELF: Parse types in directives like binutils gas
Allow binutils .type and .section directives to take the following
forms:
- @<type>
- %<type>
- "<type>"
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191134 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/MC/MCParser/ELFAsmParser.cpp | 63 | ||||
-rw-r--r-- | test/MC/ELF/section.s | 2 | ||||
-rw-r--r-- | test/MC/ELF/type.s | 28 |
3 files changed, 72 insertions, 21 deletions
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 7b8a2d0..ca71173 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -402,10 +402,13 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) { 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 '@<type>', '%<type>' or \"<type>\""); - Lex(); if (getParser().parseIdentifier(TypeName)) return TokError("expected identifier in directive"); @@ -499,7 +502,11 @@ bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { } /// ParseDirectiveELFType +/// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE> +/// ::= .type identifier , #attribute /// ::= .type identifier , @attribute +/// ::= .type identifier , %attribute +/// ::= .type identifier , "attribute" bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { StringRef Name; if (getParser().parseIdentifier(Name)) @@ -512,26 +519,42 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { return TokError("unexpected token in '.type' directive"); Lex(); - if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At)) - return TokError("expected '@' or '%' before type"); - Lex(); - StringRef Type; SMLoc TypeLoc; + MCSymbolAttr Attr; + if (getLexer().is(AsmToken::Identifier)) { + TypeLoc = getLexer().getLoc(); + if (getParser().parseIdentifier(Type)) + return TokError("expected symbol type in directive"); + Attr = StringSwitch<MCSymbolAttr>(Type) + .Case("STT_FUNC", MCSA_ELF_TypeFunction) + .Case("STT_OBJECT", MCSA_ELF_TypeObject) + .Case("STT_TLS", MCSA_ELF_TypeTLS) + .Case("STT_COMMON", MCSA_ELF_TypeCommon) + .Case("STT_NOTYPE", MCSA_ELF_TypeNoType) + .Case("STT_GNU_IFUNC", MCSA_ELF_TypeIndFunction) + .Default(MCSA_Invalid); + } else if (getLexer().is(AsmToken::Hash) || getLexer().is(AsmToken::At) || + getLexer().is(AsmToken::Percent) || + getLexer().is(AsmToken::String)) { + if (!getLexer().is(AsmToken::String)) + Lex(); - TypeLoc = getLexer().getLoc(); - if (getParser().parseIdentifier(Type)) - return TokError("expected symbol type in directive"); - - MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(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); + TypeLoc = getLexer().getLoc(); + if (getParser().parseIdentifier(Type)) + return TokError("expected symbol type in directive"); + Attr = StringSwitch<MCSymbolAttr>(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); + } else + return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " + "'%<type>' or \"<type>\""); if (Attr == MCSA_Invalid) return Error(TypeLoc, "unsupported attribute in '.type' directive"); diff --git a/test/MC/ELF/section.s b/test/MC/ELF/section.s index b3246e0..7dc23c2 100644 --- a/test/MC/ELF/section.s +++ b/test/MC/ELF/section.s @@ -5,7 +5,7 @@ .section .note.GNU-stack,"",@progbits .section .note.GNU-stack2,"",%progbits .section .note.GNU-,"",@progbits -.section -.note.GNU,"",@progbits +.section -.note.GNU,"","progbits" // CHECK: Name: .note.GNU-stack (56) // CHECK: Name: .note.GNU-stack2 (153) diff --git a/test/MC/ELF/type.s b/test/MC/ELF/type.s index a5b9812..c2f3631 100644 --- a/test/MC/ELF/type.s +++ b/test/MC/ELF/type.s @@ -31,6 +31,16 @@ tls: .type tls,@tls_object .type tls,@gnu_indirect_function +// Test that "<type>" is accepted. +tls_quoted: + .global tls_quoted + .type tls_quoted,"tls_object" + +// Test that "<type>" is accepted. +tls_upper_case: + .global tls_upper_case + .type tls_upper_case,STT_TLS + // CHECK: Symbol { // CHECK: Name: bar // CHECK-NEXT: Value: 0x0 @@ -85,3 +95,21 @@ tls: // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: tls_quoted +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: TLS +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text (0x1) +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: tls_upper_case +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: TLS +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text (0x1) +// CHECK-NEXT: } |