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

Reply via email to