Hi, Sun Feng Thank you for the patch. On Mon, Oct 28, 2024 at 11:32 AM <devel-requ...@lists.crash-utility.osci.io> wrote:
> Date: Wed, 23 Oct 2024 08:53:58 +0800 > From: Sun Feng <loyo...@gmail.com> > Subject: [Crash-utility] [PATCH] mod: introduce -v option to display > modules with valid version > To: devel@lists.crash-utility.osci.io > Cc: Sun Feng <loyo...@gmail.com> > Message-ID: <20241023005358.11328-1-loyo...@gmail.com> > > With this option, we can get module version easily in kdump, > it's helpful when developing external modules. > It seems to be a specific case? > > crash> mod -v > NAME VERSION > ahci 3.0 > vxlan 0.1.2.1 > dca 1.12.1 > ... > > Signed-off-by: Sun Feng <loyo...@gmail.com> > --- > 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 > }; > There are many kernel modules, which do not have the actual value for the field "version"(null), E.g: crash> struct module c008000005cb1d00 struct module { ... version = 0x0, srcversion = 0xc00000009c3628c0 "7D7FAEDDA764AC772D6F805", ... Currently, it is also easy to view the version string, for example: crash> mod MODULE NAME TEXT_BASE SIZE OBJECT FILE c008000004400080 libcrc32c c008000004260000 196608 (not loaded) [CONFIG_KALLSYMS] ... c0080000044a0700 sg c008000004480000 262144 (not loaded) [CONFIG_KALLSYMS] ... crash> struct module c0080000044a0700|grep -w version version = 0xc000000009d67f20 "3.5.36", Could you please explain the current background? Why is it needed? As you saw, it's not too hard to get a module version string based on crash internal command. Thanks Lianbo > > 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@lists.crash-utility.osci.io To unsubscribe send an email to devel-le...@lists.crash-utility.osci.io https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki