From a887be69963c40ced36e319e5fb14b3de4b6658b Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 7 Jul 2022 22:03:15 +0930 Subject: [PATCH] ppc gas: don't leak ppc_hash memory * config/tc-ppc.c (insn_obstack): New. (insn_calloc): New function. (ppc_setup_opcodes): Use insn_obstack for ppc_hash. (ppc_md_end): New function. * config/tc-ppc.h (ppc_md_end): Declare (md_end): Define. --- gas/config/tc-ppc.c | 36 ++++++++++++++++++++++++++++++++++-- gas/config/tc-ppc.h | 3 +++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 0c3e670d11b..ac61cd8f122 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -976,6 +976,10 @@ ppc_optimize_expr (expressionS *left, operatorT op, expressionS *right) /* Whether to target xcoff64/elf64. */ static unsigned int ppc_obj64 = BFD_DEFAULT_TARGET_SIZE == 64; +/* A separate obstack for use by ppc_hash, so that we can quickly + throw away hash table memory . */ +struct obstack insn_obstack; + /* Opcode hash table. */ static htab_t ppc_hash; @@ -1613,6 +1617,21 @@ insn_validate (const struct powerpc_opcode *op) return false; } +static void * +insn_calloc (size_t n, size_t size) +{ + size_t amt; + void *ret; + if (gas_mul_overflow (n, size, &amt)) + { + obstack_alloc_failed_handler (); + abort (); + } + ret = obstack_alloc (&insn_obstack, amt); + memset (ret, 0, amt); + return ret; +} + /* Insert opcodes into hash tables. Called at startup and for .machine pseudo. */ @@ -1624,10 +1643,16 @@ ppc_setup_opcodes (void) bool bad_insn = false; if (ppc_hash != NULL) - htab_delete (ppc_hash); + { + htab_delete (ppc_hash); + _obstack_free (&insn_obstack, NULL); + } + + obstack_begin (&insn_obstack, chunksize); /* Insert the opcodes into a hash table. */ - ppc_hash = str_htab_create (); + ppc_hash = htab_create_alloc (5000, hash_string_tuple, eq_string_tuple, + NULL, insn_calloc, NULL); if (ENABLE_CHECKING) { @@ -1875,6 +1900,13 @@ md_begin (void) #endif } +void +ppc_md_end (void) +{ + htab_delete (ppc_hash); + _obstack_free (&insn_obstack, NULL); +} + void ppc_cleanup (void) { diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index e335aa611fe..ed06a296382 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -256,6 +256,9 @@ extern void ppc_elf_md_finish (void); #endif /* OBJ_ELF */ +extern void ppc_md_end (void); +#define md_end ppc_md_end + #if defined (OBJ_ELF) || defined (OBJ_XCOFF) #define TC_FORCE_RELOCATION(FIX) ppc_force_relocation (FIX) extern int ppc_force_relocation (struct fix *); -- 2.30.2