]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Object Attributes v2: clean up attributes data when freeing BFDs
authorMatthieu Longo <matthieu.longo@arm.com>
Fri, 30 Jan 2026 11:20:02 +0000 (11:20 +0000)
committerMatthieu Longo <matthieu.longo@arm.com>
Fri, 6 Feb 2026 10:41:54 +0000 (10:41 +0000)
Once attributes merge is complete, object attributes from input files
are no longer needed and can be safely released. The same applies to
object attributes associated to the output object. Ideally, a single
clean-up mechanism should handle both inputs and output cases. GNU ld
already provides such a mechanism via _bfd_elf_free_cached_info().

The previous patch series that introduced support for Object Attributes
v2 did not free any OAv2 data, resulting in leaks of all OAv2-related
resources.

This patch adds a new helper, _bfd_elf_cleanup_object_attributes, to
the OAv2 API to deallocate all OAv2 resources associated with a BFD.
The helper is invoked from _bfd_elf_free_cached_info().

The patch also fixes a logical error after the attributes merge, where
object attributes were copied from the accumulator into output_bfd. A
simple pointer copy is insufficient because ownership of the wrapper
must be fully swapped between the two BFDs to ensure resources are
deallocated correctly.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33858
Co-authored-by: Alan Modra <amodra@gmail.com>
bfd/elf-attrs.c
bfd/elf-bfd.h
bfd/elf.c

index 7160bd4d2843581a27f76df90b838dddc6556832..6c3cfc09677c7d79294f1a2c2455cc1379cfb8b3 100644 (file)
@@ -2194,10 +2194,11 @@ _bfd_elf_link_setup_object_attributes (struct bfd_link_info *info)
     return NULL;
   BFD_ASSERT (elf_obj_attr_subsections (res.pbfd).size > 0);
 
-
-  /* Shallow-copy the object attributes into output_bfd.  */
-  elf_obj_attr_subsections (info->output_bfd)
-    = elf_obj_attr_subsections (res.pbfd);
+  /* Swap the old object attributes stored in output_bfd (i.e. the frozen
+     config) with the final merge result.  */
+  LINKED_LIST_SWAP_LISTS (obj_attr_subsection_list_t)
+    (&elf_obj_attr_subsections (info->output_bfd),
+     &elf_obj_attr_subsections (res.pbfd));
 
   /* Note: the object attributes section in the output object is copied from
      the input object which was used for the merge (res.pbfd).  No need to
@@ -2953,6 +2954,16 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
   free (data);
 }
 
+/* Clean-up all the object attributes in a file.  */
+void
+_bfd_elf_cleanup_object_attributes (bfd *abfd)
+{
+  obj_attr_subsection_list_t *plist = &elf_obj_attr_subsections (abfd);
+  obj_attr_subsection_v2_t *subsec = plist->first;
+  while (subsec != NULL)
+    subsec = oav2_subsec_delete (plist, subsec);
+}
+
 /* Merge common object attributes from IBFD into OBFD.  Raise an error
    if there are conflicting attributes.  Any processor-specific
    attributes have already been merged.  This must be called from the
index dbf53756200f39cd82ea1f658066e5cb48b79adf..837fbefa6a2fceb2dba37ec9f6620cd48d71cae2 100644 (file)
@@ -3207,6 +3207,8 @@ extern int bfd_elf_obj_attrs_arg_type
   (bfd *, obj_attr_vendor_t, obj_attr_tag_t);
 extern void _bfd_elf_parse_attributes
   (bfd *, Elf_Internal_Shdr *) ATTRIBUTE_HIDDEN;
+extern void _bfd_elf_cleanup_object_attributes
+  (bfd *) ATTRIBUTE_HIDDEN;
 extern bfd *_bfd_elf_link_setup_object_attributes
   (struct bfd_link_info *) ATTRIBUTE_HIDDEN;
 extern bool _bfd_elf_merge_object_attributes
index 75a2e0b9358f1563fbc7a576555191e1a541c0e5..f7437f11fbde1a83f101e3e600158866f93c6a16 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -10207,6 +10207,7 @@ _bfd_elf_free_cached_info (bfd *abfd)
       _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
       _bfd_dwarf1_cleanup_debug_info (abfd, &tdata->dwarf1_find_line_info);
       _bfd_stab_cleanup (abfd, &tdata->line_info);
+      _bfd_elf_cleanup_object_attributes (abfd);
       for (asection *sec = abfd->sections; sec != NULL; sec = sec->next)
        {
          _bfd_elf_munmap_section_contents (sec, sec->contents);