home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <assert.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include "tool.h"
- #include "link.h"
- #include "kernelsyms.h"
-
-
- /*
- Add the symbol defined in the kernel, simulating a pseudo module
- Return -1 if any error.
- */
- static int depmod_addksyms (
- MODULES &mods,
- SYMBOLS &syms)
- {
- int ret = -1;
- MODULE *mod = mods.setdummy ("-");
- SYMBOL *tbsym[2000];
- int nbsym=1;
- // Fake the _mod_use_count_ symbol which is provided by insmod
- int requis; // Dummy
- tbsym[0] = syms.add ("mod_use_count_",mod,SYM_DEFINI,requis,0);
- #if 0
- char *cmd_strings = "strings /usr/src/linux/kernel/ksyms.o";
- FILE *fin = popen_err (cmd_strings,"r",0);
- if (fin != NULL){
- char buf[300];
- char lin[300];
- while (fgets(lin,sizeof(lin)-1,fin)!= NULL
- && sscanf (lin,"%s\n",buf)==1){
- assert (nbsym < 2000);
- tbsym[nbsym++] = syms.add (buf,mod,SYM_DEFINI,requis,0);
- }
- pclose (fin);
- }
- #else
- #if 1
- struct kernel_sym *ksym;
- int so_far = 0;
-
- load_kernel_symbols();
- int kernel_syms = 0;
- /* #Specification: depmod / kernel syms only
- When initialising its symbol table from the kernel
- depmod silently discards all symbol from loaded modules.
-
- This means that depmod may be used at any time to compute
- the dependancy table, even if there are modules already
- loaded.
-
- depmod use the kernel system call to obtain the
- symbol table, not /proc/ksyms. depmod assume that
- kernel symbols are at the end of the list, just
- after a pseudo symbol with a one character name: #
- */
- int a_out_kernel = 0;
- for (ksym = ksymtab; so_far < nksyms ; ++so_far, ksym++) {
- if (kernel_syms){
- if (ksym->name[0] == '#')
- continue;
- assert (nbsym < 2000);
- // If a_out kernel, skip leading '_'
- tbsym[nbsym++] = syms.add (ksym->name + a_out_kernel,mod,SYM_DEFINI,requis,0);
- }else if (strcmp(ksym->name,"#") == 0){
- kernel_syms = 1;
- // This works... I promise!
- if ((ksym + 1)->name[0] == '_')
- a_out_kernel = 1;
- }
- }
- #else
- FILE *fin = fopen ("/proc/ksyms","r");
- if (fin == NULL){
- depmod_error ("Can't open /proc/ksyms");
- }else{
- char buf[300];
- char lin[300];
- char drop_me[300];
- while (fgets(lin,sizeof(lin)-1,fin)!= NULL
- && sscanf (lin,"%s %s\n",drop_me,buf)==2){
- assert (nbsym < 2000);
- tbsym[nbsym++] = syms.add (buf,mod,SYM_DEFINI,requis,0);
- }
- fclose (fin);
- }
- #endif
- #endif
- int size = nbsym*sizeof(SYMBOL*);
- mod->pub.tb = (SYMBOL**)malloc(size);
- if (mod->pub.tb == NULL){
- depmod_error ("Can't allocate memory for kernel symbols");
- }else{
- memcpy (mod->pub.tb,tbsym,size);
- ret = 0;
- }
- return ret;
- }
- /*
- Load the symbols from a module.
- */
- static int depmod_load (MODULES &mods, SYMBOLS &syms, const char *path)
- {
- return mods.loadobj (syms,path);
- }
-
- /*
- Prints the dependancies in the output or stdout if depfile is NULL.
- */
- static void depmod_prtdepend(
- MODULES &mods,
- const char *depfile,
- int verbose,
- int showerror)
- {
- FILE *out = stdout;
- if (depfile != NULL){
- out = fopen (depfile,"w");
- if (out == NULL){
- depmod_error ("Can't open %s",depfile);
- exit (-1);
- }
- }
- mods.prtdepend(out,"-",verbose,showerror);
-
- }
-
- int depmod_main (int argc, char *argv[])
- {
- int ret = -1;
- if (argc == 1){
- fprintf (stderr,
- "depmod " DEPMOD_RELEASE "\n"
- "depmod [-d -e -v ] -a\n"
- "depmod [-d -e -v ] module1.o module2.o ...\n"
- "\n"
- "depmod will output a dependancy list suitable for the\n"
- "modprobe utility. This dependancy file look like\n"
- "a Makefile\n"
- "\n"
- "It reads the kernel symbol table to find out which\n"
- "symbols are already available in the running kernel.\n"
- "\n"
- "depmod -a will find the list of module to probe from\n"
- "the file " ETC_CONF_MODULES ". It will output the result\n"
- "into the depfile specified in this configuration file\n"
- "(depfile=...)\n"
- "\n"
- "Normally depmod operate silently, reporting only the list\n"
- "of module that won't load properly (missing symbols).\n"
- "Option -e output all the unresolved symbol for a given module\n"
- "Option -s output all error message to the syslog daemon\n"
- "Option -v force a printout of all visited modules.\n"
- );
- }else{
- MODULES mods;
- SYMBOLS syms;
- ret = depmod_addksyms(mods,syms);
- if (ret != -1){
- int opt;
- int showerror = 0;
- int verbose = 0;
- int stdmode = 0;
- int err = 0;
- extern int optind;
- while ((opt=getopt(argc,argv,"adesv"))!=-1){
- switch(opt){
- case 'a':
- stdmode = 1; // Probe standard directory
- // using the config file
- break;
- case 'd':
- debugmode = 1;
- break;
- case 'e':
- showerror = 1;
- break;
- case 's':
- depmod_setsyslog ("modprobe");
- break;
- case 'v':
- verbose = 1;
- break;
- case '?':
- err = 1;
- break;
- }
- }
- if (err){
- depmod_error ("Aborting");
- ret = -1;
- }else if (stdmode){
- if (optind != argc){
- depmod_error ("No argument with option -a. Aborting");
- ret = -1;
- }else if (config_read() == -1){
- ret = -1;
- }else{
- char *lst[1000];
- int nb = config_lstmod ("*.{mod,o}",NULL,lst,1);
- for (int i=0; i<nb && ret != -1; i++){
- ret = depmod_load (mods,syms,lst[i]);
- }
- if (ret != -1){
- depmod_prtdepend (mods,config_getdepfile()
- ,verbose,showerror);
- }
- }
- }else{
- for (int i=optind; i<argc && ret != -1; i++){
- char *arg = argv[i];
- if (arg[0] == '-'){
- // Option processing, one day ...
- }else{
- ret = depmod_load (mods,syms,arg);
- }
- }
- if (ret != -1){
- depmod_prtdepend(mods,NULL,verbose,showerror);
-
- }
- }
- }
- }
- return ret;
- }
-
-