eh-frame memory leaks

Message ID Z4ej1dIzjEVL721H@squeak.grove.modra.org
State New
Headers
Series eh-frame memory leaks |

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. 15, 2025, 12:02 p.m. UTC
  The set_loc array attached to eh-frame sec_info isn't freed, and is
used in _bfd_elf_eh_frame_section_offset.  Rather than finding a
suitable late stage of linking past any b_e_e_f_s_o use, I decided
this might as well persist until the bfd is closed.
Some memory is freed in _bfd_elf_discard_section_eh_frame_hdr, but
the function isn't always called, so fix that too.

	* elf-eh-frame.c (_bfd_elf_parse_eh_frame): bfd_alloc the
	set_loc array.
	(find_merged_cie): Use bfd_malloc rather than malloc.
	(_bfd_elf_discard_section_eh_frame_hdr): Move condition under
	which this function does anything except free memory from..
	* elflink.c (bfd_elf_discard_info): ..here.
  

Patch

diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index b6f5078bb33..dd6802b05fd 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -1013,8 +1013,8 @@  _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
 	  unsigned int cnt;
 	  bfd_byte *p;
 
-	  this_inf->set_loc = (unsigned int *)
-	      bfd_malloc ((set_loc_count + 1) * sizeof (unsigned int));
+	  this_inf->set_loc
+	    = bfd_alloc (abfd, (set_loc_count + 1) * sizeof (unsigned int));
 	  REQUIRE (this_inf->set_loc);
 	  this_inf->set_loc[0] = set_loc_count;
 	  p = insns;
@@ -1307,7 +1307,7 @@  find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
   if (new_cie == NULL)
     {
       /* Keep CIE_INF and record it in the hash table.  */
-      new_cie = (struct cie *) malloc (sizeof (struct cie));
+      new_cie = bfd_malloc (sizeof (*new_cie));
       if (new_cie == NULL)
 	return cie_inf;
 
@@ -1628,6 +1628,10 @@  _bfd_elf_discard_section_eh_frame_hdr (struct bfd_link_info *info)
       hdr_info->u.dwarf.cies = NULL;
     }
 
+  if (info->eh_frame_hdr_type == 0
+      || bfd_link_relocatable (info))
+    return false;
+
   sec = hdr_info->hdr_sec;
   if (sec == NULL)
     return false;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 9b8c7357d0d..f20c9a1d04d 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -15321,9 +15321,7 @@  bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
   if (info->eh_frame_hdr_type == COMPACT_EH_HDR)
     _bfd_elf_end_eh_frame_parsing (info);
 
-  if (info->eh_frame_hdr_type
-      && !bfd_link_relocatable (info)
-      && _bfd_elf_discard_section_eh_frame_hdr (info))
+  if (_bfd_elf_discard_section_eh_frame_hdr (info))
     changed = 1;
 
   return changed;