With this option, we can get module version easily in kdump, it's helpful when developing external modules. crash> mod -v NAME VERSION ahci 3.0 vxlan 0.1.2.1 dca 1.12.1 ... Signed-off-by: Sun Feng <loyou85@xxxxxxxxx> --- defs.h | 3 +++ help.c | 12 +++++++++++- kernel.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- symbols.c | 44 +++++++++++++++++++++++++++++++++++++++----- 4 files changed, 98 insertions(+), 7 deletions(-) diff --git a/defs.h b/defs.h index e2a9278..f14fcdf 100644 --- a/defs.h +++ b/defs.h @@ -2244,6 +2244,7 @@ struct offset_table { /* stash of commonly-used offsets */ long rb_list_head; long file_f_inode; long page_page_type; + long module_version; }; struct size_table { /* stash of commonly-used sizes */ @@ -2935,6 +2936,7 @@ struct symbol_table_data { #define MAX_MOD_NAMELIST (256) #define MAX_MOD_NAME (64) +#define MAX_MOD_VERSION (64) #define MAX_MOD_SEC_NAME (64) #define MOD_EXT_SYMS (0x1) @@ -2984,6 +2986,7 @@ struct load_module { long mod_size; char mod_namelist[MAX_MOD_NAMELIST]; char mod_name[MAX_MOD_NAME]; + char mod_version[MAX_MOD_VERSION]; ulong mod_flags; struct syment *mod_symtable; struct syment *mod_symend; diff --git a/help.c b/help.c index e95ac1d..1bac5e1 100644 --- a/help.c +++ b/help.c @@ -5719,7 +5719,7 @@ NULL char *help_mod[] = { "mod", "module information and loading of symbols and debugging data", -"-s module [objfile] | -d module | -S [directory] [-D|-t|-r|-R|-o|-g]", +"-s module [objfile] | -d module | -S [directory] [-D|-t|-r|-R|-o|-g|-v]", " With no arguments, this command displays basic information of the currently", " installed modules, consisting of the module address, name, base address,", " size, the object file name (if known), and whether the module was compiled", @@ -5791,6 +5791,7 @@ char *help_mod[] = { " -g When used with -s or -S, add a module object's section", " start and end addresses to its symbol list.", " -o Load module symbols with old mechanism.", +" -v Display modules with valid version.", " ", " If the %s session was invoked with the \"--mod <directory>\" option, or", " a CRASH_MODULE_PATH environment variable exists, then /lib/modules/<release>", @@ -5881,6 +5882,15 @@ char *help_mod[] = { " vxglm P(U)", " vxgms P(U)", " vxodm P(U)", +" ", +" Display modules with valid version:", +" ", +" %s> mod -v", +" NAME VERSION", +" ahci 3.0", +" vxlan 0.1.2.1", +" dca 1.12.1", +" ...", NULL }; diff --git a/kernel.c b/kernel.c index adb19ad..91eef2a 100644 --- a/kernel.c +++ b/kernel.c @@ -3593,6 +3593,9 @@ module_init(void) MEMBER_OFFSET_INIT(module_num_gpl_syms, "module", "num_gpl_syms"); + if (MEMBER_EXISTS("module", "version")) + MEMBER_OFFSET_INIT(module_version, "module", "version"); + if (MEMBER_EXISTS("module", "mem")) { /* 6.4 and later */ kt->flags2 |= KMOD_MEMORY; /* MODULE_MEMORY() can be used. */ @@ -4043,6 +4046,7 @@ irregularity: #define REMOTE_MODULE_SAVE_MSG (6) #define REINIT_MODULES (7) #define LIST_ALL_MODULE_TAINT (8) +#define LIST_ALL_MODULE_VERSION (9) void cmd_mod(void) @@ -4117,7 +4121,7 @@ cmd_mod(void) address = 0; flag = LIST_MODULE_HDR; - while ((c = getopt(argcnt, args, "Rd:Ds:Sot")) != EOF) { + while ((c = getopt(argcnt, args, "Rd:Ds:Sotv")) != EOF) { switch(c) { case 'R': @@ -4195,6 +4199,13 @@ cmd_mod(void) flag = LIST_ALL_MODULE_TAINT; break; + case 'v': + if (flag) + cmd_usage(pc->curcmd, SYNOPSIS); + else + flag = LIST_ALL_MODULE_VERSION; + break; + default: argerrs++; break; @@ -4578,10 +4589,12 @@ do_module_cmd(ulong flag, char *modref, ulong address, struct load_module *lm, *lmp; int maxnamelen; int maxsizelen; + int maxversionlen; char buf1[BUFSIZE]; char buf2[BUFSIZE]; char buf3[BUFSIZE]; char buf4[BUFSIZE]; + char buf5[BUFSIZE]; if (NO_MODULES()) return; @@ -4744,6 +4757,37 @@ do_module_cmd(ulong flag, char *modref, ulong address, case LIST_ALL_MODULE_TAINT: show_module_taint(); break; + + case LIST_ALL_MODULE_VERSION: + maxnamelen = maxversionlen = 0; + + for (i = 0; i < kt->mods_installed; i++) { + lm = &st->load_modules[i]; + maxnamelen = strlen(lm->mod_name) > maxnamelen ? + strlen(lm->mod_name) : maxnamelen; + + maxversionlen = strlen(lm->mod_version) > maxversionlen ? + strlen(lm->mod_version) : maxversionlen; + } + + fprintf(fp, "%s %s\n", + mkstring(buf2, maxnamelen, LJUST, "NAME"), + mkstring(buf5, maxversionlen, LJUST, "VERSION")); + + for (i = 0; i < kt->mods_installed; i++) { + lm = &st->load_modules[i]; + if ((!address || (lm->module_struct == address) || + (lm->mod_base == address)) && + strlen(lm->mod_version)) { + fprintf(fp, "%s ", mkstring(buf2, maxnamelen, + LJUST, lm->mod_name)); + fprintf(fp, "%s ", mkstring(buf5, maxversionlen, + LJUST, lm->mod_version)); + + fprintf(fp, "\n"); + } + } + break; } } diff --git a/symbols.c b/symbols.c index d00fbd7..9d90df7 100644 --- a/symbols.c +++ b/symbols.c @@ -1918,6 +1918,7 @@ store_module_symbols_6_4(ulong total, int mods_installed) { int i, m, t; ulong mod, mod_next; + ulong version; char *mod_name; uint nsyms, ngplsyms; ulong syms, gpl_syms; @@ -1930,6 +1931,7 @@ store_module_symbols_6_4(ulong total, int mods_installed) struct load_module *lm; char buf1[BUFSIZE]; char buf2[BUFSIZE]; + char mod_version[BUFSIZE]; char *strbuf = NULL, *modbuf, *modsymbuf; struct syment *sp; ulong first, last; @@ -1980,6 +1982,13 @@ store_module_symbols_6_4(ulong total, int mods_installed) mod_name = modbuf + OFFSET(module_name); + BZERO(mod_version, BUFSIZE); + if (MEMBER_EXISTS("module", "version")) { + version = ULONG(modbuf + OFFSET(module_version)); + if (version) + read_string(version, mod_version, BUFSIZE - 1); + } + lm = &st->load_modules[m++]; BZERO(lm, sizeof(struct load_module)); @@ -2003,9 +2012,15 @@ store_module_symbols_6_4(ulong total, int mods_installed) error(INFO, "module name greater than MAX_MOD_NAME: %s\n", mod_name); strncpy(lm->mod_name, mod_name, MAX_MOD_NAME-1); } + if (strlen(mod_version) < MAX_MOD_VERSION) + strcpy(lm->mod_version, mod_version); + else { + error(INFO, "module version greater than MAX_MOD_VERSION: %s\n", mod_version); + strncpy(lm->mod_version, mod_version, MAX_MOD_VERSION-1); + } if (CRASHDEBUG(3)) - fprintf(fp, "%lx (%lx): %s syms: %d gplsyms: %d ksyms: %ld\n", - mod, lm->mod_base, lm->mod_name, nsyms, ngplsyms, nksyms); + fprintf(fp, "%lx (%lx): %s syms: %d gplsyms: %d ksyms: %ld version: %s\n", + mod, lm->mod_base, lm->mod_name, nsyms, ngplsyms, nksyms, lm->mod_version); lm->mod_flags = MOD_EXT_SYMS; lm->mod_ext_symcnt = mcnt; @@ -2271,6 +2286,7 @@ store_module_symbols_v2(ulong total, int mods_installed) { int i, m; ulong mod, mod_next; + ulong version; char *mod_name; uint nsyms, ngplsyms; ulong syms, gpl_syms; @@ -2285,6 +2301,7 @@ store_module_symbols_v2(ulong total, int mods_installed) char buf2[BUFSIZE]; char buf3[BUFSIZE]; char buf4[BUFSIZE]; + char mod_version[BUFSIZE]; char *strbuf, *modbuf, *modsymbuf; struct syment *sp; ulong first, last; @@ -2344,6 +2361,13 @@ store_module_symbols_v2(ulong total, int mods_installed) mod_name = modbuf + OFFSET(module_name); + BZERO(mod_version, BUFSIZE); + if (MEMBER_EXISTS("module", "version")) { + version = ULONG(modbuf + OFFSET(module_version)); + if (version) + read_string(version, mod_version, BUFSIZE - 1); + } + lm = &st->load_modules[m++]; BZERO(lm, sizeof(struct load_module)); lm->mod_base = ULONG(modbuf + MODULE_OFFSET2(module_module_core, rx)); @@ -2357,11 +2381,19 @@ store_module_symbols_v2(ulong total, int mods_installed) mod_name); strncpy(lm->mod_name, mod_name, MAX_MOD_NAME-1); } + if (strlen(mod_version) < MAX_MOD_VERSION) + strcpy(lm->mod_version, mod_version); + else { + error(INFO, + "module version greater than MAX_MOD_VERSION: %s\n", + mod_version); + strncpy(lm->mod_version, mod_version, MAX_MOD_VERSION-1); + } if (CRASHDEBUG(3)) fprintf(fp, - "%lx (%lx): %s syms: %d gplsyms: %d ksyms: %ld\n", - mod, lm->mod_base, lm->mod_name, nsyms, - ngplsyms, nksyms); + "%lx (%lx): %s syms: %d gplsyms: %d ksyms: %ld version: %s\n", + mod, lm->mod_base, lm->mod_name, nsyms, + ngplsyms, nksyms, lm->mod_version); lm->mod_flags = MOD_EXT_SYMS; lm->mod_ext_symcnt = mcnt; lm->mod_init_module_ptr = ULONG(modbuf + @@ -10177,6 +10209,8 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(module_next)); fprintf(fp, " module_name: %ld\n", OFFSET(module_name)); + fprintf(fp, " module_version: %ld\n", + OFFSET(module_version)); fprintf(fp, " module_syms: %ld\n", OFFSET(module_syms)); fprintf(fp, " module_nsyms: %ld\n", -- 2.43.0 -- Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki