--- ./util/alias.h.old Sun Jan 7 10:47:03 2001 +++ ./util/alias.h Sun Jan 7 10:47:35 2001 @@ -226,6 +226,7 @@ char *prune[] = { "modules.dep", + "modules.parms", "modules.generic_string", "modules.pcimap", "modules.isapnpmap", --- ./util/config.c.old Sun Jan 7 10:47:59 2001 +++ ./util/config.c Sun Jan 7 10:47:51 2001 @@ -111,6 +111,7 @@ /* The initialization order must match the gen_file_enum order in config.h */ struct gen_files gen_file[] = { + {"parms", NULL, 0}, {"generic_string", NULL, 0}, {"pcimap", NULL, 0}, {"isapnpmap", NULL, 0}, --- ./include/config.h.old Sun Jan 7 10:48:59 2001 +++ ./include/config.h Sun Jan 7 10:49:07 2001 @@ -87,6 +87,7 @@ extern const int gen_file_count; /* The enum order must match the gen_file initialization order in config.c */ enum gen_file_enum { + GEN_PARMSFILE, GEN_GENERIC_STRINGFILE, GEN_PCIMAPFILE, GEN_ISAPNPMAPFILE, --- ./depmod/depmod.c.old Sun Jan 7 13:02:42 2001 +++ ./depmod/depmod.c Sun Jan 7 13:07:04 2001 @@ -167,6 +167,8 @@ SYMBOL **symtab; int n_syms; } defsym, undefs; + char **parms; /* The first four chars determine the type */ + int n_parms; char **generic_string; int n_generic_string; struct pci_device_id *pci_device; @@ -366,6 +368,194 @@ "\n\tyou probably need a new version of modutils to handle this kernel." "\n\tCheck linux/Documentation/Changes."; + +static void append_parm(MODULE *mod, const char *type, const char *parm) +{ + char **latest; + + mod->parms = xrealloc(mod->parms, ++(mod->n_parms)*sizeof(*(mod->parms))); + latest = mod->parms + mod->n_parms-1; + *latest = xmalloc(strlen(type) + 1 + strlen(parm) + 1); + strcpy(*latest, type); + strcat(*latest, " "); + strcat(*latest, parm); +} + +static const char *get_modinfo_value(struct obj_file *f, const char *key) +{ + struct obj_section *sec; + char *p, *v, *n, *ep; + size_t klen = strlen(key); + + if (strcmp(key, "filename") == 0) { + return(f->filename); + } + + sec = obj_find_section(f, ".modinfo"); + if (sec == NULL) + return NULL; + + p = sec->contents; + ep = p + sec->header.sh_size; + while (p < ep) { + v = strchr(p, '='); + n = strchr(p, '\0'); + if (v) { + if (v - p == klen && strncmp(p, key, klen) == 0) + return v + 1; + } else { + if (n - p == klen && strcmp(p, key) == 0) + return n; + } + p = n + 1; + } + + return NULL; +} + +/* + * Save the module parameter. + * Note: assumes same machine and arch for depmod and module. + */ +static void save_parameter(struct obj_file *f, MODULE *mod, + char *key, char *value, const char *desc) +{ + struct obj_symbol *sym; + int min, max, size; + char *p = value; + char *res; + + sym = obj_find_symbol(f, key); + if (sym == NULL) + printf("warning: symbol for parameter %s not found\n", key); + size = strlen(key) + 1 + strlen(desc) + 64; + res = xmalloc(size); + + if (isdigit(*p)) { + min = strtoul(p, &p, 10); + if (*p == '-') + max = strtoul(p + 1, &p, 10); + else + max = min; + } else + min = max = 1; + + if (max < min) + error("warning: parameter %s has max < min!\n", key); + + strcpy(res, key); + strcat(res, " "); + + switch (*p) { + case 'c': + strcat(res, "char"); + if (!isdigit(p[1])) + error("*** missing string size ***"); + else while (isdigit(p[1])) + ++p; /* swallow c array size */ + break; + case 'b': + strcat(res, "byte"); + break; + case 'h': + strcat(res, "short"); + break; + case 'i': + strcat(res, "int"); + break; + case 'l': + strcat(res, "long"); + break; + case 's': + strcat(res, "string"); + break; + case '\0': + strcat(res, "none"); + return; + default: + strcat(res, "unknown"); + return; + } + switch (*++p) { + case 'p': + strcat(res, " persistent"); + if (*(p-1) == 's') + strcat(res, " (invalid)"); + break; + case '\0': + break; + default: + error(" unknown format modifier '%c'", *p); + break; + } + + if (min > 1 || max > 1) + sprintf(res + strlen(res), " array (min = %d, max = %d)", min, max); + + if (desc) + sprintf(res + strlen(res), ", description \"%s\"", desc); + + append_parm(mod, "PARM", res); + + free(res); +} + +/* + * Extract the module parameters and module descriptions. + * Note: assumes same machine and arch for depmod and module. + */ +static void extract_parms(struct obj_file *f, MODULE *mod) +{ + struct obj_section *sec; + const char *cvalue; + char *p, *ep, *value, *n; + int namelen; + + sec = obj_find_section(f, ".modinfo"); + if (sec == NULL) + return; + + cvalue = get_modinfo_value(f, "author"); + if (cvalue) + append_parm(mod, "AUTH", cvalue); + + cvalue = get_modinfo_value(f, "description"); + if (cvalue) + append_parm(mod, "DESC", cvalue); + + p = sec->contents; + ep = p + sec->header.sh_size; + while (p < ep) { + value = strchr(p, '='); + n = strchr(p, '\0'); + if (value) { + namelen = value - p; + if (namelen >= 5 && strncmp(p, "parm_", 5) == 0 && + !(namelen > 10 && strncmp(p, "parm_desc_", 10) == 0)) { + char *pname = xmalloc(namelen + 1); + char *desckey = xmalloc(namelen + 5 + 1); + + strncpy(pname, p + 5, namelen - 5); + pname[namelen - 5] = '\0'; + + strcpy(desckey, "parm_desc_"); /* safe, xmalloc */ + strncat(desckey, p + 5, namelen - 5); + desckey[namelen + 5] = '\0'; + + save_parameter(f, mod, pname, value + 1, get_modinfo_value(f, desckey)); + + free(pname); + free(desckey); + } + } else { + if (n - p >= 5 && strncmp(p, "parm_", 5) == 0) { + error("parameter %s found with no value", p); + } + } + p = n + 1; + } +} + /* * Extract any generic string from the given symbol. * Note: assumes same machine and arch for depmod and module. @@ -743,6 +933,7 @@ error("depmod obj_relocate failed\n"); return(-1); } + extract_parms(f, mod); extract_generic_string(f, mod); image = xmalloc(m_size); obj_create_image(f, image); @@ -937,6 +1128,7 @@ static void prtdepend(char *base_dir, int nflag) { FILE *dep = stdout; + FILE *parms = stdout; FILE *generic_string = stdout; FILE *pcimap = stdout; FILE *isapnpmap = stdout; @@ -949,6 +1141,7 @@ if (!nflag) { dep = gen_file_open(gen_file+GEN_DEPFILE); + parms = gen_file_open(gen_file+GEN_PARMSFILE); generic_string = gen_file_open(gen_file+GEN_GENERIC_STRINGFILE); pcimap = gen_file_open(gen_file+GEN_PCIMAPFILE); isapnpmap = gen_file_open(gen_file+GEN_ISAPNPMAPFILE); @@ -1010,6 +1203,17 @@ } ptmod = modules; + fprintf(parms, "# module type text\n"); + for (i = 0; i < n_modules; i++, ptmod++) { + int j; + char **pstr = ptmod->parms; + if (!ptmod->n_parms) + continue; + for (j = 0; j < ptmod->n_parms; j++, ++pstr) + fprintf(parms, "%-20s %s\n", shortname(ptmod->name), *pstr); + } + + ptmod = modules; fprintf(generic_string, "# module id=string\n"); for (i = 0; i < n_modules; i++, ptmod++) { int j; @@ -1116,6 +1320,8 @@ } } + if (parms != stdout) + fclose(parms); if (generic_string != stdout) fclose(generic_string); if (pcimap != stdout) .