switch (mk->mod->state) { case MODULE_STATE_LIVE: state = "live"; break; case MODULE_STATE_COMING: state = "coming"; break; case MODULE_STATE_GOING: state = "going"; break; } return sprintf(buffer, "%s\n", state);} static struct module_attribute modinfo_initstate = __ATTR(initstate, 0444, show_initstate, NULL); static ssize_t store_uevent(struct module_attribute *mattr, struct module_kobject *mk, const char *buffer, size_t count){ enum kobject_action action; if (kobject_action_type(buffer, count, &action) == 0) kobject_uevent(&mk->kobj, action); return count;} struct module_attribute module_uevent = __ATTR(uevent, 0200, NULL, store_uevent); static ssize_t show_coresize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer){ return sprintf(buffer, "%u\n", mk->mod->core_size);} static struct module_attribute modinfo_coresize = __ATTR(coresize, 0444, show_coresize, NULL); static ssize_t show_initsize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer){ return sprintf(buffer, "%u\n", mk->mod->init_size);} static struct module_attribute modinfo_initsize = __ATTR(initsize, 0444, show_initsize, NULL); static ssize_t show_taint(struct module_attribute *mattr, struct module_kobject *mk, char *buffer){ size_t l; l = module_flags_taint(mk->mod, buffer); buffer[l++] = '\n'; return l;} static struct module_attribute modinfo_taint = __ATTR(taint, 0444, show_taint, NULL); static struct module_attribute *modinfo_attrs[] = { &module_uevent, &modinfo_version, &modinfo_srcversion, &modinfo_initstate, &modinfo_coresize, &modinfo_initsize, &modinfo_taint,#ifdef CONFIG_MODULE_UNLOAD &modinfo_refcnt,#endif NULL,}; static const char vermagic[] = VERMAGIC_STRING; static int try_to_force_load(struct module *mod, const char *reason){#ifdef CONFIG_MODULE_FORCE_LOAD if (!test_taint(TAINT_FORCED_MODULE)) printk(KERN_WARNING "%s: %s: kernel tainted.\n", mod->name, reason); add_taint_module(mod, TAINT_FORCED_MODULE); return 0;#else return -ENOEXEC;#endif} #ifdef CONFIG_MODVERSIONS/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */static unsigned long maybe_relocated(unsigned long crc, const struct module *crc_owner){#ifdef ARCH_RELOCATES_KCRCTAB if (crc_owner == NULL) return crc - (unsigned long)reloc_start;#endif return crc;} static int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, struct module *mod, const unsigned long *crc, const struct module *crc_owner){ unsigned int i, num_versions; struct modversion_info *versions; /* Exporting module didn't supply crcs? OK, we're already tainted. */ if (!crc) return 1; /* No versions at all? modprobe --force does this. */ if (versindex == 0) return try_to_force_load(mod, symname) == 0; versions = (void *) sechdrs[versindex].sh_addr; num_versions = sechdrs[versindex].sh_size / sizeof(struct modversion_info); for (i = 0; i < num_versions; i++) { if (strcmp(versions[i].name, symname) != 0) continue; if (versions[i].crc == maybe_relocated(*crc, crc_owner)) return 1; pr_debug("Found checksum %lX vs module %lX\n", maybe_relocated(*crc, crc_owner), versions[i].crc); goto bad_version; } printk(KERN_WARNING "%s: no symbol version for %s\n", mod->name, symname); return 0; bad_version: printk("%s: disagrees about version of symbol %s\n", mod->name, symname); return 0;} static inline int check_modstruct_version(Elf_Shdr *sechdrs, unsigned int versindex, struct module *mod){ const unsigned long *crc; /* Since this should be found in kernel (which can't be removed), * no locking is necessary. */ if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, &crc, true, false)) BUG(); return check_version(sechdrs, versindex, "module_layout", mod, crc, NULL);} /* First part is kernel version, which we ignore if module has crcs. */static inline int same_magic(const char *amagic, const char *bmagic, bool has_crcs){ if (has_crcs) { amagic += strcspn(amagic, " "); bmagic += strcspn(bmagic, " "); } return strcmp(amagic, bmagic) == 0;}#elsestatic inline int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, struct module *mod, const unsigned long *crc, const struct module *crc_owner){ return 1;} static inline int check_modstruct_version(Elf_Shdr *sechdrs, unsigned int versindex, struct module *mod){ return 1;} static inline int same_magic(const char *amagic, const char *bmagic, bool has_crcs){ return strcmp(amagic, bmagic) == 0;}#endif /* CONFIG_MODVERSIONS */ /* Resolve a symbol for this module. I.e. if we find one, record usage. */static const struct kernel_symbol *resolve_symbol(struct module *mod, const struct load_info *info, const char *name, char ownername[]){ struct module *owner; const struct kernel_symbol *sym; const unsigned long *crc; int err; mutex_lock(&module_mutex); sym = find_symbol(name, &owner, &crc, !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); if (!sym) goto unlock; if (!check_version(info->sechdrs, info->index.vers, name, mod, crc, owner)) { sym = ERR_PTR(-EINVAL); goto getname; } err = ref_module(mod, owner); if (err) { sym = ERR_PTR(err); goto getname; } getname: /* We must make copy under the lock if we failed to get ref. */ strncpy(ownername, module_name(owner), MODULE_NAME_LEN);unlock: mutex_unlock(&module_mutex); return sym;} static const struct kernel_symbol *resolve_symbol_wait(struct module *mod, const struct load_info *info, const char *name){ const struct kernel_symbol *ksym; char owner[MODULE_NAME_LEN]; if (wait_event_interruptible_timeout(module_wq, !IS_ERR(ksym = resolve_symbol(mod, info, name, owner)) || PTR_ERR(ksym) != -EBUSY, 30 * HZ) <= 0) { printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n", mod->name, owner); } return ksym;} /* * /sys/module/foo/sections stuff * J. Corbet <corbet@lwn.net> */#ifdef CONFIG_SYSFS #ifdef CONFIG_KALLSYMSstatic inline bool sect_empty(const Elf_Shdr *sect){ return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0;} struct module_sect_attr{ struct module_attribute mattr; char *name; unsigned long address;}; struct module_sect_attrs{ struct attribute_group grp; unsigned int nsections; struct module_sect_attr attrs[0];}; static ssize_t module_sect_show(struct module_attribute *mattr, struct module_kobject *mk, char *buf){ struct module_sect_attr *sattr = container_of(mattr, struct module_sect_attr, mattr); return sprintf(buf, "0x%pK\n", (void *)sattr->address);} static void free_sect_attrs(struct module_sect_attrs *sect_attrs){ unsigned int section; for (section = 0; section < sect_attrs->nsections; section++) kfree(sect_attrs->attrs[section].name); kfree(sect_attrs);} static void add_sect_attrs(struct module *mod, const struct load_info *info){ unsigned int nloaded = 0, i, size[2]; struct module_sect_attrs *sect_attrs; struct module_sect_attr *sattr; struct attribute **gattr; /* Count loaded sections and allocate structures */ for (i = 0; i < info->hdr->e_shnum; i++) if (!sect_empty(&info->sechdrs[i])) nloaded++; size[0] = ALIGN(sizeof(*sect_attrs) + nloaded * sizeof(sect_attrs->attrs[0]), sizeof(sect_attrs->grp.attrs[0])); size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]); sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL); if (sect_attrs == NULL) return; /* Setup section attributes. */ sect_attrs->grp.name = "sections"; sect_attrs->grp.attrs = (void *)sect_attrs + size[0]; sect_attrs->nsections = 0; sattr = §_attrs->attrs[0]; gattr = §_attrs->grp.attrs[0]; for (i = 0; i < info->hdr->e_shnum; i++) { Elf_Shdr *sec = &info->sechdrs[i]; if (sect_empty(sec)) continue; sattr->address = sec->sh_addr; sattr->name = kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL); if (sattr->name == NULL) goto out; sect_attrs->nsections++; sysfs_attr_init(&sattr->mattr.attr); sattr->mattr.show = module_sect_show; sattr->mattr.store = NULL; sattr->mattr.attr.name = sattr->name; sattr->mattr.attr.mode = S_IRUGO; *(gattr++) = &(sattr++)->mattr.attr; } *gattr = NULL; if (sysfs_create_group(&mod->mkobj.kobj, §_attrs->grp)) goto out; mod->sect_attrs = sect_attrs; return; out: free_sect_attrs(sect_attrs);} static void remove_sect_attrs(struct module *mod){ if (mod->sect_attrs) { sysfs_remove_group(&mod->mkobj.kobj, &mod->sect_attrs->grp); /* We are positive that no one is using any sect attrs * at this point. Deallocate immediately. */ free_sect_attrs(mod->sect_attrs); mod->sect_attrs = NULL; }} /* * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections. */ struct module_notes_attrs { struct kobject *dir; unsigned int notes; struct bin_attribute attrs[0];}; static ssize_t module_notes_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count){ /* * The caller checked the pos and count against our size. */ memcpy(buf, bin_attr->private + pos, count); return count;} static void free_notes_attrs(struct module_notes_attrs *notes_attrs, unsigned int i){ if (notes_attrs->dir) { while (i-- > 0) sysfs_remove_bin_file(notes_attrs->dir, ¬es_attrs->attrs[i]); kobject_put(notes_attrs->dir); } kfree(notes_attrs);} static void add_notes_attrs(struct module *mod, const struct load_info *info){ unsigned int notes, loaded, i; struct module_notes_attrs *notes_attrs; struct bin_attribute *nattr; /* failed to create section attributes, so can't create notes */ if (!mod->sect_attrs) return; /* Count notes sections and allocate structures. */ notes = 0; for (i = 0; i < info->hdr->e_shnum; i++) if (!sect_empty(&info->sechdrs[i]) && (info->sechdrs[i].sh_type == SHT_NOTE)) ++notes; if (notes == 0) return; notes_attrs = kzalloc(sizeof(*notes_attrs) + notes * sizeof(notes_attrs->attrs[0]), GFP_KERNEL); if (notes_attrs == NULL) return; notes_attrs->notes = notes; nattr = ¬es_attrs->attrs[0]; for (loaded = i = 0; i < info->hdr->e_shnum; ++i) { if (sect_empty(&info->sechdrs[i])) continue; if (info->sechdrs[i].sh_type == SHT_NOTE) { sysfs_bin_attr_init(nattr); nattr->attr.name = mod->sect_attrs->attrs[loaded].name; nattr->attr.mode = S_IRUGO; nattr->size = info->sechdrs[i].sh_size; nattr->private = (void *) info->sechdrs[i].sh_addr; nattr->read = module_notes_read; ++nattr; } ++loaded; } notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj); if (!notes_attrs->dir) goto out; for (i = 0; i < notes; ++i) if (sysfs_create_bin_file(notes_attrs->dir, ¬es_attrs->attrs[i])) goto out; mod->notes_attrs = notes_attrs; return; out: free_notes_attrs(notes_attrs, i);} static void remove_notes_attrs(struct module *mod){ if (mod->notes_attrs) free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes);} #else static inline void add_sect_attrs(struct module *mod, const struct load_info *info){} static inline void remove_sect_attrs(struct module *mod){} static inline void add_notes_attrs(struct module *mod, const struct load_info *info){} static inline void remove_notes_attrs(struct module *mod){}#endif /* CONFIG_KALLSYMS */ static void add_usage_links(struct module *mod){#ifdef CONFIG_MODULE_UNLOAD struct module_use *use; int nowarn; mutex_lock(&module_mutex); list_for_each_entry(use, &mod->target_list, target_list) { nowarn = sysfs_create_link(use->target->holders_dir, &mod->mkobj.kobj, mod->name); } mutex_unlock(&module_mutex);#endif} static void del_usage_links(struct module *mod){#ifdef CONFIG_MODULE_UNLOAD struct module_use *use; mutex_lock(&module_mutex);Lines 1001–1500 of 3539. Previous lines Load more
switch (mk->mod->state) { case MODULE_STATE_LIVE: state = "live"; break; case MODULE_STATE_COMING: state = "coming"; break; case MODULE_STATE_GOING: state = "going"; break; } return sprintf(buffer, "%s\n", state); } static struct module_attribute modinfo_initstate = __ATTR(initstate, 0444, show_initstate, NULL); static ssize_t store_uevent(struct module_attribute *mattr, struct module_kobject *mk, const char *buffer, size_t count) { enum kobject_action action; if (kobject_action_type(buffer, count, &action) == 0) kobject_uevent(&mk->kobj, action); return count; } struct module_attribute module_uevent = __ATTR(uevent, 0200, NULL, store_uevent); static ssize_t show_coresize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { return sprintf(buffer, "%u\n", mk->mod->core_size); } static struct module_attribute modinfo_coresize = __ATTR(coresize, 0444, show_coresize, NULL); static ssize_t show_initsize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { return sprintf(buffer, "%u\n", mk->mod->init_size); } static struct module_attribute modinfo_initsize = __ATTR(initsize, 0444, show_initsize, NULL); static ssize_t show_taint(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { size_t l; l = module_flags_taint(mk->mod, buffer); buffer[l++] = '\n'; return l; } static struct module_attribute modinfo_taint = __ATTR(taint, 0444, show_taint, NULL); static struct module_attribute *modinfo_attrs[] = { &module_uevent, &modinfo_version, &modinfo_srcversion, &modinfo_initstate, &modinfo_coresize, &modinfo_initsize, &modinfo_taint, #ifdef CONFIG_MODULE_UNLOAD &modinfo_refcnt, #endif NULL, }; static const char vermagic[] = VERMAGIC_STRING; static int try_to_force_load(struct module *mod, const char *reason) { #ifdef CONFIG_MODULE_FORCE_LOAD if (!test_taint(TAINT_FORCED_MODULE)) printk(KERN_WARNING "%s: %s: kernel tainted.\n", mod->name, reason); add_taint_module(mod, TAINT_FORCED_MODULE); return 0; #else return -ENOEXEC; #endif } #ifdef CONFIG_MODVERSIONS /* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */ static unsigned long maybe_relocated(unsigned long crc, const struct module *crc_owner) { #ifdef ARCH_RELOCATES_KCRCTAB if (crc_owner == NULL) return crc - (unsigned long)reloc_start; #endif return crc; } static int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, struct module *mod, const unsigned long *crc, const struct module *crc_owner) { unsigned int i, num_versions; struct modversion_info *versions; /* Exporting module didn't supply crcs? OK, we're already tainted. */ if (!crc) return 1; /* No versions at all? modprobe --force does this. */ if (versindex == 0) return try_to_force_load(mod, symname) == 0; versions = (void *) sechdrs[versindex].sh_addr; num_versions = sechdrs[versindex].sh_size / sizeof(struct modversion_info); for (i = 0; i < num_versions; i++) { if (strcmp(versions[i].name, symname) != 0) continue; if (versions[i].crc == maybe_relocated(*crc, crc_owner)) return 1; pr_debug("Found checksum %lX vs module %lX\n", maybe_relocated(*crc, crc_owner), versions[i].crc); goto bad_version; } printk(KERN_WARNING "%s: no symbol version for %s\n", mod->name, symname); return 0; bad_version: printk("%s: disagrees about version of symbol %s\n", mod->name, symname); return 0; } static inline int check_modstruct_version(Elf_Shdr *sechdrs, unsigned int versindex, struct module *mod) { const unsigned long *crc; /* Since this should be found in kernel (which can't be removed), * no locking is necessary. */ if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, &crc, true, false)) BUG(); return check_version(sechdrs, versindex, "module_layout", mod, crc, NULL); } /* First part is kernel version, which we ignore if module has crcs. */ static inline int same_magic(const char *amagic, const char *bmagic, bool has_crcs) { if (has_crcs) { amagic += strcspn(amagic, " "); bmagic += strcspn(bmagic, " "); } return strcmp(amagic, bmagic) == 0; } #else static inline int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, struct module *mod, const unsigned long *crc, const struct module *crc_owner) { return 1; } static inline int check_modstruct_version(Elf_Shdr *sechdrs, unsigned int versindex, struct module *mod) { return 1; } static inline int same_magic(const char *amagic, const char *bmagic, bool has_crcs) { return strcmp(amagic, bmagic) == 0; } #endif /* CONFIG_MODVERSIONS */ /* Resolve a symbol for this module. I.e. if we find one, record usage. */ static const struct kernel_symbol *resolve_symbol(struct module *mod, const struct load_info *info, const char *name, char ownername[]) { struct module *owner; const struct kernel_symbol *sym; const unsigned long *crc; int err; mutex_lock(&module_mutex); sym = find_symbol(name, &owner, &crc, !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); if (!sym) goto unlock; if (!check_version(info->sechdrs, info->index.vers, name, mod, crc, owner)) { sym = ERR_PTR(-EINVAL); goto getname; } err = ref_module(mod, owner); if (err) { sym = ERR_PTR(err); goto getname; } getname: /* We must make copy under the lock if we failed to get ref. */ strncpy(ownername, module_name(owner), MODULE_NAME_LEN); unlock: mutex_unlock(&module_mutex); return sym; } static const struct kernel_symbol * resolve_symbol_wait(struct module *mod, const struct load_info *info, const char *name) { const struct kernel_symbol *ksym; char owner[MODULE_NAME_LEN]; if (wait_event_interruptible_timeout(module_wq, !IS_ERR(ksym = resolve_symbol(mod, info, name, owner)) || PTR_ERR(ksym) != -EBUSY, 30 * HZ) <= 0) { printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n", mod->name, owner); } return ksym; } /* * /sys/module/foo/sections stuff * J. Corbet <corbet@lwn.net> */ #ifdef CONFIG_SYSFS #ifdef CONFIG_KALLSYMS static inline bool sect_empty(const Elf_Shdr *sect) { return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0; } struct module_sect_attr { struct module_attribute mattr; char *name; unsigned long address; }; struct module_sect_attrs { struct attribute_group grp; unsigned int nsections; struct module_sect_attr attrs[0]; }; static ssize_t module_sect_show(struct module_attribute *mattr, struct module_kobject *mk, char *buf) { struct module_sect_attr *sattr = container_of(mattr, struct module_sect_attr, mattr); return sprintf(buf, "0x%pK\n", (void *)sattr->address); } static void free_sect_attrs(struct module_sect_attrs *sect_attrs) { unsigned int section; for (section = 0; section < sect_attrs->nsections; section++) kfree(sect_attrs->attrs[section].name); kfree(sect_attrs); } static void add_sect_attrs(struct module *mod, const struct load_info *info) { unsigned int nloaded = 0, i, size[2]; struct module_sect_attrs *sect_attrs; struct module_sect_attr *sattr; struct attribute **gattr; /* Count loaded sections and allocate structures */ for (i = 0; i < info->hdr->e_shnum; i++) if (!sect_empty(&info->sechdrs[i])) nloaded++; size[0] = ALIGN(sizeof(*sect_attrs) + nloaded * sizeof(sect_attrs->attrs[0]), sizeof(sect_attrs->grp.attrs[0])); size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]); sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL); if (sect_attrs == NULL) return; /* Setup section attributes. */ sect_attrs->grp.name = "sections"; sect_attrs->grp.attrs = (void *)sect_attrs + size[0]; sect_attrs->nsections = 0; sattr = §_attrs->attrs[0]; gattr = §_attrs->grp.attrs[0]; for (i = 0; i < info->hdr->e_shnum; i++) { Elf_Shdr *sec = &info->sechdrs[i]; if (sect_empty(sec)) continue; sattr->address = sec->sh_addr; sattr->name = kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL); if (sattr->name == NULL) goto out; sect_attrs->nsections++; sysfs_attr_init(&sattr->mattr.attr); sattr->mattr.show = module_sect_show; sattr->mattr.store = NULL; sattr->mattr.attr.name = sattr->name; sattr->mattr.attr.mode = S_IRUGO; *(gattr++) = &(sattr++)->mattr.attr; } *gattr = NULL; if (sysfs_create_group(&mod->mkobj.kobj, §_attrs->grp)) goto out; mod->sect_attrs = sect_attrs; return; out: free_sect_attrs(sect_attrs); } static void remove_sect_attrs(struct module *mod) { if (mod->sect_attrs) { sysfs_remove_group(&mod->mkobj.kobj, &mod->sect_attrs->grp); /* We are positive that no one is using any sect attrs * at this point. Deallocate immediately. */ free_sect_attrs(mod->sect_attrs); mod->sect_attrs = NULL; } } /* * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections. */ struct module_notes_attrs { struct kobject *dir; unsigned int notes; struct bin_attribute attrs[0]; }; static ssize_t module_notes_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { /* * The caller checked the pos and count against our size. */ memcpy(buf, bin_attr->private + pos, count); return count; } static void free_notes_attrs(struct module_notes_attrs *notes_attrs, unsigned int i) { if (notes_attrs->dir) { while (i-- > 0) sysfs_remove_bin_file(notes_attrs->dir, ¬es_attrs->attrs[i]); kobject_put(notes_attrs->dir); } kfree(notes_attrs); } static void add_notes_attrs(struct module *mod, const struct load_info *info) { unsigned int notes, loaded, i; struct module_notes_attrs *notes_attrs; struct bin_attribute *nattr; /* failed to create section attributes, so can't create notes */ if (!mod->sect_attrs) return; /* Count notes sections and allocate structures. */ notes = 0; for (i = 0; i < info->hdr->e_shnum; i++) if (!sect_empty(&info->sechdrs[i]) && (info->sechdrs[i].sh_type == SHT_NOTE)) ++notes; if (notes == 0) return; notes_attrs = kzalloc(sizeof(*notes_attrs) + notes * sizeof(notes_attrs->attrs[0]), GFP_KERNEL); if (notes_attrs == NULL) return; notes_attrs->notes = notes; nattr = ¬es_attrs->attrs[0]; for (loaded = i = 0; i < info->hdr->e_shnum; ++i) { if (sect_empty(&info->sechdrs[i])) continue; if (info->sechdrs[i].sh_type == SHT_NOTE) { sysfs_bin_attr_init(nattr); nattr->attr.name = mod->sect_attrs->attrs[loaded].name; nattr->attr.mode = S_IRUGO; nattr->size = info->sechdrs[i].sh_size; nattr->private = (void *) info->sechdrs[i].sh_addr; nattr->read = module_notes_read; ++nattr; } ++loaded; } notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj); if (!notes_attrs->dir) goto out; for (i = 0; i < notes; ++i) if (sysfs_create_bin_file(notes_attrs->dir, ¬es_attrs->attrs[i])) goto out; mod->notes_attrs = notes_attrs; return; out: free_notes_attrs(notes_attrs, i); } static void remove_notes_attrs(struct module *mod) { if (mod->notes_attrs) free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes); } #else static inline void add_sect_attrs(struct module *mod, const struct load_info *info) { } static inline void remove_sect_attrs(struct module *mod) { } static inline void add_notes_attrs(struct module *mod, const struct load_info *info) { } static inline void remove_notes_attrs(struct module *mod) { } #endif /* CONFIG_KALLSYMS */ static void add_usage_links(struct module *mod) { #ifdef CONFIG_MODULE_UNLOAD struct module_use *use; int nowarn; mutex_lock(&module_mutex); list_for_each_entry(use, &mod->target_list, target_list) { nowarn = sysfs_create_link(use->target->holders_dir, &mod->mkobj.kobj, mod->name); } mutex_unlock(&module_mutex); #endif } static void del_usage_links(struct module *mod) { #ifdef CONFIG_MODULE_UNLOAD struct module_use *use; mutex_lock(&module_mutex);