libctf: handle nonrepresentable types at link time
[deliverable/binutils-gdb.git] / libctf / ctf-types.c
index a7fe5d0b184525d3290915892597979e81396e89..9fe4d5a6d73b4fdb46143ca2839cb54bec0f88d2 100644 (file)
@@ -47,10 +47,10 @@ ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
   int rc;
 
   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
@@ -102,10 +102,10 @@ ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
   int rc;
 
   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
     return (ctf_set_errno (ofp, ECTF_NOTENUM));
@@ -144,6 +144,27 @@ ctf_type_iter (ctf_file_t *fp, ctf_type_f *func, void *arg)
   return 0;
 }
 
+/* Iterate over every type in the given CTF container, user-visible or not.
+   We pass the type ID of each type to the specified callback function.  */
+
+int
+ctf_type_iter_all (ctf_file_t *fp, ctf_type_all_f *func, void *arg)
+{
+  ctf_id_t id, max = fp->ctf_typemax;
+  int rc, child = (fp->ctf_flags & LCTF_CHILD);
+
+  for (id = 1; id <= max; id++)
+    {
+      const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
+      if ((rc = func (LCTF_INDEX_TO_TYPE (fp, id, child),
+                     LCTF_INFO_ISROOT(fp, tp->ctt_info)
+                     ? CTF_ADD_ROOT : CTF_ADD_NONROOT, arg) != 0))
+       return rc;
+    }
+
+  return 0;
+}
+
 /* Iterate over every variable in the given CTF container, in arbitrary order.
    We pass the name of each variable to the specified callback function.  */
 
@@ -179,6 +200,9 @@ ctf_type_resolve (ctf_file_t *fp, ctf_id_t type)
   ctf_file_t *ofp = fp;
   const ctf_type_t *tp;
 
+  if (type == 0)
+    return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
+
   while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
     {
       switch (LCTF_INFO_KIND (fp, tp->ctt_info))
@@ -199,6 +223,8 @@ ctf_type_resolve (ctf_file_t *fp, ctf_id_t type)
        default:
          return type;
        }
+      if (type == 0)
+       return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
     }
 
   return CTF_ERR;              /* errno is set for us.  */
@@ -369,6 +395,23 @@ ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
   return (rv >= 0 && (size_t) rv < len ? buf : NULL);
 }
 
+/* Lookup the given type ID and return its raw, unadorned, undecorated name as a
+   new dynamcally-allocated string.  */
+
+char *
+ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
+{
+  const ctf_type_t *tp;
+
+  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
+    return NULL;               /* errno is set for us.  */
+
+  if (ctf_strraw (fp, tp->ctt_name) != NULL)
+    return strdup (ctf_strraw (fp, tp->ctt_name));
+
+  return NULL;
+}
+
 /* Resolve the type down to a base type node, and then return the size
    of the type storage in bytes.  */
 
@@ -406,8 +449,8 @@ ctf_type_size (ctf_file_t *fp, ctf_id_t type)
       if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
        return size;
 
-      if (ctf_array_info (fp, type, &ar) == CTF_ERR
-         || (size = ctf_type_size (fp, ar.ctr_contents)) == CTF_ERR)
+      if (ctf_array_info (fp, type, &ar) < 0
+         || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
        return -1;              /* errno is set for us.  */
 
       return size * ar.ctr_nelems;
@@ -445,7 +488,7 @@ ctf_type_align (ctf_file_t *fp, ctf_id_t type)
     case CTF_K_ARRAY:
       {
        ctf_arinfo_t r;
-       if (ctf_array_info (fp, type, &r) == CTF_ERR)
+       if (ctf_array_info (fp, type, &r) < 0)
          return -1;            /* errno is set for us.  */
        return (ctf_type_align (fp, r.ctr_contents));
       }
@@ -474,7 +517,7 @@ ctf_type_align (ctf_file_t *fp, ctf_id_t type)
                for (; n != 0; n--, mp++)
                  {
                    ssize_t am = ctf_type_align (fp, mp->ctm_type);
-                   align = MAX (align, am);
+                   align = MAX (align, (size_t) am);
                  }
              }
            else
