X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fmodule.c;h=dfe295ecf2f104dfb09678be30322c1da4f4127e;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=e7a73bac2d58a4524cca09e85db3a5493bd3f431;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/kernel/module.c b/kernel/module.c index e7a73bac2..dfe295ecf 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #if 0 @@ -52,9 +51,6 @@ /* If this is set, the section belongs in the init part of the module */ #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) -#define symbol_is(literal, string) \ - (strcmp(MODULE_SYMBOL_PREFIX literal, (string)) == 0) - /* Protects module list */ static spinlock_t modlist_lock = SPIN_LOCK_UNLOCKED; @@ -717,7 +713,7 @@ static inline void module_unload_init(struct module *mod) } asmlinkage long -sys_delete_module(const char *name_user, unsigned int flags) +sys_delete_module(const char __user *name_user, unsigned int flags) { return -ENOSYS; } @@ -981,6 +977,104 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, return ret; } + +/* + * /sys/module/foo/sections stuff + * J. Corbet + */ +#ifdef CONFIG_KALLSYMS +static void module_sect_attrs_release(struct kobject *kobj) +{ + kfree(container_of(kobj, struct module_sections, kobj)); +} + +static ssize_t module_sect_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct module_sect_attr *sattr = + container_of(attr, struct module_sect_attr, attr); + return sprintf(buf, "0x%lx\n", sattr->address); +} + +static struct sysfs_ops module_sect_ops = { + .show = module_sect_show, +}; + +static struct kobj_type module_sect_ktype = { + .sysfs_ops = &module_sect_ops, + .release = module_sect_attrs_release, +}; + +static void add_sect_attrs(struct module *mod, unsigned int nsect, + char *secstrings, Elf_Shdr *sechdrs) +{ + unsigned int nloaded = 0, i; + struct module_sect_attr *sattr; + + if (!mod->mkobj) + return; + + /* Count loaded sections and allocate structures */ + for (i = 0; i < nsect; i++) + if (sechdrs[i].sh_flags & SHF_ALLOC) + nloaded++; + mod->sect_attrs = kmalloc(sizeof(struct module_sections) + + nloaded*sizeof(mod->sect_attrs->attrs[0]), GFP_KERNEL); + if (! mod->sect_attrs) + return; + + /* sections entry setup */ + memset(mod->sect_attrs, 0, sizeof(struct module_sections)); + if (kobject_set_name(&mod->sect_attrs->kobj, "sections")) + goto out; + mod->sect_attrs->kobj.parent = &mod->mkobj->kobj; + mod->sect_attrs->kobj.ktype = &module_sect_ktype; + if (kobject_register(&mod->sect_attrs->kobj)) + goto out; + + /* And the section attributes. */ + sattr = &mod->sect_attrs->attrs[0]; + for (i = 0; i < nsect; i++) { + if (! (sechdrs[i].sh_flags & SHF_ALLOC)) + continue; + sattr->address = sechdrs[i].sh_addr; + strlcpy(sattr->name, secstrings + sechdrs[i].sh_name, + MODULE_SECT_NAME_LEN); + sattr->attr.name = sattr->name; + sattr->attr.owner = mod; + sattr->attr.mode = S_IRUGO; + (void) sysfs_create_file(&mod->sect_attrs->kobj, &sattr->attr); + sattr++; + } + return; + out: + kfree(mod->sect_attrs); + mod->sect_attrs = NULL; +} + +static void remove_sect_attrs(struct module *mod) +{ + if (mod->sect_attrs) { + kobject_unregister(&mod->sect_attrs->kobj); + mod->sect_attrs = NULL; + } +} + + +#else +static inline void add_sect_attrs(struct module *mod, unsigned int nsect, + char *sectstrings, Elf_Shdr *sechdrs) +{ +} + +static inline void remove_sect_attrs(struct module *mod) +{ +} +#endif /* CONFIG_KALLSYMS */ + + + + #define to_module_attr(n) container_of(n, struct module_attribute, attr); static ssize_t module_attr_show(struct kobject *kobj, @@ -1099,6 +1193,7 @@ static void free_module(struct module *mod) list_del(&mod->list); spin_unlock_irq(&modlist_lock); + remove_sect_attrs(mod); mod_kobject_remove(mod); /* Arch-specific cleanup. */ @@ -1712,6 +1807,7 @@ static struct module *load_module(void __user *umod, / sizeof(struct kernel_param)); if (err < 0) goto arch_cleanup; + add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); /* Get rid of temporary copy */ vfree(hdr); @@ -2029,7 +2125,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) } /* Is this a valid kernel address? We don't grab the lock: we are oopsing. */ -struct module *module_text_address(unsigned long addr) +struct module *__module_text_address(unsigned long addr) { struct module *mod; @@ -2040,6 +2136,18 @@ struct module *module_text_address(unsigned long addr) return NULL; } +struct module *module_text_address(unsigned long addr) +{ + struct module *mod; + unsigned long flags; + + spin_lock_irqsave(&modlist_lock, flags); + mod = __module_text_address(addr); + spin_unlock_irqrestore(&modlist_lock, flags); + + return mod; +} + /* Don't grab lock, we're oopsing. */ void print_modules(void) {