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  * 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][next][first][last][top][bottom][index][help] */
  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][next][first][last][top][bottom][index][help] */
  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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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                 if (*q == '\0' && mp->size == 0 && mp->ref == NULL)
 533                         continue; /* don't list modules for kernel syms */
 534                 i = 20;
 535                 while (*q) {
 536                         *p++ = *q++;
 537                         i--;
 538                 }
 539                 sprintf(size, "%d", mp->size);
 540                 i -= strlen(size);
 541                 if (i <= 0)
 542                         i = 1;
 543                 while (--i >= 0)
 544                         *p++ = ' ';
 545                 q = size;
 546                 while (*q)
 547                         *p++ = *q++;
 548                 if (mp->state == MOD_UNINITIALIZED)
 549                         q = "  (uninitialized)";
 550                 else if (mp->state == MOD_RUNNING)
 551                         q = "";
 552                 else if (mp->state == MOD_DELETED)
 553                         q = "  (deleted)";
 554                 else
 555                         q = "  (bad state)";
 556                 while (*q)
 557                         *p++ = *q++;
 558 
 559                 if ((ref = mp->ref) != NULL) {
 560                         *p++ = '\t';
 561                         *p++ = '[';
 562                         for (; ref; ref = ref->next) {
 563                                 q = ref->module->name;
 564                                 while (*q)
 565                                         *p++ = *q++;
 566                                 if (ref->next)
 567                                         *p++ = ' ';
 568                         }
 569                         *p++ = ']';
 570                 }
 571                 *p++ = '\n';
 572         }
 573         return p - buf;
 574 }
 575 
 576 
 577 /*
 578  * Called by the /proc file system to return a current list of ksyms.
 579  */
 580 int get_ksyms_list(char *buf, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
 581 {
 582         struct module *mp;
 583         struct internal_symbol *sym;
 584         int i;
 585         char *p = buf;
 586         int len     = 0;        /* code from  net/ipv4/proc.c */
 587         off_t pos   = 0;
 588         off_t begin = 0;
 589 
 590         for (mp = module_list; mp; mp = mp->next) {
 591                 if ((mp->state == MOD_RUNNING) &&
 592                     (mp->symtab != NULL) &&
 593                     (mp->symtab->n_symbols > 0)) {
 594                         for (i = mp->symtab->n_symbols,
 595                                 sym = mp->symtab->symbol;
 596                                 i > 0; --i, ++sym) {
 597 
 598                                 p = buf + len;
 599                                 if (mp->name[0]) {
 600                                         len += sprintf(p, "%08lx %s\t[%s]\n",
 601                                                        (long)sym->addr,
 602                                                        sym->name, mp->name);
 603                                 } else {
 604                                         len += sprintf(p, "%08lx %s\n",
 605                                                        (long)sym->addr,
 606                                                        sym->name);
 607                                 }
 608                                 pos = begin + len;
 609                                 if (pos < offset) {
 610                                         len   = 0;
 611                                         begin = pos;
 612                                 }
 613                                 pos = begin + len;
 614                                 if (pos > offset+length)
 615                                         goto leave_the_loop;
 616                         }
 617                 }
 618         }
 619     leave_the_loop:
 620         *start = buf + (offset - begin);
 621         len -= (offset - begin);
 622         if (len > length)
 623                 len = length;
 624         return len;
 625 }
 626 
 627 /*
 628  * Rules:
 629  * - The new symbol table should be statically allocated, or else you _have_
 630  *   to set the "size" field of the struct to the number of bytes allocated.
 631  *
 632  * - The strings that name the symbols will not be copied, maybe the pointers
 633  *
 634  * - For a loadable module, the function should only be called in the
 635  *   context of init_module
 636  *
 637  * Those are the only restrictions! (apart from not being reentrant...)
 638  *
 639  * If you want to remove a symbol table for a loadable module,
 640  * the call looks like: "register_symtab(0)".
 641  *
 642  * The look of the code is mostly dictated by the format of
 643  * the frozen struct symbol_table, due to compatibility demands.
 644  */
 645 #define INTSIZ sizeof(struct internal_symbol)
 646 #define REFSIZ sizeof(struct module_ref)
 647 #define SYMSIZ sizeof(struct symbol_table)
 648 #define MODSIZ sizeof(struct module)
 649 static struct symbol_table nulltab;
 650 
 651 int
 652 register_symtab(struct symbol_table *intab)
     /* [previous][next][first][last][top][bottom][index][help] */
 653 {
 654         struct module *mp;
 655         struct module *link;
 656         struct symbol_table *oldtab;
 657         struct symbol_table *newtab;
 658         struct module_ref *newref;
 659         int size;
 660 
 661         if (intab && (intab->n_symbols == 0)) {
 662                 struct internal_symbol *sym;
 663                 /* How many symbols, really? */
 664 
 665                 for (sym = intab->symbol; sym->name; ++sym)
 666                         intab->n_symbols +=1;
 667         }
 668 
 669 #if 1
 670         if (module_init_flag == 0) { /* Hmm... */
 671 #else
 672         if (module_list == &kernel_module) {
 673 #endif
 674                 /* Aha! Called from an "internal" module */
 675                 if (!intab)
 676                         return 0; /* or -ESILLY_PROGRAMMER :-) */
 677 
 678                 /* create a pseudo module! */
 679                 if (!(mp = (struct module*) kmalloc(MODSIZ, GFP_KERNEL))) {
 680                         /* panic time! */
 681                         printk("Out of memory for new symbol table!\n");
 682                         return -ENOMEM;
 683                 }
 684                 /* else  OK */
 685                 memset(mp, 0, MODSIZ);
 686                 mp->state = MOD_RUNNING; /* Since it is resident... */
 687                 mp->name = ""; /* This is still the "kernel" symbol table! */
 688                 mp->symtab = intab;
 689 
 690                 /* link it in _after_ the resident symbol table */
 691                 mp->next = kernel_module.next;
 692                 kernel_module.next = mp;
 693 
 694                 return 0;
 695         }
 696 
 697         /* else ******** Called from a loadable module **********/
 698 
 699         /*
 700          * This call should _only_ be done in the context of the
 701          * call to  init_module  i.e. when loading the module!!
 702          * Or else...
 703          */
 704         mp = module_list; /* true when doing init_module! */
 705 
 706         /* Any table there before? */
 707         if ((oldtab = mp->symtab) == (struct symbol_table*)0) {
 708                 /* No, just insert it! */
 709                 mp->symtab = intab;
 710                 return 0;
 711         }
 712 
 713         /* else  ****** we have to replace the module symbol table ******/
 714 #if 0
 715         if (oldtab->n_symbols > 0) {
 716                 /* Oh dear, I have to drop the old ones... */
 717                 printk("Warning, dropping old symbols\n");
 718         }
 719 #endif
 720 
 721         if (oldtab->n_refs == 0) { /* no problems! */
 722                 mp->symtab = intab;
 723                 /* if the old table was kmalloc-ed, drop it */
 724                 if (oldtab->size > 0)
 725                         kfree_s(oldtab, oldtab->size);
 726 
 727                 return 0;
 728         }
 729 
 730         /* else */
 731         /***** The module references other modules... insmod said so! *****/
 732         /* We have to allocate a new symbol table, or we lose them! */
 733         if (intab == (struct symbol_table*)0)
 734                 intab = &nulltab; /* easier code with zeroes in place */
 735 
 736         /* the input symbol table space does not include the string table */
 737         /* (it does for symbol tables that insmod creates) */
 738 
 739         if (!(newtab = (struct symbol_table*)kmalloc(
 740                 size = SYMSIZ + intab->n_symbols * INTSIZ +
 741                         oldtab->n_refs * REFSIZ,
 742                 GFP_KERNEL))) {
 743                 /* panic time! */
 744                 printk("Out of memory for new symbol table!\n");
 745                 return -ENOMEM;
 746         }
 747 
 748         /* copy up to, and including, the new symbols */
 749         memcpy(newtab, intab, SYMSIZ + intab->n_symbols * INTSIZ);
 750 
 751         newtab->size = size;
 752         newtab->n_refs = oldtab->n_refs;
 753 
 754         /* copy references */
 755         memcpy( ((char *)newtab) + SYMSIZ + intab->n_symbols * INTSIZ,
 756                 ((char *)oldtab) + SYMSIZ + oldtab->n_symbols * INTSIZ,
 757                 oldtab->n_refs * REFSIZ);
 758 
 759         /* relink references from the old table to the new one */
 760 
 761         /* pointer to the first reference entry in newtab! Really! */
 762         newref = (struct module_ref*) &(newtab->symbol[newtab->n_symbols]);
 763 
 764         /* check for reference links from previous modules */
 765         for (   link = module_list;
 766                 link && (link != &kernel_module);
 767                 link = link->next) {
 768 
 769                 if (link->ref && (link->ref->module == mp))
 770                         link->ref = newref++;
 771         }
 772 
 773         mp->symtab = newtab;
 774 
 775         /* all references (if any) have been handled */
 776 
 777         /* if the old table was kmalloc-ed, drop it */
 778         if (oldtab->size > 0)
 779                 kfree_s(oldtab, oldtab->size);
 780 
 781         return 0;
 782 }

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