[llvm] r210407 - MC: make ELF .type handling more GNU AS compatible

Saleem Abdulrasool compnerd at compnerd.org
Sat Jun 7 17:34:34 PDT 2014


Author: compnerd
Date: Sat Jun  7 19:34:34 2014
New Revision: 210407

URL: http://llvm.org/viewvc/llvm-project?rev=210407&view=rev
Log:
MC: make ELF .type handling more GNU AS compatible

GAS documents the .type directive as having an optional comma following the key
symbol name when using the STT_<TYPE_IN_UPPER_CASE> form.  However, it treats
the comma as optional in all cases.  This makes the IAS support both forms of
inputs.  Furthermore, the prefixed forms take either the upper case name or the
lower case alias.

The tests are split into two separate sets as the hash character serves as a
comment character on x86, which is tested in the second set by using arm-elf
which uses the at symbol as a comment character.

Added:
    llvm/trunk/test/MC/ELF/gnu-type-diagnostics.s
    llvm/trunk/test/MC/ELF/gnu-type-hash-diagnostics.s
    llvm/trunk/test/MC/ELF/gnu-type-hash.s
    llvm/trunk/test/MC/ELF/gnu-type.s
Modified:
    llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp

Modified: llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp?rev=210407&r1=210406&r2=210407&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp Sat Jun  7 19:34:34 2014
@@ -561,6 +561,19 @@ bool ELFAsmParser::ParseDirectivePreviou
   return false;
 }
 
+static MCSymbolAttr MCAttrForString(StringRef Type) {
+  return StringSwitch<MCSymbolAttr>(Type)
+          .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction)
+          .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject)
+          .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS)
+          .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon)
+          .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType)
+          .Cases("STT_GNU_IFUNC", "gnu_indirect_function",
+                 MCSA_ELF_TypeIndFunction)
+          .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
+          .Default(MCSA_Invalid);
+}
+
 /// ParseDirectiveELFType
 ///  ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
 ///  ::= .type identifier , #attribute
@@ -575,53 +588,36 @@ bool ELFAsmParser::ParseDirectiveType(St
   // Handle the identifier as the key symbol.
   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
 
-  if (getLexer().isNot(AsmToken::Comma))
-    return TokError("unexpected token in '.type' directive");
-  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");
-    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
+  // NOTE the comma is optional in all cases.  It is only documented as being
+  // optional in the first case, however, GAS will silently treat the comma as
+  // optional in all cases.  Furthermore, although the documentation states that
+  // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS
+  // accepts both the upper case name as well as the lower case aliases.
+  if (getLexer().is(AsmToken::Comma))
+    Lex();
+
+  if (getLexer().isNot(AsmToken::Identifier) &&
+      getLexer().isNot(AsmToken::Hash) && getLexer().isNot(AsmToken::At) &&
+      getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::String))
     return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
                     "'%<type>' or \"<type>\"");
 
+  if (getLexer().isNot(AsmToken::String) &&
+      getLexer().isNot(AsmToken::Identifier))
+    Lex();
+
+  SMLoc TypeLoc = getLexer().getLoc();
+
+  StringRef Type;
+  if (getParser().parseIdentifier(Type))
+    return TokError("expected symbol type in directive");
+
+  MCSymbolAttr Attr = MCAttrForString(Type);
   if (Attr == MCSA_Invalid)
     return Error(TypeLoc, "unsupported attribute in '.type' directive");
 
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in '.type' directive");
-
   Lex();
 
   getStreamer().EmitSymbolAttribute(Sym, Attr);

Added: llvm/trunk/test/MC/ELF/gnu-type-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/gnu-type-diagnostics.s?rev=210407&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/gnu-type-diagnostics.s (added)
+++ llvm/trunk/test/MC/ELF/gnu-type-diagnostics.s Sat Jun  7 19:34:34 2014
@@ -0,0 +1,18 @@
+// RUN: not llvm-mc -triple i686-elf -filetype asm -o /dev/null %s 2>&1 | FileCheck %s
+
+	.type TYPE FUNC
+// CHECK: error: unsupported attribute in '.type' directive
+// CHECK: .type TYPE FUNC
+// CHECK:            ^
+
+	.type type stt_func
+// CHECK: error: unsupported attribute in '.type' directive
+// CHECK: .type type stt_func
+// CHECK:            ^
+
+	.type symbol 32
+// CHECK: error: expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', '%<type>' or "<type>"
+// CHECK: .type symbol 32
+// CHECK:              ^
+
+

Added: llvm/trunk/test/MC/ELF/gnu-type-hash-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/gnu-type-hash-diagnostics.s?rev=210407&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/gnu-type-hash-diagnostics.s (added)
+++ llvm/trunk/test/MC/ELF/gnu-type-hash-diagnostics.s Sat Jun  7 19:34:34 2014
@@ -0,0 +1,9 @@
+@ RUN: not llvm-mc -triple arm-elf -filetype asm -o /dev/null %s 2>&1 | FileCheck %s
+
+	.syntax unified
+
+	.type TYPE #32
+// CHECK: error: expected symbol type in directive
+// CHECK: .type TYPE #32
+// CHECK:             ^
+

Added: llvm/trunk/test/MC/ELF/gnu-type-hash.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/gnu-type-hash.s?rev=210407&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/gnu-type-hash.s (added)
+++ llvm/trunk/test/MC/ELF/gnu-type-hash.s Sat Jun  7 19:34:34 2014
@@ -0,0 +1,16 @@
+@ RUN: llvm-mc -triple arm-elf -filetype asm -o - %s | FileCheck %s
+
+	.syntax unified
+
+	.type TYPE #STT_FUNC
+// CHECK: .type TYPE,%function
+
+	.type type #function
+// CHECK: .type type,%function
+
+	.type comma_TYPE, #STT_FUNC
+// CHECK: .type comma_TYPE,%function
+
+	.type comma_type, #function
+// CHECK: .type comma_type,%function
+

Added: llvm/trunk/test/MC/ELF/gnu-type.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/gnu-type.s?rev=210407&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/gnu-type.s (added)
+++ llvm/trunk/test/MC/ELF/gnu-type.s Sat Jun  7 19:34:34 2014
@@ -0,0 +1,38 @@
+// RUN: llvm-mc -triple i686-elf -filetype asm -o - %s | FileCheck %s
+
+	.type TYPE STT_FUNC
+// CHECK: .type TYPE, at function
+
+	.type comma_TYPE, STT_FUNC
+// CHECK: .type comma_TYPE, at function
+
+	.type at_TYPE, @STT_FUNC
+// CHECK: .type at_TYPE, at function
+
+	.type percent_TYPE, %STT_FUNC
+// CHECK: .type percent_TYPE, at function
+
+	.type string_TYPE, "STT_FUNC"
+// CHECK: .type string_TYPE, at function
+
+	.type type function
+// CHECK: .type type, at function
+
+	.type comma_type, function
+// CHECK: .type comma_type, at function
+
+	.type at_type, @function
+// CHECK: .type at_type, at function
+
+	.type percent_type, %function
+// CHECK: .type percent_type, at function
+
+	.type string_type, "function"
+// CHECK: .type string_type, at function
+
+	.type special gnu_unique_object
+// CHECK: .type special, at gnu_unique_object
+
+	.type comma_special, gnu_unique_object
+// CHECK: .type comma_special, at gnu_unique_object
+





More information about the llvm-commits mailing list