]> oss.titaniummirror.com Git - msp430-binutils.git/blobdiff - bfd/elf-attrs.c
Imported binutils-2.20
[msp430-binutils.git] / bfd / elf-attrs.c
index 4ee73e659b503b424963e182d3504c8f2645d809..c34297ccdaabf8d8e4a8bd2d53931686bb2c5525 100644 (file)
@@ -1,5 +1,5 @@
 /* ELF attributes support (based on ARM EABI attributes).
 /* ELF attributes support (based on ARM EABI attributes).
-   Copyright 2005, 2006, 2007
+   Copyright 2005, 2006, 2007, 2009
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -43,9 +43,11 @@ uleb128_size (unsigned int i)
 static bfd_boolean
 is_default_attr (obj_attribute *attr)
 {
 static bfd_boolean
 is_default_attr (obj_attribute *attr)
 {
-  if ((attr->type & 1) && attr->i != 0)
+  if (ATTR_TYPE_HAS_INT_VAL (attr->type) && attr->i != 0)
     return FALSE;
     return FALSE;
-  if ((attr->type & 2) && attr->s && *attr->s)
+  if (ATTR_TYPE_HAS_STR_VAL (attr->type) && attr->s && *attr->s)
+    return FALSE;
+  if (ATTR_TYPE_HAS_NO_DEFAULT (attr->type))
     return FALSE;
 
   return TRUE;
     return FALSE;
 
   return TRUE;
@@ -61,9 +63,9 @@ obj_attr_size (int tag, obj_attribute *attr)
     return 0;
 
   size = uleb128_size (tag);
     return 0;
 
   size = uleb128_size (tag);
-  if (attr->type & 1)
+  if (ATTR_TYPE_HAS_INT_VAL (attr->type))
     size += uleb128_size (attr->i);
     size += uleb128_size (attr->i);
-  if (attr->type & 2)
+  if (ATTR_TYPE_HAS_STR_VAL (attr->type))
     size += strlen ((char *)attr->s) + 1;
   return size;
 }
     size += strlen ((char *)attr->s) + 1;
   return size;
 }
@@ -149,9 +151,9 @@ write_obj_attribute (bfd_byte *p, int tag, obj_attribute *attr)
     return p;
 
   p = write_uleb128 (p, tag);
     return p;
 
   p = write_uleb128 (p, tag);
-  if (attr->type & 1)
+  if (ATTR_TYPE_HAS_INT_VAL (attr->type))
     p = write_uleb128 (p, attr->i);
     p = write_uleb128 (p, attr->i);
-  if (attr->type & 2)
+  if (ATTR_TYPE_HAS_STR_VAL (attr->type))
     {
       int len;
 
     {
       int len;
 
@@ -187,7 +189,12 @@ vendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size,
 
   attr = elf_known_obj_attributes (abfd)[vendor];
   for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
 
   attr = elf_known_obj_attributes (abfd)[vendor];
   for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
-    p = write_obj_attribute (p, i, &attr[i]);
+    {
+      int tag = i;
+      if (get_elf_backend_data (abfd)->obj_attrs_order)
+       tag = get_elf_backend_data (abfd)->obj_attrs_order (i);
+      p = write_obj_attribute (p, tag, &attr[tag]);
+    }
 
   for (list = elf_other_obj_attributes (abfd)[vendor];
        list;
 
   for (list = elf_other_obj_attributes (abfd)[vendor];
        list;
@@ -231,7 +238,7 @@ elf_new_obj_attr (bfd *abfd, int vendor, int tag)
 
   if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
     {
 
   if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
     {
-      /* Knwon tags are preallocated.  */
+      /* Known tags are preallocated.  */
       attr = &elf_known_obj_attributes (abfd)[vendor][tag];
     }
   else
       attr = &elf_known_obj_attributes (abfd)[vendor][tag];
     }
   else
@@ -265,7 +272,7 @@ bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, int tag)
 
   if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
     {
 
   if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
     {
-      /* Knwon tags are preallocated.  */
+      /* Known tags are preallocated.  */
       return elf_known_obj_attributes (abfd)[vendor][tag].i;
     }
   else
       return elf_known_obj_attributes (abfd)[vendor][tag].i;
     }
   else
@@ -290,7 +297,7 @@ bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, int tag, unsigned int i)
   obj_attribute *attr;
 
   attr = elf_new_obj_attr (abfd, vendor, tag);
   obj_attribute *attr;
 
   attr = elf_new_obj_attr (abfd, vendor, tag);
