Move free_all_objfiles to program_space
[deliverable/binutils-gdb.git] / libctf / ctf-types.c
index a7fe5d0b184525d3290915892597979e81396e89..b0139e82bd75e9a272016883a5f0156dda5bb58e 100644 (file)
@@ -42,15 +42,16 @@ ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
 {
   ctf_file_t *ofp = fp;
   const ctf_type_t *tp;
+  ctf_dtdef_t *dtd;
   ssize_t size, increment;
   uint32_t kind, n;
   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);
@@ -58,29 +59,43 @@ ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
     return (ctf_set_errno (ofp, ECTF_NOTSOU));
 
-  if (size < CTF_LSTRUCT_THRESH)
+  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
     {
-      const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
-                                                      increment);
-
-      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
+      if (size < CTF_LSTRUCT_THRESH)
        {
-         const char *name = ctf_strptr (fp, mp->ctm_name);
-         if ((rc = func (name, mp->ctm_type, mp->ctm_offset, arg)) != 0)
+         const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
+                                                          increment);
+
+         for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
+           {
+             const char *name = ctf_strptr (fp, mp->ctm_name);
+             if ((rc = func (name, mp->ctm_type, mp->ctm_offset, arg)) != 0)
            return rc;
+           }
        }
+      else
+       {
+         const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
+                                                             increment);
 
+         for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
+           {
+             const char *name = ctf_strptr (fp, lmp->ctlm_name);
+             if ((rc = func (name, lmp->ctlm_type,
+                             (unsigned long) CTF_LMEM_OFFSET (lmp), arg)) != 0)
+               return rc;
+           }
+       }
     }
   else
     {
-      const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
-                                                         increment);
+      ctf_dmdef_t *dmd;
 
-      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
+      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
+          dmd != NULL; dmd = ctf_list_next (dmd))
        {
-         const char *name = ctf_strptr (fp, lmp->ctlm_name);
-         if ((rc = func (name, lmp->ctlm_type,
-                         (unsigned long) CTF_LMEM_OFFSET (lmp), arg)) != 0)
+         if ((rc = func (dmd->dmd_name, dmd->dmd_type,
+                         dmd->dmd_offset, arg)) != 0)
            return rc;
        }
     }
@@ -97,28 +112,43 @@ ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
   ctf_file_t *ofp = fp;
   const ctf_type_t *tp;
   const ctf_enum_t *ep;
+  ctf_dtdef_t *dtd;
   ssize_t increment;
   uint32_t n;
   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));
 
   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
 
-  ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
+  if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
+    {
+      ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
 
-  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
+      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
+       {
+         const char *name = ctf_strptr (fp, ep->cte_name);
+         if ((rc = func (name, ep->cte_value, arg)) != 0)
+           return rc;
+       }
+    }
+  else
     {
-      const char *name = ctf_strptr (fp, ep->cte_name);
-      if ((rc = func (name, ep->cte_value, arg)) != 0)
-       return rc;
+      ctf_dmdef_t *dmd;
+
+      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
+          dmd != NULL; dmd = ctf_list_next (dmd))
+       {
+         if ((rc = func (dmd->dmd_name, dmd->dmd_value, arg)) != 0)
+           return rc;
+       }
     }
 
   return 0;
@@ -144,22 +174,57 @@ 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.  */
 
 int
 ctf_variable_iter (ctf_file_t *fp, ctf_variable_f *func, void *arg)
 {
-  unsigned long i;
   int rc;
 
   if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
     return ECTF_NOPARENT;
 
-  for (i = 0; i < fp->ctf_nvars; i++)
-    if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name),
-                   fp->ctf_vars[i].ctv_type, arg)) != 0)
-      return rc;
+  if (!(fp->ctf_flags & LCTF_RDWR))
+    {
+      unsigned long i;
+      for (i = 0; i < fp->ctf_nvars; i++)
+       if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name),
+                       fp->ctf_vars[i].ctv_type, arg)) != 0)
+         return rc;
+    }
+  else
+    {
+      ctf_dvdef_t *dvd;
+
+      for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
+          dvd = ctf_list_next (dvd))
+       {
+         if ((rc = func (dvd->dvd_name, dvd->dvd_type, arg)) != 0)
+           return rc;
+       }
+    }
 
   return 0;
 }
