home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / kernel / module.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-31  |  18.9 KB  |  762 lines

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