libctf: drop LCTF_TYPE_ISPARENT/LCTF_TYPE_ISCHILD

Parent/child determination is about to become rather more complex, making a
macro impractical.  Use the ctf_type_isparent/ischild function calls
everywhere and remove the macro.  Make them more const-correct too, to
make them more widely usable.

While we're about it, change several places that hand-implemented
ctf_get_dict() to call it instead, and armour several functions against
the null returns that were always possible in this case (but previously
unprotected-against).
This commit is contained in:
Nick Alcock
2025-01-29 12:30:58 +00:00
parent 9835747b21
commit b875301e74
7 changed files with 51 additions and 46 deletions

View File

@@ -473,8 +473,8 @@ extern void ctf_dict_close (ctf_dict_t *);
extern const char *ctf_cuname (ctf_dict_t *); extern const char *ctf_cuname (ctf_dict_t *);
extern ctf_dict_t *ctf_parent_dict (ctf_dict_t *); extern ctf_dict_t *ctf_parent_dict (ctf_dict_t *);
extern const char *ctf_parent_name (ctf_dict_t *); extern const char *ctf_parent_name (ctf_dict_t *);
extern int ctf_type_isparent (ctf_dict_t *, ctf_id_t); extern int ctf_type_isparent (const ctf_dict_t *, ctf_id_t);
extern int ctf_type_ischild (ctf_dict_t *, ctf_id_t); extern int ctf_type_ischild (const ctf_dict_t *, ctf_id_t);
extern int ctf_import (ctf_dict_t *, ctf_dict_t *); extern int ctf_import (ctf_dict_t *, ctf_dict_t *);
/* Set these names (used when creating dicts). */ /* Set these names (used when creating dicts). */

View File

