diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-04-29 21:13:14 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1997-04-29 21:13:14 +0000 |
commit | 19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch) | |
tree | 40b1cb534496a7f1ca0f5c314a523c69f1fee464 /include/linux/module.h | |
parent | 7206675c40394c78a90e74812bbdbf8cf3cca1be (diff) |
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'include/linux/module.h')
-rw-r--r-- | include/linux/module.h | 315 |
1 files changed, 227 insertions, 88 deletions
diff --git a/include/linux/module.h b/include/linux/module.h index 1bf540e93..48fc78e60 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -1,138 +1,277 @@ /* * Dynamic loading of modules into the kernel. * - * Modified by Bjorn Ekwall <bj0rn@blox.se> + * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996 */ #ifndef _LINUX_MODULE_H #define _LINUX_MODULE_H +#include <linux/config.h> + #ifdef __GENKSYMS__ -# define _set_ver(sym,vers) sym +# define _set_ver(sym) sym # undef MODVERSIONS # define MODVERSIONS #else /* ! __GENKSYMS__ */ -# if defined(MODVERSIONS) && !defined(MODULE) && defined(EXPORT_SYMTAB) -# define _set_ver(sym,vers) sym +# if !defined(MODVERSIONS) && defined(EXPORT_SYMTAB) +# define _set_ver(sym) sym # include <linux/modversions.h> # endif #endif /* __GENKSYMS__ */ -/* values of module.state */ -#define MOD_UNINITIALIZED 0 -#define MOD_RUNNING 1 -#define MOD_DELETED 2 - -/* maximum length of module name */ -#define MOD_MAX_NAME 64 - -/* magic marker for modules inserted from kerneld, to be auto-reaped */ -#define MOD_AUTOCLEAN 0x40000000 /* big enough, but no sign problems... */ -#define MOD_VISITED 0x20000000 /* Thanks Jacques! */ -/* maximum length of symbol name */ -#define SYM_MAX_NAME 60 - -struct kernel_sym { /* sent to "insmod" */ - unsigned long value; /* value of symbol */ - char name[SYM_MAX_NAME]; /* name of symbol */ -}; +/* Don't need to bring in all of uaccess.h just for this decl. */ +struct exception_table_entry; -struct module_ref { - struct module *module; - struct module_ref *next; +/* Used by get_kernel_syms, which is obsolete. */ +struct kernel_sym +{ + unsigned long value; + char name[60]; /* should have been 64-sizeof(long); oh well */ }; -struct internal_symbol { - void *addr; +struct module_symbol +{ + unsigned long value; const char *name; - }; - -struct symbol_table { /* received from "insmod" */ - int size; /* total, including string table!!! */ - int n_symbols; - int n_refs; - struct internal_symbol symbol[0]; /* actual size defined by n_symbols */ - struct module_ref ref[0]; /* actual size defined by n_refs */ }; -/* - * Note: The string table follows immediately after the symbol table in memory! - */ -struct _exceptinfo{ - struct exception_table_entry *start; - struct exception_table_entry *stop; + +struct module_ref +{ + struct module *dep; /* "parent" pointer */ + struct module *ref; /* "child" pointer */ + struct module_ref *next_ref; }; -struct module { +/* TBD */ +struct module_persist; + +struct module +{ + unsigned long size_of_struct; /* == sizeof(module) */ struct module *next; - struct module_ref *ref; /* the list of modules that refer to me */ - struct symbol_table *symtab; const char *name; - int size; /* size of module in pages */ - void* addr; /* address of module */ - int state; - void (*cleanup)(void); /* cleanup routine */ - struct _exceptinfo exceptinfo; + unsigned long size; + + long usecount; + unsigned long flags; /* AUTOCLEAN et al */ + + unsigned nsyms; + unsigned ndeps; + + struct module_symbol *syms; + struct module_ref *deps; + struct module_ref *refs; + int (*init)(void); + void (*cleanup)(void); + const struct exception_table_entry *ex_table_start; + const struct exception_table_entry *ex_table_end; +#ifdef __alpha__ + unsigned long gp; +#endif + /* Members past this point are extensions to the basic + module support and are optional. Use mod_opt_member() + to examine them. */ + const struct module_persist *persist_start; + const struct module_persist *persist_end; + int (*can_unload)(void); }; -/* - prior to modules-2.1 there were no real way to identify - which insmod is talking to us Now a special signature must - be written here. - - The new module utilities knows about older kernel and write - the init in the signature and the cleanup in the init. - This is to make sure newer utilities work with older kernel - so it is simple for people to upgrade. +struct module_info +{ + unsigned long addr; + unsigned long size; + unsigned long flags; + long usecount; +}; + +/* Bits of module.flags. */ + +#define MOD_UNINITIALIZED 0 +#define MOD_RUNNING 1 +#define MOD_DELETED 2 +#define MOD_AUTOCLEAN 4 +#define MOD_VISITED 8 +#define MOD_USED_ONCE 16 + +/* Values for query_module's which. */ + +#define QM_MODULES 1 +#define QM_DEPS 2 +#define QM_REFS 3 +#define QM_SYMBOLS 4 +#define QM_INFO 5 + +/* When struct module is extended, we must test whether the new member + is present in the header received from insmod before we can use it. + This function returns true if the member is present. */ + +#define mod_member_present(mod,member) \ + ((unsigned long)(&((struct module *)0L)->member + 1) \ + <= (mod)->size_of_struct) + +/* Backwards compatibility definition. */ + +#define GET_USE_COUNT(module) ((module)->usecount) + +/* Poke the use count of a module. */ + +#define __MOD_INC_USE_COUNT(mod) \ + ((mod)->usecount++, (mod)->flags |= MOD_VISITED|MOD_USED_ONCE) +#define __MOD_DEC_USE_COUNT(mod) \ + ((mod)->usecount--, (mod)->flags |= MOD_VISITED) +#define __MOD_IN_USE(mod) \ + (mod_member_present((mod), can_unload) && (mod)->can_unload \ + ? (mod)->can_unload() : (mod)->usecount) + +/* Indirect stringification. */ + +#define __MODULE_STRING_1(x) #x +#define __MODULE_STRING(x) __MODULE_STRING_1(x) + +#if defined(MODULE) && !defined(__GENKSYMS__) + +/* Embedded module documentation macros. */ + +/* For documentation purposes only. */ + +#define MODULE_AUTHOR(name) \ +const char __module_author[] __attribute__((section(".modinfo"))) = \ +"author=" name + +#define MODULE_DESCRIPTION(desc) \ +const char __module_description[] __attribute__((section(".modinfo"))) = \ +"description=" desc + +/* Could potentially be used by kerneld... */ + +#define MODULE_SUPPORTED_DEVICE(dev) \ +const char __module_device[] __attribute__((section(".modinfo"))) = \ +"device=" dev + +/* Used to verify parameters given to the module. The TYPE arg should + be a string in the following format: + [min[-max]]{b,h,i,l,s} + The MIN and MAX specifiers delimit the length of the array. If MAX + is omitted, it defaults to MIN; if both are omitted, the default is 1. + The final character is a type specifier: + b byte + h short + i int + l long + s string */ -#define MODULE_2_1_7_SIG ((void*)0x00000217) -struct mod_routines { - void *signature; - int (*init)(void); /* initialization routine */ - void (*cleanup)(void); /* cleanup routine */ - struct _exceptinfo exceptinfo; -}; +#define MODULE_PARM(var,type) \ +const char __module_parm_##var[] \ +__attribute__((section(".modinfo"))) = \ +"parm_" __MODULE_STRING(var) "=" type -/* - * The first word of the module contains the use count. - */ -#define GET_USE_COUNT(module) (* (long *) (module)->addr) -/* - * define the count variable, and usage macros. - */ +#define MODULE_PARM_DESC(var,desc) \ +const char __module_parm_desc_##var[] \ +__attribute__((section(".modinfo"))) = \ +"parm_desc_" __MODULE_STRING(var) "=" desc -#ifdef MODULE +/* The attributes of a section are set the first time the section is + seen; we want .modinfo to not be allocated. */ + +__asm__(".section .modinfo\n\t.previous"); -extern long mod_use_count_; -#define MOD_INC_USE_COUNT (mod_use_count_++, mod_use_count_ |= MOD_VISITED) -#define MOD_DEC_USE_COUNT (mod_use_count_--, mod_use_count_ |= MOD_VISITED) -#define MOD_IN_USE ((mod_use_count_ & ~(MOD_AUTOCLEAN | MOD_VISITED)) != 0) +/* Define the module variable, and usage macros. */ +extern struct module __this_module; + +#define MOD_INC_USE_COUNT __MOD_INC_USE_COUNT(&__this_module) +#define MOD_DEC_USE_COUNT __MOD_DEC_USE_COUNT(&__this_module) +#define MOD_IN_USE __MOD_IN_USE(&__this_module) #ifndef __NO_VERSION__ #include <linux/version.h> -char kernel_version[]=UTS_RELEASE; +const char __module_kernel_version[] __attribute__((section(".modinfo"))) = +"kernel_version=" UTS_RELEASE; +#ifdef MODVERSIONS +const char __module_using_checksums[] __attribute__((section(".modinfo"))) = +"using_checksums=1"; #endif - -#if defined(MODVERSIONS) && !defined(__GENKSYMS__) -int Using_Versions; /* gcc will handle this global (used as a flag) correctly */ #endif -#else +#else /* MODULE */ + +#define MODULE_AUTHOR(name) +#define MODULE_DESCRIPTION(desc) +#define MODULE_SUPPORTED_DEVICE(name) +#define MODULE_PARM(var,type) +#define MODULE_PARM_DESC(var,desc) + +#ifndef __GENKSYMS__ #define MOD_INC_USE_COUNT do { } while (0) #define MOD_DEC_USE_COUNT do { } while (0) #define MOD_IN_USE 1 + extern struct module *module_list; +#endif /* !__GENKSYMS__ */ + +#endif /* MODULE */ + +/* Export a symbol either from the kernel or a module. + + In the kernel, the symbol is added to the kernel's global symbol table. + + In a module, it controls which variables are exported. If no + variables are explicitly exported, the action is controled by the + insmod -[xX] flags. Otherwise, only the variables listed are exported. + This obviates the need for the old register_symtab() function. */ + +#if defined(__GENKSYMS__) + +/* We want the EXPORT_SYMBOL tag left intact for recognition. */ + +#elif !defined(AUTOCONF_INCLUDED) + +#define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module +#define EXPORT_SYMBOL(var) error config_must_be_included_before_module +#define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module + +#elif !defined(CONFIG_MODULES) + +#define __EXPORT_SYMBOL(sym,str) +#define EXPORT_SYMBOL(var) +#define EXPORT_SYMBOL_NOVERS(var) + +#elif !defined(EXPORT_SYMTAB) + +/* If things weren't set up in the Makefiles to get EXPORT_SYMTAB defined, + then they weren't set up to run genksyms properly so MODVERSIONS breaks. */ +#define __EXPORT_SYMBOL(sym,str) error EXPORT_SYMTAB_not_defined +#define EXPORT_SYMBOL(var) error EXPORT_SYMTAB_not_defined +#define EXPORT_SYMBOL_NOVERS(var) error EXPORT_SYMTAB_not_defined + +#else + +#define __EXPORT_SYMBOL(sym, str) \ +const char __kstrtab_##sym[] \ +__attribute__((section(".kstrtab"))) = str; \ +const struct module_symbol __ksymtab_##sym \ +__attribute__((section("__ksymtab"))) = \ +{ (unsigned long)&sym, __kstrtab_##sym } + +#if defined(MODVERSIONS) || !defined(CONFIG_MODVERSIONS) +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) +#else +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var))) #endif -/* insert new symbol table */ -extern int register_symtab_from(struct symbol_table *, long *); +#define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) + +#endif /* __GENKSYMS__ */ + #ifdef MODULE -#define register_symtab(symtab) register_symtab_from(symtab, &mod_use_count_) +/* Force a module to export no symbols. */ +#define EXPORT_NO_SYMBOLS __asm__(".section __ksymtab\n.previous") #else -#define register_symtab(symtab) register_symtab_from(symtab, 0) -#endif +#define EXPORT_NO_SYMBOLS +#endif /* MODULE */ -#endif +#endif /* _LINUX_MODULE_H */ |