[binutils-gdb] Free sframe encoder context
Alan Modra
amodra@sourceware.org
Wed Feb 11 05:06:06 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3949fb481a6739dc1f4dc5fad09d7646c90af3d2
commit 3949fb481a6739dc1f4dc5fad09d7646c90af3d2
Author: Alan Modra <amodra@gmail.com>
Date: Wed Feb 11 15:31:33 2026 +1030
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:
---
bfd/elf-sframe.c | 2 +-
bfd/elf64-s390.c | 23 ++++++++++++++++-------
bfd/elflink.c | 2 ++
bfd/elfxx-x86.c | 17 ++++++++++-------
libsframe/sframe.c | 5 ++++-
5 files changed, 33 insertions(+), 16 deletions(-)
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;
More information about the Binutils-cvs
mailing list