[GOLD][PATCH] Handle new EABI attributes

Doug Kwan (關振德) dougkwan@google.com
Wed May 12 17:01:00 GMT 2010


Hi,

This is a port of a BFD/LD patch

http://sourceware.org/ml/binutils-cvs/2010-02/msg00129.html

I need this because other tool components now use new attribute tags.
The test suite would fail for ARM without this because gold currently
does not handle the new attributes.  This is tested on both x86_64 and
ARM.

-Doug

2010-05-12  Doug Kwan  <dougkwan@google.com>

elfcpp/ChangeLog

        * arm.h (Tag_FP_arch, Tag_ABI_align_needed, Tag_ABI_align_preserved,
        Tag_FP_HP_extension, Tag_MPextension_use_legacy): Rename from
        existing tags.
        (Tag_undefined40, Tag_undefined41, Tag_MPextension_use,
        Tag_undefined43): New tags.
        (Targ_VFP_arch, Tag_ABI_align8_needed, TAG_ABI_align8_preserved,
        Tag_VFP_HP_extension): Define aliases for backward compatiblity.

gold/ChangeLog

        * arm.cc (Target_arm::do_finalize_sections): Create an empty
        attributes section only if there no attributes section after merging.
        (Target_arm::merge_object_attributes): Move value of
        Tag_MPextension_use_legacy to that of Tag_MPextension_use.
        Handle Tag_DIV_use and Tag_MPextension_use_legacy.
        * testsuite/Makefile.am (check_SCRIPTS): Add arm_attr_merge.sh
        (check_DATA): Add arm_attr_merge_6.stdout, arm_attr_merge_6r_stdout
        and arm_attr_merge_7.stdout.
        (arm_attr_merge_6.stdout, arm_attr_merge_6 arm_attr_merge_6a.o
        arm_attr_merge_6b.o, arm_attr_merge_6r.stdout, arm_attr_merge_6r,
        arm_attr_merge_7.stdout, arm_attr_merge_7, arm_attr_merge_7a.o,
        arm_attr_merge_7b.o): New rules.
        (MOSTLYCLEANFILES): Add arm_attr_merge_6, arm_attr_merge_6r and
        arm_attr_merge_7
        * testsuite/Makefile.in: Regenerate.
        * testsuite/arm_attr_merge.sh: New file.
-------------- next part --------------
? gold/autom4te.cache
Index: elfcpp/arm.h
===================================================================
RCS file: /cvs/src/src/elfcpp/arm.h,v
retrieving revision 1.5
diff -u -u -p -r1.5 arm.h
--- elfcpp/arm.h	22 Jan 2010 06:06:45 -0000	1.5
+++ elfcpp/arm.h	12 May 2010 07:52:00 -0000
@@ -255,7 +255,7 @@ enum
   Tag_CPU_arch_profile = 7,
   Tag_ARM_ISA_use = 8,
   Tag_THUMB_ISA_use = 9,
-  Tag_VFP_arch = 10,
+  Tag_FP_arch = 10,
   Tag_WMMX_arch = 11,
   Tag_Advanced_SIMD_arch = 12,
   Tag_PCS_config = 13,
@@ -269,8 +269,8 @@ enum
   Tag_ABI_FP_exceptions = 21,
   Tag_ABI_FP_user_exceptions = 22,
   Tag_ABI_FP_number_model = 23,
-  Tag_ABI_align8_needed = 24,
-  Tag_ABI_align8_preserved = 25,
+  Tag_ABI_align_needed = 24,
+  Tag_ABI_align_preserved = 25,
   Tag_ABI_enum_size = 26,
   Tag_ABI_HardFP_use = 27,
   Tag_ABI_VFP_args = 28,
@@ -281,17 +281,28 @@ enum
   Tag_undefined33 = 33,
   Tag_CPU_unaligned_access = 34,
   Tag_undefined35 = 35,
-  Tag_VFP_HP_extension = 36,
+  Tag_FP_HP_extension = 36,
   Tag_undefined37 = 37,
   Tag_ABI_FP_16bit_format = 38,
   Tag_undefined39 = 39,
