libctf: types: recursive type visiting

ctf_type_visit and ctf_type_rvisit have to adapt to the internal
API changes, but also to the change in the representation of
structures.  The new code is quite a lot simpler than the old,
because we don't need to roll our own iterator but can just use
ctf_member_next.

API changes, the usual for the *_f typedefs and anything to do with
structures:

-typedef int ctf_visit_f (const char *name, ctf_id_t type, unsigned long offset,
-			 int depth, void *arg);
+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);
This commit is contained in:
Nick Alcock
2025-04-25 11:44:19 +01:00
parent 1ece8c93c0
commit 33326f571f
2 changed files with 16 additions and 39 deletions

View File

@@ -2623,16 +2623,16 @@ ctf_id_t ctf_variable_datasec (ctf_dict_t *fp, ctf_id_t var)
static int
ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
void *arg, const char *name, unsigned long offset, int depth)
void *arg, const char *name, unsigned long offset,
int bit_width, int depth)
{
ctf_dict_t *ofp = fp;
ctf_id_t otype = type;
const ctf_type_t *tp = NULL;
const ctf_dtdef_t *dtd;
unsigned char *vlen;
ssize_t size, increment, vbytes;
uint32_t kind, n, i = 0;
int nonrepresentable = 0;
uint32_t kind;
ctf_next_t *it = NULL;
ctf_id_t membtype;
ssize_t this_offset;
int this_bit_width;
int rc;
if (fp->ctf_flags & LCTF_NO_STR)
@@ -2645,43 +2645,20 @@ ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
nonrepresentable = 1;
}
if (!nonrepresentable)
if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
return -1; /* errno is set for us. */
if ((rc = func (name, otype, offset, depth, arg)) != 0)
if ((rc = func (fp, name, otype, offset, bit_width, depth, arg)) != 0)
return rc;
if (!nonrepresentable)
kind = LCTF_INFO_KIND (fp, tp->ctt_info);
kind = ctf_type_kind (fp, type);
if (nonrepresentable || (kind != CTF_K_STRUCT && kind != CTF_K_UNION))
return 0;
ctf_get_ctt_size (fp, tp, &size, &increment);
n = LCTF_INFO_VLEN (fp, tp->ctt_info);
if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
while ((this_offset = ctf_member_next (fp, type, &it, &name, &membtype,
&this_bit_width, 0)) >= 0)
{
vlen = dtd->dtd_vlen;
vbytes = dtd->dtd_vlen_alloc;
}
else
{
vlen = (unsigned char *) tp + increment;
vbytes = LCTF_VBYTES (fp, kind, size, n);
}
for (; n != 0; n--, i++)
{
ctf_lmember_t memb;
if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
return (ctf_set_errno (ofp, ctf_errno (fp)));
if ((rc = ctf_type_rvisit (fp, memb.ctlm_type,
func, arg, ctf_strptr (fp, memb.ctlm_name),
offset + (unsigned long) CTF_LMEM_OFFSET (&memb),
if ((rc = ctf_type_rvisit (fp, membtype, func, arg, name,
offset + this_offset, this_bit_width,
depth + 1)) != 0)
return rc;
}
@@ -2694,5 +2671,5 @@ ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
int
ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
{
return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0, 0));
}