diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2025-03-27 13:15:38 +0000 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2025-03-27 13:15:38 +0000 |
commit | 1ffa393cc60866db965cafa6046cda96306b94e5 (patch) | |
tree | 3fa506b4bb36677f3a32b821d6e5f30fa0943a57 /libctf | |
parent | 287bf9c509d3889b93d102cd0bbf6cd4fdea062d (diff) | |
download | binutils-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.c | 16 |
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); |