gas/
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
index ab1550df1f442cc1ee17c2f9864aaea7fdc6a9df..cf3177087ab2c3bf99c098c9f469d208721eedc3 100644 (file)
@@ -782,31 +782,7 @@ obj_elf_parse_section_letters (char *str, size_t len)
 }
 
 static int
-obj_elf_section_word (char *str, size_t len)
-{
-  if (len == 5 && strncmp (str, "write", 5) == 0)
-    return SHF_WRITE;
-  if (len == 5 && strncmp (str, "alloc", 5) == 0)
-    return SHF_ALLOC;
-  if (len == 9 && strncmp (str, "execinstr", 9) == 0)
-    return SHF_EXECINSTR;
-  if (len == 3 && strncmp (str, "tls", 3) == 0)
-    return SHF_TLS;
-
-#ifdef md_elf_section_word
-  {
-    int md_attr = md_elf_section_word (str, len);
-    if (md_attr >= 0)
-      return md_attr;
-  }
-#endif
-
-  as_warn (_("unrecognized section attribute"));
-  return 0;
-}
-
-static int
-obj_elf_section_type (char *str, size_t len)
+obj_elf_section_type (char *str, size_t len, bfd_boolean warn)
 {
   if (len == 8 && strncmp (str, "progbits", 8) == 0)
     return SHT_PROGBITS;
@@ -829,7 +805,39 @@ obj_elf_section_type (char *str, size_t len)
   }
 #endif
 
-  as_warn (_("unrecognized section type"));
+  if (warn)
+    as_warn (_("unrecognized section type"));
+  return 0;
+}
+
+static int
+obj_elf_section_word (char *str, size_t len, int *type)
+{
+  int ret;
+
+  if (len == 5 && strncmp (str, "write", 5) == 0)
+    return SHF_WRITE;
+  if (len == 5 && strncmp (str, "alloc", 5) == 0)
+    return SHF_ALLOC;
+  if (len == 9 && strncmp (str, "execinstr", 9) == 0)
+    return SHF_EXECINSTR;
+  if (len == 3 && strncmp (str, "tls", 3) == 0)
+    return SHF_TLS;
+
+#ifdef md_elf_section_word
+  {
+    int md_attr = md_elf_section_word (str, len);
+    if (md_attr >= 0)
+      return md_attr;
+  }
+#endif
+
+  ret = obj_elf_section_type (str, len, FALSE);
+  if (ret != 0)
+    *type = ret;
+  else
+    as_warn (_("unrecognized section attribute"));
+
   return 0;
 }
 
@@ -922,11 +930,23 @@ obj_elf_section (int push)
       ++input_line_pointer;
       SKIP_WHITESPACE ();
 
-      if (push)
+      if (push && ISDIGIT (*input_line_pointer))
        {
+         /* .pushsection has an optional subsection.  */
          new_subsection = (subsegT) get_absolute_expression ();
+
+         SKIP_WHITESPACE ();
+
+         /* Stop if we don't see a comma.  */
+         if (*input_line_pointer != ',')
+           goto done;
+
+         /* Skip the comma.  */
+         ++input_line_pointer;
+         SKIP_WHITESPACE ();
        }
-      else if (*input_line_pointer == '"')
+
+      if (*input_line_pointer == '"')
        {
          beg = demand_copy_C_string (&dummy);
          if (beg == NULL)
@@ -953,14 +973,14 @@ obj_elf_section (int push)
                      ignore_rest_of_line ();
                      return;
                    }
-                 type = obj_elf_section_type (beg, strlen (beg));
+                 type = obj_elf_section_type (beg, strlen (beg), TRUE);
                }
              else if (c == '@' || c == '%')
                {
                  beg = ++input_line_pointer;
                  c = get_symbol_end ();
                  *input_line_pointer = c;
-                 type = obj_elf_section_type (beg, input_line_pointer - beg);
+                 type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE);
                }
              else
                input_line_pointer = save;
@@ -1023,7 +1043,7 @@ obj_elf_section (int push)
              c = get_symbol_end ();
              *input_line_pointer = c;
 
-             attr |= obj_elf_section_word (beg, input_line_pointer - beg);
+             attr |= obj_elf_section_word (beg, input_line_pointer - beg, & type);
 
              SKIP_WHITESPACE ();
            }
@@ -1032,6 +1052,7 @@ obj_elf_section (int push)
        }
     }
 
+done:
   demand_empty_rest_of_line ();
 
   obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push);
@@ -1530,7 +1551,7 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSED)
 }
 
 /* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
-   There are five syntaxes:
+   There are six syntaxes:
 
    The first (used on Solaris) is
        .type SYM,#function
@@ -1542,8 +1563,32 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSED)
        .type SYM,%function
    The fifth (used on SVR4/860) is
        .type SYM,"function"
+   The sixth (emitted by recent SunPRO under Solaris) is
+       .type SYM,[0-9]
+   where the integer is the STT_* value.
    */
 
+static char *
+obj_elf_type_name (char *cp)
+{
+  char *p;
+
+  p = input_line_pointer;
+  if (*input_line_pointer >= '0'
+      && *input_line_pointer <= '9')
+    {
+      while (*input_line_pointer >= '0'
+            && *input_line_pointer <= '9')
+       ++input_line_pointer;
+      *cp = *input_line_pointer;
+      *input_line_pointer = '\0';
+    }
+  else
+    *cp = get_symbol_end ();
+
+  return p;
+}
+
 static void
 obj_elf_type (int ignore ATTRIBUTE_UNUSED)
 {
@@ -1571,23 +1616,27 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
       || *input_line_pointer == '%')
     ++input_line_pointer;
 
-  typename = input_line_pointer;
-  c = get_symbol_end ();
+  typename = obj_elf_type_name (& c);
 
   type = 0;
   if (strcmp (typename, "function") == 0
+      || strcmp (typename, "2") == 0
       || strcmp (typename, "STT_FUNC") == 0)
     type = BSF_FUNCTION;
   else if (strcmp (typename, "object") == 0
+          || strcmp (typename, "1") == 0
           || strcmp (typename, "STT_OBJECT") == 0)
     type = BSF_OBJECT;
   else if (strcmp (typename, "tls_object") == 0
+          || strcmp (typename, "6") == 0
           || strcmp (typename, "STT_TLS") == 0)
     type = BSF_OBJECT | BSF_THREAD_LOCAL;
   else if (strcmp (typename, "notype") == 0
+          || strcmp (typename, "0") == 0
           || strcmp (typename, "STT_NOTYPE") == 0)
     ;
   else if (strcmp (typename, "common") == 0
+          || strcmp (typename, "5") == 0
           || strcmp (typename, "STT_COMMON") == 0)
     {
       type = BSF_OBJECT;
This page took 0.0261 seconds and 4 git commands to generate.