aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-09-21 05:25:12 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-09-21 05:25:12 +0000
commit60c81c939755601931bea8dbde174ff52cd904dd (patch)
treef5db513a0c21a3f6786d4fb092c90e331bf6e309
parent7cdc37064116f8688bb695fc9f30f128c25dcd84 (diff)
downloadexternal_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.cpp63
-rw-r--r--test/MC/ELF/section.s2
-rw-r--r--test/MC/ELF/type.s28
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: }