]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libctf: fix ctf_type_pointer on parent dicts, etc
authorNick Alcock <nick.alcock@oracle.com>
Sun, 16 Feb 2025 19:53:40 +0000 (19:53 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 28 Feb 2025 15:13:24 +0000 (15:13 +0000)
Before now, ctf_type_pointer was crippled: it returned some type (if any)
that was a pointer to the type passed in, but only if both types were in the
current dict: if either (or both) was in the parent dict, it said there was
no pointer though there was.  This breaks real users: it's past time to lift
the restriction.

WIP (complete, but not yet tested).

libctf/ctf-types.c

index 08751cca2b495d7cc3138ddf7ea76494c8153cf0..1432d3a47db36fee943a3445128bf305fa24c155 100644 (file)
@@ -1175,33 +1175,43 @@ ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
     }
 }
 
-/* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
-   pointer to the given type, see if we can compute a pointer to the type
-   resulting from resolving the type down to its base type and use that
+/* Find a pointer to type by looking in fp->ctf_ptrtab and fp->ctf_pptrtab.  If
+   we can't find a pointer to the given type, see if we can compute a pointer to
+   the type resulting from resolving the type down to its base type and use that
    instead.  This helps with cases where the CTF data includes "struct foo *"
-   but not "foo_t *" and the user accesses "foo_t *" in the debugger.
-
-   XXX what about parent dicts?  */
+   but not "foo_t *" and the user accesses "foo_t *" in the debugger.  */
 
 ctf_id_t
 ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
 {
   ctf_dict_t *ofp = fp;
   ctf_id_t ntype;
+  uint32_t idx;
 
   if (ctf_lookup_by_id (&fp, type) == NULL)
     return CTF_ERR;            /* errno is set for us.  */
 
-  if ((ntype = fp->ctf_ptrtab[ctf_type_to_index (fp, type)]) != 0)
+  idx = ctf_type_to_index (fp, type);
+  if ((ntype = fp->ctf_ptrtab[idx]) != 0)
+    return (ctf_index_to_type (fp, ntype));
+
+  if (idx < ofp->ctf_pptrtab_len
+      && (ntype = ofp->ctf_pptrtab[idx]) != 0)
     return (ctf_index_to_type (fp, ntype));
 
+  /* Try again after resolution.  */
   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
     return (ctf_set_typed_errno (ofp, ECTF_NOTYPE));
 
   if (ctf_lookup_by_id (&fp, type) == NULL)
     return (ctf_set_typed_errno (ofp, ECTF_NOTYPE));
 
-  if ((ntype = fp->ctf_ptrtab[ctf_type_to_index (fp, type)]) != 0)
+  idx = ctf_type_to_index (fp, type);
+  if ((ntype = fp->ctf_ptrtab[idx]) != 0)
+    return (ctf_index_to_type (fp, ntype));
+
+  if (idx < ofp->ctf_pptrtab_len
+      && (ntype = ofp->ctf_pptrtab[idx]) != 0)
     return (ctf_index_to_type (fp, ntype));
 
   return (ctf_set_typed_errno (ofp, ECTF_NOTYPE));