[binutils-gdb] ld compact eh-frame leak

Alan Modra amodra@sourceware.org
Thu Jan 23 06:46:57 GMT 2025


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

commit ee8f3b6c78e1df055184635aedfe0ac1333a6706
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Jan 23 10:23:48 2025 +1030

    ld compact eh-frame leak
    
    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.

Diff:
---
 bfd/elf-eh-frame.c | 13 ++++++-------
 bfd/elflink.c      |  4 ++++
 2 files changed, 10 insertions(+), 7 deletions(-)

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);
 }


More information about the Binutils-cvs mailing list