/* * Since we're a binary read handler, we must account for the * trailing NUL byte that sprintf will write: if "buf" is * too small to hold the NUL, or the NUL is exactly the last * byte, the read will look like it got truncated by one byte. * Since there is no way to ask sprintf nicely to not write * the NUL, we have to use a bounce buffer.
*/
wrote = scnprintf(bounce, sizeof(bounce), "0x%px\n",
kallsyms_show_value(file->f_cred)
? battr->private : NULL);
count = min(count, wrote);
memcpy(buf, bounce, count);
/* Count loaded sections and allocate structures */ for (i = 0; i < info->hdr->e_shnum; i++) if (!sect_empty(&info->sechdrs[i]))
nloaded++;
sect_attrs = kzalloc(struct_size(sect_attrs, attrs, nloaded), GFP_KERNEL); if (!sect_attrs) return -ENOMEM;
staticvoid 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.
*/
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].attr.name;
nattr->attr.mode = 0444;
nattr->size = info->sechdrs[i].sh_size;
nattr->private = (void *)info->sechdrs[i].sh_addr;
nattr->read = sysfs_bin_attr_simple_read;
*(gattr++) = nattr++;
}
++loaded;
}
ret = sysfs_create_group(&mod->mkobj.kobj, ¬es_attrs->grp); if (ret) goto out;
mod->notes_attrs = notes_attrs; return 0;
out:
free_notes_attrs(notes_attrs); return ret;
}
staticvoid remove_notes_attrs(struct module *mod)
{ if (mod->notes_attrs) {
sysfs_remove_group(&mod->mkobj.kobj,
&mod->notes_attrs->grp); /* * We are positive that no one is using any notes attrs * at this point. Deallocate immediately.
*/
free_notes_attrs(mod->notes_attrs);
mod->notes_attrs = NULL;
}
}
staticint add_usage_links(struct module *mod)
{ int ret = 0; #ifdef CONFIG_MODULE_UNLOAD struct module_use *use;
mutex_lock(&module_mutex);
list_for_each_entry(use, &mod->target_list, target_list) {
ret = sysfs_create_link(use->target->holders_dir,
&mod->mkobj.kobj, mod->name); if (ret) break;
}
mutex_unlock(&module_mutex); if (ret)
del_usage_links(mod); #endif return ret;
}
staticvoid module_remove_modinfo_attrs(struct module *mod, int end)
{ conststruct module_attribute *attr; int i;
for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) { if (end >= 0 && i > end) break; /* pick a field to test for end of list */ if (!attr->attr.name) break;
sysfs_remove_file(&mod->mkobj.kobj, &attr->attr); if (attr->free)
attr->free(mod);
}
kfree(mod->modinfo_attrs);
}
staticint module_add_modinfo_attrs(struct module *mod)
{ conststruct module_attribute *attr; struct module_attribute *temp_attr; int error = 0; int i;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.