diff options
author | Alan Modra <amodra@gmail.com> | 2025-01-01 22:47:16 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2025-01-01 22:47:16 +1030 |
commit | 597de453a2291a798024471a3d7c5c0b79201f94 (patch) | |
tree | 684b0382dfda5120c048e9d168b78bbe8b702ebd | |
parent | b492153908463bd351eaa2cf3802117ce9e7c479 (diff) | |
download | gdb-597de453a2291a798024471a3d7c5c0b79201f94.zip gdb-597de453a2291a798024471a3d7c5c0b79201f94.tar.gz gdb-597de453a2291a798024471a3d7c5c0b79201f94.tar.bz2 |
gas dw2gencfi memory leaks
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.
-rw-r--r-- | gas/dw2gencfi.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index 2ca7197..fbeb697 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 (¬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 */ |