-  attr->type = 1;
+  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
   attr->i = i;
 }
 
   attr->i = i;
 }
 
@@ -300,10 +307,10 @@ _bfd_elf_attr_strdup (bfd *abfd, const char * s)
 {
   char * p;
   int len;
 {
   char * p;
   int len;
-  
+
   len = strlen (s) + 1;
   p = (char *) bfd_alloc (abfd, len);
   len = strlen (s) + 1;
   p = (char *) bfd_alloc (abfd, len);
-  return memcpy (p, s, len);
+  return (char *) memcpy (p, s, len);
 }
 
 /* Add a string object attribute.  */
 }
 
 /* Add a string object attribute.  */
@@ -313,40 +320,21 @@ bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, int tag, const char *s)
   obj_attribute *attr;
 
   attr = elf_new_obj_attr (abfd, vendor, tag);
   obj_attribute *attr;
 
   attr = elf_new_obj_attr (abfd, vendor, tag);
-  attr->type = 2;
+  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
   attr->s = _bfd_elf_attr_strdup (abfd, s);
 }
 
   attr->s = _bfd_elf_attr_strdup (abfd, s);
 }
 
-/* Add a Tag_compatibility object attribute.  */
+/* Add a int+string object attribute.  */
 void
 void
-bfd_elf_add_obj_attr_compat (bfd *abfd, int vendor, unsigned int i,
-                            const char *s)
+bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, int tag,
+                                unsigned int i, const char *s)
 {
 {
-  obj_attribute_list *list;
-  obj_attribute_list *p;
-  obj_attribute_list **lastp;
-
-  list = (obj_attribute_list *)
-    bfd_alloc (abfd, sizeof (obj_attribute_list));
-  memset (list, 0, sizeof (obj_attribute_list));
-  list->tag = Tag_compatibility;
-  list->attr.type = 3;
-  list->attr.i = i;
-  list->attr.s = _bfd_elf_attr_strdup (abfd, s);
+  obj_attribute *attr;
 
 
-  lastp = &elf_other_obj_attributes (abfd)[vendor];
-  for (p = *lastp; p; p = p->next)
-    {
-      int cmp;
-      if (p->tag != Tag_compatibility)
-       break;
-      cmp = strcmp(s, p->attr.s);
-      if (cmp < 0 || (cmp == 0 && i < p->attr.i))
-       break;
-      lastp = &p->next;
-    }
-  list->next = *lastp;
-  *lastp = list;
+  attr = elf_new_obj_attr (abfd, vendor, tag);
+  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+  attr->i = i;
+  attr->s = _bfd_elf_attr_strdup (abfd, s);
 }
 
 /* Copy the object attributes from IBFD to OBFD.  */
 }
 
 /* Copy the object attributes from IBFD to OBFD.  */
@@ -378,18 +366,18 @@ _bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
           list = list->next)
        {
          in_attr = &list->attr;
           list = list->next)
        {
          in_attr = &list->attr;
-         switch (in_attr->type)
+         switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
            {
            {
-           case 1:
+           case ATTR_TYPE_FLAG_INT_VAL:
              bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
              break;
              bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
              break;
-           case 2:
+           case ATTR_TYPE_FLAG_STR_VAL:
              bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
                                           in_attr->s);
              break;
              bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
                                           in_attr->s);
              break;
-           case 3:
-             bfd_elf_add_obj_attr_compat (obfd, vendor, in_attr->i,
-                                          in_attr->s);
+           case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
+             bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag,
+                                              in_attr->i, in_attr->s);
              break;
            default:
              abort ();
              break;
            default:
              abort ();
@@ -440,7 +428,7 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
   bfd_vma len;
   const char *std_section;
 
   bfd_vma len;
   const char *std_section;
 
-  contents = bfd_malloc (hdr->sh_size);
+  contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
   if (!contents)
     return;
   if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
   if (!contents)
     return;
   if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
@@ -506,21 +494,21 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
                      tag = read_unsigned_leb128 (abfd, p, &n);
                      p += n;
                      type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
                      tag = read_unsigned_leb128 (abfd, p, &n);
                      p += n;
                      type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
