Import 2.3.30pre1
[davej-history.git] / kernel / module.c
blob0a7d5a42dfe30c047786aca6beee6f75059240c7
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/pgalloc.h>
8 #include <linux/init.h>
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
17 * This source is covered by the GNU GPL, the same as all kernel sources.
20 #ifdef CONFIG_MODULES /* a *big* #ifdef block... */
22 extern struct module_symbol __start___ksymtab[];
23 extern struct module_symbol __stop___ksymtab[];
25 extern const struct exception_table_entry __start___ex_table[];
26 extern const struct exception_table_entry __stop___ex_table[];
28 static struct module kernel_module =
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 */
48 struct module *module_list = &kernel_module;
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);
57 * Called at boot time
60 void __init init_modules(void)
62 kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
64 #ifdef __alpha__
65 __asm__("stq $29,%0" : "=m"(kernel_module.gp));
66 #endif
70 * Copy the name of a module from user space.
73 static inline long
74 get_mod_name(const char *user_name, char **buf)
76 unsigned long page;
77 long retval;
79 page = __get_free_page(GFP_KERNEL);
80 if (!page)
81 return -ENOMEM;
83 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
84 if (retval > 0) {
85 if (retval < PAGE_SIZE) {
86 *buf = (char *)page;
87 return retval;
89 retval = -ENAMETOOLONG;
90 } else if (!retval)
91 retval = -EINVAL;
93 free_page(page);
94 return retval;
97 static inline void
98 put_mod_name(char *buf)
100 free_page((unsigned long)buf);
104 * Allocate space for a module.
107 asmlinkage unsigned long
108 sys_create_module(const char *name_user, size_t size)
110 char *name;
111 long namelen, error;
112 struct module *mod;
114 lock_kernel();
115 if (!capable(CAP_SYS_MODULE)) {
116 error = -EPERM;
117 goto err0;
119 if ((namelen = get_mod_name(name_user, &name)) < 0) {
120 error = namelen;
121 goto err0;
123 if (size < sizeof(struct module)+namelen) {
124 error = -EINVAL;
125 goto err1;
127 if (find_module(name) != NULL) {
128 error = -EEXIST;
129 goto err1;
131 if ((mod = (struct module *)module_map(size)) == NULL) {
132 error = -ENOMEM;
133 goto err1;
136 memset(mod, 0, sizeof(*mod));
137 mod->size_of_struct = sizeof(*mod);
138 mod->next = module_list;
139 mod->name = (char *)(mod + 1);
140 mod->size = size;
141 memcpy((char*)(mod+1), name, namelen+1);
143 put_mod_name(name);
145 module_list = mod; /* link it in */
147 error = (long) mod;
148 goto err0;
149 err1:
150 put_mod_name(name);
151 err0:
152 unlock_kernel();
153 return error;
157 * Initialize a module.
160 asmlinkage long
161 sys_init_module(const char *name_user, struct module *mod_user)
163 struct module mod_tmp, *mod;
164 char *name, *n_name;
165 long namelen, n_namelen, i, error = -EPERM;
166 unsigned long mod_user_size;
167 struct module_ref *dep;
169 lock_kernel();
170 if (!capable(CAP_SYS_MODULE))
171 goto err0;
172 if ((namelen = get_mod_name(name_user, &name)) < 0) {
173 error = namelen;
174 goto err0;
176 if ((mod = find_module(name)) == NULL) {
177 error = -ENOENT;
178 goto err1;
181 /* Check module header size. We allow a bit of slop over the
182 size we are familiar with to cope with a version of insmod
183 for a newer kernel. But don't over do it. */
184 if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0)
185 goto err1;
186 if (mod_user_size < (unsigned long)&((struct module *)0L)->persist_start
187 || mod_user_size > sizeof(struct module) + 16*sizeof(void*)) {
188 printk(KERN_ERR "init_module: Invalid module header size.\n"
189 KERN_ERR "A new version of the modutils is likely "
190 "needed.\n");
191 error = -EINVAL;
192 goto err1;
195 /* Hold the current contents while we play with the user's idea
196 of righteousness. */
197 mod_tmp = *mod;
199 error = copy_from_user(mod, mod_user, sizeof(struct module));
200 if (error) {
201 error = -EFAULT;
202 goto err2;
205 /* Sanity check the size of the module. */
206 error = -EINVAL;
208 if (mod->size > mod_tmp.size) {
209 printk(KERN_ERR "init_module: Size of initialized module "
210 "exceeds size of created module.\n");
211 goto err2;
214 /* Make sure all interesting pointers are sane. */
216 #define bound(p, n, m) ((unsigned long)(p) >= (unsigned long)(m+1) && \
217 (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
219 if (!bound(mod->name, namelen, mod)) {
220 printk(KERN_ERR "init_module: mod->name out of bounds.\n");
221 goto err2;
223 if (mod->nsyms && !bound(mod->syms, mod->nsyms, mod)) {
224 printk(KERN_ERR "init_module: mod->syms out of bounds.\n");
225 goto err2;
227 if (mod->ndeps && !bound(mod->deps, mod->ndeps, mod)) {
228 printk(KERN_ERR "init_module: mod->deps out of bounds.\n");
229 goto err2;
231 if (mod->init && !bound(mod->init, 0, mod)) {
232 printk(KERN_ERR "init_module: mod->init out of bounds.\n");
233 goto err2;
235 if (mod->cleanup && !bound(mod->cleanup, 0, mod)) {
236 printk(KERN_ERR "init_module: mod->cleanup out of bounds.\n");
237 goto err2;
239 if (mod->ex_table_start > mod->ex_table_end
240 || (mod->ex_table_start &&
241 !((unsigned long)mod->ex_table_start >= (unsigned long)(mod+1)
242 && ((unsigned long)mod->ex_table_end
243 < (unsigned long)mod + mod->size)))
244 || (((unsigned long)mod->ex_table_start
245 - (unsigned long)mod->ex_table_end)
246 % sizeof(struct exception_table_entry))) {
247 printk(KERN_ERR "init_module: mod->ex_table_* invalid.\n");
248 goto err2;
250 if (mod->flags & ~MOD_AUTOCLEAN) {
251 printk(KERN_ERR "init_module: mod->flags invalid.\n");
252 goto err2;
254 #ifdef __alpha__
255 if (!bound(mod->gp - 0x8000, 0, mod)) {
256 printk(KERN_ERR "init_module: mod->gp out of bounds.\n");
257 goto err2;
259 #endif
260 if (mod_member_present(mod, can_unload)
261 && mod->can_unload && !bound(mod->can_unload, 0, mod)) {
262 printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");
263 goto err2;
266 #undef bound
268 /* Check that the user isn't doing something silly with the name. */
270 if ((n_namelen = get_mod_name(mod->name - (unsigned long)mod
271 + (unsigned long)mod_user,
272 &n_name)) < 0) {
273 error = n_namelen;
274 goto err2;
276 if (namelen != n_namelen || strcmp(n_name, mod_tmp.name) != 0) {
277 printk(KERN_ERR "init_module: changed module name to "
278 "`%s' from `%s'\n",
279 n_name, mod_tmp.name);
280 goto err3;
283 /* Ok, that's about all the sanity we can stomach; copy the rest. */
285 if (copy_from_user(mod+1, mod_user+1, mod->size-sizeof(*mod))) {
286 error = -EFAULT;
287 goto err3;
290 /* On some machines it is necessary to do something here
291 to make the I and D caches consistent. */
292 flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
294 /* Update module references. */
295 mod->next = mod_tmp.next;
296 mod->refs = NULL;
297 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
298 struct module *o, *d = dep->dep;
300 /* Make sure the indicated dependencies are really modules. */
301 if (d == mod) {
302 printk(KERN_ERR "init_module: self-referential "
303 "dependency in mod->deps.\n");
304 goto err3;
307 for (o = module_list; o != &kernel_module; o = o->next)
308 if (o == d) goto found_dep;
310 printk(KERN_ERR "init_module: found dependency that is "
311 "(no longer?) a module.\n");
312 goto err3;
314 found_dep:
315 dep->ref = mod;
316 dep->next_ref = d->refs;
317 d->refs = dep;
318 /* Being referenced by a dependent module counts as a
319 use as far as kmod is concerned. */
320 d->flags |= MOD_USED_ONCE;
323 /* Free our temporary memory. */
324 put_mod_name(n_name);
325 put_mod_name(name);
327 /* Initialize the module. */
328 atomic_set(&mod->uc.usecount,1);
329 if (mod->init && mod->init() != 0) {
330 atomic_set(&mod->uc.usecount,0);
331 error = -EBUSY;
332 goto err0;
334 atomic_dec(&mod->uc.usecount);
336 /* And set it running. */
337 mod->flags |= MOD_RUNNING;
338 error = 0;
339 goto err0;
341 err3:
342 put_mod_name(n_name);
343 err2:
344 *mod = mod_tmp;
345 err1:
346 put_mod_name(name);
347 err0:
348 unlock_kernel();
349 return error;
352 asmlinkage long
353 sys_delete_module(const char *name_user)
355 struct module *mod, *next;
356 char *name;
357 long error = -EPERM;
358 int something_changed;
360 lock_kernel();
361 if (!capable(CAP_SYS_MODULE))
362 goto out;
364 if (name_user) {
365 if ((error = get_mod_name(name_user, &name)) < 0)
366 goto out;
367 if (error == 0) {
368 error = -EINVAL;
369 put_mod_name(name);
370 goto out;
372 error = -ENOENT;
373 if ((mod = find_module(name)) == NULL) {
374 put_mod_name(name);
375 goto out;
377 put_mod_name(name);
378 error = -EBUSY;
379 if (mod->refs != NULL || __MOD_IN_USE(mod))
380 goto out;
382 free_module(mod, 0);
383 error = 0;
384 goto out;
387 /* Do automatic reaping */
388 restart:
389 something_changed = 0;
390 for (mod = module_list; mod != &kernel_module; mod = next) {
391 next = mod->next;
392 if (mod->refs == NULL
393 && (mod->flags & MOD_AUTOCLEAN)
394 && (mod->flags & MOD_RUNNING)
395 && !(mod->flags & MOD_DELETED)
396 && (mod->flags & MOD_USED_ONCE)
397 && !__MOD_IN_USE(mod)) {
398 if ((mod->flags & MOD_VISITED)
399 && !(mod->flags & MOD_JUST_FREED)) {
400 mod->flags &= ~MOD_VISITED;
401 } else {
402 free_module(mod, 1);
403 something_changed = 1;
407 if (something_changed)
408 goto restart;
409 for (mod = module_list; mod != &kernel_module; mod = mod->next)
410 mod->flags &= ~MOD_JUST_FREED;
411 error = 0;
412 out:
413 unlock_kernel();
414 return error;
417 /* Query various bits about modules. */
419 static int
420 qm_modules(char *buf, size_t bufsize, size_t *ret)
422 struct module *mod;
423 size_t nmod, space, len;
425 nmod = space = 0;
427 for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) {
428 len = strlen(mod->name)+1;
429 if (len > bufsize)
430 goto calc_space_needed;
431 if (copy_to_user(buf, mod->name, len))
432 return -EFAULT;
433 buf += len;
434 bufsize -= len;
435 space += len;
438 if (put_user(nmod, ret))
439 return -EFAULT;
440 else
441 return 0;
443 calc_space_needed:
444 space += len;
445 while ((mod = mod->next) != &kernel_module)
446 space += strlen(mod->name)+1;
448 if (put_user(space, ret))
449 return -EFAULT;
450 else
451 return -ENOSPC;
454 static int
455 qm_deps(struct module *mod, char *buf, size_t bufsize, size_t *ret)
457 size_t i, space, len;
459 if (mod == &kernel_module)
460 return -EINVAL;
461 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
462 if (put_user(0, ret))
463 return -EFAULT;
464 else
465 return 0;
467 space = 0;
468 for (i = 0; i < mod->ndeps; ++i) {
469 const char *dep_name = mod->deps[i].dep->name;
471 len = strlen(dep_name)+1;
472 if (len > bufsize)
473 goto calc_space_needed;
474 if (copy_to_user(buf, dep_name, len))
475 return -EFAULT;
476 buf += len;
477 bufsize -= len;
478 space += len;
481 if (put_user(i, ret))
482 return -EFAULT;
483 else
484 return 0;
486 calc_space_needed:
487 space += len;
488 while (++i < mod->ndeps)
489 space += strlen(mod->deps[i].dep->name)+1;
491 if (put_user(space, ret))
492 return -EFAULT;
493 else
494 return -ENOSPC;
497 static int
498 qm_refs(struct module *mod, char *buf, size_t bufsize, size_t *ret)
500 size_t nrefs, space, len;
501 struct module_ref *ref;
503 if (mod == &kernel_module)
504 return -EINVAL;
505 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
506 if (put_user(0, ret))
507 return -EFAULT;
508 else
509 return 0;
511 space = 0;
512 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
513 const char *ref_name = ref->ref->name;
515 len = strlen(ref_name)+1;
516 if (len > bufsize)
517 goto calc_space_needed;
518 if (copy_to_user(buf, ref_name, len))
519 return -EFAULT;
520 buf += len;
521 bufsize -= len;
522 space += len;
525 if (put_user(nrefs, ret))
526 return -EFAULT;
527 else
528 return 0;
530 calc_space_needed:
531 space += len;
532 while ((ref = ref->next_ref) != NULL)
533 space += strlen(ref->ref->name)+1;
535 if (put_user(space, ret))
536 return -EFAULT;
537 else
538 return -ENOSPC;
541 static int
542 qm_symbols(struct module *mod, char *buf, size_t bufsize, size_t *ret)
544 size_t i, space, len;
545 struct module_symbol *s;
546 char *strings;
547 unsigned long *vals;
549 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
550 if (put_user(0, ret))
551 return -EFAULT;
552 else
553 return 0;
555 space = mod->nsyms * 2*sizeof(void *);
557 i = len = 0;
558 s = mod->syms;
560 if (space > bufsize)
561 goto calc_space_needed;
563 if (!access_ok(VERIFY_WRITE, buf, space))
564 return -EFAULT;
566 bufsize -= space;
567 vals = (unsigned long *)buf;
568 strings = buf+space;
570 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
571 len = strlen(s->name)+1;
572 if (len > bufsize)
573 goto calc_space_needed;
575 if (copy_to_user(strings, s->name, len)
576 || __put_user(s->value, vals+0)
577 || __put_user(space, vals+1))
578 return -EFAULT;
580 strings += len;
581 bufsize -= len;
582 space += len;
585 if (put_user(i, ret))
586 return -EFAULT;
587 else
588 return 0;
590 calc_space_needed:
591 for (; i < mod->nsyms; ++i, ++s)
592 space += strlen(s->name)+1;
594 if (put_user(space, ret))
595 return -EFAULT;
596 else
597 return -ENOSPC;
600 static int
601 qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret)
603 int error = 0;
605 if (mod == &kernel_module)
606 return -EINVAL;
608 if (sizeof(struct module_info) <= bufsize) {
609 struct module_info info;
610 info.addr = (unsigned long)mod;
611 info.size = mod->size;
612 info.flags = mod->flags;
613 info.usecount = (mod_member_present(mod, can_unload)
614 && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount));
616 if (copy_to_user(buf, &info, sizeof(struct module_info)))
617 return -EFAULT;
618 } else
619 error = -ENOSPC;
621 if (put_user(sizeof(struct module_info), ret))
622 return -EFAULT;
624 return error;
627 asmlinkage long
628 sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
629 size_t *ret)
631 struct module *mod;
632 int err;
634 lock_kernel();
635 if (name_user == NULL)
636 mod = &kernel_module;
637 else {
638 long namelen;
639 char *name;
641 if ((namelen = get_mod_name(name_user, &name)) < 0) {
642 err = namelen;
643 goto out;
645 err = -ENOENT;
646 if (namelen == 0)
647 mod = &kernel_module;
648 else if ((mod = find_module(name)) == NULL) {
649 put_mod_name(name);
650 goto out;
652 put_mod_name(name);
655 switch (which)
657 case 0:
658 err = 0;
659 break;
660 case QM_MODULES:
661 err = qm_modules(buf, bufsize, ret);
662 break;
663 case QM_DEPS:
664 err = qm_deps(mod, buf, bufsize, ret);
665 break;
666 case QM_REFS:
667 err = qm_refs(mod, buf, bufsize, ret);
668 break;
669 case QM_SYMBOLS:
670 err = qm_symbols(mod, buf, bufsize, ret);
671 break;
672 case QM_INFO:
673 err = qm_info(mod, buf, bufsize, ret);
674 break;
675 default:
676 err = -EINVAL;
677 break;
679 out:
680 unlock_kernel();
681 return err;
685 * Copy the kernel symbol table to user space. If the argument is
686 * NULL, just return the size of the table.
688 * This call is obsolete. New programs should use query_module+QM_SYMBOLS
689 * which does not arbitrarily limit the length of symbols.
692 asmlinkage long
693 sys_get_kernel_syms(struct kernel_sym *table)
695 struct module *mod;
696 int i;
697 struct kernel_sym ksym;
699 lock_kernel();
700 for (mod = module_list, i = 0; mod; mod = mod->next) {
701 /* include the count for the module name! */
702 i += mod->nsyms + 1;
705 if (table == NULL)
706 goto out;
708 /* So that we don't give the user our stack content */
709 memset (&ksym, 0, sizeof (ksym));
711 for (mod = module_list, i = 0; mod; mod = mod->next) {
712 struct module_symbol *msym;
713 unsigned int j;
715 if ((mod->flags & (MOD_RUNNING|MOD_DELETED)) != MOD_RUNNING)
716 continue;
718 /* magic: write module info as a pseudo symbol */
719 ksym.value = (unsigned long)mod;
720 ksym.name[0] = '#';
721 strncpy(ksym.name+1, mod->name, sizeof(ksym.name)-1);
722 ksym.name[sizeof(ksym.name)-1] = '\0';
724 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
725 goto out;
726 ++i, ++table;
728 if (mod->nsyms == 0)
729 continue;
731 for (j = 0, msym = mod->syms; j < mod->nsyms; ++j, ++msym) {
732 ksym.value = msym->value;
733 strncpy(ksym.name, msym->name, sizeof(ksym.name));
734 ksym.name[sizeof(ksym.name)-1] = '\0';
736 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
737 goto out;
738 ++i, ++table;
741 out:
742 unlock_kernel();
743 return i;
747 * Look for a module by name, ignoring modules marked for deletion.
750 static struct module *
751 find_module(const char *name)
753 struct module *mod;
755 for (mod = module_list; mod ; mod = mod->next) {
756 if (mod->flags & MOD_DELETED)
757 continue;
758 if (!strcmp(mod->name, name))
759 break;
762 return mod;
766 * Free the given module.
769 static void
770 free_module(struct module *mod, int tag_freed)
772 struct module_ref *dep;
773 unsigned i;
775 /* Let the module clean up. */
777 mod->flags |= MOD_DELETED;
778 if (mod->flags & MOD_RUNNING)
780 if(mod->cleanup)
781 mod->cleanup();
782 mod->flags &= ~MOD_RUNNING;
785 /* Remove the module from the dependency lists. */
787 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
788 struct module_ref **pp;
789 for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref)
790 continue;
791 *pp = dep->next_ref;
792 if (tag_freed && dep->dep->refs == NULL)
793 dep->dep->flags |= MOD_JUST_FREED;
796 /* And from the main module list. */
798 if (mod == module_list) {
799 module_list = mod->next;
800 } else {
801 struct module *p;
802 for (p = module_list; p->next != mod; p = p->next)
803 continue;
804 p->next = mod->next;
807 /* And free the memory. */
809 module_unmap(mod);
813 * Called by the /proc file system to return a current list of modules.
816 int get_module_list(char *p)
818 size_t left = PAGE_SIZE;
819 struct module *mod;
820 char tmpstr[64];
821 struct module_ref *ref;
823 for (mod = module_list; mod != &kernel_module; mod = mod->next) {
824 long len;
825 const char *q;
827 #define safe_copy_str(str, len) \
828 do { \
829 if (left < len) \
830 goto fini; \
831 memcpy(p, str, len); p += len, left -= len; \
832 } while (0)
833 #define safe_copy_cstr(str) safe_copy_str(str, sizeof(str)-1)
835 len = strlen(mod->name);
836 safe_copy_str(mod->name, len);
838 if ((len = 20 - len) > 0) {
839 if (left < len)
840 goto fini;
841 memset(p, ' ', len);
842 p += len;
843 left -= len;
846 len = sprintf(tmpstr, "%8lu", mod->size);
847 safe_copy_str(tmpstr, len);
849 if (mod->flags & MOD_RUNNING) {
850 len = sprintf(tmpstr, "%4ld",
851 (mod_member_present(mod, can_unload)
852 && mod->can_unload
853 ? -1L : (long)atomic_read(&mod->uc.usecount)));
854 safe_copy_str(tmpstr, len);
857 if (mod->flags & MOD_DELETED)
858 safe_copy_cstr(" (deleted)");
859 else if (mod->flags & MOD_RUNNING) {
860 if (mod->flags & MOD_AUTOCLEAN)
861 safe_copy_cstr(" (autoclean)");
862 if (!(mod->flags & MOD_USED_ONCE))
863 safe_copy_cstr(" (unused)");
864 } else
865 safe_copy_cstr(" (uninitialized)");
867 if ((ref = mod->refs) != NULL) {
868 safe_copy_cstr(" [");
869 while (1) {
870 q = ref->ref->name;
871 len = strlen(q);
872 safe_copy_str(q, len);
874 if ((ref = ref->next_ref) != NULL)
875 safe_copy_cstr(" ");
876 else
877 break;
879 safe_copy_cstr("]");
881 safe_copy_cstr("\n");
883 #undef safe_copy_str
884 #undef safe_copy_cstr
887 fini:
888 return PAGE_SIZE - left;
892 * Called by the /proc file system to return a current list of ksyms.
896 get_ksyms_list(char *buf, char **start, off_t offset, int length)
898 struct module *mod;
899 char *p = buf;
900 int len = 0; /* code from net/ipv4/proc.c */
901 off_t pos = 0;
902 off_t begin = 0;
904 for (mod = module_list; mod; mod = mod->next) {
905 unsigned i;
906 struct module_symbol *sym;
908 if (!(mod->flags & MOD_RUNNING) || (mod->flags & MOD_DELETED))
909 continue;
911 for (i = mod->nsyms, sym = mod->syms; i > 0; --i, ++sym) {
912 p = buf + len;
913 if (*mod->name) {
914 len += sprintf(p, "%0*lx %s\t[%s]\n",
915 (int)(2*sizeof(void*)),
916 sym->value, sym->name,
917 mod->name);
918 } else {
919 len += sprintf(p, "%0*lx %s\n",
920 (int)(2*sizeof(void*)),
921 sym->value, sym->name);
923 pos = begin + len;
924 if (pos < offset) {
925 len = 0;
926 begin = pos;
928 pos = begin + len;
929 if (pos > offset+length)
930 goto leave_the_loop;
933 leave_the_loop:
934 *start = buf + (offset - begin);
935 len -= (offset - begin);
936 if (len > length)
937 len = length;
938 return len;
942 * Gets the address for a symbol in the given module. If modname is
943 * NULL, it looks for the name in any registered symbol table. If the
944 * modname is an empty string, it looks for the symbol in kernel exported
945 * symbol tables.
947 unsigned long
948 get_module_symbol(char *modname, char *symname)
950 struct module *mp;
951 struct module_symbol *sym;
952 int i;
954 for (mp = module_list; mp; mp = mp->next) {
955 if (((modname == NULL) || (strcmp(mp->name, modname) == 0)) &&
956 (mp->flags & (MOD_RUNNING | MOD_DELETED)) == MOD_RUNNING &&
957 (mp->nsyms > 0)) {
958 for (i = mp->nsyms, sym = mp->syms;
959 i > 0; --i, ++sym) {
961 if (strcmp(sym->name, symname) == 0) {
962 return sym->value;
967 return 0;
970 #else /* CONFIG_MODULES */
972 /* Dummy syscalls for people who don't want modules */
974 asmlinkage unsigned long
975 sys_create_module(const char *name_user, size_t size)
977 return -ENOSYS;
980 asmlinkage long
981 sys_init_module(const char *name_user, struct module *mod_user)
983 return -ENOSYS;
986 asmlinkage long
987 sys_delete_module(const char *name_user)
989 return -ENOSYS;
992 asmlinkage long
993 sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
994 size_t *ret)
996 /* Let the program know about the new interface. Not that
997 it'll do them much good. */
998 if (which == 0)
999 return 0;
1001 return -ENOSYS;
1004 asmlinkage long
1005 sys_get_kernel_syms(struct kernel_sym *table)
1007 return -ENOSYS;
1010 #endif /* CONFIG_MODULES */