+  Tag_undefined40 = 40,
+  Tag_undefined41 = 41,
+  Tag_MPextension_use = 42,
+  Tag_undefined43 = 43,
+  Tag_DIV_use = 44,
   Tag_nodefaults = 64,
   Tag_also_compatible_with = 65,
   Tag_T2EE_use = 66,
   Tag_conformance = 67,
   Tag_Virtualization_use = 68,
   Tag_undefined69 = 69,
-  Tag_MPextension_use = 70
+  Tag_MPextension_use_legacy = 70,
+
+  // The following tags are legacy names for other tags.
+  Tag_VFP_arch = Tag_FP_arch,
+  Tag_ABI_align8_needed = Tag_ABI_align_needed,
+  Tag_ABI_align8_preserved = Tag_ABI_align_preserved,
+  Tag_VFP_HP_extension = Tag_FP_HP_extension
 };
 
 // Values for Tag_ABI_PCS_R9_use.
Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.101
diff -u -u -p -r1.101 arm.cc
--- gold/arm.cc	21 Apr 2010 16:32:28 -0000	1.101
+++ gold/arm.cc	12 May 2010 07:52:04 -0000
@@ -7998,11 +7998,6 @@ Target_arm<big_endian>::do_finalize_sect
     const Input_objects* input_objects,
     Symbol_table* symtab)
 {
-  // Create an empty uninitialized attribute section if we still don't have it
-  // at this moment.
-  if (this->attributes_section_data_ == NULL)
-    this->attributes_section_data_ = new Attributes_section_data(NULL, 0);
-
   // Merge processor-specific flags.
   for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
        p != input_objects->relobj_end();
@@ -8033,6 +8028,12 @@ Target_arm<big_endian>::do_finalize_sect
 				    arm_dynobj->attributes_section_data());
     }
 
+  // Create an empty uninitialized attribute section if we still don't have it
+  // at this moment.  This happens if there is no attributes sections in all
+  // inputs.
+  if (this->attributes_section_data_ == NULL)
+    this->attributes_section_data_ = new Attributes_section_data(NULL, 0);
+
   // Check BLX use.
   const Object_attribute* cpu_arch_attr =
     this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
@@ -9427,13 +9428,35 @@ Target_arm<big_endian>::merge_object_att
     return;
 
   // If output has no object attributes, just copy.
+  const int vendor = Object_attribute::OBJ_ATTR_PROC;
   if (this->attributes_section_data_ == NULL)
     {
       this->attributes_section_data_ = new Attributes_section_data(*pasd);
+      Object_attribute* out_attr =
+	this->attributes_section_data_->known_attributes(vendor);
+
+      // We do not output objects with Tag_MPextension_use_legacy - we move
+      //  the attribute's value to Tag_MPextension_use.  */
+      if (out_attr[elfcpp::Tag_MPextension_use_legacy].int_value() != 0)
+	{
+	  if (out_attr[elfcpp::Tag_MPextension_use].int_value() != 0
+	      && out_attr[elfcpp::Tag_MPextension_use_legacy].int_value()
+	        != out_attr[elfcpp::Tag_MPextension_use].int_value())
+	    {
+	      gold_error(_("%s has both the current and legacy "
+			   "Tag_MPextension_use attributes"),
+			 name);
+	    }
+
+	  out_attr[elfcpp::Tag_MPextension_use] =
+	    out_attr[elfcpp::Tag_MPextension_use_legacy];
+	  out_attr[elfcpp::Tag_MPextension_use_legacy].set_type(0);
+	  out_attr[elfcpp::Tag_MPextension_use_legacy].set_int_value(0);
+	}
+
       return;
     }
 
-  const int vendor = Object_attribute::OBJ_ATTR_PROC;
   const Object_attribute* in_attr = pasd->known_attributes(vendor);
   Object_attribute* out_attr =
     this->attributes_section_data_->known_attributes(vendor);
@@ -9759,6 +9782,51 @@ Target_arm<big_endian>::merge_object_att
 	    out_attr[i].set_int_value(in_attr[i].int_value());
 	  break;
 
