1 #include <linux/config.h>
2 #include <linux/mm.h>
3 #include <linux/module.h>
4 #include <asm/uaccess.h>
5 #include <linux/vmalloc.h>
6 #include <linux/smp_lock.h>
7 #include <asm/pgtable.h>
8 #include <linux/init.h>
9
10 /*
11 * Originally by Anonymous (as far as I know...)
12 * Linux version by Bas Laarhoven <bas@vimec.nl>
13 * 0.99.14 version by Jon Tombs <jon@gtex02.us.es>,
14 * Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
15 * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
16 *
17 * This source is covered by the GNU GPL, the same as all kernel sources.
18 */
19
20 #ifdef CONFIG_MODULES /* a *big* #ifdef block... */
21
22 extern struct module_symbol __start___ksymtab[];
23 extern struct module_symbol __stop___ksymtab[];
24
25 extern const struct exception_table_entry __start___ex_table[];
26 extern const struct exception_table_entry __stop___ex_table[];
27
28 static struct module kernel_module =
29 {
30 sizeof(struct module), /* size_of_struct */
31 NULL, /* next */
32 "", /* name */
33 0, /* size */
34 {ATOMIC_INIT(1)}, /* usecount */
35 MOD_RUNNING, /* flags */
36 0, /* nsyms -- to filled in in init_modules */
37 0, /* ndeps */
38 __start___ksymtab, /* syms */
39 NULL, /* deps */
40 NULL, /* refs */
41 NULL, /* init */
42 NULL, /* cleanup */
43 __start___ex_table, /* ex_table_start */
44 __stop___ex_table, /* ex_table_end */
45 /* Rest are NULL */
46 };
47
48 struct module *module_list = &kernel_module;
49
50 static long get_mod_name(const char *user_name, char **buf);
51 static void put_mod_name(char *buf);
52 static struct module *find_module(const char *name);
53 static void free_module(struct module *, int tag_freed);
54
55
56 /*
57 * Called at boot time
58 */
59
60 __initfunc(void init_modules(void))
61 {
62 kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
63
64 #ifdef __alpha__
65 __asm__("stq $29,%0" : "=m"(kernel_module.gp));
66 #endif
67 }
68
69 /*
70 * Copy the name of a module from user space.
71 */
72
73 static inline long
74 get_mod_name(const char *user_name, char **buf)
75 {
76 unsigned long page;
77 long retval;
78
79 if ((unsigned long)user_name >= TASK_SIZE
80 && !segment_eq(get_fs (), KERNEL_DS))
81 return -EFAULT;
82
83 page = __get_free_page(GFP_KERNEL);
84 if (!page)
85 return -ENOMEM;
86
87 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
88 if (retval > 0) {
89 if (retval < PAGE_SIZE) {
90 *buf = (char *)page;
91 return retval;
92 }
93 retval = -ENAMETOOLONG;
94 } else if (!retval)
95 retval = -EINVAL;
96
97 free_page(page);
98 return retval;
99 }
100
101 static inline void
102 put_mod_name(char *buf)
103 {
104 free_page((unsigned long)buf);
105 }
106
107 /*
108 * Allocate space for a module.
109 */
110
111 asmlinkage unsigned long
112 sys_create_module(const char *name_user, size_t size)
113 {
114 char *name;
115 long namelen, error;
116 struct module *mod;
117
118 lock_kernel();
119 if (!capable(CAP_SYS_MODULE)) {
120 error = -EPERM;
121 goto err0;
122 }
123 if ((namelen = get_mod_name(name_user, &name)) < 0) {
124 error = namelen;
125 goto err0;
126 }
127 if (size < sizeof(struct module)+namelen) {
128 error = -EINVAL;
129 goto err1;
130 }
131 if (find_module(name) != NULL) {
132 error = -EEXIST;
133 goto err1;
134 }
135 if ((mod = (struct module *)module_map(size)) == NULL) {
136 error = -ENOMEM;
137 goto err1;
138 }
139
140 memset(mod, 0, sizeof(*mod));
141 mod->size_of_struct = sizeof(*mod);
142 mod->next = module_list;
143 mod->name = (char *)(mod + 1);
144 mod->size = size;
145 memcpy((char*)(mod+1), name, namelen+1);
146
147 put_mod_name(name);
148
149 module_list = mod; /* link it in */
150
151 error = (long) mod;
152 goto err0;
153 err1:
154 put_mod_name(name);
155 err0:
156 unlock_kernel();
157 return error;
158 }
159
160 /*
161 * Initialize a module.
162 */
163
164 asmlinkage int
165 sys_init_module(const char *name_user, struct module *mod_user)
166 {
167 struct module mod_tmp, *mod;
168 char *name, *n_name;
169 long namelen, n_namelen, i, error = -EPERM;
170 unsigned long mod_user_size;
171 struct module_ref *dep;
172
173 lock_kernel();
174 if (!capable(CAP_SYS_MODULE))
175 goto err0;
176 if ((namelen = get_mod_name(name_user, &name)) < 0) {
177 error = namelen;
178 goto err0;
179 }
180 if ((mod = find_module(name)) == NULL) {
181 error = -ENOENT;
182 goto err1;
183 }
184
185 /* Check module header size. We allow a bit of slop over the
186 size we are familiar with to cope with a version of insmod
187 for a newer kernel. But don't over do it. */
188 if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0)
189 goto err1;
190 if (mod_user_size < (unsigned long)&((struct module *)0L)->persist_start
191 || mod_user_size > sizeof(struct module) + 16*sizeof(void*)) {
192 printk(KERN_ERR "init_module: Invalid module header size.\n"
193 KERN_ERR "A new version of the modutils is likely "
194 "needed.\n");
195 error = -EINVAL;
196 goto err1;
197 }
198
199 /* Hold the current contents while we play with the user's idea
200 of righteousness. */
201 mod_tmp = *mod;
202
203 error = copy_from_user(mod, mod_user, sizeof(struct module));
204 if (error) {
205 error = -EFAULT;
206 goto err2;
207 }
208
209 /* Sanity check the size of the module. */
210 error = -EINVAL;
211
212 if (mod->size > mod_tmp.size) {
213 printk(KERN_ERR "init_module: Size of initialized module "
214 "exceeds size of created module.\n");
215 goto err2;
216 }
217
218 /* Make sure all interesting pointers are sane. */
219
220 #define bound(p, n, m) ((unsigned long)(p) >= (unsigned long)(m+1) && \
221 (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
222
223 if (!bound(mod->name, namelen, mod)) {
224 printk(KERN_ERR "init_module: mod->name out of bounds.\n");
225 goto err2;
226 }
227 if (mod->nsyms && !bound(mod->syms, mod->nsyms, mod)) {
228 printk(KERN_ERR "init_module: mod->syms out of bounds.\n");
229 goto err2;
230 }
231 if (mod->ndeps && !bound(mod->deps, mod->ndeps, mod)) {
232 printk(KERN_ERR "init_module: mod->deps out of bounds.\n");
233 goto err2;
234 }
235 if (mod->init && !bound(mod->init, 0, mod)) {
236 printk(KERN_ERR "init_module: mod->init out of bounds.\n");
237 goto err2;
238 }
239 if (mod->cleanup && !bound(mod->cleanup, 0, mod)) {
240 printk(KERN_ERR "init_module: mod->cleanup out of bounds.\n");
241 goto err2;
242 }
243 if (mod->ex_table_start > mod->ex_table_end
244 || (mod->ex_table_start &&
245 !((unsigned long)mod->ex_table_start >= (unsigned long)(mod+1)
246 && ((unsigned long)mod->ex_table_end
247 < (unsigned long)mod + mod->size)))
248 || (((unsigned long)mod->ex_table_start
249 - (unsigned long)mod->ex_table_end)
250 % sizeof(struct exception_table_entry))) {
251 printk(KERN_ERR "init_module: mod->ex_table_* invalid.\n");
252 goto err2;
253 }
254 if (mod->flags & ~MOD_AUTOCLEAN) {
255 printk(KERN_ERR "init_module: mod->flags invalid.\n");
256 goto err2;
257 }
258 #ifdef __alpha__
259 if (!bound(mod->gp - 0x8000, 0, mod)) {
260 printk(KERN_ERR "init_module: mod->gp out of bounds.\n");
261 goto err2;
262 }
263 #endif
264 if (mod_member_present(mod, can_unload)
265 && mod->can_unload && !bound(mod->can_unload, 0, mod)) {
266 printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");
267 goto err2;
268 }
269
270 #undef bound
271
272 /* Check that the user isn't doing something silly with the name. */
273
274 if ((n_namelen = get_mod_name(mod->name - (unsigned long)mod
275 + (unsigned long)mod_user,
276 &n_name)) < 0) {
277 error = n_namelen;
278 goto err2;
279 }
280 if (namelen != n_namelen || strcmp(n_name, mod_tmp.name) != 0) {
281 printk(KERN_ERR "init_module: changed module name to "
282 "`%s' from `%s'\n",
283 n_name, mod_tmp.name);
284 goto err3;
285 }
286
287 /* Ok, that's about all the sanity we can stomach; copy the rest. */
288
289 if (copy_from_user(mod+1, mod_user+1, mod->size-sizeof(*mod))) {
290 error = -EFAULT;
291 goto err3;
292 }
293
294 /* On some machines it is necessary to do something here
295 to make the I and D caches consistent. */
296 flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
297
298 /* Update module references. */
299 mod->next = mod_tmp.next;
300 mod->refs = NULL;
301 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
302 struct module *o, *d = dep->dep;
303
304 /* Make sure the indicated dependencies are really modules. */
305 if (d == mod) {
306 printk(KERN_ERR "init_module: self-referential "
307 "dependency in mod->deps.\n");
308 goto err3;
309 }
310
311 for (o = module_list; o != &kernel_module; o = o->next)
312 if (o == d) goto found_dep;
313
314 printk(KERN_ERR "init_module: found dependency that is "
315 "(no longer?) a module.\n");
316 goto err3;
317
318 found_dep:
319 dep->ref = mod;
320 dep->next_ref = d->refs;
321 d->refs = dep;
322 /* Being referenced by a dependent module counts as a
323 use as far as kmod is concerned. */
324 d->flags |= MOD_USED_ONCE;
325 }
326
327 /* Free our temporary memory. */
328 put_mod_name(n_name);
329 put_mod_name(name);
330
331 /* Initialize the module. */
332 atomic_set(&mod->uc.usecount,1);
333 if (mod->init && mod->init() != 0) {
334 atomic_set(&mod->uc.usecount,0);
335 error = -EBUSY;
336 goto err0;
337 }
338 atomic_dec(&mod->uc.usecount);
339
340 /* And set it running. */
341 mod->flags |= MOD_RUNNING;
342 error = 0;
343 goto err0;
344
345 err3:
346 put_mod_name(n_name);
347 err2:
348 *mod = mod_tmp;
349 err1:
350 put_mod_name(name);
351 err0:
352 unlock_kernel();
353 return error;
354 }
355
356 asmlinkage int
357 sys_delete_module(const char *name_user)
358 {
359 struct module *mod, *next;
360 char *name;
361 long error = -EPERM;
362 int something_changed;
363
364 lock_kernel();
365 if (!capable(CAP_SYS_MODULE))
366 goto out;
367
368 if (name_user) {
369 if ((error = get_mod_name(name_user, &name)) < 0)
370 goto out;
371 if (error == 0) {
372 error = -EINVAL;
373 put_mod_name(name);
374 goto out;
375 }
376 error = -ENOENT;
377 if ((mod = find_module(name)) == NULL) {
378 put_mod_name(name);
379 goto out;
380 }
381 put_mod_name(name);
382 error = -EBUSY;
383 if (mod->refs != NULL || __MOD_IN_USE(mod))
384 goto out;
385
386 free_module(mod, 0);
387 error = 0;
388 goto out;
389 }
390
391 /* Do automatic reaping */
392 restart:
393 something_changed = 0;
394 for (mod = module_list; mod != &kernel_module; mod = next) {
395 next = mod->next;
396 if (mod->refs == NULL
397 && (mod->flags & MOD_AUTOCLEAN)
398 && (mod->flags & MOD_RUNNING)
399 && !(mod->flags & MOD_DELETED)
400 && (mod->flags & MOD_USED_ONCE)
401 && !__MOD_IN_USE(mod)) {
402 if ((mod->flags & MOD_VISITED)
403 && !(mod->flags & MOD_JUST_FREED)) {
404 mod->flags &= ~MOD_VISITED;
405 } else {
406 free_module(mod, 1);
407 something_changed = 1;
408 }
409 }
410 }
411 if (something_changed)
412 goto restart;
413 for (mod = module_list; mod != &kernel_module; mod = mod->next)
414 mod->flags &= ~MOD_JUST_FREED;
415 error = 0;
416 out:
417 unlock_kernel();
418 return error;
419 }
420
421 /* Query various bits about modules. */
422
423 static int
424 qm_modules(char *buf, size_t bufsize, size_t *ret)
425 {
426 struct module *mod;
427 size_t nmod, space, len;
428
429 nmod = space = 0;
430
431 for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) {
432 len = strlen(mod->name)+1;
433 if (len > bufsize)
434 goto calc_space_needed;
435 if (copy_to_user(buf, mod->name, len))
436 return -EFAULT;
437 buf += len;
438 bufsize -= len;
439 space += len;
440 }
441
442 if (put_user(nmod, ret))
443 return -EFAULT;
444 else
445 return 0;
446
447 calc_space_needed:
448 space += len;
449 while ((mod = mod->next) != &kernel_module)
450 space += strlen(mod->name)+1;
451
452 if (put_user(space, ret))
453 return -EFAULT;
454 else
455 return -ENOSPC;
456 }
457
458 static int
459 qm_deps(struct module *mod, char *buf, size_t bufsize, size_t *ret)
460 {
461 size_t i, space, len;
462
463 if (mod == &kernel_module)
464 return -EINVAL;
465 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
466 if (put_user(0, ret))
467 return -EFAULT;
468 else
469 return 0;
470
471 space = 0;
472 for (i = 0; i < mod->ndeps; ++i) {
473 const char *dep_name = mod->deps[i].dep->name;
474
475 len = strlen(dep_name)+1;
476 if (len > bufsize)
477 goto calc_space_needed;
478 if (copy_to_user(buf, dep_name, len))
479 return -EFAULT;
480 buf += len;
481 bufsize -= len;
482 space += len;
483 }
484
485 if (put_user(i, ret))
486 return -EFAULT;
487 else
488 return 0;
489
490 calc_space_needed:
491 space += len;
492 while (++i < mod->ndeps)
493 space += strlen(mod->deps[i].dep->name)+1;
494
495 if (put_user(space, ret))
496 return -EFAULT;
497 else
498 return -ENOSPC;
499 }
500
501 static int
502 qm_refs(struct module *mod, char *buf, size_t bufsize, size_t *ret)
503 {
504 size_t nrefs, space, len;
505 struct module_ref *ref;
506
507 if (mod == &kernel_module)
508 return -EINVAL;
509 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
510 if (put_user(0, ret))
511 return -EFAULT;
512 else
513 return 0;
514
515 space = 0;
516 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
517 const char *ref_name = ref->ref->name;
518
519 len = strlen(ref_name)+1;
520 if (len > bufsize)
521 goto calc_space_needed;
522 if (copy_to_user(buf, ref_name, len))
523 return -EFAULT;
524 buf += len;
525 bufsize -= len;
526 space += len;
527 }
528
529 if (put_user(nrefs, ret))
530 return -EFAULT;
531 else
532 return 0;
533
534 calc_space_needed:
535 space += len;
536 while ((ref = ref->next_ref) != NULL)
537 space += strlen(ref->ref->name)+1;
538
539 if (put_user(space, ret))
540 return -EFAULT;
541 else
542 return -ENOSPC;
543 }
544
545 static int
546 qm_symbols(struct module *mod, char *buf, size_t bufsize, size_t *ret)
547 {
548 size_t i, space, len;
549 struct module_symbol *s;
550 char *strings;
551 unsigned long *vals;
552
553 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
554 if (put_user(0, ret))
555 return -EFAULT;
556 else
557 return 0;
558
559 space = mod->nsyms * 2*sizeof(void *);
560
561 i = len = 0;
562 s = mod->syms;
563
564 if (space > bufsize)
565 goto calc_space_needed;
566
567 if (!access_ok(VERIFY_WRITE, buf, space))
568 return -EFAULT;
569
570 bufsize -= space;
571 vals = (unsigned long *)buf;
572 strings = buf+space;
573
574 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
575 len = strlen(s->name)+1;
576 if (len > bufsize)
577 goto calc_space_needed;
578
579 if (copy_to_user(strings, s->name, len)
580 || __put_user(s->value, vals+0)
581 || __put_user(space, vals+1))
582 return -EFAULT;
583
584 strings += len;
585 bufsize -= len;
586 space += len;
587 }
588
589 if (put_user(i, ret))
590 return -EFAULT;
591 else
592 return 0;
593
594 calc_space_needed:
595 for (; i < mod->nsyms; ++i, ++s)
596 space += strlen(s->name)+1;
597
598 if (put_user(space, ret))
599 return -EFAULT;
600 else
601 return -ENOSPC;
602 }
603
604 static int
605 qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret)
606 {
607 int error = 0;
608
609 if (mod == &kernel_module)
610 return -EINVAL;
611
612 if (sizeof(struct module_info) <= bufsize) {
613 struct module_info info;
614 info.addr = (unsigned long)mod;
615 info.size = mod->size;
616 info.flags = mod->flags;
617 info.usecount = (mod_member_present(mod, can_unload)
618 && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount));
619
620 if (copy_to_user(buf, &info, sizeof(struct module_info)))
621 return -EFAULT;
622 } else
623 error = -ENOSPC;
624
625 if (put_user(sizeof(struct module_info), ret))
626 return -EFAULT;
627
628 return error;
629 }
630
631 asmlinkage int
632 sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
633 size_t *ret)
634 {
635 struct module *mod;
636 int err;
637
638 lock_kernel();
639 if (name_user == NULL)
640 mod = &kernel_module;
641 else {
642 long namelen;
643 char *name;
644
645 if ((namelen = get_mod_name(name_user, &name)) < 0) {
646 err = namelen;
647 goto out;
648 }
649 err = -ENOENT;
650 if (namelen == 0)
651 mod = &kernel_module;
652 else if ((mod = find_module(name)) == NULL) {
653 put_mod_name(name);
654 goto out;
655 }
656 put_mod_name(name);
657 }
658
659 switch (which)
660 {
661 case 0:
662 err = 0;
663 break;
664 case QM_MODULES:
665 err = qm_modules(buf, bufsize, ret);
666 break;
667 case QM_DEPS:
668 err = qm_deps(mod, buf, bufsize, ret);
669 break;
670 case QM_REFS:
671 err = qm_refs(mod, buf, bufsize, ret);
672 break;
673 case QM_SYMBOLS:
674 err = qm_symbols(mod, buf, bufsize, ret);
675 break;
676 case QM_INFO:
677 err = qm_info(mod, buf, bufsize, ret);
678 break;
679 default:
680 err = -EINVAL;
681 break;
682 }
683 out:
684 unlock_kernel();
685 return err;
686 }
687
688 /*
689 * Copy the kernel symbol table to user space. If the argument is
690 * NULL, just return the size of the table.
691 *
692 * This call is obsolete. New programs should use query_module+QM_SYMBOLS
693 * which does not arbitrarily limit the length of symbols.
694 */
695
696 asmlinkage int
697 sys_get_kernel_syms(struct kernel_sym *table)
698 {
699 struct module *mod;
700 int i;
701 struct kernel_sym ksym;
702
703 lock_kernel();
704 for (mod = module_list, i = 0; mod; mod = mod->next) {
705 /* include the count for the module name! */
706 i += mod->nsyms + 1;
707 }
708
709 if (table == NULL)
710 goto out;
711
712 /* So that we don't give the user our stack content */
713 memset (&ksym, 0, sizeof (ksym));
714
715 for (mod = module_list, i = 0; mod; mod = mod->next) {
716 struct module_symbol *msym;
717 unsigned int j;
718
719 if ((mod->flags & (MOD_RUNNING|MOD_DELETED)) != MOD_RUNNING)
720 continue;
721
722 /* magic: write module info as a pseudo symbol */
723 ksym.value = (unsigned long)mod;
724 ksym.name[0] = '#';
725 strncpy(ksym.name+1, mod->name, sizeof(ksym.name)-1);
726 ksym.name[sizeof(ksym.name)-1] = '\0';
727
728 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
729 goto out;
730 ++i, ++table;
731
732 if (mod->nsyms == 0)
733 continue;
734
735 for (j = 0, msym = mod->syms; j < mod->nsyms; ++j, ++msym) {
736 ksym.value = msym->value;
737 strncpy(ksym.name, msym->name, sizeof(ksym.name));
738 ksym.name[sizeof(ksym.name)-1] = '\0';
739
740 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
741 goto out;
742 ++i, ++table;
743 }
744 }
745 out:
746 unlock_kernel();
747 return i;
748 }
749
750 /*
751 * Look for a module by name, ignoring modules marked for deletion.
752 */
753
754 static struct module *
755 find_module(const char *name)
756 {
757 struct module *mod;
758
759 for (mod = module_list; mod ; mod = mod->next) {
760 if (mod->flags & MOD_DELETED)
761 continue;
762 if (!strcmp(mod->name, name))
763 break;
764 }
765
766 return mod;
767 }
768
769 /*
770 * Free the given module.
771 */
772
773 static void
774 free_module(struct module *mod, int tag_freed)
775 {
776 struct module_ref *dep;
777 unsigned i;
778
779 /* Let the module clean up. */
780
781 mod->flags |= MOD_DELETED;
782 if (mod->flags & MOD_RUNNING)
783 {
784 if(mod->cleanup)
785 mod->cleanup();
786 mod->flags &= ~MOD_RUNNING;
787 }
788
789 /* Remove the module from the dependency lists. */
790
791 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
792 struct module_ref **pp;
793 for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref)
794 continue;
795 *pp = dep->next_ref;
796 if (tag_freed && dep->dep->refs == NULL)
797 dep->dep->flags |= MOD_JUST_FREED;
798 }
799
800 /* And from the main module list. */
801
802 if (mod == module_list) {
803 module_list = mod->next;
804 } else {
805 struct module *p;
806 for (p = module_list; p->next != mod; p = p->next)
807 continue;
808 p->next = mod->next;
809 }
810
811 /* And free the memory. */
812
813 module_unmap(mod);
814 }
815
816 /*
817 * Called by the /proc file system to return a current list of modules.
818 */
819
820 int get_module_list(char *p)
821 {
822 size_t left = PAGE_SIZE;
823 struct module *mod;
824 char tmpstr[64];
825 struct module_ref *ref;
826
827 for (mod = module_list; mod != &kernel_module; mod = mod->next) {
828 long len;
829 const char *q;
830
831 #define safe_copy_str(str, len) \
832 do { \
833 if (left < len) \
834 goto fini; \
835 memcpy(p, str, len); p += len, left -= len; \
836 } while (0)
837 #define safe_copy_cstr(str) safe_copy_str(str, sizeof(str)-1)
838
839 len = strlen(mod->name);
840 safe_copy_str(mod->name, len);
841
842 if ((len = 20 - len) > 0) {
843 if (left < len)
844 goto fini;
845 memset(p, ' ', len);
846 p += len;
847 left -= len;
848 }
849
850 len = sprintf(tmpstr, "%8lu", mod->size);
851 safe_copy_str(tmpstr, len);
852
853 if (mod->flags & MOD_RUNNING) {
854 len = sprintf(tmpstr, "%4ld",
855 (mod_member_present(mod, can_unload)
856 && mod->can_unload
857 ? -1L : (long)atomic_read(&mod->uc.usecount)));
858 safe_copy_str(tmpstr, len);
859 }
860
861 if (mod->flags & MOD_DELETED)
862 safe_copy_cstr(" (deleted)");
863 else if (mod->flags & MOD_RUNNING) {
864 if (mod->flags & MOD_AUTOCLEAN)
865 safe_copy_cstr(" (autoclean)");
866 if (!(mod->flags & MOD_USED_ONCE))
867 safe_copy_cstr(" (unused)");
868 } else
869 safe_copy_cstr(" (uninitialized)");
870
871 if ((ref = mod->refs) != NULL) {
872 safe_copy_cstr(" [");
873 while (1) {
874 q = ref->ref->name;
875 len = strlen(q);
876 safe_copy_str(q, len);
877
878 if ((ref = ref->next_ref) != NULL)
879 safe_copy_cstr(" ");
880 else
881 break;
882 }
883 safe_copy_cstr("]");
884 }
885 safe_copy_cstr("\n");
886
887 #undef safe_copy_str
888 #undef safe_copy_cstr
889 }
890
891 fini:
892 return PAGE_SIZE - left;
893 }
894
895 /*
896 * Called by the /proc file system to return a current list of ksyms.
897 */
898
899 int
900 get_ksyms_list(char *buf, char **start, off_t offset, int length)
901 {
902 struct module *mod;
903 char *p = buf;
904 int len = 0; /* code from net/ipv4/proc.c */
905 off_t pos = 0;
906 off_t begin = 0;
907
908 for (mod = module_list; mod; mod = mod->next) {
909 unsigned i;
910 struct module_symbol *sym;
911
912 if (!(mod->flags & MOD_RUNNING) || (mod->flags & MOD_DELETED))
913 continue;
914
915 for (i = mod->nsyms, sym = mod->syms; i > 0; --i, ++sym) {
916 p = buf + len;
917 if (*mod->name) {
918 len += sprintf(p, "%0*lx %s\t[%s]\n",
919 (int)(2*sizeof(void*)),
920 sym->value, sym->name,
921 mod->name);
922 } else {
923 len += sprintf(p, "%0*lx %s\n",
924 (int)(2*sizeof(void*)),
925 sym->value, sym->name);
926 }
927 pos = begin + len;
928 if (pos < offset) {
929 len = 0;
930 begin = pos;
931 }
932 pos = begin + len;
933 if (pos > offset+length)
934 goto leave_the_loop;
935 }
936 }
937 leave_the_loop:
938 *start = buf + (offset - begin);
939 len -= (offset - begin);
940 if (len > length)
941 len = length;
942 return len;
943 }
944
945 /*
946 * Gets the address for a symbol in the given module. If modname is
947 * NULL, it looks for the name in any registered symbol table. If the
948 * modname is an empty string, it looks for the symbol in kernel exported
949 * symbol tables.
950 */
951 unsigned long
952 get_module_symbol(char *modname, char *symname)
953 {
954 struct module *mp;
955 struct module_symbol *sym;
956 int i;
957
958 for (mp = module_list; mp; mp = mp->next) {
959 if (((modname == NULL) || (strcmp(mp->name, modname) == 0)) &&
960 (mp->flags & (MOD_RUNNING | MOD_DELETED)) == MOD_RUNNING &&
961 (mp->nsyms > 0)) {
962 for (i = mp->nsyms, sym = mp->syms;
963 i > 0; --i, ++sym) {
964
965 if (strcmp(sym->name, symname) == 0) {
966 return sym->value;
967 }
968 }
969 }
970 }
971 return 0;
972 }
973
974 #else /* CONFIG_MODULES */
975
976 /* Dummy syscalls for people who don't want modules */
977
978 asmlinkage unsigned long
979 sys_create_module(const char *name_user, size_t size)
980 {
981 return -ENOSYS;
982 }
983
984 asmlinkage int
985 sys_init_module(const char *name_user, struct module *mod_user)
986 {
987 return -ENOSYS;
988 }
989
990 asmlinkage int
991 sys_delete_module(const char *name_user)
992 {
993 return -ENOSYS;
994 }
995
996 asmlinkage int
997 sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
998 size_t *ret)
999 {
1000 /* Let the program know about the new interface. Not that
1001 it'll do them much good. */
1002 if (which == 0)
1003 return 0;
1004
1005 return -ENOSYS;
1006 }
1007
1008 asmlinkage int
1009 sys_get_kernel_syms(struct kernel_sym *table)
1010 {
1011 return -ENOSYS;
1012 }
1013
1014 #endif /* CONFIG_MODULES */
1015
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.