return -EINVAL; /* Not supported. */
}
-/* Iterate over all CTF files in an archive. We pass all CTF files in turn to
- the specified callback function. */
-static int
-ctf_archive_iter_internal (const ctf_archive_t *wrapper,
- const struct ctf_archive *arc,
- const ctf_sect_t *symsect,
- const ctf_sect_t *strsect,
- ctf_archive_member_f *func, void *data)
+/* Iterate over all CTF files in an archive: public entry point. We pass all
+ CTF files in turn to the specified callback function. */
+int
+ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
+ void *data)
{
- int rc;
- size_t i;
- ctf_dict_t *f;
- struct ctf_archive_modent *modent;
- const char *nametbl;
-
- modent = (ctf_archive_modent_t *) ((char *) arc
- + sizeof (struct ctf_archive));
- nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));
+ ctf_next_t *i = NULL;
+ ctf_dict_t *fp;
+ const char *name;
+ int err;
- for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
+ while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
{
- const char *name;
+ int rc;
- name = &nametbl[le64toh (modent[i].name_offset)];
- if ((f = ctf_dict_open_internal (arc, symsect, strsect,
- name,
- wrapper->ctfi_symsect_little_endian,
- &rc)) == NULL)
- return rc;
-
- f->ctf_archive = (ctf_archive_t *) wrapper;
- ctf_arc_import_parent (wrapper, f);
- if ((rc = func (f, name, data)) != 0)
+ if ((rc = func (fp, name, data)) != 0)
{
- ctf_dict_close (f);
+ ctf_dict_close (fp);
+ ctf_next_destroy (i);
return rc;
}
-
- ctf_dict_close (f);
+ ctf_dict_close (fp);
}
return 0;
}
-/* Iterate over all CTF files in an archive: public entry point. We pass all
- CTF files in turn to the specified callback function. */
-int
-ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
- void *data)
-{
- const ctf_sect_t *symsect = &arc->ctfi_symsect;
- const ctf_sect_t *strsect = &arc->ctfi_strsect;
-
- if (symsect->cts_name == NULL)
- symsect = NULL;
- if (strsect->cts_name == NULL)
- strsect = NULL;
-
- if (arc->ctfi_is_archive)
- return ctf_archive_iter_internal (arc, arc->ctfi_archive, symsect, strsect,
- func, data);
-
- return func (arc->ctfi_dict, _CTF_SECTION, data);
-}
-
/* Iterate over all CTF files in an archive, returning each dict in turn as a
ctf_dict_t, and NULL on error or end of iteration. It is the caller's
responsibility to close it. Parent dicts may be skipped.
ssize_t offset;
const char *name;
ctf_id_t membtype;
- int rc;
while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, 0)) >= 0)
{
+ int rc;
if ((rc = func (name, membtype, offset, arg)) != 0)
{
ctf_next_destroy (i);
int
ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
{
- ctf_dict_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 -1; /* errno is set for us. */
-
- if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
- 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);
+ ctf_next_t *i = NULL;
+ const char *name;
+ int val;
- if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
+ while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL)
{
- ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
-
- for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
+ int rc;
+ if ((rc = func (name, val, arg)) != 0)
{
- const char *name = ctf_strptr (fp, ep->cte_name);
- if ((rc = func (name, ep->cte_value, arg)) != 0)
- return rc;
- }
- }
- else
- {
- 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;
+ ctf_next_destroy (i);
+ return rc;
}
}
+ if (ctf_errno (fp) != ECTF_NEXT_END)
+ return -1; /* errno is set for us. */
return 0;
}
int
ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg)
{
- ctf_id_t id, max = fp->ctf_typemax;
- int rc, child = (fp->ctf_flags & LCTF_CHILD);
+ ctf_next_t *i = NULL;
+ ctf_id_t type;
- for (id = 1; id <= max; id++)
+ while ((type = ctf_type_next (fp, &i, NULL, 0)) != CTF_ERR)
{
- const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
- if (LCTF_INFO_ISROOT (fp, tp->ctt_info)
- && (rc = func (LCTF_INDEX_TO_TYPE (fp, id, child), arg)) != 0)
- return rc;
+ int rc;
+ if ((rc = func (type, arg)) != 0)
+ {
+ ctf_next_destroy (i);
+ return rc;
+ }
}
+ if (ctf_errno (fp) != ECTF_NEXT_END)
+ return -1; /* errno is set for us. */
return 0;
}
int
ctf_type_iter_all (ctf_dict_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);
+ ctf_next_t *i = NULL;
+ ctf_id_t type;
+ int flag;
- for (id = 1; id <= max; id++)
+ while ((type = ctf_type_next (fp, &i, &flag, 1)) != CTF_ERR)
{
- 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;
+ int rc;
+ if ((rc = func (type, flag, arg)) != 0)
+ {
+ ctf_next_destroy (i);
+ return rc;
+ }
}
+ if (ctf_errno (fp) != ECTF_NEXT_END)
+ return -1; /* errno is set for us. */
return 0;
}
int
ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg)
{
- int rc;
-
- if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
- return (ctf_set_errno (fp, ECTF_NOPARENT));
+ ctf_next_t *i = NULL;
+ ctf_id_t type;
+ const char *name;
- if (!(fp->ctf_flags & LCTF_RDWR))
+ while ((type = ctf_variable_next (fp, &i, &name)) != CTF_ERR)
{
- 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))
+ int rc;
+ if ((rc = func (name, type, arg)) != 0)
{
- if ((rc = func (dvd->dvd_name, dvd->dvd_type, arg)) != 0)
- return rc;
+ ctf_next_destroy (i);
+ return rc;
}
}
+ if (ctf_errno (fp) != ECTF_NEXT_END)
+ return -1; /* errno is set for us. */
return 0;
}