diff options
Diffstat (limited to 'libctf')
-rw-r--r-- | libctf/ChangeLog | 15 | ||||
-rw-r--r-- | libctf/NEWS | 3 | ||||
-rw-r--r-- | libctf/ctf-create.c | 33 | ||||
-rw-r--r-- | libctf/ctf-dedup.c | 14 | ||||
-rw-r--r-- | libctf/ctf-open.c | 4 | ||||
-rw-r--r-- | libctf/ctf-types.c | 9 | ||||
-rw-r--r-- | libctf/libctf.ver | 1 |
7 files changed, 69 insertions, 10 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog index e66224a..51ecc85 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,18 @@ +2021-05-06 Nick Alcock <nick.alcock@oracle.com> + + * ctf-open.c (init_types): Unknown types may have names. + * ctf-types.c (ctf_type_resolve): CTF_K_UNKNOWN is as + non-representable as type ID 0. + (ctf_type_aname): Print unknown types. + * ctf-dedup.c (ctf_dedup_hash_type): Do not early-exit for + CTF_K_UNKNOWN types: they have real hash values now. + (ctf_dedup_rwalk_one_output_mapping): Treat CTF_K_UNKNOWN types + like other types with no referents: call the callback and do not + skip them. + (ctf_dedup_emit_type): Emit via... + * ctf-create.c (ctf_add_unknown): ... this new function. + * libctf.ver (LIBCTF_1.2): Add it. + 2021-03-25 Nick Alcock <nick.alcock@oracle.com> * configure.ac: Check for dlsym, not dlopen. diff --git a/libctf/NEWS b/libctf/NEWS index c0aef3b..956cca8 100644 --- a/libctf/NEWS +++ b/libctf/NEWS @@ -10,6 +10,9 @@ Changes in 2.37: symbol number is known, like in object files and dynamic dicts created by ctf_create. +** libctf supports compilers that encode unrepresentable types via a special + kind (CTF_K_UNKNOWN) as well as via type ID 0. + * Bugfixes ** Avoid duplicating or losing types of data object symbols when diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index e87b91e..2d232d4 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -966,6 +966,39 @@ ctf_add_forward (ctf_dict_t *fp, uint32_t flag, const char *name, } ctf_id_t +ctf_add_unknown (ctf_dict_t *fp, uint32_t flag, const char *name) +{ + ctf_dtdef_t *dtd; + ctf_id_t type = 0; + + /* If a type is already defined with this name, error (if not CTF_K_UNKNOWN) + or just return it. */ + + if (name != NULL && name[0] != '\0' && flag == CTF_ADD_ROOT + && (type = ctf_lookup_by_rawname (fp, CTF_K_UNKNOWN, name))) + { + if (ctf_type_kind (fp, type) == CTF_K_UNKNOWN) + return type; + else + { + ctf_err_warn (fp, 1, ECTF_CONFLICT, + _("ctf_add_unknown: cannot add unknown type " + "named %s: type of this name already defined"), + name ? name : _("(unnamed type)")); + return (ctf_set_errno (fp, ECTF_CONFLICT)); + } + } + + if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNKNOWN, 0, &dtd)) == CTF_ERR) + return CTF_ERR; /* errno is set for us. */ + + dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNKNOWN, flag, 0); + dtd->dtd_data.ctt_type = 0; + + return type; +} + +ctf_id_t ctf_add_typedef (ctf_dict_t *fp, uint32_t flag, const char *name, ctf_id_t ref) { diff --git a/libctf/ctf-dedup.c b/libctf/ctf-dedup.c index 572a68d..649a76a 100644 --- a/libctf/ctf-dedup.c +++ b/libctf/ctf-dedup.c @@ -1064,10 +1064,6 @@ ctf_dedup_hash_type (ctf_dict_t *fp, ctf_dict_t *input, if (tp->ctt_name == 0 || !name || name[0] == '\0') name = NULL; - /* Treat the unknown kind just like the unimplemented type. */ - if (kind == CTF_K_UNKNOWN) - return "00000000000000000000"; - /* Decorate the name appropriately for the namespace it appears in: forwards appear in the namespace of their referent. */ @@ -2075,8 +2071,6 @@ ctf_dedup_rwalk_one_output_mapping (ctf_dict_t *output, switch (ctf_type_kind_unsliced (fp, type)) { case CTF_K_UNKNOWN: - /* Just skip things of unknown kind. */ - return 0; case CTF_K_FORWARD: case CTF_K_INTEGER: case CTF_K_FLOAT: @@ -2702,9 +2696,11 @@ ctf_dedup_emit_type (const char *hval, ctf_dict_t *output, ctf_dict_t **inputs, switch (kind) { case CTF_K_UNKNOWN: - /* These are types that CTF cannot encode, marked as such by the compile. - We intentionally do not re-emit these. */ - new_type = 0; + /* These are types that CTF cannot encode, marked as such by the + compiler. */ + errtype = _("unknown type"); + if ((new_type = ctf_add_unknown (target, isroot, name)) == CTF_ERR) + goto err_target; break; case CTF_K_FORWARD: /* This will do nothing if the type to which this forwards already exists, diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index 8d11134..1c69dc8 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -756,7 +756,8 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth) return ENOMEM; if ((fp->ctf_names.ctn_readonly - = ctf_hash_create (pop[CTF_K_INTEGER] + + = ctf_hash_create (pop[CTF_K_UNKNOWN] + + pop[CTF_K_INTEGER] + pop[CTF_K_FLOAT] + pop[CTF_K_FUNCTION] + pop[CTF_K_TYPEDEF] + @@ -800,6 +801,7 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth) switch (kind) { + case CTF_K_UNKNOWN: case CTF_K_INTEGER: case CTF_K_FLOAT: /* Names are reused by bit-fields, which are differentiated by their diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index 9afe06b..243de93 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -579,6 +579,8 @@ ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type) prev = type; type = tp->ctt_type; break; + case CTF_K_UNKNOWN: + return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE)); default: return type; } @@ -808,6 +810,13 @@ ctf_type_aname (ctf_dict_t *fp, ctf_id_t type) case CTF_K_RESTRICT: ctf_decl_sprintf (&cd, "restrict"); break; + case CTF_K_UNKNOWN: + if (name[0] == '\0') + ctf_decl_sprintf (&cd, _("(nonrepresentable type)")); + else + ctf_decl_sprintf (&cd, _("(nonrepresentable type %s)"), + name); + break; } k = cdp->cd_kind; diff --git a/libctf/libctf.ver b/libctf/libctf.ver index 8c362f3..0b182f3 100644 --- a/libctf/libctf.ver +++ b/libctf/libctf.ver @@ -201,4 +201,5 @@ LIBCTF_1.2 { global: ctf_lookup_by_symbol_name; ctf_arc_lookup_symbol_name; + ctf_add_unknown; } LIBCTF_1.1; |