struct module *module;
        unsigned int crc;
        int crc_valid;
+       const char *namespace;
        unsigned int weak:1;
        unsigned int vmlinux:1;    /* 1 if symbol is defined in vmlinux */
        unsigned int kernel:1;     /* 1 if symbol is from kernel
        return NULL;
 }
 
+static bool contains_namespace(struct namespace_list *list,
+                              const char *namespace)
+{
+       struct namespace_list *ns_entry;
+
+       for (ns_entry = list; ns_entry != NULL; ns_entry = ns_entry->next)
+               if (strcmp(ns_entry->namespace, namespace) == 0)
+                       return true;
+
+       return false;
+}
+
+static void add_namespace(struct namespace_list **list, const char *namespace)
+{
+       struct namespace_list *ns_entry;
+
+       if (!contains_namespace(*list, namespace)) {
+               ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) +
+                                        strlen(namespace) + 1));
+               strcpy(ns_entry->namespace, namespace);
+               ns_entry->next = *list;
+               *list = ns_entry;
+       }
+}
+
+static bool module_imports_namespace(struct module *module,
+                                    const char *namespace)
+{
+       return contains_namespace(module->imported_namespaces, namespace);
+}
+
 static const struct {
        const char *str;
        enum export export;
                return export_unknown;
 }
 
+static const char *sym_extract_namespace(const char **symname)
+{
+       size_t n;
+       char *dupsymname;
+
+       n = strcspn(*symname, ".");
+       if (n < strlen(*symname) - 1) {
+               dupsymname = NOFAIL(strdup(*symname));
+               dupsymname[n] = '\0';
+               *symname = dupsymname;
+               return dupsymname + n + 1;
+       }
+
+       return NULL;
+}
+
 /**
  * Add an exported symbol - it may have already been added without a
  * CRC, in this case just update the CRC
  **/
-static struct symbol *sym_add_exported(const char *name, struct module *mod,
-                                      enum export export)
+static struct symbol *sym_add_exported(const char *name, const char *namespace,
+                                      struct module *mod, enum export export)
 {
        struct symbol *s = find_symbol(name);
 
        if (!s) {
                s = new_symbol(name, mod, export);
+               s->namespace = namespace;
        } else {
                if (!s->preloaded) {
-                       warn("%s: '%s' exported twice. Previous export "
-                            "was in %s%s\n", mod->name, name,
-                            s->module->name,
-                            is_vmlinux(s->module->name) ?"":".ko");
+                       warn("%s: '%s' exported twice. Previous export was in %s%s\n",
+                            mod->name, name, s->module->name,
+                            is_vmlinux(s->module->name) ? "" : ".ko");
                } else {
                        /* In case Module.symvers was out of date */
                        s->module = mod;
        unsigned int crc;
        enum export export;
        bool is_crc = false;
+       const char *name, *namespace;
 
        if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
            strstarts(symname, "__ksymtab"))
        default:
                /* All exported symbols */
                if (strstarts(symname, "__ksymtab_")) {
-                       sym_add_exported(symname + strlen("__ksymtab_"), mod,
-                                       export);
+                       name = symname + strlen("__ksymtab_");
+                       namespace = sym_extract_namespace(&name);
+                       sym_add_exported(name, namespace, mod, export);
                }
                if (strcmp(symname, "init_module") == 0)
                        mod->has_init = 1;
        const char *symname;
        char *version;
        char *license;
+       char *namespace;
        struct module *mod;
        struct elf_info info = { };
        Elf_Sym *sym;
                license = get_next_modinfo(&info, "license", license);
        }
 
+       namespace = get_modinfo(&info, "import_ns");
+       while (namespace) {
+               add_namespace(&mod->imported_namespaces, namespace);
+               namespace = get_next_modinfo(&info, "import_ns", namespace);
+       }
+
        for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
                symname = remove_dot(info.strtab + sym->st_name);
 
                        basename++;
                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 (!mod->gpl_compatible)
                        check_for_gpl_usage(exp->export, basename, exp->name);
                check_for_unused(exp->export, basename, exp->name);
                return;
 
        while ((line = get_next_line(&pos, file, size))) {
-               char *symname, *modname, *d, *export, *end;
+               char *symname, *namespace, *modname, *d, *export, *end;
                unsigned int crc;
                struct module *mod;
                struct symbol *s;
                if (!(symname = strchr(line, '\t')))
                        goto fail;
                *symname++ = '\0';
-               if (!(modname = strchr(symname, '\t')))
+               if (!(namespace = strchr(symname, '\t')))
+                       goto fail;
+               *namespace++ = '\0';
+               if (!(modname = strchr(namespace, '\t')))
                        goto fail;
                *modname++ = '\0';
                if ((export = strchr(modname, '\t')) != NULL)
                        mod = new_module(modname);
                        mod->skip = 1;
                }
-               s = sym_add_exported(symname, mod, export_no(export));
+               s = sym_add_exported(symname, namespace, mod,
+                                    export_no(export));
                s->kernel    = kernel;
                s->preloaded = 1;
                sym_update_crc(symname, mod, crc, export_no(export));
 {
        struct buffer buf = { };
        struct symbol *symbol;
+       const char *namespace;
        int n;
 
        for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
                symbol = symbolhash[n];
                while (symbol) {
-                       if (dump_sym(symbol))
-                               buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n",
-                                       symbol->crc, symbol->name,
-                                       symbol->module->name,
-                                       export_str(symbol->export));
+                       if (dump_sym(symbol)) {
+                               namespace = symbol->namespace;
+                               buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n",
+                                          symbol->crc, symbol->name,
+                                          namespace ? namespace : "",
+                                          symbol->module->name,
+                                          export_str(symbol->export));
+                       }
                        symbol = symbol->next;
                }
        }