From: Nick Alcock Date: Mon, 15 Dec 2014 19:08:01 +0000 (+0000) Subject: ctf: duplicate-detect dependent types properly X-Git-Tag: v4.1.12-92~313^2~23 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=943c00a49fc900ed8f145f8402936cdbac97a4be;p=users%2Fjedix%2Flinux-maple.git ctf: duplicate-detect dependent types properly 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 Acked-by: Kris Van Hees --- diff --git a/scripts/dwarf2ctf/dwarf2ctf.c b/scripts/dwarf2ctf/dwarf2ctf.c index 27d1451159a2a..d10a4e493bb99 100644 --- a/scripts/dwarf2ctf/dwarf2ctf.c +++ b/scripts/dwarf2ctf/dwarf2ctf.c @@ -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); } /*