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
  14. sys_create_module
  15. sys_init_module
  16. sys_delete_module
  17. sys_get_kernel_syms
  18. 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 #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][next][first][last][top][bottom][index][help] */
  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][next][first][last][top][bottom][index][help] */
  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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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 & MOD_AUTOCLEAN) {
 232                 /*
 233                  * set autoclean marker from codesize...
 234                  * set useage count to "zero"
 235                  */
 236                 codesize &= ~MOD_AUTOCLEAN;
 237                 GET_USE_COUNT(mp) = MOD_AUTOCLEAN;
 238         }
 239         if ((codesize + sizeof (long) + PAGE_SIZE - 1) / PAGE_SIZE > mp->size)
 240                 return -EINVAL;
 241         memcpy_fromfs((char *)mp->addr + sizeof (long), code, codesize);
 242         memset((char *)mp->addr + sizeof (long) + codesize, 0,
 243                 mp->size * PAGE_SIZE - (codesize + sizeof (long)));
 244         PRINTK(( "module init entry = 0x%08lx, cleanup entry = 0x%08lx\n",
 245                 (unsigned long) rt.init, (unsigned long) rt.cleanup));
 246         mp->cleanup = rt.cleanup;
 247 
 248         /* update kernel symbol table */
 249         if (symtab) { /* symtab == NULL means no new entries to handle */
 250                 struct internal_symbol *sym;
 251                 struct module_ref *ref;
 252                 int size;
 253                 int i;
 254                 int legal_start;
 255 
 256                 if ((error = verify_area(VERIFY_READ, &symtab->size, sizeof(symtab->size))))
 257                         return error;
 258                 size = get_user(&symtab->size);
 259 
 260                 if ((newtab = (struct symbol_table*) kmalloc(size, GFP_KERNEL)) == NULL) {
 261                         return -ENOMEM;
 262                 }
 263 
 264                 if ((error = verify_area(VERIFY_READ, symtab, size))) {
 265                         kfree_s(newtab, size);
 266                         return error;
 267                 }
 268                 memcpy_fromfs((char *)(newtab), symtab, size);
 269 
 270                 /* sanity check */
 271                 legal_start = sizeof(struct symbol_table) +
 272                         newtab->n_symbols * sizeof(struct internal_symbol) +
 273                         newtab->n_refs * sizeof(struct module_ref);
 274 
 275                 if ((newtab->n_symbols < 0) || (newtab->n_refs < 0) || (legal_start > size)) {
 276                         printk("Rejecting illegal symbol table (n_symbols=%d,n_refs=%d)\n",
 277                                newtab->n_symbols, newtab->n_refs);
 278                         kfree_s(newtab, size);
 279                         return -EINVAL;
 280                 }
 281 
 282                 /* relocate name pointers, index referred from start of table */
 283                 for (sym = &(newtab->symbol[0]), i = 0; i < newtab->n_symbols; ++sym, ++i) {
 284                         if ((unsigned long)sym->name < legal_start || size <= (unsigned long)sym->name) {
 285                                 printk("Rejecting illegal symbol table\n");
 286                                 kfree_s(newtab, size);
 287                                 return -EINVAL;
 288                         }
 289                         /* else */
 290                         sym->name += (long)newtab;
 291                 }
 292                 mp->symtab = newtab;
 293 
 294                 /* Update module references.
 295                  * On entry, from "insmod", ref->module points to
 296                  * the referenced module!
 297                  * Now it will point to the current module instead!
 298                  * The ref structure becomes the first link in the linked
 299                  * list of references to the referenced module.
 300                  * Also, "sym" from above, points to the first ref entry!!!
 301                  */
 302                 for (ref = (struct module_ref *)sym, i = 0;
 303                         i < newtab->n_refs; ++ref, ++i) {
 304 
 305                         /* Check for valid reference */
 306                         struct module *link = module_list;
 307                         while (link && (ref->module != link))
 308                                 link = link->next;
 309 
 310                         if (link == (struct module *)0) {
 311                                 printk("Non-module reference! Rejected!\n");
 312                                 return -EINVAL;
 313                         }
 314 
 315                         ref->next = ref->module->ref;
 316                         ref->module->ref = ref;
 317                         ref->module = mp;
 318                 }
 319         }
 320 
 321         module_init_flag = 1; /* Hmm... */
 322         if ((*rt.init)() != 0) {
 323                 module_init_flag = 0; /* Hmm... */
 324                 return -EBUSY;
 325         }
 326         module_init_flag = 0; /* Hmm... */
 327         mp->state = MOD_RUNNING;
 328 
 329         return 0;
 330 }
 331 
 332 asmlinkage int
 333 sys_delete_module(char *module_name)
     /* [previous][next][first][last][top][bottom][index][help] */
 334 {
 335         struct module *mp;
 336         char name[MOD_MAX_NAME];
 337         int error;
 338 
 339         if (!suser())
 340                 return -EPERM;
 341         /* else */
 342         if (module_name != NULL) {
 343                 if ((error = get_mod_name(module_name, name)) != 0)
 344                         return error;
 345                 if ((mp = find_module(name)) == NULL)
 346                         return -ENOENT;
 347                 if ((mp->ref != NULL) || ((GET_USE_COUNT(mp) & ~MOD_AUTOCLEAN) != 0))
 348                         return -EBUSY;
 349                 GET_USE_COUNT(mp) &= ~MOD_AUTOCLEAN;
 350                 if (mp->state == MOD_RUNNING)
 351                         (*mp->cleanup)();
 352                 mp->state = MOD_DELETED;
 353                 free_modules();
 354         }
 355         /* for automatic reaping */
 356         else {
 357                 for (mp = module_list; mp != &kernel_module; mp = mp->next) {
 358                         if ((mp->ref == NULL) && (GET_USE_COUNT(mp) == MOD_AUTOCLEAN) &&
 359                             (mp->state == MOD_RUNNING)) {
 360                                 GET_USE_COUNT(mp) &= ~MOD_AUTOCLEAN;
 361                                 (*mp->cleanup)();
 362                                 mp->state = MOD_DELETED;
 363                                 free_modules();
 364                         }
 365                 }
 366         }
 367         return 0;
 368 }
 369 
 370 
 371 /*
 372  * Copy the kernel symbol table to user space.  If the argument is null,
 373  * just return the size of the table.
 374  *
 375  * Note that the transient module symbols are copied _first_,
 376  * in lifo order!!!
 377  *
 378  * The symbols to "insmod" are according to the "old" format: struct kernel_sym,
 379  * which is actually quite handy for this purpose.
 380  * Note that insmod inserts a struct symbol_table later on...
 381  * (as that format is quite handy for the kernel...)
 382  *
 383  * For every module, the first (pseudo)symbol copied is the module name
 384  * and the address of the module struct.
 385  * This lets "insmod" keep track of references, and build the array of
 386  * struct module_refs in the symbol table.
 387  * The format of the module name is "#module", so that "insmod" can easily
 388  * notice when a module name comes along. Also, this will make it possible
 389  * to use old versions of "insmod", albeit with reduced functionality...
 390  * The "kernel" module has an empty name.
 391  */
 392 asmlinkage int
 393 sys_get_kernel_syms(struct kernel_sym *table)
     /* [previous][next][first][last][top][bottom][index][help] */
 394 {
 395         struct internal_symbol *from;
 396         struct kernel_sym isym;
 397         struct kernel_sym *to;
 398         struct module *mp = module_list;
 399         int i;
 400         int nmodsyms = 0;
 401 
 402         for (mp = module_list; mp; mp = mp->next) {
 403                 if (mp->symtab && mp->symtab->n_symbols) {
 404                         /* include the count for the module name! */
 405                         nmodsyms += mp->symtab->n_symbols + 1;
 406                 }
 407                 else
 408                         /* include the count for the module name! */
 409                         nmodsyms += 1; /* return modules without symbols too */
 410         }
 411 
 412         if (table != NULL) {
 413                 to = table;
 414 
 415                 if ((i = verify_area(VERIFY_WRITE, to, nmodsyms * sizeof(*table))))
 416                         return i;
 417 
 418                 /* copy all module symbols first (always LIFO order) */
 419                 for (mp = module_list; mp; mp = mp->next) {
 420                         if (mp->state == MOD_RUNNING) {
 421                                 /* magic: write module info as a pseudo symbol */
 422                                 isym.value = (unsigned long)mp;
 423                                 sprintf(isym.name, "#%s", mp->name);
 424                                 memcpy_tofs(to, &isym, sizeof isym);
 425                                 ++to;
 426 
 427                                 if (mp->symtab != NULL) {
 428                                         for (i = mp->symtab->n_symbols,
 429                                                 from = mp->symtab->symbol;
 430                                                 i > 0; --i, ++from, ++to) {
 431 
 432                                                 isym.value = (unsigned long)from->addr;
 433                                                 strncpy(isym.name, from->name, sizeof isym.name);
 434                                                 memcpy_tofs(to, &isym, sizeof isym);
 435                                         }
 436                                 }
 437                         }
 438                 }
 439         }
 440 
 441         return nmodsyms;
 442 }
 443 
 444 
 445 /*
 446  * Copy the name of a module from user space.
 447  */
 448 int
 449 get_mod_name(char *user_name, char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 450 {
 451         int i;
 452 
 453         i = 0;
 454         for (i = 0 ; (buf[i] = get_user(user_name + i)) != '\0' ; ) {
 455                 if (++i >= MOD_MAX_NAME)
 456                         return -E2BIG;
 457         }
 458         return 0;
 459 }
 460 
 461 
 462 /*
 463  * Look for a module by name, ignoring modules marked for deletion.
 464  */
 465 struct module *
 466 find_module( const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 467 {
 468         struct module *mp;
 469 
 470         for (mp = module_list ; mp ; mp = mp->next) {
 471                 if (mp->state == MOD_DELETED)
 472                         continue;
 473                 if (!strcmp(mp->name, name))
 474                         break;
 475         }
 476         return mp;
 477 }
 478 
 479 static void
 480 drop_refs(struct module *mp)
     /* [previous][next][first][last][top][bottom][index][help] */
 481 {
 482         struct module *step;
 483         struct module_ref *prev;
 484         struct module_ref *ref;
 485 
 486         for (step = module_list; step; step = step->next) {
 487                 for (prev = ref = step->ref; ref; ref = prev->next) {
 488                         if (ref->module == mp) {
 489                                 if (ref == step->ref)
 490                                         step->ref = ref->next;
 491                                 else
 492                                         prev->next = ref->next;
 493                                 break; /* every module only references once! */
 494                         }
 495                         else
 496                                 prev = ref;
 497                 }
 498         }
 499 }
 500 
 501 /*
 502  * Try to free modules which have been marked for deletion.  Returns nonzero
 503  * if a module was actually freed.
 504  */
 505 int
 506 free_modules( void)
     /* [previous][next][first][last][top][bottom][index][help] */
 507 {
 508         struct module *mp;
 509         struct module **mpp;
 510         int did_deletion;
 511 
 512         did_deletion = 0;
 513         freeing_modules = 0;
 514         mpp = &module_list;
 515         while ((mp = *mpp) != NULL) {
 516                 if (mp->state != MOD_DELETED) {
 517                         mpp = &mp->next;
 518                 } else {
 519                         if ((GET_USE_COUNT(mp) != 0) || (mp->ref != NULL)) {
 520                                 freeing_modules = 1;
 521                                 mpp = &mp->next;
 522                         } else {        /* delete it */
 523                                 *mpp = mp->next;
 524                                 if (mp->symtab) {
 525                                         if (mp->symtab->n_refs)
 526                                                 drop_refs(mp);
 527                                         if (mp->symtab->size)
 528                                                 kfree_s(mp->symtab, mp->symtab->size);
 529                                 }
 530                                 vfree(mp->addr);
 531                                 kfree_s(mp, sizeof(struct module) + MOD_MAX_NAME);
 532                                 did_deletion = 1;
 533                         }
 534                 }
 535         }
 536         return did_deletion;
 537 }
 538 
 539 
 540 /*
 541  * Called by the /proc file system to return a current list of modules.
 542  */
 543 int get_module_list(char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 544 {
 545         char *p;
 546         const char *q;
 547         int i;
 548         struct module *mp;
 549         struct module_ref *ref;
 550         char size[32];
 551 
 552         p = buf;
 553         /* Do not show the kernel pseudo module */
 554         for (mp = module_list ; mp && mp->next; mp = mp->next) {
 555                 if (p - buf > 4096 - 100)
 556                         break;                  /* avoid overflowing buffer */
 557                 q = mp->name;
 558                 if (*q == '\0' && mp->size == 0 && mp->ref == NULL)
 559                         continue; /* don't list modules for kernel syms */
 560                 i = 20;
 561                 while (*q) {
 562                         *p++ = *q++;
 563                         i--;
 564                 }
 565                 sprintf(size, "%d", mp->size);
 566                 i -= strlen(size);
 567                 if (i <= 0)
 568                         i = 1;
 569                 while (--i >= 0)
 570                         *p++ = ' ';
 571                 q = size;
 572                 while (*q)
 573                         *p++ = *q++;
 574                 if (mp->state == MOD_UNINITIALIZED)
 575                         q = "  (uninitialized)";
 576                 else if (mp->state == MOD_RUNNING)
 577                         q = "";
 578                 else if (mp->state == MOD_DELETED)
 579                         q = "  (deleted)";
 580                 else
 581                         q = "  (bad state)";
 582                 while (*q)
 583                         *p++ = *q++;
 584 
 585                 if ((ref = mp->ref) != NULL) {
 586                         *p++ = '\t';
 587                         *p++ = '[';
 588                         for (; ref; ref = ref->next) {
 589                                 q = ref->module->name;
 590                                 while (*q)
 591                                         *p++ = *q++;
 592                                 if (ref->next)
 593                                         *p++ = ' ';
 594                         }
 595                         *p++ = ']';
 596                 }
 597                 if (mp->state == MOD_RUNNING) {
 598                         sprintf(size,"\t%ld%s",
 599                                 GET_USE_COUNT(mp) & ~MOD_AUTOCLEAN,
 600                                 ((GET_USE_COUNT(mp) & MOD_AUTOCLEAN)?
 601                                         " (autoclean)":""));
 602                         q = size;
 603                         while (*q)
 604                                 *p++ = *q++;
 605                 }
 606                 *p++ = '\n';
 607         }
 608         return p - buf;
 609 }
 610 
 611 
 612 /*
 613  * Called by the /proc file system to return a current list of ksyms.
 614  */
 615 int get_ksyms_list(char *buf, char **start, off_t offset, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
 616 {
 617         struct module *mp;
 618         struct internal_symbol *sym;
 619         int i;
 620         char *p = buf;
 621         int len     = 0;        /* code from  net/ipv4/proc.c */
 622         off_t pos   = 0;
 623         off_t begin = 0;
 624 
 625         for (mp = module_list; mp; mp = mp->next) {
 626                 if ((mp->state == MOD_RUNNING) &&
 627                     (mp->symtab != NULL) &&
 628                     (mp->symtab->n_symbols > 0)) {
 629                         for (i = mp->symtab->n_symbols,
 630                                 sym = mp->symtab->symbol;
 631                                 i > 0; --i, ++sym) {
 632 
 633                                 p = buf + len;
 634                                 if (mp->name[0]) {
 635                                         len += sprintf(p, "%08lx %s\t[%s]\n",
 636                                                        (long)sym->addr,
 637                                                        sym->name, mp->name);
 638                                 } else {
 639                                         len += sprintf(p, "%08lx %s\n",
 640                                                        (long)sym->addr,
 641                                                        sym->name);
 642                                 }
 643                                 pos = begin + len;
 644                                 if (pos < offset) {
 645                                         len   = 0;
 646                                         begin = pos;
 647                                 }
 648                                 pos = begin + len;
 649                                 if (pos > offset+length)
 650                                         goto leave_the_loop;
 651                         }
 652                 }
 653         }
 654     leave_the_loop:
 655         *start = buf + (offset - begin);
 656         len -= (offset - begin);
 657         if (len > length)
 658                 len = length;
 659         return len;
 660 }
 661 
 662 /*
 663  * Rules:
 664  * - The new symbol table should be statically allocated, or else you _have_
 665  *   to set the "size" field of the struct to the number of bytes allocated.
 666  *
 667  * - The strings that name the symbols will not be copied, maybe the pointers
 668  *
 669  * - For a loadable module, the function should only be called in the
 670  *   context of init_module
 671  *
 672  * Those are the only restrictions! (apart from not being reentrant...)
 673  *
 674  * If you want to remove a symbol table for a loadable module,
 675  * the call looks like: "register_symtab(0)".
 676  *
 677  * The look of the code is mostly dictated by the format of
 678  * the frozen struct symbol_table, due to compatibility demands.
 679  */
 680 #define INTSIZ sizeof(struct internal_symbol)
 681 #define REFSIZ sizeof(struct module_ref)
 682 #define SYMSIZ sizeof(struct symbol_table)
 683 #define MODSIZ sizeof(struct module)
 684 static struct symbol_table nulltab;
 685 
 686 int
 687 register_symtab(struct symbol_table *intab)
     /* [previous][next][first][last][top][bottom][index][help] */
 688 {
 689         struct module *mp;
 690         struct module *link;
 691         struct symbol_table *oldtab;
 692         struct symbol_table *newtab;
 693         struct module_ref *newref;
 694         int size;
 695 
 696         if (intab && (intab->n_symbols == 0)) {
 697                 struct internal_symbol *sym;
 698                 /* How many symbols, really? */
 699 
 700                 for (sym = intab->symbol; sym->name; ++sym)
 701                         intab->n_symbols +=1;
 702         }
 703 
 704 #if 1
 705         if (module_init_flag == 0) { /* Hmm... */
 706 #else
 707         if (module_list == &kernel_module) {
 708 #endif
 709                 /* Aha! Called from an "internal" module */
 710                 if (!intab)
 711                         return 0; /* or -ESILLY_PROGRAMMER :-) */
 712 
 713                 /* create a pseudo module! */
 714                 if (!(mp = (struct module*) kmalloc(MODSIZ, GFP_KERNEL))) {
 715                         /* panic time! */
 716                         printk("Out of memory for new symbol table!\n");
 717                         return -ENOMEM;
 718                 }
 719                 /* else  OK */
 720                 memset(mp, 0, MODSIZ);
 721                 mp->state = MOD_RUNNING; /* Since it is resident... */
 722                 mp->name = ""; /* This is still the "kernel" symbol table! */
 723                 mp->symtab = intab;
 724 
 725                 /* link it in _after_ the resident symbol table */
 726                 mp->next = kernel_module.next;
 727                 kernel_module.next = mp;
 728 
 729                 return 0;
 730         }
 731 
 732         /* else ******** Called from a loadable module **********/
 733 
 734         /*
 735          * This call should _only_ be done in the context of the
 736          * call to  init_module  i.e. when loading the module!!
 737          * Or else...
 738          */
 739         mp = module_list; /* true when doing init_module! */
 740 
 741         /* Any table there before? */
 742         if ((oldtab = mp->symtab) == (struct symbol_table*)0) {
 743                 /* No, just insert it! */
 744                 mp->symtab = intab;
 745                 return 0;
 746         }
 747 
 748         /* else  ****** we have to replace the module symbol table ******/
 749 #if 0
 750         if (oldtab->n_symbols > 0) {
 751                 /* Oh dear, I have to drop the old ones... */
 752                 printk("Warning, dropping old symbols\n");
 753         }
 754 #endif
 755 
 756         if (oldtab->n_refs == 0) { /* no problems! */
 757                 mp->symtab = intab;
 758                 /* if the old table was kmalloc-ed, drop it */
 759                 if (oldtab->size > 0)
 760                         kfree_s(oldtab, oldtab->size);
 761 
 762                 return 0;
 763         }
 764 
 765         /* else */
 766         /***** The module references other modules... insmod said so! *****/
 767         /* We have to allocate a new symbol table, or we lose them! */
 768         if (intab == (struct symbol_table*)0)
 769                 intab = &nulltab; /* easier code with zeroes in place */
 770 
 771         /* the input symbol table space does not include the string table */
 772         /* (it does for symbol tables that insmod creates) */
 773 
 774         if (!(newtab = (struct symbol_table*)kmalloc(
 775                 size = SYMSIZ + intab->n_symbols * INTSIZ +
 776                         oldtab->n_refs * REFSIZ,
 777                 GFP_KERNEL))) {
 778                 /* panic time! */
 779                 printk("Out of memory for new symbol table!\n");
 780                 return -ENOMEM;
 781         }
 782 
 783         /* copy up to, and including, the new symbols */
 784         memcpy(newtab, intab, SYMSIZ + intab->n_symbols * INTSIZ);
 785 
 786         newtab->size = size;
 787         newtab->n_refs = oldtab->n_refs;
 788 
 789         /* copy references */
 790         memcpy( ((char *)newtab) + SYMSIZ + intab->n_symbols * INTSIZ,
 791                 ((char *)oldtab) + SYMSIZ + oldtab->n_symbols * INTSIZ,
 792                 oldtab->n_refs * REFSIZ);
 793 
 794         /* relink references from the old table to the new one */
 795 
 796         /* pointer to the first reference entry in newtab! Really! */
 797         newref = (struct module_ref*) &(newtab->symbol[newtab->n_symbols]);
 798 
 799         /* check for reference links from previous modules */
 800         for (   link = module_list;
 801                 link && (link != &kernel_module);
 802                 link = link->next) {
 803 
 804                 if (link->ref && (link->ref->module == mp))
 805                         link->ref = newref++;
 806         }
 807 
 808         mp->symtab = newtab;
 809 
 810         /* all references (if any) have been handled */
 811 
 812         /* if the old table was kmalloc-ed, drop it */
 813         if (oldtab->size > 0)
 814                 kfree_s(oldtab, oldtab->size);
 815 
 816         return 0;
 817 }
 818 
 819 #else           /* CONFIG_MODULES */
 820 
 821 /* Dummy syscalls for people who don't want modules */
 822 
 823 asmlinkage unsigned long sys_create_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 824 {
 825         return -ENOSYS;
 826 }
 827 
 828 asmlinkage int sys_init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 829 {
 830         return -ENOSYS;
 831 }
 832 
 833 asmlinkage int sys_delete_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 834 {
 835         return -ENOSYS;
 836 }
 837 
 838 asmlinkage int sys_get_kernel_syms(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 839 {
 840         return -ENOSYS;
 841 }
 842 
 843 int register_symtab(struct symbol_table *intab)
     /* [previous][next][first][last][top][bottom][index][help] */
 844 {
 845         return 0;
 846 }
 847 
 848 #endif  /* CONFIG_MODULES */
 849 

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