Import 2.3.30pre7
[davej-history.git] / kernel / module.c
blob9ceb36f9e06dcb574053dee7fa320f2d6e367273
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 if (!capable(CAP_SYS_MODULE))
115 return -EPERM;
116 lock_kernel();
117 if ((namelen = get_mod_name(name_user, &name)) < 0) {
118 error = namelen;
119 goto err0;
121 if (size < sizeof(struct module)+namelen) {
122 error = -EINVAL;
123 goto err1;
125 if (find_module(name) != NULL) {
126 error = -EEXIST;
127 goto err1;
129 if ((mod = (struct module *)module_map(size)) == NULL) {
130 error = -ENOMEM;
131 goto err1;
134 memset(mod, 0, sizeof(*mod));
135 mod->size_of_struct = sizeof(*mod);
136 mod->next = module_list;
137 mod->name = (char *)(mod + 1);
138 mod->size = size;
139 memcpy((char*)(mod+1), name, namelen+1);
141 put_mod_name(name);
143 module_list = mod; /* link it in */
145 error = (long) mod;
146 goto err0;
147 err1:
148 put_mod_name(name);
149 err0:
150 unlock_kernel();
151 return error;
155 * Initialize a module.
158 asmlinkage long
159 sys_init_module(const char *name_user, struct module *mod_user)
161 struct module mod_tmp, *mod;
162 char *name, *n_name;
163 long namelen, n_namelen, i, error;
164 unsigned long mod_user_size;
165 struct module_ref *dep;
167 if (!capable(CAP_SYS_MODULE))
168 return -EPERM;
169 lock_kernel();
170 if ((namelen = get_mod_name(name_user, &name)) < 0) {
171 error = namelen;
172 goto err0;
174 if ((mod = find_module(name)) == NULL) {
175 error = -ENOENT;
176 goto err1;
179 /* Check module header size. We allow a bit of slop over the
180 size we are familiar with to cope with a version of insmod
181 for a newer kernel. But don't over do it. */
182 if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0)
183 goto err1;
184 if (mod_user_size < (unsigned long)&((struct module *)0L)->persist_start
185 || mod_user_size > sizeof(struct module) + 16*sizeof(void*)) {
186 printk(KERN_ERR "init_module: Invalid module header size.\n"
187 KERN_ERR "A new version of the modutils is likely "
188 "needed.\n");
189 error = -EINVAL;
190 goto err1;
193 /* Hold the current contents while we play with the user's idea
194 of righteousness. */
195 mod_tmp = *mod;
197 error = copy_from_user(mod, mod_user, sizeof(struct module));
198 if (error) {
199 error = -EFAULT;
200 goto err2;
203 /* Sanity check the size of the module. */
204 error = -EINVAL;
206 if (mod->size > mod_tmp.size) {
207 printk(KERN_ERR "init_module: Size of initialized module "
208 "exceeds size of created module.\n");
209 goto err2;
212 /* Make sure all interesting pointers are sane. */
214 #define bound(p, n, m) ((unsigned long)(p) >= (unsigned long)(m+1) && \
215 (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
217 if (!bound(mod->name, namelen, mod)) {
218 printk(KERN_ERR "init_module: mod->name out of bounds.\n");
219 goto err2;
221 if (mod->nsyms && !bound(mod->syms, mod->nsyms, mod)) {
222 printk(KERN_ERR "init_module: mod->syms out of bounds.\n");
223 goto err2;
225 if (mod->ndeps && !bound(mod->deps, mod->ndeps, mod)) {
226 printk(KERN_ERR "init_module: mod->deps out of bounds.\n");
227 goto err2;
229 if (mod->init && !bound(mod->init, 0, mod)) {
230 printk(KERN_ERR "init_module: mod->init out of bounds.\n");
231 goto err2;
233 if (mod->cleanup && !bound(mod->cleanup, 0, mod)) {
234 printk(KERN_ERR "init_module: mod->cleanup out of bounds.\n");
235 goto err2;
237 if (mod->ex_table_start > mod->ex_table_end
238 || (mod->ex_table_start &&
239 !((unsigned long)mod->ex_table_start >= (unsigned long)(mod+1)
240 && ((unsigned long)mod->ex_table_end
241 < (unsigned long)mod + mod->size)))
242 || (((unsigned long)mod->ex_table_start
243 - (unsigned long)mod->ex_table_end)
244 % sizeof(struct exception_table_entry))) {
245 printk(KERN_ERR "init_module: mod->ex_table_* invalid.\n");
246 goto err2;
248 if (mod->flags & ~MOD_AUTOCLEAN) {
249 printk(KERN_ERR "init_module: mod->flags invalid.\n");
250 goto err2;
252 #ifdef __alpha__
253 if (!bound(mod->gp - 0x8000, 0, mod)) {
254 printk(KERN_ERR "init_module: mod->gp out of bounds.\n");
255 goto err2;
257 #endif
258 if (mod_member_present(mod, can_unload)
259 && mod->can_unload && !bound(mod->can_unload, 0, mod)) {
260 printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");
261 goto err2;
264 #undef bound
266 /* Check that the user isn't doing something silly with the name. */
268 if ((n_namelen = get_mod_name(mod->name - (unsigned long)mod
269 + (unsigned long)mod_user,
270 &n_name)) < 0) {
271 error = n_namelen;
272 goto err2;
274 if (namelen != n_namelen || strcmp(n_name, mod_tmp.name) != 0) {
275 printk(KERN_ERR "init_module: changed module name to "
276 "`%s' from `%s'\n",
277 n_name, mod_tmp.name);
278 goto err3;
281 /* Ok, that's about all the sanity we can stomach; copy the rest. */
283 if (copy_from_user(mod+1, mod_user+1, mod->size-sizeof(*mod))) {
284 error = -EFAULT;
285 goto err3;
288 /* On some machines it is necessary to do something here
289 to make the I and D caches consistent. */
290 flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
292 /* Update module references. */
293 mod->next = mod_tmp.next;
294 mod->refs = NULL;
295 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
296 struct module *o, *d = dep->dep;
298 /* Make sure the indicated dependencies are really modules. */
299 if (d == mod) {
300 printk(KERN_ERR "init_module: self-referential "
301 "dependency in mod->deps.\n");
302 goto err3;
305 for (o = module_list; o != &kernel_module; o = o->next)
306 if (o == d) goto found_dep;
308 printk(KERN_ERR "init_module: found dependency that is "
309 "(no longer?) a module.\n");
310 goto err3;
312 found_dep:
313 dep->ref = mod;
314 dep->next_ref = d->refs;
315 d->refs = dep;
316 /* Being referenced by a dependent module counts as a
317 use as far as kmod is concerned. */
318 d->flags |= MOD_USED_ONCE;
321 /* Free our temporary memory. */
322 put_mod_name(n_name);
323 put_mod_name(name);
325 /* Initialize the module. */
326 atomic_set(&mod->uc.usecount,1);
327 if (mod->init && mod->init() != 0) {
328 atomic_set(&mod->uc.usecount,0);
329 error = -EBUSY;
330 goto err0;
332 atomic_dec(&mod->uc.usecount);
334 /* And set it running. */
335 mod->flags |= MOD_RUNNING;
336 error = 0;
337 goto err0;
339 err3:
340 put_mod_name(n_name);
341 err2:
342 *mod = mod_tmp;
343 err1:
344 put_mod_name(name);
345 err0:
346 unlock_kernel();
347 return error;
350 asmlinkage long
351 sys_delete_module(const char *name_user)
353 struct module *mod, *next;
354 char *name;
355 long error;
356 int something_changed;
358 if (!capable(CAP_SYS_MODULE))
359 return -EPERM;
361 lock_kernel();
362 if (name_user) {
363 if ((error = get_mod_name(name_user, &name)) < 0)
364 goto out;
365 if (error == 0) {
366 error = -EINVAL;
367 put_mod_name(name);
368 goto out;
370 error = -ENOENT;
371 if ((mod = find_module(name)) == NULL) {
372 put_mod_name(name);
373 goto out;
375 put_mod_name(name);
376 error = -EBUSY;
377 if (mod->refs != NULL || __MOD_IN_USE(mod))
378 goto out;
380 free_module(mod, 0);
381 error = 0;
382 goto out;
385 /* Do automatic reaping */
386 restart:
387 something_changed = 0;
388 for (mod = module_list; mod != &kernel_module; mod = next) {
389 next = mod->next;
390 if (mod->refs == NULL
391 && (mod->flags & MOD_AUTOCLEAN)
392 && (mod->flags & MOD_RUNNING)
393 && !(mod->flags & MOD_DELETED)
394 && (mod->flags & MOD_USED_ONCE)
395 && !__MOD_IN_USE(mod)) {
396 if ((mod->flags & MOD_VISITED)
397 && !(mod->flags & MOD_JUST_FREED)) {
398 mod->flags &= ~MOD_VISITED;
399 } else {
400 free_module(mod, 1);
401 something_changed = 1;
405 if (something_changed)
406 goto restart;
407 for (mod = module_list; mod != &kernel_module; mod = mod->next)
408 mod->flags &= ~MOD_JUST_FREED;
409 error = 0;
410 out:
411 unlock_kernel();
412 return error;
415 /* Query various bits about modules. */
417 static int
418 qm_modules(char *buf, size_t bufsize, size_t *ret)
420 struct module *mod;
421 size_t nmod, space, len;
423 nmod = space = 0;
425 for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) {
426 len = strlen(mod->name)+1;
427 if (len > bufsize)
428 goto calc_space_needed;
429 if (copy_to_user(buf, mod->name, len))
430 return -EFAULT;
431 buf += len;
432 bufsize -= len;
433 space += len;
436 if (put_user(nmod, ret))
437 return -EFAULT;
438 else
439 return 0;
441 calc_space_needed:
442 space += len;
443 while ((mod = mod->next) != &kernel_module)
444 space += strlen(mod->name)+1;
446 if (put_user(space, ret))
447 return -EFAULT;
448 else
449 return -ENOSPC;
452 static int
453 qm_deps(struct module *mod, char *buf, size_t bufsize, size_t *ret)
455 size_t i, space, len;
457 if (mod == &kernel_module)
458 return -EINVAL;
459 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
460 if (put_user(0, ret))
461 return -EFAULT;
462 else
463 return 0;
465 space = 0;
466 for (i = 0; i < mod->ndeps; ++i) {
467 const char *dep_name = mod->deps[i].dep->name;
469 len = strlen(dep_name)+1;
470 if (len > bufsize)
471 goto calc_space_needed;
472 if (copy_to_user(buf, dep_name, len))
473 return -EFAULT;
474 buf += len;
475 bufsize -= len;
476 space += len;
479 if (put_user(i, ret))
480 return -EFAULT;
481 else
482 return 0;
484 calc_space_needed:
485 space += len;
486 while (++i < mod->ndeps)
487 space += strlen(mod->deps[i].dep->name)+1;
489 if (put_user(space, ret))
490 return -EFAULT;
491 else
492 return -ENOSPC;
495 static int
496 qm_refs(struct module *mod, char *buf, size_t bufsize, size_t *ret)
498 size_t nrefs, space, len;
499 struct module_ref *ref;
501 if (mod == &kernel_module)
502 return -EINVAL;
503 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
504 if (put_user(0, ret))
505 return -EFAULT;
506 else
507 return 0;
509 space = 0;
510 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
511 const char *ref_name = ref->ref->name;
513 len = strlen(ref_name)+1;
514 if (len > bufsize)
515 goto calc_space_needed;
516 if (copy_to_user(buf, ref_name, len))
517 return -EFAULT;
518 buf += len;
519 bufsize -= len;
520 space += len;
523 if (put_user(nrefs, ret))
524 return -EFAULT;
525 else
526 return 0;
528 calc_space_needed:
529 space += len;
530 while ((ref = ref->next_ref) != NULL)
531 space += strlen(ref->ref->name)+1;
533 if (put_user(space, ret))
534 return -EFAULT;
535 else
536 return -ENOSPC;
539 static int
540 qm_symbols(struct module *mod, char *buf, size_t bufsize, size_t *ret)
542 size_t i, space, len;
543 struct module_symbol *s;
544 char *strings;
545 unsigned long *vals;
547 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
548 if (put_user(0, ret))
549 return -EFAULT;
550 else
551 return 0;
553 space = mod->nsyms * 2*sizeof(void *);
555 i = len = 0;
556 s = mod->syms;
558 if (space > bufsize)
559 goto calc_space_needed;
561 if (!access_ok(VERIFY_WRITE, buf, space))
562 return -EFAULT;
564 bufsize -= space;
565 vals = (unsigned long *)buf;
566 strings = buf+space;
568 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
569 len = strlen(s->name)+1;
570 if (len > bufsize)
571 goto calc_space_needed;
573 if (copy_to_user(strings, s->name, len)
574 || __put_user(s->value, vals+0)
575 || __put_user(space, vals+1))
576 return -EFAULT;
578 strings += len;
579 bufsize -= len;
580 space += len;
583 if (put_user(i, ret))
584 return -EFAULT;
585 else
586 return 0;
588 calc_space_needed:
589 for (; i < mod->nsyms; ++i, ++s)
590 space += strlen(s->name)+1;
592 if (put_user(space, ret))
593 return -EFAULT;
594 else
595 return -ENOSPC;
598 static int
599 qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret)
601 int error = 0;
603 if (mod == &kernel_module)
604 return -EINVAL;
606 if (sizeof(struct module_info) <= bufsize) {
607 struct module_info info;
608 info.addr = (unsigned long)mod;
609 info.size = mod->size;
610 info.flags = mod->flags;
611 info.usecount = (mod_member_present(mod, can_unload)
612 && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount));
614 if (copy_to_user(buf, &info, sizeof(struct module_info)))
615 return -EFAULT;
616 } else
617 error = -ENOSPC;
619 if (put_user(sizeof(struct module_info), ret))
620 return -EFAULT;
622 return error;
625 asmlinkage long
626 sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
627 size_t *ret)
629 struct module *mod;
630 int err;
632 lock_kernel();
633 if (name_user == NULL)
634 mod = &kernel_module;
635 else {
636 long namelen;
637 char *name;
639 if ((namelen = get_mod_name(name_user, &name)) < 0) {
640 err = namelen;
641 goto out;
643 err = -ENOENT;
644 if (namelen == 0)
645 mod = &kernel_module;
646 else if ((mod = find_module(name)) == NULL) {
647 put_mod_name(name);
648 goto out;
650 put_mod_name(name);
653 switch (which)
655 case 0:
656 err = 0;
657 break;
658 case QM_MODULES:
659 err = qm_modules(buf, bufsize, ret);
660 break;
661 case QM_DEPS:
662 err = qm_deps(mod, buf, bufsize, ret);
663 break;
664 case QM_REFS:
665 err = qm_refs(mod, buf, bufsize, ret);
666 break;
667 case QM_SYMBOLS:
668 err = qm_symbols(mod, buf, bufsize, ret);
669 break;
670 case QM_INFO:
671 err = qm_info(mod, buf, bufsize, ret);
672 break;
673 default:
674 err = -EINVAL;
675 break;
677 out:
678 unlock_kernel();
679 return err;
683 * Copy the kernel symbol table to user space. If the argument is
684 * NULL, just return the size of the table.
686 * This call is obsolete. New programs should use query_module+QM_SYMBOLS
687 * which does not arbitrarily limit the length of symbols.
690 asmlinkage long
691 sys_get_kernel_syms(struct kernel_sym *table)
693 struct module *mod;
694 int i;
695 struct kernel_sym ksym;
697 lock_kernel();
698 for (mod = module_list, i = 0; mod; mod = mod->next) {
699 /* include the count for the module name! */
700 i += mod->nsyms + 1;
703 if (table == NULL)
704 goto out;
706 /* So that we don't give the user our stack content */
707 memset (&ksym, 0, sizeof (ksym));
709 for (mod = module_list, i = 0; mod; mod = mod->next) {
710 struct module_symbol *msym;
711 unsigned int j;
713 if ((mod->flags & (MOD_RUNNING|MOD_DELETED)) != MOD_RUNNING)
714 continue;
716 /* magic: write module info as a pseudo symbol */
717 ksym.value = (unsigned long)mod;
718 ksym.name[0] = '#';
719 strncpy(ksym.name+1, mod->name, sizeof(ksym.name)-1);
720 ksym.name[sizeof(ksym.name)-1] = '\0';
722 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
723 goto out;
724 ++i, ++table;
726 if (mod->nsyms == 0)
727 continue;
729 for (j = 0, msym = mod->syms; j < mod->nsyms; ++j, ++msym) {
730 ksym.value = msym->value;
731 strncpy(ksym.name, msym->name, sizeof(ksym.name));
732 ksym.name[sizeof(ksym.name)-1] = '\0';
734 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
735 goto out;
736 ++i, ++table;
739 out:
740 unlock_kernel();
741 return i;
745 * Look for a module by name, ignoring modules marked for deletion.
748 static struct module *
749 find_module(const char *name)
751 struct module *mod;
753 for (mod = module_list; mod ; mod = mod->next) {
754 if (mod->flags & MOD_DELETED)
755 continue;
756 if (!strcmp(mod->name, name))
757 break;
760 return mod;
764 * Free the given module.
767 static void
768 free_module(struct module *mod, int tag_freed)
770 struct module_ref *dep;
771 unsigned i;
773 /* Let the module clean up. */
775 mod->flags |= MOD_DELETED;
776 if (mod->flags & MOD_RUNNING)
778 if(mod->cleanup)
779 mod->cleanup();
780 mod->flags &= ~MOD_RUNNING;
783 /* Remove the module from the dependency lists. */
785 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
786 struct module_ref **pp;
787 for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref)
788 continue;
789 *pp = dep->next_ref;
790 if (tag_freed && dep->dep->refs == NULL)
791 dep->dep->flags |= MOD_JUST_FREED;
794 /* And from the main module list. */
796 if (mod == module_list) {
797 module_list = mod->next;
798 } else {
799 struct module *p;
800 for (p = module_list; p->next != mod; p = p->next)
801 continue;
802 p->next = mod->next;
805 /* And free the memory. */
807 module_unmap(mod);
811 * Called by the /proc file system to return a current list of modules.
814 int get_module_list(char *p)
816 size_t left = PAGE_SIZE;
817 struct module *mod;
818 char tmpstr[64];
819 struct module_ref *ref;
821 for (mod = module_list; mod != &kernel_module; mod = mod->next) {
822 long len;
823 const char *q;
825 #define safe_copy_str(str, len) \
826 do { \
827 if (left < len) \
828 goto fini; \
829 memcpy(p, str, len); p += len, left -= len; \
830 } while (0)
831 #define safe_copy_cstr(str) safe_copy_str(str, sizeof(str)-1)
833 len = strlen(mod->name);
834 safe_copy_str(mod->name, len);
836 if ((len = 20 - len) > 0) {
837 if (left < len)
838 goto fini;
839 memset(p, ' ', len);
840 p += len;
841 left -= len;
844 len = sprintf(tmpstr, "%8lu", mod->size);
845 safe_copy_str(tmpstr, len);
847 if (mod->flags & MOD_RUNNING) {
848 len = sprintf(tmpstr, "%4ld",
849 (mod_member_present(mod, can_unload)
850 && mod->can_unload
851 ? -1L : (long)atomic_read(&mod->uc.usecount)));
852 safe_copy_str(tmpstr, len);
855 if (mod->flags & MOD_DELETED)
856 safe_copy_cstr(" (deleted)");
857 else if (mod->flags & MOD_RUNNING) {
858 if (mod->flags & MOD_AUTOCLEAN)
859 safe_copy_cstr(" (autoclean)");
860 if (!(mod->flags & MOD_USED_ONCE))
861 safe_copy_cstr(" (unused)");
862 } else
863 safe_copy_cstr(" (uninitialized)");
865 if ((ref = mod->refs) != NULL) {
866 safe_copy_cstr(" [");
867 while (1) {
868 q = ref->ref->name;
869 len = strlen(q);
870 safe_copy_str(q, len);
872 if ((ref = ref->next_ref) != NULL)
873 safe_copy_cstr(" ");
874 else
875 break;
877 safe_copy_cstr("]");
879 safe_copy_cstr("\n");
881 #undef safe_copy_str
882 #undef safe_copy_cstr
885 fini:
886 return PAGE_SIZE - left;
890 * Called by the /proc file system to return a current list of ksyms.
894 get_ksyms_list(char *buf, char **start, off_t offset, int length)
896 struct module *mod;
897 char *p = buf;
898 int len = 0; /* code from net/ipv4/proc.c */
899 off_t pos = 0;
900 off_t begin = 0;
902 for (mod = module_list; mod; mod = mod->next) {
903 unsigned i;
904 struct module_symbol *sym;
906 if (!(mod->flags & MOD_RUNNING) || (mod->flags & MOD_DELETED))
907 continue;
909 for (i = mod->nsyms, sym = mod->syms; i > 0; --i, ++sym) {
910 p = buf + len;
911 if (*mod->name) {
912 len += sprintf(p, "%0*lx %s\t[%s]\n",
913 (int)(2*sizeof(void*)),
914 sym->value, sym->name,
915 mod->name);
916 } else {
917 len += sprintf(p, "%0*lx %s\n",
918 (int)(2*sizeof(void*)),
919 sym->value, sym->name);
921 pos = begin + len;
922 if (pos < offset) {
923 len = 0;
924 begin = pos;
926 pos = begin + len;
927 if (pos > offset+length)
928 goto leave_the_loop;
931 leave_the_loop:
932 *start = buf + (offset - begin);
933 len -= (offset - begin);
934 if (len > length)
935 len = length;
936 return len;
940 * Gets the address for a symbol in the given module. If modname is
941 * NULL, it looks for the name in any registered symbol table. If the
942 * modname is an empty string, it looks for the symbol in kernel exported
943 * symbol tables.
945 unsigned long
946 get_module_symbol(char *modname, char *symname)
948 struct module *mp;
949 struct module_symbol *sym;
950 int i;
952 for (mp = module_list; mp; mp = mp->next) {
953 if (((modname == NULL) || (strcmp(mp->name, modname) == 0)) &&
954 (mp->flags & (MOD_RUNNING | MOD_DELETED)) == MOD_RUNNING &&
955 (mp->nsyms > 0)) {
956 for (i = mp->nsyms, sym = mp->syms;
957 i > 0; --i, ++sym) {
959 if (strcmp(sym->name, symname) == 0) {
960 return sym->value;
965 return 0;
968 #else /* CONFIG_MODULES */
970 /* Dummy syscalls for people who don't want modules */
972 asmlinkage unsigned long
973 sys_create_module(const char *name_user, size_t size)
975 return -ENOSYS;
978 asmlinkage long
979 sys_init_module(const char *name_user, struct module *mod_user)
981 return -ENOSYS;
984 asmlinkage long
985 sys_delete_module(const char *name_user)
987 return -ENOSYS;
990 asmlinkage long
991 sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
992 size_t *ret)
994 /* Let the program know about the new interface. Not that
995 it'll do them much good. */
996 if (which == 0)
997 return 0;
999 return -ENOSYS;
1002 asmlinkage long
1003 sys_get_kernel_syms(struct kernel_sym *table)
1005 return -ENOSYS;
1008 #endif /* CONFIG_MODULES */