#include <asm/semaphore.h>
#include <asm/cacheflush.h>
#include <linux/license.h>
+#include <asm/sections.h>
#if 0
#define DEBUGP printk
}
}
DEBUGP("Failed to find symbol %s\n", name);
- return 0;
+ return -ENOENT;
}
/* Search for module by name: must hold module_mutex. */
return val;
}
-/* Created by linker magic */
-extern char __per_cpu_start[], __per_cpu_end[];
-
static void *percpu_modalloc(unsigned long size, unsigned long align,
const char *name)
{
const unsigned long *crc;
preempt_disable();
- if (!__find_symbol(symbol, &owner, &crc, 1))
+ if (IS_ERR_VALUE(__find_symbol(symbol, &owner, &crc, 1)))
BUG();
module_put(owner);
preempt_enable();
const unsigned long *crc;
struct module *owner;
- if (!__find_symbol("struct_module", &owner, &crc, 1))
+ if (IS_ERR_VALUE(__find_symbol("struct_module",
+ &owner, &crc, 1)))
BUG();
return check_version(sechdrs, versindex, "struct_module", mod,
crc);
ret = __find_symbol(name, &owner, &crc,
!(mod->taints & TAINT_PROPRIETARY_MODULE));
- if (ret) {
+ if (!IS_ERR_VALUE(ret)) {
/* use_module can fail due to OOM,
or module initialization or unloading */
if (!check_version(sechdrs, versindex, name, mod, crc) ||
!use_module(mod, owner))
- ret = 0;
+ ret = -EINVAL;
}
return ret;
}
-
/*
* /sys/module/foo/sections stuff
* J. Corbet <corbet@lwn.net>
*/
-#ifdef CONFIG_KALLSYMS
+#if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS)
static ssize_t module_sect_show(struct module_attribute *mattr,
struct module *mod, char *buf)
{
static inline void remove_notes_attrs(struct module *mod)
{
}
-#endif /* CONFIG_KALLSYMS */
+#endif
#ifdef CONFIG_SYSFS
int module_add_modinfo_attrs(struct module *mod)
}
kfree(mod->modinfo_attrs);
}
-#endif
-#ifdef CONFIG_SYSFS
int mod_sysfs_init(struct module *mod)
{
int err;
preempt_disable();
value = __find_symbol(symbol, &owner, &crc, 1);
- if (value && strong_try_module_get(owner) != 0)
+ if (IS_ERR_VALUE(value))
+ value = 0;
+ else if (strong_try_module_get(owner))
value = 0;
preempt_enable();
const unsigned long *crc;
for (i = 0; i < mod->num_syms; i++)
- if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
+ if (!IS_ERR_VALUE(__find_symbol(mod->syms[i].name,
+ &owner, &crc, 1))) {
name = mod->syms[i].name;
ret = -ENOEXEC;
goto dup;
}
for (i = 0; i < mod->num_gpl_syms; i++)
- if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
+ if (!IS_ERR_VALUE(__find_symbol(mod->gpl_syms[i].name,
+ &owner, &crc, 1))) {
name = mod->gpl_syms[i].name;
ret = -ENOEXEC;
goto dup;
strtab + sym[i].st_name, mod);
/* Ok if resolved. */
- if (sym[i].st_value != 0)
+ if (!IS_ERR_VALUE(sym[i].st_value))
break;
/* Ok if weak. */
if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
/* Set up license info based on the info section */
set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
+ /*
+ * ndiswrapper is under GPL by itself, but loads proprietary modules.
+ * Don't use add_taint_module(), as it would prevent ndiswrapper from
+ * using GPL-only symbols it needs.
+ */
if (strcmp(mod->name, "ndiswrapper") == 0)
- add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+ add_taint(TAINT_PROPRIETARY_MODULE);
+
+ /* driverloader was caught wrongly pretending to be under GPL */
if (strcmp(mod->name, "driverloader") == 0)
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
#ifdef CONFIG_MARKERS
if (!mod->taints)
marker_update_probe_range(mod->markers,
- mod->markers + mod->num_markers, NULL, NULL);
+ mod->markers + mod->num_markers);
#endif
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
wake_up(&module_wq);
return ret;
}
+ if (ret > 0) {
+ printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, "
+ "it should follow 0/-E convention\n"
+ KERN_WARNING "%s: loading module anyway...\n",
+ __func__, mod->name, ret,
+ __func__);
+ dump_stack();
+ }
- /* Now it's a first class citizen! */
- mutex_lock(&module_mutex);
+ /* Now it's a first class citizen! Wake up anyone waiting for it. */
mod->state = MODULE_STATE_LIVE;
+ wake_up(&module_wq);
+
+ mutex_lock(&module_mutex);
/* Drop initial reference. */
module_put(mod);
unwind_remove_table(mod->unwind_info, 1);
mod->init_size = 0;
mod->init_text_size = 0;
mutex_unlock(&module_mutex);
- wake_up(&module_wq);
return 0;
}
/* For kallsyms to ask for address resolution. NULL means not found. Careful
* not to lock to avoid deadlock on oopses, simply disable preemption. */
-char *module_address_lookup(unsigned long addr,
+const char *module_address_lookup(unsigned long addr,
unsigned long *size,
unsigned long *offset,
char **modname,
ret = namebuf;
}
preempt_enable();
- return (char *)ret;
+ return ret;
}
int lookup_module_symbol_name(unsigned long addr, char *symname)
#endif
#ifdef CONFIG_MARKERS
-void module_update_markers(struct module *probe_module, int *refcount)
+void module_update_markers(void)
{
struct module *mod;
list_for_each_entry(mod, &modules, list)
if (!mod->taints)
marker_update_probe_range(mod->markers,
- mod->markers + mod->num_markers,
- probe_module, refcount);
+ mod->markers + mod->num_markers);
mutex_unlock(&module_mutex);
}
#endif