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] Arm EABI object attributes


The attached patch adds partial support for Arm EABI object attributes.
Partial because it only supports file scope attributes. Finer grained 
(section/symbol level) attributes are currently ignored.

I've tried to connfine the knowledge of the file level format of this section 
to bfd. My original implementation had gas create these sections manually, 
but that ended up with significant amounts of duplication.

The majority of the testsuite changes are to squish spurious failures due to 
the presence of the new section. There already seem to be similar hacks for 
mips special sections, and I couldn't think of a better fix.

There are 4 new assembly directives. The first 3 (.cpu, .arch and .fpu) are 
technically independent of this patch. They implement the equivalent of the 
the -mcpu=, -march= and -mfpu= commandline options.  Some changes were 
necessary to make ".cpu all" (the default on many targets) mark the object 
file based on the instructions actually user, rather than marking it as being 
for the most advanced CPU we know about.

The .eabi_attribute allows the user to add specific tags to an object.

Ok?
Comments/suggestions?

Paul

2005-09-28  Paul Brook  <paul@codesourcery.com>

bfd/
	* elf32-arm.c: Move #include "elf/arm.x" after libbfd.h.
	(elf32_arm_obj_tdata): Add eabi_attributes.
	(uleb128_size, elf32_arm_eabi_attr_size, write_uleb128,
	elf32_arm_set_eabi_attr_contents, elf32_arm_bfd_final_link,
	elf32_arm_new_eabi_attr, elf32_arm_add_eabi_attr_int,
	elf32_arm_add_eabi_attr_compat, elf32_arm_find_eabi_attr,
	elf32_arm_merge_eabi_attributes): New functions.
	(elf32_arm_copy_private_bfd_data): Copy EABI object attributes.
gas/
	* config/tc-arm.c: Don't provide fallback default for CPU_DEFAULT.
	(arm_arch_used, thumb_arch_used, selected_cpu, selected_cpu_name):
	New variables.
	(s_arm_eabi_attribute, s_arm_arch, s_arm_cpu, s_arm_fpu,
	aeabi_set_public_attributes, arm_md_end): New functions.
	(md_pseudo_table): Add "cpu", "arch", "fpu" and "eabi_attribute".
	(md_assemble): Set thumb_arch_used and arm_arch_used.
	(md_begin): Set defaut cpu if CPU_DEFAULT not defined.
	* config/tc-arm.h (md_end): Define.
	* doc/c-arm.texi: Document .cpu, .arch, .fpu and .eabi_attribute.
gas/testsuite/
	* gas/arm/arm7t.d: Only disassemble code sections.
	* gas/arm/bignum1.d: Ignore Arm object attribute sections.
	* gas/arm/mapping.d: Ditto.
	* gas/arm/unwind.d: Ditto.
	* gas/elf/section0.d: Ditto.
	* gas/elf/section1.d: Ditto.
	* gas/elf/elf.exp: Set target_machine for Arm EABI based targets.
	* gas/elf/section2.e-armeabi: New file.
include/elf/
	* arm.h: Add prototypes for BFD object attribute routines.
ld/testsuite/
	* ld-arm/arm-rel31.d: Ignore Arm object attribute sections.
	* ld-arm/arm-target1-abs.d: Ditto.
	* ld-arm/arm-target1-rel.d: Ditto.
	* ld-arm/arm-target2-abs.d: Ditto.
	* ld-arm/arm-target2-got-rel.d: Ditto.
	* ld-arm/arm-target2-rel.d: Ditto.
Index: bfd/elf32-arm.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elf32-arm.c,v
retrieving revision 1.55
diff -u -p -r1.55 elf32-arm.c
--- bfd/elf32-arm.c	9 Sep 2005 13:10:01 -0000	1.55
+++ bfd/elf32-arm.c	28 Sep 2005 16:05:14 -0000
@@ -18,11 +18,11 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-#include "elf/arm.h"
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
+#include "elf/arm.h"
 
 #ifndef NUM_ELEM
 #define NUM_ELEM(a)  (sizeof (a) / (sizeof (a)[0]))
@@ -1535,6 +1535,8 @@ struct elf32_arm_obj_tdata
 
   /* tls_type for each local got entry.  */
   char *local_got_tls_type;
+
+  aeabi_attribute *eabi_attributes;
 };
 
 #define elf32_arm_tdata(abfd) \
@@ -3909,6 +3911,145 @@ elf32_arm_final_link_relocate (reloc_how
     }
 }
 
