X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=include%2Flinux%2Fmodule.h;h=482efc865acf272994b4de7906a8d403a1c1454a;hb=dc7a08166f3a5f23e79e839a8a88849bd3397c32;hp=2c599175c583c36a0bbd71528640489fceb6c149;hpb=04b1db9fd7eea63c9663072feece616ea41b0a79;p=safe%2Fjmp%2Flinux-2.6 diff --git a/include/linux/module.h b/include/linux/module.h index 2c59917..482efc8 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -6,8 +6,6 @@ * Rewritten by Richard Henderson Dec 1996 * Rewritten again by Rusty Russell, 2002 */ -#include -#include #include #include #include @@ -17,19 +15,22 @@ #include #include #include -#include +#include +#include #include +#include + /* Not Yet Implemented */ #define MODULE_SUPPORTED_DEVICE(name) -/* v850 toolchain uses a `_' prefix for all user symbols */ +/* some toolchains uses a `_' prefix for all user symbols */ #ifndef MODULE_SYMBOL_PREFIX #define MODULE_SYMBOL_PREFIX "" #endif -#define MODULE_NAME_LEN (64 - sizeof(unsigned long)) +#define MODULE_NAME_LEN MAX_PARAM_PREFIX_LEN struct kernel_symbol { @@ -59,6 +60,8 @@ struct module_kobject { struct kobject kobj; struct module *mod; + struct kobject *drivers_dir; + struct module_param_attrs *mp; }; /* These are either module local, or the kernel's dummy ones. */ @@ -75,8 +78,7 @@ search_extable(const struct exception_table_entry *first, void sort_extable(struct exception_table_entry *start, struct exception_table_entry *finish); void sort_main_extable(void); - -extern struct subsystem module_subsys; +void trim_init_extable(struct module *m); #ifdef MODULE #define MODULE_GENERIC_TABLE(gtype,name) \ @@ -126,7 +128,10 @@ extern struct module __this_module; */ #define MODULE_LICENSE(_license) MODULE_INFO(license, _license) -/* Author, ideally of form NAME [, NAME ]*[ and NAME ] */ +/* + * Author(s), use "Name " or just "Name", for multiple + * authors use multiple MODULE_AUTHOR() statements/lines. + */ #define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) /* What your module does. */ @@ -180,7 +185,7 @@ void *__symbol_get_gpl(const char *symbol); #define __CRC_SYMBOL(sym, sec) \ extern void *__crc_##sym __attribute__((weak)); \ static const unsigned long __kcrctab_##sym \ - __attribute_used__ \ + __used \ __attribute__((section("__kcrctab" sec), unused)) \ = (unsigned long) &__crc_##sym; #else @@ -192,10 +197,10 @@ void *__symbol_get_gpl(const char *symbol); extern typeof(sym) sym; \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"))) \ + __attribute__((section("__ksymtab_strings"), aligned(1))) \ = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ - __attribute_used__ \ + __used \ __attribute__((section("__ksymtab" sec), unused)) \ = { (unsigned long)&sym, __kstrtab_##sym } @@ -219,11 +224,6 @@ void *__symbol_get_gpl(const char *symbol); #endif -struct module_ref -{ - local_t count; -} ____cacheline_aligned; - enum module_state { MODULE_STATE_LIVE, @@ -231,23 +231,6 @@ enum module_state MODULE_STATE_GOING, }; -/* Similar stuff for section attributes. */ -struct module_sect_attr -{ - struct module_attribute mattr; - char *name; - unsigned long address; -}; - -struct module_sect_attrs -{ - struct attribute_group grp; - int nsections; - struct module_sect_attr attrs[0]; -}; - -struct module_param_attrs; - struct module { enum module_state state; @@ -260,38 +243,45 @@ struct module /* Sysfs stuff. */ struct module_kobject mkobj; - struct module_param_attrs *param_attrs; struct module_attribute *modinfo_attrs; const char *version; const char *srcversion; + struct kobject *holders_dir; /* Exported symbols */ const struct kernel_symbol *syms; - unsigned int num_syms; const unsigned long *crcs; + unsigned int num_syms; + + /* Kernel parameters. */ + struct kernel_param *kp; + unsigned int num_kp; /* GPL-only exported symbols. */ - const struct kernel_symbol *gpl_syms; unsigned int num_gpl_syms; + const struct kernel_symbol *gpl_syms; const unsigned long *gpl_crcs; +#ifdef CONFIG_UNUSED_SYMBOLS /* unused exported symbols. */ const struct kernel_symbol *unused_syms; - unsigned int num_unused_syms; const unsigned long *unused_crcs; + unsigned int num_unused_syms; + /* GPL-only, unused exported symbols. */ - const struct kernel_symbol *unused_gpl_syms; unsigned int num_unused_gpl_syms; + const struct kernel_symbol *unused_gpl_syms; const unsigned long *unused_gpl_crcs; +#endif /* symbols that will be GPL-only in the near future. */ const struct kernel_symbol *gpl_future_syms; - unsigned int num_gpl_future_syms; const unsigned long *gpl_future_crcs; + unsigned int num_gpl_future_syms; /* Exception table */ unsigned int num_exentries; - const struct exception_table_entry *extable; + struct exception_table_entry *extable; /* Startup function. */ int (*init)(void); @@ -303,45 +293,38 @@ struct module void *module_core; /* Here are the sizes of the init and core sections */ - unsigned long init_size, core_size; + unsigned int init_size, core_size; /* The size of the executable code in each section. */ - unsigned long init_text_size, core_text_size; - - /* The handle returned from unwind_add_table. */ - void *unwind_info; + unsigned int init_text_size, core_text_size; /* Arch-specific module values */ struct mod_arch_specific arch; - /* Am I unsafe to unload? */ - int unsafe; - - /* Am I GPL-compatible */ - int license_gplok; - -#ifdef CONFIG_MODULE_UNLOAD - /* Reference counts */ - struct module_ref ref[NR_CPUS]; - - /* What modules depend on me? */ - struct list_head modules_which_use_me; + unsigned int taints; /* same bits as kernel:tainted */ - /* Who is waiting for us to be unloaded */ - struct task_struct *waiter; - - /* Destruction function. */ - void (*exit)(void); +#ifdef CONFIG_GENERIC_BUG + /* Support for BUG */ + unsigned num_bugs; + struct list_head bug_list; + struct bug_entry *bug_table; #endif #ifdef CONFIG_KALLSYMS - /* We keep the symbol and string tables for kallsyms. */ - Elf_Sym *symtab; - unsigned long num_symtab; - char *strtab; + /* + * We keep the symbol and string tables for kallsyms. + * The core_* fields below are temporary, loader-only (they + * could really be discarded after module init). + */ + Elf_Sym *symtab, *core_symtab; + unsigned int num_symtab, core_num_syms; + char *strtab, *core_strtab; /* Section attributes */ struct module_sect_attrs *sect_attrs; + + /* Notes attributes */ + struct module_notes_attrs *notes_attrs; #endif /* Per-cpu data. */ @@ -350,7 +333,52 @@ struct module /* The command line arguments (may be mangled). People like keeping pointers to this stuff */ char *args; +#ifdef CONFIG_TRACEPOINTS + struct tracepoint *tracepoints; + unsigned int num_tracepoints; +#endif + +#ifdef CONFIG_TRACING + const char **trace_bprintk_fmt_start; + unsigned int num_trace_bprintk_fmt; +#endif +#ifdef CONFIG_EVENT_TRACING + struct ftrace_event_call *trace_events; + unsigned int num_trace_events; +#endif +#ifdef CONFIG_FTRACE_MCOUNT_RECORD + unsigned long *ftrace_callsites; + unsigned int num_ftrace_callsites; +#endif + +#ifdef CONFIG_MODULE_UNLOAD + /* What modules depend on me? */ + struct list_head modules_which_use_me; + + /* Who is waiting for us to be unloaded */ + struct task_struct *waiter; + + /* Destruction function. */ + void (*exit)(void); + +#ifdef CONFIG_SMP + char *refptr; +#else + local_t ref; +#endif +#endif + +#ifdef CONFIG_CONSTRUCTORS + /* Constructor functions. */ + ctor_fn_t *ctors; + unsigned int num_ctors; +#endif }; +#ifndef MODULE_ARCH_INIT +#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 @@ -360,20 +388,59 @@ static inline int module_is_live(struct module *mod) return mod->state != MODULE_STATE_GOING; } -/* Is this address in a module? (second is with no locks, for oops) */ -struct module *module_text_address(unsigned long addr); struct module *__module_text_address(unsigned long addr); -int is_module_address(unsigned long addr); +struct module *__module_address(unsigned long addr); +bool is_module_address(unsigned long addr); +bool is_module_text_address(unsigned long addr); + +static inline int within_module_core(unsigned long addr, struct module *mod) +{ + return (unsigned long)mod->module_core <= addr && + addr < (unsigned long)mod->module_core + mod->core_size; +} + +static inline int within_module_init(unsigned long addr, struct module *mod) +{ + return (unsigned long)mod->module_init <= addr && + 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; +}; -/* Returns module and fills in value, defined and namebuf, or NULL if +/* 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. */ -struct module *module_get_kallsym(unsigned int symnum, unsigned long *value, - char *type, char *name, size_t namelen); +int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, + char *name, char *module_name, int *exported); /* Look for this name: can be of form module:name. */ unsigned long module_kallsyms_lookup_name(const char *name); -int is_exported(const char *name, const struct module *mod); +int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, + struct module *, unsigned long), + void *data); extern void __module_put_and_exit(struct module *mod, long code) __attribute__((noreturn)); @@ -385,13 +452,24 @@ void __symbol_put(const char *symbol); #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) void symbol_put_addr(void *addr); +static inline local_t *__module_ref_addr(struct module *mod, int cpu) +{ +#ifdef CONFIG_SMP + return (local_t *) (mod->refptr + per_cpu_offset(cpu)); +#else + return &mod->ref; +#endif +} + /* Sometimes we know we already have a refcount, and it's easier not to handle the error case (which only happens with rmmod --wait). */ static inline void __module_get(struct module *module) { if (module) { - BUG_ON(module_refcount(module) == 0); - local_inc(&module->ref[get_cpu()].count); + unsigned int cpu = get_cpu(); + local_inc(__module_ref_addr(module, cpu)); + trace_module_get(module, _THIS_IP_, + local_read(__module_ref_addr(module, cpu))); put_cpu(); } } @@ -402,8 +480,11 @@ static inline int try_module_get(struct module *module) if (module) { unsigned int cpu = get_cpu(); - if (likely(module_is_live(module))) - local_inc(&module->ref[cpu].count); + if (likely(module_is_live(module))) { + local_inc(__module_ref_addr(module, cpu)); + trace_module_get(module, _THIS_IP_, + local_read(__module_ref_addr(module, cpu))); + } else ret = 0; put_cpu(); @@ -411,17 +492,7 @@ static inline int try_module_get(struct module *module) return ret; } -static inline void module_put(struct module *module) -{ - if (module) { - unsigned int cpu = get_cpu(); - local_dec(&module->ref[cpu].count); - /* Maybe they're waiting for us to drop reference? */ - if (unlikely(!module_is_live(module))) - wake_up_process(module->waiter); - put_cpu(); - } -} +extern void module_put(struct module *module); #else /*!CONFIG_MODULE_UNLOAD*/ static inline int try_module_get(struct module *module) @@ -438,6 +509,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) \ @@ -446,21 +518,16 @@ static inline void __module_get(struct module *module) __mod ? __mod->name : "kernel"; \ }) -#define __unsafe(mod) \ -do { \ - if (mod && !(mod)->unsafe) { \ - printk(KERN_WARNING \ - "Module %s cannot be unloaded due to unsafe usage in" \ - " %s:%u\n", (mod)->name, __FILE__, __LINE__); \ - (mod)->unsafe = 1; \ - } \ -} while(0) - -/* For kallsyms to ask for address resolution. NULL means not found. */ +/* For kallsyms to ask for address resolution. namebuf should be at + * least KSYM_NAME_LEN long: a pointer to namebuf is returned if + * found, otherwise NULL. */ const char *module_address_lookup(unsigned long addr, - unsigned long *symbolsize, - unsigned long *offset, - char **modname); + unsigned long *symbolsize, + unsigned long *offset, + char **modname, + char *namebuf); +int lookup_module_symbol_name(unsigned long addr, char *symname); +int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name); /* For extable.c to search modules' exception tables. */ const struct exception_table_entry *search_module_extables(unsigned long addr); @@ -470,9 +537,8 @@ int unregister_module_notifier(struct notifier_block * nb); extern void print_modules(void); -struct device_driver; -void module_add_driver(struct module *, struct device_driver *); -void module_remove_driver(struct device_driver *); +extern void module_update_tracepoints(void); +extern int module_get_iter_tracepoints(struct tracepoint_iter *iter); #else /* !CONFIG_MODULES... */ #define EXPORT_SYMBOL(sym) @@ -488,21 +554,24 @@ search_module_extables(unsigned long addr) return NULL; } -/* Is this address in a module? */ -static inline struct module *module_text_address(unsigned long addr) +static inline struct module *__module_address(unsigned long addr) { return NULL; } -/* Is this address in a module? (don't take a lock, we're oopsing) */ static inline struct module *__module_text_address(unsigned long addr) { return NULL; } -static inline int is_module_address(unsigned long addr) +static inline bool is_module_address(unsigned long addr) { - return 0; + return false; +} + +static inline bool is_module_text_address(unsigned long addr) +{ + return false; } /* Get/put a kernel symbol (calls should be symmetric) */ @@ -525,23 +594,31 @@ static inline void module_put(struct module *module) #define module_name(mod) "kernel" -#define __unsafe(mod) - /* For kallsyms to ask for address resolution. NULL means not found. */ static inline const char *module_address_lookup(unsigned long addr, - unsigned long *symbolsize, - unsigned long *offset, - char **modname) + unsigned long *symbolsize, + unsigned long *offset, + char **modname, + char *namebuf) { return NULL; } -static inline struct module *module_get_kallsym(unsigned int symnum, - unsigned long *value, - char *type, char *name, - size_t namelen) +static inline int lookup_module_symbol_name(unsigned long addr, char *symname) { - return NULL; + return -ERANGE; +} + +static inline int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name) +{ + return -ERANGE; +} + +static inline int module_get_kallsym(unsigned int symnum, unsigned long *value, + char *type, char *name, + char *module_name, int *exported) +{ + return -ERANGE; } static inline unsigned long module_kallsyms_lookup_name(const char *name) @@ -549,7 +626,10 @@ static inline unsigned long module_kallsyms_lookup_name(const char *name) return 0; } -static inline int is_exported(const char *name, const struct module *mod) +static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, + struct module *, + unsigned long), + void *data) { return 0; } @@ -571,18 +651,55 @@ static inline void print_modules(void) { } +static inline void module_update_tracepoints(void) +{ +} + +static inline int module_get_iter_tracepoints(struct tracepoint_iter *iter) +{ + return 0; +} + +#endif /* CONFIG_MODULES */ + struct device_driver; +#ifdef CONFIG_SYSFS struct module; -static inline void module_add_driver(struct module *module, struct device_driver *driver) +extern struct kset *module_kset; +extern struct kobj_type module_ktype; +extern int module_sysfs_initialized; + +int mod_sysfs_init(struct module *mod); +int mod_sysfs_setup(struct module *mod, + struct kernel_param *kparam, + unsigned int num_params); +int module_add_modinfo_attrs(struct module *mod); +void module_remove_modinfo_attrs(struct module *mod); + +#else /* !CONFIG_SYSFS */ + +static inline int mod_sysfs_init(struct module *mod) { + return 0; } -static inline void module_remove_driver(struct device_driver *driver) +static inline int mod_sysfs_setup(struct module *mod, + struct kernel_param *kparam, + unsigned int num_params) { + return 0; } -#endif /* CONFIG_MODULES */ +static inline int module_add_modinfo_attrs(struct module *mod) +{ + return 0; +} + +static inline void module_remove_modinfo_attrs(struct module *mod) +{ } + +#endif /* CONFIG_SYSFS */ #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) @@ -590,4 +707,21 @@ static inline void module_remove_driver(struct device_driver *driver) #define __MODULE_STRING(x) __stringify(x) + +#ifdef CONFIG_GENERIC_BUG +int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, + struct module *); +void module_bug_cleanup(struct module *); + +#else /* !CONFIG_GENERIC_BUG */ + +static inline int module_bug_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *mod) +{ + return 0; +} +static inline void module_bug_cleanup(struct module *mod) {} +#endif /* CONFIG_GENERIC_BUG */ + #endif /* _LINUX_MODULE_H */