]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ctf: fix the size of int and avoid duplicating it
authorNick Alcock <nick.alcock@oracle.com>
Thu, 2 Feb 2017 00:23:16 +0000 (00:23 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 26 May 2017 00:06:06 +0000 (01:06 +0100)
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 <nick.alcock@oracle.com>
Reviewed-by: tomas.jedlicka@oracle.com
scripts/dwarf2ctf/dwarf2ctf.c

index 9745a5daefd0773877376acf7125afbf647259ef..0d0f955a7d50e92fa9989e29215b3538489811f5 100644 (file)
@@ -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, "<built-in type>");
+#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.
  *