]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libctf: types: ctf_type_resolve_nonrepresentable
authorNick Alcock <nick.alcock@oracle.com>
Thu, 24 Apr 2025 15:55:20 +0000 (16:55 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 17:07:42 +0000 (18:07 +0100)
This new internal function allows us to say "resolve a type to its base
type, but treat type 0 like BTF, returning 0 if it is found rather than
erroring with ECTF_NONREPRESENTABLE".  Used in the next commit.

libctf/ctf-impl.h
libctf/ctf-types.c

index 25617f50b04438aeb66808be09dea8dc4ebd48af..c9d1c8cf8ba322529aa2044fb036e785ec6d41e7 100644 (file)
@@ -811,6 +811,7 @@ extern char *ctf_str_append (char *, const char *);
 extern char *ctf_str_append_noerr (char *, const char *);
 
 extern ctf_id_t ctf_type_resolve_unsliced (ctf_dict_t *, ctf_id_t);
+extern ctf_id_t ctf_type_resolve_nonrepresentable (ctf_dict_t *, ctf_id_t, int allow_zero);
 extern int ctf_type_kind_unsliced (ctf_dict_t *, ctf_id_t);
 extern ssize_t ctf_type_align_natural (ctf_dict_t *fp, ctf_id_t prev_type,
                                       ctf_id_t type, ssize_t bit_offset);
index 6a714ceb850f3bf3ab330509d2483b603dd4e411..ddc9f8c98a53bae8d8ddf7ede6a230344c96e84b 100644 (file)
@@ -677,31 +677,45 @@ ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name)
 
 ctf_id_t
 ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type)
+{
+  return ctf_type_resolve_nonrepresentable (fp, type, 0);
+}
+
+/* As with ctf_type_resolve(), but optionally do not consider type 0
+   to be ECTF_NONREPRESENTABLE.  Internal only.  */
+ctf_id_t
+ctf_type_resolve_nonrepresentable (ctf_dict_t *fp, ctf_id_t type, int allow_zero)
 {
   ctf_id_t prev = type, otype = type;
   ctf_dict_t *ofp = fp;
-  const ctf_type_t *tp;
+  const ctf_type_t *tp, *suffix;
 
   if (type == 0)
-    return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE));
+    {
+      if (allow_zero)
+       return 0;
+      else
+       return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE));
+    }
 
-  while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
+  while ((tp = ctf_lookup_by_id (&fp, type, &suffix)) != NULL)
     {
-      switch (LCTF_INFO_KIND (fp, tp->ctt_info))
+      switch (LCTF_KIND (fp, tp))
        {
        case CTF_K_TYPEDEF:
        case CTF_K_VOLATILE:
        case CTF_K_CONST:
        case CTF_K_RESTRICT:
-         if (tp->ctt_type == type || tp->ctt_type == otype
-             || tp->ctt_type == prev)
+       case CTF_K_VAR:
+         if (suffix->ctt_type == type || suffix->ctt_type == otype
+             || suffix->ctt_type == prev)
            {
              ctf_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"),
                            otype);
              return (ctf_set_typed_errno (ofp, ECTF_CORRUPT));
            }
          prev = type;
-         type = tp->ctt_type;
+         type = suffix->ctt_type;
          break;
        case CTF_K_UNKNOWN:
          return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE));
@@ -709,7 +723,12 @@ ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type)
          return type;
        }
       if (type == 0)
-       return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE));
+       {
+         if (allow_zero)
+           return 0;
+         else
+           return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE));
+       }
     }
 
   return CTF_ERR;              /* errno is set for us.  */
@@ -728,7 +747,7 @@ ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
     return CTF_ERR;
 
-  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
+  if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL)
     return CTF_ERR;            /* errno is set for us.  */
   resolved_type = type;
 
@@ -736,17 +755,17 @@ ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
     {
       type = resolved_type;
 
-      if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
+      if ((LCTF_KIND (fp, tp)) == CTF_K_SLICE)
        if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
          return (ctf_set_typed_errno (ofp, ctf_errno (fp)));
 
       if ((resolved_type = ctf_type_resolve (fp, type)) == CTF_ERR)
        return CTF_ERR;
 
-      if ((tp = ctf_lookup_by_id (&fp, resolved_type)) == NULL)
+      if ((tp = ctf_lookup_by_id (&fp, resolved_type, NULL)) == NULL)
        return CTF_ERR;         /* errno is set for us.  */
     }
-  while (LCTF_INFO_KIND (fp, tp->ctt_info) == CTF_K_SLICE);
+  while (LCTF_KIND (fp, tp) == CTF_K_SLICE);
 
   return type;
 }