From a869e179069a3ef64870eec58ee2aaf1a59a6070 Mon Sep 17 00:00:00 2001 From: Hirofumi Ogawa Date: Sat, 28 Dec 2002 23:54:15 -0800 Subject: [PATCH] Simplify ramfs_getattr() and move it to the generic libfs.c This moves ramfs_getattr() to fs/libfs.c as simple_getattr() --- kernel/ksyms.c | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel') diff --git a/kernel/ksyms.c b/kernel/ksyms.c index f634f12d4bef..cd49778dd1f3 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -299,6 +299,7 @@ EXPORT_SYMBOL(dcache_dir_open); EXPORT_SYMBOL(dcache_dir_close); EXPORT_SYMBOL(dcache_dir_lseek); EXPORT_SYMBOL(dcache_readdir); +EXPORT_SYMBOL(simple_getattr); EXPORT_SYMBOL(simple_statfs); EXPORT_SYMBOL(simple_lookup); EXPORT_SYMBOL(simple_dir_operations); -- cgit v1.2.3 From 2cdea2157dfbe0ea2a28bf6d4dc6c53013e4088f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 29 Dec 2002 00:35:42 -0800 Subject: [PATCH] more deprectation bits Rename the deprecated attribute to __deprecated to make it obvious this is something special and to avoid namespace clashes. Mark old module interfaces deprecated. --- include/linux/compiler.h | 4 ++-- include/linux/ioport.h | 2 +- include/linux/module.h | 34 ++++++++++++++++++++++++++-------- kernel/resource.c | 2 +- 4 files changed, 30 insertions(+), 12 deletions(-) (limited to 'kernel') diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 51cfdb71594b..f88889740949 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -21,9 +21,9 @@ * and then gcc will emit a warning for each usage of the function. */ #if __GNUC__ >= 3 -#define deprecated __attribute__((deprecated)) +#define __deprecated __attribute__((deprecated)) #else -#define deprecated +#define __deprecated #endif /* This macro obfuscates arithmetic on a variable address so that gcc diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 7c48dfa36962..edd1eadb98b8 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -108,7 +108,7 @@ extern struct resource * __request_region(struct resource *, unsigned long start #define check_mem_region(start,n) __check_region(&iomem_resource, (start), (n)) #define release_mem_region(start,n) __release_region(&iomem_resource, (start), (n)) -extern int deprecated __check_region(struct resource *, unsigned long, unsigned long); +extern int __deprecated __check_region(struct resource *, unsigned long, unsigned long); extern void __release_region(struct resource *, unsigned long, unsigned long); #define get_ioport_list(buf) get_resource_list(&ioport_resource, buf, PAGE_SIZE) diff --git a/include/linux/module.h b/include/linux/module.h index 2392edcc3307..c033488d6eeb 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -296,9 +296,20 @@ extern spinlock_t modlist_lock; #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) /* BELOW HERE ALL THESE ARE OBSOLETE AND WILL VANISH */ -#define __MOD_INC_USE_COUNT(mod) \ - do { __unsafe(mod); (void)try_module_get(mod); } while(0) -#define __MOD_DEC_USE_COUNT(mod) module_put(mod) +static inline void __deprecated __MOD_INC_USE_COUNT(struct module *module) +{ + __unsafe(module); + /* + * Yes, we ignore the retval here, that's why it's deprecated. + */ + try_module_get(module); +} + +static inline void __deprecated __MOD_DEC_USE_COUNT(struct module *module) +{ + module_put(module); +} + #define SET_MODULE_OWNER(dev) ((dev)->owner = THIS_MODULE) struct obsolete_modparm { @@ -319,14 +330,21 @@ struct obsolete_modparm __parm_##var __attribute__((section("__obsparm"))) = \ /* People do this inside their init routines, when the module isn't "live" yet. They should no longer be doing that, but meanwhile... */ +static inline void __deprecated _MOD_INC_USE_COUNT(struct module *module) +{ + __unsafe(module); + #if defined(CONFIG_MODULE_UNLOAD) && defined(MODULE) -#define MOD_INC_USE_COUNT \ - do { __unsafe(THIS_MODULE); local_inc(&THIS_MODULE->ref[get_cpu()].count); put_cpu(); } while (0) + local_inc(&module->ref[get_cpu()].count); + put_cpu(); #else -#define MOD_INC_USE_COUNT \ - do { __unsafe(THIS_MODULE); (void)try_module_get(THIS_MODULE); } while (0) + try_module_get(module); #endif -#define MOD_DEC_USE_COUNT module_put(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 try_inc_mod_count(mod) try_module_get(mod) #define EXPORT_NO_SYMBOLS extern int module_dummy_usage; diff --git a/kernel/resource.c b/kernel/resource.c index 7e23211ac0a9..83d04826245d 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -237,7 +237,7 @@ struct resource * __request_region(struct resource *parent, unsigned long start, return res; } -int deprecated __check_region(struct resource *parent, unsigned long start, unsigned long n) +int __deprecated __check_region(struct resource *parent, unsigned long start, unsigned long n) { struct resource * res; -- cgit v1.2.3 From afe0458b256d78a37ba9f244cce29e141e1c658a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 29 Dec 2002 00:40:46 -0800 Subject: [PATCH] avoid deprecated module functions in core code A second start at removing them from kernel/*.c and fs/*.c. Note that module_put is fine for a NULL argument. --- crypto/api.c | 3 +-- drivers/block/genhd.c | 6 ++---- fs/block_dev.c | 11 +++++------ fs/dquot.c | 3 +-- fs/exec.c | 17 ++++++++++------- fs/nls/nls_base.c | 3 +-- fs/partitions/check.c | 3 +-- include/linux/binfmts.h | 8 +------- include/linux/fs.h | 4 ++-- include/linux/personality.h | 18 ------------------ kernel/exec_domain.c | 7 ++----- kernel/exit.c | 6 +++--- kernel/fork.c | 14 ++++++++------ kernel/intermodule.c | 2 +- 14 files changed, 38 insertions(+), 67 deletions(-) (limited to 'kernel') diff --git a/crypto/api.c b/crypto/api.c index 626437fb5dea..64886f4d6335 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -29,8 +29,7 @@ static inline int crypto_alg_get(struct crypto_alg *alg) static inline void crypto_alg_put(struct crypto_alg *alg) { - if (alg->cra_module) - __MOD_DEC_USE_COUNT(alg->cra_module); + module_put(alg->cra_module); } struct crypto_alg *crypto_alg_lookup(const char *name) diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 98a62d7c7a6b..c133b454b2fb 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -168,15 +168,13 @@ retry: best = p->range; *part = dev - p->dev; if (p->lock && p->lock(dev, data) < 0) { - if (owner) - __MOD_DEC_USE_COUNT(owner); + module_put(owner); continue; } read_unlock(&gendisk_lock); disk = probe(dev, part, data); /* Currently ->owner protects _only_ ->probe() itself. */ - if (owner) - __MOD_DEC_USE_COUNT(owner); + module_put(owner); if (disk) return disk; goto retry; diff --git a/fs/block_dev.c b/fs/block_dev.c index e6fc5b1984e3..2e0b69ff70a1 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -623,8 +623,7 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * } } else { put_disk(disk); - if (owner) - __MOD_DEC_USE_COUNT(owner); + module_put(owner); if (bdev->bd_contains == bdev) { if (bdev->bd_disk->fops->open) { ret = bdev->bd_disk->fops->open(inode, file); @@ -651,8 +650,7 @@ out_first: blkdev_put(bdev->bd_contains, BDEV_RAW); bdev->bd_contains = NULL; put_disk(disk); - if (owner) - __MOD_DEC_USE_COUNT(owner); + module_put(owner); out: up(&bdev->bd_sem); unlock_kernel(); @@ -723,9 +721,10 @@ int blkdev_put(struct block_device *bdev, int kind) } if (!bdev->bd_openers) { struct module *owner = disk->fops->owner; + put_disk(disk); - if (owner) - __MOD_DEC_USE_COUNT(owner); + module_put(owner); + bdev->bd_disk = NULL; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; if (bdev != bdev->bd_contains) { diff --git a/fs/dquot.c b/fs/dquot.c index 5da20a7049ce..8781f7201a87 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -111,8 +111,7 @@ static struct quota_format_type *find_quota_format(int id) static void put_quota_format(struct quota_format_type *fmt) { - if (fmt->qf_owner) - __MOD_DEC_USE_COUNT(fmt->qf_owner); + module_put(fmt->qf_owner); } /* diff --git a/fs/exec.c b/fs/exec.c index 1699f5bdf92e..901b8e12388f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -102,8 +102,7 @@ int unregister_binfmt(struct linux_binfmt * fmt) static inline void put_binfmt(struct linux_binfmt * fmt) { - if (fmt->module) - __MOD_DEC_USE_COUNT(fmt->module); + module_put(fmt->module); } /* @@ -1108,14 +1107,18 @@ out_file: return retval; } -void set_binfmt(struct linux_binfmt *new) +int set_binfmt(struct linux_binfmt *new) { struct linux_binfmt *old = current->binfmt; - if (new && new->module) - __MOD_INC_USE_COUNT(new->module); + + if (new) { + if (!try_module_get(new->module)) + return -1; + } current->binfmt = new; - if (old && old->module) - __MOD_DEC_USE_COUNT(old->module); + if (old) + module_put(old->module); + return 0; } #define CORENAME_MAX_SIZE 64 diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 0af5e08cb950..3ea711688341 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -245,8 +245,7 @@ struct nls_table *load_nls(char *charset) void unload_nls(struct nls_table *nls) { - if (nls->owner) - __MOD_DEC_USE_COUNT(nls->owner); + module_put(nls->owner); } wchar_t charset2uni[256] = { diff --git a/fs/partitions/check.c b/fs/partitions/check.c index da216ea3efa6..b1d436feb241 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -565,8 +565,7 @@ char *partition_name(dev_t dev) dname->name = NULL; if (hd) { dname->name = disk_name(hd, part, dname->namebuf); - if (hd->fops->owner) - __MOD_DEC_USE_COUNT(hd->fops->owner); + module_put(hd->fops->owner); put_disk(hd); } if (!dname->name) { diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index ae1b454395b5..bd929e344d75 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -58,13 +58,7 @@ extern int copy_strings(int argc,char ** argv,struct linux_binprm *bprm); extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm); extern void compute_creds(struct linux_binprm *binprm); extern int do_coredump(long signr, int exit_code, struct pt_regs * regs); -extern void set_binfmt(struct linux_binfmt *new); - - -#if 0 -/* this went away now */ -#define change_ldt(a,b) setup_arg_pages(a,b) -#endif +extern int set_binfmt(struct linux_binfmt *new); #endif /* __KERNEL__ */ #endif /* _LINUX_BINFMTS_H */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 5c00caf3edf1..6c3188b991e6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -983,13 +983,13 @@ struct super_block *get_sb_pseudo(struct file_system_type *, char *, /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \ (((fops) && (fops)->owner) \ - ? ( try_inc_mod_count((fops)->owner) ? (fops) : NULL ) \ + ? (try_inc_mod_count((fops)->owner) ? (fops) : NULL) \ : (fops)) #define fops_put(fops) \ do { \ if ((fops) && (fops)->owner) \ - __MOD_DEC_USE_COUNT((fops)->owner); \ + module_put((fops)->owner); \ } while(0) extern int register_filesystem(struct file_system_type *); diff --git a/include/linux/personality.h b/include/linux/personality.h index ca5d403e49ff..33802c8eeedb 100644 --- a/include/linux/personality.h +++ b/include/linux/personality.h @@ -107,22 +107,4 @@ struct exec_domain { #define set_personality(pers) \ ((current->personality == pers) ? 0 : __set_personality(pers)) -/* - * Load an execution domain. - */ -#define get_exec_domain(ep) \ -do { \ - if (ep != NULL && ep->module != NULL) \ - __MOD_INC_USE_COUNT(ep->module); \ -} while (0) - -/* - * Unload an execution domain. - */ -#define put_exec_domain(ep) \ -do { \ - if (ep != NULL && ep->module != NULL) \ - __MOD_DEC_USE_COUNT(ep->module); \ -} while (0) - #endif /* _LINUX_PERSONALITY_H */ diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c index e0b31f7f5243..162a5c23e606 100644 --- a/kernel/exec_domain.c +++ b/kernel/exec_domain.c @@ -172,7 +172,7 @@ __set_personality(u_long personality) fsp = copy_fs_struct(current->fs); if (fsp == NULL) { - put_exec_domain(ep); + module_put(ep->module); return -ENOMEM;; } @@ -194,10 +194,7 @@ __set_personality(u_long personality) current_thread_info()->exec_domain = ep; set_fs_altroot(); - put_exec_domain(oep); - - printk(KERN_DEBUG "[%s:%d]: set personality to %lx\n", - current->comm, current->pid, personality); + module_put(oep->module); return 0; } diff --git a/kernel/exit.c b/kernel/exit.c index 5e7fcdaa6221..6adea537242a 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -664,9 +664,9 @@ fake_volatile: if (current->leader) disassociate_ctty(1); - put_exec_domain(tsk->thread_info->exec_domain); - if (tsk->binfmt && tsk->binfmt->module) - __MOD_DEC_USE_COUNT(tsk->binfmt->module); + module_put(tsk->thread_info->exec_domain->module); + if (tsk->binfmt) + module_put(tsk->binfmt->module); tsk->exit_code = code; exit_notify(); diff --git a/kernel/fork.c b/kernel/fork.c index b8771509f285..6f7298827344 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -743,10 +743,11 @@ static struct task_struct *copy_process(unsigned long clone_flags, if (nr_threads >= max_threads) goto bad_fork_cleanup_count; - get_exec_domain(p->thread_info->exec_domain); + if (!try_module_get(p->thread_info->exec_domain->module)) + goto bad_fork_cleanup_count; - if (p->binfmt && p->binfmt->module) - __MOD_INC_USE_COUNT(p->binfmt->module); + if (p->binfmt && !try_module_get(p->binfmt->module)) + goto bad_fork_cleanup_put_domain; #ifdef CONFIG_PREEMPT /* @@ -958,9 +959,10 @@ bad_fork_cleanup_security: bad_fork_cleanup: if (p->pid > 0) free_pidmap(p->pid); - put_exec_domain(p->thread_info->exec_domain); - if (p->binfmt && p->binfmt->module) - __MOD_DEC_USE_COUNT(p->binfmt->module); + if (p->binfmt) + module_put(p->binfmt->module); +bad_fork_cleanup_put_domain: + module_put(p->thread_info->exec_domain->module); bad_fork_cleanup_count: atomic_dec(&p->user->processes); free_uid(p->user); diff --git a/kernel/intermodule.c b/kernel/intermodule.c index a6cd1d08afa4..9228ca4fe035 100644 --- a/kernel/intermodule.c +++ b/kernel/intermodule.c @@ -166,7 +166,7 @@ void inter_module_put(const char *im_name) ime = list_entry(tmp, struct inter_module_entry, list); if (strcmp(ime->im_name, im_name) == 0) { if (ime->owner) - __MOD_DEC_USE_COUNT(ime->owner); + module_put(ime->owner); spin_unlock(&ime_lock); return; } -- cgit v1.2.3 From 35bc6f3f8db6a6412fcb6fb9a251a1083094ca47 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 29 Dec 2002 01:47:53 -0800 Subject: [PATCH] Embed __this_module in module itself. Rather than have the module loader the module structure and resolve the symbols __this_module to it, make __this_module a real structure inside the module, using the linkonce trick we used for module names. This saves us an allocation (saving a page per module on archs which need the module structure close by), and means we don't have to fill in a few module fields. --- include/linux/init.h | 5 +-- include/linux/module.h | 34 ++++++++-------- kernel/module.c | 103 ++++++++++++++++++++++--------------------------- 3 files changed, 66 insertions(+), 76 deletions(-) (limited to 'kernel') diff --git a/include/linux/init.h b/include/linux/init.h index 46b1ef190c52..b7c6363478aa 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -147,14 +147,13 @@ struct obs_kernel_param { #define module_init(initfn) \ static inline initcall_t __inittest(void) \ { return initfn; } \ - int __initfn(void) __attribute__((alias(#initfn))); + int init_module(void) __attribute__((alias(#initfn))); /* This is only required if you want to be unloadable. */ #define module_exit(exitfn) \ static inline exitcall_t __exittest(void) \ { return exitfn; } \ - void __exitfn(void) __attribute__((alias(#exitfn))); - + void cleanup_module(void) __attribute__((alias(#exitfn))); #define __setup(str,func) /* nothing */ #endif diff --git a/include/linux/module.h b/include/linux/module.h index c033488d6eeb..3a411c8c6575 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -40,12 +40,11 @@ struct kernel_symbol char name[MODULE_NAME_LEN]; }; -#ifdef MODULE +/* These are either module local, or the kernel's dummy ones. */ +extern int init_module(void); +extern void cleanup_module(void); -#ifdef KBUILD_MODNAME -static const char __module_name[MODULE_NAME_LEN] __attribute__((section(".gnu.linkonce.modname"))) = \ - __stringify(KBUILD_MODNAME); -#endif +#ifdef MODULE /* For replacement modutils, use an alias not a pointer. */ #define MODULE_GENERIC_TABLE(gtype,name) \ @@ -56,9 +55,6 @@ static const struct gtype##_id * __module_##gtype##_table \ extern const struct gtype##_id __mod_##gtype##_table \ __attribute__ ((unused, alias(__stringify(name)))) -/* This is magically filled in by the linker, but THIS_MODULE must be - a constant so it works in initializers. */ -extern struct module __this_module; #define THIS_MODULE (&__this_module) #else /* !MODULE */ @@ -176,7 +172,7 @@ struct module /* The command line arguments (may be mangled). People like keeping pointers to this stuff */ - char args[0]; + char *args; }; /* FIXME: It'd be nice to isolate modules during init, too, so they @@ -289,6 +285,19 @@ static inline const char *module_address_lookup(unsigned long addr, } #endif /* CONFIG_MODULES */ +#if defined(MODULE) && defined(KBUILD_MODNAME) +/* We make the linker do some of the work. */ +struct module __this_module +__attribute__((section(".gnu.linkonce.this_module"))) = { + .name = __stringify(KBUILD_MODNAME), + .symbols = { .owner = &__this_module }, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif +}; +#endif /* MODULE && KBUILD_MODNAME */ + /* For archs to search exception tables */ extern struct list_head extables; extern spinlock_t modlist_lock; @@ -360,13 +369,6 @@ extern int module_dummy_usage; && __mod_between((p),(n),(m)->module_init,(m)->init_size)) \ || __mod_between((p),(n),(m)->module_core,(m)->core_size)) -/* Old-style "I'll just call it init_module and it'll be run at - insert". Use module_init(myroutine) instead. */ -#ifdef MODULE -#define init_module(voidarg) __initfn(void) -#define cleanup_module(voidarg) __exitfn(void) -#endif - /* * The exception and symbol tables, and the lock * to protect them. diff --git a/kernel/module.c b/kernel/module.c index 2209ab07e733..fe995b8d8ea9 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -60,6 +60,13 @@ struct sizes unsigned long core_size; }; +/* Stub function for modules which don't have an initfn */ +int init_module(void) +{ + return 0; +} +EXPORT_SYMBOL(init_module); + /* Find a symbol, return value and the symbol group */ static unsigned long __find_symbol(const char *name, struct kernel_symbol_group **group) @@ -357,6 +364,12 @@ static inline int try_force(unsigned int flags) } #endif /* CONFIG_MODULE_FORCE_UNLOAD */ +/* Stub function for modules which don't have an exitfn */ +void cleanup_module(void) +{ +} +EXPORT_SYMBOL(cleanup_module); + asmlinkage long sys_delete_module(const char *name_user, unsigned int flags) { @@ -406,7 +419,8 @@ sys_delete_module(const char *name_user, unsigned int flags) } /* If it has an init func, it must have an exit func to unload */ - if ((mod->init && !mod->exit) || mod->unsafe) { + if ((mod->init != init_module && mod->exit == cleanup_module) + || mod->unsafe) { forced = try_force(flags); if (!forced) { /* This module can't be removed */ @@ -453,8 +467,7 @@ sys_delete_module(const char *name_user, unsigned int flags) destroy: /* Final destruction now noone is using it. */ - if (mod->exit) - mod->exit(); + mod->exit(); free_module(mod); out: @@ -474,7 +487,7 @@ static void print_unload_info(struct seq_file *m, struct module *mod) if (mod->unsafe) seq_printf(m, " [unsafe]"); - if (mod->init && !mod->exit) + if (mod->init != init_module && mod->exit == cleanup_module) seq_printf(m, " [permanent]"); seq_printf(m, "\n"); @@ -708,15 +721,15 @@ static void free_module(struct module *mod) list_del(&mod->extable.list); spin_unlock_irq(&modlist_lock); - /* These may be NULL, but that's OK */ - module_free(mod, mod->module_init); - module_free(mod, mod->module_core); - /* Module unload stuff */ module_unload_free(mod); - /* Finally, free the module structure */ - module_free(mod, mod); + /* This may be NULL, but that's OK */ + module_free(mod, mod->module_init); + kfree(mod->args); + + /* Finally, free the core (containing the module structure) */ + module_free(mod, mod->module_core); } void *__symbol_get(const char *symbol) @@ -771,27 +784,6 @@ static void *copy_section(const char *name, return dest; } -/* Look for the special symbols */ -static int grab_private_symbols(Elf_Shdr *sechdrs, - unsigned int symbolsec, - const char *strtab, - struct module *mod) -{ - Elf_Sym *sym = (void *)sechdrs[symbolsec].sh_offset; - unsigned int i; - - for (i = 1; i < sechdrs[symbolsec].sh_size/sizeof(*sym); i++) { - if (symbol_is("__initfn", strtab + sym[i].st_name)) - mod->init = (void *)sym[i].st_value; -#ifdef CONFIG_MODULE_UNLOAD - if (symbol_is("__exitfn", strtab + sym[i].st_name)) - mod->exit = (void *)sym[i].st_value; -#endif - } - - return 0; -} - /* Deal with the given section */ static int handle_section(const char *name, Elf_Shdr *sechdrs, @@ -810,9 +802,6 @@ static int handle_section(const char *name, case SHT_RELA: ret = apply_relocate_add(sechdrs, strtab, symindex, i, mod); break; - case SHT_SYMTAB: - ret = grab_private_symbols(sechdrs, i, strtab, mod); - break; default: DEBUGP("Ignoring section %u: %s\n", i, sechdrs[i].sh_type==SHT_NULL ? "NULL": @@ -920,9 +909,6 @@ static void simplify_symbols(Elf_Shdr *sechdrs, strtab + sym[i].st_name, mod, &ksg); - /* We fake up "__this_module" */ - if (symbol_is("__this_module", strtab+sym[i].st_name)) - sym[i].st_value = (unsigned long)mod; } } } @@ -964,9 +950,9 @@ static struct module *load_module(void *umod, { Elf_Ehdr *hdr; Elf_Shdr *sechdrs; - char *secstrings; + char *secstrings, *args; unsigned int i, symindex, exportindex, strindex, setupindex, exindex, - modnameindex, obsparmindex; + modindex, obsparmindex; long arglen; unsigned long common_length; struct sizes sizes, used; @@ -1007,7 +993,7 @@ static struct module *load_module(void *umod, exportindex = setupindex = obsparmindex = 0; /* And these should exist, but gcc whinges if we don't init them */ - symindex = strindex = exindex = modnameindex = 0; + symindex = strindex = exindex = modindex = 0; /* Find where important sections are */ for (i = 1; i < hdr->e_shnum; i++) { @@ -1016,10 +1002,10 @@ static struct module *load_module(void *umod, DEBUGP("Symbol table in section %u\n", i); symindex = i; } else if (strcmp(secstrings+sechdrs[i].sh_name, - ".gnu.linkonce.modname") == 0) { - /* This module's name */ - DEBUGP("Module name in section %u\n", i); - modnameindex = i; + ".gnu.linkonce.this_module") == 0) { + /* The module struct */ + DEBUGP("Module in section %u\n", i); + modindex = i; } else if (strcmp(secstrings+sechdrs[i].sh_name, "__ksymtab") == 0) { /* Exported symbols. */ @@ -1058,39 +1044,35 @@ static struct module *load_module(void *umod, #endif } - if (!modnameindex) { - DEBUGP("Module has no name!\n"); + if (!modindex) { + printk(KERN_WARNING "No module found in object\n"); err = -ENOEXEC; goto free_hdr; } + mod = (void *)hdr + sechdrs[modindex].sh_offset; - /* Now allocate space for the module proper, and copy name and args. */ + /* Now copy in args */ err = strlen_user(uargs); if (err < 0) goto free_hdr; arglen = err; - mod = module_alloc(sizeof(*mod) + arglen+1); - if (!mod) { + args = kmalloc(arglen+1, GFP_KERNEL); + if (!args) { err = -ENOMEM; goto free_hdr; } - memset(mod, 0, sizeof(*mod) + arglen+1); - if (copy_from_user(mod->args, uargs, arglen) != 0) { + if (copy_from_user(args, uargs, arglen+1) != 0) { err = -EFAULT; goto free_mod; } - strncpy(mod->name, (char *)hdr + sechdrs[modnameindex].sh_offset, - sizeof(mod->name)-1); if (find_module(mod->name)) { err = -EEXIST; goto free_mod; } - mod->symbols.owner = mod; mod->state = MODULE_STATE_COMING; - module_unload_init(mod); /* How much space will we need? (Common area in first) */ common_length = read_commons(hdr, &sechdrs[symindex]); @@ -1139,6 +1121,9 @@ static struct module *load_module(void *umod, if (IS_ERR(ptr)) goto cleanup; sechdrs[i].sh_offset = (unsigned long)ptr; + /* Have we just copied __this_module across? */ + if (i == modindex) + mod = ptr; } else { sechdrs[i].sh_offset += (unsigned long)hdr; } @@ -1147,6 +1132,9 @@ static struct module *load_module(void *umod, if (used.init_size > mod->init_size || used.core_size > mod->core_size) BUG(); + /* Now we've moved module, initialize linked lists, etc. */ + module_unload_init(mod); + /* Fix up syms, so that st_value is a pointer to location. */ simplify_symbols(sechdrs, symindex, strindex, mod->module_core, mod); @@ -1183,6 +1171,7 @@ static struct module *load_module(void *umod, if (err < 0) goto cleanup; + mod->args = args; if (obsparmindex) { err = obsolete_params(mod->name, mod->args, (struct obsolete_modparm *) @@ -1215,7 +1204,7 @@ static struct module *load_module(void *umod, free_core: module_free(mod, mod->module_core); free_mod: - module_free(mod, mod); + kfree(args); free_hdr: vfree(hdr); if (err < 0) return ERR_PTR(err); @@ -1266,7 +1255,7 @@ sys_init_module(void *umod, up(&module_mutex); /* Start the module */ - ret = mod->init ? mod->init() : 0; + ret = mod->init(); if (ret < 0) { /* Init routine failed: abort. Try to protect us from buggy refcounters. */ -- cgit v1.2.3 From f846aa921ba1b4393655e15e79c0f6bb12e30649 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 29 Dec 2002 01:48:08 -0800 Subject: [PATCH] Trivial patch for module.c: Strtab by sh_link field. The strtab section is supposed to be found using the symtab's sh_link field, not by name. --- kernel/module.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/module.c b/kernel/module.c index fe995b8d8ea9..4b789cf97f5d 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1001,6 +1001,9 @@ static struct module *load_module(void *umod, /* Internal symbols */ DEBUGP("Symbol table in section %u\n", i); symindex = i; + /* Strings */ + strindex = sechdrs[i].sh_link; + DEBUGP("String table found in section %u\n", strindex); } else if (strcmp(secstrings+sechdrs[i].sh_name, ".gnu.linkonce.this_module") == 0) { /* The module struct */ @@ -1011,11 +1014,6 @@ static struct module *load_module(void *umod, /* Exported symbols. */ DEBUGP("EXPORT table in section %u\n", i); exportindex = i; - } else if (strcmp(secstrings + sechdrs[i].sh_name, ".strtab") - == 0) { - /* Strings */ - DEBUGP("String table found in section %u\n", i); - strindex = i; } else if (strcmp(secstrings+sechdrs[i].sh_name, "__param") == 0) { /* Setup parameter info */ -- cgit v1.2.3