]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ctf: duplicate-detect dependent types properly
authorNick Alcock <nick.alcock@oracle.com>
Mon, 15 Dec 2014 19:08:01 +0000 (19:08 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Tue, 21 Jul 2015 14:29:55 +0000 (15:29 +0100)
dwarf2ctf's duplicate-detection machinery takes care to spot and mark members of
structures reliably, but does not take quite the same care with dependent types.

Code such as that in drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c:

struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
                                     void (*fn)(struct brcms_phy *pi),
                                     void *arg, const char *name);

where no definition of struct brcms_phy is already in scope, produces this
DWARF for the "fn" pointer:

 [ b0426]    subroutine_type
             prototyped           (flag)
             sibling              (ref4) [ b0438]
 [ b042c]      formal_parameter
               type                 (ref4) [ b0438]
 [ b0431]      structure_type
               name                 (strp) "brcms_phy"
               declaration          (flag)
 [ b043e]    pointer_type
             byte_size            (data1) 8
             type                 (ref4) [ b0426]

The pointer is marked as seen, since it is at the top level, but the
structure_type, because it is inside a subroutine_type, does not.  Type emission
then recurses through dependent types and crashes horribly.

The fix is to recurse through dependent types (via a type_id() callback) when
marking things as seen.

Unfortunately this slows down dwarf2ctf quite a lot: speedups are next on the
agenda.

Orabug: 20229431

Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
Acked-by: Kris Van Hees <kris.van.hees@oracle.com>
scripts/dwarf2ctf/dwarf2ctf.c

index 27d1451159a2aa1182c44f388a4ac60272aa05ed..d10a4e493bb996cf2e295ea8805e8dd5eb387941 100644 (file)
@@ -282,6 +282,14 @@ static void detect_duplicates(const char *module_name, const char *file_name,
                              Dwarf_Die *die, Dwarf_Die *parent_die,
                              void *data);
 
+/*
+ * Detect duplicates and mark seen types for a given type, via a type_id()
+ * callback: used to detect dependent types (particularly those at child-DIE
+ * level) as duplicates.
+ */
+static void detect_duplicates_typeid(Dwarf_Die *die, const char *id,
+                                    void *data);
+
 /*
  * Mark any aggregates contained within a particular type DIE as seen.  This is
  * needed since even nameless aggregates contained within other aggregates can
@@ -1792,7 +1800,7 @@ static void detect_duplicates(const char *module_name,
                    (dwarf_whatform(&type_attr) == DW_FORM_ref_sig8)) {
                        fprintf(stderr, "sorry, not yet implemented: %s "
                                "contains DWARF-4 debugging information.\n",
-                               file_name);
+                               module_name);
                        exit(1);
                }
        }
@@ -1835,12 +1843,27 @@ static void detect_duplicates(const char *module_name,
        }
 
        /*
-        * Record that we have seen this type in this module.
+        * Record that we have seen this type, and all its dependent types, in
+        * this module (or in the shared module if need be).
         */
 
        dw_ctf_trace("Marking %s as seen in %s\n", id, module_name);
        g_hash_table_replace(id_to_module, id, xstrdup(module_name));
        mark_seen_contained(die, module_name);
+       free(type_id(die, detect_duplicates_typeid, data));
+}
+
+/*
+ * Detect duplicates and mark seen types for a given type, via a type_id()
+ * callback: used to detect dependent types (particularly those at child-DIE
+ * level) as duplicates.
+ */
+static void detect_duplicates_typeid(Dwarf_Die *die, const char *id,
+                                    void *data)
+{
+       struct detect_duplicates_state *state = data;
+
+       detect_duplicates(state->module_name, NULL, die, NULL, data);
 }
 
 /*