Skip to content

Commit

Permalink
kbuild: warn when a moduled uses a symbol marked UNUSED
Browse files Browse the repository at this point in the history
We now have infrastructure in place to mark an EXPORTed symbol
as unused. So the natural next step is to warn during buildtime when
a module uses a symbol marked UNUSED.

Signed-off-by: Sam Ravnborg <[email protected]>
  • Loading branch information
Sam Ravnborg committed Jul 1, 2006
1 parent 534b89a commit c96fca2
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 23 deletions.
85 changes: 62 additions & 23 deletions scripts/mod/modpost.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ static int all_versions = 0;
/* If we are modposting external module set to 1 */
static int external_module = 0;
/* How a symbol is exported */
enum export {export_plain, export_gpl, export_gpl_future, export_unknown};
enum export {
export_plain, export_unused, export_gpl,
export_unused_gpl, export_gpl_future, export_unknown
};

void fatal(const char *fmt, ...)
{
Expand Down Expand Up @@ -191,7 +194,9 @@ static struct {
enum export export;
} export_list[] = {
{ .str = "EXPORT_SYMBOL", .export = export_plain },
{ .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused },
{ .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
{ .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
{ .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
{ .str = "(unknown)", .export = export_unknown },
};
Expand All @@ -218,8 +223,12 @@ static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
{
if (sec == elf->export_sec)
return export_plain;
else if (sec == elf->export_unused_sec)
return export_unused;
else if (sec == elf->export_gpl_sec)
return export_gpl;
else if (sec == elf->export_unused_gpl_sec)
return export_unused_gpl;
else if (sec == elf->export_gpl_future_sec)
return export_gpl_future;
else
Expand Down Expand Up @@ -368,8 +377,12 @@ static void parse_elf(struct elf_info *info, const char *filename)
info->modinfo_len = sechdrs[i].sh_size;
} else if (strcmp(secname, "__ksymtab") == 0)
info->export_sec = i;
else if (strcmp(secname, "__ksymtab_unused") == 0)
info->export_unused_sec = i;
else if (strcmp(secname, "__ksymtab_gpl") == 0)
info->export_gpl_sec = i;
else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
info->export_unused_gpl_sec = i;
else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
info->export_gpl_future_sec = i;

Expand Down Expand Up @@ -1087,38 +1100,64 @@ void buf_write(struct buffer *buf, const char *s, int len)
buf->pos += len;
}

void check_license(struct module *mod)
static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
{
const char *e = is_vmlinux(m) ?"":".ko";

switch (exp) {
case export_gpl:
fatal("modpost: GPL-incompatible module %s%s "
"uses GPL-only symbol '%s'\n", m, e, s);
break;
case export_unused_gpl:
fatal("modpost: GPL-incompatible module %s%s "
"uses GPL-only symbol marked UNUSED '%s'\n", m, e, s);
break;
case export_gpl_future:
warn("modpost: GPL-incompatible module %s%s "
"uses future GPL-only symbol '%s'\n", m, e, s);
break;
case export_plain:
case export_unused:
case export_unknown:
/* ignore */
break;
}
}

static void check_for_unused(enum export exp, const char* m, const char* s)
{
const char *e = is_vmlinux(m) ?"":".ko";

switch (exp) {
case export_unused:
case export_unused_gpl:
warn("modpost: module %s%s "
"uses symbol '%s' marked UNUSED\n", m, e, s);
break;
default:
/* ignore */
break;
}
}

static void check_exports(struct module *mod)
{
struct symbol *s, *exp;

for (s = mod->unres; s; s = s->next) {
const char *basename;
if (mod->gpl_compatible == 1) {
/* GPL-compatible modules may use all symbols */
continue;
}
exp = find_symbol(s->name);
if (!exp || exp->module == mod)
continue;
basename = strrchr(mod->name, '/');
if (basename)
basename++;
switch (exp->export) {
case export_gpl:
fatal("modpost: GPL-incompatible module %s "
"uses GPL-only symbol '%s'\n",
basename ? basename : mod->name,
exp->name);
break;
case export_gpl_future:
warn("modpost: GPL-incompatible module %s "
"uses future GPL-only symbol '%s'\n",
basename ? basename : mod->name,
exp->name);
break;
case export_plain: /* ignore */ break;
case export_unknown: /* ignore */ break;
}
else
basename = mod->name;
if (!mod->gpl_compatible)
check_for_gpl_usage(exp->export, basename, exp->name);
check_for_unused(exp->export, basename, exp->name);
}
}

Expand Down Expand Up @@ -1399,7 +1438,7 @@ int main(int argc, char **argv)
for (mod = modules; mod; mod = mod->next) {
if (mod->skip)
continue;
check_license(mod);
check_exports(mod);
}

for (mod = modules; mod; mod = mod->next) {
Expand Down
2 changes: 2 additions & 0 deletions scripts/mod/modpost.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ struct elf_info {
Elf_Sym *symtab_start;
Elf_Sym *symtab_stop;
Elf_Section export_sec;
Elf_Section export_unused_sec;
Elf_Section export_gpl_sec;
Elf_Section export_unused_gpl_sec;
Elf_Section export_gpl_future_sec;
const char *strtab;
char *modinfo;
Expand Down

0 comments on commit c96fca2

Please sign in to comment.