+
+static int
+uleb128_size (unsigned int i)
+{
+  int size;
+  size = 1;
+  while (i >= 0x80)
+    {
+      i >>= 7;
+      size++;
+    }
+  return size;
+}
+
+/* Returns the size of the eabi object attributess section.  */
+bfd_vma
+elf32_arm_eabi_attr_size (bfd *abfd)
+{
+  bfd_vma size;
+  aeabi_attribute *attr;
+
+  size = 16; /* 'A' <size> "aeabi" 0x1 <size>.  */
+  for (attr = elf32_arm_tdata (abfd)->eabi_attributes;
+       attr;
+       attr = attr->next)
+    {
+      size += uleb128_size (attr->tag);
+      if (attr->type & 1)
+	size += uleb128_size (attr->i);
+      if (attr->type & 2)
+	size += strlen ((char *)attr->s) + 1;
+    }
+  return size;
+}
+
+static bfd_byte *
+write_uleb128 (bfd_byte *p, unsigned int val)
+{
+  bfd_byte c;
+  do
+    {
+      c = val & 0x7f;
+      val >>= 7;
+      if (val)
+	c |= 0x80;
+      *(p++) = c;
+    }
+  while (val);
+  return p;
+}
+
+/* Write the contents of the eabi attributes section to p.  */
+void
+elf32_arm_set_eabi_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size)
+{
+  bfd_byte *p;
+  aeabi_attribute *attr;
+
+  p = contents;
+  *(p++) = 'A';
+  bfd_put_32 (abfd, size - 1, p);
+  p += 4;
+  memcpy (p, "aeabi", 6);
+  p += 6;
+  *(p++) = 1;
+  bfd_put_32 (abfd, size - 11, p);
+  p += 4;
+  for (attr = elf32_arm_tdata (abfd)->eabi_attributes;
+       attr;
+       attr = attr->next)
+    {
+      p = write_uleb128 (p, attr->tag);
+      if (attr->type & 1)
+	p = write_uleb128 (p, attr->i);
+      if (attr->type & 2)
+	{
+	  int len;
+
+	  len = strlen (attr->s) + 1;
+	  memcpy (p, attr->s, len);
+	  p += len;
+	}
+    }
+}
+
+/* Override final_link to handle EABI EABI object attribute sections.  */
+
+static bfd_boolean
+elf32_arm_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+  asection *o;
+  struct bfd_link_order *p;
+  asection *attr_section = NULL;
+  bfd_byte *contents;
+  bfd_vma size = 0;
+
+  /* elf32_arm_merge_private_bfd_data wil already have merged the
+     object attributes.  Remove the input sections from the link, and set
+     the contents of the output secton.  */
+  for (o = abfd->sections; o != NULL; o = o->next)
+    {
+      if (strcmp (o->name, ".ARM.attributes") == 0)
+	{
+	  for (p = o->map_head.link_order; p != NULL; p = p->next)
+	    {
+	      asection *input_section;
+
+	      if (p->type != bfd_indirect_link_order)
+		continue;
+	      input_section = p->u.indirect.section;
+	      /* Hack: reset the SEC_HAS_CONTENTS flag so that
+		 elf_link_input_bfd ignores this section.  */
+	      input_section->flags &= ~SEC_HAS_CONTENTS;
+	    }
+	    
+	  size = elf32_arm_eabi_attr_size (abfd);
+	  bfd_set_section_size (abfd, o, size);
+	  attr_section = o;
+	  /* Skip this section later on.  */
+	  o->map_head.link_order = NULL;
+	}
+    }
+  /* Invoke the ELF linker to do all the work.  */
+  if (!bfd_elf_final_link (abfd, info))
+    return FALSE;
+
+  if (attr_section)
+    {
+      contents = bfd_malloc(size);
+      if (contents == NULL)
+	return FALSE;
+      elf32_arm_set_eabi_attr_contents (abfd, contents, size);
+      bfd_set_section_contents (abfd, attr_section, contents, 0, size);
+      free (contents);
+    }
+  return TRUE;
+}
+
+
 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS.  */
 static void
 arm_add_to_rel (bfd *              abfd,
@@ -4239,6 +4380,57 @@ elf32_arm_relocate_section (bfd *       
   return TRUE;
 }
 
+/* Create a new attribute, or return the existing one if it already exists.  */
+static aeabi_attribute *
+elf32_arm_new_eabi_attr (bfd *abfd, int tag, int type)
+{
+  aeabi_attribute *attr;
+
+  /* Create a new tag.  */
+  attr = (aeabi_attribute *) bfd_alloc (abfd, sizeof (aeabi_attribute));
+  memset (attr, 0, sizeof (aeabi_attribute));
+  attr->tag = tag;
+  attr->type = type;
+  attr->next = elf32_arm_tdata (abfd)->eabi_attributes;
+  elf32_arm_tdata (abfd)->eabi_attributes = attr;
+  return attr;
+}
+
+void
+elf32_arm_add_eabi_attr_int (bfd *abfd, int tag, unsigned int i)
+{
+  aeabi_attribute *attr;
+
+  attr = elf32_arm_new_eabi_attr (abfd, tag, 1);
+  attr->i = i;
+}
+
+void
+elf32_arm_add_eabi_attr_string (bfd *abfd, int tag, const char *s)
+{
+  aeabi_attribute *attr;
+  int len;
+
+  attr = elf32_arm_new_eabi_attr (abfd, tag, 2);
+  len = strlen (s) + 1;
+  attr->s = (char *)bfd_alloc(abfd, len);
+  memcpy (attr->s, s, len);
+}
+
+void
+elf32_arm_add_eabi_attr_compat (bfd *abfd, int tag, unsigned int i,
+				const char *s)
+{
+  aeabi_attribute *attr;
+  int len;
+
+  attr = elf32_arm_new_eabi_attr (abfd, tag, 3);
+  attr->i = i;
+  len = strlen (s) + 1;
+  attr->s = (char *)bfd_alloc(abfd, len);
+  memcpy (attr->s, s, len);
+}
+
 /* Set the right machine number.  */
 
 static bfd_boolean
@@ -4296,6 +4488,7 @@ elf32_arm_copy_private_bfd_data (bfd *ib
 {
   flagword in_flags;
   flagword out_flags;
+  aeabi_attribute *attr;
 
   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
@@ -4340,6 +4533,279 @@ elf32_arm_copy_private_bfd_data (bfd *ib
   elf_elfheader (obfd)->e_ident[EI_OSABI] =
     elf_elfheader (ibfd)->e_ident[EI_OSABI];
 
+  /* Copy EABI object attributes.  */
+  for (attr = elf32_arm_tdata (ibfd)->eabi_attributes;
+       attr;
+       attr = attr->next)
+    {
+      switch (attr->type)
+	{
+	case 1:
+	  elf32_arm_add_eabi_attr_int (obfd, attr->tag, attr->i);
+	  break;
+	case 2:
+	  elf32_arm_add_eabi_attr_string (obfd, attr->tag, attr->s);
+	  break;
+	case 3:
+	  elf32_arm_add_eabi_attr_compat (obfd, attr->tag, attr->i, attr->s);
+	  break;
+	default:
+	  abort();
+	}
+    }
+  return TRUE;
+}
+
+
+/* Find the eabi object attrbute with the given TAG.  Return NULL if no
+   attribute exists.  */
+aeabi_attribute *
+elf32_arm_find_eabi_attr (bfd *abfd, int tag)
+{
+  aeabi_attribute *attr;
+
+  attr = elf32_arm_tdata (abfd)->eabi_attributes;
+  while (attr)
+    {
+      if (attr->tag == tag)
+	return attr;
+      attr = attr->next;
+    }
+  return NULL;
+}
+
+
+/* Merge EABI object attributes from IBFD into OBFD.  Raise an error if there
+   are conflicting attributes.  */
+static bfd_boolean
+elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
+{
+  aeabi_attribute *attr;
+  aeabi_attribute *prev;
+  /* Some tags have 0 = don't care, 1 = strong requirement,
+     2 = weak requirement.  */
+  static const int order_312[3] = {3, 1, 2};
+  bfd_boolean seen_compat = FALSE;
+  bfd_boolean seen_tag;
+
+  for (attr = elf32_arm_tdata (ibfd)->eabi_attributes;
+       attr;
+       attr = attr->next)
+    {
+      prev = elf32_arm_find_eabi_attr(obfd, attr->tag);
+      if (prev)
+	{
+	  /* Merge this attribute with existing attributes.  */
+	  switch (attr->tag)
+	    {
+	    case 4: /* Tag_CPU_raw_name.  */
+	    case 5: /* Tag_CPU_name.  */
+	    case 30: /* Tag_ABI_optimization_goals.  */
+	    case 31: /* Tag_ABI_FP_optimization_goals.  */
+	      /* Use the first value seen.  */
+	      break;
+	    case 6: /* Tag_CPU_arch.  */
+	    case 7: /* Tag_ARM_ISA_use.  */
+	    case 9: /* Tag_THUMB_ISA_use.  */
+	    case 10: /* Tag_VFP_arch.  */
+	    case 11: /* Tag_WMMX_arch.  */
+	    case 12: /* Tag_NEON_arch.  */
+	      /* ??? Do NEON and WMMX conflict?  */
+	    case 19: /* Tag_ABI_FP_rounding.  */
+	    case 20: /* Tag_ABI_FP_denormal.  */
+	    case 21: /* Tag_ABI_FP_exceptions.  */
+	    case 22: /* Tag_ABI_FP_user_exceptions.  */
+	    case 23: /* Tag_ABI_FP_number_model.  */
+	    case 25: /* Tag_ABI_align8_preserved.  */
+	    case 27: /* Tag_ABI_HardFP_use.  */
+	      /* Use the largest value specified.  */
+	      if (attr->i > prev->i)
+		prev->i = attr->i;
+	      break;
+	    case 8: /* Tag_CPU_arch_profile N/A.  */
+	      /* Warn if conflicting architecture profiules used.  */
+	      if (prev->i && attr->i && attr->i != prev->i)
+		{
+		  _bfd_error_handler
+		    (_("ERROR: %B: Conflicting architecture profiles %c/%c"),
+		     ibfd, attr->i, prev->i);
+		  return FALSE;
+		}
+	      if (attr->i)
+		prev->i = attr->i;
+	      break;
+	    case 13: /* Tag_PCS_config.  */
+	      if (prev->i && attr->i)
+		{
+		  /* ??? It's probably ok to mix some of these configs,
+		     so this is only a warning.  */
+		  _bfd_error_handler
+		    (_("ERROR: %B: Conflicting platform configuration"), ibfd);
+		  return FALSE;
+		}
+	      else if (attr->i)
+		attr->i = prev->i;
+	      break;
+	    case 14: /* Tag_ABI_PCS_R9_use.  */
+	      if (prev->i != 3 && attr->i != 3)
+		{
+		  _bfd_error_handler
+		    (_("ERROR: %B: Conflicting use of R9"), ibfd);
+		  return FALSE;
+		}
+	      if (prev->i == 3)
+		prev->i = attr->i;
+	      break;
+	    case 15: /* Tag_ABI_PCS_RW_data.  */
+	    case 16: /* Tag_ABI_PCS_RO_data.  */
+	      /* Use the smallest value specified.  */
+	      if (attr->i < prev->i)
+		prev->i = attr->i;
+	      break;
+	    case 17: /* Tag_ABI_PCS_GOT_use.  */
+	      if (attr->i > 2 || prev->i > 2
+		  || order_312[attr->i] < order_312[prev->i])
+		prev->i = attr->i;
+	      break;
+	    case 18: /* Tag_ABI_ABI_PCS_wchar_t.  */
+	      if (prev->i && attr->i && prev->i != attr->i)
+		{
+		  _bfd_error_handler
+		    (_("ERROR: %B: Conflicting definitions of wchar_t"), ibfd);
+		  return FALSE;
+		}
+	      if (attr->i)
+		prev->i = attr->i;
+	      break;
+	    case 24: /* Tag_ABI_align8_needed.  */
+	      /* ??? Check agains Tag_ABI_align8_preserved.  */
+	      if (attr->i > 2 || prev->i > 2
+		  || order_312[attr->i] < order_312[prev->i])
+		prev->i = attr->i;
+	      break;
+	    case 26: /* Tag_ABI_enum_size.  */
+	      if (prev->i == 0)
+		prev->i = attr->i;
+	      else if (attr->i != 0)
+		{
+		  if ((attr->i == 1 && prev->i != 1)
+		      || (attr->i != 1 && prev->i == 1))
+		    {
+		      _bfd_error_handler
+			(_("ERROR: %B: Conflicting enum sizes"), ibfd);
+		    }
+		}
+	      break;
+	    case 28: /* Tag_ABI_VFP_args.  */
+	      if (attr->i != prev->i)
+		{
+		  _bfd_error_handler
+		    (_("ERROR: %B uses VFP register arguments, %B does not"),
+		     ibfd, obfd);
+		  return FALSE;
+		}
+	      break;
+	    case 29: /* Tag_ABI_WMMX_args.  */
+	      if (attr->i != prev->i)
+		{
+		  _bfd_error_handler
+		    (_("ERROR: %B uses iWMMXt register arguments, %B does not"),
+		     ibfd, obfd);
+		  return FALSE;
+		}
+	      break;
+	    case 32: /* Tag_compatibility.  */
+	      /* Ignore zero tags.  */
+	      if (attr->i == 0)
+		break;
+	      if (attr->i == 1)
+		{
+		  _bfd_error_handler
+		    (_("ERROR: %B: Must be processed by '%s' toolchain"),
+		     ibfd, attr->s);
+		  return FALSE;
+		}
+	      /* Look for compat tags from the same vendor.  An object must
+	         have all or none of the tags.  This loop checks the output
+		 has all the tags present on the input.  */
+	      seen_tag = FALSE;
+	      for (; prev; prev = prev->next)
+		{
+		  if (prev->tag == 32 && strcmp (prev->s, attr->s) == 0)
+		    {
+		      seen_compat = TRUE;
+		      seen_tag = TRUE;
+		      if (prev->i == attr->i)
+			break;
+		    }
+		}
+	      if (seen_tag && !prev)
+		{
+		  _bfd_error_handler
+		    (_("ERROR: %B: Incompatible object tag '%s':%d"),
+		     ibfd, attr->s, attr->i);
+		  return FALSE;
+		}
+	      break;
+	    default:
+	      if (attr->tag < 64)
+		_bfd_error_handler
+		  (_("Warning: %B: Unknown EABI object attribute %d"),
+		   ibfd, attr->tag);
+	      break;
+	    }
+	}
+      if (!prev)
+	{
+	  switch (attr->type)
+	    {
+	    case 1:
+	      elf32_arm_add_eabi_attr_int (obfd, attr->tag, attr->i);
+	      break;
+	    case 2:
+	      elf32_arm_add_eabi_attr_string (obfd, attr->tag, attr->s);
+	      break;
+	    case 3:
+	      elf32_arm_add_eabi_attr_compat (obfd, attr->tag, attr->i,
+					      attr->s);
+	      break;
+	    default:
+	      abort();
+	    }
+	}
+    }
+  if (seen_compat)
+    {
+      /* Check that the input has all or none of the tags present in
+	 the output.  */
+      for (prev = elf32_arm_tdata (obfd)->eabi_attributes;
+	   prev;
+	   prev = prev->next)
+	{
+	  if (prev->tag != 32)
+	    continue;
+	  seen_tag = FALSE;
+	  for (attr = elf32_arm_tdata (ibfd)->eabi_attributes;
+	       attr;
+	       attr = attr->next)
+	    {
+	      if (attr->tag == 32 && strcmp (prev->s, attr->s) == 0)
+		{
+		  seen_tag = TRUE;
+		  if (attr->i == prev->i)
+		    break;
+		}
+	    }
+	  if (seen_tag && !attr)
+	    {
+	      _bfd_error_handler
+		(_("ERROR: %B: Incompatible object tag '%s':%d"),
+		 ibfd, attr->s, attr->i);
+	      return FALSE;
+	    }
+	}
+
+    }
   return TRUE;
 }
 
@@ -4362,6 +4828,9 @@ elf32_arm_merge_private_bfd_data (bfd * 
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
 
+  if (!elf32_arm_merge_eabi_attributes (ibfd, obfd))
+    return FALSE;
+
   /* The input BFD must have had its flags initialised.  */
   /* The following seems bogus to me -- The flags are initialized in
      the assembler but I don't think an elf_flags_init field is
@@ -6489,9 +6958,125 @@ elf32_arm_fake_sections (bfd * abfd, Elf
       hdr->sh_type = SHT_ARM_EXIDX;
       hdr->sh_flags |= SHF_LINK_ORDER;
     }
+  else if (strcmp(name, ".ARM.attributes") == 0)
+    {
+      hdr->sh_type = SHT_ARM_ATTRIBUTES;
+    }
   return TRUE;
 }
 
+/* Parse an Arm EABI attributes section.  */
+static void
+elf32_arm_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
+{
+  bfd_byte *contents;
+  bfd_byte *p;
+  bfd_vma len;
+
+  contents = bfd_malloc (hdr->sh_size);
+  if (!contents)
+    return;
+  if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
+				 hdr->sh_size))
+    {
+      free (contents);
+      return;
+    }
+  p = contents;
+  if (*(p++) == 'A')
+    {
+      len = hdr->sh_size - 1;
+      while (len > 0)
+	{
+	  int namelen;
+	  bfd_vma section_len;
+
+	  section_len = bfd_get_32 (abfd, p);
+	  p += 4;
+	  if (section_len > len)
+	    section_len = len;
+	  len -= section_len;
+	  namelen = strlen ((char *)p) + 1;
+	  section_len -= namelen + 4;
+	  if (strcmp((char *)p, "aeabi") != 0)
+	    {
+	      /* Vendor section.  Ignore it.  */
+	      p += namelen + section_len;
+	    }
+	  else
+	    {
+	      p += namelen;
+	      while (section_len > 0)
+		{
+		  int tag;
+		  unsigned int n;
+		  unsigned int val;
+		  bfd_vma subsection_len;
+		  bfd_byte *end;
+
+		  tag = read_unsigned_leb128 (abfd, p, &n);
+		  p += n;
+		  subsection_len = bfd_get_32 (abfd, p);
+		  p += 4;
+		  if (subsection_len > section_len)
+		    subsection_len = section_len;
+		  section_len -= subsection_len;
+		  subsection_len -= n + 4;
+		  end = p + subsection_len;
+		  switch (tag)
+		    {
+		    case 1: /* File tag.  */
+		      while (p < end)
+			{
+			  bfd_boolean is_string;
+
+			  tag = read_unsigned_leb128 (abfd, p, &n);
+			  p += n;
+			  if (tag == 4 || tag == 5)
+			    is_string = 1;
+			  else if (tag < 32)
+			    is_string = 0;
+			  else
+			    is_string = (tag & 1) != 0;
+			  if (tag == 32)
+			    {
+			      val = read_unsigned_leb128 (abfd, p, &n);
+			      p += n;
+			      elf32_arm_add_eabi_attr_compat (abfd, tag,
+							      val, (char *)p);
+			      p += strlen ((char *)p) + 1;
+			    }
+			  else if (is_string)
+			    {
+			      elf32_arm_add_eabi_attr_string (abfd, tag,
+							      (char *)p);
+			      p += strlen ((char *)p) + 1;
+			    }
+			  else
+			    {
+			      val = read_unsigned_leb128 (abfd, p, &n);
+			      p += n;
+			      elf32_arm_add_eabi_attr_int (abfd, tag, val);
+			    }
+			}
+		      break;
+		    case 2: /* Section tag.  */
+		    case 3: /* Symbol tag.  */
+		      /* Don't have anywhere convenient to attach these.
+		         Fall through for now.  */
+		    default:
+		      /* Ignore things we don't kow about.  */
+		      p += subsection_len;
+		      subsection_len = 0;
+		      break;
+		    }
+		}
+	    }
+	}
+    }
+  free (contents);
+}
+
 /* Handle an ARM specific section when reading an object file.  This is
    called when bfd_section_from_shdr finds a section with an unknown
    type.  */
@@ -6521,6 +7106,8 @@ elf32_arm_section_from_shdr (bfd *abfd,
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     return FALSE;
 
+  if (hdr->sh_type == SHT_ARM_ATTRIBUTES)
+    elf32_arm_parse_attributes(abfd, hdr);
   return TRUE;
 }
 
@@ -6926,6 +7513,7 @@ const struct elf_size_info elf32_arm_siz
 #define bfd_elf32_new_section_hook		elf32_arm_new_section_hook
 #define bfd_elf32_bfd_is_target_special_symbol	elf32_arm_is_target_special_symbol
 #define bfd_elf32_close_and_cleanup             elf32_arm_close_and_cleanup
+#define bfd_elf32_bfd_final_link		elf32_arm_bfd_final_link
 
 #define elf_backend_get_symbol_type             elf32_arm_get_symbol_type
 #define elf_backend_gc_mark_hook                elf32_arm_gc_mark_hook
Index: binutils/testsuite/binutils-all/readelf.ss
===================================================================
RCS file: /var/cvsroot/src-cvs/src/binutils/testsuite/binutils-all/readelf.ss,v
retrieving revision 1.6
diff -u -p -r1.6 readelf.ss
--- binutils/testsuite/binutils-all/readelf.ss	30 Dec 2004 22:37:31 -0000	1.6
+++ binutils/testsuite/binutils-all/readelf.ss	11 Sep 2005 14:41:04 -0000
@@ -13,6 +13,6 @@ Symbol table '.symtab' contains .* entri
 # and .call_table_text sections.
 #...
 .*   .: 00000000     0 NOTYPE  GLOBAL DEFAULT    1 text_symbol
-     .: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND external_symbol
+    ..: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND external_symbol
     ..: 00000000     0 NOTYPE  GLOBAL DEFAULT    [34] data_symbol
     ..: 00000004     4 OBJECT  GLOBAL DEFAULT ( COM|ANSI_COM) common_symbol
Index: gas/config/tc-arm.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/config/tc-arm.c,v
retrieving revision 1.228
diff -u -p -r1.228 tc-arm.c
--- gas/config/tc-arm.c	27 Sep 2005 13:23:36 -0000	1.228
+++ gas/config/tc-arm.c	27 Sep 2005 20:16:33 -0000
@@ -115,8 +115,6 @@ enum arm_float_abi
 #else
 #if defined __thumb__
 #define CPU_DEFAULT	(ARM_ARCH_V5T)
-#else
-#define CPU_DEFAULT	ARM_ANY
 #endif
 #endif
 #endif
@@ -142,6 +140,8 @@ enum arm_float_abi
 #define streq(a, b)	      (strcmp (a, b) == 0)
 
 static unsigned long cpu_variant;
+static unsigned long arm_arch_used;
+static unsigned long thumb_arch_used;
 
 /* Flags stored in private area of BFD structure.  */
 static int uses_apcs_26	     = FALSE;
@@ -162,6 +162,10 @@ static int march_cpu_opt = -1;
 static int march_fpu_opt = -1;
 static int mfpu_opt = -1;
 static int mfloat_abi_opt = -1;
+/* Record user cpu selection for object attributes.  Unlike 
+   cpu_variant/mcpu_cpu_opt this will be zero for the "any" cpu.  */
+static int selected_cpu = -1;
+static const char *selected_cpu_name = NULL;
 #ifdef OBJ_ELF
 # ifdef EABI_DEFAULT
 static int meabi_flags = EABI_DEFAULT;
@@ -2790,6 +2794,95 @@ s_arm_unwind_raw (int ignored ATTRIBUTE_
 
   demand_empty_rest_of_line ();
 }
+
+
+/* Parse a .eabi_attribute directive.  */
+
+static void
+s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
+{
+  expressionS exp;
+  bfd_boolean is_string;
+  int tag;
+  unsigned int i = 0;
+  char *s = NULL;
+  char saved_char;
+
+  expression (& exp);
+  if (exp.X_op != O_constant)
+    goto bad;
+
+  tag = exp.X_add_number;
+  if (tag == 4 || tag == 5 || tag == 32 || (tag > 32 && (tag & 1) != 0))
+    is_string = 1;
+  else
+    is_string = 0;
+
+  if (skip_past_comma (&input_line_pointer) == FAIL)
+    goto bad;
+  if (tag == 32 || !is_string)
+    {
+      expression (& exp);
+      if (exp.X_op != O_constant)
+	{
+	  as_bad (_("expected numeric constant"));
+	  ignore_rest_of_line ();
+	  return;
+	}
+      i = exp.X_add_number;
+    }
+  if (tag == 32 && skip_past_comma (&input_line_pointer) == FAIL)
+    {
+      as_bad (_("expected comma"));
+      ignore_rest_of_line ();
+      return;
+    }
+  if (is_string)
+    {
+      skip_whitespace(input_line_pointer);
+      if (*input_line_pointer != '"')
+	goto bad_string;
+      input_line_pointer++;
+      s = input_line_pointer;
+      while (*input_line_pointer && *input_line_pointer != '"')
+	input_line_pointer++;
+      if (*input_line_pointer != '"')
+	goto bad_string;
+      saved_char = *input_line_pointer;
+      *input_line_pointer = 0;
+    }
+  else
+    {
+      s = NULL;
+      saved_char = 0;
+    }
+  
+  if (tag == 32)
+    elf32_arm_add_eabi_attr_compat (stdoutput, tag, i, s);
+  else if (is_string)
+    elf32_arm_add_eabi_attr_string (stdoutput, tag, s);
+  else
+    elf32_arm_add_eabi_attr_int (stdoutput, tag, i);
+
+  if (s)
+    {
+      *input_line_pointer = saved_char;
+      input_line_pointer++;
+    }
+  demand_empty_rest_of_line ();
+  return;
+bad_string:
+  as_bad (_("bad string constant"));
+  ignore_rest_of_line ();
+  return;
+bad:
+  as_bad (_("expected <tag> , <value>"));
+  ignore_rest_of_line ();
+}
+
+static void s_arm_arch (int);
+static void s_arm_cpu (int);
+static void s_arm_fpu (int);
 #endif /* OBJ_ELF */
 
 /* This table describes all the machine specific pseudo-ops the assembler
@@ -2830,6 +2923,10 @@ const pseudo_typeS md_pseudo_table[] =
   { "pad",		s_arm_unwind_pad,	0 },
   { "setfp",		s_arm_unwind_setfp,	0 },
   { "unwind_raw",	s_arm_unwind_raw,	0 },
+  { "cpu",		s_arm_cpu,		0 },
+  { "arch",		s_arm_arch,		0 },
+  { "fpu",		s_arm_fpu,		0 },
+  { "eabi_attribute",	s_arm_eabi_attribute,	0 },
 #else
   { "word",	   cons, 4},
 #endif
@@ -8003,6 +8100,14 @@ md_assemble (char *str)
 	      return;
 	    }
 	}
+      thumb_arch_used |= opcode->tvariant;
+      /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
+         set those bits when Thumb-2 32-bit instuctions are seen.  ie.
+	 anything other than bl/blx.
+	 This is overly pessimistic for relaxable instructions.  */
+      if ((inst.size == 4 && (inst.instruction & 0xf800e800) != 0xf000e800)
+	  || inst.relax)
+	thumb_arch_used |= ARM_EXT_V6T2;
     }
   else
     {
@@ -8027,6 +8132,12 @@ md_assemble (char *str)
       inst.size = INSN_SIZE;
       if (!parse_operands (p, opcode->operands))
 	opcode->aencode ();
+      /* blx is marked as both v4T and v5 to work around the fact that
+	 v5 doesn't really exist (only v5t).  */
+      if (opcode->avariant == (ARM_EXT_V4T | ARM_EXT_V5))
+	arm_arch_used |= ARM_EXT_V4T;
+      else
+	arm_arch_used |= opcode->avariant;
     }
   output_inst (str);
 }
