]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ctf: blacklist certain modules from deduplication
authorNick Alcock <nick.alcock@oracle.com>
Tue, 7 Aug 2012 08:46:38 +0000 (09:46 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Mon, 29 Jun 2015 21:40:29 +0000 (22:40 +0100)
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 <nick.alcock@oracle.com>
scripts/Makefile.modpost
scripts/dwarf2ctf/dedup.blacklist [new file with mode: 0644]
scripts/dwarf2ctf/dwarf2ctf.c

index 4056968961a3a120a1a32da645bc78cac157fefb..cd6da8c7a663c0bace418467993b7ad389eb29fa 100644 (file)
@@ -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 (file)
index 0000000..ddb1f0b
--- /dev/null
@@ -0,0 +1 @@
+snd-ens1371
index c54702f56158258ddab7a866ed7276c85c5846a5..2464b02496d562601721db06503a4756113cd0ee 100644 (file)
@@ -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);