1 #include <linux/errno.h>
2 #include <linux/kernel.h>
3 #include <asm/segment.h>
4 #include <linux/mm.h> /* defines GFP_KERNEL */
5 #include <linux/string.h>
6 #include <linux/module.h>
7 #include <linux/sched.h>
8 #include <linux/malloc.h>
9 #include <linux/config.h>
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 *
15 * Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
16 * This source is covered by the GNU GPL, the same as all kernel sources.
17 *
18 * Features:
19 * - Supports stacked modules (removable only of there are no dependents).
20 * - Supports table of symbols defined by the modules.
21 * - Supports /proc/ksyms, showing value, name and owner of all
22 * the symbols defined by all modules (in stack order).
23 * - Added module dependencies information into /proc/modules
24 * - Supports redefines of all symbols, for streams-like behaviour.
25 * - Compatible with older versions of insmod.
26 *
27 * New addition in December 1994: (Bjorn Ekwall, idea from Jacques Gelinas)
28 * - Externally callable function:
29 *
30 * "int register_symtab(struct symbol_table *)"
31 *
32 * This function can be called from within the kernel,
33 * and ALSO from loadable modules.
34 * The goal is to assist in modularizing the kernel even more,
35 * and finally: reducing the number of entries in ksyms.c
36 * since every subsystem should now be able to decide and
37 * control exactly what symbols it wants to export, locally!
38 *
39 * On 1-Aug-95: <Matti.Aarnio@utu.fi> altered code to use same style as
40 * do /proc/net/XXX "files". Namely allow more than 4kB
41 * (or what the block size if) output.
42 *
43 * - Use dummy syscall functions for users who disable all
44 * module support. Similar to kernel/sys.c (Paul Gortmaker)
45 */
46
47 #ifdef CONFIG_MODULES /* a *big* #ifdef block... */
48
49 #ifdef DEBUG_MODULE
50 #define PRINTK(a) printk a
51 #else
52 #define PRINTK(a) /* */
53 #endif
54
55 static struct module kernel_module;
56 static struct module *module_list = &kernel_module;
57
58 static int freeing_modules; /* true if some modules are marked for deletion */
59
60 static struct module *find_module( const char *name);
61 static int get_mod_name( char *user_name, char *buf);
62 static int free_modules( void);
63
64 static int module_init_flag = 0; /* Hmm... */
65
66 extern struct symbol_table symbol_table; /* in kernel/ksyms.c */
67
68 /*
69 * Called at boot time
70 */
71 void init_modules(void) {
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
72 struct internal_symbol *sym;
73 int i;
74
75 for (i = 0, sym = symbol_table.symbol; sym->name; ++sym, ++i)
76 ;
77 symbol_table.n_symbols = i;
78
79 kernel_module.symtab = &symbol_table;
80 kernel_module.state = MOD_RUNNING; /* Hah! */
81 kernel_module.name = "";
82 }
83
84 int
85 rename_module_symbol(char *old_name, char *new_name)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
86 {
87 struct internal_symbol *sym;
88 int i = 0; /* keep gcc silent */
89
90 if (module_list->symtab) {
91 sym = module_list->symtab->symbol;
92 for (i = module_list->symtab->n_symbols; i > 0; ++sym, --i) {
93 if (strcmp(sym->name, old_name) == 0) { /* found it! */
94 sym->name = new_name; /* done! */
95 PRINTK(("renamed %s to %s\n", old_name, new_name));
96 return 1; /* it worked! */
97 }
98 }
99 }
100 printk("rename %s to %s failed!\n", old_name, new_name);
101 return 0; /* not there... */
102
103 /*
104 * This one will change the name of the first matching symbol!
105 *
106 * With this function, you can replace the name of a symbol defined
107 * in the current module with a new name, e.g. when you want to insert
108 * your own function instead of a previously defined function
109 * with the same name.
110 *
111 * "Normal" usage:
112 *
113 * bogus_function(int params)
114 * {
115 * do something "smart";
116 * return real_function(params);
117 * }
118 *
119 * ...
120 *
121 * init_module()
122 * {
123 * if (rename_module_symbol("_bogus_function", "_real_function"))
124 * printk("yep!\n");
125 * else
126 * printk("no way!\n");
127 * ...
128 * }
129 *
130 * When loading this module, real_function will be resolved
131 * to the real function address.
132 * All later loaded modules that refer to "real_function()" will
133 * then really call "bogus_function()" instead!!!
134 *
135 * This feature will give you ample opportunities to get to know
136 * the taste of your foot when you stuff it into your mouth!!!
137 */
138 }
139
140 /*
141 * Allocate space for a module.
142 */
143 asmlinkage unsigned long
144 sys_create_module(char *module_name, unsigned long size)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
145 {
146 struct module *mp;
147 void* addr;
148 int error;
149 int npages;
150 int sspace = sizeof(struct module) + MOD_MAX_NAME;
151 char name[MOD_MAX_NAME];
152
153 if (!suser())
154 return -EPERM;
155 if (module_name == NULL || size == 0)
156 return -EINVAL;
157 if ((error = get_mod_name(module_name, name)) != 0)
158 return error;
159 if (find_module(name) != NULL) {
160 return -EEXIST;
161 }
162
163 if ((mp = (struct module*) kmalloc(sspace, GFP_KERNEL)) == NULL) {
164 return -ENOMEM;
165 }
166 strcpy((char *)(mp + 1), name); /* why not? */
167
168 npages = (size + sizeof (long) + PAGE_SIZE - 1) / PAGE_SIZE;
169 if ((addr = vmalloc(npages * PAGE_SIZE)) == 0) {
170 kfree_s(mp, sspace);
171 return -ENOMEM;
172 }
173
174 mp->next = module_list;
175 mp->ref = NULL;
176 mp->symtab = NULL;
177 mp->name = (char *)(mp + 1);
178 mp->size = npages;
179 mp->addr = addr;
180 mp->state = MOD_UNINITIALIZED;
181 mp->cleanup = NULL;
182
183 * (long *) addr = 0; /* set use count to zero */
184 module_list = mp; /* link it in */
185
186 PRINTK(("module `%s' (%lu pages @ 0x%08lx) created\n",
187 mp->name, (unsigned long) mp->size, (unsigned long) mp->addr));
188 return (unsigned long) addr;
189 }
190
191 /*
192 * Initialize a module.
193 */
194 asmlinkage int
195 sys_init_module(char *module_name, char *code, unsigned codesize,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
196 struct mod_routines *routines,
197 struct symbol_table *symtab)
198 {
199 struct module *mp;
200 struct symbol_table *newtab;
201 char name[MOD_MAX_NAME];
202 int error;
203 struct mod_routines rt;
204
205 if (!suser())
206 return -EPERM;
207
208 #ifdef __i386__
209 /* A little bit of protection... we "know" where the user stack is... */
210
211 if (symtab && ((unsigned long)symtab > 0xb0000000)) {
212 printk("warning: you are using an old insmod, no symbols will be inserted!\n");
213 symtab = NULL;
214 }
215 #endif
216
217 /*
218 * First reclaim any memory from dead modules that where not
219 * freed when deleted. Should I think be done by timers when
220 * the module was deleted - Jon.
221 */
222 free_modules();
223
224 if ((error = get_mod_name(module_name, name)) != 0)
225 return error;
226 PRINTK(("initializing module `%s', %d (0x%x) bytes\n",
227 name, codesize, codesize));
228 memcpy_fromfs(&rt, routines, sizeof rt);
229 if ((mp = find_module(name)) == NULL)
230 return -ENOENT;
231 if ((codesize + sizeof (long) + PAGE_SIZE - 1) / PAGE_SIZE > mp->size)
232 return -EINVAL;
233 memcpy_fromfs((char *)mp->addr + sizeof (long), code, codesize);
234 memset((char *)mp->addr + sizeof (long) + codesize, 0,
235 mp->size * PAGE_SIZE - (codesize + sizeof (long)));
236 PRINTK(( "module init entry = 0x%08lx, cleanup entry = 0x%08lx\n",
237 (unsigned long) rt.init, (unsigned long) rt.cleanup));
238 mp->cleanup = rt.cleanup;
239
240 /* update kernel symbol table */
241 if (symtab) { /* symtab == NULL means no new entries to handle */
242 struct internal_symbol *sym;
243 struct module_ref *ref;
244 int size;
245 int i;
246 int legal_start;
247
248 if ((error = verify_area(VERIFY_READ, &symtab->size, sizeof(symtab->size))))
249 return error;
250 size = get_user(&symtab->size);
251
252 if ((newtab = (struct symbol_table*) kmalloc(size, GFP_KERNEL)) == NULL) {
253 return -ENOMEM;
254 }
255
256 if ((error = verify_area(VERIFY_READ, symtab, size))) {
257 kfree_s(newtab, size);
258 return error;
259 }
260 memcpy_fromfs((char *)(newtab), symtab, size);
261
262 /* sanity check */
263 legal_start = sizeof(struct symbol_table) +
264 newtab->n_symbols * sizeof(struct internal_symbol) +
265 newtab->n_refs * sizeof(struct module_ref);
266
267 if ((newtab->n_symbols < 0) || (newtab->n_refs < 0) || (legal_start > size)) {
268 printk("Rejecting illegal symbol table (n_symbols=%d,n_refs=%d)\n",
269 newtab->n_symbols, newtab->n_refs);
270 kfree_s(newtab, size);
271 return -EINVAL;
272 }
273
274 /* relocate name pointers, index referred from start of table */
275 for (sym = &(newtab->symbol[0]), i = 0; i < newtab->n_symbols; ++sym, ++i) {
276 if ((unsigned long)sym->name < legal_start || size <= (unsigned long)sym->name) {
277 printk("Rejecting illegal symbol table\n");
278 kfree_s(newtab, size);
279 return -EINVAL;
280 }
281 /* else */
282 sym->name += (long)newtab;
283 }
284 mp->symtab = newtab;
285
286 /* Update module references.
287 * On entry, from "insmod", ref->module points to
288 * the referenced module!
289 * Now it will point to the current module instead!
290 * The ref structure becomes the first link in the linked
291 * list of references to the referenced module.
292 * Also, "sym" from above, points to the first ref entry!!!
293 */
294 for (ref = (struct module_ref *)sym, i = 0;
295 i < newtab->n_refs; ++ref, ++i) {
296
297 /* Check for valid reference */
298 struct module *link = module_list;
299 while (link && (ref->module != link))
300 link = link->next;
301
302 if (link == (struct module *)0) {
303 printk("Non-module reference! Rejected!\n");
304 return -EINVAL;
305 }
306
307 ref->next = ref->module->ref;
308 ref->module->ref = ref;
309 ref->module = mp;
310 }
311 }
312
313 module_init_flag = 1; /* Hmm... */
314 if ((*rt.init)() != 0) {
315 module_init_flag = 0; /* Hmm... */
316 return -EBUSY;
317 }
318 module_init_flag = 0; /* Hmm... */
319 mp->state = MOD_RUNNING;
320
321 return 0;
322 }
323
324 asmlinkage int
325 sys_delete_module(char *module_name)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
326 {
327 struct module *mp;
328 char name[MOD_MAX_NAME];
329 int error;
330
331 if (!suser())
332 return -EPERM;
333 /* else */
334 if (module_name != NULL) {
335 if ((error = get_mod_name(module_name, name)) != 0)
336 return error;
337 if ((mp = find_module(name)) == NULL)
338 return -ENOENT;
339 if ((mp->ref != NULL) || (GET_USE_COUNT(mp) != 0))
340 return -EBUSY;
341 if (mp->state == MOD_RUNNING)
342 (*mp->cleanup)();
343 mp->state = MOD_DELETED;
344 }
345 free_modules();
346 return 0;
347 }
348
349
350 /*
351 * Copy the kernel symbol table to user space. If the argument is null,
352 * just return the size of the table.
353 *
354 * Note that the transient module symbols are copied _first_,
355 * in lifo order!!!
356 *
357 * The symbols to "insmod" are according to the "old" format: struct kernel_sym,
358 * which is actually quite handy for this purpose.
359 * Note that insmod inserts a struct symbol_table later on...
360 * (as that format is quite handy for the kernel...)
361 *
362 * For every module, the first (pseudo)symbol copied is the module name
363 * and the address of the module struct.
364 * This lets "insmod" keep track of references, and build the array of
365 * struct module_refs in the symbol table.
366 * The format of the module name is "#module", so that "insmod" can easily
367 * notice when a module name comes along. Also, this will make it possible
368 * to use old versions of "insmod", albeit with reduced functionality...
369 * The "kernel" module has an empty name.
370 */
371 asmlinkage int
372 sys_get_kernel_syms(struct kernel_sym *table)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
373 {
374 struct internal_symbol *from;
375 struct kernel_sym isym;
376 struct kernel_sym *to;
377 struct module *mp = module_list;
378 int i;
379 int nmodsyms = 0;
380
381 for (mp = module_list; mp; mp = mp->next) {
382 if (mp->symtab && mp->symtab->n_symbols) {
383 /* include the count for the module name! */
384 nmodsyms += mp->symtab->n_symbols + 1;
385 }
386 else
387 /* include the count for the module name! */
388 nmodsyms += 1; /* return modules without symbols too */
389 }
390
391 if (table != NULL) {
392 to = table;
393
394 if ((i = verify_area(VERIFY_WRITE, to, nmodsyms * sizeof(*table))))
395 return i;
396
397 /* copy all module symbols first (always LIFO order) */
398 for (mp = module_list; mp; mp = mp->next) {
399 if (mp->state == MOD_RUNNING) {
400 /* magic: write module info as a pseudo symbol */
401 isym.value = (unsigned long)mp;
402 sprintf(isym.name, "#%s", mp->name);
403 memcpy_tofs(to, &isym, sizeof isym);
404 ++to;
405
406 if (mp->symtab != NULL) {
407 for (i = mp->symtab->n_symbols,
408 from = mp->symtab->symbol;
409 i > 0; --i, ++from, ++to) {
410
411 isym.value = (unsigned long)from->addr;
412 strncpy(isym.name, from->name, sizeof isym.name);
413 memcpy_tofs(to, &isym, sizeof isym);
414 }
415 }
416 }
417 }
418 }
419
420 return nmodsyms;
421 }
422
423
424 /*
425 * Copy the name of a module from user space.
426 */
427 int
428 get_mod_name(char *user_name, char *buf)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
429 {
430 int i;
431
432 i = 0;
433 for (i = 0 ; (buf[i] = get_user(user_name + i)) != '\0' ; ) {
434 if (++i >= MOD_MAX_NAME)
435 return -E2BIG;
436 }
437 return 0;
438 }
439
440
441 /*
442 * Look for a module by name, ignoring modules marked for deletion.
443 */
444 struct module *
445 find_module( const char *name)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
446 {
447 struct module *mp;
448
449 for (mp = module_list ; mp ; mp = mp->next) {
450 if (mp->state == MOD_DELETED)
451 continue;
452 if (!strcmp(mp->name, name))
453 break;
454 }
455 return mp;
456 }
457
458 static void
459 drop_refs(struct module *mp)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
460 {
461 struct module *step;
462 struct module_ref *prev;
463 struct module_ref *ref;
464
465 for (step = module_list; step; step = step->next) {
466 for (prev = ref = step->ref; ref; ref = prev->next) {
467 if (ref->module == mp) {
468 if (ref == step->ref)
469 step->ref = ref->next;
470 else
471 prev->next = ref->next;
472 break; /* every module only references once! */
473 }
474 else
475 prev = ref;
476 }
477 }
478 }
479
480 /*
481 * Try to free modules which have been marked for deletion. Returns nonzero
482 * if a module was actually freed.
483 */
484 int
485 free_modules( void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
486 {
487 struct module *mp;
488 struct module **mpp;
489 int did_deletion;
490
491 did_deletion = 0;
492 freeing_modules = 0;
493 mpp = &module_list;
494 while ((mp = *mpp) != NULL) {
495 if (mp->state != MOD_DELETED) {
496 mpp = &mp->next;
497 } else {
498 if (GET_USE_COUNT(mp) != 0) {
499 freeing_modules = 1;
500 mpp = &mp->next;
501 } else { /* delete it */
502 *mpp = mp->next;
503 if (mp->symtab) {
504 if (mp->symtab->n_refs)
505 drop_refs(mp);
506 if (mp->symtab->size)
507 kfree_s(mp->symtab, mp->symtab->size);
508 }
509 vfree(mp->addr);
510 kfree_s(mp, sizeof(struct module) + MOD_MAX_NAME);
511 did_deletion = 1;
512 }
513 }
514 }
515 return did_deletion;
516 }
517
518
519 /*
520 * Called by the /proc file system to return a current list of modules.
521 */
522 int get_module_list(char *buf)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
523 {
524 char *p;
525 const char *q;
526 int i;
527 struct module *mp;
528 struct module_ref *ref;
529 char size[32];
530
531 p = buf;
532 /* Do not show the kernel pseudo module */
533 for (mp = module_list ; mp && mp->next; mp = mp->next) {
534 if (p - buf > 4096 - 100)
535 break; /* avoid overflowing buffer */
536 q = mp->name;
537 if (*q == '\0' && mp->size == 0 && mp->ref == NULL)
538 continue; /* don't list modules for kernel syms */
539 i = 20;
540 while (*q) {
541 *p++ = *q++;
542 i--;
543 }
544 sprintf(size, "%d", mp->size);
545 i -= strlen(size);
546 if (i <= 0)
547 i = 1;
548 while (--i >= 0)
549 *p++ = ' ';
550 q = size;
551 while (*q)
552 *p++ = *q++;
553 if (mp->state == MOD_UNINITIALIZED)
554 q = " (uninitialized)";
555 else if (mp->state == MOD_RUNNING) {
556 sprintf(size,"\t%ld",GET_USE_COUNT(mp));
557 q=size;
558 }
559 else if (mp->state == MOD_DELETED)
560 q = " (deleted)";
561 else
562 q = " (bad state)";
563 while (*q)
564 *p++ = *q++;
565
566 if ((ref = mp->ref) != NULL) {
567 *p++ = '\t';
568 *p++ = '[';
569 for (; ref; ref = ref->next) {
570 q = ref->module->name;
571 while (*q)
572 *p++ = *q++;
573 if (ref->next)
574 *p++ = ' ';
575 }
576 *p++ = ']';
577 }
578 *p++ = '\n';
579 }
580 return p - buf;
581 }
582
583
584 /*
585 * Called by the /proc file system to return a current list of ksyms.
586 */
587 int get_ksyms_list(char *buf, char **start, off_t offset, int length)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
588 {
589 struct module *mp;
590 struct internal_symbol *sym;
591 int i;
592 char *p = buf;
593 int len = 0; /* code from net/ipv4/proc.c */
594 off_t pos = 0;
595 off_t begin = 0;
596
597 for (mp = module_list; mp; mp = mp->next) {
598 if ((mp->state == MOD_RUNNING) &&
599 (mp->symtab != NULL) &&
600 (mp->symtab->n_symbols > 0)) {
601 for (i = mp->symtab->n_symbols,
602 sym = mp->symtab->symbol;
603 i > 0; --i, ++sym) {
604
605 p = buf + len;
606 if (mp->name[0]) {
607 len += sprintf(p, "%08lx %s\t[%s]\n",
608 (long)sym->addr,
609 sym->name, mp->name);
610 } else {
611 len += sprintf(p, "%08lx %s\n",
612 (long)sym->addr,
613 sym->name);
614 }
615 pos = begin + len;
616 if (pos < offset) {
617 len = 0;
618 begin = pos;
619 }
620 pos = begin + len;
621 if (pos > offset+length)
622 goto leave_the_loop;
623 }
624 }
625 }
626 leave_the_loop:
627 *start = buf + (offset - begin);
628 len -= (offset - begin);
629 if (len > length)
630 len = length;
631 return len;
632 }
633
634 /*
635 * Rules:
636 * - The new symbol table should be statically allocated, or else you _have_
637 * to set the "size" field of the struct to the number of bytes allocated.
638 *
639 * - The strings that name the symbols will not be copied, maybe the pointers
640 *
641 * - For a loadable module, the function should only be called in the
642 * context of init_module
643 *
644 * Those are the only restrictions! (apart from not being reentrant...)
645 *
646 * If you want to remove a symbol table for a loadable module,
647 * the call looks like: "register_symtab(0)".
648 *
649 * The look of the code is mostly dictated by the format of
650 * the frozen struct symbol_table, due to compatibility demands.
651 */
652 #define INTSIZ sizeof(struct internal_symbol)
653 #define REFSIZ sizeof(struct module_ref)
654 #define SYMSIZ sizeof(struct symbol_table)
655 #define MODSIZ sizeof(struct module)
656 static struct symbol_table nulltab;
657
658 int
659 register_symtab(struct symbol_table *intab)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
660 {
661 struct module *mp;
662 struct module *link;
663 struct symbol_table *oldtab;
664 struct symbol_table *newtab;
665 struct module_ref *newref;
666 int size;
667
668 if (intab && (intab->n_symbols == 0)) {
669 struct internal_symbol *sym;
670 /* How many symbols, really? */
671
672 for (sym = intab->symbol; sym->name; ++sym)
673 intab->n_symbols +=1;
674 }
675
676 #if 1
677 if (module_init_flag == 0) { /* Hmm... */
678 #else
679 if (module_list == &kernel_module) {
680 #endif
681 /* Aha! Called from an "internal" module */
682 if (!intab)
683 return 0; /* or -ESILLY_PROGRAMMER :-) */
684
685 /* create a pseudo module! */
686 if (!(mp = (struct module*) kmalloc(MODSIZ, GFP_KERNEL))) {
687 /* panic time! */
688 printk("Out of memory for new symbol table!\n");
689 return -ENOMEM;
690 }
691 /* else OK */
692 memset(mp, 0, MODSIZ);
693 mp->state = MOD_RUNNING; /* Since it is resident... */
694 mp->name = ""; /* This is still the "kernel" symbol table! */
695 mp->symtab = intab;
696
697 /* link it in _after_ the resident symbol table */
698 mp->next = kernel_module.next;
699 kernel_module.next = mp;
700
701 return 0;
702 }
703
704 /* else ******** Called from a loadable module **********/
705
706 /*
707 * This call should _only_ be done in the context of the
708 * call to init_module i.e. when loading the module!!
709 * Or else...
710 */
711 mp = module_list; /* true when doing init_module! */
712
713 /* Any table there before? */
714 if ((oldtab = mp->symtab) == (struct symbol_table*)0) {
715 /* No, just insert it! */
716 mp->symtab = intab;
717 return 0;
718 }
719
720 /* else ****** we have to replace the module symbol table ******/
721 #if 0
722 if (oldtab->n_symbols > 0) {
723 /* Oh dear, I have to drop the old ones... */
724 printk("Warning, dropping old symbols\n");
725 }
726 #endif
727
728 if (oldtab->n_refs == 0) { /* no problems! */
729 mp->symtab = intab;
730 /* if the old table was kmalloc-ed, drop it */
731 if (oldtab->size > 0)
732 kfree_s(oldtab, oldtab->size);
733
734 return 0;
735 }
736
737 /* else */
738 /***** The module references other modules... insmod said so! *****/
739 /* We have to allocate a new symbol table, or we lose them! */
740 if (intab == (struct symbol_table*)0)
741 intab = &nulltab; /* easier code with zeroes in place */
742
743 /* the input symbol table space does not include the string table */
744 /* (it does for symbol tables that insmod creates) */
745
746 if (!(newtab = (struct symbol_table*)kmalloc(
747 size = SYMSIZ + intab->n_symbols * INTSIZ +
748 oldtab->n_refs * REFSIZ,
749 GFP_KERNEL))) {
750 /* panic time! */
751 printk("Out of memory for new symbol table!\n");
752 return -ENOMEM;
753 }
754
755 /* copy up to, and including, the new symbols */
756 memcpy(newtab, intab, SYMSIZ + intab->n_symbols * INTSIZ);
757
758 newtab->size = size;
759 newtab->n_refs = oldtab->n_refs;
760
761 /* copy references */
762 memcpy( ((char *)newtab) + SYMSIZ + intab->n_symbols * INTSIZ,
763 ((char *)oldtab) + SYMSIZ + oldtab->n_symbols * INTSIZ,
764 oldtab->n_refs * REFSIZ);
765
766 /* relink references from the old table to the new one */
767
768 /* pointer to the first reference entry in newtab! Really! */
769 newref = (struct module_ref*) &(newtab->symbol[newtab->n_symbols]);
770
771 /* check for reference links from previous modules */
772 for ( link = module_list;
773 link && (link != &kernel_module);
774 link = link->next) {
775
776 if (link->ref && (link->ref->module == mp))
777 link->ref = newref++;
778 }
779
780 mp->symtab = newtab;
781
782 /* all references (if any) have been handled */
783
784 /* if the old table was kmalloc-ed, drop it */
785 if (oldtab->size > 0)
786 kfree_s(oldtab, oldtab->size);
787
788 return 0;
789 }
790
791 #else /* CONFIG_MODULES */
792
793 /* Dummy syscalls for people who don't want modules */
794
795 asmlinkage unsigned long sys_create_module(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
796 {
797 return -ENOSYS;
798 }
799
800 asmlinkage int sys_init_module(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
801 {
802 return -ENOSYS;
803 }
804
805 asmlinkage int sys_delete_module(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
806 {
807 return -ENOSYS;
808 }
809
810 asmlinkage int sys_get_kernel_syms(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
811 {
812 return -ENOSYS;
813 }
814
815 int register_symtab(struct symbol_table *intab)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
816 {
817 return 0;
818 }
819
820 #endif /* CONFIG_MODULES */
821