系統 - Debian - 解決BFD_ASSERT (out_attr[Tag_ABI_HardFP_use].i == 0) assert failed elf32-arm.c問題



參考資訊:
https://github.com/OlegGirko/binutils/blob/master/0001-Fix-newer-binutils-not-to-assert-on-non-existence-tag_FP_arch.patch

問題如下:

BFD_ASSERT (in_attr[Tag_ABI_HardFP_use].i == 0) " assert failed elf32-arm.c
BFD_ASSERT (out_attr[Tag_ABI_HardFP_use].i == 0) " assert failed elf32-arm.c

解法如下:

diff --git a/binutils-2.21/bfd/elf-attrs.c b/binutils-2.21/bfd/elf-attrs.c
index e1893d3..01a1180 100644
--- a/binutils-2.21/bfd/elf-attrs.c
+++ b/binutils-2.21/bfd/elf-attrs.c
@@ -297,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);
-  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag) | ATTR_TYPE_FLAG_EXIST;
   attr->i = i;
 }
 
@@ -320,7 +320,7 @@ 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);
-  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag) | ATTR_TYPE_FLAG_EXIST;
   attr->s = _bfd_elf_attr_strdup (abfd, s);
 }
 
@@ -332,7 +332,7 @@ bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, int tag,
   obj_attribute *attr;
 
   attr = elf_new_obj_attr (abfd, vendor, tag);
-  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag) | ATTR_TYPE_FLAG_EXIST;
   attr->i = i;
   attr->s = _bfd_elf_attr_strdup (abfd, s);
 }
diff --git a/binutils-2.21/bfd/elf-bfd.h b/binutils-2.21/bfd/elf-bfd.h
index 2e607f8..3338ea7 100644
--- a/binutils-2.21/bfd/elf-bfd.h
+++ b/binutils-2.21/bfd/elf-bfd.h
@@ -1430,17 +1430,20 @@ struct bfd_elf_section_data
 
 /* The value of an object attribute.  The type indicates whether the attribute
    holds and integer, a string, or both.  It can also indicate that there can
-   be no default (i.e. all values must be written to file, even zero).  */
+   be no default (i.e. all values must be written to file, even zero), and whether
+   it exists in bfd to begin with. */
 
 typedef struct obj_attribute
 {
 #define ATTR_TYPE_FLAG_INT_VAL    (1 << 0)
 #define ATTR_TYPE_FLAG_STR_VAL    (1 << 1)
 #define ATTR_TYPE_FLAG_NO_DEFAULT (1 << 2)
+#define ATTR_TYPE_FLAG_EXIST      (1 << 3)
 
 #define ATTR_TYPE_HAS_INT_VAL(TYPE)  ((TYPE) & ATTR_TYPE_FLAG_INT_VAL)
 #define ATTR_TYPE_HAS_STR_VAL(TYPE)  ((TYPE) & ATTR_TYPE_FLAG_STR_VAL)
 #define ATTR_TYPE_HAS_NO_DEFAULT(TYPE)  ((TYPE) & ATTR_TYPE_FLAG_NO_DEFAULT)
+#define ATTR_TYPE_EXIST(TYPE)          ((TYPE) & ATTR_TYPE_FLAG_EXIST)
 
   int type;
   unsigned int i;
diff --git a/binutils-2.21/bfd/elf32-arm.c b/binutils-2.21/bfd/elf32-arm.c
index ee920b7..e865d52 100644
--- a/binutils-2.21/bfd/elf32-arm.c
+++ b/binutils-2.21/bfd/elf32-arm.c
@@ -10197,7 +10197,9 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
      nothing.  */
         else if (in_attr[i].i == 0)
     {
-      BFD_ASSERT (in_attr[Tag_ABI_HardFP_use].i == 0);
+           /* When linking against earlier version of object file, Tag_FP_arch may not
+              even exist, while Tag_ABI_HardFP_use is non-zero. */
+      BFD_ASSERT (!ATTR_TYPE_EXIST(in_attr[i].type) || in_attr[Tag_ABI_HardFP_use].i == 0);
       break;
     }