diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2021-02-18 17:03:28 +0000 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2021-03-02 15:09:18 +0000 |
commit | ac36e134d96fa71a2f5c141058e06b57bcc72136 (patch) | |
tree | e6647d27d24de83a812c7960384abec8a9dcec41 /libctf | |
parent | eaa2913a7acead8654e7e79ba13c0d22fd70a452 (diff) | |
download | binutils-ac36e134d96fa71a2f5c141058e06b57bcc72136.zip binutils-ac36e134d96fa71a2f5c141058e06b57bcc72136.tar.gz binutils-ac36e134d96fa71a2f5c141058e06b57bcc72136.tar.bz2 |
libctf: reimplement many _iter iterators in terms of _next
Ever since the generator-style _next iterators were introduced, there
have been separate implementations of the functional-style _iter
iterators that do the same thing as _next.
This is annoying and adds more dependencies on the internal guts of the
file format. Rip them all out and replace them with the corresponding
_next iterators. Only ctf_archive_raw_iter and ctf_label_iter survive,
the former because there is no access to the raw binary data of archives
via any _next iterator, and the latter because ctf_label_next hasn't
been implemented (because labels are currently not used for anything).
Tested by reverting the change (already applied) that reimplemented
ctf_member_iter in terms of ctf_member_next, then verifying that the
_iter and _next iterators produced the same results for every iterable
entity within a large type archive.
libctf/ChangeLog
2021-03-02 Nick Alcock <nick.alcock@oracle.com>
* ctf-types.c (ctf_member_iter): Move 'rc' to an inner scope.
(ctf_enum_iter): Reimplement in terms of ctf_enum_next.
(ctf_type_iter): Reimplement in terms of ctf_type_next.
(ctf_type_iter_all): Likewise.
(ctf_variable_iter): Reimplement in terms of ctf_variable_next.
* ctf-archive.c (ctf_archive_iter_internal): Remove.
(ctf_archive_iter): Reimplement in terms of ctf_archive_next.
Diffstat (limited to 'libctf')
-rw-r--r-- | libctf/ChangeLog | 10 | ||||
-rw-r--r-- | libctf/ctf-archive.c | 68 | ||||
-rw-r--r-- | libctf/ctf-types.c | 115 |
3 files changed, 69 insertions, 124 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog index db44cae..c639fdd 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,5 +1,15 @@ 2021-03-02 Nick Alcock <nick.alcock@oracle.com> + * ctf-types.c (ctf_member_iter): Move 'rc' to an inner scope. + (ctf_enum_iter): Reimplement in terms of ctf_enum_next. + (ctf_type_iter): Reimplement in terms of ctf_type_next. + (ctf_type_iter_all): Likewise. + (ctf_variable_iter): Reimplement in terms of ctf_variable_next. + * ctf-archive.c (ctf_archive_iter_internal): Remove. + (ctf_archive_iter): Reimplement in terms of ctf_archive_next. + +2021-03-02 Nick Alcock <nick.alcock@oracle.com> + * ctf-archive.c (ctf_archive_next): Set the name of parents in single-member archives. diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c index 6e1bf15..8b8e170 100644 --- a/libctf/ctf-archive.c +++ b/libctf/ctf-archive.c @@ -1043,70 +1043,32 @@ ctf_archive_raw_iter (const ctf_archive_t *arc, 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. diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index 57a284d..28c5c7a 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -45,10 +45,10 @@ ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg) 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); @@ -255,47 +255,21 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, 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; } @@ -424,16 +398,20 @@ ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, 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; } @@ -448,17 +426,21 @@ ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg) 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; } @@ -518,30 +500,21 @@ ctf_type_next (ctf_dict_t *fp, ctf_next_t **it, int *flag, int want_hidden) 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; } |