diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2025-06-26 15:45:31 +0100 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2025-06-27 13:08:28 +0100 |
commit | 22381f3dfd1a9431f4c6d01294a54b576d16a6db (patch) | |
tree | 7274d41ec41f5edec5732650eaf468d8ab75ea98 | |
parent | 56245d74e26f1ae6365f39ca0f4dce4f26c19607 (diff) | |
download | binutils-22381f3dfd1a9431f4c6d01294a54b576d16a6db.zip binutils-22381f3dfd1a9431f4c6d01294a54b576d16a6db.tar.gz binutils-22381f3dfd1a9431f4c6d01294a54b576d16a6db.tar.bz2 |
libctf: create: addition of non-root types should not return root types
If you add a non-root type to a dict, you should always get a new, unique
type ID back, even if a root-visible type with the same name already exists.
Unfortunately, if the root-visible type is a forward, and you're adding a
non-root-visible struct, union, or enum, the machinery to detect forwards
and promote them to the concrete type fires in this case and returns the
root-visible type! If this is an enum being inserted hidden because its
enumerands conflict with some other enum, this will lead to failure later
on: in any case, it's seriously counterintuitive to add a non-root- visible
type and get a root-visible one instead.
Fix this by checking the root-visible flag properly and only checking for
forwards if this type is root-visible. (This may lead to a certain degree
of proliferation of non-root-visible forwards: we can add a cleanup pass for
those later if needed.)
libctf/
* ctf-create.c (ctf_add_sou_sized): Check the root-visible flag when
doing forward promotion.
(ctf_add_enum_internal): Likewise.
(ctf_add_enum_encoded_internal): Likewise.
-rw-r--r-- | libctf/ctf-create.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index 5d1057e..d165602 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -1193,7 +1193,7 @@ ctf_add_sou_sized (ctf_dict_t *fp, uint32_t flag, const char *name, return (ctf_set_errno (fp, ECTF_NOPARENT)); /* Promote root-visible forwards to structs/unions. */ - if (name != NULL) + if (name != NULL && root_flag == CTF_ADD_ROOT) type = ctf_lookup_by_rawname (fp, kind, name); if (type > 0) @@ -1269,7 +1269,7 @@ ctf_add_enum_internal (ctf_dict_t *fp, uint32_t flag, const char *name, return (ctf_set_errno (fp, ECTF_NOPARENT)); /* Promote root-visible forwards to enums. */ - if (name != NULL) + if (name != NULL && flag == CTF_ADD_ROOT) type = ctf_lookup_by_rawname (fp, kind, name); /* Prohibit promotion if this type was ctf_open()ed. */ @@ -1322,7 +1322,7 @@ ctf_add_enum_encoded_internal (ctf_dict_t *fp, uint32_t flag, const char *name, enums or forwards to them. (This includes other slices: you cannot slice a slice, which would be a useless thing to do anyway.) */ - if (name != NULL) + if (name != NULL && flag == CTF_ADD_ROOT) type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name); if (type != 0) |