]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libctf: create: addition of non-root types should not return root types
authorNick Alcock <nick.alcock@oracle.com>
Thu, 26 Jun 2025 14:45:31 +0000 (15:45 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 27 Jun 2025 12:07:52 +0000 (13:07 +0100)
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.

libctf/ctf-create.c

index 5d1057eafd4ac8f5deb573c47ddd852ac9522310..d165602a981572e0a7d563ee66dab067c4b2ab65 100644 (file)
@@ -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)