+	case elfcpp::Tag_DIV_use:
+	  // This tag is set to zero if we can use UDIV and SDIV in Thumb
+	  // mode on a v7-M or v7-R CPU; to one if we can not use UDIV or
+	  // SDIV at all; and to two if we can use UDIV or SDIV on a v7-A
+	  // CPU.  We will merge as follows: If the input attribute's value
+	  // is one then the output attribute's value remains unchanged.  If
+	  // the input attribute's value is zero or two then if the output
+	  // attribute's value is one the output value is set to the input
+	  // value, otherwise the output value must be the same as the
+	  // inputs.  */ 
+	  if (in_attr[i].int_value() != 1 && out_attr[i].int_value() != 1) 
+	    { 
+	      if (in_attr[i].int_value() != out_attr[i].int_value())
+		{
+		  gold_error(_("DIV usage mismatch between %s and output"),
+			     name);
+		}
+	    } 
+
+	  if (in_attr[i].int_value() != 1)
+	    out_attr[i].set_int_value(in_attr[i].int_value()); 
+	  
+	  break;
+
+	case elfcpp::Tag_MPextension_use_legacy:
+	  // We don't output objects with Tag_MPextension_use_legacy - we
+	  // move the value to Tag_MPextension_use.
+	  if (in_attr[i].int_value() != 0
+	      && in_attr[elfcpp::Tag_MPextension_use].int_value() != 0)
+	    {
+	      if (in_attr[elfcpp::Tag_MPextension_use].int_value()
+		  != in_attr[i].int_value())
+		{
+		  gold_error(_("%s has has both the current and legacy "
+			       "Tag_MPextension_use attributes"), 
+			     name);
+		}
+	    }
+
+	  if (in_attr[i].int_value()
+	      > out_attr[elfcpp::Tag_MPextension_use].int_value())
+	    out_attr[elfcpp::Tag_MPextension_use] = in_attr[i];
+
+	  break;
+
 	case elfcpp::Tag_nodefaults:
 	  // This tag is set if it exists, but the value is unused (and is
 	  // typically zero).  We don't actually need to do anything here -
Index: gold/testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.132
diff -u -u -p -r1.132 Makefile.am
--- gold/testsuite/Makefile.am	23 Apr 2010 18:49:23 -0000	1.132
+++ gold/testsuite/Makefile.am	12 May 2010 07:52:04 -0000
@@ -1666,4 +1666,40 @@ arm_no_fix_v4bx: arm_fix_v4bx.o ../ld-ne
 
 MOSTLYCLEANFILES += arm_fix_v4bx arm_fix_v4bx_interworking arm_no_fix_v4bx
 
+check_SCRIPTS += arm_attr_merge.sh
+check_DATA += arm_attr_merge_6.stdout arm_attr_merge_6r.stdout \
+	arm_attr_merge_7.stdout
+
+arm_attr_merge_6.stdout: arm_attr_merge_6
+	$(TEST_READELF) -A $< > $@
+
+arm_attr_merge_6: arm_attr_merge_6a.o arm_attr_merge_6b.o
+	../ld-new -o $@ arm_attr_merge_6a.o arm_attr_merge_6b.o
+
+arm_attr_merge_6a.o: arm_attr_merge_6a.s
+	$(TEST_AS) -o $@ $<
+
+arm_attr_merge_6b.o: arm_attr_merge_6b.s
+	$(TEST_AS) -o $@ $<
+
+arm_attr_merge_6r.stdout: arm_attr_merge_6r
+	$(TEST_READELF) -A $< > $@
+
+arm_attr_merge_6r: arm_attr_merge_6b.o arm_attr_merge_6a.o
+	../ld-new -o $@ arm_attr_merge_6b.o arm_attr_merge_6a.o
+
+arm_attr_merge_7.stdout: arm_attr_merge_7
+	$(TEST_READELF) -A $< > $@
+
+arm_attr_merge_7: arm_attr_merge_7a.o arm_attr_merge_7b.o
+	../ld-new -o $@ arm_attr_merge_7a.o arm_attr_merge_7b.o
+
+arm_attr_merge_7a.o: arm_attr_merge_7a.s
+	$(TEST_AS) -o $@ $<
+
+arm_attr_merge_7b.o: arm_attr_merge_7b.s
+	$(TEST_AS) -o $@ $<
+
+MOSTLYCLEANFILES += arm_attr_merge_6 arm_attr_merge_6r arm_attr_merge_7
+
 endif DEFAULT_TARGET_ARM
