root/kernel/module.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. init_modules
  2. rename_module_symbol
  3. sys_create_module
  4. sys_init_module
  5. sys_delete_module
  6. sys_get_kernel_syms
  7. get_mod_name
  8. find_module
  9. drop_refs
  10. free_modules
  11. get_module_list
  12. get_ksyms_list
  13. register_symtab

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

/* [previous][next][first][last][top][bottom][index][help] */