From: Nick Alcock Date: Thu, 24 Apr 2025 15:55:20 +0000 (+0100) Subject: libctf: types: ctf_type_resolve_nonrepresentable X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a4312b684ad779c5c14e0838adc868cc6b14847;p=thirdparty%2Fbinutils-gdb.git libctf: types: ctf_type_resolve_nonrepresentable This new internal function allows us to say "resolve a type to its base type, but treat type 0 like BTF, returning 0 if it is found rather than erroring with ECTF_NONREPRESENTABLE". Used in the next commit. --- diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index 25617f50b04..c9d1c8cf8ba 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -811,6 +811,7 @@ extern char *ctf_str_append (char *, const char *); extern char *ctf_str_append_noerr (char *, const char *); extern ctf_id_t ctf_type_resolve_unsliced (ctf_dict_t *, ctf_id_t); +extern ctf_id_t ctf_type_resolve_nonrepresentable (ctf_dict_t *, ctf_id_t, int allow_zero); extern int ctf_type_kind_unsliced (ctf_dict_t *, ctf_id_t); extern ssize_t ctf_type_align_natural (ctf_dict_t *fp, ctf_id_t prev_type, ctf_id_t type, ssize_t bit_offset); diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index 6a714ceb850..ddc9f8c98a5 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -677,31 +677,45 @@ ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name) ctf_id_t ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type) +{ + return ctf_type_resolve_nonrepresentable (fp, type, 0); +} + +/* As with ctf_type_resolve(), but optionally do not consider type 0 + to be ECTF_NONREPRESENTABLE. Internal only. */ +ctf_id_t +ctf_type_resolve_nonrepresentable (ctf_dict_t *fp, ctf_id_t type, int allow_zero) { ctf_id_t prev = type, otype = type; ctf_dict_t *ofp = fp; - const ctf_type_t *tp; + const ctf_type_t *tp, *suffix; if (type == 0) - return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE)); + { + if (allow_zero) + return 0; + else + return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE)); + } - while ((tp = ctf_lookup_by_id (&fp, type)) != NULL) + while ((tp = ctf_lookup_by_id (&fp, type, &suffix)) != NULL) { - switch (LCTF_INFO_KIND (fp, tp->ctt_info)) + switch (LCTF_KIND (fp, tp)) { case CTF_K_TYPEDEF: case CTF_K_VOLATILE: case CTF_K_CONST: case CTF_K_RESTRICT: - if (tp->ctt_type == type || tp->ctt_type == otype - || tp->ctt_type == prev) + case CTF_K_VAR: + if (suffix->ctt_type == type || suffix->ctt_type == otype + || suffix->ctt_type == prev) { ctf_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"), otype); return (ctf_set_typed_errno (ofp, ECTF_CORRUPT)); } prev = type; - type = tp->ctt_type; + type = suffix->ctt_type; break; case CTF_K_UNKNOWN: return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE)); @@ -709,7 +723,12 @@ ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type) return type; } if (type == 0) - return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE)); + { + if (allow_zero) + return 0; + else + return (ctf_set_typed_errno (ofp, ECTF_NONREPRESENTABLE)); + } } return CTF_ERR; /* errno is set for us. */ @@ -728,7 +747,7 @@ ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type) if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) return CTF_ERR; - if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) + if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL) return CTF_ERR; /* errno is set for us. */ resolved_type = type; @@ -736,17 +755,17 @@ ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type) { type = resolved_type; - if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE) + if ((LCTF_KIND (fp, tp)) == CTF_K_SLICE) if ((type = ctf_type_reference (fp, type)) == CTF_ERR) return (ctf_set_typed_errno (ofp, ctf_errno (fp))); if ((resolved_type = ctf_type_resolve (fp, type)) == CTF_ERR) return CTF_ERR; - if ((tp = ctf_lookup_by_id (&fp, resolved_type)) == NULL) + if ((tp = ctf_lookup_by_id (&fp, resolved_type, NULL)) == NULL) return CTF_ERR; /* errno is set for us. */ } - while (LCTF_INFO_KIND (fp, tp->ctt_info) == CTF_K_SLICE); + while (LCTF_KIND (fp, tp) == CTF_K_SLICE); return type; }