@@ -268,13 +268,28 @@ static struct symbol *find_symbol(const char *name)
struct namespace_list {
struct list_head list;
+ bool used;
char namespace[];
};
+static struct namespace_list *find_namespace_entry(struct list_head *head,
+ const char *namespace)
+{
+ struct namespace_list *ns_entry;
+
+ if (!namespace[0])
+ return NULL;
+
+ list_for_each_entry(ns_entry, head, list) {
+ if (!strcmp(ns_entry->namespace, namespace))
+ return ns_entry;
+ }
+
+ return NULL;
+}
+
static bool contains_namespace(struct list_head *head, const char *namespace)
{
- struct namespace_list *list;
-
/*
* The default namespace is null string "", which is always implicitly
* contained.
@@ -282,21 +297,20 @@ static bool contains_namespace(struct list_head *head, const char *namespace)
if (!namespace[0])
return true;
- list_for_each_entry(list, head, list) {
- if (!strcmp(list->namespace, namespace))
- return true;
- }
+ if (find_namespace_entry(head, namespace))
+ return true;
return false;
}
-static void add_namespace(struct list_head *head, const char *namespace)
+static void add_namespace(struct list_head *head, const char *namespace, bool used)
{
struct namespace_list *ns_entry;
if (!contains_namespace(head, namespace)) {
ns_entry = xmalloc(sizeof(*ns_entry) + strlen(namespace) + 1);
strcpy(ns_entry->namespace, namespace);
+ ns_entry->used = used;
list_add_tail(&ns_entry->list, head);
}
}
@@ -1580,7 +1594,7 @@ static void read_symbols(const char *modname)
namespace = get_modinfo(&info, "import_ns");
while (namespace) {
- add_namespace(&mod->imported_namespaces, namespace);
+ add_namespace(&mod->imported_namespaces, namespace, false);
namespace = get_next_modinfo(&info, "import_ns",
namespace);
}
@@ -1670,9 +1684,16 @@ void buf_write(struct buffer *buf, const char *s, int len)
static void check_exports(struct module *mod)
{
struct symbol *s, *exp;
+ struct namespace_list *ns_entry;
+ const char *basename;
+
+ basename = strrchr(mod->name, '/');
+ if (basename)
+ basename++;
+ else
+ basename = mod->name;
list_for_each_entry(s, &mod->unresolved_symbols, list) {
- const char *basename;
exp = find_symbol(s->name);
if (!exp) {
if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS)
@@ -1692,23 +1713,30 @@ static void check_exports(struct module *mod)
s->crc_valid = exp->crc_valid;
s->crc = exp->crc;
- basename = strrchr(mod->name, '/');
- if (basename)
- basename++;
- else
- basename = mod->name;
+ ns_entry = find_namespace_entry(&mod->imported_namespaces, exp->namespace);
- if (!contains_namespace(&mod->imported_namespaces, exp->namespace)) {
+ if (exp->namespace[0] && !ns_entry) {
modpost_log(!allow_missing_ns_imports,
"module %s uses symbol %s from namespace %s, but does not import it.\n",
basename, exp->name, exp->namespace);
- add_namespace(&mod->missing_namespaces, exp->namespace);
+ add_namespace(&mod->missing_namespaces, exp->namespace, true);
+ } else if (ns_entry) {
+ ns_entry->used = true;
}
if (!mod->is_gpl_compatible && exp->is_gpl_only)
error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
basename, exp->name);
}
+
+ if (extra_warn) {
+ list_for_each_entry(ns_entry, &mod->imported_namespaces, list) {
+ if (!ns_entry->used)
+ modpost_log(false,
+ "module %s imports namespace %s, but doesn't use it.\n",
+ basename, ns_entry->namespace);
+ }
+ }
}
static void handle_white_list_exports(const char *white_list)
Symbols can be exported in namespaces and to make use of such symbols, the namespace has to be explicitly imported. Importing a namespace without actually using one of its symbols is likely a mistake. There are a few offenders for an x86_64 allmodconfig build, so the warning is (for now) only enabled for W=1 builds. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> --- Hello, one of the offenders is drivers/pwm/pwm-raspberrypi-poe.c ( WARNING: modpost: module pwm-raspberrypi-poe imports namespace PWM, but doesn't use it. ). The issue there is that on x86_64 CONFIG_RASPBERRYPI_FIRMWARE is always disabled and so devm_rpi_firmware_get() returns always NULL which makes raspberrypi_pwm_probe return an error before the pwm functions are used. So the compiler optimizes out all references to pwm functions and the warning triggers. I didn't look into the other problems to check if these are similar half-false positives. Still I think this is a useful check? Best regards Uwe scripts/mod/modpost.c | 60 +++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 16 deletions(-) base-commit: 232f121837ad8b1c21cc80f2c8842a4090c5a2a0