Kyle McMartin d6a7761
commit cd49363b8ae1725522ea29ccc0dda7b138f3d5aa
Kyle McMartin d6a7761
Author: Nick Clifton <nickc@redhat.com>
Kyle McMartin d6a7761
Date:   Tue Oct 30 12:44:53 2012 +0000
Kyle McMartin d6a7761
Kyle McMartin d6a7761
    bfd:
Kyle McMartin d6a7761
            * elf32-arm.c (elf32_arm_print_private_bfd_data): Recognise and
Kyle McMartin d6a7761
            display the new ARM hard-float/soft-float ABI flags for EABI_VER5
Kyle McMartin d6a7761
            (elf32_arm_post_process_headers): Add the hard-float/soft-float
Kyle McMartin d6a7761
            ABI flag as appropriate for ET_DYN/ET_EXEC in EABI_VER5.
Kyle McMartin d6a7761
    
Kyle McMartin d6a7761
    binutils:
Kyle McMartin d6a7761
            * readelf.c (decode_ARM_machine_flags): Recognise and display the
Kyle McMartin d6a7761
            new ARM hard-float/soft-float ABI flags for EABI_VER5. Split out
Kyle McMartin d6a7761
            the code for EABI_VER4 and EABI_VER5 to allow this.
Kyle McMartin d6a7761
    
Kyle McMartin d6a7761
    elfcpp:
Kyle McMartin d6a7761
            * arm.h: New enum for EABI soft- and hard-float flags.
Kyle McMartin d6a7761
    
Kyle McMartin d6a7761
    gold:
Kyle McMartin d6a7761
            * gold.cc (Target_arm::do_adjust_elf_header): Add the
Kyle McMartin d6a7761
            hard-float/soft-float ABI flag as appropriate for ET_DYN/ET_EXEC
Kyle McMartin d6a7761
            in EABI_VER5.
Kyle McMartin d6a7761
    
Kyle McMartin d6a7761
    include:
Kyle McMartin d6a7761
            * elf/arm.h (EF_ARM_ABI_FLOAT_SOFT): New define.
Kyle McMartin d6a7761
            (EF_ARM_ABI_FLOAT_HARD): Likewise.
Kyle McMartin d6a7761
    
Kyle McMartin d6a7761
    ld/testsuite:
Kyle McMartin d6a7761
            * ld-arm/eabi-hard-float.s: New test source.
Kyle McMartin d6a7761
            * ld-arm/eabi-soft-float.s: New test source.
Kyle McMartin d6a7761
            * ld-arm/eabi-hard-float.d: New test.
Kyle McMartin d6a7761
            * ld-arm/eabi-soft-float.d: New test.
Kyle McMartin d6a7761
            * ld-arm/eabi-soft-float-ABI4.d: New test.
Kyle McMartin d6a7761
            * ld-arm/eabi-soft-float-r.d: New test.
Kyle McMartin d6a7761
            * ld-arm/arm-elf.xp: Use the new tests.
Kyle McMartin d6a7761
    
Kyle McMartin d6a7761
--- a/bfd/elf32-arm.c
Kyle McMartin d6a7761
+++ b/bfd/elf32-arm.c
Kyle McMartin d6a7761
@@ -12110,6 +12110,15 @@ elf32_arm_print_private_bfd_data (bfd *abfd, void * ptr)
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
     case EF_ARM_EABI_VER5:
Kyle McMartin d6a7761
       fprintf (file, _(" [Version5 EABI]"));
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
+      if (flags & EF_ARM_ABI_FLOAT_SOFT)
Kyle McMartin d6a7761
+	fprintf (file, _(" [soft-float ABI]"));
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
+      if (flags & EF_ARM_ABI_FLOAT_HARD)
Kyle McMartin d6a7761
+	fprintf (file, _(" [hard-float ABI]"));
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
+      flags &= ~(EF_ARM_ABI_FLOAT_SOFT | EF_ARM_ABI_FLOAT_HARD);
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
     eabi:
Kyle McMartin d6a7761
       if (flags & EF_ARM_BE8)
Kyle McMartin d6a7761
 	fprintf (file, _(" [BE8]"));
Kyle McMartin d6a7761
@@ -14417,6 +14426,16 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT
Kyle McMartin d6a7761
       if (globals != NULL && globals->byteswap_code)
Kyle McMartin d6a7761
 	i_ehdrp->e_flags |= EF_ARM_BE8;