@@ -12260,11 +12371,23 @@ md_begin (void)
 	mfpu_opt = FPU_ARCH_FPA;
     }
 
+#ifdef CPU_DEFAULT
+  if (mcpu_cpu_opt == -1)
+    selected_cpu = mcpu_cpu_opt = CPU_DEFAULT;
+#else
   if (mcpu_cpu_opt == -1)
-    mcpu_cpu_opt = CPU_DEFAULT;
+    {
+      mcpu_cpu_opt = ARM_ANY;
+      selected_cpu = 0;
+    }
+  else if (selected_cpu == -1)
+    selected_cpu = mcpu_cpu_opt;
+#endif
 
   cpu_variant = mcpu_cpu_opt | mfpu_opt;
 
+  arm_arch_used = thumb_arch_used = 0;
+
 #if defined OBJ_COFF || defined OBJ_ELF
   {
     unsigned int flags = 0;
@@ -12896,6 +13019,10 @@ arm_parse_cpu (char * str)
       {
 	mcpu_cpu_opt = opt->value;
 	mcpu_fpu_opt = opt->default_fpu;
+	if (streq(str, "any"))
+	  selected_cpu = 0;
+	else
+	  selected_cpu_name = opt->name;
 
 	if (ext != NULL)
 	  return arm_parse_extension (ext, &mcpu_cpu_opt);
@@ -12931,6 +13058,10 @@ arm_parse_arch (char * str)
       {
 	march_cpu_opt = opt->value;
 	march_fpu_opt = opt->default_fpu;
+	if (streq(str, "any"))
+	  selected_cpu = 0;
+	else
+	  selected_cpu_name = opt->name;
 
 	if (ext != NULL)
 	  return arm_parse_extension (ext, &march_cpu_opt);
@@ -13106,3 +13237,185 @@ md_show_usage (FILE * fp)
   -EL                     assemble code for a little-endian cpu\n"));
 #endif
 }
+
+
+#ifdef OBJ_ELF
+/* Set the public EABI object attributes.  */
+static void
+aeabi_set_public_attributes (void)
+{
+  int arch;
+  int flags;
+
+  /* Choose the architecture based on the capabilities of the requested cpu
+     (if any) and/or the instructions actually used.  */
+  flags = selected_cpu | arm_arch_used | thumb_arch_used;
+  if (flags & ARM_EXT_V6T2)
+    arch = 8;
+  else if (flags & ARM_EXT_V6Z)
+    arch = 7;
+  else if (flags & ARM_EXT_V6K)
+    arch = 9;
+  else if (flags & ARM_EXT_V6)
+    arch = 6;
+  else if (flags & ARM_EXT_V5E)
+    arch = 4;
+  else if (flags & (ARM_EXT_V5 | ARM_EXT_V5T))
+    arch = 3;
+  else if (flags & ARM_EXT_V4T)
+    arch = 2;
+  else if (flags & ARM_EXT_V4)
+    arch = 1;
+  else
+    arch = 0;
+
+  /* Tag_CPU_name.  */
+  if (selected_cpu_name)
+    {
+      if (strncmp(selected_cpu_name, "armv", 4) == 0)
+	selected_cpu_name += 4;
+      elf32_arm_add_eabi_attr_string (stdoutput, 5, selected_cpu_name);
+    }
+  /* Tag_CPU_arch.  */
+  elf32_arm_add_eabi_attr_int (stdoutput, 6, arch);
+  /* Tag_ARM_ISA_use.  */
+  if (arm_arch_used)
+    elf32_arm_add_eabi_attr_int (stdoutput, 8, 1);
+  /* Tag_THUMB_ISA_use.  */
+  if (thumb_arch_used)
+    elf32_arm_add_eabi_attr_int (stdoutput, 9,
+				 (thumb_arch_used & ARM_EXT_V6T2) ? 2 : 1);
+  /* Tag_VFP_arch.  */
+  if ((arm_arch_used | thumb_arch_used) & FPU_ARCH_VFP_V2)
+    elf32_arm_add_eabi_attr_int (stdoutput, 10, 2);
+  else if ((arm_arch_used | thumb_arch_used) & FPU_ARCH_VFP_V1)
+    elf32_arm_add_eabi_attr_int (stdoutput, 10, 1);
+  /* Tag_WMMX_arch.  */
+  if ((arm_arch_used | thumb_arch_used) & ARM_CEXT_IWMMXT)
+    elf32_arm_add_eabi_attr_int (stdoutput, 11, 1);
+}
+
+/* Add the .ARM.attributes section.  */
+void
+arm_md_end (void)
+{
+  segT s;
+  char *p;
+  addressT addr;
+  offsetT size;
+  
+  if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
+    return;
+
+  aeabi_set_public_attributes ();
+  size = elf32_arm_eabi_attr_size (stdoutput);
+  s = subseg_new (".ARM.attributes", 0);
+  bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA);
+  addr = frag_now_fix ();
+  p = frag_more (size);
+  elf32_arm_set_eabi_attr_contents (stdoutput, (bfd_byte *)p, size);
+}
+
+
+/* Parse a .cpu directive.  */
+
+static void
+s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
+{
+  struct arm_cpu_option_table *opt;
+  char *name;
+  char saved_char;
+
+  name = input_line_pointer;
+  while (*input_line_pointer && !ISSPACE(*input_line_pointer))
+    input_line_pointer++;
+  saved_char = *input_line_pointer;
+  *input_line_pointer = 0;
+
+  for (opt = arm_cpus; opt->name != NULL; opt++)
+    if (streq (opt->name, name))
+      {
+	mcpu_cpu_opt = opt->value;
+	if (!streq(name, "all"))
+	  {
+	    selected_cpu = mcpu_cpu_opt;
+	    selected_cpu_name = opt->name;
+	  }
+	cpu_variant = mcpu_cpu_opt | mfpu_opt;
+	*input_line_pointer = saved_char;
+	demand_empty_rest_of_line ();
+	return;
+      }
+  as_bad (_("unknown cpu `%s'"), name);
+  *input_line_pointer = saved_char;
+  ignore_rest_of_line ();
+}
+
+
+/* Parse a .arch directive.  */
+
+static void
+s_arm_arch (int ignored ATTRIBUTE_UNUSED)
+{
+  struct arm_arch_option_table *opt;
+  char saved_char;
+  char *name;
+
+  name = input_line_pointer;
+  while (*input_line_pointer && !ISSPACE(*input_line_pointer))
+    input_line_pointer++;
+  saved_char = *input_line_pointer;
+  *input_line_pointer = 0;
+  
+  for (opt = arm_archs; opt->name != NULL; opt++)
+    if (streq (opt->name, name))
+      {
+	mcpu_cpu_opt = opt->value;
+	if (!streq(name, "all"))
+	  {
+	    selected_cpu = mcpu_cpu_opt;
+	    selected_cpu_name = opt->name;
+	  }
+	cpu_variant = mcpu_cpu_opt | mfpu_opt;
+	*input_line_pointer = saved_char;
+	demand_empty_rest_of_line ();
+	return;
+      }
+
+  as_bad (_("unknown architecture `%s'\n"), name);
+  *input_line_pointer = saved_char;
+  ignore_rest_of_line ();
+}
+
+
+/* Parse a .fpu directive.  */
+
+static void
+s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
+{
+  struct arm_option_value_table *opt;
+  char saved_char;
+  char *name;
+
+  name = input_line_pointer;
+  while (*input_line_pointer && !ISSPACE(*input_line_pointer))
+    input_line_pointer++;
+  saved_char = *input_line_pointer;
+  *input_line_pointer = 0;
+  
+  for (opt = arm_fpus; opt->name != NULL; opt++)
+    if (streq (opt->name, name))
+      {
+	mfpu_opt = opt->value;
+	cpu_variant = selected_cpu | mfpu_opt;
+	*input_line_pointer = saved_char;
+	demand_empty_rest_of_line ();
+	return;
+      }
+
+  as_bad (_("unknown floating point format `%s'\n"), name);
+  *input_line_pointer = saved_char;
+  ignore_rest_of_line ();
+}
+#endif /* OBJ_ELF */
+
Index: gas/config/tc-arm.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/config/tc-arm.h,v
retrieving revision 1.35
diff -u -p -r1.35 tc-arm.h
--- gas/config/tc-arm.h	6 Sep 2005 16:59:23 -0000	1.35
+++ gas/config/tc-arm.h	10 Sep 2005 02:14:47 -0000
@@ -92,6 +92,11 @@ extern int arm_relax_frag (asection *, s
 /* We also need to mark assembler created symbols:  */
 #define tc_frob_fake_label(S) arm_frob_label (S)
 
+#ifdef OBJ_ELF
+#define md_end arm_md_end
+extern void arm_md_end (void);
+#endif
+
 /* NOTE: The fake label creation in stabs.c:s_stab_generic() has
    deliberately not been updated to mark assembler created stabs
    symbols as Thumb.  */
Index: gas/doc/c-arm.texi
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/doc/c-arm.texi,v
retrieving revision 1.34
diff -u -p -r1.34 c-arm.texi
--- gas/doc/c-arm.texi	27 Sep 2005 13:23:38 -0000	1.34
+++ gas/doc/c-arm.texi	27 Sep 2005 14:55:14 -0000
@@ -505,6 +505,27 @@ the stack pointer by @var{offset} bytes.
 For example @code{.unwind_raw 4, 0xb1, 0x01} is equivalent to
 @code{.save @{r0@}}
 
+@cindex @code{.cpu} directive, ARM
+@item .cpu @var{name}
+Select the target processor.  Valid values for @var{name} are the same as
+for the @option{-mcpu} commandline option.
+
+@cindex @code{.arch} directive, ARM
+@item .arch @var{name}
+Select the target architecture.  Valid values for @var{name} are the same as
+for the @option{-march} commandline option.
+
+@cindex @code{.fpu} directive, ARM
+@item .fpu @var{name}
+Select the floating point unit to assemble for.  Valid values for @var{name}
+are the same as for the @option{-mfpu} commandline option.
+
+@cindex @code{.eabi_attribute} directive, ARM
+@item .eabi_attribute @var{tag}, @var{value}
+Set the EABI object attribute number @var{tag} to @var{value}.  The value
+is either a @code{number}, @code{"string"}, or @code{number, "string"}
+depending on the tag.
+
 @end table
 
 @node ARM Opcodes
Index: gas/testsuite/gas/arm/arm7t.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/arm7t.d,v
retrieving revision 1.11
diff -u -p -r1.11 arm7t.d
--- gas/testsuite/gas/arm/arm7t.d	14 Nov 2003 15:12:43 -0000	1.11
+++ gas/testsuite/gas/arm/arm7t.d	13 Sep 2005 22:20:13 -0000
@@ -1,4 +1,4 @@
-#objdump: -Dr --prefix-addresses --show-raw-insn
+#objdump: -dr --prefix-addresses --show-raw-insn
 #name: ARM arm7t
 #as: -mcpu=arm7t -EL
 
Index: gas/testsuite/gas/arm/bignum1.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/bignum1.d,v
retrieving revision 1.3
diff -u -p -r1.3 bignum1.d
--- gas/testsuite/gas/arm/bignum1.d	4 Jul 2005 14:55:52 -0000	1.3
+++ gas/testsuite/gas/arm/bignum1.d	14 Sep 2005 14:35:30 -0000
@@ -8,3 +8,5 @@
 
 Contents of section .data:
  0000 [08]0000000 000000[08]0 11111111 11111111  \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.
+# Ignore .ARM.attributes section
+#...
Index: gas/testsuite/gas/arm/mapping.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/mapping.d,v
retrieving revision 1.6
diff -u -p -r1.6 mapping.d
--- gas/testsuite/gas/arm/mapping.d	4 Jul 2005 14:55:52 -0000	1.6
+++ gas/testsuite/gas/arm/mapping.d	14 Sep 2005 00:07:45 -0000
@@ -16,5 +16,7 @@ SYMBOL TABLE:
 0+00 l       .data	0+0 \$d
 0+00 l    d  foo	0+0 (|foo)
 0+00 l       foo	0+0 \$t
+#Maybe section symbol for .ARM.attributes
+#...
 0+00 g       .text	0+0 mapping
 0+08 g     F .text	0+0 thumb_mapping
Index: gas/testsuite/gas/arm/unwind.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/unwind.d,v
retrieving revision 1.7
diff -u -p -r1.7 unwind.d
--- gas/testsuite/gas/arm/unwind.d	4 Jul 2005 14:55:52 -0000	1.7
+++ gas/testsuite/gas/arm/unwind.d	14 Sep 2005 15:32:26 -0000
@@ -37,3 +37,5 @@ Contents of section .ARM.exidx:
  0000 00000000 (b0b0a880 04000000|80a8b0b0 00000004) 00000000  .*
  0010 (08000000 0c000000 0c000000 1c000000|00000008 0000000c 0000000c 0000001c)  .*
  0020 (10000000 08849780|00000010 80978408)                    .*
+# Ignore .ARM.attributes section
+#...
Index: gas/testsuite/gas/elf/elf.exp
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/elf/elf.exp,v
retrieving revision 1.29
diff -u -p -r1.29 elf.exp
--- gas/testsuite/gas/elf/elf.exp	15 Apr 2005 11:38:59 -0000	1.29
+++ gas/testsuite/gas/elf/elf.exp	14 Sep 2005 17:57:23 -0000
@@ -50,6 +50,12 @@ if { ([istarget "*-*-*elf*"]		
     if {[istarget m32r*-*-*]} then {
 	set target_machine -m32r
     }
+    if { ([istarget "*arm*-*-*"]
+	  || [istarget "xscale*-*-*"])
+	&& ([istarget "*-*-*eabi"]
+	    || [istarget "*-*-symbianelf"])} then {
+	set target_machine -armeabi
+    }
     run_dump_test "ehopt0"
     run_dump_test "group0a" 
     run_dump_test "group0b" 
Index: gas/testsuite/gas/elf/section0.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/elf/section0.d,v
retrieving revision 1.4
diff -u -p -r1.4 section0.d
--- gas/testsuite/gas/elf/section0.d	3 Sep 2003 08:26:50 -0000	1.4
+++ gas/testsuite/gas/elf/section0.d	14 Sep 2005 14:36:26 -0000
@@ -13,3 +13,5 @@ Contents of section B:
  0+000 02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02.*
 Contents of section C:
  0+000 03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03.*
+# Arm includes a .ARM.attributes section here
+#...
Index: gas/testsuite/gas/elf/section1.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/elf/section1.d,v
retrieving revision 1.4
diff -u -p -r1.4 section1.d
--- gas/testsuite/gas/elf/section1.d	3 Sep 2003 08:26:50 -0000	1.4
+++ gas/testsuite/gas/elf/section1.d	14 Sep 2005 14:36:54 -0000
@@ -13,3 +13,5 @@ Contents of section B:
  0+000 02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02 ?02.*
 Contents of section C:
  0+000 03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03 ?03.*
+# Arm includes a .ARM.attributes section here
+#...
Index: gas/testsuite/gas/elf/section2.e-armeabi
===================================================================
RCS file: gas/testsuite/gas/elf/section2.e-armeabi
diff -N gas/testsuite/gas/elf/section2.e-armeabi
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/elf/section2.e-armeabi	14 Sep 2005 14:47:47 -0000
@@ -0,0 +1,9 @@
+
+Symbol table '.symtab' contains 6 entries:
+   Num:    Value[ 	]* Size Type    Bind   Vis      Ndx Name
+     0: 0+0     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0+0     0 SECTION LOCAL  DEFAULT    1 
+     2: 0+0     0 SECTION LOCAL  DEFAULT    2 
+     3: 0+0     0 SECTION LOCAL  DEFAULT    3 
+     4: 0+0     0 SECTION LOCAL  DEFAULT    4 
+     5: 0+0     0 SECTION LOCAL  DEFAULT    5 
Index: include/elf/arm.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/include/elf/arm.h,v
retrieving revision 1.26
diff -u -p -r1.26 arm.h
--- include/elf/arm.h	9 Sep 2005 13:06:21 -0000	1.26
+++ include/elf/arm.h	20 Sep 2005 14:33:50 -0000
@@ -223,6 +223,26 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
   FAKE_RELOC (R_ARM_PC13,               R_ARM_LDR_PC_G0)  /* Unclear whether meaning is different.  */
 END_RELOC_NUMBERS (R_ARM_max)
 
+#ifdef BFD_ARCH_SIZE
+typedef struct aeabi_attribute
+{
+  struct aeabi_attribute *next;
+  int tag;
+  int type;
+  unsigned int i;
+  char *s;
+} aeabi_attribute;
+
+/* Routines for manipulating EABI object attributes.  */
+void elf32_arm_add_eabi_attr_int (bfd *, int, unsigned int);
+void elf32_arm_add_eabi_attr_string (bfd *, int, const char *);
+void elf32_arm_add_eabi_attr_compat (bfd *, int, unsigned int, const char *);
+
+aeabi_attribute *elf32_arm_find_eabi_attr (bfd *, int);
+void elf32_arm_set_eabi_attr_contents (bfd *, bfd_byte *, bfd_vma);
+bfd_vma elf32_arm_eabi_attr_size (bfd *);
+#endif
+
 /* The name of the note section used to identify arm variants.  */
 #define ARM_NOTE_SECTION ".note.gnu.arm.ident"
 
Index: ld/testsuite/ld-arm/arm-rel31.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-rel31.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-rel31.d
--- ld/testsuite/ld-arm/arm-rel31.d	17 Sep 2004 12:18:18 -0000	1.1
+++ ld/testsuite/ld-arm/arm-rel31.d	14 Sep 2005 16:21:55 -0000
@@ -3,3 +3,5 @@
 
 Contents of section .text:
  8000 (10000000 fcffff7f 08000080 f4ffffff|00000010 7ffffffc 80000008 fffffff4) .*
+# Ignore .ARM.attributes section
+#...
Index: ld/testsuite/ld-arm/arm-target1-abs.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-target1-abs.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-target1-abs.d
--- ld/testsuite/ld-arm/arm-target1-abs.d	17 Sep 2004 12:18:18 -0000	1.1
+++ ld/testsuite/ld-arm/arm-target1-abs.d	14 Sep 2005 16:19:41 -0000
@@ -3,3 +3,5 @@
 
 Contents of section .text:
  8000 (04800000|00008004) .*
+# Ignore .ARM.attributes section
+#...
Index: ld/testsuite/ld-arm/arm-target1-rel.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-target1-rel.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-target1-rel.d
--- ld/testsuite/ld-arm/arm-target1-rel.d	17 Sep 2004 12:18:18 -0000	1.1
+++ ld/testsuite/ld-arm/arm-target1-rel.d	14 Sep 2005 16:19:59 -0000
@@ -3,3 +3,5 @@
 
 Contents of section .text:
  8000 (04000000|00000004) .*
+# Ignore .ARM.attributes section
+#...
Index: ld/testsuite/ld-arm/arm-target2-abs.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-target2-abs.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-target2-abs.d
--- ld/testsuite/ld-arm/arm-target2-abs.d	30 Sep 2004 17:03:53 -0000	1.1
+++ ld/testsuite/ld-arm/arm-target2-abs.d	14 Sep 2005 16:21:16 -0000
@@ -3,3 +3,5 @@
 
 Contents of section .text:
  8000 (04800000|00008004) .*
+# Ignore .ARM.attributes section
+#...
Index: ld/testsuite/ld-arm/arm-target2-got-rel.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-target2-got-rel.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-target2-got-rel.d
--- ld/testsuite/ld-arm/arm-target2-got-rel.d	17 Sep 2004 12:18:18 -0000	1.1
+++ ld/testsuite/ld-arm/arm-target2-got-rel.d	14 Sep 2005 16:21:21 -0000
@@ -5,3 +5,5 @@ Contents of section .text:
  8000 (00100000|00001000) .*
 Contents of section .got:
  9000 (04800000|00008004) .*
+# Ignore .ARM.attributes section
+#...
Index: ld/testsuite/ld-arm/arm-target2-rel.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-target2-rel.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-target2-rel.d
--- ld/testsuite/ld-arm/arm-target2-rel.d	17 Sep 2004 12:18:18 -0000	1.1
+++ ld/testsuite/ld-arm/arm-target2-rel.d	14 Sep 2005 16:21:01 -0000
@@ -3,3 +3,5 @@
 
 Contents of section .text:
  8000 (04000000|00000004) .*
+# Ignore .ARM.attributes section
+#...

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