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:
Tim Abbott 2008-12-05 19:03:59 -05:00 committed by Rusty Russell
parent 75a66614db
commit c6b3780191
2 changed files with 47 additions and 24 deletions

View file

@ -354,6 +354,8 @@ struct module
#define MODULE_ARCH_INIT {} #define MODULE_ARCH_INIT {}
#endif #endif
extern struct mutex module_mutex;
/* FIXME: It'd be nice to isolate modules during init, too, so they /* 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 aren't used before they (may) fail. But presently too much code
(IDE & SCSI) require entry into the module during init.*/ (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; 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 /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
symnum out of range. */ symnum out of range. */
int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, 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) #define symbol_put_addr(p) do { } while(0)
#endif /* CONFIG_MODULE_UNLOAD */ #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 */ /* This is a #define so the string doesn't get put in every .o file */
#define module_name(mod) \ #define module_name(mod) \

View file

@ -68,7 +68,8 @@
/* List of modules, protected by module_mutex or preempt_disable /* List of modules, protected by module_mutex or preempt_disable
* (delete uses stop_machine/add uses RCU list operations). */ * (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); static LIST_HEAD(modules);
/* Waiting for a module to finish initializing? */ /* 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) #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
#endif #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, static bool each_symbol_in_section(const struct symsearch *arr,
unsigned int arrsize, unsigned int arrsize,
struct module *owner, 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. */ /* Returns true as soon as fn returns true, otherwise false. */
static bool each_symbol(bool (*fn)(const struct symsearch *arr, bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
struct module *owner, unsigned int symnum, void *data), void *data)
unsigned int symnum, void *data),
void *data)
{ {
struct module *mod; struct module *mod;
const struct symsearch arr[] = { const struct symsearch arr[] = {
@ -273,6 +261,7 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr,
} }
return false; return false;
} }
EXPORT_SYMBOL_GPL(each_symbol);
struct find_symbol_arg { struct find_symbol_arg {
/* Input */ /* 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 /* Find a symbol and return it, along with, (optional) crc and
* (optional) module which owns it */ * (optional) module which owns it */
static const struct kernel_symbol *find_symbol(const char *name, const struct kernel_symbol *find_symbol(const char *name,
struct module **owner, struct module **owner,
const unsigned long **crc, const unsigned long **crc,
bool gplok, bool gplok,
bool warn) bool warn)
{ {
struct find_symbol_arg fsa; 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); DEBUGP("Failed to find symbol %s\n", name);
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(find_symbol);
/* Search for module by name: must hold module_mutex. */ /* 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; struct module *mod;
@ -365,6 +355,7 @@ static struct module *find_module(const char *name)
} }
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(find_module);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
@ -641,7 +632,7 @@ static int already_uses(struct module *a, struct module *b)
} }
/* Module a uses 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; struct module_use *use;
int no_warn, err; 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); no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
return 1; return 1;
} }
EXPORT_SYMBOL_GPL(use_module);
/* Clear the unload stuff of the module. */ /* Clear the unload stuff of the module. */
static void module_unload_free(struct module *mod) 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; return strong_try_module_get(b) == 0;
} }
EXPORT_SYMBOL_GPL(use_module);
static inline void module_unload_init(struct module *mod) 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 mod;
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(__module_address);
/* /*
* is_module_text_address - is this address inside module code? * is_module_text_address - is this address inside module code?
@ -2841,6 +2835,7 @@ struct module *__module_text_address(unsigned long addr)
} }
return mod; return mod;
} }
EXPORT_SYMBOL_GPL(__module_text_address);
/* Don't grab lock, we're oopsing. */ /* Don't grab lock, we're oopsing. */
void print_modules(void) void print_modules(void)