Kyle McMartin d6a7761
     }
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
+  if (EF_ARM_EABI_VERSION (i_ehdrp->e_flags) == EF_ARM_EABI_VER5
Kyle McMartin d6a7761
+      && ((i_ehdrp->e_type == ET_DYN) || (i_ehdrp->e_type == ET_EXEC)))
Kyle McMartin d6a7761
+    {
Kyle McMartin d6a7761
+      int abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_ABI_VFP_args);
Kyle McMartin d6a7761
+      if (abi)
Kyle McMartin d6a7761
+	i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_HARD;
Kyle McMartin d6a7761
+      else
Kyle McMartin d6a7761
+	i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_SOFT;
Kyle McMartin d6a7761
+    }
Kyle McMartin d6a7761
 }
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
 static enum elf_reloc_type_class
Kyle McMartin d6a7761
--- a/binutils/readelf.c
Kyle McMartin d6a7761
+++ b/binutils/readelf.c
Kyle McMartin d6a7761
@@ -2122,11 +2134,34 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[])
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
     case EF_ARM_EABI_VER4:
Kyle McMartin d6a7761
       strcat (buf, ", Version4 EABI");
Kyle McMartin d6a7761
-      goto eabi;
Kyle McMartin d6a7761
+      while (e_flags)
Kyle McMartin d6a7761
+	{
Kyle McMartin d6a7761
+	  unsigned flag;
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
+	  /* Process flags one bit at a time.  */
Kyle McMartin d6a7761
+	  flag = e_flags & - e_flags;
Kyle McMartin d6a7761
+	  e_flags &= ~ flag;
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
+	  switch (flag)
Kyle McMartin d6a7761
+	    {
Kyle McMartin d6a7761
+	    case EF_ARM_BE8:
Kyle McMartin d6a7761
+	      strcat (buf, ", BE8");
Kyle McMartin d6a7761
+	      break;
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
+	    case EF_ARM_LE8:
Kyle McMartin d6a7761
+	      strcat (buf, ", LE8");
Kyle McMartin d6a7761
+	      break;
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
+	    default:
Kyle McMartin d6a7761
+	      unknown = 1;
Kyle McMartin d6a7761
+	      break;
Kyle McMartin d6a7761
+	    }
Kyle McMartin d6a7761
+      break;
Kyle McMartin d6a7761
+	}
Kyle McMartin d6a7761
+      break;
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
     case EF_ARM_EABI_VER5:
Kyle McMartin d6a7761
       strcat (buf, ", Version5 EABI");
Kyle McMartin d6a7761
-    eabi:
Kyle McMartin d6a7761
       while (e_flags)
Kyle McMartin d6a7761
 	{
Kyle McMartin d6a7761
 	  unsigned flag;
Kyle McMartin d6a7761
@@ -2145,6 +2180,14 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[])
Kyle McMartin d6a7761
 	      strcat (buf, ", LE8");
Kyle McMartin d6a7761
 	      break;
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
+	    case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT.  */
Kyle McMartin d6a7761
+	      strcat (buf, ", soft-float ABI");
Kyle McMartin d6a7761
+	      break;
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
+	    case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT.  */
Kyle McMartin d6a7761
+	      strcat (buf, ", hard-float ABI");
Kyle McMartin d6a7761
+	      break;
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
 	    default:
Kyle McMartin d6a7761
 	      unknown = 1;
Kyle McMartin d6a7761
 	      break;
Kyle McMartin d6a7761
diff --git a/elfcpp/arm.h b/elfcpp/arm.h
Kyle McMartin d6a7761
index cb85eeb..ab0618a 100644
Kyle McMartin d6a7761
--- a/elfcpp/arm.h
Kyle McMartin d6a7761
+++ b/elfcpp/arm.h
Kyle McMartin d6a7761
@@ -1,6 +1,6 @@
Kyle McMartin d6a7761
 // arm.h -- ELF definitions specific to EM_ARM  -*- C++ -*-
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
-// Copyright 2009, Free Software Foundation, Inc.
Kyle McMartin d6a7761
+// Copyright 2009, 2012 Free Software Foundation, Inc.
Kyle McMartin d6a7761
 // Written by Doug Kwan <dougkwan@google.com>.
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
 // This file is part of elfcpp.
Kyle McMartin d6a7761
@@ -222,6 +222,14 @@ inline Elf_Word
Kyle McMartin d6a7761
 arm_eabi_version(Elf_Word flags)