@@ -179,6 +244,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 +267,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.  */
@@ -223,6 +293,29 @@ ctf_type_resolve_unsliced (ctf_file_t *fp, ctf_id_t type)
   return type;
 }
 
+/* Look up a name in the given name table, in the appropriate hash given the
+   kind of the identifier.  The name is a raw, undecorated identifier.  */
+
+ctf_id_t ctf_lookup_by_rawname (ctf_file_t *fp, int kind, const char *name)
+{
+  return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
+}
+
+/* Look up a name in the given name table, in the appropriate hash given the
+   readability state of the dictionary.  The name is a raw, undecorated
+   identifier.  */
+
+ctf_id_t ctf_lookup_by_rawhash (ctf_file_t *fp, ctf_names_t *np, const char *name)
+{
+  ctf_id_t id;
+
+  if (fp->ctf_flags & LCTF_RDWR)
+    id = (ctf_id_t) ctf_dynhash_lookup (np->ctn_writable, name);
+  else
+    id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
+  return id;
+}
+
 /* Lookup the given type ID and return its name as a new dynamcally-allocated
    string.  */
 
@@ -345,11 +438,12 @@ ssize_t
 ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
 {
   char *str = ctf_type_aname (fp, type);
-  size_t slen = strlen (str);
+  size_t slen;
 
   if (str == NULL)
-    return CTF_ERR;             /* errno is set for us */
+    return CTF_ERR;                    /* errno is set for us.  */
 
+  slen = strlen (str);
   snprintf (buf, len, "%s", str);
   free (str);
 
@@ -369,6 +463,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 +517,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 +556,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 +585,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 +594,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 +606,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 +631,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 +644,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,11 +735,31 @@ 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)
     {
-      *ep = dtd->dtd_u.dtu_enc;
+      switch (LCTF_INFO_KIND (fp, tp->ctt_info))
+       {
+       case CTF_K_INTEGER:
+       case CTF_K_FLOAT:
+         *ep = dtd->dtd_u.dtu_enc;
+         break;
+       case CTF_K_SLICE:
+         {
+           const ctf_slice_t *slice;
+           ctf_encoding_t underlying_en;
+           slice = &dtd->dtd_u.dtu_slice;
+
+           data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
+           ep->cte_format = underlying_en.cte_format;
+           ep->cte_offset = slice->cts_offset;
+           ep->cte_bits = slice->cts_bits;
+           break;
+         }
+       default:
+         return (ctf_set_errno (ofp, ECTF_NOTINTFP));
+       }
       return 0;
     }
 
@@ -786,14 +917,15 @@ ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
 {
   ctf_file_t *ofp = fp;
   const ctf_type_t *tp;
+  ctf_dtdef_t *dtd;
   ssize_t size, increment;
   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);
@@ -801,32 +933,50 @@ ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
   if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
     return (ctf_set_errno (ofp, ECTF_NOTSOU));
 
-  if (size < CTF_LSTRUCT_THRESH)
+  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
     {
-      const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
-                                                      increment);
+      if (size < CTF_LSTRUCT_THRESH)
+       {
+         const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
+                                                          increment);
 
-      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
+         for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
+           {
+             if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
+               {
+                 mip->ctm_type = mp->ctm_type;
+                 mip->ctm_offset = mp->ctm_offset;
+                 return 0;
+               }
+           }
+       }
+      else
        {
-         if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
+         const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
+                                                             increment);
+
+         for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
            {
-             mip->ctm_type = mp->ctm_type;
-             mip->ctm_offset = mp->ctm_offset;
-             return 0;
+             if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
+               {
+                 mip->ctm_type = lmp->ctlm_type;
+                 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
+                 return 0;
+               }
            }
        }
     }
   else
     {
-      const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
-                                                         increment);
+      ctf_dmdef_t *dmd;
 
-      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
+      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
+          dmd != NULL; dmd = ctf_list_next (dmd))
        {
-         if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
+         if (strcmp (dmd->dmd_name, name) == 0)
            {
-             mip->ctm_type = lmp->ctlm_type;
-             mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
+             mip->ctm_type = dmd->dmd_type;
+             mip->ctm_offset = dmd->dmd_offset;
              return 0;
            }
        }
