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