forked from Imagelibrary/binutils-gdb
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:
@@ -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). */
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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*/
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user