ld compact eh-frame leak

Message ID Z5HlQHA-26o5QAfd@squeak.grove.modra.org
State New
Headers
Series ld compact eh-frame leak |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply

Commit Message

Alan Modra Jan. 23, 2025, 6:44 a.m. UTC
  u.compact.extries wasn't being freed anywhere.  Free it when
destroying the linker hash table.  Also free u.dwarf.aray there in
case errors result in the linker not getting to the slightly earlier
free in write_dwarf_eh_frame_hdr.

	* elf-eh-frame.c (write_dwarf_eh_frame_hdr): Don't exit without
	freeing u.dwarf.array.
	* elflink.c (_bfd_elf_link_hash_table_free): Free u.compact.entries
	and u.dwarf.array.
  

Patch

diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 08ffc5f1b4a..78b3ecb5a7d 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -2411,7 +2411,7 @@  write_dwarf_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
   struct elf_link_hash_table *htab;
   struct eh_frame_hdr_info *hdr_info;
   asection *sec;
-  bool retval = true;
+  bool retval = false;
 
   htab = elf_hash_table (info);
   hdr_info = &htab->eh_info;
@@ -2427,14 +2427,11 @@  write_dwarf_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
     size += 4 + hdr_info->u.dwarf.fde_count * 8;
   contents = (bfd_byte *) bfd_malloc (size);
   if (contents == NULL)
-    return false;
+    goto out;
 
   eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
   if (eh_frame_sec == NULL)
-    {
-      free (contents);
-      return false;
-    }
+    goto out;
 
   memset (contents, 0, EH_FRAME_HDR_SIZE);
   /* Version.  */
@@ -2458,6 +2455,7 @@  write_dwarf_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
     }
   bfd_put_32 (abfd, encoded_eh_frame, contents + 4);
 
+  retval = true;
   if (contents[2] != DW_EH_PE_omit)
     {
       unsigned int i;
@@ -2510,9 +2508,10 @@  write_dwarf_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
 				 (file_ptr) sec->output_offset,
 				 sec->size))
     retval = false;
+ out:
   free (contents);
-
   free (hdr_info->u.dwarf.array);
+  hdr_info->u.dwarf.array = NULL;
   return retval;
 }
 
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 27b02dd404f..309b4d75094 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -8383,6 +8383,10 @@  _bfd_elf_link_hash_table_free (bfd *obfd)
       bfd_hash_table_free (htab->first_hash);
       free (htab->first_hash);
     }
+  if (htab->eh_info.frame_hdr_is_compact)
+    free (htab->eh_info.u.compact.entries);
+  else
+    free (htab->eh_info.u.dwarf.array);
   _bfd_generic_link_hash_table_free (obfd);
 }