]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
eh-frame memory leaks
authorAlan Modra <amodra@gmail.com>
Sat, 11 Jan 2025 05:18:55 +0000 (15:48 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 15 Jan 2025 12:07:16 +0000 (22:37 +1030)
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.

bfd/elf-eh-frame.c
bfd/elflink.c

index b6f5078bb331410e29d245d70c283b71065568a5..dd6802b05fd3009842ddbac7a83174128a42ee36 100644 (file)
@@ -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;
index 9b8c7357d0dc94d952323a6a58495849de94c19a..f20c9a1d04d3736c29b29906b076c8633ec9f9ab 100644 (file)
@@ -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;