home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1999 May / pcp151c.iso / misc / src / install / modutils / insmod / insmod.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-06  |  33.9 KB  |  1,534 lines

  1. /* Insert a module into a running kernel.
  2.    Copyright 1996, 1997 Linux International.
  3.  
  4.    New implementation contributed by Richard Henderson <rth@tamu.edu>
  5.    Based on original work by Bjorn Eckwall <bj0rn@blox.se>
  6.  
  7.    This file is part of the Linux modutils.
  8.  
  9.    This program is free software; you can redistribute it and/or modify it
  10.    under the terms of the GNU General Public License as published by the
  11.    Free Software Foundation; either version 2 of the License, or (at your
  12.    option) any later version.
  13.  
  14.    This program is distributed in the hope that it will be useful, but
  15.    WITHOUT ANY WARRANTY; without even the implied warranty of
  16.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.    General Public License for more details.
  18.  
  19.    You should have received a copy of the GNU General Public License
  20.    along with this program; if not, write to the Free Software Foundation,
  21.    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  22.  
  23. #ident "$Id: insmod.c,v 1.1.1.1 1998/01/06 20:51:07 ewt Exp $"
  24.  
  25. #include <sys/types.h>
  26. #include <stdlib.h>
  27. #include <unistd.h>
  28. #include <string.h>
  29. #include <alloca.h>
  30. #include <limits.h>
  31. #include <ctype.h>
  32. #include <errno.h>
  33. #include <stddef.h>
  34. #include <sys/utsname.h>
  35. #include <sys/stat.h>
  36.  
  37. #include "module.h"
  38. #include "obj.h"
  39. #include "util.h"
  40. #include "version.h"
  41.  
  42. #include "logger.h"
  43.  
  44. #define STRVERSIONLEN    32
  45.  
  46.  
  47. /*======================================================================*/
  48.  
  49. int flag_force_load = 0;
  50. int flag_autoclean = 0;
  51. int flag_silent_poll = 0;
  52. int flag_verbose = 0;
  53. int flag_export = 1;
  54. int flag_load_map = 0;
  55.  
  56. struct external_module
  57. {
  58.   const char *name;
  59.   ElfW(Addr) addr;
  60.   int used;
  61.   size_t nsyms;
  62.   struct new_module_symbol *syms;
  63. };
  64.  
  65. struct new_module_symbol *ksyms;
  66. size_t nksyms;
  67.  
  68. struct external_module *ext_modules;
  69. int n_ext_modules;
  70. int n_ext_modules_used;
  71.  
  72.  
  73. /*======================================================================*/
  74.  
  75. /* Given a bare module name, poke through the module path to find the file.  */
  76.  
  77. static char *
  78. search_module_path(char *base)
  79. {
  80.   static const char default_path[] =
  81.     ".:"
  82.     "/linux/modules:"
  83.     "/lib/modules/%s/fs:"
  84.     "/lib/modules/%s/net:"
  85.     "/lib/modules/%s/scsi:"
  86.     "/lib/modules/%s/block:"
  87.     "/lib/modules/%s/cdrom:"
  88.     "/lib/modules/%s/ipv4:"
  89.     "/lib/modules/%s/ipv6:"
  90.     "/lib/modules/%s/misc:"
  91.     "/lib/modules/default/fs:"
  92.     "/lib/modules/default/net:"
  93.     "/lib/modules/default/scsi:"
  94.     "/lib/modules/default/block:"
  95.     "/lib/modules/default/cdrom:"
  96.     "/lib/modules/default/ipv4:"
  97.     "/lib/modules/default/ipv6:"
  98.     "/lib/modules/default/misc:"
  99.     "/lib/modules/fs:"
  100.     "/lib/modules/net:"
  101.     "/lib/modules/scsi:"
  102.     "/lib/modules/block:"
  103.     "/lib/modules/cdrom:"
  104.     "/lib/modules/ipv4:"
  105.     "/lib/modules/ipv6:"
  106.     "/lib/modules/misc";
  107.  
  108.   char *path, *p, *filename;
  109.   struct utsname uts_info;
  110.   size_t len;
  111.  
  112.   if ((path = getenv("MODPATH")) == NULL)
  113.     path = (char *)default_path;
  114.  
  115.   /* Make a copy so's we can mung it with strtok.  */
  116.   len = strlen(path)+1;
  117.   p = alloca(len);
  118.   path = memcpy(p, path, len);
  119.  
  120.   uname(&uts_info);
  121.   filename = xmalloc(PATH_MAX);
  122.  
  123.   for (p = strtok(path, ":"); p != NULL ; p = strtok(NULL, ":"))
  124.     {
  125.       struct stat sb;
  126.  
  127.       len = snprintf(filename, PATH_MAX, p, uts_info.release);
  128.       len += snprintf(filename+len, PATH_MAX-len, "/%s", base);
  129.  
  130.       if (stat(filename, &sb) == 0 && S_ISREG(sb.st_mode))
  131.     return filename;
  132.  
  133.       snprintf(filename+len, PATH_MAX-len, ".o");
  134.  
  135.       if (stat(filename, &sb) == 0 && S_ISREG(sb.st_mode))
  136.     return filename;
  137.     }
  138.  
  139.   free(filename);
  140.   return NULL;
  141. }
  142.  
  143. /* Get the kernel version in the canonical integer form.  */
  144.  
  145. static int
  146. get_kernel_version(char str[STRVERSIONLEN])
  147. {
  148.   struct utsname uts_info;
  149.   char *p, *q;
  150.   int a, b, c;
  151.  
  152.   if (uname(&uts_info) < 0)
  153.     return -1;
  154.   strncpy(str, uts_info.release, STRVERSIONLEN);
  155.   p = uts_info.release;
  156.  
  157.   a = strtoul(p, &p, 10);
  158.   if (*p != '.')
  159.     return -1;
  160.   b = strtoul(p+1, &p, 10);
  161.   if (*p != '.')
  162.     return -1;
  163.   c = strtoul(p+1, &q, 10);
  164.   if (p+1 == q)
  165.     return -1;
  166.  
  167.   return a << 16 | b << 8 | c;
  168. }
  169.  
  170. /* String comparison for non-co-versioned kernel and module.  */
  171.  
  172. static int
  173. ncv_strcmp(const char *a, const char *b)
  174. {
  175.   size_t alen = strlen(a), blen = strlen(b);
  176.  
  177.   if (blen == alen + 10 && b[alen] == '_' && b[alen+1] == 'R')
  178.     return strncmp(a, b, alen);
  179.   else if (alen == blen + 10 && a[blen] == '_' && a[blen+1] == 'R')
  180.     return strncmp(a, b, blen);
  181.   else
  182.     return strcmp(a, b);
  183. }
  184.  
  185. /* String hashing for non-co-versioned kernel and module.  Here
  186.    we are simply forced to drop the crc from the hash.  */
  187.  
  188. static unsigned long
  189. ncv_symbol_hash(const char *str)
  190. {
  191.   size_t len = strlen(str);
  192.   if (len > 10 && str[len-10] == '_' && str[len-9] == 'R')
  193.     len -= 10;
  194.   return obj_elf_hash_n(str, len);
  195. }
  196.  
  197. /* Conditionally add the symbols from the given symbol set to the
  198.    new module.  */
  199.  
  200. static int
  201. add_symbols_from(struct obj_file *f, int idx,
  202.          struct new_module_symbol *syms, size_t nsyms)
  203. {
  204.   struct new_module_symbol *s;
  205.   size_t i;
  206.   int used = 0;
  207.  
  208.   for (i = 0, s = syms; i < nsyms; ++i, ++s)
  209.     {
  210.       /* We don't really need to add all of the symbols, just the ones
  211.      that already exist in the symtab -- this covers the undefineds
  212.      and the weaks, all the rest get ignored.  */
  213.  
  214.       struct obj_symbol *sym;
  215.       sym = obj_find_symbol(f, (char *)s->name);
  216.       if (sym)
  217.     {
  218.       sym = obj_add_symbol(f, (char *)s->name,
  219.                    ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE),
  220.                    idx, s->value, 0);
  221.  
  222.       /* Did our symbol just get installed?  If so, mark the
  223.          module as "used".  */
  224.  
  225.       if (sym->secidx == idx)
  226.         used = 1;
  227.     }
  228.     }
  229.  
  230.   return used;
  231. }
  232.  
  233. static void
  234. add_kernel_symbols(struct obj_file *f)
  235. {
  236.   struct external_module *m;
  237.   size_t i, nused = 0;
  238.  
  239.   /* Add module symbols first.  */
  240.  
  241.   for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
  242.     if (m->nsyms && add_symbols_from(f, SHN_HIRESERVE+2+i, m->syms, m->nsyms))
  243.       m->used = 1, ++nused;
  244.  
  245.   n_ext_modules_used = nused;
  246.  
  247.   /* And finally the symbols from the kernel proper.  */
  248.  
  249.   if (nksyms)
  250.     add_symbols_from(f, SHN_HIRESERVE+1, ksyms, nksyms);
  251. }
  252.  
  253. static void
  254. hide_special_symbols(struct obj_file *f)
  255. {
  256.   static const char * const specials[] =
  257.   {
  258.     "cleanup_module",
  259.     "init_module",
  260.     "kernel_version",
  261.     NULL
  262.   };
  263.  
  264.   struct obj_symbol *sym;
  265.   const char * const *p;
  266.  
  267.   for (p = specials; *p ; ++p)
  268.     if ((sym = obj_find_symbol(f, *p)) != NULL)
  269.       sym->info = ELFW(ST_INFO)(STB_LOCAL, ELFW(ST_TYPE)(sym->info));
  270. }
  271.  
  272. static void
  273. print_load_map(struct obj_file *f)
  274. {
  275.   int
  276.   load_map_cmp(const void *a, const void *b)
  277.   {
  278.     struct obj_symbol **as = (struct obj_symbol **)a;
  279.     struct obj_symbol **bs = (struct obj_symbol **)b;
  280.     unsigned long aa = obj_symbol_final_value(f, *as);
  281.     unsigned long ba = obj_symbol_final_value(f, *bs);
  282.     return aa < ba ? -1 : aa > ba ? 1 : 0;
  283.   }
  284.  
  285.   int i, nsyms, *loaded;
  286.   struct obj_symbol *sym;
  287.   struct obj_symbol **all, **p;
  288.   struct obj_section *sec;
  289.  
  290.   /* Report on the section layout.  */
  291.  
  292.   lprintf("Sections:       Size      %-*s  Align",
  293.       (int)(2*sizeof(void*)), "Address");
  294.   for (sec = f->load_order; sec ; sec = sec->load_next)
  295.     {
  296.       int a;
  297.       unsigned long tmp;
  298.       for (a = -1, tmp = sec->header.sh_addralign; tmp ; ++a)
  299.     tmp >>= 1;
  300.       if (a == -1)
  301.     a = 0;
  302.  
  303.       lprintf("%-16s%08lx  %0*lx  2**%d", sec->name, sec->header.sh_size,
  304.           (int)(2*sizeof(void*)), sec->header.sh_addr, a);
  305.     }
  306.  
  307.   /* Quick reference which section indicies are loaded.  */
  308.  
  309.   loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
  310.   while (--i >= 0)
  311.     loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
  312.  
  313.   /* Collect the symbols we'll be listing.  */
  314.  
  315.   for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
  316.     for (sym = f->symtab[i]; sym; sym = sym->next)
  317.       if (sym->secidx <= SHN_HIRESERVE
  318.       && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
  319.     ++nsyms;
  320.  
  321.   all = alloca(nsyms * sizeof(struct obj_symbol *));
  322.  
  323.   for (i = 0, p = all; i < HASH_BUCKETS; ++i)
  324.     for (sym = f->symtab[i]; sym; sym = sym->next)
  325.       if (sym->secidx <= SHN_HIRESERVE
  326.       && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
  327.     *p++ = sym;
  328.  
  329.   /* Sort them by final value.  */
  330.  
  331.   qsort(all, nsyms, sizeof(struct obj_file *), load_map_cmp);
  332.  
  333.   /* And list them.  */
  334.  
  335.   lprintf("\nSymbols:");
  336.   for (p = all; p < all+nsyms; ++p)
  337.     {
  338.       char type = '?';
  339.       unsigned long value;
  340.  
  341.       sym = *p;
  342.       if (sym->secidx == SHN_ABS)
  343.     {
  344.       type = 'A';
  345.       value = sym->value;
  346.     }
  347.       else if (sym->secidx == SHN_UNDEF)
  348.     {
  349.       type = 'U';
  350.       value = 0;
  351.     }
  352.       else
  353.     {
  354.       struct obj_section *sec = f->sections[sym->secidx];
  355.  
  356.       if (sec->header.sh_type == SHT_NOBITS)
  357.         type = 'B';
  358.       else if (sec->header.sh_flags & SHF_ALLOC)
  359.         {
  360.           if (sec->header.sh_flags & SHF_EXECINSTR)
  361.         type = 'T';
  362.           else if (sec->header.sh_flags & SHF_WRITE)
  363.         type = 'D';
  364.           else
  365.         type = 'R';
  366.         }
  367.  
  368.       value = sym->value + sec->header.sh_addr;
  369.     }
  370.  
  371.       if (ELFW(ST_BIND)(sym->info) == STB_LOCAL)
  372.     type = tolower(type);
  373.  
  374.       lprintf("%0*lx %c %s", (int)(2*sizeof(void*)), value,
  375.           type, sym->name);
  376.     }
  377. }
  378.  
  379. /*======================================================================*/
  380. /* Functions relating to module loading in pre 2.1 kernels.  */
  381.  
  382. /* Fetch all the symbols and divvy them up as appropriate for the modules.  */
  383.  
  384. static int
  385. old_get_kernel_symbols(void)
  386. {
  387.   struct old_kernel_sym *ks, *k;
  388.   struct new_module_symbol *s;
  389.   struct external_module *mod;
  390.   int nks, nms, nmod, i;
  391.  
  392.   nks = get_kernel_syms(NULL);
  393.   if (nks < 0)
  394.     {
  395.       error("get_kernel_syms: %m");
  396.       return 0;
  397.     }
  398.  
  399.   ks = k = xmalloc(nks * sizeof(*ks));
  400.  
  401.   if (get_kernel_syms(ks) != nks)
  402.     {
  403.       error("inconsistency with get_kernel_syms -- is someone else "
  404.         "playing with modules?");
  405.       free(ks);
  406.       return 0;
  407.     }
  408.  
  409.   /* Collect the module information.  */
  410.  
  411.   mod = NULL;
  412.   nmod = -1;
  413.  
  414.   while (k->name[0] == '#' && k->name[1])
  415.     {
  416.       struct old_kernel_sym *k2;
  417.       struct new_module_symbol *s;
  418.  
  419.       /* Find out how many symbols this module has.  */
  420.       for (k2 = k+1; k2->name[0] != '#'; ++k2)
  421.     continue;
  422.       nms = k2 - k - 1;
  423.  
  424.       mod = xrealloc(mod, (++nmod+1) * sizeof(*mod));
  425.       mod[nmod].name = k->name+1;
  426.       mod[nmod].addr = k->value;
  427.       mod[nmod].used = 0;
  428.       mod[nmod].nsyms = nms;
  429.       mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
  430.  
  431.       for (i = 0, ++k; i < nms; ++i, ++s, ++k)
  432.     {
  433.       s->name = (unsigned long)k->name;
  434.       s->value = k->value;
  435.     }
  436.  
  437.       k = k2;
  438.     }
  439.  
  440.   ext_modules = mod;
  441.   n_ext_modules = nmod+1;
  442.  
  443.   /* Now collect the symbols for the kernel proper.  */
  444.  
  445.   if (k->name[0] == '#')
  446.     ++k;
  447.  
  448.   nksyms = nms = nks - (k - ks);
  449.   ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
  450.  
  451.   for (i = 0; i < nms; ++i, ++s, ++k)
  452.     {
  453.       s->name = (unsigned long)k->name;
  454.       s->value = k->value;
  455.     }
  456.  
  457.   return 1;
  458. }
  459.  
  460. /* Return the kernel symbol checksum version, or zero if not used.  */
  461.  
  462. static int
  463. old_is_kernel_checksummed(void)
  464. {
  465.   /* Using_Versions is the first symbol.  */
  466.   if (nksyms > 0 && strcmp((char *)ksyms[0].name, "Using_Versions") == 0)
  467.     return ksyms[0].value;
  468.   else
  469.     return 0;
  470. }
  471.  
  472. /* Get the module's kernel version in the canonical integer form.  */
  473.  
  474. static int
  475. old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
  476. {
  477.   struct obj_symbol *sym;
  478.   char *p, *q;
  479.   int a, b, c;
  480.  
  481.   sym = obj_find_symbol(f, "kernel_version");
  482.   if (sym == NULL)
  483.     return -1;
  484.   p = f->sections[sym->secidx]->contents + sym->value;
  485.   strncpy(str, p, STRVERSIONLEN);
  486.  
  487.   a = strtoul(p, &p, 10);
  488.   if (*p != '.')
  489.     return -1;
  490.   b = strtoul(p+1, &p, 10);
  491.   if (*p != '.')
  492.     return -1;
  493.   c = strtoul(p+1, &q, 10);
  494.   if (p+1 == q)
  495.     return -1;
  496.  
  497.   return a << 16 | b << 8 | c;
  498. }
  499.  
  500. static int
  501. old_is_module_checksummed(struct obj_file *f)
  502. {
  503.   return obj_find_symbol(f, "Using_Versions") != NULL;
  504. }
  505.  
  506. static int
  507. old_create_mod_use_count(struct obj_file *f)
  508. {
  509.   struct obj_section *sec;
  510.  
  511.   sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
  512.                      sizeof(long));
  513.  
  514.   obj_add_symbol(f, "mod_use_count_", ELFW(ST_INFO)(STB_LOCAL, STT_OBJECT),
  515.          sec->idx, 0, sizeof(long));
  516.  
  517.   return 1;
  518. }
  519.  
  520. static int
  521. old_process_module_arguments(struct obj_file *f, int argc, char **argv)
  522. {
  523.   while (argc > 0)
  524.     {
  525.       char *p, *q;
  526.       struct obj_symbol *sym;
  527.       int *loc;
  528.  
  529.       p = *argv;
  530.       if ((q = strchr(p, '=')) == NULL)
  531.     continue;
  532.       *q++ = '\0';
  533.  
  534.       sym = obj_find_symbol(f, p);
  535.       if (sym == NULL)
  536.     {
  537.       error("symbol for parameter %s not found", p);
  538.       return 0;
  539.     }
  540.  
  541.       loc = (int *)(f->sections[sym->secidx]->contents + sym->value);
  542.  
  543.       if (*q >= '0' && *q <= '9')
  544.     {
  545.       do
  546.         *loc++ = strtol(q, &q, 0);
  547.       while (*q++ == ',');
  548.     }
  549.       else
  550.     {
  551.       char *contents = f->sections[sym->secidx]->contents;
  552.       char *loc = contents + sym->value;
  553.       char *r;    /* To search for commas */
  554.  
  555.       /* Break the string with comas */
  556.       while((r = strchr(q, ',')) != (char *) NULL)
  557.         {
  558.           *r++ = '\0';
  559.           obj_string_patch(f, sym->secidx, loc-contents, q);
  560.           loc += sizeof(char*);
  561.           q = r;
  562.         }
  563.  
  564.       /* last part */
  565.       obj_string_patch(f, sym->secidx, loc-contents, q);
  566.     }
  567.  
  568.       argc--, argv++;
  569.     }
  570.  
  571.   return 1;
  572. }
  573.  
  574. static int
  575. old_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
  576. {
  577.   char *image;
  578.   struct old_mod_routines routines;
  579.   struct old_symbol_table *symtab;
  580.   int ret;
  581.  
  582.   /* Create the symbol table */
  583.   {
  584.     int nsyms = 0, strsize = 0, total;
  585.  
  586.     /* Size things first... */
  587.     if (flag_export)
  588.       {
  589.     int i;
  590.     for (i = 0; i < HASH_BUCKETS; ++i)
  591.       {
  592.         struct obj_symbol *sym;
  593.         for (sym = f->symtab[i]; sym; sym = sym->next)
  594.           if (ELFW(ST_BIND)(sym->info) != STB_LOCAL
  595.           && sym->secidx <= SHN_HIRESERVE)
  596.         {
  597.           sym->ksymidx = nsyms++;
  598.           strsize += strlen(sym->name)+1;
  599.         }
  600.       }
  601.       }
  602.  
  603.     total = (sizeof(struct old_symbol_table)
  604.          + nsyms * sizeof(struct old_module_symbol)
  605.          + n_ext_modules_used * sizeof(struct old_module_ref)
  606.          + strsize);
  607.     symtab = xmalloc(total);
  608.     symtab->size = total;
  609.     symtab->n_symbols = nsyms;
  610.     symtab->n_refs = n_ext_modules_used;
  611.  
  612.     if (flag_export && nsyms)
  613.       {
  614.     struct old_module_symbol *ksym;
  615.     char *str;
  616.     int i;
  617.  
  618.     ksym = symtab->symbol;
  619.     str = ((char *)ksym
  620.            + nsyms * sizeof(struct old_module_symbol)
  621.            + n_ext_modules_used * sizeof(struct old_module_ref));
  622.  
  623.     for (i = 0; i < HASH_BUCKETS; ++i)
  624.       {
  625.         struct obj_symbol *sym;
  626.         for (sym = f->symtab[i]; sym; sym = sym->next)
  627.           if (sym->ksymidx >= 0)
  628.         {
  629.           ksym->addr = obj_symbol_final_value(f, sym);
  630.           ksym->name = (unsigned long)str - (unsigned long)symtab;
  631.  
  632.           str = stpcpy(str, sym->name)+1;
  633.           ksym++;
  634.         }
  635.       }
  636.       }
  637.  
  638.     if (n_ext_modules_used)
  639.       {
  640.     struct old_module_ref *ref;
  641.     int i;
  642.  
  643.     ref = (struct old_module_ref *)
  644.       ((char *)symtab->symbol + nsyms * sizeof(struct old_module_symbol));
  645.  
  646.     for (i = 0; i < n_ext_modules; ++i)
  647.       if (ext_modules[i].used)
  648.         ref++->module = ext_modules[i].addr;
  649.       }
  650.   }
  651.  
  652.   /* Fill in routines.  */
  653.  
  654.   routines.init = obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
  655.   routines.cleanup
  656.     = obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
  657.  
  658.   /* Whew!  All of the initialization is complete.  Collect the final
  659.      module image and give it to the kernel.  */
  660.  
  661.   image = xmalloc(m_size);
  662.   obj_create_image(f, image);
  663.  
  664.   /* image holds the complete relocated module, accounting correctly for
  665.      mod_use_count.  However the old module kernel support assume that
  666.      it is receiving something which does not contain mod_use_count.  */
  667.   ret = old_sys_init_module(m_name, image+sizeof(long),
  668.                 m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN : 0),
  669.                 &routines, symtab);
  670.   if (ret)
  671.     error("init_module: %m");
  672.  
  673.   free(image);
  674.   free(symtab);
  675.  
  676.   return ret == 0;
  677. }
  678.  
  679. /*======================================================================*/
  680. /* Functions relating to module loading after 2.1.18.  */
  681.  
  682. /* Fetch the loaded modules, and all currently exported symbols.  */
  683.  
  684. static int
  685. new_get_kernel_symbols(void)
  686. {
  687.   char *module_names, *mn;
  688.   struct external_module *modules, *m;
  689.   struct new_module_symbol *syms, *s;
  690.   size_t ret, bufsize, nmod, nsyms, i, j;
  691.  
  692.   /* Collect the loaded modules.  */
  693.  
  694.   module_names = xmalloc(bufsize = 256);
  695. retry_modules_load:
  696.   if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret))
  697.     {
  698.       if (errno == ENOSPC)
  699.     {
  700.       module_names = xrealloc(module_names, bufsize = ret);
  701.       goto retry_modules_load;
  702.     }
  703.       error("QM_MODULES: %m\n");
  704.       return 0;
  705.     }
  706.  
  707.   n_ext_modules = nmod = ret;
  708.   ext_modules = modules = xmalloc(nmod * sizeof(*modules));
  709.   memset(modules, 0, nmod * sizeof(*modules));
  710.  
  711.   /* Collect the modules' symbols.  */
  712.  
  713.   for (i = 0, mn = module_names, m = modules;
  714.        i < nmod;
  715.        ++i, ++m, mn += strlen(mn)+1)
  716.     {
  717.       struct new_module_info info;
  718.  
  719.       if (query_module(mn, QM_INFO, &info, sizeof(info), &ret))
  720.     {
  721.       if (errno == ENOENT)
  722.         /* The module was removed out from underneath us.  */
  723.         continue;
  724.       error("module %s: QM_INFO: %m", mn);
  725.       return 0;
  726.     }
  727.  
  728.       syms = xmalloc(bufsize = 1024);
  729.     retry_mod_sym_load:
  730.       if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret))
  731.     {
  732.       switch (errno)
  733.         {
  734.         case ENOSPC:
  735.           syms = xrealloc(syms, bufsize = ret);
  736.           goto retry_mod_sym_load;
  737.         case ENOENT:
  738.           /* The module was removed out from underneath us.  */
  739.           continue;
  740.         default:
  741.           error("module %s: QM_SYMBOLS: %m", mn);
  742.           return 0;
  743.         }
  744.     }
  745.       nsyms = ret;
  746.  
  747.       m->name = mn;
  748.       m->addr = info.addr;
  749.       m->nsyms = nsyms;
  750.       m->syms = syms;
  751.  
  752.       for (j = 0, s = syms; j < nsyms; ++j, ++s)
  753.     s->name += (unsigned long)syms;
  754.     }
  755.  
  756.   /* Collect the kernel's symbols.  */
  757.  
  758.   syms = xmalloc(bufsize = 16*1024);
  759. retry_kern_sym_load:
  760.   if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret))
  761.     {
  762.       if (errno == ENOSPC)
  763.     {
  764.       syms = xrealloc(syms, bufsize = ret);
  765.       goto retry_kern_sym_load;
  766.     }
  767.       error("kernel: QM_SYMBOLS: %m");
  768.       return 0;
  769.     }
  770.   nksyms = nsyms = ret;
  771.   ksyms = syms;
  772.  
  773.   for (j = 0, s = syms; j < nsyms; ++j, ++s)
  774.     s->name += (unsigned long)syms;
  775.  
  776.   return 1;
  777. }
  778.  
  779. /* Return the kernel symbol checksum version, or zero if not used.  */
  780.  
  781. static int
  782. new_is_kernel_checksummed(void)
  783. {
  784.   struct new_module_symbol *s;
  785.   size_t i;
  786.  
  787.   /* Using_Versions is not the first symbol, but it should be in there.  */
  788.  
  789.   for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
  790.     if (strcmp((char *)s->name, "Using_Versions") == 0)
  791.       return s->value;
  792.  
  793.   return 0;
  794. }
  795.  
  796. static char *
  797. get_modinfo_value(struct obj_file *f, const char *key)
  798. {
  799.   struct obj_section *sec;
  800.   char *p, *v, *n, *ep;
  801.   size_t klen = strlen(key);
  802.  
  803.   sec = obj_find_section(f, ".modinfo");
  804.   if (sec == NULL)
  805.     return NULL;
  806.  
  807.   p = sec->contents;
  808.   ep = p + sec->header.sh_size;
  809.   while (p < ep)
  810.     {
  811.       v = strchr(p, '=');
  812.       n = strchr(p, '\0');
  813.       if (v)
  814.     {
  815.       if (v-p == klen && strncmp(p, key, klen) == 0)
  816.         return v+1;
  817.     }
  818.       else
  819.     {
  820.       if (n-p == klen && strcmp(p, key) == 0)
  821.         return n;
  822.     }
  823.       p = n+1;
  824.     }
  825.  
  826.   return NULL;
  827. }
  828.  
  829. /* Get the module's kernel version in the canonical integer form.  */
  830.  
  831. static int
  832. new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
  833. {
  834.   char *p, *q;
  835.   int a, b, c;
  836.  
  837.   p = get_modinfo_value(f, "kernel_version");
  838.   if (p == NULL)
  839.     return -1;
  840.   strncpy(str, p, STRVERSIONLEN);
  841.  
  842.   a = strtoul(p, &p, 10);
  843.   if (*p != '.')
  844.     return -1;
  845.   b = strtoul(p+1, &p, 10);
  846.   if (*p != '.')
  847.     return -1;
  848.   c = strtoul(p+1, &q, 10);
  849.   if (p+1 == q)
  850.     return -1;
  851.  
  852.   return a << 16 | b << 8 | c;
  853. }
  854.  
  855. static int
  856. new_is_module_checksummed(struct obj_file *f)
  857. {
  858.   const char *p = get_modinfo_value(f, "using_checksums");
  859.   if (p)
  860.     return atoi(p);
  861.   else
  862.     return 0;
  863. }
  864.  
  865. static int
  866. new_process_module_arguments(struct obj_file *f, int argc, char **argv)
  867. {
  868.   while (argc > 0)
  869.     {
  870.       char *p, *q, *key;
  871.       struct obj_symbol *sym;
  872.       char *contents, *loc;
  873.       int min, max, n;
  874.  
  875.       p = *argv;
  876.       if ((q = strchr(p, '=')) == NULL)
  877.     continue;
  878.  
  879.       key = alloca(q-p + 6);
  880.       memcpy(key, "parm_", 5);
  881.       memcpy(key+5, p, q-p);
  882.       key[q-p+5] = 0;
  883.  
  884.       p = get_modinfo_value(f, key);
  885.       key += 5;
  886.       if (p == NULL)
  887.     {
  888.       error("invalid parameter %s", key);
  889.       return 0;
  890.     }
  891.  
  892.       sym = obj_find_symbol(f, key);
  893.       if (sym == NULL)
  894.     {
  895.       error("symbol for parameter %s not found", key);
  896.       return 0;
  897.     }
  898.  
  899.       if (isdigit(*p))
  900.     {
  901.       min = strtoul(p, &p, 10);
  902.       if (*p == '-')
  903.         max = strtoul(p+1, &p, 10);
  904.       else
  905.         max = min;
  906.     }
  907.       else
  908.     min = max = 1;
  909.  
  910.       contents = f->sections[sym->secidx]->contents;
  911.       loc = contents + sym->value;
  912.       n = (*++q != '\0');
  913.  
  914.       while (1)
  915.     {
  916.       if((*p == 's') || (*p == 'c'))
  917.         {
  918.           char *str;
  919.  
  920.           /* Do C quoting if we begin with a ", else slurp the lot.  */
  921.           if (*q == '"')
  922.         {
  923.           char *r;
  924.  
  925.           str = alloca(strlen(q));
  926.           for (r = str, q++; *q != '"'; ++q, ++r)
  927.             {
  928.               if (*q == '\0')
  929.             {
  930.               error("improperly terminated string argument for %s",
  931.                 key);
  932.               return 0;
  933.             }
  934.               else if (*q == '\\')
  935.             switch (*++q)
  936.               {
  937.               case 'a': *r = '\a'; break;
  938.               case 'b': *r = '\b'; break;
  939.               case 'e': *r = '\033'; break;
  940.               case 'f': *r = '\f'; break;
  941.               case 'n': *r = '\n'; break;
  942.               case 'r': *r = '\r'; break;
  943.               case 't': *r = '\t'; break;
  944.  
  945.               case '0': case '1': case '2': case '3':
  946.               case '4': case '5': case '6': case '7':
  947.                 {
  948.                   int c = *q - '0';
  949.                   if (q[1] >= '0' && q[1] <= '7')
  950.                 {
  951.                   c = (c * 8) + *++q - '0';
  952.                   if (q[1] >= '0' && q[1] <= '7')
  953.                     c = (c * 8) + *++q - '0';
  954.                 }
  955.                   *r = c;
  956.                 }
  957.               break;
  958.  
  959.               default:
  960.                 *r = *q;
  961.                 break;
  962.               }
  963.               else
  964.             *r = *q;
  965.             }
  966.           ++q;
  967.         }
  968.           else
  969.         {
  970.           char *r;
  971.  
  972.           /* In this case, the string is not quoted. We will break
  973.              it using the coma (like for ints). If the user wants to
  974.              include comas in a string, he just has to quote it */
  975.  
  976.           /* Search the next coma */
  977.           r = strchr(q, ',');
  978.  
  979.           /* Found ? */
  980.           if(r != (char *) NULL)
  981.             {
  982.               /* Recopy the current field */
  983.               str = alloca(r - q + 1);
  984.               memcpy(str, q, r - q);
  985.  
  986.               /* I don't know if it is usefull, as the previous case
  987.                  doesn't null terminate the string ??? */
  988.               str[r - q] = '\0';
  989.  
  990.               /* Keep next fields */
  991.               q = r;
  992.             }
  993.           else
  994.             {
  995.               /* last string */
  996.               str = q;
  997.               q = "";
  998.             }
  999.         }
  1000.  
  1001.           if (*p == 's')
  1002.         {
  1003.           /* Normal string */
  1004.           obj_string_patch(f, sym->secidx, loc-contents, str);
  1005.           loc += tgt_sizeof_char_p;
  1006.         }
  1007.           else
  1008.         {
  1009.           /* Array of chars (in fact, matrix !) */
  1010.           long    charssize;    /* size of each member */
  1011.  
  1012.           /* Get the size of each member */
  1013.           /* Probably we should do that outside the loop ? */
  1014.           if(!isdigit(*(p + 1)))
  1015.             {
  1016.               error("parameter type 'c' for %s must be followed by the maximum size",
  1017.                 key);
  1018.               return 0;
  1019.             }
  1020.           charssize = strtoul(p + 1, (char **) NULL, 10);
  1021.  
  1022.           /* Check length */
  1023.           if(strlen(str) >= charssize)
  1024.             {
  1025.               error("string too long for %s (max %ld)",
  1026.                 key, charssize - 1);
  1027.               return 0;
  1028.             }
  1029.  
  1030.           /* Copy to location */
  1031.           strcpy((char *) loc, str);
  1032.           loc += charssize;
  1033.         }
  1034.         }
  1035.       else
  1036.         {
  1037.           long v = strtol(q, &q, 0);
  1038.           switch (*p)
  1039.         {
  1040.         case 'b':
  1041.           *loc++ = v;
  1042.           break;
  1043.         case 'h':
  1044.           *(short *)loc = v;
  1045.           loc += tgt_sizeof_short;
  1046.           break;
  1047.         case 'i':
  1048.           *(int *)loc = v;
  1049.           loc += tgt_sizeof_int;
  1050.           break;
  1051.         case 'l':
  1052.           *(long *)loc = v;
  1053.           loc += tgt_sizeof_long;
  1054.           break;
  1055.  
  1056.         default:
  1057.           error("unknown parameter type '%c' for %s",
  1058.             *p, key);
  1059.           return 0;
  1060.         }
  1061.         }
  1062.  
  1063.     retry_end_of_value:
  1064.       switch (*q)
  1065.         {
  1066.         case '\0':
  1067.           goto end_of_arg;
  1068.  
  1069.         case ' ': case '\t': case '\n': case '\r':
  1070.           ++q;
  1071.           goto retry_end_of_value;
  1072.  
  1073.         case ',':
  1074.           if (++n > max)
  1075.         {
  1076.           error("too many values for %s (max %d)", key, max);
  1077.           return 0;
  1078.         }
  1079.           ++q;
  1080.           break;
  1081.  
  1082.         default:
  1083.           error("invalid argument syntax for %s", key);
  1084.           return 0;
  1085.         }
  1086.     }
  1087.  
  1088.     end_of_arg:
  1089.       if (n < min)
  1090.     {
  1091.       error("too few values for %s (min %d)", key, min);
  1092.       return 0;
  1093.     }
  1094.  
  1095.       argc--, argv++;
  1096.     }
  1097.  
  1098.   return 1;
  1099. }
  1100.  
  1101. static int
  1102. new_create_this_module(struct obj_file *f, const char *m_name)
  1103. {
  1104.   struct obj_section *sec;
  1105.  
  1106.   sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
  1107.                      sizeof(struct new_module));
  1108.   memset(sec->contents, 0, sizeof(struct new_module));
  1109.  
  1110.   obj_add_symbol(f, "__this_module", ELFW(ST_INFO)(STB_LOCAL, STT_OBJECT),
  1111.          sec->idx, 0, sizeof(struct new_module));
  1112.  
  1113.   obj_string_patch(f, sec->idx, offsetof(struct new_module, name), m_name);
  1114.  
  1115.   return 1;
  1116. }
  1117.  
  1118. static int
  1119. new_create_module_ksymtab(struct obj_file *f)
  1120. {
  1121.   struct obj_section *sec;
  1122.   int i;
  1123.  
  1124.   /* We must always add the module references.  */
  1125.  
  1126.   if (n_ext_modules_used)
  1127.     {
  1128.       struct new_module_ref *dep;
  1129.       struct obj_symbol *tm;
  1130.  
  1131.       sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
  1132.                        (sizeof(struct new_module_ref)
  1133.                     * n_ext_modules_used));
  1134.       if (!sec)
  1135.     return 0;
  1136.  
  1137.       tm = obj_find_symbol(f, "__this_module");
  1138.       dep = (struct new_module_ref *)sec->contents;
  1139.       for (i = 0; i < n_ext_modules; ++i)
  1140.     if (ext_modules[i].used)
  1141.       {
  1142.         dep->dep = ext_modules[i].addr;
  1143.         obj_symbol_patch(f, sec->idx, (char*)&dep->ref - sec->contents, tm);
  1144.         dep->next_ref = 0;
  1145.         ++dep;
  1146.       }
  1147.     }
  1148.  
  1149.   if (flag_export && !obj_find_section(f, "__ksymtab"))
  1150.     {
  1151.       size_t nsyms;
  1152.       int *loaded;
  1153.  
  1154.       sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0);
  1155.  
  1156.       /* We don't want to export symbols residing in sections that
  1157.      aren't loaded.  There are a number of these created so that
  1158.      we make sure certain module options don't appear twice.  */
  1159.  
  1160.       loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
  1161.       while (--i >= 0)
  1162.     loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
  1163.  
  1164.       for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
  1165.     {
  1166.       struct obj_symbol *sym;
  1167.       for (sym = f->symtab[i]; sym; sym = sym->next)
  1168.         if (ELFW(ST_BIND)(sym->info) != STB_LOCAL
  1169.         && sym->secidx <= SHN_HIRESERVE
  1170.         && (sym->secidx >= SHN_LORESERVE
  1171.             || loaded[sym->secidx]))
  1172.           {
  1173.         ElfW(Addr) ofs = nsyms * 2*tgt_sizeof_void_p;
  1174.  
  1175.         obj_symbol_patch(f, sec->idx, ofs, sym);
  1176.         obj_string_patch(f, sec->idx, ofs+tgt_sizeof_void_p, sym->name);
  1177.  
  1178.         nsyms++;
  1179.           }
  1180.     }
  1181.  
  1182.       obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
  1183.     }
  1184.  
  1185.   return 1;
  1186. }
  1187.  
  1188. static int
  1189. new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
  1190. {
  1191.   struct new_module *module;
  1192.   struct obj_section *sec;
  1193.   void *image;
  1194.   int ret;
  1195.  
  1196.   sec = obj_find_section(f, ".this");
  1197.   module = (struct new_module *)sec->contents;
  1198.  
  1199.   module->size_of_struct = sizeof(*module);
  1200.   module->size = m_size;
  1201.   module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
  1202.  
  1203.   sec = obj_find_section(f, "__ksymtab");
  1204.   if (sec && sec->header.sh_size)
  1205.     {
  1206.       module->syms = sec->header.sh_addr;
  1207.       module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
  1208.     }
  1209.  
  1210.   if (n_ext_modules_used)
  1211.     {
  1212.       sec = obj_find_section(f, ".kmodtab");
  1213.       module->deps = sec->header.sh_addr;
  1214.       module->ndeps = n_ext_modules_used;
  1215.     }
  1216.  
  1217.   module->init = obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
  1218.   module->cleanup
  1219.     = obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
  1220.  
  1221.   sec = obj_find_section(f, "__ex_table");
  1222.   if (sec)
  1223.     {
  1224.       module->ex_table_start = sec->header.sh_addr;
  1225.       module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
  1226.     }
  1227.  
  1228.   if (!arch_init_module(f, module))
  1229.     return 0;
  1230.  
  1231.   /* Whew!  All of the initialization is complete.  Collect the final
  1232.      module image and give it to the kernel.  */
  1233.  
  1234.   image = xmalloc(m_size);
  1235.   obj_create_image(f, image);
  1236.  
  1237.   ret = new_sys_init_module(m_name, (struct new_module *)image);
  1238.   if (ret)
  1239.     error("init_module: %m");
  1240.  
  1241.   free(image);
  1242.  
  1243.   return ret == 0;
  1244. }
  1245.  
  1246.  
  1247. /*======================================================================*/
  1248.  
  1249. int
  1250. main(int argc, char **argv)
  1251. {
  1252.   int k_version;
  1253.   int k_crcs;
  1254.   int k_new_syscalls;
  1255.   char k_strversion[STRVERSIONLEN];
  1256.  
  1257.   char *m_name = NULL;
  1258.   int m_version;
  1259.   ElfW(Addr) m_addr;
  1260.   unsigned long m_size;
  1261.   int m_crcs;
  1262.   int m_has_modinfo;
  1263.   char m_strversion[STRVERSIONLEN];
  1264.  
  1265.   char *filename;
  1266.   FILE *fp;
  1267.   struct obj_file *f;
  1268.   int o, noload = 0;
  1269.  
  1270.   error_file = "insmod";
  1271.  
  1272.   /* Process the command line.  */
  1273.  
  1274.   while ((o = getopt(argc, argv, "fkmno:psvVxX")) != EOF)
  1275.     switch (o)
  1276.       {
  1277.       case 'f': /* force loading */
  1278.     flag_force_load = 1;
  1279.     break;
  1280.       case 'k': /* module loaded by kerneld, auto-cleanable */
  1281.     flag_autoclean = 1;
  1282.     break;
  1283.       case 'm': /* generate load map */
  1284.     flag_load_map = 1;
  1285.     break;
  1286.       case 'n':
  1287.         noload = 1;
  1288.     break;
  1289.       case 'o': /* name the output module */
  1290.     m_name = optarg;
  1291.     break;
  1292.       case 'p': /* silent poll mode */
  1293.     flag_silent_poll = 1;
  1294.     break;
  1295.       case 's': /* start syslog */
  1296.     setsyslog("insmod");
  1297.     break;
  1298.       case 'v': /* verbose output */
  1299.     flag_verbose = 1;
  1300.     break;
  1301.       case 'V':
  1302.     fputs("insmod version " MODUTILS_VERSION "\n", stderr);
  1303.     break;
  1304.       case 'x': /* do not export externs */
  1305.     flag_export = 0;
  1306.     break;
  1307.       case 'X': /* do export externs */
  1308.     flag_export = 1;
  1309.     break;
  1310.       default:
  1311.     goto usage;
  1312.       }
  1313.  
  1314.   if (optind >= argc)
  1315.     {
  1316.     usage:
  1317.       fputs("Usage:\n"
  1318.         "insmod [-fkmopsvVxX] [-o name] module [[sym=value]...]\n"
  1319.         "\n"
  1320.         "  module     Filename of a loadable kernel module (*.o)\n"
  1321.         "  -f         Force loading under wrong kernel version\n"
  1322.         "  -k         Make module autoclean-able\n"
  1323.         "  -m         Generate load map (so crashes can be traced)\n"
  1324.         "  -o name    Set internal modulname to name\n"
  1325.         "  -p         Poll mode; check if the module matches the kernel\n"
  1326.         "  -s         Report errors via syslog\n"
  1327.         "  -v         Verbose output\n"
  1328.         "  -V         Show version\n"
  1329.         "  -x         do not export externs\n"
  1330.         "  -X         do export externs (default)\n"
  1331.         , stderr);
  1332.       return 1;
  1333.     }
  1334.  
  1335.   filename = argv[optind++];
  1336.  
  1337.   if (m_name == NULL)
  1338.     {
  1339.       size_t len;
  1340.       char *p;
  1341.  
  1342.       if ((p = strrchr(filename, '/')) != NULL)
  1343.     p++;
  1344.       else
  1345.     p = filename;
  1346.       len = strlen(p);
  1347.       if (len > 2 && p[len-2] == '.' && p[len-1] == 'o')
  1348.     len -= 2;
  1349.       else if (len > 4 && p[len-4] == '.' && p[len-3] == 'm'
  1350.            && p[len-2] == 'o' && p[len-1] == 'd')
  1351.     len -= 4;
  1352.  
  1353.       m_name = xmalloc(len+1);
  1354.       memcpy(m_name, p, len);
  1355.       m_name[len] = '\0';
  1356.     }
  1357.  
  1358.   /* Locate the file to be loaded.  */
  1359.  
  1360.   if (!strchr(filename, '/') && !strchr(filename, '.'))
  1361.     {
  1362.       char *tmp = search_module_path(filename);
  1363.       if (tmp == NULL)
  1364.         {
  1365.       error("%s: no module by that name found", filename);
  1366.       return 1;
  1367.     }
  1368.       filename = tmp;
  1369.     }
  1370.  
  1371.   error_file = filename;
  1372.  
  1373.   /* And open it.  */
  1374.  
  1375.   if ((fp = fopen(filename, "r")) == NULL)
  1376.     {
  1377.       error("%s: %m", filename);
  1378.       return 1;
  1379.     }
  1380.   else if ((f = obj_load(fp)) == NULL)
  1381.     return 1;
  1382.   fclose(fp);
  1383.  
  1384.   /* Version correspondence?  */
  1385.  
  1386.   k_version = get_kernel_version(k_strversion);
  1387.   m_version = new_get_module_version(f, m_strversion);
  1388.   if (m_version != -1)
  1389.     m_has_modinfo = 1;
  1390.   else
  1391.     {
  1392.       m_has_modinfo = 0;
  1393.       m_version = old_get_module_version(f, m_strversion);
  1394.       if (m_version == -1)
  1395.     {
  1396.       error("couldn't find the kernel version the module was compiled for");
  1397.       return 1;
  1398.     }
  1399.     }
  1400.  
  1401.   if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0)
  1402.     {
  1403.       if (flag_force_load)
  1404.     {
  1405.       lprintf("Warning: kernel-module version mismatch\n"
  1406.           "\t%s was compiled for kernel version %s\n"
  1407.           "\twhile this kernel is version %s\n",
  1408.           filename, m_strversion, k_strversion);
  1409.     }
  1410.       else
  1411.     {
  1412.       error("kernel-module version mismatch\n"
  1413.         "\t%s was compiled for kernel version %s\n"
  1414.         "\twhile this kernel is version %s.",
  1415.         filename, m_strversion, k_strversion);
  1416.       return 1;
  1417.     }
  1418.     }
  1419.  
  1420.   k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
  1421.  
  1422.   if (k_new_syscalls)
  1423.     {
  1424.       if (!new_get_kernel_symbols())
  1425.     return 1;
  1426.       k_crcs = new_is_kernel_checksummed();
  1427.     }
  1428.   else
  1429.     {
  1430.       if (!old_get_kernel_symbols())
  1431.     return 1;
  1432.       k_crcs = old_is_kernel_checksummed();
  1433.     }
  1434.  
  1435.   if (m_has_modinfo)
  1436.     m_crcs = new_is_module_checksummed(f);
  1437.   else
  1438.     m_crcs = old_is_module_checksummed(f);
  1439.  
  1440.   if (m_crcs != k_crcs)
  1441.     obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
  1442.  
  1443.   /* Let the module know about the kernel symbols.  */
  1444.  
  1445.   add_kernel_symbols(f);
  1446.  
  1447.   /* Allocate common symbols, symbol tables, and string tables.  */
  1448.  
  1449.   if (k_new_syscalls
  1450.       ? !new_create_this_module(f, m_name)
  1451.       : !old_create_mod_use_count(f))
  1452.     return 1;
  1453.  
  1454.   if (!obj_allocate_commons_and_check_undefineds(f))
  1455.     return 1;
  1456.  
  1457.   if (optind < argc)
  1458.     {
  1459.       if (m_has_modinfo
  1460.       ? !new_process_module_arguments(f, argc-optind, argv+optind)
  1461.       : !old_process_module_arguments(f, argc-optind, argv+optind))
  1462.     return 1;
  1463.     }
  1464.  
  1465.   arch_create_got(f);
  1466.   hide_special_symbols(f);
  1467.  
  1468.   if (k_new_syscalls)
  1469.     new_create_module_ksymtab(f);
  1470.  
  1471.   if (errors)
  1472.     return 1;
  1473.  
  1474.   /* If we were just checking, we made it.  */
  1475.  
  1476.   if (flag_silent_poll)
  1477.     return 0;
  1478.  
  1479.   /* Module has now finished growing; find its size and install it.  */
  1480.  
  1481.   m_size = obj_load_size(f);
  1482.  
  1483.   if (noload)
  1484.     {
  1485.       /* Don't bother actually touching the kernel.  */
  1486.       m_addr = 0x12340000;
  1487.     }
  1488.   else
  1489.     {
  1490.       errno = 0;
  1491.       m_addr = create_module(m_name, m_size);
  1492.       switch (errno)
  1493.         {
  1494.         case 0:
  1495.           break;
  1496.         case EEXIST:
  1497.           error("a module named %s already exists", m_name);
  1498.           return 1;
  1499.         case ENOMEM:
  1500.           error("can't allocate kernel memory for module; needed %lu bytes",
  1501.             m_size);
  1502.           return 1;
  1503.         default:
  1504.           error("create_module: %m");
  1505.           return 1;
  1506.         }
  1507.     }
  1508.  
  1509.   if (!obj_relocate(f, m_addr))
  1510.     {
  1511.       if (!noload)
  1512.         delete_module(m_name);
  1513.       return 1;
  1514.     }
  1515.  
  1516.   if (noload)
  1517.     ;
  1518.   else if (k_new_syscalls)
  1519.     new_init_module(m_name, f, m_size);
  1520.   else
  1521.     old_init_module(m_name, f, m_size);
  1522.   if (errors)
  1523.     {
  1524.       if (!noload)
  1525.         delete_module(m_name);
  1526.       return 1;
  1527.     }
  1528.  
  1529.   if (flag_load_map)
  1530.     print_load_map(f);
  1531.  
  1532.   return 0;
  1533. }
  1534.