-                     switch (type)
+                     switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
                        {
                        {
-                       case 3:
+                       case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
                          val = read_unsigned_leb128 (abfd, p, &n);
                          p += n;
                          val = read_unsigned_leb128 (abfd, p, &n);
                          p += n;
-                         bfd_elf_add_obj_attr_compat (abfd, vendor, val,
-                                                      (char *)p);
+                         bfd_elf_add_obj_attr_int_string (abfd, vendor, tag,
+                                                          val, (char *)p);
                          p += strlen ((char *)p) + 1;
                          break;
                          p += strlen ((char *)p) + 1;
                          break;
-                       case 2:
+                       case ATTR_TYPE_FLAG_STR_VAL:
                          bfd_elf_add_obj_attr_string (abfd, vendor, tag,
                                                       (char *)p);
                          p += strlen ((char *)p) + 1;
                          break;
                          bfd_elf_add_obj_attr_string (abfd, vendor, tag,
                                                       (char *)p);
                          p += strlen ((char *)p) + 1;
                          break;
-                       case 1:
+                       case ATTR_TYPE_FLAG_INT_VAL:
                          val = read_unsigned_leb128 (abfd, p, &n);
                          p += n;
                          bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
                          val = read_unsigned_leb128 (abfd, p, &n);
                          p += n;
                          bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
@@ -561,67 +549,35 @@ _bfd_elf_merge_object_attributes (bfd *ibfd, bfd *obfd)
 {
   obj_attribute *in_attr;
   obj_attribute *out_attr;
 {
   obj_attribute *in_attr;
   obj_attribute *out_attr;
-  obj_attribute_list *in_list;
-  obj_attribute_list *out_list;
   int vendor;
 
   /* The only common attribute is currently Tag_compatibility,
      accepted in both processor and "gnu" sections.  */
   for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
     {
   int vendor;
 
   /* The only common attribute is currently Tag_compatibility,
      accepted in both processor and "gnu" sections.  */
   for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
     {
-      in_list = elf_other_obj_attributes (ibfd)[vendor];
-      out_list = elf_other_obj_attributes (ibfd)[vendor];
-      while (in_list && in_list->tag == Tag_compatibility)
+      /* Handle Tag_compatibility.  The tags are only compatible if the flags
+        are identical and, if the flags are '1', the strings are identical.
+        If the flags are non-zero, then we can only use the string "gnu".  */
+      in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility];
+      out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility];
+
+      if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0)
        {
        {
-         in_attr = &in_list->attr;
-         if (in_attr->i == 0)
-           continue;
-         if (in_attr->i == 1 && strcmp (in_attr->s, "gnu") != 0)
-           {
-             _bfd_error_handler
-               (_("ERROR: %B: Must be processed by '%s' toolchain"),
+         _bfd_error_handler
+               (_("error: %B: Must be processed by '%s' toolchain"),
                 ibfd, in_attr->s);
                 ibfd, in_attr->s);
-             return FALSE;
-           }
-         if (!out_list || out_list->tag != Tag_compatibility
-             || strcmp (in_attr->s, out_list->attr.s) != 0)
-           {
-             /* Add this compatibility tag to the output.  */
-             bfd_elf_add_proc_attr_compat (obfd, in_attr->i, in_attr->s);
-             continue;
-           }
-         out_attr = &out_list->attr;
-         /* Check all the input tags with the same identifier.  */
-         for (;;)
-           {
-             if (out_list->tag != Tag_compatibility
-                 || in_attr->i != out_attr->i
-                 || strcmp (in_attr->s, out_attr->s) != 0)
-               {
-                 _bfd_error_handler
-                   (_("ERROR: %B: Incompatible object tag '%s':%d"),
-                    ibfd, in_attr->s, in_attr->i);
-                 return FALSE;
-               }
-             in_list = in_list->next;
-             if (in_list->tag != Tag_compatibility
-                 || strcmp (in_attr->s, in_list->attr.s) != 0)
-               break;
-             in_attr = &in_list->attr;
-             out_list = out_list->next;
-             if (out_list)
-               out_attr = &out_list->attr;
-           }
+         return FALSE;
+       }
 
 
-         /* Check the output doesn't have extra tags with this identifier.  */
-         if (out_list && out_list->tag == Tag_compatibility
-             && strcmp (in_attr->s, out_list->attr.s) == 0)
-           {
-             _bfd_error_handler
-               (_("ERROR: %B: Incompatible object tag '%s':%d"),
-                ibfd, in_attr->s, out_list->attr.i);
-             return FALSE;
-           }
+      if (in_attr->i != out_attr->i
+         || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0))
+       {
+         _bfd_error_handler (_("error: %B: Object tag '%d, %s' is "
+                               "incompatible with tag '%d, %s'"),
+                             ibfd,
+                             in_attr->i, in_attr->s ? in_attr->s : "",
+                             out_attr->i, out_attr->s ? out_attr->s : "");
+         return FALSE;
        }
     }
 
        }
     }