~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/kernel/module.c

Version: ~ [ linux-2.2.14 ] ~ [ modutils-2.3.10 ] ~
DefVersion: ~ [ linux-2.2.14 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.