@@ -483,7 +526,7 @@ ctf_type_align (ctf_file_t *fp, ctf_id_t type)
                for (; n != 0; n--, lmp++)
                  {
                    ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
-                   align = MAX (align, am);
+                   align = MAX (align, (size_t) am);
                  }
              }
          }
@@ -495,7 +538,7 @@ ctf_type_align (ctf_file_t *fp, ctf_id_t type)
                   dmd != NULL; dmd = ctf_list_next (dmd))
                {
                  ssize_t am = ctf_type_align (fp, dmd->dmd_type);
-                 align = MAX (align, am);
+                 align = MAX (align, (size_t) am);
                  if (kind == CTF_K_STRUCT)
                    break;
                }
@@ -520,7 +563,7 @@ ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
   const ctf_type_t *tp;
 
   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   return (LCTF_INFO_KIND (fp, tp->ctt_info));
 }
@@ -533,13 +576,13 @@ ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
 {
   int kind;
 
-  if ((kind = ctf_type_kind_unsliced (fp, type)) == CTF_ERR)
-    return CTF_ERR;
+  if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
+    return -1;
 
   if (kind == CTF_K_SLICE)
     {
       if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
-       return CTF_ERR;
+       return -1;
       kind = ctf_type_kind_unsliced (fp, type);
     }
 
@@ -624,7 +667,7 @@ ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
   uint32_t data;
 
   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
     {
@@ -790,10 +833,10 @@ ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
   uint32_t kind, n;
 
   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
   kind = LCTF_INFO_KIND (fp, tp->ctt_info);
@@ -847,7 +890,7 @@ ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
   ssize_t increment;
 
   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
     return (ctf_set_errno (ofp, ECTF_NOTARRAY));
@@ -919,15 +962,15 @@ ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
   uint32_t n;
 
   if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
     {
       (void) ctf_set_errno (ofp, ECTF_NOTENUM);
-      return CTF_ERR;
+      return -1;
     }
 
   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
@@ -945,7 +988,75 @@ ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
     }
 
   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
-  return CTF_ERR;
+  return -1;
+}
+
+/* Given a type ID relating to a function type, return info on return types and
+   arg counts for that function.  */
+
+int
+ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
+{
+  const ctf_type_t *tp;
+  uint32_t kind;
+  const uint32_t *args;
+  ssize_t size, increment;
+
+  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
+    return -1;                 /* errno is set for us.  */
+
+  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
+    return -1;                 /* errno is set for us.  */
+
+  (void) ctf_get_ctt_size (fp, tp, &size, &increment);
+  kind = LCTF_INFO_KIND (fp, tp->ctt_info);
+
+  if (kind != CTF_K_FUNCTION)
+    return (ctf_set_errno (fp, ECTF_NOTFUNC));
+
+  fip->ctc_return = tp->ctt_type;
+  fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
+  fip->ctc_flags = 0;
+
+  args = (uint32_t *) ((uintptr_t) tp + increment);
+
+  if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
+    {
+      fip->ctc_flags |= CTF_FUNC_VARARG;
+      fip->ctc_argc--;
+    }
+
+  return 0;
+}
+
+/* Given a type ID relating to a function type,, return the arguments for the
+   function.  */
+
+int
+ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
+{
+  const ctf_type_t *tp;
+  const uint32_t *args;
+  ssize_t size, increment;
+  ctf_funcinfo_t f;
+
+  if (ctf_func_type_info (fp, type, &f) < 0)
+    return -1;                 /* errno is set for us.  */
+
+  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
+    return -1;                 /* errno is set for us.  */
+
+  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
+    return -1;                 /* errno is set for us.  */
+
+  (void) ctf_get_ctt_size (fp, tp, &size, &increment);
+
+  args = (uint32_t *) ((uintptr_t) tp + increment);
+
+  for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
+    *argv++ = *args++;
+
+  return 0;
 }
 
 /* Recursively visit the members of any type.  This function is used as the
@@ -965,10 +1076,10 @@ ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
   int rc;
 
   if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
-    return CTF_ERR;            /* errno is set for us.  */
+    return -1;                 /* errno is set for us.  */
 
   if ((rc = func (name, otype, offset, depth, arg)) != 0)
     return rc;
This page took 0.051251 seconds and 4 git commands to generate.