/* Local function prototypes */
-static int ctf_add_type_cb (ctf_dict_t *fp, ctf_id_t tid, void *arg);
+static void ctf_add_type_cb (ctf_dict_t *fp, ctf_id_t tid,
+ struct ctf_context *ccp);
static struct type *read_array_type (struct ctf_context *cp, ctf_id_t tid);
and ARG contains the ctf_field_info. */
static int
-ctf_add_member_cb (ctf_dict_t *unused,
+ctf_add_member_cb (ctf_dict_t *dict,
const char *name,
ctf_id_t tid,
unsigned long offset,
fp = &new_field.field;
fp->set_name (name);
- kind = ctf_type_kind (ccp->dict, tid);
+ kind = ctf_type_kind (dict, tid);
t = fetch_tid_type (ccp, tid);
if (t == nullptr)
{
t = read_type_record (ccp, tid);
if (t == nullptr)
{
- complaint (_("ctf_add_member_cb: %s has NO type (%ld)"), name, tid);
+ complaint (_("ctf_add_member_cb: %s has no type (%ld)"), name, tid);
t = builtin_type (ccp->of)->builtin_error;
set_tid_type (ccp->of, tid, t);
}
/* Callback to add member NAME of EVAL to an enumeration type.
ARG contains the ctf_field_info. */
-static int
-ctf_add_enum_member_cb (const char *name, int64_t enum_value, void *arg)
+static void
+ctf_add_enum_member_cb (const char *name, int64_t enum_value, ctf_field_info *fip)
{
- struct ctf_field_info *fip = (struct ctf_field_info *) arg;
struct ctf_nextfield new_field;
struct field *fp;
struct ctf_context *ccp = fip->cur_context;
}
fip->fields.emplace_back (new_field);
-
- return 0;
}
/* Add a new type symbol entry, with its name from TID, its access
struct type *type)
{
struct ctf_field_info fi;
+ ctf_next_t *it = NULL;
+ const char *membname;
+ ctf_id_t membtype;
+ ssize_t offset;
+ int bit_width;
fi.cur_context = ccp;
- if (ctf_member_iter (ccp->dict, tid, ctf_add_member_cb, &fi) == CTF_ERR)
- complaint (_("ctf_member_iter process_struct_members failed - %s"),
+ while ((offset = ctf_member_next (ccp->dict, tid, &it, &membname, &membtype,
+ &bit_width, 0)) >= 0)
+ {
+ if (ctf_add_member_cb (ccp->dict, membname, membtype, offset, bit_width,
+ &fi) < 0)
+ complaint (_("ctf_add_member_cb process_struct_members failed - %s"),
+ ctf_errmsg (ctf_errno (ccp->dict)));
+ }
+ if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
+ complaint (_("process_struct_members iteration over members failed - %s"),
ctf_errmsg (ctf_errno (ccp->dict)));
/* Attach fields to the type. */
{
struct type *type;
struct ctf_field_info fi;
+ ctf_next_t *it = NULL;
+ const char *name;
+ int64_t value;
type = read_enum_type (ccp, tid);
fi.cur_context = ccp;
fi.ptype = type;
- if (ctf_enum_iter (ccp->dict, tid, ctf_add_enum_member_cb, &fi) == CTF_ERR)
- complaint (_("ctf_enum_iter process_enum_type failed - %s"),
+ while ((name = ctf_enum_next (ccp->dict, tid, &it, &value)) != NULL)
+ ctf_add_enum_member_cb (name, value, &fi);
+
+ if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
+ complaint (_("ctf_enum_next process_enum_type failed - %s"),
ctf_errmsg (ctf_errno (ccp->dict)));
/* Attach fields to the type. */
/* Callback to add type TID to the symbol table. */
-static int
-ctf_add_type_cb (ctf_dict_t *fp, ctf_id_t tid, void *arg)
+static void
+ctf_add_type_cb (ctf_dict_t *fp, ctf_id_t tid, struct ctf_context *ccp)
{
- struct ctf_context *ccp = (struct ctf_context *) arg;
struct type *type;
uint32_t kind;
/* Check if tid's type has already been defined. */
type = get_tid_type (ccp->of, tid);
if (type != nullptr)
- return 0;
+ return;
ctf_id_t btid = ctf_type_reference (ccp->dict, tid);
kind = ctf_type_kind (ccp->dict, tid);
default:
break;
}
-
- return 0;
}
/* Callback to add variable NAME with TID to the symbol table. */
-static int
-ctf_add_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id, void *arg)
+static void
+ctf_add_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id,
+ struct ctf_context *ccp)
{
- struct ctf_context *ccp = (struct ctf_context *) arg;
struct symbol *sym = nullptr;
struct type *type;
uint32_t kind;
add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
set_symbol_address (ccp->of, sym, name);
-
- return 0;
}
/* Add entries in either data objects or function info section, controlled
ctf_psymtab::expand_psymtab (struct objfile *objfile)
{
struct ctf_context *ccp;
+ ctf_next_t *it = NULL;
+ ctf_id_t type;
+ const char *name;
gdb_assert (!readin);
ccp = &context;
/* Iterate over entries in data types section. */
- if (ctf_type_iter (ccp->dict, ctf_add_type_cb, ccp) == CTF_ERR)
- complaint (_("ctf_type_iter psymtab_to_symtab failed - %s"),
- ctf_errmsg (ctf_errno (ccp->dict)));
+ while ((type = ctf_type_next (ccp->dict, &it, NULL, 0)) != CTF_ERR)
+ ctf_add_type_cb (ccp->dict, type, ccp);
+ if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
+ complaint (_("ctf_type_next psymtab_to_symtab failed - %s"),
+ ctf_errmsg (ctf_errno (ccp->dict)));
/* Iterate over entries in variable info section. */
- if (ctf_variable_iter (ccp->dict, ctf_add_var_cb, ccp) == CTF_ERR)
- complaint (_("ctf_variable_iter psymtab_to_symtab failed - %s"),
+ while ((type = ctf_variable_next (ccp->dict, &it, &name)) != CTF_ERR)
+ ctf_add_var_cb (ccp->dict, name, type, ccp);
+
+ if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
+ complaint (_("ctf_variable_next psymtab_to_symtab failed - %s"),
ctf_errmsg (ctf_errno (ccp->dict)));
/* Add entries in data objects and function info sections. */
/* Callback to add type TID to partial symbol table. */
-static int
-ctf_psymtab_type_cb (ctf_dict_t *fp, ctf_id_t tid, void *arg)
+static void
+ctf_psymtab_type_cb (ctf_dict_t *fp, ctf_id_t tid, struct ctf_context *ccp)
{
- struct ctf_context *ccp;
uint32_t kind;
int section = -1;
- ccp = (struct ctf_context *) arg;
-
domain_enum domain = UNDEF_DOMAIN;
location_class loc_class = LOC_UNDEF;
kind = ctf_type_kind (ccp->dict, tid);
loc_class = LOC_TYPEDEF;
break;
case CTF_K_UNKNOWN:
- return 0;
+ return;
}
const char *name = ctf_type_name_raw (ccp->dict, tid);
if (name == nullptr || *name == '\0')
- return 0;
+ return;
ccp->pst->add_psymbol (name, false,
domain, loc_class, section,
psymbol_placement::GLOBAL,
unrelocated_addr (0),
language_c, ccp->partial_symtabs, ccp->of);
-
- return 0;
}
/* Callback to add variable NAME with ID to partial symbol table. */
-static int
-ctf_psymtab_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id, void *arg)
+static void
+ctf_psymtab_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id,
+ struct ctf_context *ccp)
{
- struct ctf_context *ccp = (struct ctf_context *) arg;
-
uint32_t kind = ctf_type_kind (ccp->dict, id);
+
ccp->pst->add_psymbol (name, true,
kind == CTF_K_FUNCTION
? FUNCTION_DOMAIN
psymbol_placement::GLOBAL,
unrelocated_addr (0),
language_c, ccp->partial_symtabs, ccp->of);
- return 0;
}
/* Setup partial_symtab's describing each source file for which
{
struct objfile *of = tup->of;
bool isparent = false;
+ ctf_next_t *it = NULL;
+ ctf_id_t type;
+ const char *name;
if (strcmp (fname, ".ctf") == 0)
{
if (isparent == false)
ccx->pst = pst;
- if (ctf_type_iter (dict, ctf_psymtab_type_cb, ccx) == CTF_ERR)
- complaint (_("ctf_type_iter scan_partial_symbols failed - %s"),
+ while ((type = ctf_type_next (dict, &it, NULL, 0)) != CTF_ERR)
+ ctf_psymtab_type_cb (dict, type, ccx);
+
+ if (ctf_errno (dict) != ECTF_NEXT_END)
+ complaint (_("ctf_type_next scan_partial_symbols failed - %s"),
ctf_errmsg (ctf_errno (dict)));
- if (ctf_variable_iter (dict, ctf_psymtab_var_cb, ccx) == CTF_ERR)
- complaint (_("ctf_variable_iter scan_partial_symbols failed - %s"),
+ while ((type = ctf_variable_next (dict, &it, &name)) != CTF_ERR)
+ ctf_psymtab_var_cb (dict, name, type, ccx);
+
+ if (ctf_errno (dict) != ECTF_NEXT_END)
+ complaint (_("ctf_variable_next scan_partial_symbols failed - %s"),
ctf_errmsg (ctf_errno (dict)));
/* Scan CTF object and function sections which correspond to each
/* Callback to build the psymtab for archive member NAME. */
-static int
-build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
+static void
+build_ctf_archive_member (ctf_dict_t *ctf, const char *name,
+ struct ctf_per_tu_data *tup)
{
- struct ctf_per_tu_data *tup = (struct ctf_per_tu_data *) arg;
ctf_dict_t *parent = tup->dict;
if (strcmp (name, ".ctf") != 0)
psymtab_storage *pss = tup->psf->get_partial_symtabs ().get ();
scan_partial_symbols (ctf, pss, tup, name);
-
- return 0;
}
/* Read CTF debugging information from a BFD section. This is
{
struct ctf_per_tu_data pcu;
bfd *abfd = of->obfd.get ();
+ ctf_next_t *it = NULL;
+ ctf_dict_t *ctf;
+ const char *name;
ctf_error_t err;
ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
of->qf.emplace_front (psf);
pcu.psf = psf;
- if (ctf_archive_iter (arc, build_ctf_archive_member, &pcu) < 0)
- error (_("ctf_archive_iter failed in input file %s: - %s"),
+ while ((ctf = ctf_archive_next (arc, &it, &name, 0, &err)) != NULL)
+ {
+ build_ctf_archive_member (ctf, name, &pcu);
+ ctf_dict_close (ctf);
+ }
+ if (err != ECTF_NEXT_END)
+ error (_("ctf_archive_next failed in input file %s: - %s"),
bfd_get_filename (abfd), ctf_errmsg (err));
}
typedef int ctf_visit_f (ctf_dict_t *, const char *name, ctf_id_t type,
size_t offset, int bit_width, int depth,
void *arg);
-typedef int ctf_member_f (ctf_dict_t *, const char *name, ctf_id_t membtype,
- size_t offset, int bit_width, void *arg);
-typedef int ctf_enum_f (const char *name, int64_t val, void *arg);
-typedef int ctf_unsigned_enum_f (const char *name, uint64_t val, void *arg);
-typedef int ctf_variable_f (ctf_dict_t *, const char *name, ctf_id_t type,
- void *arg);
-typedef int ctf_datasec_var_f (ctf_dict_t *fp, ctf_id_t type, size_t offset,
- size_t datasec_size, void *arg);
-typedef int ctf_type_f (ctf_dict_t *, ctf_id_t type, void *arg);
-typedef int ctf_type_all_f (ctf_dict_t *, ctf_id_t type, int flag, void *arg);
-typedef int ctf_type_kind_f (ctf_dict_t *, ctf_id_t type, int kind, void *arg);
-typedef int ctf_archive_member_f (ctf_dict_t *fp, const char *name, void *arg);
typedef int ctf_archive_raw_member_f (const char *name, const void *content,
size_t len, void *arg);
typedef char *ctf_dump_decorate_f (ctf_sect_names_t sect,
the members of unnamed structs nested within this struct as if they were
direct members, if CTF_MN_RECURSE is passed in the flags. */
-extern int ctf_member_iter (ctf_dict_t *, ctf_id_t, ctf_member_f *, void *);
extern ssize_t ctf_member_next (ctf_dict_t *, ctf_id_t, ctf_next_t **,
const char **name, ctf_id_t *membtype,
int *bit_width, int flags);
-/* Return all enumeration constants in a given enum type. The return value, and
- VAL argument, may need to be cast to uint64_t: see ctf_enum_unsigned(). */
-extern int64_t ctf_enum_iter (ctf_dict_t *, ctf_id_t, ctf_enum_f *, void *);
+/* Return all enumeration constants in a given enum type. The VAL argument may
+ need to be cast to uint64_t: see ctf_enum_unsigned(). */
extern const char *ctf_enum_next (ctf_dict_t *, ctf_id_t, ctf_next_t **,
int64_t *);
ctf_next_t **, int64_t *enum_value,
ctf_dict_t **dict, ctf_error_t *errp);
-/* Iterate over all types in a dict. ctf_type_iter_all recurses over all types:
- ctf_type_iter recurses only over types with user-visible names (for which
- CTF_ADD_ROOT was passed). All such types are returned, even if they are
- things like pointers that intrinsically have no name: this is the only effect
- of CTF_ADD_ROOT for such types. ctf_type_next allows you to choose whether
- to see non-root types or not with the want_hidden arg: if set, the flag (if
- passed) returns the non-root state of each type in turn. Types in parent
- dictionaries are not returned.
+/* Iterate over all types, kinds, variables, or datasecs in a dict.
+ ctf_type_next returns all types in a dict in turn, allowing you to choose
+ whether to see conflicting types or not with the want_hidden arg: if set, the
+ flag (if passed) returns the conflicting state of each type in turn. Types
+ in parent dictionaries are not returned. Note that this is the opposite of
+ the convention in the old API: a true value for the flag argument used to
+ mean it is visible; now it means it is conflicting.
These days, even variables are included in the things returned by ctf_type*()
(type kind CTF_K_VAR). */
-extern int ctf_type_iter (ctf_dict_t *, ctf_type_f *, void *);
-extern int ctf_type_iter_all (ctf_dict_t *, ctf_type_all_f *, void *);
-extern int ctf_type_kind_iter (ctf_dict_t *, int kind, ctf_type_kind_f *, void *);
extern ctf_id_t ctf_type_next (ctf_dict_t *, ctf_next_t **,
int *flag, int want_hidden);
extern ctf_id_t ctf_type_kind_next (ctf_dict_t *, ctf_next_t **, int kind);
-
-extern int ctf_variable_iter (ctf_dict_t *, ctf_variable_f *, void *);
extern ctf_id_t ctf_variable_next (ctf_dict_t *, ctf_next_t **,
const char **);
-
-extern int ctf_datasec_var_iter (ctf_dict_t *, ctf_id_t, ctf_datasec_var_f *,
- void *);
extern ctf_id_t ctf_datasec_var_next (ctf_dict_t *, ctf_id_t, ctf_next_t **,
size_t *size, size_t *offset);
/* Iterate over all tags with the given TAG, returning the ID of each tag. */
extern ctf_id_t ctf_tag_next (ctf_dict_t *, const char *tag, ctf_next_t **);
-/* ctf_archive_iter and ctf_archive_next open each member dict for you,
- automatically importing any parent dict as usual: ctf_archive_iter closes the
- dict on return from ctf_archive_member_f, but for ctf_archive_next the caller
- must close each dict returned. If skip_parent is set, the parent dict is
- skipped on the basis that it's already been seen in every child dict (but if
- no child dicts exist, this will lead to nothing being returned).
+/* ctf_archive_next opens each member dict for you, automatically importing any
+ parent dict as usual: the caller must close each dict returned once done with
+ it, though it may outlive the loop until the archive is closed; the cost of
+ opening is amortized so that repeated calls cost almost nothing. If
+ skip_parent is set, the parent dict is skipped on the basis that it's already
+ been seen in every child dict (but if no child dicts exist, this will lead to
+ nothing being returned).
- If an open fails, ctf_archive_iter returns -1 early (losing the error), but
- ctf_archive_next both passes back the error in the passed errp and allows you
- to iterate past errors (until the usual ECTF_NEXT_END is returned). */
+ If an open fails, ctf_archive_next both passes back the error in the passed
+ errp and allows you to iterate past errors (until the usual ECTF_NEXT_END is
+ returned). */
-extern int ctf_archive_iter (const ctf_archive_t *, ctf_archive_member_f *,
- void *);
extern ctf_dict_t *ctf_archive_next (const ctf_archive_t *, ctf_next_t **,
const char **, int skip_parent, ctf_error_t *errp);
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 struct ctf_archive_internal *arci,
- ctf_archive_member_f *func, void *data)
-{
- ctf_next_t *i = NULL;
- ctf_dict_t *fp;
- const char *name;
- ctf_error_t err = 0;
-
- while ((fp = ctf_archive_next (arci, &i, &name, 0, &err)) != NULL)
- {
- int rc;
-
- if ((rc = func (fp, name, data)) != 0)
- {
- ctf_dict_close (fp);
- ctf_next_destroy (i);
- return rc;
- }
- ctf_dict_close (fp);
- }
- if (err != ECTF_NEXT_END && err != 0)
- {
- ctf_next_destroy (i);
- return -1;
- }
- return 0;
-}
-
/* 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.
} ctf_bundle_t;
static int
-enumcmp (const char *name, int64_t value, void *arg)
+enumcmp (ctf_dict_t *fp, ctf_id_t type, ctf_bundle_t *ctb, ctf_dict_t *err_fp)
{
- ctf_bundle_t *ctb = arg;
+ ctf_next_t *i = NULL;
+ const char *name;
+ int64_t value;
int64_t bvalue;
- if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
+ while ((name = ctf_enum_next (fp, type, &i, &value)) != NULL)
{
- ctf_err_warn (ctb->ctb_dict, 0, 0,
- _("conflict due to enum %s iteration error"), name);
- return 1;
+ if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
+ {
+ ctf_next_destroy (i);
+ ctf_err_warn (err_fp, 0, ctf_errno (ctb->ctb_dict),
+ _("conflict due to enum %s iteration error"), name);
+ return 1;
+ }
+ if (value != bvalue)
+ {
+ ctf_next_destroy (i);
+ ctf_err_warn (err_fp, 1, ECTF_CONFLICT,
+ _("conflict due to enum value change: %li versus %li"),
+ value, bvalue);
+ return 1;
+ }
}
- if (value != bvalue)
+ if (ctf_errno (fp) != ECTF_NEXT_END)
{
- ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
- _("conflict due to enum value change: %li versus %li"),
- value, bvalue);
+ ctf_err_warn (err_fp, 0, ctf_errno (fp),
+ _("conflict due to enum %s iteration error"), name);
return 1;
}
- return 0;
-}
-
-static int
-enumadd (const char *name, int64_t value, void *arg)
-{
- ctf_bundle_t *ctb = arg;
- return (ctf_add_enumerator (ctb->ctb_dict, ctb->ctb_type,
- name, value) < 0);
+ return 0;
}
-static int
-membcmp (ctf_dict_t *src_fp _libctf_unused_, const char *name,
- ctf_id_t type _libctf_unused_, size_t offset, int bit_width,
- void *arg)
+static ctf_ret_t
+membcmp (const char *name, size_t offset, int bit_width, ctf_bundle_t *ctb)
{
- ctf_bundle_t *ctb = arg;
ctf_membinfo_t ctm;
/* Don't check nameless members (e.g. anonymous structs/unions) against each
ctf_err_warn (ctb->ctb_dict, 0, 0,
_("conflict due to struct member %s iteration error"),
name);
- return 1;
+ return -1;
}
if (ctm.ctm_offset != offset)
{
_("conflict due to struct member %s offset change: "
"%zx versus %zx"),
name, ctm.ctm_offset, offset);
- return 1;
+ return -1;
}
if (ctm.ctm_bit_width != bit_width)
{
_("conflict due to struct member %s bit-width change: "
"%i versus %i"),
name, ctm.ctm_bit_width, bit_width);
- return 1;
+ return -1;
}
return 0;
}
return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
}
- if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
+ while ((offset = ctf_member_next (src_fp, src_type, &i,
+ &membname, NULL, &bit_width, 0)) >= 0)
{
- ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
- _("conflict for type %s against ID %lx: members "
- "differ, see above"), name, dst_type);
- return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
+ if (membcmp (membname, offset, bit_width, &dst) < 0)
+ {
+ ctf_next_destroy (i);
+ ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
+ _("conflict for type %s against ID %lx: members "
+ "differ, see above"), name, dst_type);
+ return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
+ }
}
+ if (ctf_errno (src_fp) != ECTF_NEXT_END)
+ return CTF_ERR; /* errno is set for us. */
break;
}
{
if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
{
- ctf_next_destroy (i);
+ ctf_next_destroy (i); /* errno is set for us. */
break;
}
}
if (ctf_add_member_bitfield (dst_fp, dst_type, membname,
dst_membtype, offset, bit_width) < 0)
{
- ctf_next_destroy (i);
+ ctf_next_destroy (i); /* errno is set for us. */
break;
}
}
"signedness differs"), name, dst_type);
return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
}
- if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
- || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
+ if (enumcmp (src_fp, src_type, &dst, dst_fp)
+ || enumcmp (dst_fp, dst_type, &src, dst_fp))
{
ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
_("conflict for enum %s against ID %lx: members "
else
{
ctf_snapshot_id_t snap = ctf_snapshot (dst_fp);
+ ctf_next_t *it = NULL;
+ const char *enum_name;
+ int64_t value;
if (src_type == CTF_K_ENUM)
dst_type = ctf_add_enum (dst_fp, flag, name);
else
dst_type = ctf_add_enum64 (dst_fp, flag, name);
- if ((dst.ctb_type = dst_type) == CTF_ERR
- || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
+ if (dst_type == CTF_ERR)
+ goto enum_err;
+
+ while ((enum_name = ctf_enum_next (src_fp, src_type,
+ &it, &value)) != NULL)
{
- ctf_rollback (dst_fp, snap);
- return CTF_ERR; /* errno is set for us */
+ if (ctf_add_enumerator (dst_fp, dst_type, enum_name, value) < 0)
+ goto enum_err;
}
+ if (ctf_errno (src_fp) != ECTF_NEXT_END)
+ {
+ ctf_set_errno (dst_fp, ctf_errno (src_fp));
+ goto enum_err;
+ }
+
+ break;
+
+ enum_err:
+ {
+ ctf_next_destroy (it);
+ ctf_rollback (dst_fp, snap);
+ return CTF_ERR; /* errno is set for us. */
+ }
}
break;
while ((type = ctf_type_kind_next (fp, &next, CTF_K_DATASEC)) != CTF_ERR)
{
+ ctf_next_t *next_var = NULL;
+ ctf_id_t var_type;
+ size_t size;
+ size_t offset;
+
/* Dump DATASEC name. */
if (asprintf (&str, "%sSection %s:\n\n", first ? "" : "\n",
first = 0;
/* Dump all variables in the datasec. */
- if (ctf_datasec_var_iter (fp, type, ctf_dump_var, state) < 0)
- goto err;
+
+ while ((var_type = ctf_datasec_var_next (fp, type, &next_var, &size,
+ &offset)) != CTF_ERR)
+ {
+ if (ctf_dump_var (fp, type, offset, size, state) < 0)
+ {
+ ctf_err_warn (fp, 1, 0, _("cannot dump var %s (%lx) in datasec %s (%lx)\n"),
+ ctf_type_name_raw (fp, var_type), var_type,
+ ctf_type_name_raw (fp, type), type);
+ goto err;
+ }
+ }
+ if (ctf_errno (fp) != ECTF_NEXT_END)
+ {
+ ctf_err_warn (fp, 1, 0, _("cannot iterate over vars in datasec %s (%lx)\n"),
+ ctf_type_name_raw (fp, type), type);
+ goto err;
+ }
}
if (ctf_errno (fp) != ECTF_NEXT_END)
{
- ctf_err_warn (fp, 1, ctf_errno (fp), _("cannot visit datasecs\n"));
+ ctf_err_warn (fp, 1, ctf_errno (fp), _("cannot iterate over datasecs\n"));
goto err;
}
/* Dump a single type into the cds_items. */
static int
-ctf_dump_type (ctf_dict_t *fp, ctf_id_t id, int flag, void *arg)
+ctf_dump_type (ctf_dict_t *fp, ctf_id_t id, int hidden,
+ ctf_dump_state_t *state)
{
char *str;
char *indent;
- ctf_dump_state_t *state = arg;
+ int flag = CTF_ADD_ROOT;
ctf_dump_membstate_t membstate = { &str, NULL };
+ if (hidden)
+ flag = CTF_ADD_NONROOT;
+
/* Indent neatly. */
if (asprintf (&indent, " %*s", type_hex_digits (id), "") < 0)
return (ctf_set_errno (fp, ENOMEM));
goto err; /* errno is set for us. */
break;
case CTF_SECT_TYPE:
- if (ctf_type_iter_all (fp, ctf_dump_type, state) < 0)
- goto err; /* errno is set for us. */
- break;
+ {
+ ctf_next_t *it = NULL;
+ ctf_id_t type;
+ int hidden;
+
+ while ((type = ctf_type_next (fp, &it, &hidden, 1)) != CTF_ERR)
+ {
+ if (ctf_dump_type (fp, type, hidden, state) < 0)
+ goto err; /* errno is set for us. */
+ }
+ if (ctf_errno (fp) != ECTF_NEXT_END)
+ goto err; /* errno is set for us. */
+ break;
+ }
case CTF_SECT_STR:
ctf_dump_str (fp, state);
break;
}
}
-/* Iterate over the members of a STRUCT or UNION. We pass the name, member
- type, and offset of each member to the specified callback function. */
-
-int
-ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
-{
- ctf_next_t *i = NULL;
- ssize_t offset;
- int bit_width;
- const char *name;
- ctf_id_t membtype;
-
- while ((offset = ctf_member_next (fp, type, &i, &name, &membtype,
- &bit_width, 0)) >= 0)
- {
- int rc;
- if ((rc = func (fp, name, membtype, offset, bit_width, arg)) != 0)
- {
- ctf_next_destroy (i);
- return rc;
- }
- }
- if (ctf_errno (fp) != ECTF_NEXT_END)
- return -1; /* errno is set for us. */
-
- return 0;
-}
-
/* Iterate over the members of a STRUCT or UNION, returning each member's
offset and optionally name and member type in turn. On end-of-iteration,
returns -1. If FLAGS is CTF_MN_RECURSE, recurse into unnamed members. */
return ctf_set_errno (ofp, ECTF_NEXT_END);
}
-/* Iterate over the members of an ENUM. We pass the string name and associated
- integer value of each enum element to the specified callback function. */
-
-int64_t
-ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
-{
- ctf_next_t *i = NULL;
- const char *name;
- int64_t val;
-
- while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL)
- {
- int rc;
- if ((rc = func (name, val, arg)) != 0)
- {
- ctf_next_destroy (i);
- return rc;
- }
- }
- if (ctf_errno (fp) != ECTF_NEXT_END)
- return -1; /* errno is set for us. */
-
- return 0;
-}
-
/* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
NULL at end of iteration or error, and optionally passing back the
enumerand's integer VALue. */
return NULL;
}
-/* Iterate over every root (user-visible) type in the given CTF dict. We pass
- the type ID of each type to the specified callback function.
-
- Does not traverse parent types: you have to do that explicitly. This is by
- design, to avoid traversing them more than once if traversing many children
- of a single parent. */
-
-int
-ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg)
-{
- ctf_next_t *i = NULL;
- ctf_id_t type;
-
- while ((type = ctf_type_next (fp, &i, NULL, 0)) != CTF_ERR)
- {
- int rc;
- if ((rc = func (fp, 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;
-}
-
-/* Iterate over every type in the given CTF dict, user-visible or not. We pass
- the type ID of each type to the specified callback function.
-
- Does not traverse parent types: you have to do that explicitly. This is by
- design, to avoid traversing them more than once if traversing many children
- of a single parent. */
-
-int
-ctf_type_iter_all (ctf_dict_t *fp, ctf_type_all_f *func, void *arg)
-{
- ctf_next_t *i = NULL;
- ctf_id_t type;
- int flag;
-
- while ((type = ctf_type_next (fp, &i, &flag, 1)) != CTF_ERR)
- {
- int rc;
- if ((rc = func (fp, 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;
-}
-
-/* Iterate over every type of the given kind in the given CTF dict.
- We pass the type ID of each type to the specified callback function.
-
- Types returned may be prefixed (but this is normally invisible): you can also
- specifically traverse prefixed types by asking for CTF_K_BIG or CTF_K_HIDDEN.
- In this case, the kind of the type returned will be different (the kind
- prefixed). Using CTF_K_BIG may have unexpected results if types have been
- added to this dict since it was opened, since types are only 'unbiggened'
- upon being written out.
-
- Does not traverse parent types: you have to do that explicitly. This is by
- design, to avoid traversing them more than once if traversing many children
- of a single parent. */
-
-int
-ctf_type_kind_iter (ctf_dict_t *fp, int kind, ctf_type_kind_f *func, void *arg)
-{
- ctf_next_t *i = NULL;
- ctf_id_t type;
-
- while ((type = ctf_type_kind_next (fp, &i, kind)) != CTF_ERR)
- {
- int rc;
- if ((rc = func (fp, type, kind, arg)) != 0)
- {
- ctf_next_destroy (i);
- return rc;
- }
- }
- if (ctf_errno (fp) != ECTF_NEXT_END)
- return -1; /* errno is set for us. */
-
- return 0;
-}
-
/* Iterate over every type in the given CTF dict, optionally including
non-user-visible types, returning each type ID and hidden flag in turn.
Returns CTF_ERR on end of iteration or error.
return ctf_set_typed_errno (fp, ECTF_NEXT_END);
}
-/* Iterate over every variable in the given CTF dict, in arbitrary order.
- We pass the name of each variable to the specified callback function. */
-
-int
-ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg)
-{
- ctf_next_t *i = NULL;
- ctf_id_t type;
- const char *name;
-
- while ((type = ctf_variable_next (fp, &i, &name)) != CTF_ERR)
- {
- int rc;
- if ((rc = func (fp, name, 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;
-}
-
/* Iterate over every variable in the given CTF dict, in arbitrary order,
returning the name and type of each variable in turn. The name argument is
not optional. Returns CTF_ERR on end of iteration or error. */
return ctf_set_typed_errno (fp, err);
}
-/* Iterate over every variable in the given DATASEC, in arbitrary order. We
- pass the type ID, datasec-recorded size (usually 0), and offset of each
- variable to the specified callback function. */
-
-int
-ctf_datasec_var_iter (ctf_dict_t *fp, ctf_id_t datasec,
- ctf_datasec_var_f *func, void *arg)
-{
- ctf_next_t *i = NULL;
- ctf_id_t type;
- size_t size, offset;
-
- while ((type = ctf_datasec_var_next (fp, datasec, &i, &size, &offset)) != CTF_ERR)
- {
- int rc;
- if ((rc = func (fp, type, offset, size, arg)) != 0)
- {
- ctf_next_destroy (i);
- return rc;
- }
- }
- if (ctf_errno (fp) != ECTF_NEXT_END)
- return -1; /* errno is set for us. */
-
- return 0;
-}
-
/* Iterate over every variable in the given CTF datasec, in arbitrary order,
returning the name and type of each variable in turn. Returns CTF_ERR on end
of iteration or error.
ctf_lookup_enumerator_next;
ctf_arc_lookup_enumerator_next;
- ctf_member_iter;
- ctf_enum_iter;
ctf_enum_next;
- ctf_type_iter;
ctf_type_next;
- ctf_type_iter_all;
- ctf_type_kind_iter;
ctf_type_kind_next;
- ctf_variable_iter;
ctf_variable_next;
- ctf_datasec_iter;
ctf_datasec_next;
ctf_tag_next;
ctf_arc_open_by_name;
ctf_arc_open_by_name_sections;
ctf_archive_count;
- ctf_archive_iter;
ctf_archive_next;
ctf_archive_raw_iter;
ctf_get_arc;
#include <stdio.h>
#include <stdlib.h>
-static int
-print_enum (const char *name, int val, void *unused)
-{
- printf ("iter test: %s has value %i\n", name, val);
- return 0;
-}
-
int
main (int argc, char *argv[])
{
if ((type = ctf_lookup_by_name (fp, "enum ie") ) == CTF_ERR)
goto err;
- if ((ctf_enum_iter (fp, type, print_enum, NULL)) < 0)
- goto ierr;
-
while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL)
{
printf ("next test: %s has value %i\n", name, val);
err:
fprintf (stderr, "Lookup failed: %s\n", ctf_errmsg (ctf_errno (fp)));
return 1;
- ierr:
- fprintf (stderr, "_iter iteration failed: %s\n", ctf_errmsg (ctf_errno (fp)));
- return 1;
nerr:
- fprintf (stderr, "_next iteration failed: %s\n", ctf_errmsg (ctf_errno (fp)));
+ fprintf (stderr, "iteration failed: %s\n", ctf_errmsg (ctf_errno (fp)));
return 1;
}