modpost: add support for generating namespace dependencies
[linux-2.6-block.git] / scripts / mod / modpost.c
index c2d49afaea1c3bbc5c9752096d9079814248a6dc..be72da25fe7caa0395fbc18209aee7a3755dd4fc 100644 (file)
@@ -38,6 +38,8 @@ static int sec_mismatch_count = 0;
 static int sec_mismatch_fatal = 0;
 /* ignore missing files */
 static int ignore_missing_files;
+/* write namespace dependencies */
+static int write_namespace_deps;
 
 enum export {
        export_plain,      export_unused,     export_gpl,
@@ -2176,10 +2178,15 @@ static int check_exports(struct module *mod)
                else
                        basename = mod->name;
 
-               if (exp->namespace &&
-                   !module_imports_namespace(mod, exp->namespace)) {
-                       warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
-                            basename, exp->name, exp->namespace);
+               if (exp->namespace) {
+                       add_namespace(&mod->required_namespaces,
+                                     exp->namespace);
+
+                       if (!write_namespace_deps &&
+                           !module_imports_namespace(mod, exp->namespace)) {
+                               warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
+                                    basename, exp->name, exp->namespace);
+                       }
                }
 
                if (!mod->gpl_compatible)
@@ -2484,6 +2491,31 @@ static void write_dump(const char *fname)
        free(buf.p);
 }
 
+static void write_namespace_deps_files(void)
+{
+       struct module *mod;
+       struct namespace_list *ns;
+       struct buffer ns_deps_buf = {};
+
+       for (mod = modules; mod; mod = mod->next) {
+               char fname[PATH_MAX];
+
+               if (mod->skip)
+                       continue;
+
+               ns_deps_buf.pos = 0;
+
+               for (ns = mod->required_namespaces; ns; ns = ns->next)
+                       buf_printf(&ns_deps_buf, "%s\n", ns->namespace);
+
+               if (ns_deps_buf.pos == 0)
+                       continue;
+
+               sprintf(fname, "%s.ns_deps", mod->name);
+               write_if_changed(&ns_deps_buf, fname);
+       }
+}
+
 struct ext_sym_list {
        struct ext_sym_list *next;
        const char *file;
@@ -2500,7 +2532,7 @@ int main(int argc, char **argv)
        struct ext_sym_list *extsym_iter;
        struct ext_sym_list *extsym_start = NULL;
 
-       while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awE")) != -1) {
+       while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awEd")) != -1) {
                switch (opt) {
                case 'i':
                        kernel_read = optarg;
@@ -2541,6 +2573,9 @@ int main(int argc, char **argv)
                case 'E':
                        sec_mismatch_fatal = 1;
                        break;
+               case 'd':
+                       write_namespace_deps = 1;
+                       break;
                default:
                        exit(1);
                }
@@ -2575,6 +2610,9 @@ int main(int argc, char **argv)
 
                err |= check_modname_len(mod);
                err |= check_exports(mod);
+               if (write_namespace_deps)
+                       continue;
+
                add_header(&buf, mod);
                add_intree_flag(&buf, !external_module);
                add_retpoline(&buf);
@@ -2587,6 +2625,12 @@ int main(int argc, char **argv)
                sprintf(fname, "%s.mod.c", mod->name);
                write_if_changed(&buf, fname);
        }
+
+       if (write_namespace_deps) {
+               write_namespace_deps_files();
+               return 0;
+       }
+
        if (dump_write)
                write_dump(dump_write);
        if (sec_mismatch_count && sec_mismatch_fatal)