gas dw2gencfi memory leaks
Commit Message
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.
@@ -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 (¬es, name, len);
- insn->u.sym_name = (char *) obstack_finish (¬es);
+ 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 */