From 443101612dddb5af7332dde5da1845c4321b2e39 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 1 Jan 2025 22:48:38 +1030 Subject: [PATCH] gas gen-sframe memory leaks More freeing required. * gen-sframe.c (all_sframe_fdes, last_sframe_fde): Move earlier, make file scope. (sframe_row_entry_new): Move earlier. (sframe_row_entry_free): New function. (sframe_fde_alloc, sframe_fde_free): Move earlier. (sframe_fde_link): Delete. Expand into.. (create_sframe_all): ..here. (output_sframe_internal): Delete silly sframe_flags init. Free fdes. Reset static vars. (sframe_xlate_ctx_cleanup): Use sframe_row_entry_free. Free remember_fre too. Don't re-init xlate_ctx we're about to drop. * gen-sframe.h (all_sframe_fdes): Don't declare. --- gas/gen-sframe.c | 133 ++++++++++++++++++++++------------------------- gas/gen-sframe.h | 4 -- 2 files changed, 62 insertions(+), 75 deletions(-) diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 1fd87cc53a2..71296f2f4fb 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -66,6 +66,14 @@ # define SFRAME_FRE_TYPE_SELECTION_OPT 1 #endif +/* List of SFrame FDE entries. */ + +static struct sframe_func_entry *all_sframe_fdes = NULL; + +/* Tail of the list to add to. */ + +static struct sframe_func_entry **last_sframe_fde = &all_sframe_fdes; + /* Emit a single byte into the current segment. */ static inline void @@ -487,6 +495,50 @@ create_func_info_exp (expressionS *cexp, symbolS *dw_fde_end_addrS, #endif +static struct sframe_row_entry* +sframe_row_entry_new (void) +{ + struct sframe_row_entry *fre = XCNEW (struct sframe_row_entry); + /* Reset cfa_base_reg to -1. A value of 0 will imply some valid register + for the supported arches. */ + fre->cfa_base_reg = SFRAME_FRE_BASE_REG_INVAL; + fre->merge_candidate = true; + /* Reset the mangled RA status bit to zero by default. We will + initialize it in sframe_row_entry_initialize () with the sticky + bit if set. */ + fre->mangled_ra_p = false; + + return fre; +} + +static void +sframe_row_entry_free (struct sframe_row_entry *fre) +{ + while (fre) + { + struct sframe_row_entry *fre_next = fre->next; + XDELETE (fre); + fre = fre_next; + } +} + +/* Allocate an SFrame FDE. */ + +static struct sframe_func_entry* +sframe_fde_alloc (void) +{ + return XCNEW (struct sframe_func_entry); +} + +/* Free up the SFrame FDE. */ + +static void +sframe_fde_free (struct sframe_func_entry *sframe_fde) +{ + sframe_row_entry_free (sframe_fde->sframe_fres); + XDELETE (sframe_fde); +} + static void output_sframe_row_entry (symbolS *fde_start_addr, symbolS *fde_end_addr, @@ -624,7 +676,7 @@ output_sframe_internal (void) symbolS *end_of_frame_section; symbolS *start_of_func_desc_section; symbolS *start_of_fre_section; - struct sframe_func_entry *sframe_fde; + struct sframe_func_entry *sframe_fde, *sframe_fde_next; struct sframe_row_entry *sframe_fre; unsigned char abi_arch = 0; int fixed_fp_offset = SFRAME_CFA_FIXED_FP_INVALID; @@ -636,7 +688,6 @@ output_sframe_internal (void) /* The function descriptor entries as dumped by the assembler are not sorted on PCs. */ unsigned char sframe_flags = 0; - sframe_flags |= !SFRAME_F_FDE_SORTED; unsigned int num_fdes = get_num_sframe_fdes (); unsigned int num_fres = get_num_sframe_fres (); @@ -726,7 +777,7 @@ output_sframe_internal (void) i = 0; sframe_fde = all_sframe_fdes; - for (sframe_fde = all_sframe_fdes; sframe_fde; sframe_fde = sframe_fde->next) + for (sframe_fde = all_sframe_fdes; sframe_fde; sframe_fde = sframe_fde_next) { for (sframe_fre = sframe_fde->sframe_fres; sframe_fre; @@ -738,7 +789,11 @@ output_sframe_internal (void) sframe_fre); i++; } + sframe_fde_next = sframe_fde->next; + sframe_fde_free (sframe_fde); } + all_sframe_fdes = NULL; + last_sframe_fde = &all_sframe_fdes; symbol_set_value_now (end_of_frame_section); @@ -748,14 +803,6 @@ output_sframe_internal (void) fre_symbols = NULL; } -/* List of SFrame FDE entries. */ - -struct sframe_func_entry *all_sframe_fdes; - -/* Tail of the list to add to. */ - -static struct sframe_func_entry **last_sframe_fde = &all_sframe_fdes; - static unsigned int get_num_sframe_fdes (void) { @@ -782,35 +829,6 @@ get_num_sframe_fres (void) return total_fres; } -/* Allocate an SFrame FDE. */ - -static struct sframe_func_entry* -sframe_fde_alloc (void) -{ - struct sframe_func_entry *sframe_fde = XCNEW (struct sframe_func_entry); - return sframe_fde; -} - -/* Link the SFrame FDE in. */ - -static int -sframe_fde_link (struct sframe_func_entry *sframe_fde) -{ - *last_sframe_fde = sframe_fde; - last_sframe_fde = &sframe_fde->next; - - return 0; -} - -/* Free up the SFrame FDE. */ - -static void -sframe_fde_free (struct sframe_func_entry *sframe_fde) -{ - XDELETE (sframe_fde); - sframe_fde = NULL; -} - /* SFrame translation context functions. */ /* Allocate a new SFrame translation context. */ @@ -840,22 +858,9 @@ sframe_xlate_ctx_init (struct sframe_xlate_ctx *xlate_ctx) static void sframe_xlate_ctx_cleanup (struct sframe_xlate_ctx *xlate_ctx) { - struct sframe_row_entry *fre, *fre_next; - - if (xlate_ctx->num_xlate_fres) - { - fre = xlate_ctx->first_fre; - while (fre) - { - fre_next = fre->next; - XDELETE (fre); - fre = fre_next; - } - } - + sframe_row_entry_free (xlate_ctx->first_fre); + XDELETE (xlate_ctx->remember_fre); XDELETE (xlate_ctx->cur_fre); - - sframe_xlate_ctx_init (xlate_ctx); } /* Transfer the state from the SFrame translation context to the SFrame FDE. */ @@ -869,21 +874,6 @@ sframe_xlate_ctx_finalize (struct sframe_xlate_ctx *xlate_ctx, sframe_fde->num_fres = xlate_ctx->num_xlate_fres; } -static struct sframe_row_entry* -sframe_row_entry_new (void) -{ - struct sframe_row_entry *fre = XCNEW (struct sframe_row_entry); - /* Reset cfa_base_reg to -1. A value of 0 will imply some valid register - for the supported arches. */ - fre->cfa_base_reg = SFRAME_FRE_BASE_REG_INVAL; - fre->merge_candidate = true; - /* Reset the mangled RA status bit to zero by default. We will initialize it in - sframe_row_entry_initialize () with the sticky bit if set. */ - fre->mangled_ra_p = false; - - return fre; -} - /* Add the given FRE in the list of frame row entries in the given FDE translation context. */ @@ -1521,7 +1511,8 @@ create_sframe_all (void) /* All done. Transfer the state from the SFrame translation context to the SFrame FDE. */ sframe_xlate_ctx_finalize (xlate_ctx, sframe_fde); - sframe_fde_link (sframe_fde); + *last_sframe_fde = sframe_fde; + last_sframe_fde = &sframe_fde->next; } } diff --git a/gas/gen-sframe.h b/gas/gen-sframe.h index 47daa6b5b79..e4a4c6ea0ce 100644 --- a/gas/gen-sframe.h +++ b/gas/gen-sframe.h @@ -135,10 +135,6 @@ unsigned char sframe_get_abi_arch_callback (const char *target_arch, int big_endian_p); -/* The list of all FDEs with data in SFrame internal representation. */ - -extern struct sframe_func_entry *all_sframe_fdes; - /* SFrame version specific operations structure. */ struct sframe_version_ops