aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ChangeLog6
-rw-r--r--include/ctf-api.h1
-rw-r--r--include/ctf.h3
-rw-r--r--libctf/ChangeLog15
-rw-r--r--libctf/NEWS3
-rw-r--r--libctf/ctf-create.c33
-rw-r--r--libctf/ctf-dedup.c14
-rw-r--r--libctf/ctf-open.c4
-rw-r--r--libctf/ctf-types.c9
-rw-r--r--libctf/libctf.ver1
10 files changed, 78 insertions, 11 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index 0f277f9..aed37fd 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,9 @@
+2021-05-06 Nick Alcock <nick.alcock@oracle.com>
+
+ * ctf.h (CTF_K_UNKNOWN): Document that it can be used for
+ nonrepresentable types, not just padding.
+ * ctf-api.h (ctf_add_unknown): New.
+
2021-04-22 Clément Chigot <clement.chigot@atos.net>
* coff/internal.h (union internal_auxent):
diff --git a/include/ctf-api.h b/include/ctf-api.h
index 25dbe9e..fa8f2cd 100644
--- a/include/ctf-api.h
+++ b/include/ctf-api.h
@@ -491,6 +491,7 @@ extern ctf_id_t ctf_add_struct_sized (ctf_dict_t *, uint32_t, const char *,
size_t);
extern ctf_id_t ctf_add_union_sized (ctf_dict_t *, uint32_t, const char *,
size_t);
+extern ctf_id_t ctf_add_unknown (ctf_dict_t *, uint32_t, const char *);
extern ctf_id_t ctf_add_volatile (ctf_dict_t *, uint32_t, ctf_id_t);
extern int ctf_add_enumerator (ctf_dict_t *, ctf_id_t, const char *, int);
diff --git a/include/ctf.h b/include/ctf.h
index 90631fc..fa31c46 100644
--- a/include/ctf.h
+++ b/include/ctf.h
@@ -405,7 +405,8 @@ union
CTF_INFO_VLEN() will extract the number of elements in the list, and
the type of each element is shown in the comments below. */
-#define CTF_K_UNKNOWN 0 /* Unknown type (used for padding). */
+#define CTF_K_UNKNOWN 0 /* Unknown type (used for padding and
+ unrepresentable types). */
#define CTF_K_INTEGER 1 /* Variant data is CTF_INT_DATA (see below). */
#define CTF_K_FLOAT 2 /* Variant data is CTF_FP_DATA (see below). */
#define CTF_K_POINTER 3 /* ctt_type is referenced type. */
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;