module: Export symbols needed for Ksplice
Impact: Expose some module.c symbols Ksplice uses several functions from module.c in order to resolve symbols and implement dependency handling. Calling these functions requires holding module_mutex, so it is exported. (This is just the module part of a bigger add-exports patch from Tim). Cc: Anders Kaseorg <andersk@mit.edu> Cc: Jeff Arnold <jbarnold@mit.edu> Signed-off-by: Tim Abbott <tabbott@mit.edu> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
75a66614db
commit
c6b3780191
|
@ -354,6 +354,8 @@ struct module
|
|||
#define MODULE_ARCH_INIT {}
|
||||
#endif
|
||||
|
||||
extern struct mutex module_mutex;
|
||||
|
||||
/* FIXME: It'd be nice to isolate modules during init, too, so they
|
||||
aren't used before they (may) fail. But presently too much code
|
||||
(IDE & SCSI) require entry into the module during init.*/
|
||||
|
@ -379,6 +381,31 @@ static inline int within_module_init(unsigned long addr, struct module *mod)
|
|||
addr < (unsigned long)mod->module_init + mod->init_size;
|
||||
}
|
||||
|
||||
/* Search for module by name: must hold module_mutex. */
|
||||
struct module *find_module(const char *name);
|
||||
|
||||
struct symsearch {
|
||||
const struct kernel_symbol *start, *stop;
|
||||
const unsigned long *crcs;
|
||||
enum {
|
||||
NOT_GPL_ONLY,
|
||||
GPL_ONLY,
|
||||
WILL_BE_GPL_ONLY,
|
||||
} licence;
|
||||
bool unused;
|
||||
};
|
||||
|
||||
/* Search for an exported symbol by name. */
|
||||
const struct kernel_symbol *find_symbol(const char *name,
|
||||
struct module **owner,
|
||||
const unsigned long **crc,
|
||||
bool gplok,
|
||||
bool warn);
|
||||
|
||||
/* Walk the exported symbol table */
|
||||
bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
|
||||
unsigned int symnum, void *data), void *data);
|
||||
|
||||
/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
|
||||
symnum out of range. */
|
||||
int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
|
||||
|
@ -452,6 +479,7 @@ static inline void __module_get(struct module *module)
|
|||
#define symbol_put_addr(p) do { } while(0)
|
||||
|
||||
#endif /* CONFIG_MODULE_UNLOAD */
|
||||
int use_module(struct module *a, struct module *b);
|
||||
|
||||
/* This is a #define so the string doesn't get put in every .o file */
|
||||
#define module_name(mod) \
|
||||
|
|
|
@ -68,7 +68,8 @@
|
|||
|
||||
/* List of modules, protected by module_mutex or preempt_disable
|
||||
* (delete uses stop_machine/add uses RCU list operations). */
|
||||
static DEFINE_MUTEX(module_mutex);
|
||||
DEFINE_MUTEX(module_mutex);
|
||||
EXPORT_SYMBOL_GPL(module_mutex);
|
||||
static LIST_HEAD(modules);
|
||||
|
||||
/* Waiting for a module to finish initializing? */
|
||||
|
@ -186,17 +187,6 @@ extern const unsigned long __start___kcrctab_unused_gpl[];
|
|||
#define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
|
||||
#endif
|
||||
|
||||
struct symsearch {
|
||||
const struct kernel_symbol *start, *stop;
|
||||
const unsigned long *crcs;
|
||||
enum {
|
||||
NOT_GPL_ONLY,
|
||||
GPL_ONLY,
|
||||
WILL_BE_GPL_ONLY,
|
||||
} licence;
|
||||
bool unused;
|
||||
};
|
||||
|
||||
static bool each_symbol_in_section(const struct symsearch *arr,
|
||||
unsigned int arrsize,
|
||||
struct module *owner,
|
||||
|
@ -217,10 +207,8 @@ static bool each_symbol_in_section(const struct symsearch *arr,
|
|||
}
|
||||
|
||||
/* Returns true as soon as fn returns true, otherwise false. */
|
||||
static bool each_symbol(bool (*fn)(const struct symsearch *arr,
|
||||
struct module *owner,
|
||||
unsigned int symnum, void *data),
|
||||
void *data)
|
||||
bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
|
||||
unsigned int symnum, void *data), void *data)
|
||||
{
|
||||
struct module *mod;
|
||||
const struct symsearch arr[] = {
|
||||
|
@ -273,6 +261,7 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr,
|
|||
}
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(each_symbol);
|
||||
|
||||
struct find_symbol_arg {
|
||||
/* Input */
|
||||
|
@ -330,11 +319,11 @@ static bool find_symbol_in_section(const struct symsearch *syms,
|
|||
|
||||
/* Find a symbol and return it, along with, (optional) crc and
|
||||
* (optional) module which owns it */
|
||||
static const struct kernel_symbol *find_symbol(const char *name,
|
||||
struct module **owner,
|
||||
const unsigned long **crc,
|
||||
bool gplok,
|
||||
bool warn)
|
||||
const struct kernel_symbol *find_symbol(const char *name,
|
||||
struct module **owner,
|
||||
const unsigned long **crc,
|
||||
bool gplok,
|
||||
bool warn)
|
||||
{
|
||||
struct find_symbol_arg fsa;
|
||||
|
||||
|
@ -353,9 +342,10 @@ static const struct kernel_symbol *find_symbol(const char *name,
|
|||
DEBUGP("Failed to find symbol %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(find_symbol);
|
||||
|
||||
/* Search for module by name: must hold module_mutex. */
|
||||
static struct module *find_module(const char *name)
|
||||
struct module *find_module(const char *name)
|
||||
{
|
||||
struct module *mod;
|
||||
|
||||
|
@ -365,6 +355,7 @@ static struct module *find_module(const char *name)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(find_module);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
|
@ -641,7 +632,7 @@ static int already_uses(struct module *a, struct module *b)
|
|||
}
|
||||
|
||||
/* Module a uses b */
|
||||
static int use_module(struct module *a, struct module *b)
|
||||
int use_module(struct module *a, struct module *b)
|
||||
{
|
||||
struct module_use *use;
|
||||
int no_warn, err;
|
||||
|
@ -674,6 +665,7 @@ static int use_module(struct module *a, struct module *b)
|
|||
no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(use_module);
|
||||
|
||||
/* Clear the unload stuff of the module. */
|
||||
static void module_unload_free(struct module *mod)
|
||||
|
@ -951,10 +943,11 @@ static inline void module_unload_free(struct module *mod)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int use_module(struct module *a, struct module *b)
|
||||
int use_module(struct module *a, struct module *b)
|
||||
{
|
||||
return strong_try_module_get(b) == 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(use_module);
|
||||
|
||||
static inline void module_unload_init(struct module *mod)
|
||||
{
|
||||
|
@ -2803,6 +2796,7 @@ __notrace_funcgraph struct module *__module_address(unsigned long addr)
|
|||
return mod;
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__module_address);
|
||||
|
||||
/*
|
||||
* is_module_text_address - is this address inside module code?
|
||||
|
@ -2841,6 +2835,7 @@ struct module *__module_text_address(unsigned long addr)
|
|||
}
|
||||
return mod;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__module_text_address);
|
||||
|
||||
/* Don't grab lock, we're oopsing. */
|
||||
void print_modules(void)
|
||||
|
|
Loading…
Reference in New Issue