From af17c59be610765e38551abdb9a8292c2eb42df1 Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Thu, 2 Feb 2017 00:23:16 +0000 Subject: [PATCH] ctf: fix the size of int and avoid duplicating it An upcoming bitfield-capable release of libdtrace-ctf adds extra consistency checking which identified embarrassing but heretofore harmless bugs in dwarf2ctf's representation of basic types. dwarf2ctf has to emit a few basic types "by hand", since these are used in the representation of types one of CTF or DWARF does not bother to encode more complex forms for (function pointers, always encoded as 'int (*)()' in CTF, and 'void'). Embarrassingly, we were getting the size of 'int' wrong: it should be in bits but we were emitting a count of bytes instead, leading to a CTF representation of a 4-bit int. This is always overridden by an accurate representation built into DTrace in real use, but libdtrace-ctf finds the inconsistency anyway. Worse is that it emits a representation of 'int' twice, once by hand in init_ctf_table() and then again when it comes across the real 'int' type DIE in the debuginfo. This is because we forgot to intern the types we add by hand in the id_to_module and id_to_type hashes we use to detect duplicate types, because we can only intern types we have a DWARF DIE for, and these types either have no DIE at all or we just don't know about it because we haven't even begun to traverse the debuginfo to look up DIEs yet. Fix this by adding a mark_shared_by_name() function which can be used to intern basic types by name in these hashes. It has hardwired knowledge of the type ID notation, but no more such knowledge than is already present in detect_duplicates_alias_fixup() and friends (no more than that types with no associated filename or line number are preceded by "////".) Orabug: 25815129 Signed-off-by: Nick Alcock Reviewed-by: tomas.jedlicka@oracle.com --- scripts/dwarf2ctf/dwarf2ctf.c | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/scripts/dwarf2ctf/dwarf2ctf.c b/scripts/dwarf2ctf/dwarf2ctf.c index 9745a5daefd0..0d0f955a7d50 100644 --- a/scripts/dwarf2ctf/dwarf2ctf.c +++ b/scripts/dwarf2ctf/dwarf2ctf.c @@ -363,6 +363,13 @@ static void detect_duplicates_alias_fixup(const char *module_name, static void detect_duplicates_alias_fixup_internal(Dwarf_Die *die, const char *id, void *data); +/* + * Mark a basic type shared by name and intern it in all relevant hashes. (Used + * for marking basic types we don't have a DIE for.) + */ +static void mark_shared_by_name(ctf_file_t *ctf, ctf_id_t ctf_id, + const char *name); + /* * Determine if a type is a named struct, union, or enum. * @@ -1236,7 +1243,7 @@ static ctf_file_t *init_ctf_table(const char *module_name) (builtin_modules == NULL)) { ctf_encoding_t void_encoding = { CTF_INT_SIGNED, 0, 0 }; ctf_encoding_t int_encoding = { CTF_INT_SIGNED, 0, - sizeof (int) }; + sizeof (int) * 8 }; ctf_id_t int_type; ctf_id_t func_type; ctf_funcinfo_t func_info; @@ -1251,6 +1258,8 @@ static ctf_file_t *init_ctf_table(const char *module_name) "void", &void_encoding); int_type = ctf_add_integer(ctf_file, CTF_ADD_ROOT, "int", &int_encoding); + mark_shared_by_name(ctf_file, ctf_void_type, "void"); + mark_shared_by_name(ctf_file, int_type, "int"); func_info.ctc_return = int_type; func_info.ctc_argc = 0; @@ -2245,6 +2254,33 @@ static void detect_duplicates_alias_fixup_internal(Dwarf_Die *die, free(opaque_id); } +/* + * Mark a basic type shared by name and intern it in all relevant hashes. (Used + * for marking basic types we don't have a DIE for.) + */ +static void mark_shared_by_name(ctf_file_t *ctf, ctf_id_t ctf_id, + const char *name) +{ + ctf_full_id_t static_ctf_id = { ctf, ctf_id }; + ctf_full_id_t *full_ctf_id; + char *id = NULL; + + full_ctf_id = malloc(sizeof (struct ctf_full_id)); + if (full_ctf_id == NULL) { + fprintf(stderr, "%s: out of memory\n", __func__); + exit(1); + } + *full_ctf_id = static_ctf_id; + + id = str_appendn(id, "////", name, " ", NULL); +#ifdef DEBUG + strcpy(full_ctf_id->module_name, "shared_ctf"); + strcpy(full_ctf_id->file_name, ""); +#endif + g_hash_table_replace(id_to_module, id, xstrdup("shared_ctf")); + g_hash_table_replace(id_to_type, xstrdup(id), full_ctf_id); +} + /* * Type assembly. * -- 2.50.1