home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / a / bin / modules-.2 / modules- / modules-1.2.8 / depmod / depmod.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-31  |  5.5 KB  |  230 lines

  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include "tool.h"
  7. #include "link.h"
  8. #include "kernelsyms.h"
  9.  
  10.  
  11. /*
  12.     Add the symbol defined in the kernel, simulating a pseudo module
  13.     Return -1 if any error.
  14. */
  15. static int depmod_addksyms (
  16.     MODULES &mods,
  17.     SYMBOLS &syms)
  18. {
  19.     int ret = -1;
  20.     MODULE *mod = mods.setdummy ("-");
  21.     SYMBOL *tbsym[2000];
  22.     int nbsym=1;
  23.     // Fake the _mod_use_count_ symbol which is provided by insmod
  24.     int requis;        // Dummy
  25.     tbsym[0] = syms.add ("mod_use_count_",mod,SYM_DEFINI,requis,0);
  26. #if 0
  27.         char *cmd_strings = "strings /usr/src/linux/kernel/ksyms.o";
  28.         FILE *fin = popen_err (cmd_strings,"r",0);
  29.         if (fin != NULL){
  30.             char buf[300];
  31.             char lin[300];
  32.             while (fgets(lin,sizeof(lin)-1,fin)!= NULL
  33.                 && sscanf (lin,"%s\n",buf)==1){
  34.                 assert (nbsym < 2000);
  35.                 tbsym[nbsym++] = syms.add (buf,mod,SYM_DEFINI,requis,0);
  36.             }
  37.             pclose (fin);
  38.         }
  39. #else
  40. #if 1
  41.         struct kernel_sym *ksym;
  42.         int so_far = 0;
  43.  
  44.         load_kernel_symbols();
  45.         int kernel_syms = 0;
  46.         /* #Specification: depmod / kernel syms only
  47.             When initialising its symbol table from the kernel
  48.             depmod silently discards all symbol from loaded modules.
  49.  
  50.             This means that depmod may be used at any time to compute
  51.             the dependancy table, even if there are modules already
  52.             loaded.
  53.  
  54.             depmod use the kernel system call to obtain the
  55.             symbol table, not /proc/ksyms. depmod assume that
  56.             kernel symbols are at the end of the list, just
  57.             after a pseudo symbol with a one character name: #
  58.         */
  59.         int a_out_kernel = 0;
  60.         for (ksym = ksymtab; so_far < nksyms ; ++so_far, ksym++) {
  61.             if (kernel_syms){
  62.                 if (ksym->name[0] == '#')
  63.                     continue;
  64.                 assert (nbsym < 2000);
  65.                 // If a_out kernel, skip leading '_'
  66.                 tbsym[nbsym++] = syms.add (ksym->name + a_out_kernel,mod,SYM_DEFINI,requis,0);
  67.             }else if (strcmp(ksym->name,"#") == 0){
  68.                 kernel_syms = 1;
  69.                 // This works... I promise!
  70.                 if ((ksym + 1)->name[0] == '_')
  71.                     a_out_kernel = 1;
  72.             }
  73.         }
  74. #else
  75.         FILE *fin = fopen ("/proc/ksyms","r");
  76.         if (fin == NULL){
  77.             depmod_error ("Can't open /proc/ksyms");
  78.         }else{
  79.             char buf[300];
  80.             char lin[300];
  81.             char drop_me[300];
  82.             while (fgets(lin,sizeof(lin)-1,fin)!= NULL
  83.                 && sscanf (lin,"%s %s\n",drop_me,buf)==2){
  84.                 assert (nbsym < 2000);
  85.                 tbsym[nbsym++] = syms.add (buf,mod,SYM_DEFINI,requis,0);
  86.             }
  87.             fclose (fin);
  88.         }
  89. #endif
  90. #endif
  91.     int size = nbsym*sizeof(SYMBOL*);
  92.     mod->pub.tb = (SYMBOL**)malloc(size);
  93.     if (mod->pub.tb == NULL){
  94.         depmod_error ("Can't allocate memory for kernel symbols");
  95.     }else{
  96.         memcpy (mod->pub.tb,tbsym,size);
  97.         ret = 0;
  98.     }
  99.     return ret;
  100. }
  101. /*
  102.     Load the symbols from a module.
  103. */
  104. static int depmod_load (MODULES &mods, SYMBOLS &syms, const char *path)
  105. {
  106.     return mods.loadobj (syms,path);
  107. }
  108.  
  109. /*
  110.     Prints the dependancies in the output or stdout if depfile is NULL.
  111. */
  112. static void depmod_prtdepend(
  113.     MODULES &mods,
  114.     const char *depfile,
  115.     int verbose,
  116.     int showerror)
  117. {
  118.     FILE *out = stdout;
  119.     if (depfile != NULL){
  120.         out = fopen (depfile,"w");
  121.         if (out == NULL){
  122.             depmod_error ("Can't open %s",depfile);
  123.             exit (-1);
  124.         }
  125.     }                                
  126.     mods.prtdepend(out,"-",verbose,showerror);
  127.  
  128. }
  129.  
  130. int depmod_main (int argc, char *argv[])
  131. {
  132.     int ret = -1;
  133.     if (argc == 1){
  134.         fprintf (stderr,
  135.             "depmod " DEPMOD_RELEASE "\n"
  136.             "depmod [-d -e -v ] -a\n"
  137.             "depmod [-d -e -v ] module1.o module2.o ...\n"
  138.             "\n"
  139.             "depmod will output a dependancy list suitable for the\n"
  140.             "modprobe utility. This dependancy file look like\n"
  141.             "a Makefile\n"
  142.             "\n"
  143.             "It reads the kernel symbol table to find out which\n"
  144.             "symbols are already available in the running kernel.\n"
  145.             "\n"
  146.             "depmod -a will find the list of module to probe from\n"
  147.             "the file " ETC_CONF_MODULES ". It will output the result\n"
  148.             "into the depfile specified in this configuration file\n"
  149.             "(depfile=...)\n"
  150.             "\n"
  151.             "Normally depmod operate silently, reporting only the list\n"
  152.             "of module that won't load properly (missing symbols).\n"
  153.             "Option -e output all the unresolved symbol for a given module\n"
  154.             "Option -s output all error message to the syslog daemon\n"
  155.             "Option -v force a printout of all visited modules.\n"
  156.             );
  157.     }else{
  158.         MODULES mods;
  159.         SYMBOLS syms;
  160.         ret = depmod_addksyms(mods,syms);
  161.         if (ret != -1){
  162.             int opt;
  163.             int showerror = 0;
  164.             int verbose = 0;
  165.             int stdmode = 0;
  166.             int err = 0;
  167.             extern int optind;
  168.             while ((opt=getopt(argc,argv,"adesv"))!=-1){
  169.                 switch(opt){
  170.                 case 'a':
  171.                     stdmode = 1;    // Probe standard directory
  172.                                     // using the config file
  173.                     break;
  174.                 case 'd':
  175.                     debugmode = 1;
  176.                     break;
  177.                 case 'e':
  178.                     showerror = 1;
  179.                     break;
  180.                 case 's':
  181.                     depmod_setsyslog ("modprobe");
  182.                     break;
  183.                 case 'v':
  184.                     verbose = 1;
  185.                     break;
  186.                 case '?':
  187.                     err = 1;
  188.                     break;
  189.                 }
  190.             }
  191.             if (err){
  192.                 depmod_error ("Aborting");
  193.                 ret = -1;
  194.             }else if (stdmode){
  195.                 if (optind != argc){
  196.                     depmod_error ("No argument with option -a. Aborting");
  197.                     ret = -1;
  198.                 }else if (config_read() == -1){
  199.                     ret = -1;
  200.                 }else{
  201.                     char *lst[1000];
  202.                     int nb = config_lstmod ("*.{mod,o}",NULL,lst,1);
  203.                     for (int i=0; i<nb && ret != -1; i++){
  204.                         ret = depmod_load (mods,syms,lst[i]);
  205.                     }
  206.                     if (ret != -1){
  207.                         depmod_prtdepend (mods,config_getdepfile()
  208.                             ,verbose,showerror);
  209.                     }
  210.                 }                
  211.             }else{
  212.                 for (int i=optind; i<argc && ret != -1; i++){
  213.                     char *arg = argv[i];
  214.                     if (arg[0] == '-'){
  215.                         // Option processing, one day ...
  216.                     }else{
  217.                         ret = depmod_load (mods,syms,arg);
  218.                     }
  219.                 }
  220.                 if (ret != -1){
  221.                     depmod_prtdepend(mods,NULL,verbose,showerror);
  222.  
  223.                 }
  224.             }
  225.         }
  226.     }
  227.     return ret;            
  228. }
  229.  
  230.