aboutsummaryrefslogtreecommitdiff
path: root/libctf
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2025-03-27 13:15:38 +0000
committerNick Alcock <nick.alcock@oracle.com>2025-03-27 13:15:38 +0000
commit1ffa393cc60866db965cafa6046cda96306b94e5 (patch)
tree3fa506b4bb36677f3a32b821d6e5f30fa0943a57 /libctf
parent287bf9c509d3889b93d102cd0bbf6cd4fdea062d (diff)
downloadbinutils-1ffa393cc60866db965cafa6046cda96306b94e5.zip
binutils-1ffa393cc60866db965cafa6046cda96306b94e5.tar.gz
binutils-1ffa393cc60866db965cafa6046cda96306b94e5.tar.bz2
libctf: create: another missed realloc-adaptation in struct member addition
Every single time we call ctf_grow_vlen or anything that calls it, we have to look up pointers into the vlen and/or prefix again, since they're in the region that ctf_grow_vlen reallocs. Fix a missed case.
Diffstat (limited to 'libctf')
-rw-r--r--libctf/ctf-create.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c
index 6fe09e8..7742268 100644
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -1703,6 +1703,7 @@ ctf_add_member_bitfield (ctf_dict_t *fp, ctf_id_t souid, const char *name,
{
size_t bound;
ssize_t off;
+ int added_padding = 0;
if (bit_offset == (unsigned long) - 1)
{
@@ -1752,6 +1753,8 @@ ctf_add_member_bitfield (ctf_dict_t *fp, ctf_id_t souid, const char *name,
while (bit_offset > bound)
{
+ added_padding = 1;
+
off = bound;
if (kflag)
off = CTF_MEMBER_BIT_OFFSET (bound);
@@ -1766,10 +1769,11 @@ ctf_add_member_bitfield (ctf_dict_t *fp, ctf_id_t souid, const char *name,
if (kflag)
off = CTF_MEMBER_BIT_OFFSET (off);
- /* Hunt down the prefix and member list again: they may have been moved by
- the realloc()s involved in field additions. */
+ /* Possibly hunt down the prefix and member list again: they may have been
+ moved by the realloc()s involved in field additions. */
- if ((prefix = (ctf_type_t *) ctf_find_prefix (fp, dtd->dtd_buf, CTF_K_BIG)) == NULL)
+ if (added_padding
+ && (prefix = (ctf_type_t *) ctf_find_prefix (fp, dtd->dtd_buf, CTF_K_BIG)) == NULL)
return (ctf_set_errno (ofp, ECTF_CORRUPT));
vlen = LCTF_VLEN (fp, prefix);
@@ -1791,6 +1795,12 @@ ctf_add_member_bitfield (ctf_dict_t *fp, ctf_id_t souid, const char *name,
return (ctf_set_errno (ofp, ctf_errno (fp)));
dtd->dtd_vlen_size += sizeof (ctf_member_t);
+
+ /* Hunt down the prefix and member list yet again, since they may have been
+ reallocated by ctf_grow_vlen. */
+
+ if ((prefix = (ctf_type_t *) ctf_find_prefix (fp, dtd->dtd_buf, CTF_K_BIG)) == NULL)
+ return (ctf_set_errno (ofp, ECTF_CORRUPT));
memb = (ctf_member_t *) dtd->dtd_vlen;
memb[vlen].ctm_name = ctf_str_add (fp, name);