This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch 1/6] ARM attributes: Tag_compatibility


Under ARM ABI 2.07, the Tag_compatibility attribute can no longer be
used multiple times. This patch adds the attribute to the fixed table,
rather than using the 'unknown attribute' list.

Since there is no longer any need for special handling for this tag,
I've also generalized the function names for the int-plus-string
attribute format.

I'll post some test cases separately.

OK?

Andrew

2009-01-12  Andrew Stubbs  <ams@codesourcery.com>

	bfd/
	* elf-attrs.c (bfd_elf_add_obj_attr_compat): Rename to
	bfd_elf_add_obj_attr_int_string.
	Read Tag_compatibility from its new location in the attribute array,
	rather than the attribute list.
	(_bfd_elf_copy_obj_attributes): bfd_elf_add_obj_attr_compat ->
	bfd_elf_add_obj_attr_int_string.
	(_bfd_elf_parse_attributes): Likewise.
	(_bfd_elf_merge_object_attributes): There's now only one
	Tag_compatibility, and it's in the array, not the list.
	* elf-bfd.h (NUM_KNOWN_OBJ_ATTRIBUTES): Set to 33 to include
	Tag_compatibility.
	(bfd_elf_add_obj_attr_compat): Rename to
	bfd_elf_add_obj_attr_int_string.
	(bfd_elf_add_proc_attr_compat): Rename to
	bfd_elf_add_proc_attr_int_string.
	elf32-arm.c (elf32_arm_merge_eabi_attributes): Explicitly don't handle
	Tag_compatibility.

	gas/
	* read.c (s_vendor_attribute): bfd_elf_add_obj_attr_compat ->
	bfd_elf_add_obj_attr_int_string.


---
 bfd/elf-attrs.c |  113 +++++++++++++++-----------------------------------------
 bfd/elf-bfd.h   |   11 ++---
 bfd/elf32-arm.c |    9 +---
 gas/read.c      |    2 
 4 files changed, 42 insertions(+), 93 deletions(-)

Index: bfd/elf-attrs.c
===================================================================
--- bfd/elf-attrs.c.orig
+++ bfd/elf-attrs.c
@@ -317,36 +317,17 @@ bfd_elf_add_obj_attr_string (bfd *abfd, 
   attr->s = _bfd_elf_attr_strdup (abfd, s);
 }
 
-/* Add a Tag_compatibility object attribute.  */
+/* Add a int+string object attribute.  */
 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 = 3;
+  attr->i = i;
+  attr->s = _bfd_elf_attr_strdup (abfd, s);
 }
 
 /* Copy the object attributes from IBFD to OBFD.  */
@@ -388,8 +369,8 @@ _bfd_elf_copy_obj_attributes (bfd *ibfd,
 					   in_attr->s);
 	      break;
 	    case 3:
-	      bfd_elf_add_obj_attr_compat (obfd, vendor, in_attr->i,
-					   in_attr->s);
+	      bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag,
+					       in_attr->i, in_attr->s);
 	      break;
 	    default:
 	      abort ();
@@ -511,8 +492,8 @@ _bfd_elf_parse_attributes (bfd *abfd, El
 			case 3:
 			  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;
 			case 2:
@@ -561,67 +542,35 @@ _bfd_elf_merge_object_attributes (bfd *i
 {
   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++)
     {
-      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
+	  _bfd_error_handler
 		(_("ERROR: %B: Must be processed by '%s' toolchain"),
 		 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;
 	}
     }
 
Index: bfd/elf-bfd.h
===================================================================
--- bfd/elf-bfd.h.orig
+++ bfd/elf-bfd.h
@@ -1371,7 +1371,7 @@ struct elf_find_verdep_info
 };
 
 /* The maximum number of known object attributes for any target.  */
-#define NUM_KNOWN_OBJ_ATTRIBUTES 32
+#define NUM_KNOWN_OBJ_ATTRIBUTES 33
 
 /* The value of an object attribute.  type & 1 indicates whether there
    is an integer value; type & 2 indicates whether there is a string
@@ -2188,10 +2188,11 @@ extern void bfd_elf_add_obj_attr_int (bf
 extern void bfd_elf_add_obj_attr_string (bfd *, int, int, const char *);
 #define bfd_elf_add_proc_attr_string(BFD, TAG, VALUE) \
   bfd_elf_add_obj_attr_string ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE))
-extern void bfd_elf_add_obj_attr_compat (bfd *, int, unsigned int,
-					 const char *);
-#define bfd_elf_add_proc_attr_compat(BFD, INTVAL, STRVAL) \
-  bfd_elf_add_obj_attr_compat ((BFD), OBJ_ATTR_PROC, (INTVAL), (STRVAL))
+extern void bfd_elf_add_obj_attr_int_string (bfd *, int, int, unsigned int,
+					     const char *);
+#define bfd_elf_add_proc_attr_int_string(BFD, TAG, INTVAL, STRVAL) \
+  bfd_elf_add_obj_attr_int_string ((BFD), OBJ_ATTR_PROC, (TAG), \
+				   (INTVAL), (STRVAL))
 
 extern char *_bfd_elf_attr_strdup (bfd *, const char *);
 extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *);
Index: bfd/elf32-arm.c
===================================================================
--- bfd/elf32-arm.c.orig
+++ bfd/elf32-arm.c
@@ -8371,6 +8371,10 @@ elf32_arm_merge_eabi_attributes (bfd *ib
 	    }
 	  break;
 
+	case Tag_compatibility:
+	  /* Merged in target-independent code.  */
+	  break;
+
 	default: /* All known attributes should be explicitly covered.   */
 	  abort ();
 	}
@@ -8398,12 +8402,7 @@ elf32_arm_merge_eabi_attributes (bfd *ib
 
   /* Check for any attributes not known on ARM.  */
   in_list = elf_other_obj_attributes_proc (ibfd);
-  while (in_list && in_list->tag == Tag_compatibility)
-    in_list = in_list->next;
-
   out_list = elf_other_obj_attributes_proc (obfd);
-  while (out_list && out_list->tag == Tag_compatibility)
-    out_list = out_list->next;
 
   for (; in_list != NULL; )
     {
Index: gas/read.c
===================================================================
--- gas/read.c.orig
+++ gas/read.c
@@ -2121,7 +2121,7 @@ s_vendor_attribute (int vendor)
   switch (type)
     {
     case 3:
-      bfd_elf_add_obj_attr_compat (stdoutput, vendor, i, s);
+      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);



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]