Kyle McMartin d6a7761
 { return flags & EF_ARM_EABIMASK; }
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
+// EABI_VER5 e_flags values for identifying soft- and hard-float ABI
Kyle McMartin d6a7761
+// choice.
Kyle McMartin d6a7761
+enum
Kyle McMartin d6a7761
+{
Kyle McMartin d6a7761
+  EF_ARM_ABI_FLOAT_SOFT = 0x200,
Kyle McMartin d6a7761
+  EF_ARM_ABI_FLOAT_HARD = 0x400,
Kyle McMartin d6a7761
+};
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
 // Values for the Tag_CPU_arch EABI attribute.
Kyle McMartin d6a7761
 enum
Kyle McMartin d6a7761
 {
Kyle McMartin d6a7761
diff --git a/gold/arm.cc b/gold/arm.cc
Kyle McMartin d6a7761
index d847126..5770c8a 100644
Kyle McMartin d6a7761
--- a/gold/arm.cc
Kyle McMartin d6a7761
+++ b/gold/arm.cc
Kyle McMartin d6a7761
@@ -2476,7 +2476,7 @@ class Target_arm : public Sized_target<32, big_endian>
Kyle McMartin d6a7761
   { return new Arm_output_section<big_endian>(name, type, flags); }
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
   void
Kyle McMartin d6a7761
-  do_adjust_elf_header(unsigned char* view, int len) const;
Kyle McMartin d6a7761
+  do_adjust_elf_header(unsigned char* view, int len);
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
   // We only need to generate stubs, and hence perform relaxation if we are
Kyle McMartin d6a7761
   // not doing relocatable linking.
Kyle McMartin d6a7761
@@ -10016,15 +10016,16 @@ template<bool big_endian>
Kyle McMartin d6a7761
 void
Kyle McMartin d6a7761
 Target_arm<big_endian>::do_adjust_elf_header(
Kyle McMartin d6a7761
     unsigned char* view,
Kyle McMartin d6a7761
-    int len) const
Kyle McMartin d6a7761
+    int len)
Kyle McMartin d6a7761
 {
Kyle McMartin d6a7761
   gold_assert(len == elfcpp::Elf_sizes<32>::ehdr_size);
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
   elfcpp::Ehdr<32, big_endian> ehdr(view);
Kyle McMartin d6a7761
+  elfcpp::Elf_Word flags = this->processor_specific_flags();
Kyle McMartin d6a7761
   unsigned char e_ident[elfcpp::EI_NIDENT];
Kyle McMartin d6a7761
   memcpy(e_ident, ehdr.get_e_ident(), elfcpp::EI_NIDENT);
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
-  if (elfcpp::arm_eabi_version(this->processor_specific_flags())
Kyle McMartin d6a7761
+  if (elfcpp::arm_eabi_version(flags)
Kyle McMartin d6a7761
       == elfcpp::EF_ARM_EABI_UNKNOWN)
Kyle McMartin d6a7761
     e_ident[elfcpp::EI_OSABI] = elfcpp::ELFOSABI_ARM;
Kyle McMartin d6a7761
   else
Kyle McMartin d6a7761
@@ -10033,6 +10034,21 @@ Target_arm<big_endian>::do_adjust_elf_header(
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
   // FIXME: Do EF_ARM_BE8 adjustment.
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
+  // If we're working in EABI_VER5, set the hard/soft float ABI flags
Kyle McMartin d6a7761
+  // as appropriate.
Kyle McMartin d6a7761
+  if (elfcpp::arm_eabi_version(flags) == elfcpp::EF_ARM_EABI_VER5)
Kyle McMartin d6a7761
+  {
Kyle McMartin d6a7761
+    elfcpp::Elf_Half type = ehdr.get_e_type();
Kyle McMartin d6a7761
+    if (type == elfcpp::ET_EXEC || type == elfcpp::ET_DYN)
Kyle McMartin d6a7761
+      {
Kyle McMartin d6a7761
+	Object_attribute* attr = this->get_aeabi_object_attribute(elfcpp::Tag_ABI_VFP_args);
Kyle McMartin d6a7761
+	if (attr->int_value())
Kyle McMartin d6a7761
+	  flags |= elfcpp::EF_ARM_ABI_FLOAT_HARD;
Kyle McMartin d6a7761
+	else
Kyle McMartin d6a7761
+	  flags |= elfcpp::EF_ARM_ABI_FLOAT_SOFT;
Kyle McMartin d6a7761
+	this->set_processor_specific_flags(flags);
Kyle McMartin d6a7761
+      }
Kyle McMartin d6a7761
+  }
Kyle McMartin d6a7761
   elfcpp::Ehdr_write<32, big_endian> oehdr(view);
Kyle McMartin d6a7761
   oehdr.put_e_ident(e_ident);
Kyle McMartin d6a7761
 }
Kyle McMartin d6a7761
diff --git a/include/elf/arm.h b/include/elf/arm.h
Kyle McMartin d6a7761
index 8ea3fe8..d799303 100644
Kyle McMartin d6a7761
--- a/include/elf/arm.h
Kyle McMartin d6a7761
+++ b/include/elf/arm.h
Kyle McMartin d6a7761
@@ -46,6 +46,11 @@
Kyle McMartin d6a7761
 #define EF_ARM_MAPSYMSFIRST 0x10	/* NB conflicts with EF_APCS_FLOAT.  */
Kyle McMartin d6a7761
 #define EF_ARM_EABIMASK      0xFF000000
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
+/* New constants defined in the ARM ELF spec. version XXX.
Kyle McMartin d6a7761
+   Only valid in conjunction with EF_ARM_EABI_VER5. */
Kyle McMartin d6a7761
+#define EF_ARM_ABI_FLOAT_SOFT 0x200	/* NB conflicts with EF_ARM_SOFT_FLOAT.  */
Kyle McMartin d6a7761
+#define EF_ARM_ABI_FLOAT_HARD 0x400	/* NB conflicts with EF_ARM_VFP_FLOAT.  */
Kyle McMartin d6a7761
+
Kyle McMartin d6a7761
 /* Constants defined in AAELF.  */
Kyle McMartin d6a7761
 #define EF_ARM_BE8	    0x00800000
Kyle McMartin d6a7761
 #define EF_ARM_LE8	    0x00400000
Kyle McMartin d6a7761
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
Kyle McMartin d6a7761
index 8e15ffe..81ee0bd 100644
Kyle McMartin d6a7761
--- a/ld/testsuite/ld-arm/arm-elf.exp
Kyle McMartin d6a7761
+++ b/ld/testsuite/ld-arm/arm-elf.exp
Kyle McMartin d6a7761
@@ -271,6 +271,21 @@ set armelftests_common {
Kyle McMartin d6a7761
     {"Simple non-PIC shared library (no PLT check)" "-shared" "" {arm-lib.s}
Kyle McMartin d6a7761
      {{objdump -Rw arm-lib.r}}
Kyle McMartin d6a7761
      "arm-lib.so"}
Kyle McMartin d6a7761
+    {"EABI soft-float ET_EXEC ABI flag" "-T arm.ld" "-mfloat-abi=soft -meabi=5" {eabi-soft-float.s}
Kyle McMartin d6a7761
+     {{readelf -h eabi-soft-float.d}}
Kyle McMartin d6a7761
+     "eabi-soft-float"}
Kyle McMartin d6a7761
+    {"EABI hard-float ET_EXEC ABI flag" "-T arm.ld" "-mfloat-abi=hard -meabi=5" {eabi-hard-float.s}
Kyle McMartin d6a7761
+     {{readelf -h eabi-hard-float.d}}
Kyle McMartin d6a7761
+     "eabi-hard-float"}
Kyle McMartin d6a7761
+    {"EABI hard-float ET_DYN ABI flag" "-shared" "-mfloat-abi=hard -meabi=5" {eabi-hard-float.s}
Kyle McMartin d6a7761
+     {{readelf -h eabi-hard-float.d}}
Kyle McMartin d6a7761
+     "eabi-hard-float.so"}
Kyle McMartin d6a7761
+    {"EABI ABI flags wrong ABI version" "-T arm.ld" "-mfloat-abi=soft -meabi=4" {eabi-soft-float.s}
Kyle McMartin d6a7761
+     {{readelf -h eabi-soft-float-ABI4.d}}
Kyle McMartin d6a7761
+     "eabi-soft-float-no-flags"}
Kyle McMartin d6a7761
+    {"EABI ABI flags ld -r" "-r" "-mfloat-abi=soft -meabi=5" {eabi-soft-float.s}
Kyle McMartin d6a7761
+     {{readelf -h eabi-soft-float-r.d}}
Kyle McMartin d6a7761
+     "eabi-soft-float-r.o"}
Kyle McMartin d6a7761
 }
Kyle McMartin d6a7761
 
Kyle McMartin d6a7761
 set armelftests_nonacl {