2013-02-06 Sandra Loosemore <sandra@codesourcery.com>
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
index a101e8a996d67d7a02dc76eba4278931385923c4..33772619194511bead50ebe62179253e102755fe 100644 (file)
 #include "elf/mep.h"
 #endif
 
+#ifdef TC_NIOS2
+#include "elf/nios2.h"
+#endif
+
 static void obj_elf_line (int);
 static void obj_elf_size (int);
 static void obj_elf_type (int);
@@ -72,6 +76,7 @@ static void obj_elf_visibility (int);
 static void obj_elf_symver (int);
 static void obj_elf_subsection (int);
 static void obj_elf_popsection (int);
+static void obj_elf_gnu_attribute (int);
 static void obj_elf_tls_common (int);
 static void obj_elf_lcomm (int);
 static void obj_elf_struct (int);
@@ -113,6 +118,9 @@ static const pseudo_typeS elf_pseudo_table[] =
   {"vtable_inherit", (void (*) (int)) &obj_elf_vtable_inherit, 0},
   {"vtable_entry", (void (*) (int)) &obj_elf_vtable_entry, 0},
 
+  /* A GNU extension for object attributes.  */
+  {"gnu_attribute", obj_elf_gnu_attribute, 0},
+
   /* These are used for dwarf.  */
   {"2byte", cons, 2},
   {"4byte", cons, 4},
@@ -447,7 +455,6 @@ obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
       symbolP = get_sym_from_input_line_and_check ();
       c = *input_line_pointer;
       S_SET_WEAK (symbolP);
-      symbol_get_obj (symbolP)->local = 1;
       if (c == ',')
        {
          input_line_pointer++;
@@ -658,6 +665,14 @@ obj_elf_change_section (const char *name,
          /* A section on Alpha may have SHF_ALPHA_GPREL.  */
          else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL)
            override = TRUE;
+#endif
+#ifdef TC_RX
+         else if (attr == (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)
+                  && (ssect->type == SHT_INIT_ARRAY
+                      || ssect->type == SHT_FINI_ARRAY
+                      || ssect->type == SHT_PREINIT_ARRAY))
+           /* RX init/fini arrays can and should have the "awx" attributes set.  */
+           ;
 #endif
          else
            {
@@ -1049,10 +1064,15 @@ obj_elf_section (int push)
              group_name = obj_elf_section_name ();
              if (group_name == NULL)
                attr &= ~SHF_GROUP;
-             else if (strncmp (input_line_pointer, ",comdat", 7) == 0)
+             else if (*input_line_pointer == ',')
                {
-                 input_line_pointer += 7;
-                 linkonce = 1;
+                 ++input_line_pointer;
+                 SKIP_WHITESPACE ();
+                 if (strncmp (input_line_pointer, "comdat", 6) == 0)
+                   {
+                     input_line_pointer += 6;
+                     linkonce = 1;
+                   }
                }
              else if (strncmp (name, ".gnu.linkonce", 13) == 0)
                linkonce = 1;
@@ -1425,6 +1445,138 @@ obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
                  BFD_RELOC_VTABLE_ENTRY);
 }
 
+#define skip_whitespace(str)  do { if (*(str) == ' ') ++(str); } while (0)
+
+static inline int
+skip_past_char (char ** str, char c)
+{
+  if (**str == c)
+    {
+      (*str)++;
+      return 0;
+    }
+  else
+    return -1;
+}
+#define skip_past_comma(str) skip_past_char (str, ',')
+
+/* Parse an attribute directive for VENDOR.
+   Returns the attribute number read, or zero on error.  */
+
+int
+obj_elf_vendor_attribute (int vendor)
+{
+  expressionS exp;
+  int type;
+  int tag;
+  unsigned int i = 0;
+  char *s = NULL;
+
+  /* Read the first number or name.  */
+  skip_whitespace (input_line_pointer);
+  s = input_line_pointer;
+  if (ISDIGIT (*input_line_pointer))
+    {
+      expression (& exp);
+      if (exp.X_op != O_constant)
+       goto bad;
+      tag = exp.X_add_number;
+    }
+  else
+    {
+      char *name;
+
+      /* A name may contain '_', but no other punctuation.  */
+      for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
+          ++input_line_pointer)
+       i++;
+      if (i == 0)
+       goto bad;
+
+      name = (char *) alloca (i + 1);
+      memcpy (name, s, i);
+      name[i] = '\0';
+
+#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
+#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
+#endif
+
+      tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
+      if (tag == -1)
+       {
+         as_bad (_("Attribute name not recognised: %s"), name);
+         ignore_rest_of_line ();
+         return 0;
+       }
+    }
+
+  type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
+
+  if (skip_past_comma (&input_line_pointer) == -1)
+    goto bad;
+  if (type & 1)
+    {
+      expression (& exp);
+      if (exp.X_op != O_constant)
+       {
+         as_bad (_("expected numeric constant"));
+         ignore_rest_of_line ();
+         return 0;
+       }
+      i = exp.X_add_number;
+    }
+  if ((type & 3) == 3
+      && skip_past_comma (&input_line_pointer) == -1)
+    {
+      as_bad (_("expected comma"));
+      ignore_rest_of_line ();
+      return 0;
+    }
+  if (type & 2)
+    {
+      int len;
+
+      skip_whitespace (input_line_pointer);
+      if (*input_line_pointer != '"')
+       goto bad_string;
+      s = demand_copy_C_string (&len);
+    }
+
+  switch (type & 3)
+    {
+    case 3:
+      bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
+      break;
+    case 2:
+      bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
+      break;
+    case 1:
+      bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
+      break;
+    default:
+      abort ();
+    }
+
+  demand_empty_rest_of_line ();
+  return tag;
+bad_string:
+  as_bad (_("bad string constant"));
+  ignore_rest_of_line ();
+  return 0;
+bad:
+  as_bad (_("expected <tag> , <value>"));
+  ignore_rest_of_line ();
+  return 0;
+}
+
+/* Parse a .gnu_attribute directive.  */
+
+static void
+obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
+{
+  obj_elf_vendor_attribute (OBJ_ATTR_GNU);
+}
+
 void
 elf_obj_read_begin_hook (void)
 {
This page took 0.026375 seconds and 4 git commands to generate.