gas dw2gencfi memory leaks

Message ID Z3U2Rq8grTvAP09x@squeak.grove.modra.org
State New
Headers
Series gas dw2gencfi memory leaks |

Commit Message

Alan Modra Jan. 1, 2025, 12:34 p.m. UTC
  Some of these could have remained as malloc'd memory, but that would
require quite a bit of code to traverse frch_cfi_data for example, and
would rely on matching cfi directives (ie. valid input).  Just put
them on the notes obstack instead.

	* dw2gencfi.c (alloc_fde_entry): Use notes_calloc.
	(alloc_cfi_insn_data): Likewise.
	(cfi_end_fde): Don't free frch_cfi_data.
	(cfi_add_label): Use notes_strdup.
	(cfi_add_CFA_remember_state): Use notes_alloc.
	(cfi_add_CFA_restore_state): Don't free.
	(dot_cfi_escape): Use notes_alloc.
	(cfi_finish): Free cies after each pass, not before.  Clear
	out static vars too.
  

Patch

diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c
index 2ca71977117..fbeb697af09 100644
--- a/gas/dw2gencfi.c
+++ b/gas/dw2gencfi.c
@@ -406,9 +406,9 @@  static struct cie_entry *cie_root;
 static struct fde_entry *
 alloc_fde_entry (void)
 {
-  struct fde_entry *fde = XCNEW (struct fde_entry);
+  struct fde_entry *fde = notes_calloc (1, sizeof (*fde));
 
-  frchain_now->frch_cfi_data = XCNEW (struct frch_cfi_data);
+  frchain_now->frch_cfi_data = notes_calloc (1, sizeof (struct frch_cfi_data));
   frchain_now->frch_cfi_data->cur_fde_data = fde;
   *last_fde_data = fde;
   last_fde_data = &fde->next;
@@ -440,7 +440,7 @@  static struct fde_entry *last_fde;
 static struct cfi_insn_data *
 alloc_cfi_insn_data (void)
 {
-  struct cfi_insn_data *insn = XCNEW (struct cfi_insn_data);
+  struct cfi_insn_data *insn = notes_calloc (1, sizeof (*insn));
   struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
 
   *cur_fde_data->last = insn;
@@ -465,7 +465,6 @@  void
 cfi_end_fde (symbolS *label)
 {
   frchain_now->frch_cfi_data->cur_fde_data->end_address = label;
-  free (frchain_now->frch_cfi_data);
   frchain_now->frch_cfi_data = NULL;
 }
 
@@ -559,12 +558,10 @@  cfi_add_advance_loc (symbolS *label)
 void
 cfi_add_label (const char *name)
 {
-  unsigned int len = strlen (name) + 1;
   struct cfi_insn_data *insn = alloc_cfi_insn_data ();
 
   insn->insn = CFI_label;
-  obstack_grow (&notes, name, len);
-  insn->u.sym_name = (char *) obstack_finish (&notes);
+  insn->u.sym_name = notes_strdup (name);
 }
 
 /* Add a DW_CFA_offset record to the CFI data.  */
@@ -658,7 +655,7 @@  cfi_add_CFA_remember_state (void)
 
   cfi_add_CFA_insn (DW_CFA_remember_state);
 
-  p = XNEW (struct cfa_save_data);
+  p = notes_alloc (sizeof (*p));
   p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset;
   p->next = frchain_now->frch_cfi_data->cfa_save_stack;
   frchain_now->frch_cfi_data->cfa_save_stack = p;
@@ -676,7 +673,6 @@  cfi_add_CFA_restore_state (void)
     {
       frchain_now->frch_cfi_data->cur_cfa_offset = p->cfa_offset;
       frchain_now->frch_cfi_data->cfa_save_stack = p->next;
-      free (p);
     }
   else
     as_bad (_("CFI state restore without previous remember"));
@@ -951,7 +947,7 @@  dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
   tail = &head;
   do
     {
-      e = XNEW (struct cfi_escape_data);
+      e = notes_alloc (sizeof (*e));
       do_parse_cons_expression (&e->exp, 1);
       *tail = e;
       tail = &e->next;
@@ -2333,13 +2329,6 @@  cfi_finish (void)
 	  ccseg = NULL;
 	  seek_next_seg = 0;
 
-	  for (cie = cie_root; cie; cie = cie_next)
-	    {
-	      cie_next = cie->next;
-	      free ((void *) cie);
-	    }
-	  cie_root = NULL;
-
 	  for (fde = all_fde_data; fde ; fde = fde->next)
 	    {
 	      if ((fde->sections & CFI_EMIT_eh_frame) == 0
@@ -2396,6 +2385,13 @@  cfi_finish (void)
 	      output_fde (fde, cie, true, first,
 			  fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
 	    }
+
+	  for (cie = cie_root; cie; cie = cie_next)
+	    {
+	      cie_next = cie->next;
+	      free (cie);
+	    }
+	  cie_root = NULL;
 	}
       while (EH_FRAME_LINKONCE && seek_next_seg == 2);
 
@@ -2527,13 +2523,6 @@  cfi_finish (void)
 	  ccseg = NULL;
 	  seek_next_seg = 0;
 
-	  for (cie = cie_root; cie; cie = cie_next)
-	    {
-	      cie_next = cie->next;
-	      free ((void *) cie);
-	    }
-	  cie_root = NULL;
-
 	  for (fde = all_fde_data; fde ; fde = fde->next)
 	    {
 	      if ((fde->sections & CFI_EMIT_debug_frame) == 0)
@@ -2572,6 +2561,13 @@  cfi_finish (void)
 	      cie = select_cie_for_fde (fde, false, &first, alignment);
 	      output_fde (fde, cie, false, first, alignment);
 	    }
+
+	  for (cie = cie_root; cie; cie = cie_next)
+	    {
+	      cie_next = cie->next;
+	      free (cie);
+	    }
+	  cie_root = NULL;
 	}
       while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
 
@@ -2579,8 +2575,17 @@  cfi_finish (void)
 	for (fde = all_fde_data; fde ; fde = fde->next)
 	  SET_HANDLED (fde, 0);
     }
+  all_fde_data = NULL;
+  last_fde_data = &all_fde_data;
+  cfi_sections_set = false;
+  cfi_sections = CFI_EMIT_eh_frame;
+  all_cfi_sections = 0;
+  last_fde = NULL;
   if (dwcfi_hash)
-    htab_delete (dwcfi_hash);
+    {
+      htab_delete (dwcfi_hash);
+      dwcfi_hash = NULL;
+    }
 }
 
 #else /* TARGET_USE_CFIPOP */