@@ -847,7 +997,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));
@@ -877,6 +1027,7 @@ ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
   ctf_file_t *ofp = fp;
   const ctf_type_t *tp;
   const ctf_enum_t *ep;
+  const ctf_dtdef_t *dtd;
   ssize_t increment;
   uint32_t n;
 
@@ -894,12 +1045,26 @@ ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
 
   (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
 
-  ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
+  if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
+    {
+      ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
 
-  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
+      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
+       {
+         if (ep->cte_value == value)
+           return (ctf_strptr (fp, ep->cte_name));
+       }
+    }
+  else
     {
-      if (ep->cte_value == value)
-       return (ctf_strptr (fp, ep->cte_name));
+      ctf_dmdef_t *dmd;
+
+      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
+          dmd != NULL; dmd = ctf_list_next (dmd))
+       {
+         if (dmd->dmd_value == value)
+           return dmd->dmd_name;
+       }
     }
 
   (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
@@ -915,37 +1080,132 @@ ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
   ctf_file_t *ofp = fp;
   const ctf_type_t *tp;
   const ctf_enum_t *ep;
+  const ctf_dtdef_t *dtd;
   ssize_t increment;
   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);
 
   ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
 
-  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
+  if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
     {
-      if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
+      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
        {
-         if (valp != NULL)
-           *valp = ep->cte_value;
-         return 0;
+         if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
+           {
+             if (valp != NULL)
+               *valp = ep->cte_value;
+             return 0;
+           }
+       }
+    }
+  else
+    {
+      ctf_dmdef_t *dmd;
+
+      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
+          dmd != NULL; dmd = ctf_list_next (dmd))
+       {
+         if (strcmp (dmd->dmd_name, name) == 0)
+           {
+             if (valp != NULL)
+               *valp = dmd->dmd_value;
+             return 0;
+           }
        }
     }
 
   (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;
+  const ctf_dtdef_t *dtd;
+  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_flags = 0;
+  fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
+
+  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
+    args = (uint32_t *) ((uintptr_t) tp + increment);
+  else
+    args = (uint32_t *) dtd->dtd_u.dtu_argv;
+
+  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;
+  const ctf_dtdef_t *dtd;
+  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);
+
+  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
+    args = (uint32_t *) ((uintptr_t) tp + increment);
+  else
+    args = (uint32_t *) dtd->dtd_u.dtu_argv;
+
+  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
@@ -960,15 +1220,16 @@ ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
 {
   ctf_id_t otype = type;
   const ctf_type_t *tp;
+  const ctf_dtdef_t *dtd;
   ssize_t size, increment;
   uint32_t kind, n;
   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;
@@ -980,32 +1241,48 @@ ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
 
   (void) ctf_get_ctt_size (fp, tp, &size, &increment);
 
-  if (size < CTF_LSTRUCT_THRESH)
+  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
     {
-      const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
-                                                      increment);
-
-      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
+      if (size < CTF_LSTRUCT_THRESH)
        {
-         if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
-                                    func, arg, ctf_strptr (fp, mp->ctm_name),
-                                    offset + mp->ctm_offset,
-                                    depth + 1)) != 0)
-           return rc;
+         const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
+                                                          increment);
+
+         for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
+           {
+             if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
+                                        func, arg, ctf_strptr (fp,
+                                                               mp->ctm_name),
+                                        offset + mp->ctm_offset,
+                                        depth + 1)) != 0)
+               return rc;
+           }
        }
+      else
+       {
+         const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
+                                                             increment);
 
+         for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
+           {
+             if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
+                                        func, arg, ctf_strptr (fp,
+                                                               lmp->ctlm_name),
+                                        offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
+                                        depth + 1)) != 0)
+               return rc;
+           }
+       }
     }
   else
     {
-      const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
-                                                         increment);
+      ctf_dmdef_t *dmd;
 
-      for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
+      for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
+          dmd != NULL; dmd = ctf_list_next (dmd))
        {
-         if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
-                                    func, arg, ctf_strptr (fp,
-                                                           lmp->ctlm_name),
-                                    offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
+         if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
+                                    dmd->dmd_name, dmd->dmd_offset,
                                     depth + 1)) != 0)
            return rc;
        }
This page took 0.033125 seconds and 4 git commands to generate.