On Wed, Nov 20, 2024 at 11:12 PM lijiang <liji...@redhat.com> wrote: > > 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.
Agreed, there is no need to bring in extra code to implement this when we already have an approach to achieve the same. Thanks, Tao Liu > > 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 -- 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