|
@@ -1,4 +1,4 @@
|
|
-/* Rewritten by Rusty Russell, on the backs of many others...
|
|
|
|
|
|
+/*
|
|
Copyright (C) 2002 Richard Henderson
|
|
Copyright (C) 2002 Richard Henderson
|
|
Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
|
|
Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
|
|
|
|
|
|
@@ -122,9 +122,17 @@ extern const struct kernel_symbol __start___ksymtab_gpl[];
|
|
extern const struct kernel_symbol __stop___ksymtab_gpl[];
|
|
extern const struct kernel_symbol __stop___ksymtab_gpl[];
|
|
extern const struct kernel_symbol __start___ksymtab_gpl_future[];
|
|
extern const struct kernel_symbol __start___ksymtab_gpl_future[];
|
|
extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
|
|
extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
|
|
|
|
+extern const struct kernel_symbol __start___ksymtab_unused[];
|
|
|
|
+extern const struct kernel_symbol __stop___ksymtab_unused[];
|
|
|
|
+extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
|
|
|
|
+extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
|
|
|
|
+extern const struct kernel_symbol __start___ksymtab_gpl_future[];
|
|
|
|
+extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
|
|
extern const unsigned long __start___kcrctab[];
|
|
extern const unsigned long __start___kcrctab[];
|
|
extern const unsigned long __start___kcrctab_gpl[];
|
|
extern const unsigned long __start___kcrctab_gpl[];
|
|
extern const unsigned long __start___kcrctab_gpl_future[];
|
|
extern const unsigned long __start___kcrctab_gpl_future[];
|
|
|
|
+extern const unsigned long __start___kcrctab_unused[];
|
|
|
|
+extern const unsigned long __start___kcrctab_unused_gpl[];
|
|
|
|
|
|
#ifndef CONFIG_MODVERSIONS
|
|
#ifndef CONFIG_MODVERSIONS
|
|
#define symversion(base, idx) NULL
|
|
#define symversion(base, idx) NULL
|
|
@@ -144,6 +152,17 @@ static const struct kernel_symbol *lookup_symbol(const char *name,
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void printk_unused_warning(const char *name)
|
|
|
|
+{
|
|
|
|
+ printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
|
|
|
|
+ "however this module is using it.\n", name);
|
|
|
|
+ printk(KERN_WARNING "This symbol will go away in the future.\n");
|
|
|
|
+ printk(KERN_WARNING "Please evalute if this is the right api to use, "
|
|
|
|
+ "and if it really is, submit a report the linux kernel "
|
|
|
|
+ "mailinglist together with submitting your code for "
|
|
|
|
+ "inclusion.\n");
|
|
|
|
+}
|
|
|
|
+
|
|
/* Find a symbol, return value, crc and module which owns it */
|
|
/* Find a symbol, return value, crc and module which owns it */
|
|
static unsigned long __find_symbol(const char *name,
|
|
static unsigned long __find_symbol(const char *name,
|
|
struct module **owner,
|
|
struct module **owner,
|
|
@@ -186,6 +205,25 @@ static unsigned long __find_symbol(const char *name,
|
|
return ks->value;
|
|
return ks->value;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ ks = lookup_symbol(name, __start___ksymtab_unused,
|
|
|
|
+ __stop___ksymtab_unused);
|
|
|
|
+ if (ks) {
|
|
|
|
+ printk_unused_warning(name);
|
|
|
|
+ *crc = symversion(__start___kcrctab_unused,
|
|
|
|
+ (ks - __start___ksymtab_unused));
|
|
|
|
+ return ks->value;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (gplok)
|
|
|
|
+ ks = lookup_symbol(name, __start___ksymtab_unused_gpl,
|
|
|
|
+ __stop___ksymtab_unused_gpl);
|
|
|
|
+ if (ks) {
|
|
|
|
+ printk_unused_warning(name);
|
|
|
|
+ *crc = symversion(__start___kcrctab_unused_gpl,
|
|
|
|
+ (ks - __start___ksymtab_unused_gpl));
|
|
|
|
+ return ks->value;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Now try modules. */
|
|
/* Now try modules. */
|
|
list_for_each_entry(mod, &modules, list) {
|
|
list_for_each_entry(mod, &modules, list) {
|
|
*owner = mod;
|
|
*owner = mod;
|
|
@@ -204,6 +242,23 @@ static unsigned long __find_symbol(const char *name,
|
|
return ks->value;
|
|
return ks->value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms);
|
|
|
|
+ if (ks) {
|
|
|
|
+ printk_unused_warning(name);
|
|
|
|
+ *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms));
|
|
|
|
+ return ks->value;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (gplok) {
|
|
|
|
+ ks = lookup_symbol(name, mod->unused_gpl_syms,
|
|
|
|
+ mod->unused_gpl_syms + mod->num_unused_gpl_syms);
|
|
|
|
+ if (ks) {
|
|
|
|
+ printk_unused_warning(name);
|
|
|
|
+ *crc = symversion(mod->unused_gpl_crcs,
|
|
|
|
+ (ks - mod->unused_gpl_syms));
|
|
|
|
+ return ks->value;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
ks = lookup_symbol(name, mod->gpl_future_syms,
|
|
ks = lookup_symbol(name, mod->gpl_future_syms,
|
|
(mod->gpl_future_syms +
|
|
(mod->gpl_future_syms +
|
|
mod->num_gpl_future_syms));
|
|
mod->num_gpl_future_syms));
|
|
@@ -1407,6 +1462,8 @@ static struct module *load_module(void __user *umod,
|
|
exportindex, modindex, obsparmindex, infoindex, gplindex,
|
|
exportindex, modindex, obsparmindex, infoindex, gplindex,
|
|
crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
|
|
crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
|
|
gplfuturecrcindex, unwindex = 0;
|
|
gplfuturecrcindex, unwindex = 0;
|
|
|
|
+ unsigned int unusedindex, unusedcrcindex, unusedgplindex,
|
|
|
|
+ unusedgplcrcindex;
|
|
struct module *mod;
|
|
struct module *mod;
|
|
long err = 0;
|
|
long err = 0;
|
|
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
|
|
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
|
|
@@ -1487,9 +1544,13 @@ static struct module *load_module(void __user *umod,
|
|
exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
|
|
exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
|
|
gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
|
|
gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
|
|
gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
|
|
gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
|
|
|
|
+ unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");
|
|
|
|
+ unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl");
|
|
crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
|
|
crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
|
|
gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
|
|
gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
|
|
gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
|
|
gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
|
|
|
|
+ unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused");
|
|
|
|
+ unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl");
|
|
setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
|
|
setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
|
|
exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
|
|
exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
|
|
obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
|
|
obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
|
|
@@ -1638,14 +1699,27 @@ static struct module *load_module(void __user *umod,
|
|
mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
|
|
mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
|
|
mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
|
|
mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
|
|
sizeof(*mod->gpl_future_syms);
|
|
sizeof(*mod->gpl_future_syms);
|
|
|
|
+ mod->num_unused_syms = sechdrs[unusedindex].sh_size /
|
|
|
|
+ sizeof(*mod->unused_syms);
|
|
|
|
+ mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size /
|
|
|
|
+ sizeof(*mod->unused_gpl_syms);
|
|
mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
|
|
mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
|
|
if (gplfuturecrcindex)
|
|
if (gplfuturecrcindex)
|
|
mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
|
|
mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
|
|
|
|
|
|
|
|
+ mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;
|
|
|
|
+ if (unusedcrcindex)
|
|
|
|
+ mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr;
|
|
|
|
+ mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr;
|
|
|
|
+ if (unusedgplcrcindex)
|
|
|
|
+ mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr;
|
|
|
|
+
|
|
#ifdef CONFIG_MODVERSIONS
|
|
#ifdef CONFIG_MODVERSIONS
|
|
if ((mod->num_syms && !crcindex) ||
|
|
if ((mod->num_syms && !crcindex) ||
|
|
(mod->num_gpl_syms && !gplcrcindex) ||
|
|
(mod->num_gpl_syms && !gplcrcindex) ||
|
|
- (mod->num_gpl_future_syms && !gplfuturecrcindex)) {
|
|
|
|
|
|
+ (mod->num_gpl_future_syms && !gplfuturecrcindex) ||
|
|
|
|
+ (mod->num_unused_syms && !unusedcrcindex) ||
|
|
|
|
+ (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
|
|
printk(KERN_WARNING "%s: No versions for exported symbols."
|
|
printk(KERN_WARNING "%s: No versions for exported symbols."
|
|
" Tainting kernel.\n", mod->name);
|
|
" Tainting kernel.\n", mod->name);
|
|
add_taint(TAINT_FORCED_MODULE);
|
|
add_taint(TAINT_FORCED_MODULE);
|