From 9c4c2387c1506a2cdd76f06b1955da8d740c795c Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Tue, 7 Aug 2012 09:46:38 +0100 Subject: [PATCH] ctf: blacklist certain modules from deduplication sound/pci/ens1371.c #includes another file, ens1370.c, with a #define that changes the definition, but not name, of a single structure. While this grotesquerie is permitted in C, there's no way that translation units that engage in it can be permitted to share types with other translation units. More specifically, types defined in such TUs must not be permitted to transform a non-shared type to shared by virtue of their being detected in such TUs. I'd like to detect the redefined structures themselves, but since the preprocessor trickery leaves no mark in the DWARF another pass would be necessary just to detect this. It's easier -- and faster -- to introduce a blacklist of modules that do things like this and simply turn deduplication scanning off for these modules. (Because they are still allowed to reuse duplicates found in other modules, this does not increase their size appreciably.) Signed-off-by: Nick Alcock --- scripts/Makefile.modpost | 2 +- scripts/dwarf2ctf/dedup.blacklist | 1 + scripts/dwarf2ctf/dwarf2ctf.c | 87 +++++++++++++++++++++++++++++-- 3 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 scripts/dwarf2ctf/dedup.blacklist diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 4056968961a3a..cd6da8c7a663c 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -140,7 +140,7 @@ ifndef CONFIG_DT_DISABLE_CTF ifeq ($(KBUILD_EXTMOD),) quiet_cmd_ctf = DWARF2CTF - cmd_ctf = scripts/dwarf2ctf/dwarf2ctf objects.builtin modules.builtin $^ + cmd_ctf = scripts/dwarf2ctf/dwarf2ctf objects.builtin modules.builtin scripts/dwarf2ctf/dedup.blacklist $^ builtins := $(shell cat objects.builtin 2>/dev/null) ctf-stamp := .ctf/dtrace-ctf.stamp diff --git a/scripts/dwarf2ctf/dedup.blacklist b/scripts/dwarf2ctf/dedup.blacklist new file mode 100644 index 0000000000000..ddb1f0be4792c --- /dev/null +++ b/scripts/dwarf2ctf/dedup.blacklist @@ -0,0 +1 @@ +snd-ens1371 diff --git a/scripts/dwarf2ctf/dwarf2ctf.c b/scripts/dwarf2ctf/dwarf2ctf.c index c54702f561582..2464b02496d56 100644 --- a/scripts/dwarf2ctf/dwarf2ctf.c +++ b/scripts/dwarf2ctf/dwarf2ctf.c @@ -128,6 +128,25 @@ static size_t builtin_objects_cnt; static void init_builtin(const char *builtin_objects_file, const char *builtin_module_file); +/* + * The deduplication blacklist bans specific modules that do notably insane + * things with the preprocessor from participating in deduplication. The list + * of sins is short: things like #including two different source files that + * proceed to add or remove members from structures depending on which source + * file they were included from. + * + * These modules still share types with the rest of the kernel, but types that + * only they share with other modules will not be shared for that reason alone. + * + * This is, of course, only used if deduplication is turned on. + */ +static GHashTable *dedup_blacklist; + +/* + * Populate the deduplication blacklist from the dedup_blacklist file. + */ +static void init_blacklist(const char *dedup_blacklist_file); + /* * A mapping from translation unit name to the name of the module that * translation unit is part of. Module names have no trailing suffix. @@ -592,8 +611,6 @@ static void private_ctf_free(void *ctf_file); int main(int argc, char *argv[]) { - char *builtin_objects_file; - char *builtin_module_file; int starting_argv = 2; trace = getenv("DWARF2CTF_TRACE"); @@ -623,10 +640,16 @@ int main(int argc, char *argv[]) * independently invoked with every argument. */ if (strcmp(argv[1], "-e") != 0) { + char *builtin_objects_file; + char *builtin_module_file; + char *dedup_blacklist_file; + builtin_objects_file = argv[1]; builtin_module_file = argv[2]; - starting_argv = 3; + dedup_blacklist_file = argv[3]; + starting_argv = 4; init_builtin(builtin_objects_file, builtin_module_file); + init_blacklist(dedup_blacklist_file); run(starting_argv, argv); } else { @@ -843,6 +866,45 @@ static void init_assembly_tab(void) } } +/* + * Populate the deduplication blacklist from the dedup_blacklist file. + */ +static void init_blacklist(const char *dedup_blacklist_file) +{ + FILE *f; + char *line = NULL; + size_t line_size = 0; + + /* + * Not having a deduplication blacklist is not an error. + */ + if ((f = fopen(dedup_blacklist_file, "r")) == NULL) + return; + + dedup_blacklist = g_hash_table_new(g_str_hash, g_str_equal); + + while (getline(&line, &line_size, f) >= 0) { + size_t len = strlen(line); + + if (len == 0) + continue; + + if (line[len-1] == '\n') + line[len-1] = '\0'; + + + g_hash_table_insert(dedup_blacklist, strdup(line), NULL); + } + + if (ferror(f)) { + fprintf(stderr, "Error reading from %s: %s\n", + dedup_blacklist_file, strerror(errno)); + exit(1); + } + + fclose(f); +} + /* * Initialize a CTF type table, and possibly fill it with those special types * that appear in CTF but not in DWARF (such as 'void'). (This filling happens @@ -1516,6 +1578,9 @@ static void detect_duplicates(const char *module_name, * (This means that duplicated types are repeatedly so marked: this * is unavoidable, because pass 3 requires re-marking structures that * have already been marked, to pick up unmarked intermediate types.) + * + * We never consider types in modules on the deduplication blacklist + * to introduce duplicates. */ const char *existing_type_module; @@ -1523,7 +1588,10 @@ static void detect_duplicates(const char *module_name, if (existing_type_module != NULL) { if ((strcmp(existing_type_module, module_name) != 0) && - (builtin_modules != NULL)) { + (builtin_modules != NULL) && + (dedup_blacklist == NULL || + !g_hash_table_lookup_extended(dedup_blacklist, module_name, + NULL, NULL))) { mark_shared(die, NULL, data); mark_seen_contained(die, "dtrace_ctf"); } @@ -1722,6 +1790,15 @@ static void detect_duplicates_alias_fixup(const char *module_name, { int is_sou = 0; + /* + * We skip this for all modules in the deduplication blacklist, if there + * is one. + */ + if (dedup_blacklist != NULL && + g_hash_table_lookup_extended(dedup_blacklist, module_name, + NULL, NULL)) + return; + /* * We only do anything for structures and unions that are not opaque, * and that have names. @@ -2749,7 +2826,7 @@ static ctf_id_t assemble_ctf_su_member(const char *module_name, "dtrace_ctf"))) { fprintf(stderr, "%s:%s: internal error: referenced type lookup " "for member %s yields a different CTF file: %p versus " - "%p", locerrstr, dwarf_diename(&cu_die), + "%p\n", locerrstr, dwarf_diename(&cu_die), dwarf_diename(die), ctf, new_type->ctf_file); fprintf(stderr, "detect_duplicates() is probably buggy.\n"); exit(1); -- 2.50.1