1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

ELF: Parse types in directives like binutils gas

Allow binutils .type and .section directives to take the following
forms:
- @<type>
- %<type>
- "<type>"

llvm-svn: 191134
This commit is contained in:
David Majnemer 2013-09-21 05:25:12 +00:00
parent d4aac28519
commit c1bd9963f1
3 changed files with 72 additions and 21 deletions

View File

@ -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");

View File

@ -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)

View File

@ -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: }