[binutils-gdb] OAv2 merge: prune unsupported or invalid subsections and attributes

Matthieu Longo mlongo@sourceware.org
Thu Jan 22 10:13:26 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5bd6b379605d0f2fa428ba928a739db117719ed7

commit 5bd6b379605d0f2fa428ba928a739db117719ed7
Author: Matthieu Longo <matthieu.longo@arm.com>
Date:   Fri Nov 14 10:31:29 2025 +0000

    OAv2 merge: prune unsupported or invalid subsections and attributes
    
    During the merge, each subsection and attribute is assigned a status.
    If the status is OK, the item is retained and serialized into the
    output object. Otherwise, unsupported or invalid subsections and
    attributes are pruned before serialization.
    
    When a subsection or attribute is pruned, ld emits information-level
    messages to inform the user, preventing confusion about the absence
    of elements that were present in the input objects.

Diff:
---
 bfd/elf-attrs.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 72 insertions(+), 5 deletions(-)

diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c
index e1ca52a060c..010c6acaeb2 100644
--- a/bfd/elf-attrs.c
+++ b/bfd/elf-attrs.c
@@ -2033,14 +2033,81 @@ oav2_merge_all (const struct bfd_link_info *info,
   return success;
 }
 
+/* Prune the given attribute, and return the next one in the list.  */
+static obj_attr_v2_t *
+oav2_attr_delete (obj_attr_subsection_v2_t *subsec,
+		  obj_attr_v2_t *attr)
+{
+  obj_attr_v2_t *next = attr->next;
+  LINKED_LIST_REMOVE (obj_attr_v2_t) (subsec, attr);
+  _bfd_elf_obj_attr_v2_free (attr, subsec->encoding);
+  return next;
+}
+
+/* Prune the given subsection, and return the next one in the list.  */
+static obj_attr_subsection_v2_t *
+oav2_subsec_delete (obj_attr_subsection_list_t *plist,
+		    obj_attr_subsection_v2_t *subsec)
+{
+  obj_attr_subsection_v2_t *next = subsec->next;
+  LINKED_LIST_REMOVE (obj_attr_subsection_v2_t) (plist, subsec);
+  _bfd_elf_obj_attr_subsection_v2_free (subsec);
+  return next;
+}
+
+/* Prune any attributes with a status different from obj_attr_v2_ok in the
+   given subsection.  */
+static void
+oav2_attrs_prune_nok (const struct bfd_link_info *info,
+		      obj_attr_subsection_v2_t *subsec)
+{
+  const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
+  for (obj_attr_v2_t *attr = subsec->first;
+       attr != NULL;)
+    {
+      if (attr->status != obj_attr_v2_ok)
+	{
+	  const char *tag_s
+	    = _bfd_obj_attr_v2_tag_to_string (bed, subsec->name, attr->tag);
+	  info->callbacks->minfo
+	    (_("Removed attribute '%s' from '%s'\n"), tag_s, subsec->name);
+	  free ((char *) tag_s);
+	  attr = oav2_attr_delete (subsec, attr);
+	}
+      else
+	attr = attr->next;
+    }
+}
+
+/* Prune any subsection with a status different from obj_attr_subsection_v2_ok
+   in the given list of subsections.  */
+static void
+oav2_subsecs_prune_nok (const struct bfd_link_info *info,
+			obj_attr_subsection_list_t *plist)
+{
+  for (obj_attr_subsection_v2_t *subsec = plist->first;
+       subsec != NULL;)
+    {
+      if (subsec->status == obj_attr_subsection_v2_ok)
+	oav2_attrs_prune_nok (info, subsec);
+
+      if (subsec->size == 0 || subsec->status != obj_attr_subsection_v2_ok)
+	{
+	  info->callbacks->minfo (_("Removed subsection '%s'\n"), subsec->name);
+	  subsec = oav2_subsec_delete (plist, subsec);
+	}
+      else
+	subsec = subsec->next;
+    }
+}
+
 /* Prune any subsection or attribute with a status different from OK.  */
-static bfd *
+static bool
 oav2_prune_nok_attrs (const struct bfd_link_info *info, bfd *abfd)
 {
-  (void) info;
-  (void) abfd;
-  /* TO IMPLEMENT */
-  return NULL;
+  obj_attr_subsection_list_t *plist = &elf_obj_attr_subsections (abfd);
+  oav2_subsecs_prune_nok (info, plist);
+  return (plist->size != 0);
 }
 
 /* Set up object attributes coming from configuration, and merge them with the


More information about the Binutils-cvs mailing list