From: Alan Modra Date: Wed, 11 Feb 2026 05:01:33 +0000 (+1030) Subject: Free sframe encoder context X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3949fb481a6739dc1f4dc5fad09d7646c90af3d2;p=thirdparty%2Fbinutils-gdb.git Free sframe encoder context Like the patch to free sframe decoder data, this also needs to ensure the function doing the free is passed the actual context address. bfd/ * elf-sframe.c (_bfd_elf_write_section_sframe): Don't pass address of local var to sframe_encoder_free, pass the actual context address. * elf64-s390.c (elf_s390_link_hash_table_free): New function. (elf_s390_link_hash_table_create): Set hash_table_free. Tidy zmalloc call. (_bfd_s390_elf_write_sframe_plt): Don't pass address of local var to sframe_encoder_free, pass the actual context address. * elflink.c: Include sframe-api.h. (_bfd_elf_link_hash_table_free): Free sframe encoder data. * elfxx-x86.c (elf_x86_link_hash_table_free): Likewise. (_bfd_x86_elf_write_sframe_plt): Don't pass address of local var to sframe_encoder_free, pass the actual context address. libsframe/ * sframe.c (sframe_encode): Free context on error return path. --- diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c index c28f1236a2f..7b2eed81c9f 100644 --- a/bfd/elf-sframe.c +++ b/bfd/elf-sframe.c @@ -730,7 +730,7 @@ _bfd_elf_write_section_sframe (bfd *abfd, struct bfd_link_info *info) hdr->sh_size = sec->size; } - sframe_encoder_free (&sfe_ctx); + sframe_encoder_free (&sfe_info->sfe_ctx); return retval; } diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 6f6c28bedce..3925cf6494d 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -790,15 +790,23 @@ link_hash_newfunc (struct bfd_hash_entry *entry, return entry; } +static void +elf_s390_link_hash_table_free (bfd *obfd) +{ + struct elf_s390_link_hash_table *htab + = (struct elf_s390_link_hash_table *) obfd->link.hash; + sframe_encoder_free (&htab->plt_cfe_ctx); + _bfd_elf_link_hash_table_free (obfd); +} + /* Create an s390 ELF linker hash table. */ static struct bfd_link_hash_table * elf_s390_link_hash_table_create (bfd *abfd) { struct elf_s390_link_hash_table *ret; - size_t amt = sizeof (struct elf_s390_link_hash_table); - ret = (struct elf_s390_link_hash_table *) bfd_zmalloc (amt); + ret = bfd_zmalloc (sizeof (*ret)); if (ret == NULL) return NULL; @@ -808,6 +816,7 @@ elf_s390_link_hash_table_create (bfd *abfd) free (ret); return NULL; } + ret->elf.root.hash_table_free = elf_s390_link_hash_table_free; return &ret->elf.root; } @@ -1669,7 +1678,7 @@ static bool _bfd_s390_elf_write_sframe_plt (struct bfd_link_info *info) { struct elf_s390_link_hash_table *htab; - sframe_encoder_ctx *ectx; + sframe_encoder_ctx **ectx; size_t sec_size; asection *sec; bfd *dynobj; @@ -1679,19 +1688,19 @@ _bfd_s390_elf_write_sframe_plt (struct bfd_link_info *info) htab = elf_s390_hash_table (info); dynobj = htab->elf.dynobj; - ectx = htab->plt_cfe_ctx; + ectx = &htab->plt_cfe_ctx; sec = htab->plt_sframe; - BFD_ASSERT (ectx); + BFD_ASSERT (*ectx); - void *contents = sframe_encoder_write (ectx, &sec_size, false, &err); + void *contents = sframe_encoder_write (*ectx, &sec_size, false, &err); sec->size = (bfd_size_type) sec_size; sec->contents = (unsigned char *) bfd_zalloc (dynobj, sec->size); sec->alloced = 1; memcpy (sec->contents, contents, sec_size); - sframe_encoder_free (&ectx); + sframe_encoder_free (ectx); return true; } diff --git a/bfd/elflink.c b/bfd/elflink.c index 29b89d4ab9e..78751f957c4 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -24,6 +24,7 @@ #include "libbfd.h" #define ARCH_SIZE 0 #include "elf-bfd.h" +#include "sframe-api.h" #include "safe-ctype.h" #include "libiberty.h" #include "objalloc.h" @@ -8457,6 +8458,7 @@ _bfd_elf_link_hash_table_free (bfd *obfd) free (htab->eh_info.u.compact.entries); else free (htab->eh_info.u.dwarf.array); + sframe_encoder_free (&htab->sfe_info.sfe_ctx); _bfd_generic_link_hash_table_free (obfd); } diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index f476c04c888..f3c267f5fcc 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -695,6 +695,9 @@ elf_x86_link_hash_table_free (bfd *obfd) htab_delete (htab->loc_hash_table); if (htab->loc_hash_memory) objalloc_free ((struct objalloc *) htab->loc_hash_memory); + sframe_encoder_free (&htab->plt_cfe_ctx); + sframe_encoder_free (&htab->plt_second_cfe_ctx); + sframe_encoder_free (&htab->plt_got_cfe_ctx); _bfd_elf_link_hash_table_free (obfd); } @@ -1975,7 +1978,7 @@ _bfd_x86_elf_write_sframe_plt (bfd *output_bfd, { struct elf_x86_link_hash_table *htab; elf_backend_data *bed; - sframe_encoder_ctx *ectx; + sframe_encoder_ctx **ectx; size_t sec_size; asection *sec; bfd *dynobj; @@ -1989,15 +1992,15 @@ _bfd_x86_elf_write_sframe_plt (bfd *output_bfd, switch (plt_sec_type) { case SFRAME_PLT: - ectx = htab->plt_cfe_ctx; + ectx = &htab->plt_cfe_ctx; sec = htab->plt_sframe; break; case SFRAME_PLT_SEC: - ectx = htab->plt_second_cfe_ctx; + ectx = &htab->plt_second_cfe_ctx; sec = htab->plt_second_sframe; break; case SFRAME_PLT_GOT: - ectx = htab->plt_got_cfe_ctx; + ectx = &htab->plt_got_cfe_ctx; sec = htab->plt_got_sframe; break; default: @@ -2006,16 +2009,16 @@ _bfd_x86_elf_write_sframe_plt (bfd *output_bfd, break; } - BFD_ASSERT (ectx); + BFD_ASSERT (*ectx); - void *contents = sframe_encoder_write (ectx, &sec_size, false, &err); + void *contents = sframe_encoder_write (*ectx, &sec_size, false, &err); sec->size = (bfd_size_type) sec_size; sec->contents = (unsigned char *) bfd_zalloc (dynobj, sec->size); sec->alloced = 1; memcpy (sec->contents, contents, sec_size); - sframe_encoder_free (&ectx); + sframe_encoder_free (ectx); return true; } diff --git a/libsframe/sframe.c b/libsframe/sframe.c index 37590f3c11c..cd6bb3022db 100644 --- a/libsframe/sframe.c +++ b/libsframe/sframe.c @@ -1990,7 +1990,10 @@ sframe_encode (uint8_t ver, uint8_t flags, uint8_t abi_arch, sframe_encoder_write_sframe assume flag SFRAME_F_FDE_FUNC_START_PCREL set. */ if (!(flags & SFRAME_F_FDE_FUNC_START_PCREL)) - return sframe_ret_set_errno (errp, SFRAME_ERR_ECTX_INVAL); + { + free (ectx); + return sframe_ret_set_errno (errp, SFRAME_ERR_ECTX_INVAL); + } hp->sfh_abi_arch = abi_arch; hp->sfh_cfa_fixed_fp_offset = fixed_fp_offset;