@@ -272,22 +272,20 @@ ctf_dtd_delete (ctf_dict_t *fp, ctf_dtdef_t *dtd)
ctf_dtdef_t * ctf_dtdef_t *
ctf_dtd_lookup (const ctf_dict_t *fp, ctf_id_t type) ctf_dtd_lookup (const ctf_dict_t *fp, ctf_id_t type)
{ {
if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type)) fp = ctf_get_dict (fp, type);
fp = fp->ctf_parent;
return (ctf_dtdef_t *) return (ctf_dtdef_t *)
ctf_dynhash_lookup (fp->ctf_dthash, (void *) (uintptr_t) type); ctf_dynhash_lookup (fp->ctf_dthash, (void *) (uintptr_t) type);
} }
ctf_dtdef_t * ctf_dtdef_t *
ctf_dynamic_type (const ctf_dict_t *fp, ctf_id_t id) ctf_dynamic_type (const ctf_dict_t *fp, ctf_id_t type)
{ {
ctf_id_t idx; ctf_id_t idx;
if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id)) fp = ctf_get_dict (fp, type);
fp = fp->ctf_parent;
idx = LCTF_TYPE_TO_INDEX(fp, id); idx = LCTF_TYPE_TO_INDEX(fp, type);
if ((unsigned long) idx <= fp->ctf_typemax) if ((unsigned long) idx <= fp->ctf_typemax)
return ctf_dtd_lookup (fp, id); return ctf_dtd_lookup (fp, id);
@@ -295,14 +293,13 @@ ctf_dynamic_type (const ctf_dict_t *fp, ctf_id_t id)
} }
static int static int
ctf_static_type (const ctf_dict_t *fp, ctf_id_t id) ctf_static_type (const ctf_dict_t *fp, ctf_id_t type)
{ {
ctf_id_t idx; ctf_id_t idx;
if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, id)) fp = ctf_get_dict (fp, type);
fp = fp->ctf_parent;
idx = LCTF_TYPE_TO_INDEX(fp, id); idx = LCTF_TYPE_TO_INDEX(fp, type);
return ((unsigned long) idx <= fp->ctf_stypes); return ((unsigned long) idx <= fp->ctf_stypes);
} }
@@ -581,7 +578,7 @@ ctf_add_reftype (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type); uint32_t type_idx = LCTF_TYPE_TO_INDEX (fp, type);
uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref); uint32_t ref_idx = LCTF_TYPE_TO_INDEX (fp, ref);
if (LCTF_TYPE_ISCHILD (fp, ref) == child if (ctf_type_ischild (fp, ref) == child
&& ref_idx < fp->ctf_typemax) && ref_idx < fp->ctf_typemax)
fp->ctf_ptrtab[ref_idx] = type_idx; fp->ctf_ptrtab[ref_idx] = type_idx;
@@ -711,8 +708,7 @@ ctf_set_array (ctf_dict_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type); ctf_dtdef_t *dtd = ctf_dtd_lookup (fp, type);
ctf_array_t *vlen; ctf_array_t *vlen;
if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type)) fp = ctf_get_dict (fp, type);
fp = fp->ctf_parent;
/* You can only call ctf_set_array on a type you have added, not a /* You can only call ctf_set_array on a type you have added, not a
type that was read in via ctf_open(). */ type that was read in via ctf_open(). */
@@ -1075,8 +1071,7 @@ ctf_add_enumerator (ctf_dict_t *fp, ctf_id_t enid, const char *name,
if (name == NULL) if (name == NULL)
return (ctf_set_errno (fp, EINVAL)); return (ctf_set_errno (fp, EINVAL));
if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, enid)) fp = ctf_get_dict (fp, enid);
fp = fp->ctf_parent;
if (enid < fp->ctf_stypes) if (enid < fp->ctf_stypes)
return (ctf_set_errno (ofp, ECTF_RDONLY)); return (ctf_set_errno (ofp, ECTF_RDONLY));
@@ -1172,12 +1167,12 @@ ctf_add_member_offset (ctf_dict_t *fp, ctf_id_t souid, const char *name,
if (fp->ctf_flags & LCTF_NO_STR) if (fp->ctf_flags & LCTF_NO_STR)
return (ctf_set_errno (fp, ECTF_NOPARENT)); return (ctf_set_errno (fp, ECTF_NOPARENT));
if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, souid)) if ((fp->ctf_flags & LCTF_CHILD) && ctf_type_isparent (fp, souid))
{ {
/* Adding a child type to a parent, even via the child, is prohibited. /* Adding a child type to a parent, even via the child, is prohibited.
Otherwise, climb to the parent and do all work there. */ Otherwise, climb to the parent and do all work there. */
if (LCTF_TYPE_ISCHILD (fp, type)) if (ctf_type_ischild (fp, type))
return (ctf_set_errno (ofp, ECTF_BADID)); return (ctf_set_errno (ofp, ECTF_BADID));
fp = fp->ctf_parent; fp = fp->ctf_parent;
@@ -1587,14 +1582,15 @@ static void
ctf_add_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type, ctf_add_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type,
ctf_dict_t *dst_fp, ctf_id_t dst_type) ctf_dict_t *dst_fp, ctf_id_t dst_type)
{ {
if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent) src_fp = ctf_get_dict (src_fp, src_type);
src_fp = src_fp->ctf_parent; dst_fp = ctf_get_dict (dst_fp, dst_type);
/* Not imported? No mapping is meaningful. */
if (src_fp == NULL || dst_fp == NULL)
return;
src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type); src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
if (LCTF_TYPE_ISPARENT (dst_fp, dst_type) && dst_fp->ctf_parent)
dst_fp = dst_fp->ctf_parent;
dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type); dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type);
if (dst_fp->ctf_link_type_mapping == NULL) if (dst_fp->ctf_link_type_mapping == NULL)
@@ -1631,8 +1627,11 @@ ctf_type_mapping (ctf_dict_t *src_fp, ctf_id_t src_type, ctf_dict_t **dst_fp)
ctf_dict_t *target_fp = *dst_fp; ctf_dict_t *target_fp = *dst_fp;
ctf_id_t dst_type = 0; ctf_id_t dst_type = 0;
if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent) src_fp = ctf_get_dict (src_fp, src_type);
src_fp = src_fp->ctf_parent;
/* No mapping is possible if the parent is not imported. */
if (src_fp == NULL)
return 0;
src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type); src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
key.cltk_fp = src_fp; key.cltk_fp = src_fp;
@@ -2098,7 +2097,9 @@ ctf_add_type (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type)
{ {
ctf_id_t id; ctf_id_t id;
if ((src_fp->ctf_flags & LCTF_NO_STR) || (dst_fp->ctf_flags & LCTF_NO_STR)) if ((src_fp->ctf_flags & LCTF_NO_STR) || (dst_fp->ctf_flags & LCTF_NO_STR)
|| ((src_fp->ctf_flags & LCTF_CHILD) && (src_fp->ctf_parent == NULL))
|| ((dst_fp->ctf_flags & LCTF_CHILD) && (dst_fp->ctf_parent == NULL)))
return (ctf_set_errno (dst_fp, ECTF_NOPARENT)); return (ctf_set_errno (dst_fp, ECTF_NOPARENT));
if (!src_fp->ctf_add_processing) if (!src_fp->ctf_add_processing)

View File

@@ -2087,7 +2087,7 @@ ctf_dedup_rwalk_one_output_mapping (ctf_dict_t *output,
const char *hashval; \ const char *hashval; \
int cited_type_input_num = input_num; \ int cited_type_input_num = input_num; \
\ \
if ((fp->ctf_flags & LCTF_CHILD) && (LCTF_TYPE_ISPARENT (fp, type))) \ if ((fp->ctf_flags & LCTF_CHILD) && (ctf_type_isparent (fp, type))) \
cited_type_input_num = parents[input_num]; \ cited_type_input_num = parents[input_num]; \
\ \
type_id = CTF_DEDUP_GID (output, cited_type_input_num, type); \ type_id = CTF_DEDUP_GID (output, cited_type_input_num, type); \
@@ -2549,7 +2549,7 @@ ctf_dedup_id_to_target (ctf_dict_t *output, ctf_dict_t *target,
/* If the input type is in the parent type space, and this is a child, reset /* If the input type is in the parent type space, and this is a child, reset
the input to the parent (which must already have been emitted, since the input to the parent (which must already have been emitted, since
emission of parent dicts happens before children). */ emission of parent dicts happens before children). */
if ((input->ctf_flags & LCTF_CHILD) && (LCTF_TYPE_ISPARENT (input, id))) if ((input->ctf_flags & LCTF_CHILD) && (ctf_type_isparent (input, id)))
{ {
if (!ctf_assert (output, parents[input_num] <= ninputs)) if (!ctf_assert (output, parents[input_num] <= ninputs))
return CTF_ERR; return CTF_ERR;

View File

@@ -587,8 +587,6 @@ struct ctf_next
/* * If an offs is not aligned already then round it up and align it. */ /* * If an offs is not aligned already then round it up and align it. */
#define LCTF_ALIGN_OFFS(offs, align) ((offs + (align - 1)) & ~(align - 1)) #define LCTF_ALIGN_OFFS(offs, align) ((offs + (align - 1)) & ~(align - 1))
#define LCTF_TYPE_ISPARENT(fp, id) ((id) <= fp->ctf_parmax)
#define LCTF_TYPE_ISCHILD(fp, id) ((id) > fp->ctf_parmax)
#define LCTF_TYPE_TO_INDEX(fp, id) ((id) & (fp->ctf_parmax)) #define LCTF_TYPE_TO_INDEX(fp, id) ((id) & (fp->ctf_parmax))
#define LCTF_INDEX_TO_TYPE(fp, id, child) (child ? ((id) | (fp->ctf_parmax+1)) : \ #define LCTF_INDEX_TO_TYPE(fp, id, child) (child ? ((id) | (fp->ctf_parmax+1)) : \
(id)) (id))
@@ -627,7 +625,7 @@ extern int ctf_symtab_skippable (ctf_link_sym_t *sym);
extern int ctf_add_funcobjt_sym (ctf_dict_t *, int is_function, extern int ctf_add_funcobjt_sym (ctf_dict_t *, int is_function,
const char *, ctf_id_t); const char *, ctf_id_t);
extern ctf_dict_t *ctf_get_dict (ctf_dict_t *fp, ctf_id_t type); extern ctf_dict_t *ctf_get_dict (const ctf_dict_t *fp, ctf_id_t type);
typedef unsigned int (*ctf_hash_fun) (const void *ptr); typedef unsigned int (*ctf_hash_fun) (const void *ptr);
extern unsigned int ctf_hash_integer (const void *ptr); extern unsigned int ctf_hash_integer (const void *ptr);

View File

@@ -57,7 +57,7 @@ refresh_pptrtab (ctf_dict_t *fp, ctf_dict_t *pfp)
reffed_type = ctf_type_reference (fp, type); reffed_type = ctf_type_reference (fp, type);
if (LCTF_TYPE_ISPARENT (fp, reffed_type)) if (ctf_type_isparent (fp, reffed_type))
{ {
uint32_t idx = LCTF_TYPE_TO_INDEX (fp, reffed_type); uint32_t idx = LCTF_TYPE_TO_INDEX (fp, reffed_type);

View File

@@ -1084,7 +1084,7 @@ init_static_types_names_internal (ctf_dict_t *fp, ctf_header_t *cth,
store the index of the pointer type in fp->ctf_ptrtab[ index of store the index of the pointer type in fp->ctf_ptrtab[ index of
referenced type ]. */ referenced type ]. */
if (LCTF_TYPE_ISCHILD (fp, tp->ctt_type) == child if (ctf_type_ischild (fp, tp->ctt_type) == child
&& LCTF_TYPE_TO_INDEX (fp, tp->ctt_type) <= fp->ctf_typemax) && LCTF_TYPE_TO_INDEX (fp, tp->ctt_type) <= fp->ctf_typemax)
fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, tp->ctt_type)] = id; fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, tp->ctt_type)] = id;
/*FALLTHRU*/ /*FALLTHRU*/

View File

@@ -24,15 +24,15 @@
/* Determine whether a type is a parent or a child. */ /* Determine whether a type is a parent or a child. */
int int
ctf_type_isparent (ctf_dict_t *fp, ctf_id_t id) ctf_type_isparent (const ctf_dict_t *fp, ctf_id_t id)
{ {
return (LCTF_TYPE_ISPARENT (fp, id)); return (id <= fp->ctf_parmax);
} }
int int
ctf_type_ischild (ctf_dict_t * fp, ctf_id_t id) ctf_type_ischild (const ctf_dict_t *fp, ctf_id_t id)
{ {
return (LCTF_TYPE_ISCHILD (fp, id)); return (!ctf_type_isparent (fp, id));
} }
/* Expand a structure element into the passed-in ctf_lmember_t. */ /* Expand a structure element into the passed-in ctf_lmember_t. */
@@ -628,12 +628,12 @@ ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
type is in the parent, return the parent. Needed if you plan to access type is in the parent, return the parent. Needed if you plan to access
the type directly, without using the API. */ the type directly, without using the API. */
ctf_dict_t * ctf_dict_t *
ctf_get_dict (ctf_dict_t *fp, ctf_id_t type) ctf_get_dict (const ctf_dict_t *fp, ctf_id_t type)
{ {
if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type)) if ((fp->ctf_flags & LCTF_CHILD) && ctf_type_isparent (fp, type))
return fp->ctf_parent; return fp->ctf_parent;
return fp; return (ctf_dict_t *) fp;
} }
/* Look up a name in the given name table, in the appropriate hash given the /* Look up a name in the given name table, in the appropriate hash given the
@@ -1261,11 +1261,11 @@ ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
if (lfp == rfp) if (lfp == rfp)
return rval; return rval;
if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL) if (lfp->ctf_parent != NULL)
lfp = lfp->ctf_parent; lfp = ctf_get_dict (lfp, ltype);
if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL) if (rfp->ctf_parent != NULL)
rfp = rfp->ctf_parent; rfp = ctf_get_dict (rfp, rtype);
if (lfp < rfp) if (lfp < rfp)
return -1; return -1;
@@ -1298,6 +1298,12 @@ ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
if (rfp->ctf_flags & LCTF_NO_STR) if (rfp->ctf_flags & LCTF_NO_STR)
return (ctf_set_errno (rfp, ECTF_NOPARENT)); return (ctf_set_errno (rfp, ECTF_NOPARENT));
if (ctf_type_isparent (lfp, ltype) && !lfp->ctf_parent)
return (ctf_set_errno (rfp, ECTF_NOPARENT));
if (ctf_type_isparent (rfp, rtype) && !rfp->ctf_parent)
return (ctf_set_errno (rfp, ECTF_NOPARENT));
if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0) if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
return 1; return 1;