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:
parent
d4aac28519
commit
c1bd9963f1
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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: }
|
||||
|
Loading…
x
Reference in New Issue
Block a user