Index: gold/testsuite/Makefile.in
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.in,v
retrieving revision 1.139
diff -u -u -p -r1.139 Makefile.in
--- gold/testsuite/Makefile.in	23 Apr 2010 18:49:23 -0000	1.139
+++ gold/testsuite/Makefile.in	12 May 2010 07:52:05 -0000
@@ -344,7 +344,7 @@ check_PROGRAMS = object_unittest$(EXEEXT
 
 @DEFAULT_TARGET_ARM_TRUE@am__append_38 = arm_abs_global.sh \
 @DEFAULT_TARGET_ARM_TRUE@	arm_branch_in_range.sh \
-@DEFAULT_TARGET_ARM_TRUE@	arm_fix_v4bx.sh
+@DEFAULT_TARGET_ARM_TRUE@	arm_fix_v4bx.sh arm_attr_merge.sh
 @DEFAULT_TARGET_ARM_TRUE@am__append_39 = arm_abs_global.stdout \
 @DEFAULT_TARGET_ARM_TRUE@	arm_bl_in_range.stdout \
 @DEFAULT_TARGET_ARM_TRUE@	arm_bl_out_of_range.stdout \
@@ -358,7 +358,10 @@ check_PROGRAMS = object_unittest$(EXEEXT
 @DEFAULT_TARGET_ARM_TRUE@	thumb2_blx_out_of_range.stdout \
 @DEFAULT_TARGET_ARM_TRUE@	arm_fix_v4bx.stdout \
 @DEFAULT_TARGET_ARM_TRUE@	arm_fix_v4bx_interworking.stdout \
-@DEFAULT_TARGET_ARM_TRUE@	arm_no_fix_v4bx.stdout
+@DEFAULT_TARGET_ARM_TRUE@	arm_no_fix_v4bx.stdout \
+@DEFAULT_TARGET_ARM_TRUE@	arm_attr_merge_6.stdout \
+@DEFAULT_TARGET_ARM_TRUE@	arm_attr_merge_6r.stdout \
+@DEFAULT_TARGET_ARM_TRUE@	arm_attr_merge_7.stdout
 @DEFAULT_TARGET_ARM_TRUE@am__append_40 = arm_abs_global \
 @DEFAULT_TARGET_ARM_TRUE@	arm_bl_in_range arm_bl_out_of_range \
 @DEFAULT_TARGET_ARM_TRUE@	thumb_bl_in_range \
@@ -370,7 +373,8 @@ check_PROGRAMS = object_unittest$(EXEEXT
 @DEFAULT_TARGET_ARM_TRUE@	thumb2_blx_in_range \
 @DEFAULT_TARGET_ARM_TRUE@	thumb2_blx_out_of_range arm_fix_v4bx \
 @DEFAULT_TARGET_ARM_TRUE@	arm_fix_v4bx_interworking \
-@DEFAULT_TARGET_ARM_TRUE@	arm_no_fix_v4bx
+@DEFAULT_TARGET_ARM_TRUE@	arm_no_fix_v4bx arm_attr_merge_6 \
+@DEFAULT_TARGET_ARM_TRUE@	arm_attr_merge_6r arm_attr_merge_7
 subdir = testsuite
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -1244,7 +1248,9 @@ host_vendor = @host_vendor@
 htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
+install_as_default = @install_as_default@
 install_sh = @install_sh@
+installed_linker = @installed_linker@
 libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
@@ -3284,6 +3290,36 @@ uninstall-am:
 @DEFAULT_TARGET_ARM_TRUE@arm_no_fix_v4bx: arm_fix_v4bx.o ../ld-new
 @DEFAULT_TARGET_ARM_TRUE@	../ld-new -o $@ $<
 
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_6.stdout: arm_attr_merge_6
+@DEFAULT_TARGET_ARM_TRUE@	$(TEST_READELF) -A $< > $@
+
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_6: arm_attr_merge_6a.o arm_attr_merge_6b.o
+@DEFAULT_TARGET_ARM_TRUE@	../ld-new -o $@ arm_attr_merge_6a.o arm_attr_merge_6b.o
+
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_6a.o: arm_attr_merge_6a.s
+@DEFAULT_TARGET_ARM_TRUE@	$(TEST_AS) -o $@ $<
+
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_6b.o: arm_attr_merge_6b.s
+@DEFAULT_TARGET_ARM_TRUE@	$(TEST_AS) -o $@ $<
+
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_6r.stdout: arm_attr_merge_6r
+@DEFAULT_TARGET_ARM_TRUE@	$(TEST_READELF) -A $< > $@
+
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_6r: arm_attr_merge_6b.o arm_attr_merge_6a.o
+@DEFAULT_TARGET_ARM_TRUE@	../ld-new -o $@ arm_attr_merge_6b.o arm_attr_merge_6a.o
+
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_7.stdout: arm_attr_merge_7
+@DEFAULT_TARGET_ARM_TRUE@	$(TEST_READELF) -A $< > $@
+
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_7: arm_attr_merge_7a.o arm_attr_merge_7b.o
+@DEFAULT_TARGET_ARM_TRUE@	../ld-new -o $@ arm_attr_merge_7a.o arm_attr_merge_7b.o
+
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_7a.o: arm_attr_merge_7a.s
+@DEFAULT_TARGET_ARM_TRUE@	$(TEST_AS) -o $@ $<
+
+@DEFAULT_TARGET_ARM_TRUE@arm_attr_merge_7b.o: arm_attr_merge_7b.s
+@DEFAULT_TARGET_ARM_TRUE@	$(TEST_AS) -o $@ $<
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
Index: gold/testsuite/arm_attr_merge.sh
===================================================================
RCS file: gold/testsuite/arm_attr_merge.sh
diff -N gold/testsuite/arm_attr_merge.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_attr_merge.sh	12 May 2010 07:52:05 -0000
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# arm_attr_merge.sh -- test ARM attributes merging.
+
+# Copyright 2010 Free Software Foundation, Inc.
+# Written by Doug Kwan <dougkwan@google.com>
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# This file goes with the assembler source files arm_attr_merge*.s
+
+check()
+{
+    file=$1
+    pattern=$2
+    found=`grep "$pattern" $file`
+    if test -z "$found"; then
+	echo "pattern \"$pattern\" not found in file $file."
+	exit 1
+    fi
+}
+
+# This is a bit crude.
+
+check arm_attr_merge_6.stdout "Tag_MPextension_use: Allowed"
+check arm_attr_merge_6r.stdout "Tag_MPextension_use: Allowed"
+check arm_attr_merge_7.stdout  "Tag_MPextension_use: Allowed"
+
+exit 0
Index: gold/testsuite/arm_attr_merge_6a.s
===================================================================
RCS file: gold/testsuite/arm_attr_merge_6a.s
diff -N gold/testsuite/arm_attr_merge_6a.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_attr_merge_6a.s	12 May 2010 07:52:05 -0000
@@ -0,0 +1,4 @@
+	.cpu cortex-a9
+	.fpu softvfp
+	.eabi_attribute 70, 1
+	.file	"arm_attr_merge_6a.s"
Index: gold/testsuite/arm_attr_merge_6b.s
===================================================================
RCS file: gold/testsuite/arm_attr_merge_6b.s
diff -N gold/testsuite/arm_attr_merge_6b.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_attr_merge_6b.s	12 May 2010 07:52:05 -0000
@@ -0,0 +1,3 @@
+	.cpu cortex-a9
+	.fpu softvfp
+	.file	"arm_attr_merge_6b.s"
Index: gold/testsuite/arm_attr_merge_7a.s
===================================================================
RCS file: gold/testsuite/arm_attr_merge_7a.s
diff -N gold/testsuite/arm_attr_merge_7a.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_attr_merge_7a.s	12 May 2010 07:52:05 -0000
@@ -0,0 +1,4 @@
+	.cpu cortex-a9
+	.fpu softvfp
+	.eabi_attribute 70, 1
+	.file	"arm_attr_merge_7a.s"
Index: gold/testsuite/arm_attr_merge_7b.s
===================================================================
RCS file: gold/testsuite/arm_attr_merge_7b.s
diff -N gold/testsuite/arm_attr_merge_7b.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_attr_merge_7b.s	12 May 2010 07:52:05 -0000
@@ -0,0 +1,4 @@
+	.cpu cortex-a9
+	.fpu softvfp
+	.eabi_attribute Tag_MPextension_use, 1
+	.file	"arm_attr_merge_7b.s"


More information about the Binutils mailing list