aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c77
1 files changed, 34 insertions, 43 deletions
diff --git a/kernel/module.c b/kernel/module.c
index fb11e2a88233..fd8d46c69766 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1126,8 +1126,9 @@ static const struct kernel_symbol *resolve_symbol_wait(Elf_Shdr *sechdrs,
1126 * /sys/module/foo/sections stuff 1126 * /sys/module/foo/sections stuff
1127 * J. Corbet <corbet@lwn.net> 1127 * J. Corbet <corbet@lwn.net>
1128 */ 1128 */
1129#if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS) 1129#ifdef CONFIG_SYSFS
1130 1130
1131#ifdef CONFIG_KALLSYMS
1131static inline bool sect_empty(const Elf_Shdr *sect) 1132static inline bool sect_empty(const Elf_Shdr *sect)
1132{ 1133{
1133 return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0; 1134 return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0;
@@ -1164,8 +1165,7 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
1164 kfree(sect_attrs); 1165 kfree(sect_attrs);
1165} 1166}
1166 1167
1167static void add_sect_attrs(struct module *mod, unsigned int nsect, 1168static void add_sect_attrs(struct module *mod, const struct load_info *info)
1168 char *secstrings, Elf_Shdr *sechdrs)
1169{ 1169{
1170 unsigned int nloaded = 0, i, size[2]; 1170 unsigned int nloaded = 0, i, size[2];
1171 struct module_sect_attrs *sect_attrs; 1171 struct module_sect_attrs *sect_attrs;
@@ -1173,8 +1173,8 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
1173 struct attribute **gattr; 1173 struct attribute **gattr;
1174 1174
1175 /* Count loaded sections and allocate structures */ 1175 /* Count loaded sections and allocate structures */
1176 for (i = 0; i < nsect; i++) 1176 for (i = 0; i < info->hdr->e_shnum; i++)
1177 if (!sect_empty(&sechdrs[i])) 1177 if (!sect_empty(&info->sechdrs[i]))
1178 nloaded++; 1178 nloaded++;
1179 size[0] = ALIGN(sizeof(*sect_attrs) 1179 size[0] = ALIGN(sizeof(*sect_attrs)
1180 + nloaded * sizeof(sect_attrs->attrs[0]), 1180 + nloaded * sizeof(sect_attrs->attrs[0]),
@@ -1191,11 +1191,12 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
1191 sect_attrs->nsections = 0; 1191 sect_attrs->nsections = 0;
1192 sattr = &sect_attrs->attrs[0]; 1192 sattr = &sect_attrs->attrs[0];
1193 gattr = &sect_attrs->grp.attrs[0]; 1193 gattr = &sect_attrs->grp.attrs[0];
1194 for (i = 0; i < nsect; i++) { 1194 for (i = 0; i < info->hdr->e_shnum; i++) {
1195 if (sect_empty(&sechdrs[i])) 1195 Elf_Shdr *sec = &info->sechdrs[i];
1196 if (sect_empty(sec))
1196 continue; 1197 continue;
1197 sattr->address = sechdrs[i].sh_addr; 1198 sattr->address = sec->sh_addr;
1198 sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, 1199 sattr->name = kstrdup(info->secstrings + sec->sh_name,
1199 GFP_KERNEL); 1200 GFP_KERNEL);
1200 if (sattr->name == NULL) 1201 if (sattr->name == NULL)
1201 goto out; 1202 goto out;
@@ -1263,8 +1264,7 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
1263 kfree(notes_attrs); 1264 kfree(notes_attrs);
1264} 1265}
1265 1266
1266static void add_notes_attrs(struct module *mod, unsigned int nsect, 1267static void add_notes_attrs(struct module *mod, const struct load_info *info)
1267 char *secstrings, Elf_Shdr *sechdrs)
1268{ 1268{
1269 unsigned int notes, loaded, i; 1269 unsigned int notes, loaded, i;
1270 struct module_notes_attrs *notes_attrs; 1270 struct module_notes_attrs *notes_attrs;
@@ -1276,9 +1276,9 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
1276 1276
1277 /* Count notes sections and allocate structures. */ 1277 /* Count notes sections and allocate structures. */
1278 notes = 0; 1278 notes = 0;
1279 for (i = 0; i < nsect; i++) 1279 for (i = 0; i < info->hdr->e_shnum; i++)
1280 if (!sect_empty(&sechdrs[i]) && 1280 if (!sect_empty(&info->sechdrs[i]) &&
1281 (sechdrs[i].sh_type == SHT_NOTE)) 1281 (info->sechdrs[i].sh_type == SHT_NOTE))
1282 ++notes; 1282 ++notes;
1283 1283
1284 if (notes == 0) 1284 if (notes == 0)
@@ -1292,15 +1292,15 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
1292 1292
1293 notes_attrs->notes = notes; 1293 notes_attrs->notes = notes;
1294 nattr = &notes_attrs->attrs[0]; 1294 nattr = &notes_attrs->attrs[0];
1295 for (loaded = i = 0; i < nsect; ++i) { 1295 for (loaded = i = 0; i < info->hdr->e_shnum; ++i) {
1296 if (sect_empty(&sechdrs[i])) 1296 if (sect_empty(&info->sechdrs[i]))
1297 continue; 1297 continue;
1298 if (sechdrs[i].sh_type == SHT_NOTE) { 1298 if (info->sechdrs[i].sh_type == SHT_NOTE) {
1299 sysfs_bin_attr_init(nattr); 1299 sysfs_bin_attr_init(nattr);
1300 nattr->attr.name = mod->sect_attrs->attrs[loaded].name; 1300 nattr->attr.name = mod->sect_attrs->attrs[loaded].name;
1301 nattr->attr.mode = S_IRUGO; 1301 nattr->attr.mode = S_IRUGO;
1302 nattr->size = sechdrs[i].sh_size; 1302 nattr->size = info->sechdrs[i].sh_size;
1303 nattr->private = (void *) sechdrs[i].sh_addr; 1303 nattr->private = (void *) info->sechdrs[i].sh_addr;
1304 nattr->read = module_notes_read; 1304 nattr->read = module_notes_read;
1305 ++nattr; 1305 ++nattr;
1306 } 1306 }
@@ -1331,8 +1331,8 @@ static void remove_notes_attrs(struct module *mod)
1331 1331
1332#else 1332#else
1333 1333
1334static inline void add_sect_attrs(struct module *mod, unsigned int nsect, 1334static inline void add_sect_attrs(struct module *mod,
1335 char *sectstrings, Elf_Shdr *sechdrs) 1335 const struct load_info *info)
1336{ 1336{
1337} 1337}
1338 1338
@@ -1340,17 +1340,16 @@ static inline void remove_sect_attrs(struct module *mod)
1340{ 1340{
1341} 1341}
1342 1342
1343static inline void add_notes_attrs(struct module *mod, unsigned int nsect, 1343static inline void add_notes_attrs(struct module *mod,
1344 char *sectstrings, Elf_Shdr *sechdrs) 1344 const struct load_info *info)
1345{ 1345{
1346} 1346}
1347 1347
1348static inline void remove_notes_attrs(struct module *mod) 1348static inline void remove_notes_attrs(struct module *mod)
1349{ 1349{
1350} 1350}
1351#endif 1351#endif /* CONFIG_KALLSYMS */
1352 1352
1353#ifdef CONFIG_SYSFS
1354static void add_usage_links(struct module *mod) 1353static void add_usage_links(struct module *mod)
1355{ 1354{
1356#ifdef CONFIG_MODULE_UNLOAD 1355#ifdef CONFIG_MODULE_UNLOAD
@@ -1455,6 +1454,7 @@ out:
1455} 1454}
1456 1455
1457static int mod_sysfs_setup(struct module *mod, 1456static int mod_sysfs_setup(struct module *mod,
1457 const struct load_info *info,
1458 struct kernel_param *kparam, 1458 struct kernel_param *kparam,
1459 unsigned int num_params) 1459 unsigned int num_params)
1460{ 1460{
@@ -1479,6 +1479,8 @@ static int mod_sysfs_setup(struct module *mod,
1479 goto out_unreg_param; 1479 goto out_unreg_param;
1480 1480
1481 add_usage_links(mod); 1481 add_usage_links(mod);
1482 add_sect_attrs(mod, info);
1483 add_notes_attrs(mod, info);
1482 1484
1483 kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); 1485 kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
1484 return 0; 1486 return 0;
@@ -1495,32 +1497,26 @@ out:
1495 1497
1496static void mod_sysfs_fini(struct module *mod) 1498static void mod_sysfs_fini(struct module *mod)
1497{ 1499{
1500 remove_notes_attrs(mod);
1501 remove_sect_attrs(mod);
1498 kobject_put(&mod->mkobj.kobj); 1502 kobject_put(&mod->mkobj.kobj);
1499} 1503}
1500 1504
1501#else /* CONFIG_SYSFS */ 1505#else /* !CONFIG_SYSFS */
1502 1506
1503static inline int mod_sysfs_init(struct module *mod) 1507static int mod_sysfs_init(struct module *mod)
1504{ 1508{
1505 return 0; 1509 return 0;
1506} 1510}
1507 1511
1508static inline int mod_sysfs_setup(struct module *mod, 1512static int mod_sysfs_setup(struct module *mod,
1513 const struct load_info *info,
1509 struct kernel_param *kparam, 1514 struct kernel_param *kparam,
1510 unsigned int num_params) 1515 unsigned int num_params)
1511{ 1516{
1512 return 0; 1517 return 0;
1513} 1518}
1514 1519
1515static inline int module_add_modinfo_attrs(struct module *mod)
1516{
1517 return 0;
1518}
1519
1520static inline void module_remove_modinfo_attrs(struct module *mod)
1521{
1522}
1523
1524static void mod_sysfs_fini(struct module *mod) 1520static void mod_sysfs_fini(struct module *mod)
1525{ 1521{
1526} 1522}
@@ -1561,8 +1557,6 @@ static void free_module(struct module *mod)
1561 mutex_lock(&module_mutex); 1557 mutex_lock(&module_mutex);
1562 stop_machine(__unlink_module, mod, NULL); 1558 stop_machine(__unlink_module, mod, NULL);
1563 mutex_unlock(&module_mutex); 1559 mutex_unlock(&module_mutex);
1564 remove_notes_attrs(mod);
1565 remove_sect_attrs(mod);
1566 mod_kobject_remove(mod); 1560 mod_kobject_remove(mod);
1567 1561
1568 /* Remove dynamic debug info */ 1562 /* Remove dynamic debug info */
@@ -2691,13 +2685,10 @@ static noinline struct module *load_module(void __user *umod,
2691 if (err < 0) 2685 if (err < 0)
2692 goto unlink; 2686 goto unlink;
2693 2687
2694 err = mod_sysfs_setup(mod, mod->kp, mod->num_kp); 2688 err = mod_sysfs_setup(mod, &info, mod->kp, mod->num_kp);
2695 if (err < 0) 2689 if (err < 0)
2696 goto unlink; 2690 goto unlink;
2697 2691
2698 add_sect_attrs(mod, info.hdr->e_shnum, info.secstrings, info.sechdrs);
2699 add_notes_attrs(mod, info.hdr->e_shnum, info.secstrings, info.sechdrs);
2700
2701 /* Get rid of temporary copy and strmap. */ 2692 /* Get rid of temporary copy and strmap. */
2702 kfree(info.strmap); 2693 kfree(info.strmap);
2703 free_copy(&info); 2694 free_copy(&info);